Commit b20870a3 authored by Boris Kocherov's avatar Boris Kocherov

Merge branch 'bk_xmla_client.dev.171107' into merge

parents 1fb1ddf7 e54c7247
......@@ -275,6 +275,8 @@
"../common/externs/jquery-3.2.js",
"../common/externs/xregexp-3.0.0.js",
"../common/externs/sockjs.js",
"../common/externs/Xmla.js",
"../common/externs/rsvp-2.0.4.js",
"../common/externs/jszip.min.js",
"../common/externs/jszip-utils.js"
],
......
......@@ -10,6 +10,8 @@
<link rel="stylesheet" href="qunit/qunit-1.11.0.css" type="text/css" media="screen" />
<script type="text/javascript" src="qunit/qunit-1.11.0.js"></script>
<script type="text/javascript" src="../../../web-apps/vendor/xregexp/xregexp-all-min.js"></script>
<script type="text/javascript" src="../../../web-apps/vendor/rsvp/rsvp.min.js"></script>
<script type="text/javascript" src="../../../web-apps/vendor/xmla4js/Xmla-compiled.js"></script>
<script type="text/javascript" src="../../../web-apps/apps/spreadsheeteditor/sdk_dev_scripts.js"></script>
<script>
......
/* jshint -W040 */
/*
* (c) Copyright Ascensio System SIA 2010-2017
* Copyright (c) 2017 Nexedi SA and Contributors. All Rights Reserved.
* Author: Boris Kocherov
*
* This extension was developed by Nexedi as part of
* OpenPaaS::NG PSPC collaborative R&D project financed by BPI France
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
* version 3 as published by the Free Software Foundation.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
* You can contact jp@nexedi.com.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
......@@ -34,19 +35,512 @@
(/**
* @param {Window} window
* @param {Object} RSVP
* @param {Xmla} Xmla
* @param {console} console
* @param {undefined} undefined
*/
function (window, undefined) {
function (window, RSVP, Xmla, console, undefined) {
var cBaseFunction = AscCommonExcel.cBaseFunction;
var cFormulaFunctionGroup = AscCommonExcel.cFormulaFunctionGroup;
var cFormulaFunctionGroup = AscCommonExcel.cFormulaFunctionGroup,
cElementType = AscCommonExcel.cElementType,
cNumber = AscCommonExcel.cNumber,
cString = AscCommonExcel.cString,
cBool = AscCommonExcel.cBool,
cError = AscCommonExcel.cError,
cErrorType = AscCommonExcel.cErrorType,
cArea = AscCommonExcel.cArea,
cArea3D = AscCommonExcel.cArea3D,
cRef = AscCommonExcel.cRef,
cRef3D = AscCommonExcel.cRef3D,
cEmpty = AscCommonExcel.cEmpty,
cArray = AscCommonExcel.cArray,
cubeScheme = {},
cubeExecutionScheme = {};
cFormulaFunctionGroup['Cube'] = cFormulaFunctionGroup['Cube'] || [];
cFormulaFunctionGroup['Cube'].push(cCUBEKPIMEMBER, cCUBEMEMBER, cCUBEMEMBERPROPERTY, cCUBERANKEDMEMBER, cCUBESET,
cFormulaFunctionGroup.Cube = cFormulaFunctionGroup.Cube || [];
cFormulaFunctionGroup.Cube.push(cCUBEKPIMEMBER, cCUBEMEMBER, cCUBEMEMBERPROPERTY, cCUBERANKEDMEMBER, cCUBESET,
cCUBESETCOUNT, cCUBEVALUE);
cFormulaFunctionGroup['NotRealised'] = cFormulaFunctionGroup['NotRealised'] || [];
cFormulaFunctionGroup['NotRealised'].push(cCUBEKPIMEMBER, cCUBEMEMBER, cCUBEMEMBERPROPERTY, cCUBERANKEDMEMBER,
cCUBESET, cCUBESETCOUNT, cCUBEVALUE);
cFormulaFunctionGroup.NotRealised = cFormulaFunctionGroup.NotRealised || [];
cFormulaFunctionGroup.NotRealised.push(cCUBEKPIMEMBER, cCUBEMEMBERPROPERTY, cCUBERANKEDMEMBER,
cCUBESET, cCUBESETCOUNT);
var xmla = new Xmla({
// listeners: {
// events: Xmla.EVENT_ERROR,
// handler: function (eventName, eventData, xmla) {
// console.log(eventData.exception);
// // alert(
// // "Snap, an error occurred: " + eventData.exception.message + " (" + eventData.exception.code + ")" +
// // (eventData.exception.code === Xmla.Exception.HTTP_ERROR_CDE
// // ? "\nstatus: " + eventData.exception.data.status + "; statusText: " + eventData.exception.data.statusText
// // : "")
// // );
// }
// },
async: true
});
function xmla_request(func, prop) {
var xmla = new Xmla({async: true});
// return function () {
return new RSVP.Queue()
.push(function () {
return new RSVP.Promise(function (resolve, reject) {
prop.success = function (xmla, options, response) {
resolve(response);
};
prop.error = function (xmla, options, response) {
reject(response);
};
xmla[func](prop);
});
});
}
function xmla_request_retry(func, prop) {
return xmla_request(func, prop)
.push(undefined, function (response) {
// fix mondrian Internal and Sql errors
if (response) {
switch (response["code"]) {
case "SOAP-ENV:Server.00HSBE02":
case "SOAP-ENV:00UE001.Internal Error":
// rarely server error, so try again
return xmla_request(func, prop);
}
}
throw response;
});
}
function discover_hierarchies(connection) {
var settings = getProperties(connection),
prop = settings.prop;
prop.restrictions = {
// 'CATALOG_NAME': 'FoodMart',
// 'HIERARCHY_NAME': hierarchy_name,
// 'HIERARCHY_UNIQUE_NAME': hierarchy_name,
'CUBE_NAME': settings["cube"]
};
return xmla_request_retry("discoverMDHierarchies", prop)
.push(function (response) {
var hierarchies = {},
hierarchy,
uname,
caption,
all_member,
dimension_uname,
dimension,
dimensions = {};
while (response.hasMoreRows()) {
uname = response["getHierarchyUniqueName"]();
caption = response["getHierarchyCaption"]();
all_member = response["getAllMember"]();
dimension_uname = response["getDimensionUniqueName"]();
dimension = dimensions[dimension_uname];
if (!dimension) {
dimension = {
"uname": dimension_uname,
"all_member": all_member
};
dimensions[dimension_uname] = dimension;
}
if (!dimension.all_member && all_member) {
dimension.all_member = all_member;
}
hierarchy = {
"uname": uname,
"caption": caption,
"all_member": all_member,
"dimension_uname": dimension_uname,
"dimension": dimension
};
hierarchies[uname] = hierarchy;
hierarchies[caption] = hierarchy;
response.nextRow();
}
return {
"hierarchies": hierarchies,
"dimensions": dimensions
};
});
}
function getProperties(connection) {
var connections = {
"xmla": {
"prop": {
"url": "https://d1.erp5.ru/saiku/xmla",
"properties": {
"DataSourceInfo": "FoodMart",
"Catalog": "FoodMart"
}
},
"cube": "Sales"
},
"olapy": {
"prop": {
"url": "https://d1.erp5.ru/olapy/xmla",
"properties": {
"DataSourceInfo": "-",
"Catalog": "sales"
}
},
"cube": "Sales"
}
};
connection = connections[connection];
if (!connection) {
throw "connection not exist";
}
connection = JSON.parse(JSON.stringify(connection));
return connection;
}
function getScheme(connection) {
var scheme = cubeScheme[connection],
queue = new RSVP.Queue();
if (scheme) {
return queue.push(function () {
return scheme;
});
}
cubeScheme[connection] = queue;
return queue
.push(function () {
return discover_hierarchies(connection);
})
.push(function (arg) {
scheme = {
members: {},
hierarchies: arg.hierarchies,
dimensions: arg.dimensions
};
cubeScheme[connection] = scheme;
return scheme;
});
}
function getExecutionScheme(connection) {
var scheme = cubeExecutionScheme[connection];
if (scheme) {
return scheme;
} else {
scheme = {
members: {},
hierarchies: {},
levels: {}
};
cubeExecutionScheme[connection] = scheme;
return scheme;
}
}
function getCell(arg0) {
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
// } else if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
// arg0 = arg0.cross(arguments[1].bbox);
} else if (arg0 instanceof cRef || arg0 instanceof cRef3D) {
arg0 = arg0.getValue();
}
return arg0;
}
function parseArgs(mdx_array) {
return function () {
var members = [];
function stringForge(value) {
var array;
if (value.cube_value) {
array = value.cube_value;
} else {
array = value.value.split(',');
}
if (array.length > 0) {
// filter members already existed
members = members.filter(function (i) {
return array.indexOf(i) === -1;
});
members = members.concat(array);
}
}
function cellForge(cell) {
if (cell) {
if (cell.type === cElementType.error) {
// debugger;
throw "referenced cell contain error";
}
if (cell.formulaParsed && cell.formulaParsed.value) {
stringForge(cell.formulaParsed.value);
} else {
stringForge({value: cell.getValue()});
}
}
}
mdx_array.forEach(function (element) {
if (element instanceof cArea || element instanceof cArea3D ||
element instanceof cRef || element instanceof cRef3D) {
element.getRange()._foreach(cellForge);
} else {
stringForge(element);
}
});
return members;
};
}
var AddCubeValueCalculate = (function () {
var deferred = RSVP.defer(),
cells = [];
return function (cell_id) {
if (cells.indexOf(cell_id) === -1) {
cells.push(cell_id);
}
// console.log('+ ' + cells);
return function () {
var i = cells.indexOf(cell_id);
if (i !== -1) {
cells.splice(i, 1);
}
// console.log('-' + cells);
if (cells.length === 0) {
deferred.resolve();
deferred = RSVP.defer();
return {};
}
return deferred.promise;
};
};
})();
function execute(connection) {
var execution_scheme = getExecutionScheme(connection),
scheme;
if (!execution_scheme.execute) {
execution_scheme.execute = RSVP.defer();
return getScheme(connection)
.push(function (s) {
var settings = getProperties(connection),
prop = settings.prop,
hierarchies = execution_scheme.hierarchies,
hierarchy,
mdx = [],
tuple_str,
all_member;
scheme = s;
for (hierarchy in hierarchies) {
tuple_str = hierarchies[hierarchy].join(",");
all_member = scheme.hierarchies[hierarchy]["all_member"];
if (all_member) {
tuple_str = tuple_str + ',' + all_member;
}
mdx.push("{" + tuple_str + "}");
}
prop.statement = "SELECT " + mdx.join("*") +
" ON 0 FROM [" + settings["cube"] + "]";
return xmla_request("execute", prop);
})
.push(function (dataset) {
var cellset = dataset.getCellset(),
axis_count = dataset.axisCount(),
axis_array = [],
axis_id,
cube = {
"axes": {"length": axis_count},
"members": {},
"hierarchies": {"length": 0},
"hierarchies_info": scheme.hierarchies,
"cells": []
};
for (axis_id = 0; axis_id < axis_count; axis_id++) {
axis_array.push(dataset.getAxis(axis_id));
}
axis_array.forEach(function (axis, axis_id) {
cube.axes[axis_id] = {
tuples: {},
length: 0
};
axis.eachTuple(function (tuple) {
var coordinate_tuple = [];
axis.eachHierarchy(function () {
var member = this.member();
if (!cube.members.hasOwnProperty(member["UName"])) {
cube.members[member["UName"]] = member;
}
coordinate_tuple.push(member["UName"]);
});
cube.axes[axis_id].tuples[coordinate_tuple.join(',')] = tuple.index;
cube.axes[axis_id].length++;
});
axis.eachHierarchy(function (hierarchy) {
cube.hierarchies[hierarchy.name] = {
axis_id: axis_id, tuple_id: hierarchy.index, name: hierarchy.name
};
cube.hierarchies[cube.hierarchies.length] = cube.hierarchies[hierarchy.name];
cube.hierarchies['' + axis_id + ',' + hierarchy.index] = cube.hierarchies[hierarchy.name];
cube.hierarchies.length++;
});
});
do {
cube.cells[cellset.cellOrdinal()] = cellset["cellValue"]();
} while (cellset.nextCell() > 0);
execution_scheme.cube = cube;
execution_scheme.execute.resolve(cube);
execution_scheme.execute = null;
execution_scheme.hierarchies = [];
return cube;
})
.push(undefined, function (error) {
console.error(error);
execution_scheme.execute = null;
execution_scheme.hierarchies = [];
});
}
return execution_scheme.execute.promise;
}
function discover_members(connection, opt) {
return new RSVP.Queue()
.push(function () {
var settings = getProperties(connection),
prop = settings.prop,
cached_member,
scheme = getExecutionScheme(connection);
prop.restrictions = {
// 'CATALOG_NAME': 'FoodMart',
'CUBE_NAME': settings["cube"]
};
if (!opt) {
opt = {};
}
if (opt.member_uname) {
prop.restrictions["MEMBER_UNIQUE_NAME"] = opt.member_uname;
cached_member = scheme.members[opt.member_uname];
}
if (opt.level_uname) {
prop.restrictions["LEVEL_UNIQUE_NAME"] = opt.level_uname;
}
if (cached_member) {
return [cached_member];
} else {
return xmla_request_retry("discoverMDMembers", prop)
.push(function (r) {
var ret = [],
uname,
level,
cached_member;
while (r.hasMoreRows()) {
uname = r["getMemberUniqueName"]();
level = r["getLevelUniqueName"]();
// we can check cache twice because fist check
// only if discover by member_uname
if (!scheme.members.hasOwnProperty(uname)) {
cached_member = {
uname: uname,
h: r["getHierarchyUniqueName"](),
level: r["getLevelUniqueName"](),
caption: r["getMemberCaption"](),
type: r["getMemberType"]()
};
scheme.members[uname] = cached_member;
} else {
cached_member = scheme.members[uname];
}
ret.push(cached_member);
r.nextRow();
if (!scheme.levels.hasOwnProperty(level)) {
scheme.levels[level] = discover_level(connection, scheme, level);
}
}
return ret;
});
}
});
}
function discover_level(connection, scheme, level) {
return discover_members(connection, {
level_uname: level
})
.push(function (members) {
var i;
function compare(a, b) {
if (a.uname < b.uname)
return -1;
if (a.uname > b.uname)
return 1;
return 0;
}
members.sort(compare);
for (i = 0; i < members.length; i++) {
members[i].level_index = i;
}
scheme.levels[level] = members;
});
}
function discover_members_for_arguments(connection, members) {
var promises = [],
hierarchies = {};
function check_interseption(hierarchy) {
if (hierarchies.hasOwnProperty(hierarchy)) {
throw "The tuple is invalid because there is no intersection for the specified values.";
} else {
hierarchies[hierarchy] = 1;
}
}
members.forEach(function (member) {
if (member) {
promises
.push(
discover_members(connection, {
member_uname: member
})
.push(function (members) {
var member;
if (members.length > 0) {
member = members[0];
check_interseption(member.h);
return member;
} else {
throw "member not found";
}
})
);
}
});
return RSVP.all(promises);
}
function error_handler(current_cell_id) {
return function (error) {
console.error(current_cell_id, error);
var ret;
if (error === "referenced cell contain error") {
ret = new cError(cErrorType.wrong_value_type);
} else if (error === "connection not exist" ||
error instanceof Xmla.Exception) {
ret = new cError(cErrorType.wrong_name);
} else {
ret = new cError(cErrorType.not_available);
}
return ret;
};
}
/**
* @constructor
......@@ -69,6 +563,69 @@
cCUBEMEMBER.prototype = Object.create(cBaseFunction.prototype);
cCUBEMEMBER.prototype.constructor = cCUBEMEMBER;
cCUBEMEMBER.prototype.name = 'CUBEMEMBER';
cCUBEMEMBER.prototype.argumentsMin = 2;
cCUBEMEMBER.prototype.argumentsMax = 3;
cCUBEMEMBER.prototype.ca = true;
cCUBEMEMBER.prototype.CalculateLazy = function (queue, bbox, isDefName, ws) {
var connection,
current_cell_id = [ws.getId(),bbox.r1,bbox.c2].join(";"),
caption;
return queue
.push(function (arg) {
connection = getCell(arg[0]);
caption = getCell(arg[2]);
if (caption) {
caption = caption.getValue();
}
return parseArgs([arg[1]])();
})
.push(function (members) {
return discover_members_for_arguments(connection, members);
})
.push(function (members) {
var last_id = members.length - 1,
ret;
if (!caption) {
caption = members[last_id].caption;
}
ret = new cString(caption);
ret.cube_value = [];
members.forEach(function (member) {
ret.cube_value.push(member.uname);
});
return ret;
})
.push(undefined, error_handler(current_cell_id));
};
cCUBEMEMBER.prototype.changeOffsetElem = function (arg, offset) {
var connection = getCell(arg[0]),
scheme = getExecutionScheme(connection),
i,
elem,
member,
new_member,
level;
for (i = 0; i < arg.length; i++) {
elem = arg[i];
if (cElementType.string === elem.type) {
member = scheme.members[elem.value];
if (member && (member.level_index >= 0)) {
level = scheme.levels[member.level];
new_member = level[member.level_index + offset.offsetCol + offset.offsetRow];
if (new_member) {
elem.value = new_member.uname;
} else {
elem.value = "";
}
}
}
}
};
cCUBEMEMBER.prototype.getInfo = function () {
return {
name: this.name, args: "( connection, members, caption )"
};
};
/**
* @constructor
......@@ -124,4 +681,125 @@
cCUBEVALUE.prototype = Object.create(cBaseFunction.prototype);
cCUBEVALUE.prototype.constructor = cCUBEVALUE;
cCUBEVALUE.prototype.name = 'CUBEVALUE';
})(window);
cCUBEVALUE.prototype.argumentsMin = 2;
cCUBEVALUE.prototype.argumentsMax = 5;
cCUBEVALUE.prototype.ca = true;
cCUBEVALUE.prototype.CalculateLazy = function (queue, bbox, isDefName, ws) {
var scheme,
connection,
members = [],
current_cell_id = [ws.getId(),bbox.r1,bbox.c2].join(";"),
waiter = AddCubeValueCalculate(current_cell_id);
return queue
.push(function (arg) {
connection = getCell(arg[0]);
scheme = getExecutionScheme(connection);
return parseArgs(arg.slice(1))();
})
.push(function (members) {
return discover_members_for_arguments(connection, members);
})
.push(function (m) {
var member_uname,
member,
h,
hierarchy;
for (member_uname in m) {
if (m.hasOwnProperty(member_uname)) {
member = m[member_uname];
hierarchy = member.h;
h = scheme.hierarchies[hierarchy];
if (!h) {
h = [];
scheme.hierarchies[hierarchy] = h;
}
if (h.indexOf(member.uname) === -1) {
h.push(member.uname);
}
members.push(member.uname);
}
}
return waiter();
})
.push(function () {
return execute(connection);
})
.push(function (cube) {
var cell_id = 0,
p_d = 1,
h,
member_path,
coordinate = [],
i,
ret;
function getHierarchyByMember(member_path) {
var h;
h = cube.members[member_path];
if (h === undefined) {
throw "query result not contain data for member:" +
member_path;
}
h = h.hierarchy;
h = cube.hierarchies[h];
return h;
}
for (i = 0; i < cube.hierarchies.length; i++) {
h = cube.hierarchies[i];
if (!coordinate[h.axis_id]) {
coordinate[h.axis_id] = [];
}
coordinate[h.axis_id][h.tuple_id] = null;
}
for (i = 0; i < members.length; i++) {
member_path = members[i];
h = getHierarchyByMember(members[i]);
coordinate[h.axis_id][h.tuple_id] = member_path;
}
coordinate = coordinate.map(function (axis, axis_id) {
return axis.map(function (h, h_id) {
var hierarchy_name,
all_member;
if (!h) {
hierarchy_name = cube.hierarchies[axis_id + ',' + h_id].name;
all_member = cube["hierarchies_info"][hierarchy_name]["all_member"];
if (all_member) {
h = getHierarchyByMember(all_member);
if (h) {
return all_member;
}
}
throw "Axis:" + axis_id + " hierarchy:" +
cube.hierarchies[axis_id + ',' + h_id].name +
" not determinated";
}
return h;
}).join(',');
});
coordinate.forEach(function (tuple, axis_id) {
var axis = cube.axes[axis_id];
cell_id = p_d * axis.tuples[tuple] + cell_id;
p_d = p_d * axis.length;
});
ret = new cNumber(cube.cells[cell_id]);
return ret;
})
.push(undefined, function (error) {
// issue in one cell(cubevalue) not stop calculation in other
return new RSVP.Queue()
.push(function () {
return waiter();
})
.push(function () {
return error_handler(current_cell_id)(error);
});
});
};
cCUBEVALUE.prototype.changeOffsetElem = cCUBEMEMBER.prototype.changeOffsetElem;
cCUBEVALUE.prototype.getInfo = function () {
return {
name: this.name, args: "( connection, member1, member2, .. )"
};
};
})(window, RSVP, Xmla, console);
......@@ -659,6 +659,10 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
this.value = val;
}
cBaseType.prototype.clone = function () {
return new this.constructor(this.value);
};
cBaseType.prototype.cloneTo = function (oRes) {
oRes.numFormat = this.numFormat;
oRes.value = this.value;
......@@ -672,6 +676,110 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
cBaseType.prototype.toLocaleString = function () {
return this.toString();
};
cBaseType.prototype.CalculatePromise = function (arg, opt_bbox, isDefName, ws, bIsSpecialFunction) {
// depromise args
var t = this,
lazy_formulas = [],
lazy_found;
function check_args_promise() {
var promise_flag = false,
element,
length,
i;
function cellForge(cell) {
if (cell && cell.formulaParsed &&
(cell.formulaParsed.lazy_value || cell.formulaParsed.queue)) {
promise_flag = true;
lazy_formulas.push(cell.formulaParsed);
}
}
for (i = 0, length = arg.length; i < length; ++i) {
element = arg[i];
if (typeof element === "function") {
promise_flag = true;
}
if (element instanceof cArea || element instanceof cArea3D ||
element instanceof cRef || element instanceof cRef3D) {
element.getRange()._foreach(cellForge);
}
}
return promise_flag;
}
lazy_found = check_args_promise();
if (t.CalculateLazy) {
return function () {
var queue = new RSVP.Queue();
if (lazy_formulas.length > 0) {
lazy_formulas.forEach(function (formula) {
var lazy = formula.lazy_value;
if (lazy) {
// if value lazy run it
lazy();
}
if (formula.queue) {
// add dependence from already
// running but not computed lazy
queue.push(function () {
return formula.queue;
});
}
});
}
queue
.push(function () {
return RSVP.all(arg.map(function (z) {
if (typeof z === "function") {
return z();
} else {
return z;
}
}));
});
return t.CalculateLazy(queue, opt_bbox, isDefName, ws, bIsSpecialFunction);
};
} else {
if (lazy_found) {
return function () {
var queue = new RSVP.Queue();
if (lazy_formulas.length > 0) {
lazy_formulas.forEach(function (formula) {
var lazy = formula.lazy_value;
if (lazy) {
// if value lazy add it dependence list
lazy();
}
if (formula.queue) {
// add dependence from already
// running but not computed lazy
queue.push(function () {
return formula.queue;
});
}
});
}
return queue
.push(function () {
return RSVP.all(arg.map(function (z) {
if (typeof z === "function") {
return z();
} else {
return z;
}
}));
})
.push(function (arg) {
return t.Calculate(arg, opt_bbox, isDefName, ws, bIsSpecialFunction);
});
};
} else {
return t.Calculate(arg, opt_bbox, isDefName, ws, bIsSpecialFunction);
}
}
};
/*Basic types of an elements used into formulas*/
/**
......@@ -2415,6 +2523,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
cBaseOperator.prototype.Calculate = function () {
return null;
};
cBaseOperator.prototype.CalculatePromise = cBaseType.prototype.CalculatePromise;
cBaseOperator.prototype.Assemble2 = function (arg, start, count) {
var str = "";
if (this.argumentsCurrent === 2) {
......@@ -2463,6 +2572,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
cBaseFunction.prototype.Calculate = function () {
return new cError(cErrorType.wrong_name);
};
cBaseFunction.prototype.CalculatePromise = cBaseOperator.prototype.CalculatePromise;
cBaseFunction.prototype.Assemble2 = function (arg, start, count) {
var str = "", c = start + count - 1;
......@@ -5314,6 +5424,8 @@ parserFormula.prototype.setFormula = function(formula) {
};
parserFormula.prototype.calculate = function (opt_defName, opt_bbox, opt_offset) {
var value,
formula = this;
if (this.isCalculate && (!this.calculateDefName || this.calculateDefName[opt_bbox ? opt_bbox.getName() :
opt_bbox])) {
//cycle
......@@ -5372,7 +5484,7 @@ parserFormula.prototype.setFormula = function(formula) {
}
arg.unshift(elemArr.pop());
}
_tmp = currentElement.Calculate(arg, opt_bbox, opt_defName, this.ws, bIsSpecialFunction);
_tmp = currentElement.CalculatePromise(arg, opt_bbox, opt_defName, this.ws, bIsSpecialFunction);
if (cNumFormatNull !== _tmp.numFormat) {
numFormat = _tmp.numFormat;
} else if (0 > numFormat || cNumFormatNone === currentElement.numFormat) {
......@@ -5390,8 +5502,31 @@ parserFormula.prototype.setFormula = function(formula) {
elemArr.push(currentElement);
}
}
this.value = elemArr.pop();
this.value.numFormat = numFormat;
value = elemArr.pop();
if (typeof value === "function") {
this.value = new cError(cErrorType.getting_data);
this.queue = true;
this.lazy_value = function () {
formula.lazy_value = null;
formula.queue = value()
.push(function (ret) {
formula.value = ret;
formula.value.numFormat = numFormat;
formula._endCalculate();
// updateOnScreen cell
formula.ws.workbook.handlers.trigger("cleanCellCache",
formula.ws.getId(), {0: opt_bbox},
AscCommonExcel.c_oAscCanChangeColWidth.none);
formula.queue = false;
// formula.lazy_value = null;
return formula.value;
});
return formula.queue
}
} else {
this.value = value;
this.value.numFormat = numFormat;
}
this._endCalculate();
return this.value;
......@@ -5407,8 +5542,39 @@ parserFormula.prototype.setFormula = function(formula) {
/* Для обратной сборки функции иногда необходимо поменять ссылки на ячейки */
parserFormula.prototype.changeOffset = function (offset, canResize) {//offset = AscCommonExcel.CRangeOffset
var elemArr = [], currentElement = null, arg,
disable_changeOffset_run = false;
for (var i = 0; i < this.outStack.length; i++) {
this.changeOffsetElem(this.outStack[i], this.outStack, i, offset, canResize);
currentElement = this.outStack[i];
this.changeOffsetElem(currentElement, this.outStack, i, offset, canResize);
if (disable_changeOffset_run) {
continue;
}
if (currentElement.name == "(") {
continue;
}
if (currentElement.type === cElementType.operator || currentElement.type === cElementType.func) {
if (elemArr.length < currentElement.getArguments()) {
disable_changeOffset_run = true;
continue;
} else {
if (currentElement && currentElement.changeOffsetElem) {
arg = [];
for (var ind = 0; ind < currentElement.getArguments(); ind++) {
arg.unshift(elemArr.pop());
}
currentElement.changeOffsetElem(arg, offset);
}
// calculation not work on changeOffset stage
elemArr.push(new cEmpty());
}
} else if (currentElement.type === cElementType.name || currentElement.type === cElementType.name3D) {
elemArr.push(currentElement.Calculate(null, rangeCell));
} else if (currentElement.type === cElementType.table) {
elemArr.push(currentElement.toRef(rangeCell.getBBox0()));
} else {
elemArr.push(currentElement);
}
}
return this;
};
......
......@@ -927,6 +927,11 @@
this.buildDefName = {};
},
calcTree: function() {
var dependency_graph = this,
formula,
i,
tasks = [],
lazy_value;
if (this.lockCounter > 0) {
return;
}
......@@ -944,26 +949,44 @@
this._broadcastCells(notifyData, calcTrack);
}
this._broadcastCellsEnd();
for (var i = 0; i < noCalcTrack.length; ++i) {
var formula = noCalcTrack[i];
for (i = 0; i < noCalcTrack.length; ++i) {
formula = noCalcTrack[i];
//defName recalc when calc formula containing it. no need calc it
formula.setIsDirty(false);
}
for (var i = 0; i < calcTrack.length; ++i) {
var formula = calcTrack[i];
for (i = 0; i < calcTrack.length; ++i) {
formula = calcTrack[i];
if (formula.getIsDirty()) {
formula.calculate();
}
}
//copy cleanCellCache to prevent recursion in trigger("cleanCellCache")
var tmpCellCache = this.cleanCellCache;
this.cleanCellCache = {};
for (var i in tmpCellCache) {
this.wb.handlers.trigger("cleanCellCache", i, {0: tmpCellCache[i]},
AscCommonExcel.c_oAscCanChangeColWidth.none);
for (i = calcTrack.length-1; i >= 0; --i) {
lazy_value = calcTrack[i].lazy_value;
if (lazy_value) {
tasks.push(lazy_value());
}
}
function end () {
//copy cleanCellCache to prevent recursion in trigger("cleanCellCache")
var tmpCellCache = dependency_graph.cleanCellCache;
dependency_graph.cleanCellCache = {};
for (var i in dependency_graph.cleanCellCache) {
dependency_graph.wb.handlers.trigger("cleanCellCache", i, {0: tmpCellCache[i]},
AscCommonExcel.c_oAscCanChangeColWidth.none);
}
AscCommonExcel.g_oVLOOKUPCache.clean();
AscCommonExcel.g_oHLOOKUPCache.clean();
}
if (tasks.length > 0) {
new RSVP.Queue()
.push(function () {
return RSVP.all(tasks);
})
.push(end);
} else {
end();
}
AscCommonExcel.g_oVLOOKUPCache.clean();
AscCommonExcel.g_oHLOOKUPCache.clean();
},
initOpen: function() {
this._foreachDefName(function(defName) {
......@@ -6418,7 +6441,7 @@
this.setValue("");
};
Cell.prototype._checkDirty = function(){
if(this.formulaParsed && this.formulaParsed.getIsDirty()) {
if(this.formulaParsed && this.formulaParsed.getIsDirty() && !this.formulaParsed.queue) {
this.formulaParsed.calculate();
}
};
......
This source diff could not be displayed because it is too large. You can view the blob instead.
(function(globals) {
var define, requireModule;
(function() {
var registry = {}, seen = {};
define = function(name, deps, callback) {
registry[name] = { deps: deps, callback: callback };
};
requireModule = function(name) {
if (seen[name]) { return seen[name]; }
seen[name] = {};
var mod = registry[name];
if (!mod) {
throw new Error("Module '" + name + "' not found.");
}
var deps = mod.deps,
callback = mod.callback,
reified = [],
exports;
for (var i=0, l=deps.length; i<l; i++) {
if (deps[i] === 'exports') {
reified.push(exports = {});
} else {
reified.push(requireModule(deps[i]));
}
}
var value = callback.apply(this, reified);
return seen[name] = exports || value;
};
})();
define("rsvp/all",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
/* global toString */
function promiseAtLeast(expected_count, promises) {
if (Object.prototype.toString.call(promises) !== "[object Array]") {
throw new TypeError('You must pass an array to all.');
}
function canceller() {
var promise;
for (var i = 0; i < promises.length; i++) {
promise = promises[i];
if (promise && typeof promise.then === 'function' &&
typeof promise.cancel === 'function') {
promise.cancel();
}
}
}
return new Promise(function(resolve, reject, notify) {
var results = [], remaining = promises.length,
promise, remaining_count = promises.length - expected_count;
if (remaining === 0) {
if (expected_count === 1) {
resolve();
} else {
resolve([]);
}
}
function resolver(index) {
return function(value) {
resolveAll(index, value);
};
}
function resolveAll(index, value) {
results[index] = value;
if (--remaining === remaining_count) {
if (remaining_count === 0) {
resolve(results);
} else {
resolve(value);
canceller();
}
}
}
function notifier(index) {
return function(value) {
notify({"index": index, "value": value});
};
}
function cancelAll(rejectionValue) {
reject(rejectionValue);
canceller();
}
for (var i = 0; i < promises.length; i++) {
promise = promises[i];
if (promise && typeof promise.then === 'function') {
promise.then(resolver(i), cancelAll, notifier(i));
} else {
resolveAll(i, promise);
}
}
}, canceller
);
}
function all(promises) {
return promiseAtLeast(promises.length, promises);
}
function any(promises) {
return promiseAtLeast(1, promises);
}
__exports__.all = all;
__exports__.any = any;
});
define("rsvp/async",
["exports"],
function(__exports__) {
"use strict";
var browserGlobal = (typeof window !== 'undefined') ? window : {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var async;
var local = (typeof global !== 'undefined') ? global : this;
function checkNativePromise() {
if (typeof Promise === "function" &&
typeof Promise.resolve === "function") {
try {
/* global Promise */
var promise = new Promise(function(){});
if ({}.toString.call(promise) === "[object Promise]") {
return true;
}
} catch (e) {}
}
return false;
}
function useNativePromise() {
var nativePromise = Promise.resolve();
return function(callback, arg) {
nativePromise.then(function () {
callback(arg);
});
};
}
// old node
function useNextTick() {
return function(callback, arg) {
process.nextTick(function() {
callback(arg);
});
};
}
// node >= 0.10.x
function useSetImmediate() {
return function(callback, arg) {
/* global setImmediate */
setImmediate(function(){
callback(arg);
});
};
}
function useMutationObserver() {
var queue = [];
var observer = new BrowserMutationObserver(function() {
var toProcess = queue.slice();
queue = [];
toProcess.forEach(function(tuple) {
var callback = tuple[0], arg= tuple[1];
callback(arg);
});
});
var element = document.createElement('div');
observer.observe(element, { attributes: true });
// Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
window.addEventListener('unload', function(){
observer.disconnect();
observer = null;
}, false);
return function(callback, arg) {
queue.push([callback, arg]);
element.setAttribute('drainQueue', 'drainQueue');
};
}
function useSetTimeout() {
return function(callback, arg) {
local.setTimeout(function() {
callback(arg);
}, 1);
};
}
if (typeof setImmediate === 'function') {
async = useSetImmediate();
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
async = useNextTick();
} else if (BrowserMutationObserver) {
async = useMutationObserver();
} else if (checkNativePromise()) {
async = useNativePromise();
} else {
async = useSetTimeout();
}
__exports__.async = async;
});
define("rsvp/cancellation_error",
["exports"],
function(__exports__) {
"use strict";
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
function CancellationError(message) {
this.name = "cancel";
if ((message !== undefined) && (typeof message !== "string")) {
throw new TypeError('You must pass a string.');
}
this.message = message || "Default Message";
}
CancellationError.prototype = new Error();
CancellationError.prototype.constructor = CancellationError;
__exports__.CancellationError = CancellationError;
});
define("rsvp/config",
["rsvp/async","exports"],
function(__dependency1__, __exports__) {
"use strict";
var async = __dependency1__.async;
var config = {};
config.async = async;
__exports__.config = config;
});
define("rsvp/defer",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function defer() {
var deferred = {
// pre-allocate shape
resolve: undefined,
reject: undefined,
promise: undefined
};
deferred.promise = new Promise(function(resolve, reject) {
deferred.resolve = resolve;
deferred.reject = reject;
});
return deferred;
}
__exports__.defer = defer;
});
define("rsvp/events",
["exports"],
function(__exports__) {
"use strict";
var Event = function(type, options) {
this.type = type;
for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
this[option] = options[option];
}
};
var indexOf = function(callbacks, callback) {
for (var i=0, l=callbacks.length; i<l; i++) {
if (callbacks[i][0] === callback) { return i; }
}
return -1;
};
var callbacksFor = function(object) {
var callbacks = object._promiseCallbacks;
if (!callbacks) {
callbacks = object._promiseCallbacks = {};
}
return callbacks;
};
var EventTarget = {
mixin: function(object) {
object.on = this.on;
object.off = this.off;
object.trigger = this.trigger;
return object;
},
on: function(eventNames, callback, binding) {
var allCallbacks = callbacksFor(this), callbacks, eventName;
eventNames = eventNames.split(/\s+/);
binding = binding || this;
while (eventName = eventNames.shift()) {
callbacks = allCallbacks[eventName];
if (!callbacks) {
callbacks = allCallbacks[eventName] = [];
}
if (indexOf(callbacks, callback) === -1) {
callbacks.push([callback, binding]);
}
}
},
off: function(eventNames, callback) {
var allCallbacks = callbacksFor(this), callbacks, eventName, index;
eventNames = eventNames.split(/\s+/);
while (eventName = eventNames.shift()) {
if (!callback) {
allCallbacks[eventName] = [];
continue;
}
callbacks = allCallbacks[eventName];
index = indexOf(callbacks, callback);
if (index !== -1) { callbacks.splice(index, 1); }
}
},
trigger: function(eventName, options) {
var allCallbacks = callbacksFor(this),
callbacks, callbackTuple, callback, binding, event;
if (callbacks = allCallbacks[eventName]) {
// Don't cache the callbacks.length since it may grow
for (var i=0; i<callbacks.length; i++) {
callbackTuple = callbacks[i];
callback = callbackTuple[0];
binding = callbackTuple[1];
if (typeof options !== 'object') {
options = { detail: options };
}
event = new Event(eventName, options);
callback.call(binding, event);
}
}
}
};
__exports__.EventTarget = EventTarget;
});
define("rsvp/hash",
["rsvp/defer","exports"],
function(__dependency1__, __exports__) {
"use strict";
var defer = __dependency1__.defer;
function size(object) {
var s = 0;
for (var prop in object) {
s++;
}
return s;
}
function hash(promises) {
var results = {}, deferred = defer(), remaining = size(promises);
if (remaining === 0) {
deferred.resolve({});
}
var resolver = function(prop) {
return function(value) {
resolveAll(prop, value);
};
};
var resolveAll = function(prop, value) {
results[prop] = value;
if (--remaining === 0) {
deferred.resolve(results);
}
};
var rejectAll = function(error) {
deferred.reject(error);
};
for (var prop in promises) {
if (promises[prop] && typeof promises[prop].then === 'function') {
promises[prop].then(resolver(prop), rejectAll);
} else {
resolveAll(prop, promises[prop]);
}
}
return deferred.promise;
}
__exports__.hash = hash;
});
define("rsvp/node",
["rsvp/promise","rsvp/all","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
var all = __dependency2__.all;
function makeNodeCallbackFor(resolve, reject) {
return function (error, value) {
if (error) {
reject(error);
} else if (arguments.length > 2) {
resolve(Array.prototype.slice.call(arguments, 1));
} else {
resolve(value);
}
};
}
function denodeify(nodeFunc) {
return function() {
var nodeArgs = Array.prototype.slice.call(arguments), resolve, reject;
var thisArg = this;
var promise = new Promise(function(nodeResolve, nodeReject) {
resolve = nodeResolve;
reject = nodeReject;
});
all(nodeArgs).then(function(nodeArgs) {
nodeArgs.push(makeNodeCallbackFor(resolve, reject));
try {
nodeFunc.apply(thisArg, nodeArgs);
} catch(e) {
reject(e);
}
});
return promise;
};
}
__exports__.denodeify = denodeify;
});
define("rsvp/promise",
["rsvp/config","rsvp/events","rsvp/cancellation_error","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
"use strict";
var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget;
var CancellationError = __dependency3__.CancellationError;
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver, canceller) {
var promise = this,
resolved = false;
if (typeof resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
}
if ((canceller !== undefined) && (typeof canceller !== 'function')) {
throw new TypeError('You can only pass a canceller function' +
' as the second argument to the promise constructor');
}
if (!(promise instanceof Promise)) {
return new Promise(resolver, canceller);
}
var resolvePromise = function(value) {
if (resolved) { return; }
resolved = true;
resolve(promise, value);
};
var rejectPromise = function(value) {
if (resolved) { return; }
resolved = true;
reject(promise, value);
};
var notifyPromise = function(value) {
if (resolved) { return; }
notify(promise, value);
};
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
this.on('error', onerror);
this.cancel = function () {
// For now, simply reject the promise and does not propagate the cancel
// to parent or children
if (resolved) { return; }
if (canceller !== undefined) {
try {
canceller();
} catch (e) {
rejectPromise(e);
return;
}
}
// Trigger cancel?
rejectPromise(new CancellationError());
};
try {
resolver(resolvePromise, rejectPromise, notifyPromise);
} catch(e) {
rejectPromise(e);
}
};
function onerror(event) {
if (config.onerror) {
config.onerror(event.detail);
}
}
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (promise.isFulfilled) { return; }
if (promise.isRejected) { return; }
if (hasCallback) {
try {
value = callback(event.detail);
succeeded = true;
} catch(e) {
failed = true;
error = e;
}
} else {
value = event.detail;
succeeded = true;
}
if (handleThenable(promise, value)) {
return;
} else if (hasCallback && succeeded) {
resolve(promise, value);
} else if (failed) {
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
var invokeNotifyCallback = function(promise, callback, event) {
var value;
if (typeof callback === 'function') {
try {
value = callback(event.detail);
} catch (e) {
// stop propagating
return;
}
notify(promise, value);
} else {
notify(promise, event.detail);
}
};
Promise.prototype = {
constructor: Promise,
isRejected: undefined,
isFulfilled: undefined,
rejectedReason: undefined,
fulfillmentValue: undefined,
then: function(done, fail, progress) {
this.off('error', onerror);
var thenPromise = new this.constructor(function() {},
function () {
thenPromise.trigger('promise:cancelled', {});
});
if (this.isFulfilled) {
config.async(function(promise) {
invokeCallback('resolve', thenPromise, done, { detail: promise.fulfillmentValue });
}, this);
}
if (this.isRejected) {
config.async(function(promise) {
invokeCallback('reject', thenPromise, fail, { detail: promise.rejectedReason });
}, this);
}
this.on('promise:resolved', function(event) {
invokeCallback('resolve', thenPromise, done, event);
});
this.on('promise:failed', function(event) {
invokeCallback('reject', thenPromise, fail, event);
});
this.on('promise:notified', function (event) {
invokeNotifyCallback(thenPromise, progress, event);
});
return thenPromise;
},
fail: function(fail) {
return this.then(null, fail);
},
always: function(fail) {
return this.then(fail, fail);
}
};
EventTarget.mixin(Promise.prototype);
function resolve(promise, value) {
if (promise === value) {
fulfill(promise, value);
} else if (!handleThenable(promise, value)) {
fulfill(promise, value);
}
}
function handleThenable(promise, value) {
var then = null,
resolved;
try {
if (promise === value) {
throw new TypeError("A promises callback cannot return that same promise.");
}
if (objectOrFunction(value)) {
then = value.then;
if (isFunction(then)) {
if (isFunction(value.on)) {
value.on('promise:notified', function (event) {
notify(promise, event.detail);
});
}
promise.on('promise:cancelled', function(event) {
if (isFunction(value.cancel)) {
value.cancel();
}
});
then.call(value, function(val) {
if (resolved) { return true; }
resolved = true;
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
if (resolved) { return true; }
resolved = true;
reject(promise, val);
});
return true;
}
}
} catch (error) {
reject(promise, error);
return true;
}
return false;
}
function fulfill(promise, value) {
config.async(function() {
if (promise.isFulfilled) { return; }
if (promise.isRejected) { return; }
promise.trigger('promise:resolved', { detail: value });
promise.isFulfilled = true;
promise.fulfillmentValue = value;
});
}
function reject(promise, value) {
config.async(function() {
if (promise.isFulfilled) { return; }
if (promise.isRejected) { return; }
promise.trigger('promise:failed', { detail: value });
promise.isRejected = true;
promise.rejectedReason = value;
});
}
function notify(promise, value) {
config.async(function() {
promise.trigger('promise:notified', { detail: value });
});
}
__exports__.Promise = Promise;
});
define("rsvp/queue",
["rsvp/promise","rsvp/resolve","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
var resolve = __dependency2__.resolve;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
function ResolvedQueueError(message) {
this.name = "resolved";
if ((message !== undefined) && (typeof message !== "string")) {
throw new TypeError('You must pass a string.');
}
this.message = message || "Default Message";
}
ResolvedQueueError.prototype = new Error();
ResolvedQueueError.prototype.constructor = ResolvedQueueError;
var Queue = function() {
var queue = this,
promise_list = [],
promise,
fulfill,
reject,
notify,
resolved;
if (!(this instanceof Queue)) {
return new Queue();
}
function canceller() {
for (var i = 0; i < 2; i++) {
promise_list[i].cancel();
}
}
promise = new Promise(function(done, fail, progress) {
fulfill = function (fulfillmentValue) {
if (resolved) {return;}
queue.isFulfilled = true;
queue.fulfillmentValue = fulfillmentValue;
resolved = true;
return done(fulfillmentValue);
};
reject = function (rejectedReason) {
if (resolved) {return;}
queue.isRejected = true;
queue.rejectedReason = rejectedReason ;
resolved = true;
return fail(rejectedReason);
};
notify = progress;
}, canceller);
promise_list.push(resolve());
promise_list.push(promise_list[0].then(function () {
promise_list.splice(0, 2);
if (promise_list.length === 0) {
fulfill();
}
}));
queue.cancel = function () {
if (resolved) {return;}
resolved = true;
promise.cancel();
promise.fail(function (rejectedReason) {
queue.isRejected = true;
queue.rejectedReason = rejectedReason;
});
};
queue.then = function () {
return promise.then.apply(promise, arguments);
};
queue.push = function(done, fail, progress) {
var last_promise = promise_list[promise_list.length - 1],
next_promise;
if (resolved) {
throw new ResolvedQueueError();
}
next_promise = last_promise.then(done, fail, progress);
promise_list.push(next_promise);
// Handle pop
last_promise = next_promise.then(function (fulfillmentValue) {
promise_list.splice(0, 2);
if (promise_list.length === 0) {
fulfill(fulfillmentValue);
} else {
return fulfillmentValue;
}
}, function (rejectedReason) {
promise_list.splice(0, 2);
if (promise_list.length === 0) {
reject(rejectedReason);
} else {
throw rejectedReason;
}
}, function (notificationValue) {
if (promise_list[promise_list.length - 1] === last_promise) {
notify(notificationValue);
}
return notificationValue;
});
promise_list.push(last_promise);
return this;
};
};
Queue.prototype = Object.create(Promise.prototype);
Queue.prototype.constructor = Queue;
__exports__.Queue = Queue;
__exports__.ResolvedQueueError = ResolvedQueueError;
});
define("rsvp/reject",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function reject(reason) {
return new Promise(function (resolve, reject) {
reject(reason);
});
}
__exports__.reject = reject;
});
define("rsvp/resolve",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function resolve(thenable) {
return new Promise(function(resolve, reject) {
if (typeof thenable === "object" && thenable !== null) {
var then = thenable.then;
if ((then !== undefined) && (typeof then === "function")) {
return then.apply(thenable, [resolve, reject]);
}
}
return resolve(thenable);
}, function () {
if ((thenable !== undefined) && (thenable.cancel !== undefined)) {
thenable.cancel();
}
});
}
__exports__.resolve = resolve;
});
define("rsvp/rethrow",
["exports"],
function(__exports__) {
"use strict";
var local = (typeof global === "undefined") ? this : global;
function rethrow(reason) {
local.setTimeout(function() {
throw reason;
});
throw reason;
}
__exports__.rethrow = rethrow;
});
define("rsvp/timeout",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function promiseSetTimeout(millisecond, should_reject, message) {
var timeout_id;
function resolver(resolve, reject) {
timeout_id = setTimeout(function () {
if (should_reject) {
reject(message);
} else {
resolve(message);
}
}, millisecond);
}
function canceller() {
clearTimeout(timeout_id);
}
return new Promise(resolver, canceller);
}
function delay(millisecond, message) {
return promiseSetTimeout(millisecond, false, message);
}
function timeout(millisecond) {
return promiseSetTimeout(millisecond, true,
"Timed out after " + millisecond + " ms");
}
Promise.prototype.delay = function(millisecond) {
return this.then(function (fulfillmentValue) {
return delay(millisecond, fulfillmentValue);
});
};
__exports__.delay = delay;
__exports__.timeout = timeout;
});
define("rsvp",
["rsvp/events","rsvp/cancellation_error","rsvp/promise","rsvp/node","rsvp/all","rsvp/queue","rsvp/timeout","rsvp/hash","rsvp/rethrow","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) {
"use strict";
var EventTarget = __dependency1__.EventTarget;
var CancellationError = __dependency2__.CancellationError;
var Promise = __dependency3__.Promise;
var denodeify = __dependency4__.denodeify;
var all = __dependency5__.all;
var any = __dependency5__.any;
var Queue = __dependency6__.Queue;
var ResolvedQueueError = __dependency6__.ResolvedQueueError;
var delay = __dependency7__.delay;
var timeout = __dependency7__.timeout;
var hash = __dependency8__.hash;
var rethrow = __dependency9__.rethrow;
var defer = __dependency10__.defer;
var config = __dependency11__.config;
var resolve = __dependency12__.resolve;
var reject = __dependency13__.reject;
function configure(name, value) {
config[name] = value;
}
__exports__.CancellationError = CancellationError;
__exports__.Promise = Promise;
__exports__.EventTarget = EventTarget;
__exports__.all = all;
__exports__.any = any;
__exports__.Queue = Queue;
__exports__.ResolvedQueueError = ResolvedQueueError;
__exports__.delay = delay;
__exports__.timeout = timeout;
__exports__.hash = hash;
__exports__.rethrow = rethrow;
__exports__.defer = defer;
__exports__.denodeify = denodeify;
__exports__.configure = configure;
__exports__.resolve = resolve;
__exports__.reject = reject;
});
window.RSVP = requireModule("rsvp");
})(window);
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment