@progress/kendo-spreadsheet-common 1.1.3-develop.2 → 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.
Files changed (3) hide show
  1. package/dist/index-esm.js +186 -274
  2. package/dist/index.js +186 -274
  3. package/package.json +6 -5
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) {
@@ -9406,13 +9384,18 @@ function looksLikeANumber(str) {
9406
9384
 
9407
9385
  function getTextHeight(text, width, fontFamily, fontSize, wrap) {
9408
9386
  const measureBox = document.createElement("div");
9409
- measureBox.setAttribute(
9410
- "style",
9411
- "position: absolute !important; top: -4000px !important; height: auto !important;" +
9412
- "padding: 1px 3px !important; box-sizing: border-box; margin: 0 !important; border: 1px solid black !important;" +
9413
- "line-height: normal !important; visibility: hidden !important;" +
9414
- "white-space: pre-wrap;"
9415
- );
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
+
9416
9399
  let styles = {
9417
9400
  "baselineMarkerSize" : 0,
9418
9401
  "width" : (wrap === true) ? width + "px" : "auto",
@@ -12127,210 +12110,131 @@ const kendoDate = (function() {
12127
12110
 
12128
12111
  /* eslint-disable no-var */
12129
12112
 
12130
- 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
+ };
12131
12123
 
12132
- var operators = (function() {
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
+ };
12144
+
12145
+ const dateRegExp = /^\/Date\((.*?)\)\/$/;
12133
12146
 
12134
- function quote(str) {
12135
- if (typeof str == "string") {
12136
- 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();
12137
12156
  }
12138
- return JSON.stringify(str);
12157
+ } else if (value != null && isDate(value)) {
12158
+ return value.getTime();
12139
12159
  }
12160
+ return value;
12161
+ };
12140
12162
 
12141
- function textOp(impl) {
12142
- return function(a, b, ignore, accentFoldingFiltering) {
12143
- b += "";
12144
- if (ignore) {
12145
- a = "(" + a + " + '').toString()" + ((accentFoldingFiltering) ? ".toLocaleLowerCase('" + accentFoldingFiltering + "')" : ".toLowerCase()");
12146
- b = ((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase());
12147
- }
12148
- return impl(a, quote(b), ignore);
12149
- };
12150
- }
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
+ );
12151
12180
 
12152
- function operator(op, a, b, ignore, accentFoldingFiltering) {
12153
- if (b != null) {
12154
- if (typeof b === 'string') {
12155
- var date = dateRegExp.exec(b);
12156
- if (date) {
12157
- b = new Date(+date[1]);
12158
- } else if (ignore) {
12159
- b = quote(((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase()));
12160
- a = "((" + a + " || '')+'')" + ((accentFoldingFiltering) ? ".toLocaleLowerCase('" + accentFoldingFiltering + "')" : ".toLowerCase()");
12161
- } else {
12162
- b = quote(b);
12163
- }
12164
- }
12181
+ value = convertValue(value, ignoreCase, accentFoldingFiltering);
12165
12182
 
12166
- if (b.getTime) {
12167
- //b looks like a Date
12168
- a = "(" + a + "&&" + a + ".getTime?" + a + ".getTime():" + a + ")";
12169
- b = b.getTime();
12170
- }
12171
- }
12183
+ const op = isFunction(operator) ? operator : operatorsMap[operator];
12172
12184
 
12173
- return a + " " + op + " " + b;
12174
- }
12185
+ return (a) => op(itemProp(a), value, ignoreCase);
12186
+ };
12175
12187
 
12176
- function getMatchRegexp(pattern) {
12177
- // take a pattern, as supported by Excel match filter, and
12178
- // convert it to the equivalent JS regular expression.
12179
- // Excel patterns support:
12180
- //
12181
- // * - match any sequence of characters
12182
- // ? - match a single character
12183
- //
12184
- // to match a literal * or ?, they must be prefixed by a tilde (~)
12185
- var rx = "/^";
12186
- for (var esc = false, i = 0; i < pattern.length; ++i) {
12187
- var ch = pattern.charAt(i);
12188
- if (esc) {
12189
- rx += "\\" + ch;
12190
- } else if (ch === "~") {
12191
- esc = true;
12192
- continue;
12193
- } else if (ch === "*") {
12194
- rx += ".*";
12195
- } else if (ch === "?") {
12196
- rx += ".";
12197
- } else if (".+^$()[]{}|\\/\n\r\u2028\u2029\xA0".indexOf(ch) >= 0) {
12198
- rx += "\\" + ch;
12199
- } else {
12200
- rx += ch;
12201
- }
12202
- esc = false;
12203
- }
12204
- return rx + "$/";
12188
+ const typedGetter = (prop, value, ignoreCase, accentFoldingFiltering) => {
12189
+ if (!isPresent(value)) {
12190
+ return prop;
12205
12191
  }
12206
12192
 
12207
- return {
12208
- quote: function(value) {
12209
- if (value && value.getTime) {
12210
- return "new Date(" + value.getTime() + ")";
12211
- }
12212
- return quote(value);
12213
- },
12214
- eq: function(a, b, ignore, accentFoldingFiltering) {
12215
- return operator("==", a, b, ignore, accentFoldingFiltering);
12216
- },
12217
- neq: function(a, b, ignore, accentFoldingFiltering) {
12218
- return operator("!=", a, b, ignore, accentFoldingFiltering);
12219
- },
12220
- gt: function(a, b, ignore) {
12221
- return operator(">", a, b, ignore);
12222
- },
12223
- gte: function(a, b, ignore) {
12224
- return operator(">=", a, b, ignore);
12225
- },
12226
- lt: function(a, b, ignore) {
12227
- return operator("<", a, b, ignore);
12228
- },
12229
- lte: function(a, b, ignore) {
12230
- return operator("<=", a, b, ignore);
12231
- },
12232
- startswith: textOp(function(a, b) {
12233
- return a + ".lastIndexOf(" + b + ", 0) == 0";
12234
- }),
12235
- doesnotstartwith: textOp(function(a, b) {
12236
- return a + ".lastIndexOf(" + b + ", 0) == -1";
12237
- }),
12238
- endswith: textOp(function(a, b) {
12239
- var n = b ? b.length - 2 : 0;
12240
- return a + ".indexOf(" + b + ", " + a + ".length - " + n + ") >= 0";
12241
- }),
12242
- doesnotendwith: textOp(function(a, b) {
12243
- var n = b ? b.length - 2 : 0;
12244
- return a + ".indexOf(" + b + ", " + a + ".length - " + n + ") < 0";
12245
- }),
12246
- contains: textOp(function(a, b) {
12247
- return a + ".indexOf(" + b + ") >= 0";
12248
- }),
12249
- doesnotcontain: textOp(function(a, b) {
12250
- return a + ".indexOf(" + b + ") == -1";
12251
- }),
12252
- matches: textOp(function(a, b) {
12253
- b = b.substring(1, b.length - 1);
12254
- return getMatchRegexp(b) + ".test(" + a + ")";
12255
- }),
12256
- doesnotmatch: textOp(function(a, b) {
12257
- b = b.substring(1, b.length - 1);
12258
- return "!" + getMatchRegexp(b) + ".test(" + a + ")";
12259
- }),
12260
- isempty: function(a) {
12261
- return a + " === ''";
12262
- },
12263
- isnotempty: function(a) {
12264
- return a + " !== ''";
12265
- },
12266
- isnull: function(a) {
12267
- return "(" + a + " == null)";
12268
- },
12269
- isnotnull: function(a) {
12270
- return "(" + a + " != null)";
12271
- },
12272
- isnullorempty: function(a) {
12273
- return "(" + a + " === null) || (" + a + " === '')";
12274
- },
12275
- isnotnullorempty: function(a) {
12276
- return "(" + a + " !== null) && (" + a + " !== '')";
12277
- }
12278
- };
12279
- })();
12280
-
12281
- const filterExpr = function(expression) {
12282
- var expressions = [],
12283
- logic = { and: " && ", or: " || " },
12284
- idx,
12285
- length,
12286
- filter,
12287
- expr$1,
12288
- fieldFunctions = [],
12289
- operatorFunctions = [],
12290
- field,
12291
- operator,
12292
- filters = expression.filters;
12293
-
12294
- for (idx = 0, length = filters.length; idx < length; idx++) {
12295
- filter = filters[idx];
12296
- field = filter.field;
12297
- operator = filter.operator;
12298
-
12299
- if (filter.filters) {
12300
- expr$1 = filterExpr(filter);
12301
- //Nested function fields or operators - update their index e.g. __o[0] -> __o[1]
12302
- filter = expr$1.expression
12303
- .replace(/__o\[(\d+)\]/g, function(match, index) {
12304
- index = +index;
12305
- return "__o[" + (operatorFunctions.length + index) + "]";
12306
- })
12307
- .replace(/__f\[(\d+)\]/g, function(match, index) {
12308
- index = +index;
12309
- return "__f[" + (fieldFunctions.length + index) + "]";
12310
- });
12193
+ let acc = prop;
12311
12194
 
12312
- operatorFunctions.push.apply(operatorFunctions, expr$1.operators);
12313
- 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]);
12314
12199
  } else {
12315
- if (typeof field === 'function') {
12316
- expr$1 = "__f[" + fieldFunctions.length + "](d)";
12317
- fieldFunctions.push(field);
12318
- } else {
12319
- expr$1 = expr(field);
12320
- }
12321
-
12322
- if (typeof operator === 'function') {
12323
- filter = "__o[" + operatorFunctions.length + "](" + expr$1 + ", " + operators.quote(filter.value) + ")";
12324
- operatorFunctions.push(operator);
12325
- } else {
12326
- filter = operators[(operator || "eq").toLowerCase()](expr$1, filter.value, filter.ignoreCase !== undefined ? filter.ignoreCase : true, expression.accentFoldingFiltering);
12327
- }
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
+ };
12328
12210
  }
12211
+ }
12329
12212
 
12330
- expressions.push(filter);
12213
+ if (isDate(value)) {
12214
+ return (a) => {
12215
+ const x = acc(a);
12216
+ return isDate(x) ? x.getTime() : x;
12217
+ };
12331
12218
  }
12219
+ return acc;
12220
+ };
12332
12221
 
12333
- 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);
12334
12238
  };
