@progress/kendo-spreadsheet-common 1.1.3-develop.1 → 1.1.3-develop.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index-esm.js CHANGED
@@ -1165,66 +1165,36 @@ function withExit(f, obj) {
1165
1165
  }
1166
1166
  }
1167
1167
 
1168
- const wrapExpression = function(members, paramName) {
1169
- let result = paramName || "d",
1170
- index,
1171
- idx,
1172
- length,
1173
- member,
1174
- count = 1;
1175
-
1176
- for (idx = 0, length = members.length; idx < length; idx++) {
1177
- member = members[idx];
1178
- if (member !== "") {
1179
- index = member.indexOf("[");
1180
-
1181
- if (index !== 0) {
1182
- if (index === -1) {
1183
- member = "." + member;
1184
- } else {
1185
- count++;
1186
- member = "." + member.substring(0, index) + " || {})" + member.substring(index);
1187
- }
1188
- }
1189
-
1190
- count++;
1191
- result += member + ((idx < length - 1) ? " || {})" : ")");
1192
- }
1193
- }
1194
- return new Array(count).join("(") + result;
1195
- };
1196
-
1197
1168
  const getterCache = {};
1198
1169
 
1199
- function expr(expression, safe, paramName) {
1200
- expression = expression || "";
1201
-
1202
- if (typeof safe == 'string') {
1203
- paramName = safe;
1204
- safe = false;
1205
- }
1170
+ getterCache["undefined"] = (obj) => obj;
1206
1171
 
1207
- paramName = paramName || "d";
1172
+ const FIELD_REGEX = /\[(?:(\d+)|['"](.*?)['"])\]|((?:(?!\[.*?\]|\.).)+)/g;
1173
+ function getter(field, safe) {
1174
+ const key = field + safe;
1208
1175
 
1209
- if (expression && expression.charAt(0) !== "[") {
1210
- expression = "." + expression;
1176
+ if (getterCache[key]) {
1177
+ return getterCache[key];
1211
1178
  }
1212
1179
 
1213
- if (safe) {
1214
- expression = expression.replace(/"([^.]*)\.([^"]*)"/g,'"$1_$DOT$_$2"');
1215
- expression = expression.replace(/'([^.]*)\.([^']*)'/g,"'$1_$DOT$_$2'");
1216
- expression = wrapExpression(expression.split("."), paramName);
1217
- expression = expression.replace(/_\$DOT\$_/g, ".");
1218
- } else {
1219
- expression = paramName + expression;
1220
- }
1180
+ const fields = [];
1181
+ field.replace(FIELD_REGEX, (_, index, indexAccessor, field) => {
1182
+ fields.push(isPresent(index) ? index : indexAccessor || field);
1183
+ return undefined;
1184
+ });
1221
1185
 
1222
- return expression;
1223
- }
1186
+ getterCache[key] = (obj) => {
1187
+ let result = obj;
1188
+ for (let idx = 0; idx < fields.length; idx++) {
1189
+ result = result[fields[idx]];
1190
+ if (!isPresent(result) && safe) {
1191
+ return result;
1192
+ }
1193
+ }
1194
+
1195
+ return result;
1196
+ };
1224
1197
 
1225
- function getter(expression, safe) {
1226
- let key = expression + safe;
1227
- getterCache[key] = getterCache[key] || new Function("d", "return " + expr(expression, safe));
1228
1198
  return getterCache[key];
1229
1199
  }
1230
1200
 
@@ -1239,10 +1209,6 @@ function deepExtend(destination) {
1239
1209
  return destination;
1240
1210
  }
1241
1211
 
1242
- function isFunction(fn) {
1243
- return typeof fn === "function";
1244
- }
1245
-
1246
1212
  function deepExtendOne(destination, source) {
1247
1213
  let property,
1248
1214
  propValue,
@@ -1316,7 +1282,12 @@ const scrollbar = function(refresh) {
1316
1282
  let div = document.createElement("div"),
1317
1283
  result;
1318
1284
 
1319
- div.style.cssText = "overflow:scroll;overflow-x:hidden;zoom:1;clear:both;display:block";
1285
+ div.style.overflow = "scroll";
1286
+ div.style.overflowX = "hidden";
1287
+ div.style.zoom = "1";
1288
+ div.style.clear = "both";
1289
+ div.style.display = "block";
1290
+
1320
1291
  div.innerHTML = "&nbsp;";
1321
1292
  document.body.appendChild(div);
1322
1293
 
@@ -1391,6 +1362,13 @@ const _activeElement$1 = function() {
1391
1362
  }
1392
1363
  };
1393
1364
 
1365
+ const isPresent = (value) => value !== null && value !== undefined;
1366
+ const isBlank = (value) => !isPresent(value);
1367
+ const isDate = (value) => value && value.getTime;
1368
+ const isString = (value) => typeof value === "string";
1369
+ const isNumeric = (value) => !isNaN(value - parseFloat(value));
1370
+ const isFunction = (fn) => typeof fn === "function";
1371
+
1394
1372
  class CalcError {
1395
1373
 
1396
1374
  constructor(code) {
@@ -2485,13 +2463,13 @@ function compileArgumentChecks(functionName, args) {
2485
2463
  }
2486
2464
  }
2487
2465
 
2488
- function limitPrecision$1(num) {
2489
- return num === parseInt(num, 10) ? num : +num.toPrecision(16);
2466
+ function limitPrecision$1(num, digits) {
2467
+ return num === parseInt(num, 10) ? num : +num.toPrecision(digits || 16);
2490
2468
  }
2491
2469
 
2492
- function maybeRoundFloatErrors(num) {
2470
+ function maybeRoundFloatErrors(num, digits) {
2493
2471
  if (typeof num == "number") {
2494
- return limitPrecision$1(num);
2472
+ return limitPrecision$1(num, digits);
2495
2473
  } else {
2496
2474
  return num;
2497
2475
  }
@@ -5650,6 +5628,10 @@ class FormulaContext {
5650
5628
  // try global name
5651
5629
  val = this.workbook.nameValue(this._displayString(ref.name));
5652
5630
  }
5631
+ if (val == null) {
5632
+ // try without _displayString
5633
+ val = this.workbook.nameValue(ref.print()) || this.workbook.nameValue(ref.name);
5634
+ }
5653
5635
  }
5654
5636
  if (val instanceof Ref) {
5655
5637
  val = val.absolute(frow, fcol);
@@ -8868,6 +8850,7 @@ let Range$1 = class Range {
8868
8850
  sheet._set(ref, propName, propValue);
8869
8851
  };
8870
8852
 
8853
+ let isValue = false;
8871
8854
  for (ci = topLeftCol; ci <= bottomRightCol; ci ++) {
8872
8855
  if (!isAutofill && sheet.isHiddenColumn(ci)) {
8873
8856
  continue;
@@ -8883,12 +8866,14 @@ let Range$1 = class Range {
8883
8866
  if (row) {
8884
8867
  data = row[ci - topLeftCol];
8885
8868
  if (data) {
8886
- Object.keys(data).forEach(setProp);
8869
+ const keys = Object.keys(data);
8870
+ keys.forEach(setProp);
8871
+ isValue = isValue || keys.includes("value");
8887
8872
  }
8888
8873
  }
8889
8874
  }
8890
8875
  }
8891
- sheet.triggerChange({ recalc: true, ref: this._ref });
8876
+ sheet.triggerChange({ recalc: true, ref: this._ref, isValue: isValue });
8892
8877
  return this;
8893
8878
  }
8894
8879
  }
@@ -8901,7 +8886,8 @@ let Range$1 = class Range {
8901
8886
 
8902
8887
  let reason = {
8903
8888
  recalc: clearAll || options.contentsOnly,
8904
- ref: this._ref
8889
+ ref: this._ref,
8890
+ isValue: true
8905
8891
  };
8906
8892
 
8907
8893
  sheet.batch(function() {
@@ -9398,13 +9384,18 @@ function looksLikeANumber(str) {
9398
9384
 
9399
9385
  function getTextHeight(text, width, fontFamily, fontSize, wrap) {
9400
9386
  const measureBox = document.createElement("div");
9401
- measureBox.setAttribute(
9402
- "style",
9403
- "position: absolute !important; top: -4000px !important; height: auto !important;" +
9404
- "padding: 1px 3px !important; box-sizing: border-box; margin: 0 !important; border: 1px solid black !important;" +
9405
- "line-height: normal !important; visibility: hidden !important;" +
9406
- "white-space: pre-wrap;"
9407
- );
9387
+
9388
+ measureBox.style.setProperty('position', 'absolute', 'important');
9389
+ measureBox.style.setProperty('top', '-4000px', 'important');
9390
+ measureBox.style.setProperty('height', 'auto', 'important');
9391
+ measureBox.style.setProperty('padding', '1px 3px', 'important');
9392
+ measureBox.style.setProperty('box-sizing', 'border-box', 'important');
9393
+ measureBox.style.setProperty('margin', '0', 'important');
9394
+ measureBox.style.setProperty('border', '1px solid black', 'important');
9395
+ measureBox.style.setProperty('line-height', 'normal', 'important');
9396
+ measureBox.style.setProperty('visibility', 'hidden', 'important');
9397
+ measureBox.style.setProperty('white-space', 'pre-wrap');
9398
+
9408
9399
  let styles = {
9409
9400
  "baselineMarkerSize" : 0,
9410
9401
  "width" : (wrap === true) ? width + "px" : "auto",
@@ -12119,210 +12110,131 @@ const kendoDate = (function() {
12119
12110
 
12120
12111
  /* eslint-disable no-var */
12121
12112
 
12122
- const dateRegExp = /^\/Date\((.*?)\)\/$/;
12113
+ const logic = {
12114
+ or: {
12115
+ concat: (acc, fn) => (a) => acc(a) || fn(a),
12116
+ identity: () => false,
12117
+ },
12118
+ and: {
12119
+ concat: (acc, fn) => (a) => acc(a) && fn(a),
12120
+ identity: () => true,
12121
+ },
12122
+ };
12123
+
12124
+ const operatorsMap = {
12125
+ contains: (a, b) => (a || "").indexOf(b) >= 0,
12126
+ doesnotcontain: (a, b) => (a || "").indexOf(b) === -1,
12127
+ doesnotendwith: (a, b) =>
12128
+ (a || "").indexOf(b, (a || "").length - (b || "").length) < 0,
12129
+ doesnotstartwith: (a, b) => (a || "").lastIndexOf(b, 0) === -1,
12130
+ endswith: (a, b) =>
12131
+ (a || "").indexOf(b, (a || "").length - (b || "").length) >= 0,
12132
+ eq: (a, b) => a === b,
12133
+ gt: (a, b) => a > b,
12134
+ gte: (a, b) => a >= b,
12135
+ isempty: (a) => a === "",
12136
+ isnotempty: (a) => a !== "",
12137
+ isnotnull: (a) => isPresent(a),
12138
+ isnull: (a) => isBlank(a),
12139
+ lt: (a, b) => a < b,
12140
+ lte: (a, b) => a <= b,
12141
+ neq: (a, b) => a != b, // tslint:disable-line:triple-equals
12142
+ startswith: (a, b) => (a || "").lastIndexOf(b, 0) === 0,
12143
+ };
12123
12144
 
12124
- var operators = (function() {
12145
+ const dateRegExp = /^\/Date\((.*?)\)\/$/;
12125
12146
 
12126
- function quote(str) {
12127
- if (typeof str == "string") {
12128
- str = str.replace(/[\r\n]+/g, "");
12147
+ const convertValue = (value, ignoreCase, accentFoldingFiltering) => {
12148
+ if (value != null && isString(value)) {
12149
+ const date = dateRegExp.exec(value);
12150
+ if (date) {
12151
+ return new Date(+date[1]).getTime();
12152
+ } else if (ignoreCase) {
12153
+ return accentFoldingFiltering
12154
+ ? value.toLocaleLowerCase(accentFoldingFiltering)
12155
+ : value.toLowerCase();
12129
12156
  }
12130
- return JSON.stringify(str);
12157
+ } else if (value != null && isDate(value)) {
12158
+ return value.getTime();
12131
12159
  }
12160
+ return value;
12161
+ };
12132
12162
 
12133
- function textOp(impl) {
12134
- return function(a, b, ignore, accentFoldingFiltering) {
12135
- b += "";
12136
- if (ignore) {
12137
- a = "(" + a + " + '').toString()" + ((accentFoldingFiltering) ? ".toLocaleLowerCase('" + accentFoldingFiltering + "')" : ".toLowerCase()");
12138
- b = ((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase());
12139
- }
12140
- return impl(a, quote(b), ignore);
12141
- };
12142
- }
12163
+ const transformFilter = ({
12164
+ field,
12165
+ ignoreCase,
12166
+ value,
12167
+ operator,
12168
+ accentFoldingFiltering,
12169
+ }) => {
12170
+ field = !isPresent(field) ? (a) => a : field;
12171
+
12172
+ ignoreCase = isPresent(ignoreCase) ? ignoreCase : true;
12173
+
12174
+ const itemProp = typedGetter(
12175
+ isFunction(field) ? field : getter(field, true),
12176
+ value,
12177
+ ignoreCase,
12178
+ accentFoldingFiltering
12179
+ );
12143
12180
 
12144
- function operator(op, a, b, ignore, accentFoldingFiltering) {
12145
- if (b != null) {
12146
- if (typeof b === 'string') {
12147
- var date = dateRegExp.exec(b);
12148
- if (date) {
12149
- b = new Date(+date[1]);
12150
- } else if (ignore) {
12151
- b = quote(((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase()));
12152
- a = "((" + a + " || '')+'')" + ((accentFoldingFiltering) ? ".toLocaleLowerCase('" + accentFoldingFiltering + "')" : ".toLowerCase()");
12153
- } else {
12154
- b = quote(b);
12155
- }
12156
- }
12181
+ value = convertValue(value, ignoreCase, accentFoldingFiltering);
12157
12182
 
12158
- if (b.getTime) {
12159
- //b looks like a Date
12160
- a = "(" + a + "&&" + a + ".getTime?" + a + ".getTime():" + a + ")";
12161
- b = b.getTime();
12162
- }
12163
- }
12183
+ const op = isFunction(operator) ? operator : operatorsMap[operator];
12164
12184
 
12165
- return a + " " + op + " " + b;
12166
- }
12185
+ return (a) => op(itemProp(a), value, ignoreCase);
12186
+ };
12167
12187
 
12168
- function getMatchRegexp(pattern) {
12169
- // take a pattern, as supported by Excel match filter, and
12170
- // convert it to the equivalent JS regular expression.
12171
- // Excel patterns support:
12172
- //
12173
- // * - match any sequence of characters
12174
- // ? - match a single character
12175
- //
12176
- // to match a literal * or ?, they must be prefixed by a tilde (~)
12177
- var rx = "/^";
12178
- for (var esc = false, i = 0; i < pattern.length; ++i) {
12179
- var ch = pattern.charAt(i);
12180
- if (esc) {
12181
- rx += "\\" + ch;
12182
- } else if (ch === "~") {
12183
- esc = true;
12184
- continue;
12185
- } else if (ch === "*") {
12186
- rx += ".*";
12187
- } else if (ch === "?") {
12188
- rx += ".";
12189
- } else if (".+^$()[]{}|\\/\n\r\u2028\u2029\xA0".indexOf(ch) >= 0) {
12190
- rx += "\\" + ch;
12191
- } else {
12192
- rx += ch;
12193
- }
12194
- esc = false;
12195
- }
12196
- return rx + "$/";
12188
+ const typedGetter = (prop, value, ignoreCase, accentFoldingFiltering) => {
12189
+ if (!isPresent(value)) {
12190
+ return prop;
12197
12191
  }
12198
12192
 
12199
- return {
12200
- quote: function(value) {
12201
- if (value && value.getTime) {
12202
- return "new Date(" + value.getTime() + ")";
12203
- }
12204
- return quote(value);
12205
- },
12206
- eq: function(a, b, ignore, accentFoldingFiltering) {
12207
- return operator("==", a, b, ignore, accentFoldingFiltering);
12208
- },
12209
- neq: function(a, b, ignore, accentFoldingFiltering) {
12210
- return operator("!=", a, b, ignore, accentFoldingFiltering);
12211
- },
12212
- gt: function(a, b, ignore) {
12213
- return operator(">", a, b, ignore);
12214
- },
12215
- gte: function(a, b, ignore) {
12216
- return operator(">=", a, b, ignore);
12217
- },
12218
- lt: function(a, b, ignore) {
12219
- return operator("<", a, b, ignore);
12220
- },
12221
- lte: function(a, b, ignore) {
12222
- return operator("<=", a, b, ignore);
12223
- },
12224
- startswith: textOp(function(a, b) {
12225
- return a + ".lastIndexOf(" + b + ", 0) == 0";
12226
- }),
12227
- doesnotstartwith: textOp(function(a, b) {
12228
- return a + ".lastIndexOf(" + b + ", 0) == -1";
12229
- }),
12230
- endswith: textOp(function(a, b) {
12231
- var n = b ? b.length - 2 : 0;
12232
- return a + ".indexOf(" + b + ", " + a + ".length - " + n + ") >= 0";
12233
- }),
12234
- doesnotendwith: textOp(function(a, b) {
12235
- var n = b ? b.length - 2 : 0;
12236
- return a + ".indexOf(" + b + ", " + a + ".length - " + n + ") < 0";
12237
- }),
12238
- contains: textOp(function(a, b) {
12239
- return a + ".indexOf(" + b + ") >= 0";
12240
- }),
12241
- doesnotcontain: textOp(function(a, b) {
12242
- return a + ".indexOf(" + b + ") == -1";
12243
- }),
12244
- matches: textOp(function(a, b) {
12245
- b = b.substring(1, b.length - 1);
12246
- return getMatchRegexp(b) + ".test(" + a + ")";
12247
- }),
12248
- doesnotmatch: textOp(function(a, b) {
12249
- b = b.substring(1, b.length - 1);
12250
- return "!" + getMatchRegexp(b) + ".test(" + a + ")";
12251
- }),
12252
- isempty: function(a) {
12253
- return a + " === ''";
12254
- },
12255
- isnotempty: function(a) {
12256
- return a + " !== ''";
12257
- },
12258
- isnull: function(a) {
12259
- return "(" + a + " == null)";
12260
- },
12261
- isnotnull: function(a) {
12262
- return "(" + a + " != null)";
12263
- },
12264
- isnullorempty: function(a) {
12265
- return "(" + a + " === null) || (" + a + " === '')";
12266
- },
12267
- isnotnullorempty: function(a) {
12268
- return "(" + a + " !== null) && (" + a + " !== '')";
12269
- }
12270
- };
12271
- })();
12272
-
12273
- const filterExpr = function(expression) {
12274
- var expressions = [],
12275
- logic = { and: " && ", or: " || " },
12276
- idx,
12277
- length,
12278
- filter,
12279
- expr$1,
12280
- fieldFunctions = [],
12281
- operatorFunctions = [],
12282
- field,
12283
- operator,
12284
- filters = expression.filters;
12285
-
12286
- for (idx = 0, length = filters.length; idx < length; idx++) {
12287
- filter = filters[idx];
12288
- field = filter.field;
12289
- operator = filter.operator;
12290
-
12291
- if (filter.filters) {
12292
- expr$1 = filterExpr(filter);
12293
- //Nested function fields or operators - update their index e.g. __o[0] -> __o[1]
12294
- filter = expr$1.expression
12295
- .replace(/__o\[(\d+)\]/g, function(match, index) {
12296
- index = +index;
12297
- return "__o[" + (operatorFunctions.length + index) + "]";
12298
- })
12299
- .replace(/__f\[(\d+)\]/g, function(match, index) {
12300
- index = +index;
12301
- return "__f[" + (fieldFunctions.length + index) + "]";
12302
- });
12193
+ let acc = prop;
12303
12194
 
12304
- operatorFunctions.push.apply(operatorFunctions, expr$1.operators);
12305
- fieldFunctions.push.apply(fieldFunctions, expr$1.fields);
12195
+ if (isString(value)) {
12196
+ const date = dateRegExp.exec(value);
12197
+ if (date) {
12198
+ value = new Date(+date[1]);
12306
12199
  } else {
12307
- if (typeof field === 'function') {
12308
- expr$1 = "__f[" + fieldFunctions.length + "](d)";
12309
- fieldFunctions.push(field);
12310
- } else {
12311
- expr$1 = expr(field);
12312
- }
12313
-
12314
- if (typeof operator === 'function') {
12315
- filter = "__o[" + operatorFunctions.length + "](" + expr$1 + ", " + operators.quote(filter.value) + ")";
12316
- operatorFunctions.push(operator);
12317
- } else {
12318
- filter = operators[(operator || "eq").toLowerCase()](expr$1, filter.value, filter.ignoreCase !== undefined ? filter.ignoreCase : true, expression.accentFoldingFiltering);
12319
- }
12200
+ acc = (a) => {
12201
+ const x = prop(a);
12202
+ if (typeof x === "string" && ignoreCase) {
12203
+ return accentFoldingFiltering
12204
+ ? x.toLocaleLowerCase(accentFoldingFiltering)
12205
+ : x.toLowerCase();
12206
+ } else {
12207
+ return isNumeric(x) ? x + "" : x;
12208
+ }
12209
+ };
12320
12210
  }
12211
+ }
12321
12212
 
12322
- expressions.push(filter);
12213
+ if (isDate(value)) {
12214
+ return (a) => {
12215
+ const x = acc(a);
12216
+ return isDate(x) ? x.getTime() : x;
12217
+ };
12323
12218
  }
12219
+ return acc;
12220
+ };
12324
12221
 
12325
- return { expression: "(" + expressions.join(logic[expression.logic]) + ")", fields: fieldFunctions, operators: operatorFunctions };
12222
+ const transformCompositeFilter = function (filter) {
12223
+ const accentFoldingFiltering = filter.accentFoldingFiltering;
12224
+ const combiner = logic[filter.logic || "and"];
12225
+
12226
+ return filter.filters
12227
+ .filter(isPresent)
12228
+ .map((x) => {
12229
+ const extendedFilter = isPresent(accentFoldingFiltering)
12230
+ ? deepExtend({}, x, { accentFoldingFiltering })
12231
+ : x;
12232
+
12233
+ return isPresent(x.filters)
12234
+ ? transformCompositeFilter(extendedFilter)
12235
+ : transformFilter(extendedFilter);
12236
+ })
12237
+ .reduce(combiner.concat, combiner.identity);
12326
12238
  };
12327
12239
 
12328
12240
  /* eslint-disable max-params */
@@ -12437,13 +12349,11 @@ class CustomFilter extends Filter {
12437
12349
 
12438
12350
  this._criteria = options.criteria;
12439
12351
 
12440
- var expression = filterExpr({
12352
+ this._matches = transformCompositeFilter({
12441
12353
  logic: this._logic,
12442
12354
  filters: this._criteria,
12443
- accentFoldingFiltering: culture().name
12444
- }).expression;
12445
-
12446
- this._matches = new Function("d", "return " + expression);
12355
+ accentFoldingFiltering: culture().name,
12356
+ });
12447
12357
  }
12448
12358
  matches(value) {
12449
12359
  if (value === null) {
@@ -16172,7 +16082,7 @@ function drawCell(collection, cell, cls, showGrid) {
16172
16082
  if (data.__dataType) {
16173
16083
  type = data.__dataType;
16174
16084
  }
16175
- } else if (data !== null && data !== undefined) {
16085
+ } else if (data != null) {
16176
16086
  if (cell.html) {
16177
16087
  data = dom.html(data);
16178
16088
  } else {
@@ -16207,6 +16117,17 @@ function drawCell(collection, cell, cls, showGrid) {
16207
16117
  }
16208
16118
  if (cell.merged) {
16209
16119
  classNames.push("k-spreadsheet-merged-cell");
16120
+ if (!cell.enable) {
16121
+ collection.push(dom.element("div", {
16122
+ className: "k-spreadsheet-disabled-mask",
16123
+ style: {
16124
+ left: (cell.left + 1) + "px",
16125
+ top: (cell.top + 1) + "px",
16126
+ width: (cell.width - 1) + "px",
16127
+ height: (cell.height - 1) + "px"
16128
+ }
16129
+ }));
16130
+ }
16210
16131
  }
16211
16132
  if (cell.comment) {
16212
16133
  classNames.push("k-spreadsheet-has-comment");
@@ -17008,24 +16929,9 @@ class FormulaInput extends Widget {
17008
16929
  end = begin;
17009
16930
  }
17010
16931
  if (begin && end) {
17011
- let range = document.createRange();
17012
- range.setStart(begin.node, begin.pos);
17013
- range.setEnd(end.node, end.pos);
17014
- let sel = window.getSelection();
17015
- let currentRange = sel.getRangeAt(0);
17016
- if (differ(range, currentRange)) {
17017
- sel.removeAllRanges();
17018
- sel.addRange(range);
17019
- }
17020
- }
17021
- function differ(a, b) {
17022
- return (
17023
- a.startOffset !== b.startOffset ||
17024
- a.endOffset !== b.endOffset ||
17025
- a.startContainer !== b.endContainer ||
17026
- a.endContainer !== b.endContainer
17027
- );
16932
+ this._setRange(begin, end);
17028
16933
  }
16934
+
17029
16935
  function lookup(node, pos) {
17030
16936
  try {
17031
16937
  (function loop(node) {
@@ -17063,6 +16969,27 @@ class FormulaInput extends Widget {
17063
16969
  return this.value().length;
17064
16970
  }
17065
16971
 
16972
+ _setRange(begin, end) {
16973
+ let range = document.createRange();
16974
+ range.setStart(begin.node, begin.pos);
16975
+ range.setEnd(end.node, end.pos);
16976
+ let sel = window.getSelection();
16977
+ let currentRange = sel.getRangeAt(0);
16978
+ if (differ(range, currentRange)) {
16979
+ sel.removeAllRanges();
16980
+ sel.addRange(range);
16981
+ }
16982
+
16983
+ function differ(a, b) {
16984
+ return (
16985
+ a.startOffset !== b.startOffset ||
16986
+ a.endOffset !== b.endOffset ||
16987
+ a.startContainer !== b.endContainer ||
16988
+ a.endContainer !== b.endContainer
16989
+ );
16990
+ }
16991
+ }
16992
+
17066
16993
  _formulaSource() {
17067
16994
  let result = [];
17068
16995
  let value;
@@ -17813,27 +17740,43 @@ function addCell(table, row, cell) {
17813
17740
  }
17814
17741
  }
17815
17742
 
17743
+ let attrs = { style: style };
17744
+
17816
17745
  if (!style.textAlign) {
17817
17746
  switch (type) {
17818
- case "number":
17819
- case "date":
17820
- case "percent":
17821
- case "currency":
17822
- style.textAlign = "right";
17823
- break;
17824
- case "boolean":
17825
- style.textAlign = "center";
17747
+ case "number":
17748
+ case "date":
17749
+ case "percent":
17750
+ case "currency":
17751
+ style.textAlign = "right";
17752
+ break;
17753
+ case "boolean":
17754
+ style.textAlign = "center";
17826
17755
  break;
17827
17756
  }
17828
17757
  }
17829
17758
 
17759
+ if (!/^(?:string|undefined)$/.test(type)) {
17760
+ // provide original value and number format for better
17761
+ // interoperability with google sheets and libre office.
17762
+ attrs.sdval = cell.value;
17763
+ attrs["data-sheets-value"] = JSON.stringify({ 1: 3, 3: cell.value });
17764
+ if (format) {
17765
+ attrs.sdnum = format;
17766
+ attrs["data-sheets-numberformat"] = JSON.stringify({ 1: 2, 2: format, 3: 1 });
17767
+ }
17768
+ }
17769
+ if (cell.formula) {
17770
+ attrs["data-sheets-formula"] = "=" + cell.formula.print();
17771
+ }
17772
+
17830
17773
  let className = null;
17831
17774
 
17832
17775
  if (cell.enable === false) {
17833
17776
  className = "k-disabled";
17834
17777
  }
17835
17778
 
17836
- let td = table.addCell(row, data, style, className, cell.validation);
17779
+ let td = table.addCell(row, data, attrs, className, cell.validation);
17837
17780
 
17838
17781
  let border, sibling;
17839
17782
 
@@ -17892,7 +17835,7 @@ class HtmlTable {
17892
17835
  this.trs.push(tr);
17893
17836
  }
17894
17837
 
17895
- addCell(rowIndex, text, style, className, validation) {
17838
+ addCell(rowIndex, text, attrs, className, validation) {
17896
17839
  if (text === null || text === undefined) {
17897
17840
  text = "";
17898
17841
  }
@@ -17901,19 +17844,18 @@ class HtmlTable {
17901
17844
  }
17902
17845
 
17903
17846
  let children = [ text ];
17904
- let properties = { style: style };
17905
17847
 
17906
17848
  if (validation && !validation.value) {
17907
17849
  children.push(dom.element("span", { className: "k-dirty" }));
17908
17850
 
17909
17851
  className = (className || "") + (className ? " " : "") + "k-dirty-cell";
17910
- properties.title = validation.message;
17852
+ attrs.title = validation.message;
17911
17853
  }
17912
17854
 
17913
17855
  if (className) {
17914
- properties.className = className;
17856
+ attrs.className = className;
17915
17857
  }
17916
- let td = dom.element("td", properties, children);
17858
+ let td = dom.element("td", attrs, children);
17917
17859
 
17918
17860
  this.trs[rowIndex].children.push(td);
17919
17861
  return td;
@@ -18906,7 +18848,13 @@ function stripStyle(style) {
18906
18848
  return style.replace(/^-(?:ms|moz|webkit)-/, "");
18907
18849
  }
18908
18850
 
18909
- function borderObject(styles) {
18851
+ function borderObject(element, styles) {
18852
+ // MS Office uses class name and writes borders in the <style> section, so for it we need to
18853
+ // use the computed styles. For Google Sheets / LibreOffice, however, the inline styles are
18854
+ // more accurate.
18855
+ if (!element.className) {
18856
+ styles = element.style;
18857
+ }
18910
18858
  let obj = {};
18911
18859
  [
18912
18860
  "borderBottom",
@@ -18914,16 +18862,45 @@ function borderObject(styles) {
18914
18862
  "borderLeft",
18915
18863
  "borderTop"
18916
18864
  ].forEach(function(key) {
18917
- obj[key] = styles[key + "Style"] === "none" ? null : {
18918
- size: 1,
18919
- color: styles[key + "Color"]
18920
- };
18865
+ let width = styles[key + "Width"];
18866
+ if (width) {
18867
+ width = parseInt(width, 10);
18868
+ }
18869
+ if (width) {
18870
+ obj[key] = {
18871
+ size: width,
18872
+ color: styles[key + "Color"] || "#000"
18873
+ };
18874
+ }
18921
18875
  });
18922
18876
  return obj;
18923
18877
  }
18924
18878
 
18925
18879
  function cellState(row, col, element, hBorders, vBorders) {
18926
18880
  let styles = window.getComputedStyle(element);
18881
+ let value, format, formula;
18882
+
18883
+ // google sheets
18884
+ if ((value = element.getAttribute("data-sheets-value"))) {
18885
+ value = JSON.parse(value);
18886
+ value = value[value[1]];
18887
+ }
18888
+ if ((format = element.getAttribute("data-sheets-numberformat"))) {
18889
+ format = JSON.parse(format);
18890
+ format = format[format[1]];
18891
+ }
18892
+ formula = element.getAttribute("data-sheets-formula");
18893
+
18894
+ // libre office
18895
+ if (value == null && format == null && formula == null) {
18896
+ value = element.getAttribute("sdval");
18897
+ format = element.getAttribute("sdnum");
18898
+ if (format) {
18899
+ // for ungoogable reasons, libreoffice prepends format strings with
18900
+ // "1033;" and sometimes with "1033;0;". discard it below.
18901
+ format = format.replace(/^1033;(?:0;)?/, "");
18902
+ }
18903
+ }
18927
18904
 
18928
18905
  // note: Chrome 70 appends a \t to a cell's text, which is actually mandated by the standard
18929
18906
  // ([1] item 6). We remove it below. In [2] it's suggested they might switch back to
@@ -18931,49 +18908,62 @@ function cellState(row, col, element, hBorders, vBorders) {
18931
18908
  //
18932
18909
  // [1] https://www.w3.org/TR/html53/dom.html#dom-htmlelement-innertext
18933
18910
  // [2] https://bugs.chromium.org/p/chromium/issues/detail?id=897373
18934
- let text = (element.innerText || element.textContent).replace(/\t$/, "");
18911
+ if (value == null) {
18912
+ value = (element.innerText || element.textContent).replace(/\t$/, "");
18913
+ }
18935
18914
 
18936
- let borders = borderObject(styles);
18915
+ let borders = borderObject(element, styles);
18937
18916
  let state = {
18938
- value: text === "" ? null : text,
18917
+ value: value === "" ? null : value,
18918
+ formula: formula,
18939
18919
 
18940
18920
  borderTop: borders.borderTop || hBorders.get(row, col) || null,
18941
18921
  borderBottom: borders.borderBottom || hBorders.get(row + 1, col) || null,
18942
18922
  borderLeft: borders.borderLeft || vBorders.get(row, col) || null,
18943
18923
  borderRight: borders.borderRight || vBorders.get(row, col + 1) || null,
18944
18924
 
18945
- fontSize: parseInt(styles["font-size"], 10)
18925
+ fontSize: parseInt(styles["fontSize"], 10)
18946
18926
  };
18947
18927
 
18928
+ if (format != null) {
18929
+ state.format = format;
18930
+ }
18931
+
18948
18932
  hBorders.set(row, col, state.borderTop);
18949
18933
  hBorders.set(row + 1, col, state.borderBottom);
18950
18934
  vBorders.set(row, col, state.borderLeft);
18951
18935
  vBorders.set(row, col + 1, state.borderRight);
18952
18936
 
18953
- if (styles["background-color"] !== "rgb(0, 0, 0)" && styles["background-color"] !== "rgba(0, 0, 0, 0)") {
18954
- state.background = styles["background-color"];
18937
+ if (styles["backgroundColor"] !== "rgb(0, 0, 0)" && styles["backgroundColor"] !== "rgba(0, 0, 0, 0)") {
18938
+ state.background = styles["backgroundColor"];
18955
18939
  }
18940
+ if (stripStyle(styles["textAlign"]) !== "right") {
18941
+ state.textAlign = stripStyle(styles["textAlign"]);
18942
+ }
18943
+ if (styles["verticalAlign"] !== "middle") {
18944
+ state.verticalAlign = styles["verticalAlign"];
18945
+ }
18946
+ if (styles["wordWrap"] !== "normal" ) {
18947
+ state.wrap = true;
18948
+ }
18949
+
18950
+ const txtElem = element.querySelector("font"); // libre office
18951
+ if (txtElem) {
18952
+ styles = window.getComputedStyle(txtElem);
18953
+ }
18954
+
18956
18955
  if (styles.color !== "rgb(0, 0, 0)" && styles.color !== "rgba(0, 0, 0, 0)") {
18957
18956
  state.color = styles.color;
18958
18957
  }
18959
- if (styles["text-decoration"] === "underline") {
18958
+ if (/^underline/.test(styles["textDecoration"])) {
18960
18959
  state.underline = true;
18961
18960
  }
18962
- if (styles["font-style"] === "italic") {
18961
+ if (styles["fontStyle"] == "italic") {
18963
18962
  state.italic = true;
18964
18963
  }
18965
- if (styles["font-weight"] === "bold") {
18964
+ if (/^(?:bold|[67]00)$/i.test(styles["fontWeight"])) {
18966
18965
  state.bold = true;
18967
18966
  }
18968
- if (stripStyle(styles["text-align"]) !== "right") {
18969
- state.textAlign = stripStyle(styles["text-align"]);
18970
- }
18971
- if (styles["vertical-align"] !== "middle") {
18972
- state.verticalAlign = styles["vertical-align"];
18973
- }
18974
- if (styles["word-wrap"] !== "normal" ) {
18975
- state.wrap = true;
18976
- }
18977
18967
 
18978
18968
  return state;
18979
18969
  }
@@ -20807,6 +20797,60 @@ const parseXML = function parseXML() {
20807
20797
  }
20808
20798
  };
20809
20799
 
20800
+ class Deferred {
20801
+ constructor() {
20802
+ this._progressHandlers = [];
20803
+ this._resolved = false;
20804
+ this._rejected = false;
20805
+ this.promise = new window.Promise((resolve, reject) => {
20806
+ this._resolve = (value) => {
20807
+ if (!this._resolved && !this._rejected) {
20808
+ this._resolved = true;
20809
+ resolve(value);
20810
+ }
20811
+ };
20812
+ this._reject = (reason) => {
20813
+ if (!this._resolved && !this._rejected) {
20814
+ this._rejected = true;
20815
+ reject(reason);
20816
+ }
20817
+ };
20818
+ });
20819
+ }
20820
+
20821
+ resolve(value) {
20822
+ this._resolve(value);
20823
+ return this;
20824
+ }
20825
+
20826
+ reject(reason) {
20827
+ this._reject(reason);
20828
+ return this;
20829
+ }
20830
+
20831
+ notify(value) {
20832
+ if (!this._resolved && !this._rejected) {
20833
+ this._progressHandlers.forEach(handler => handler(value));
20834
+ }
20835
+ }
20836
+
20837
+ progress(callback) {
20838
+ this._progressHandlers.push(callback);
20839
+ return this;
20840
+ }
20841
+
20842
+ then(onFulfilled, onRejected, onProgress) {
20843
+ if (onProgress) {
20844
+ this.progress(onProgress);
20845
+ }
20846
+ return this.promise.then(onFulfilled, onRejected);
20847
+ }
20848
+
20849
+ promise() {
20850
+ return this.promise;
20851
+ }
20852
+ }
20853
+
20810
20854
  /* eslint-disable complexity */
20811
20855
 
20812
20856
  // WARNING: removing the following jshint declaration and turning
@@ -20821,12 +20865,11 @@ let MAP_EXCEL_OPERATOR = {
20821
20865
 
20822
20866
  let ERROR_LOG = null;
20823
20867
 
20824
- function readExcel(file, workbook) {
20868
+ function readExcel(file, workbook, deferred) {
20825
20869
  let reader = new FileReader();
20826
- reader.onload = function(e) {
20827
- JSZip.loadAsync(e.target.result).then(zip => {
20828
- readWorkbook(zip, workbook);
20829
- });
20870
+ reader.onload = async function(e) {
20871
+ JSZip.loadAsync(e.target.result)
20872
+ .then(async zip => await readWorkbook(zip, workbook, deferred));
20830
20873
  };
20831
20874
 
20832
20875
  reader.readAsArrayBuffer(file);
@@ -20848,6 +20891,7 @@ let SEL_VALUE = ["sheetData", "row", "c", "v"];
20848
20891
  let SEL_VIEW = ["bookViews", "workbookView"];
20849
20892
  let SEL_SHEET_VIEW = ["sheetViews", "sheetView"];
20850
20893
  let SEL_HYPERLINK = ["hyperlinks", "hyperlink"];
20894
+ let SEL_PROTECTION = ["sheetProtection"];
20851
20895
 
20852
20896
  /* A validation section looks like this:
20853
20897
  *
@@ -20909,7 +20953,7 @@ function xl(file) {
20909
20953
  return file;
20910
20954
  }
20911
20955
 
20912
- async function readWorkbook(zip, workbook) {
20956
+ async function readWorkbook(zip, workbook, progress) {
20913
20957
  ERROR_LOG = workbook.excelImportErrors = [];
20914
20958
 
20915
20959
  let strings = await readStrings(zip);
@@ -20926,6 +20970,10 @@ async function readWorkbook(zip, workbook) {
20926
20970
  let file = relationships.byId[relId];
20927
20971
  let name = attrs.name;
20928
20972
  let state = attrs.state;
20973
+ let dim = sheetDimensions(relationships.bytes[file]);
20974
+
20975
+ workbook.options.columnWidth = dim.columnWidth || workbook.options.columnWidth;
20976
+ workbook.options.rowHeight = dim.rowHeight || workbook.options.rowHeight;
20929
20977
 
20930
20978
  items.push({
20931
20979
  workbook: workbook,
@@ -20935,7 +20983,11 @@ async function readWorkbook(zip, workbook) {
20935
20983
  file: file,
20936
20984
  options: {
20937
20985
  state: state,
20938
- name: name
20986
+ name: name,
20987
+ rows: Math.max(workbook.options.rows || 0, dim.rows),
20988
+ columns: Math.max(workbook.options.columns || 0, dim.cols),
20989
+ columnWidth: dim.columnWidth,
20990
+ rowHeight: dim.rowHeight
20939
20991
  }
20940
20992
  });
20941
20993
  } else if (this.is(SEL_VIEW)) {
@@ -20965,43 +21017,63 @@ async function readWorkbook(zip, workbook) {
20965
21017
  }
20966
21018
  });
20967
21019
 
20968
- for (let i = 0; i < items.length; i++) {
20969
- const item = items[i];
20970
- const dim = await sheetDimensions(item.zip, item.file);
20971
- const { workbook } = item;
20972
-
20973
- workbook.options.columnWidth = dim.columnWidth || workbook.options.columnWidth;
20974
- workbook.options.rowHeight = dim.rowHeight || workbook.options.rowHeight;
20975
-
20976
- item.options = {
20977
- ...item.options,
20978
- rows: Math.max(workbook.options.rows || 0, dim.rows),
20979
- columns: Math.max(workbook.options.columns || 0, dim.cols),
20980
- columnWidth: dim.columnWidth,
20981
- rowHeight: dim.rowHeight
20982
- };
20983
- }
21020
+ let loading = new Deferred();
21021
+ loading.progress(function(args) {
21022
+ if (progress) {
21023
+ progress.notify(args);
21024
+ }
21025
+ })
21026
+ .then(function() {
21027
+ let sheets = workbook.sheets();
21028
+ recalcSheets(sheets);
20984
21029
 
20985
- await loadSheets(items, workbook);
21030
+ workbook.activeSheet(sheets[activeSheet]);
20986
21031
 
20987
- let sheets = workbook.sheets();
20988
- recalcSheets(sheets);
21032
+ if (progress) {
21033
+ progress.resolve();
21034
+ }
21035
+ });
20989
21036
 
20990
- workbook.activeSheet(sheets[activeSheet]);
21037
+ loadSheets(items, workbook, loading);
20991
21038
  }
20992
21039
 
20993
- async function loadSheets(items, workbook) {
21040
+ function loadSheets(items, workbook, progress) {
21041
+ let ready = window.Promise.resolve();
20994
21042
  for (let i = 0; i < items.length; i++) {
20995
- const ctx = items[i];
20996
- let sheet = workbook.insertSheet(ctx.options);
21043
+ (function(entry, i) {
21044
+ ready = ready.then(function() {
21045
+ let sheet = workbook.insertSheet(entry.options);
21046
+ sheet.suspendChanges(true);
21047
+
21048
+ let promise = queueSheet(sheet, entry);
21049
+ let args = {
21050
+ sheet: sheet,
21051
+ progress: i === 1 ? 1 : (i / (items.length - 1))
21052
+ };
20997
21053
 
20998
- if (!sheet) {
20999
- continue;
21000
- }
21054
+ promise.then(function() {
21055
+ progress.notify(args);
21056
+ });
21001
21057
 
21002
- sheet.suspendChanges(true);
21003
- await readSheet(ctx.zip, ctx.file, sheet, ctx.strings, ctx.styles);
21058
+ return promise;
21059
+ });
21060
+ })(items[i], i);
21004
21061
  }
21062
+
21063
+ ready.then(function() {
21064
+ progress.resolve();
21065
+ });
21066
+ }
21067
+
21068
+ function queueSheet(sheet, ctx) {
21069
+ let deferred = new Deferred();
21070
+
21071
+ setTimeout(async function() {
21072
+ await readSheet(ctx.zip, ctx.file, sheet, ctx.strings, ctx.styles);
21073
+ deferred.resolve();
21074
+ }, 0);
21075
+
21076
+ return deferred;
21005
21077
  }
21006
21078
 
21007
21079
  function recalcSheets(sheets) {
@@ -21012,13 +21084,13 @@ function recalcSheets(sheets) {
21012
21084
  }
21013
21085
  }
21014
21086
 
21015
- async function sheetDimensions(zip, file) {
21087
+ function sheetDimensions(bytes) {
21016
21088
  let ref, dim = {
21017
21089
  rows: 0,
21018
21090
  cols: 0
21019
21091
  };
21020
21092
 
21021
- await parse(zip, xl(file), {
21093
+ parseXML(bytes, {
21022
21094
  enter: function(tag, attrs) {
21023
21095
  if (tag === "dimension") {
21024
21096
  ref = calc.parseReference(attrs.ref);
@@ -21076,6 +21148,7 @@ async function readSheet(zip, file, sheet, strings, styles) {
21076
21148
  let valueFilterBlanks;
21077
21149
  let valueFilterValues;
21078
21150
  let filters = [];
21151
+ let deferredStyles = [];
21079
21152
 
21080
21153
  ERROR_LOG = sheet._workbook.excelImportErrors;
21081
21154
 
@@ -21120,7 +21193,7 @@ async function readSheet(zip, file, sheet, strings, styles) {
21120
21193
 
21121
21194
  let styleIndex = attrs.s;
21122
21195
  if (styleIndex != null) {
21123
- applyStyle(sheet, ref, styles, styleIndex);
21196
+ deferredStyles.push({ ref: ref, sty: +styleIndex });
21124
21197
  }
21125
21198
  } else if (this.is(SEL_MERGE)) {
21126
21199
  sheet.range(attrs.ref).merge();
@@ -21141,10 +21214,13 @@ async function readSheet(zip, file, sheet, strings, styles) {
21141
21214
  }
21142
21215
  if (attrs.style != null) {
21143
21216
  // apply style on a whole range of columns
21144
- applyStyle(sheet, new RangeRef(
21145
- new CellRef(-Infinity, start),
21146
- new CellRef(+Infinity, stop)
21147
- ), styles, attrs.style);
21217
+ deferredStyles.unshift({
21218
+ ref: new RangeRef(
21219
+ new CellRef(-Infinity, start),
21220
+ new CellRef(+Infinity, stop)
21221
+ ),
21222
+ sty: +attrs.style
21223
+ });
21148
21224
  }
21149
21225
  } else if (this.is(SEL_ROW)) {
21150
21226
  let row = integer(attrs.r) - 1;
@@ -21181,6 +21257,10 @@ async function readSheet(zip, file, sheet, strings, styles) {
21181
21257
  if (target) {
21182
21258
  sheet.range(attrs.ref).link(target);
21183
21259
  }
21260
+ } else if (this.is(SEL_PROTECTION)) {
21261
+ if (attrs.sheet) {
21262
+ sheet.range(SHEETREF).enable(false);
21263
+ }
21184
21264
  } else if (this.is(["autoFilter"])) {
21185
21265
  filterRef = attrs.ref;
21186
21266
  if (closed) {
@@ -21351,6 +21431,8 @@ async function readSheet(zip, file, sheet, strings, styles) {
21351
21431
  }
21352
21432
  });
21353
21433
 
21434
+ deferredStyles.forEach(({ ref, sty }) => applyStyle(sheet, ref, styles, sty));
21435
+
21354
21436
  if (relationships.byType.comments) {
21355
21437
  let commentFile = relative_file(file, relationships.byType.comments[0]);
21356
21438
  await readComments(zip, commentFile, sheet);
@@ -21401,12 +21483,14 @@ async function readDrawings(zip, file, sheet) {
21401
21483
  let relationships = await readRelationships(zip, relsFile);
21402
21484
 
21403
21485
  if (relationships.byType.image) {
21404
- for (const id of Object.keys(relationships.byId)) {
21486
+ let relkeys = Object.keys(relationships.byId);
21487
+ for (let i = 0; i < relkeys.length; ++i) {
21488
+ let id = relkeys[i];
21405
21489
  let img = relative_file(file, relationships.byId[id]);
21406
21490
  let type = getContentType(img);
21407
21491
 
21408
21492
  if (type) {
21409
- let data = await zip.files[img].async("arrayBuffer");
21493
+ let data = await zip.file(img).async("arraybuffer");
21410
21494
  let name = getFileName(img);
21411
21495
  let blob = name && !(browser.edge)
21412
21496
  ? new window.File([ data ], name, { type: type })
@@ -21680,6 +21764,9 @@ function applyStyle(sheet, ref, styles, styleIndex) {
21680
21764
  if (shouldSet("applyNumberFormat", "numFmtId")) {
21681
21765
  setFormat(styles.numFmts[value] || DEFAULT_FORMATS[value]);
21682
21766
  }
21767
+ if (shouldSet("applyProtection", "protection")) {
21768
+ range.enable(!xf.protection.locked);
21769
+ }
21683
21770
 
21684
21771
  function setFormat(f) {
21685
21772
  let format = typeof f == "string" ? f : f.formatCode;
@@ -21768,11 +21855,18 @@ function applyStyle(sheet, ref, styles, styleIndex) {
21768
21855
  }
21769
21856
  }
21770
21857
 
21771
- async function parse(zip, file, callbacks) {
21772
- let part = zip.files[file];
21773
- if (part) {
21774
- await parseXML(await part.async("uint8array"), callbacks);
21775
- }
21858
+ function parse(zip, file, callbacks) {
21859
+ return new window.Promise(resolve => {
21860
+ let obj = zip.file(file);
21861
+ if (obj) {
21862
+ obj.async("uint8array").then(bytes => {
21863
+ parseXML(bytes, callbacks);
21864
+ resolve();
21865
+ });
21866
+ } else {
21867
+ resolve();
21868
+ }
21869
+ });
21776
21870
  }
21777
21871
 
21778
21872
  async function readStrings(zip) {
@@ -21798,7 +21892,7 @@ async function readStrings(zip) {
21798
21892
  }
21799
21893
 
21800
21894
  async function readRelationships(zip, file) {
21801
- let map = { byId: {}, byType: { theme: [] } };
21895
+ let map = { byId: {}, byType: { theme: [] }, bytes: {} };
21802
21896
  await parse(zip, xl(file) + ".rels", {
21803
21897
  enter: function(tag, attrs) {
21804
21898
  if (tag === "Relationship") {
@@ -21811,6 +21905,18 @@ async function readRelationships(zip, file) {
21811
21905
  }
21812
21906
  }
21813
21907
  });
21908
+ let names = [];
21909
+ let promises = [];
21910
+ Object.keys(map.byId).forEach(id => {
21911
+ let filename = map.byId[id];
21912
+ let obj = zip.file(xl(filename));
21913
+ if (obj) {
21914
+ names.push(filename);
21915
+ promises.push(obj.async("uint8array"));
21916
+ }
21917
+ });
21918
+ let data = await window.Promise.all(promises);
21919
+ names.forEach((name, i) => map.bytes[name] = data[i]);
21814
21920
  return map;
21815
21921
  }
21816
21922
 
@@ -21952,6 +22058,10 @@ async function readStyles(zip, theme) {
21952
22058
  if (attrs.indent != null) {
21953
22059
  xf.indent = integer(attrs.indent);
21954
22060
  }
22061
+ } else if (tag == "protection") {
22062
+ xf.protection = {
22063
+ locked: bool(attrs.locked)
22064
+ };
21955
22065
  }
21956
22066
  }
21957
22067
  },
@@ -21983,10 +22093,12 @@ async function readStyles(zip, theme) {
21983
22093
  addBool("applyFill");
21984
22094
  addBool("applyFont");
21985
22095
  addBool("applyNumberFormat");
21986
- addBool("applyProtection");
22096
+ if (addBool("applyProtection")) {
22097
+ xf.protection = { locked: true };
22098
+ }
21987
22099
  function addBool(name) {
21988
22100
  if (attrs[name] != null) {
21989
- xf[name] = bool(attrs[name]);
22101
+ return xf[name] = bool(attrs[name]);
21990
22102
  }
21991
22103
  }
21992
22104
  return xf;
@@ -22035,7 +22147,7 @@ async function readTheme(zip, rel) {
22035
22147
  };
22036
22148
 
22037
22149
  let file = xl(rel);
22038
- if (zip.files[file]) {
22150
+ if (zip.file(file)) {
22039
22151
  await parse(zip, file, {
22040
22152
  enter: function(tag, attrs) {
22041
22153
  if (this.is(SEL_SCHEME_SYSCLR)) {
@@ -22766,10 +22878,18 @@ class Workbook extends Observable {
22766
22878
  }
22767
22879
 
22768
22880
  fromFile(file) {
22769
- if (file && !this.trigger("excelImport", { file })) {
22881
+ const deferred = new Deferred();
22882
+
22883
+ if (file && !this.trigger("excelImport", { file, deferred })) {
22770
22884
  this._clearSheets();
22771
- readExcel(file, this);
22885
+ this._readExcel(file, this, deferred);
22772
22886
  }
22887
+
22888
+ return deferred.promise;
22889
+ }
22890
+
22891
+ _readExcel(file, workbook, deferred) {
22892
+ readExcel(file, workbook, deferred);
22773
22893
  }
22774
22894
 
22775
22895
  saveAsExcel(options) {
@@ -24267,6 +24387,11 @@ function binaryCompare(left, right, func) {
24267
24387
  right = right.toLowerCase();
24268
24388
  }
24269
24389
  if (typeof right == typeof left) {
24390
+ // for issue https://github.com/telerik/kendo-ui-core/issues/6879, limitPrecision
24391
+ // digits got bumped to 16, but it's too much for the case 9.302 - 0.002 (issue
24392
+ // https://github.com/telerik/kendo-ui-core/issues/7170).
24393
+ left = maybeRoundFloatErrors(left, 15);
24394
+ right = maybeRoundFloatErrors(right, 15);
24270
24395
  return func(left, right);
24271
24396
  } else {
24272
24397
  return new CalcError("VALUE");
@@ -32609,10 +32734,10 @@ defineBuiltinFunction('index', true, function () {
32609
32734
  }
32610
32735
  }
32611
32736
  if (ref.width == 1) {
32612
- return callback(ref.get(row - 1, 0));
32737
+ return callback(ref.get((row || 1) - 1, 0));
32613
32738
  }
32614
32739
  if (ref.height == 1) {
32615
- return callback(ref.get(0, col - 1));
32740
+ return callback(ref.get(0, (col || 1) - 1));
32616
32741
  }
32617
32742
  } else {
32618
32743
  callback(new CalcError('REF'));
@@ -43758,4 +43883,4 @@ const {
43758
43883
  defineAlias
43759
43884
  } = calc.runtime;
43760
43885
 
43761
- export { CalcError, CellRef, Context, Matrix, NULLREF, NameRef, Range$1 as Range, RangeRef, Ref, Sheet, SpreadsheetWidget, UnionRef, View, Workbook, calc, dateToSerial, defineAlias, defineFunction, packDate, packTime, serialToDate, unpackDate, unpackTime };
43886
+ export { CalcError, CellRef, Context, Deferred, Matrix, NULLREF, NameRef, Range$1 as Range, RangeRef, Ref, Sheet, SpreadsheetWidget, UnionRef, View, Workbook, calc, dateToSerial, defineAlias, defineFunction, packDate, packTime, serialToDate, unpackDate, unpackTime };