12335
12239
 
12336
12240
  /* eslint-disable max-params */
@@ -12445,13 +12349,11 @@ class CustomFilter extends Filter {
12445
12349
 
12446
12350
  this._criteria = options.criteria;
12447
12351
 
12448
- var expression = filterExpr({
12352
+ this._matches = transformCompositeFilter({
12449
12353
  logic: this._logic,
12450
12354
  filters: this._criteria,
12451
- accentFoldingFiltering: culture().name
12452
- }).expression;
12453
-
12454
- this._matches = new Function("d", "return " + expression);
12355
+ accentFoldingFiltering: culture().name,
12356
+ });
12455
12357
  }
12456
12358
  matches(value) {
12457
12359
  if (value === null) {
@@ -17027,24 +16929,9 @@ class FormulaInput extends Widget {
17027
16929
  end = begin;
17028
16930
  }
17029
16931
  if (begin && end) {
17030
- let range = document.createRange();
17031
- range.setStart(begin.node, begin.pos);
17032
- range.setEnd(end.node, end.pos);
17033
- let sel = window.getSelection();
17034
- let currentRange = sel.getRangeAt(0);
17035
- if (differ(range, currentRange)) {
17036
- sel.removeAllRanges();
17037
- sel.addRange(range);
17038
- }
17039
- }
17040
- function differ(a, b) {
17041
- return (
17042
- a.startOffset !== b.startOffset ||
17043
- a.endOffset !== b.endOffset ||
17044
- a.startContainer !== b.endContainer ||
17045
- a.endContainer !== b.endContainer
17046
- );
16932
+ this._setRange(begin, end);
17047
16933
  }
16934
+
17048
16935
  function lookup(node, pos) {
17049
16936
  try {
17050
16937
  (function loop(node) {
@@ -17082,6 +16969,27 @@ class FormulaInput extends Widget {
17082
16969
  return this.value().length;
17083
16970
  }
17084
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
+
17085
16993
  _formulaSource() {
17086
16994
  let result = [];
17087
16995
  let value;
@@ -22974,12 +22882,16 @@ class Workbook extends Observable {
22974
22882
 
22975
22883
  if (file && !this.trigger("excelImport", { file, deferred })) {
22976
22884
  this._clearSheets();
22977
- readExcel(file, this, deferred);
22885
+ this._readExcel(file, this, deferred);
22978
22886
  }
22979
22887
 
22980
22888
  return deferred.promise;
22981
22889
  }
22982
22890
 
22891
+ _readExcel(file, workbook, deferred) {
22892
+ readExcel(file, workbook, deferred);
22893
+ }
22894
+
22983
22895
  saveAsExcel(options) {
22984
22896
  let self = this;
22985
22897
  options = deepExtend({}, self.options.excel, options);
package/dist/index.js CHANGED
@@ -1166,66 +1166,36 @@
1166
1166
  }
1167
1167
  }
1168
1168
 
1169
- const wrapExpression = function(members, paramName) {
1170
- let result = paramName || "d",
1171
- index,
1172
- idx,
1173
- length,
1174
- member,
1175
- count = 1;
1176
-
1177
- for (idx = 0, length = members.length; idx < length; idx++) {
1178
- member = members[idx];
1179
- if (member !== "") {
1180
- index = member.indexOf("[");
1181
-
1182
- if (index !== 0) {
1183
- if (index === -1) {
1184
- member = "." + member;
1185
- } else {
1186
- count++;
1187
- member = "." + member.substring(0, index) + " || {})" + member.substring(index);
1188
- }
1189
- }
1190
-
1191
- count++;
1192
- result += member + ((idx < length - 1) ? " || {})" : ")");
1193
- }
1194
- }
1195
- return new Array(count).join("(") + result;
1196
- };
1197
-
1198
1169
  const getterCache = {};
1199
1170
 
1200
- function expr(expression, safe, paramName) {
1201
- expression = expression || "";
1202
-
1203
- if (typeof safe == 'string') {
1204
- paramName = safe;
1205
- safe = false;
1206
- }
1171
+ getterCache["undefined"] = (obj) => obj;
1207
1172
 
1208
- paramName = paramName || "d";
1173
+ const FIELD_REGEX = /\[(?:(\d+)|['"](.*?)['"])\]|((?:(?!\[.*?\]|\.).)+)/g;
1174
+ function getter(field, safe) {
1175
+ const key = field + safe;
1209
1176
 
1210
- if (expression && expression.charAt(0) !== "[") {
1211
- expression = "." + expression;
1177
+ if (getterCache[key]) {
1178
+ return getterCache[key];
1212
1179
  }
1213
1180
 
1214
- if (safe) {
1215
- expression = expression.replace(/"([^.]*)\.([^"]*)"/g,'"$1_$DOT$_$2"');
1216
- expression = expression.replace(/'([^.]*)\.([^']*)'/g,"'$1_$DOT$_$2'");
1217
- expression = wrapExpression(expression.split("."), paramName);
1218
- expression = expression.replace(/_\$DOT\$_/g, ".");
1219
- } else {
1220
- expression = paramName + expression;
1221
- }
1181
+ const fields = [];
1182
+ field.replace(FIELD_REGEX, (_, index, indexAccessor, field) => {
1183
+ fields.push(isPresent(index) ? index : indexAccessor || field);
1184
+ return undefined;
1185
+ });
1222
1186
 
1223
- return expression;
1224
- }
1187
+ getterCache[key] = (obj) => {
1188
+ let result = obj;
1189
+ for (let idx = 0; idx < fields.length; idx++) {
1190
+ result = result[fields[idx]];
1191
+ if (!isPresent(result) && safe) {
1192
+ return result;
1193
+ }
1194
+ }
1195
+
1196
+ return result;
1197
+ };
1225
1198
 
1226
- function getter(expression, safe) {
1227
- let key = expression + safe;
1228
- getterCache[key] = getterCache[key] || new Function("d", "return " + expr(expression, safe));
1229
1199
  return getterCache[key];
1230
1200
  }
1231
1201
 
@@ -1240,10 +1210,6 @@
1240
1210
  return destination;
1241
1211
  }
1242
1212
 
1243
- function isFunction(fn) {
1244
- return typeof fn === "function";
1245
- }
1246
-
1247
1213
  function deepExtendOne(destination, source) {
1248
1214
  let property,
1249
1215
  propValue,
@@ -1317,7 +1283,12 @@
1317
1283
  let div = document.createElement("div"),
1318
1284
  result;
1319
1285
 
1320
- div.style.cssText = "overflow:scroll;overflow-x:hidden;zoom:1;clear:both;display:block";
1286
+ div.style.overflow = "scroll";
1287
+ div.style.overflowX = "hidden";
1288
+ div.style.zoom = "1";
1289
+ div.style.clear = "both";
1290
+ div.style.display = "block";
1291
+
1321
1292
  div.innerHTML = "&nbsp;";
1322
1293
  document.body.appendChild(div);
1323
1294
 
@@ -1392,6 +1363,13 @@
1392
1363
  }
1393
1364
  };
1394
1365
 
1366
+ const isPresent = (value) => value !== null && value !== undefined;
1367
+ const isBlank = (value) => !isPresent(value);
1368
+ const isDate = (value) => value && value.getTime;
1369
+ const isString = (value) => typeof value === "string";
1370
+ const isNumeric = (value) => !isNaN(value - parseFloat(value));
1371
+ const isFunction = (fn) => typeof fn === "function";
1372
+
1395
1373
  class CalcError {
1396
1374
 
1397
1375
  constructor(code) {
@@ -9407,13 +9385,18 @@
9407
9385
 
9408
9386
  function getTextHeight(text, width, fontFamily, fontSize, wrap) {
9409
9387
  const measureBox = document.createElement("div");
9410
- measureBox.setAttribute(
9411
- "style",
9412
- "position: absolute !important; top: -4000px !important; height: auto !important;" +
9413
- "padding: 1px 3px !important; box-sizing: border-box; margin: 0 !important; border: 1px solid black !important;" +
9414
- "line-height: normal !important; visibility: hidden !important;" +
9415
- "white-space: pre-wrap;"
9416
- );
9388
+
9389
+ measureBox.style.setProperty('position', 'absolute', 'important');
9390
+ measureBox.style.setProperty('top', '-4000px', 'important');
9391
+ measureBox.style.setProperty('height', 'auto', 'important');
9392
+ measureBox.style.setProperty('padding', '1px 3px', 'important');
9393
+ measureBox.style.setProperty('box-sizing', 'border-box', 'important');
9394
+ measureBox.style.setProperty('margin', '0', 'important');
9395
+ measureBox.style.setProperty('border', '1px solid black', 'important');
9396
+ measureBox.style.setProperty('line-height', 'normal', 'important');
9397
+ measureBox.style.setProperty('visibility', 'hidden', 'important');
9398
+ measureBox.style.setProperty('white-space', 'pre-wrap');
9399
+
9417
9400
  let styles = {
9418
9401
  "baselineMarkerSize" : 0,
9419
9402
  "width" : (wrap === true) ? width + "px" : "auto",
@@ -12128,210 +12111,131 @@
12128
12111
 
12129
12112
  /* eslint-disable no-var */
12130
12113
 
12131
- const dateRegExp = /^\/Date\((.*?)\)\/$/;
12114
+ const logic = {
12115
+ or: {
12116
+ concat: (acc, fn) => (a) => acc(a) || fn(a),
12117
+ identity: () => false,
12118
+ },
12119
+ and: {
12120
+ concat: (acc, fn) => (a) => acc(a) && fn(a),
12121
+ identity: () => true,
12122
+ },
12123
+ };
12132
12124
 
12133
- var operators = (function() {
12125
+ const operatorsMap = {
12126
+ contains: (a, b) => (a || "").indexOf(b) >= 0,
12127
+ doesnotcontain: (a, b) => (a || "").indexOf(b) === -1,
12128
+ doesnotendwith: (a, b) =>
12129
+ (a || "").indexOf(b, (a || "").length - (b || "").length) < 0,
12130
+ doesnotstartwith: (a, b) => (a || "").lastIndexOf(b, 0) === -1,
12131
+ endswith: (a, b) =>
12132
+ (a || "").indexOf(b, (a || "").length - (b || "").length) >= 0,
12133
+ eq: (a, b) => a === b,
12134
+ gt: (a, b) => a > b,
12135
+ gte: (a, b) => a >= b,
12136
+ isempty: (a) => a === "",
12137
+ isnotempty: (a) => a !== "",
12138
+ isnotnull: (a) => isPresent(a),
12139
+ isnull: (a) => isBlank(a),
12140
+ lt: (a, b) => a < b,
12141
+ lte: (a, b) => a <= b,
12142
+ neq: (a, b) => a != b, // tslint:disable-line:triple-equals
12143
+ startswith: (a, b) => (a || "").lastIndexOf(b, 0) === 0,
12144
+ };
12145
+
12146
+ const dateRegExp = /^\/Date\((.*?)\)\/$/;
12134
12147
 
12135
- function quote(str) {
12136
- if (typeof str == "string") {
12137
- str = str.replace(/[\r\n]+/g, "");
12148
+ const convertValue = (value, ignoreCase, accentFoldingFiltering) => {
12149
+ if (value != null && isString(value)) {
12150
+ const date = dateRegExp.exec(value);
12151
+ if (date) {
12152
+ return new Date(+date[1]).getTime();
12153
+ } else if (ignoreCase) {
12154
+ return accentFoldingFiltering
12155
+ ? value.toLocaleLowerCase(accentFoldingFiltering)
12156
+ : value.toLowerCase();
12138
12157
  }
12139
- return JSON.stringify(str);
12158
+ } else if (value != null && isDate(value)) {
12159
+ return value.getTime();
12140
12160
  }
12161
+ return value;
12162
+ };
12141
12163
 
12142
- function textOp(impl) {
12143
- return function(a, b, ignore, accentFoldingFiltering) {
12144
- b += "";
12145
- if (ignore) {
12146
- a = "(" + a + " + '').toString()" + ((accentFoldingFiltering) ? ".toLocaleLowerCase('" + accentFoldingFiltering + "')" : ".toLowerCase()");
12147
- b = ((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase());
12148
- }
12149
- return impl(a, quote(b), ignore);
12150
- };
12151
- }
12164
+ const transformFilter = ({
12165
+ field,
12166
+ ignoreCase,
12167
+ value,
12168
+ operator,
12169
+ accentFoldingFiltering,
12170
+ }) => {
12171
+ field = !isPresent(field) ? (a) => a : field;
12172
+
12173
+ ignoreCase = isPresent(ignoreCase) ? ignoreCase : true;
12174
+
12175
+ const itemProp = typedGetter(
12176
+ isFunction(field) ? field : getter(field, true),
12177
+ value,
12178
+ ignoreCase,
12179
+ accentFoldingFiltering
12180
+ );
12152
12181
 
12153
- function operator(op, a, b, ignore, accentFoldingFiltering) {
12154
- if (b != null) {
12155
- if (typeof b === 'string') {
12156
- var date = dateRegExp.exec(b);
12157
- if (date) {
12158
- b = new Date(+date[1]);
12159
- } else if (ignore) {
12160
- b = quote(((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase()));
12161
- a = "((" + a + " || '')+'')" + ((accentFoldingFiltering) ? ".toLocaleLowerCase('" + accentFoldingFiltering + "')" : ".toLowerCase()");
12162
- } else {
12163
- b = quote(b);
12164
- }
12165
- }
12182
+ value = convertValue(value, ignoreCase, accentFoldingFiltering);
12166
12183
 
12167
- if (b.getTime) {
12168
- //b looks like a Date
12169
- a = "(" + a + "&&" + a + ".getTime?" + a + ".getTime():" + a + ")";
12170
- b = b.getTime();
12171
- }
12172
- }
12184
+ const op = isFunction(operator) ? operator : operatorsMap[operator];
12173
12185
 
12174
- return a + " " + op + " " + b;
12175
- }
12186
+ return (a) => op(itemProp(a), value, ignoreCase);
12187
+ };
12176
12188
 
12177
- function getMatchRegexp(pattern) {
12178
- // take a pattern, as supported by Excel match filter, and
12179
- // convert it to the equivalent JS regular expression.
12180
- // Excel patterns support:
12181
- //
12182
- // * - match any sequence of characters
12183
- // ? - match a single character
12184
- //
12185
- // to match a literal * or ?, they must be prefixed by a tilde (~)
12186
- var rx = "/^";
12187
- for (var esc = false, i = 0; i < pattern.length; ++i) {
12188
- var ch = pattern.charAt(i);
12189
- if (esc) {
12190
- rx += "\\" + ch;
12191
- } else if (ch === "~") {
12192
- esc = true;
12193
- continue;
12194
- } else if (ch === "*") {
12195
- rx += ".*";
12196
- } else if (ch === "?") {
12197
- rx += ".";
12198
- } else if (".+^$()[]{}|\\/\n\r\u2028\u2029\xA0".indexOf(ch) >= 0) {
12199
- rx += "\\" + ch;
12200
- } else {
12201
- rx += ch;
12202
- }
12203
- esc = false;
12204
- }
12205
- return rx + "$/";
12189
+ const typedGetter = (prop, value, ignoreCase, accentFoldingFiltering) => {
12190
+ if (!isPresent(value)) {
12191
+ return prop;
12206
12192
  }
12207
12193
 
12208
- return {
12209
- quote: function(value) {
12210
- if (value && value.getTime) {
12211
- return "new Date(" + value.getTime() + ")";
12212
- }
12213
- return quote(value);
12214
- },
12215
- eq: function(a, b, ignore, accentFoldingFiltering) {
12216
- return operator("==", a, b, ignore, accentFoldingFiltering);
12217
- },
12218
- neq: function(a, b, ignore, accentFoldingFiltering) {
12219
- return operator("!=", a, b, ignore, accentFoldingFiltering);
12220
- },
12221
- gt: function(a, b, ignore) {
12222
- return operator(">", a, b, ignore);
12223
- },
12224
- gte: function(a, b, ignore) {
12225
- return operator(">=", a, b, ignore);
12226
- },
12227
- lt: function(a, b, ignore) {
12228
- return operator("<", a, b, ignore);
12229
- },
12230
- lte: function(a, b, ignore) {
12231
- return operator("<=", a, b, ignore);
12232
- },
12233
- startswith: textOp(function(a, b) {
12234
- return a + ".lastIndexOf(" + b + ", 0) == 0";
12235
- }),
12236
- doesnotstartwith: textOp(function(a, b) {
12237
- return a + ".lastIndexOf(" + b + ", 0) == -1";
12238
- }),
12239
- endswith: textOp(function(a, b) {
12240
- var n = b ? b.length - 2 : 0;
12241
- return a + ".indexOf(" + b + ", " + a + ".length - " + n + ") >= 0";
12242
- }),
12243
- doesnotendwith: textOp(function(a, b) {
12244
- var n = b ? b.length - 2 : 0;
12245
- return a + ".indexOf(" + b + ", " + a + ".length - " + n + ") < 0";
12246
- }),
12247
- contains: textOp(function(a, b) {
12248
- return a + ".indexOf(" + b + ") >= 0";
12249
- }),
12250
- doesnotcontain: textOp(function(a, b) {
12251
- return a + ".indexOf(" + b + ") == -1";
12252
- }),
12253
- matches: textOp(function(a, b) {
12254
- b = b.substring(1, b.length - 1);
12255
- return getMatchRegexp(b) + ".test(" + a + ")";
12256
- }),
12257
- doesnotmatch: textOp(function(a, b) {
12258
- b = b.substring(1, b.length - 1);
12259
- return "!" + getMatchRegexp(b) + ".test(" + a + ")";
12260
- }),
12261
- isempty: function(a) {
12262
- return a + " === ''";
12263
- },
12264
- isnotempty: function(a) {
12265
- return a + " !== ''";
12266
- },
12267
- isnull: function(a) {
12268
- return "(" + a + " == null)";
12269
- },
12270
- isnotnull: function(a) {
12271
- return "(" + a + " != null)";
12272
- },
12273
- isnullorempty: function(a) {
12274
- return "(" + a + " === null) || (" + a + " === '')";
12275
- },
12276
- isnotnullorempty: function(a) {
12277
- return "(" + a + " !== null) && (" + a + " !== '')";
12278
- }
12279
- };
12280
- })();
12281
-
12282
- const filterExpr = function(expression) {
12283
- var expressions = [],
12284
- logic = { and: " && ", or: " || " },
12285
- idx,
12286
- length,
12287
- filter,
12288
- expr$1,
12289
- fieldFunctions = [],
12290
- operatorFunctions = [],
12291
- field,
12292
- operator,
12293
- filters = expression.filters;
12294
-
12295
- for (idx = 0, length = filters.length; idx < length; idx++) {
12296
- filter = filters[idx];
12297
- field = filter.field;
12298
- operator = filter.operator;
12299
-
12300
- if (filter.filters) {
12301
- expr$1 = filterExpr(filter);
12302
- //Nested function fields or operators - update their index e.g. __o[0] -> __o[1]
12303
- filter = expr$1.expression
12304
- .replace(/__o\[(\d+)\]/g, function(match, index) {
12305
- index = +index;
12306
- return "__o[" + (operatorFunctions.length + index) + "]";
12307
- })
12308
- .replace(/__f\[(\d+)\]/g, function(match, index) {
12309
- index = +index;
12310
- return "__f[" + (fieldFunctions.length + index) + "]";
12311
- });
12194
+ let acc = prop;
12312
12195
 
12313
- operatorFunctions.push.apply(operatorFunctions, expr$1.operators);
12314
- fieldFunctions.push.apply(fieldFunctions, expr$1.fields);
12196
+ if (isString(value)) {
12197
+ const date = dateRegExp.exec(value);
12198
+ if (date) {
12199
+ value = new Date(+date[1]);
12315
12200
  } else {
12316
- if (typeof field === 'function') {
12317
- expr$1 = "__f[" + fieldFunctions.length + "](d)";
12318
- fieldFunctions.push(field);
12319
- } else {
12320
- expr$1 = expr(field);
12321
- }
12322
-
12323
- if (typeof operator === 'function') {
12324
- filter = "__o[" + operatorFunctions.length + "](" + expr$1 + ", " + operators.quote(filter.value) + ")";
12325
- operatorFunctions.push(operator);
12326
- } else {
12327
- filter = operators[(operator || "eq").toLowerCase()](expr$1, filter.value, filter.ignoreCase !== undefined ? filter.ignoreCase : true, expression.accentFoldingFiltering);
12328
- }
12201
+ acc = (a) => {
12202
+ const x = prop(a);
12203
+ if (typeof x === "string" && ignoreCase) {
12204
+ return accentFoldingFiltering
12205
+ ? x.toLocaleLowerCase(accentFoldingFiltering)
12206
+ : x.toLowerCase();
12207
+ } else {
12208
+ return isNumeric(x) ? x + "" : x;
12209
+ }
12210
+ };
12329
12211
  }
12212
+ }
12330
12213
 
12331
- expressions.push(filter);
12214
+ if (isDate(value)) {
12215
+ return (a) => {
12216
+ const x = acc(a);
12217
+ return isDate(x) ? x.getTime() : x;
12218
+ };
12332
12219
  }
12220
+ return acc;
12221
+ };
12333
12222
 
12334
- return { expression: "(" + expressions.join(logic[expression.logic]) + ")", fields: fieldFunctions, operators: operatorFunctions };
12223
+ const transformCompositeFilter = function (filter) {
12224
+ const accentFoldingFiltering = filter.accentFoldingFiltering;
12225
+ const combiner = logic[filter.logic || "and"];
12226
+
12227
+ return filter.filters
12228
+ .filter(isPresent)
12229
+ .map((x) => {
12230
+ const extendedFilter = isPresent(accentFoldingFiltering)
12231
+ ? deepExtend({}, x, { accentFoldingFiltering })
12232
+ : x;
12233
+
12234
+ return isPresent(x.filters)
12235
+ ? transformCompositeFilter(extendedFilter)
12236
+ : transformFilter(extendedFilter);
12237
+ })
12238
+ .reduce(combiner.concat, combiner.identity);
12335
12239
  };
12336
12240
 
12337
12241
  /* eslint-disable max-params */
@@ -12446,13 +12350,11 @@
12446
12350
 
12447
12351
  this._criteria = options.criteria;
12448
12352
 
12449
- var expression = filterExpr({
12353
+ this._matches = transformCompositeFilter({
12450
12354
  logic: this._logic,
12451
12355
  filters: this._criteria,
12452
- accentFoldingFiltering: culture().name
12453
- }).expression;
12454
-
12455
- this._matches = new Function("d", "return " + expression);
12356
+ accentFoldingFiltering: culture().name,
12357
+ });
12456
12358
  }
12457
12359
  matches(value) {
12458
12360
  if (value === null) {
@@ -17028,24 +16930,9 @@
17028
16930
  end = begin;
17029
16931
  }
17030
16932
  if (begin && end) {
17031
- let range = document.createRange();
17032
- range.setStart(begin.node, begin.pos);
17033
- range.setEnd(end.node, end.pos);
17034
- let sel = window.getSelection();
17035
- let currentRange = sel.getRangeAt(0);
17036
- if (differ(range, currentRange)) {
17037
- sel.removeAllRanges();
17038
- sel.addRange(range);
17039
- }
17040
- }
17041
- function differ(a, b) {
17042
- return (
17043
- a.startOffset !== b.startOffset ||
17044
- a.endOffset !== b.endOffset ||
17045
- a.startContainer !== b.endContainer ||
17046
- a.endContainer !== b.endContainer
17047
- );
16933
+ this._setRange(begin, end);
17048
16934
  }
16935
+
17049
16936
  function lookup(node, pos) {
17050
16937
  try {
17051
16938
  (function loop(node) {
@@ -17083,6 +16970,27 @@
17083
16970
  return this.value().length;
17084
16971
  }
17085
16972
 
16973
+ _setRange(begin, end) {
16974
+ let range = document.createRange();
16975
+ range.setStart(begin.node, begin.pos);
16976
+ range.setEnd(end.node, end.pos);
16977
+ let sel = window.getSelection();
16978
+ let currentRange = sel.getRangeAt(0);
16979
+ if (differ(range, currentRange)) {
16980
+ sel.removeAllRanges();
16981
+ sel.addRange(range);
16982
+ }
16983
+
16984
+ function differ(a, b) {
16985
+ return (
16986
+ a.startOffset !== b.startOffset ||
16987
+ a.endOffset !== b.endOffset ||
16988
+ a.startContainer !== b.endContainer ||
16989
+ a.endContainer !== b.endContainer
16990
+ );
16991
+ }
16992
+ }
16993
+
17086
16994
  _formulaSource() {
17087
16995
  let result = [];
17088
16996
  let value;
@@ -22975,12 +22883,16 @@
22975
22883
 
22976
22884
  if (file && !this.trigger("excelImport", { file, deferred })) {
22977
22885
  this._clearSheets();
22978
- readExcel(file, this, deferred);
22886
+ this._readExcel(file, this, deferred);
22979
22887
  }
22980
22888
 
22981
22889
  return deferred.promise;
22982
22890
  }
22983
22891
 
22892
+ _readExcel(file, workbook, deferred) {
22893
+ readExcel(file, workbook, deferred);
22894
+ }
22895
+
22984
22896
  saveAsExcel(options) {
22985
22897
  let self = this;
22986
22898
  options = deepExtend({}, self.options.excel, options);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@progress/kendo-spreadsheet-common",
3
3
  "description": "Kendo UI platform-independent Spreadsheet library",
4
- "version": "1.1.3-develop.2",
4
+ "version": "1.1.3-develop.3",
5
5
  "keywords": [
6
6
  "Kendo UI"
7
7
  ],
@@ -29,19 +29,20 @@
29
29
  "devDependencies": {
30
30
  "@commitlint/cli": "^17.3.0",
31
31
  "@commitlint/config-conventional": "^17.3.0",
32
- "@progress/kendo-e2e": "^3.0.1",
32
+ "@progress/kendo-e2e": "^4.0.0",
33
33
  "@progress/kendo-intl": "^3.1.1",
34
+ "@telerik/dx-metrics": "^2.1.8",
34
35
  "@types/jest": "^29.0.0",
36
+ "acorn": "^8.12.0",
35
37
  "es-jest": "^2.1.0",
38
+ "escodegen": "^2.1.0",
36
39
  "eslint": "^8.28.0",
37
40
  "husky": "^8.0.2",
38
41
  "jest-cli": "^29.0.0",
39
42
  "jest-environment-jsdom": "^29.5.0",
40
43
  "rollup": "^3.5.1",
41
44
  "rollup-plugin-watch": "^1.0.4",
42
- "semantic-release": "^24.0.0",
43
- "acorn": "^8.12.0",
44
- "escodegen": "^2.1.0"
45
+ "semantic-release": "^24.0.0"
45
46
  },
46
47
  "repository": {
47
48
  "type": "git",