symfony-expression-editor 0.2.0 → 1.0.0

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.cjs CHANGED
@@ -870,14 +870,14 @@ const replaceNext = /* @__PURE__ */ searchCommand((view$1, { query }) => {
870
870
  next = query.nextMatch(state$1, next.from, next.to);
871
871
  effects.push(view.EditorView.announce.of(state$1.phrase("replaced match on line $", state$1.doc.lineAt(from).number) + "."));
872
872
  }
873
+ let changeSet = view$1.state.changes(changes);
873
874
  if (next) {
874
- let off = changes.length == 0 || changes[0].from >= match.to ? 0 : match.to - match.from - replacement.length;
875
- selection = state.EditorSelection.single(next.from - off, next.to - off);
875
+ selection = state.EditorSelection.single(next.from, next.to).map(changeSet);
876
876
  effects.push(announceMatch(view$1, next));
877
877
  effects.push(state$1.facet(searchConfigFacet).scrollToMatch(selection.main, view$1));
878
878
  }
879
879
  view$1.dispatch({
880
- changes,
880
+ changes: changeSet,
881
881
  selection,
882
882
  effects,
883
883
  userEvent: "input.replace"
@@ -1148,6 +1148,22 @@ const searchExtensions = [
1148
1148
  baseTheme$2
1149
1149
  ];
1150
1150
 
1151
+ var __defProp = Object.defineProperty;
1152
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
1153
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
1154
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
1155
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1156
+ var __spreadValues = (a, b) => {
1157
+ for (var prop in b || (b = {}))
1158
+ if (__hasOwnProp.call(b, prop))
1159
+ __defNormalProp(a, prop, b[prop]);
1160
+ if (__getOwnPropSymbols)
1161
+ for (var prop of __getOwnPropSymbols(b)) {
1162
+ if (__propIsEnum.call(b, prop))
1163
+ __defNormalProp(a, prop, b[prop]);
1164
+ }
1165
+ return a;
1166
+ };
1151
1167
  class SelectedDiagnostic {
1152
1168
  constructor(from, to, diagnostic) {
1153
1169
  this.from = from;
@@ -1167,6 +1183,7 @@ class LintState {
1167
1183
  diagnostics = diagnosticFilter(diagnostics, state$1);
1168
1184
  let sorted = diagnostics.slice().sort((a, b) => a.from - b.from || a.to - b.to);
1169
1185
  let deco = new state.RangeSetBuilder(), active = [], pos = 0;
1186
+ let scan = state$1.doc.iter(), scanPos = 0, docLen = state$1.doc.length;
1170
1187
  for (let i = 0; ; ) {
1171
1188
  let next = i == sorted.length ? null : sorted[i];
1172
1189
  if (!next && !active.length)
@@ -1177,6 +1194,8 @@ class LintState {
1177
1194
  to = active.reduce((p, d) => Math.min(p, d.to), next && next.from > from ? next.from : 1e8);
1178
1195
  } else {
1179
1196
  from = next.from;
1197
+ if (from > docLen)
1198
+ break;
1180
1199
  to = next.to;
1181
1200
  active.push(next);
1182
1201
  i++;
@@ -1192,8 +1211,31 @@ class LintState {
1192
1211
  break;
1193
1212
  }
1194
1213
  }
1214
+ to = Math.min(to, docLen);
1215
+ let widget = false;
1216
+ if (active.some((d) => d.from == from && (d.to == to || to == docLen))) {
1217
+ widget = from == to;
1218
+ if (!widget && to - from < 10) {
1219
+ let behind = from - (scanPos + scan.value.length);
1220
+ if (behind > 0) {
1221
+ scan.next(behind);
1222
+ scanPos = from;
1223
+ }
1224
+ for (let check = from; ; ) {
1225
+ if (check >= to) {
1226
+ widget = true;
1227
+ break;
1228
+ }
1229
+ if (!scan.lineBreak && scanPos + scan.value.length > check)
1230
+ break;
1231
+ check = scanPos + scan.value.length;
1232
+ scanPos += scan.value.length;
1233
+ scan.next();
1234
+ }
1235
+ }
1236
+ }
1195
1237
  let sev = maxSeverity(active);
1196
- if (active.some((d) => d.from == d.to || d.from == d.to - 1 && state$1.doc.lineAt(d.from).to == d.from)) {
1238
+ if (widget) {
1197
1239
  deco.add(from, from, view.Decoration.widget({
1198
1240
  widget: new DiagnosticWidget(sev),
1199
1241
  diagnostics: active.slice()
@@ -1207,6 +1249,8 @@ class LintState {
1207
1249
  }));
1208
1250
  }
1209
1251
  pos = to;
1252
+ if (pos == docLen)
1253
+ break;
1210
1254
  for (let i2 = 0; i2 < active.length; i2++)
1211
1255
  if (active[i2].to <= pos)
1212
1256
  active.splice(i2--, 1);
@@ -1339,17 +1383,27 @@ const lintKeymap = [
1339
1383
  ];
1340
1384
  const lintConfig = /* @__PURE__ */ state.Facet.define({
1341
1385
  combine(input) {
1342
- return Object.assign({ sources: input.map((i) => i.source).filter((x) => x != null) }, state.combineConfig(input.map((i) => i.config), {
1386
+ return __spreadValues({
1387
+ sources: input.map((i) => i.source).filter((x) => x != null)
1388
+ }, state.combineConfig(input.map((i) => i.config), {
1343
1389
  delay: 750,
1344
1390
  markerFilter: null,
1345
1391
  tooltipFilter: null,
1346
1392
  needsRefresh: null,
1347
1393
  hideOn: () => null
1348
1394
  }, {
1349
- needsRefresh: (a, b) => !a ? b : !b ? a : (u) => a(u) || b(u)
1395
+ delay: Math.max,
1396
+ markerFilter: combineFilter,
1397
+ tooltipFilter: combineFilter,
1398
+ needsRefresh: (a, b) => !a ? b : !b ? a : (u) => a(u) || b(u),
1399
+ hideOn: (a, b) => !a ? b : !b ? a : (t, x, y) => a(t, x, y) || b(t, x, y),
1400
+ autoPanel: (a, b) => a || b
1350
1401
  }));
1351
1402
  }
1352
1403
  });
1404
+ function combineFilter(a, b) {
1405
+ return !a ? b : !b ? a : (d, s) => b(a(d, s), s);
1406
+ }
1353
1407
  function assignKeys(actions) {
1354
1408
  let assigned = [];
1355
1409
  if (actions)
@@ -1384,9 +1438,10 @@ function renderDiagnostic(view, diagnostic, inPanel) {
1384
1438
  crelt("u", name.slice(keyIndex, keyIndex + 1)),
1385
1439
  name.slice(keyIndex + 1)
1386
1440
  ];
1441
+ let markClass = action.markClass ? " " + action.markClass : "";
1387
1442
  return crelt("button", {
1388
1443
  type: "button",
1389
- class: "cm-diagnosticAction",
1444
+ class: "cm-diagnosticAction" + markClass,
1390
1445
  onclick: click,
1391
1446
  onmousedown: click,
1392
1447
  "aria-label": ` Action: ${name}${keyIndex < 0 ? "" : ` (access key "${keys[i]})"`}.`
package/dist/index.mjs CHANGED
@@ -868,14 +868,14 @@ const replaceNext = /* @__PURE__ */ searchCommand((view, { query }) => {
868
868
  next = query.nextMatch(state, next.from, next.to);
869
869
  effects.push(EditorView.announce.of(state.phrase("replaced match on line $", state.doc.lineAt(from).number) + "."));
870
870
  }
871
+ let changeSet = view.state.changes(changes);
871
872
  if (next) {
872
- let off = changes.length == 0 || changes[0].from >= match.to ? 0 : match.to - match.from - replacement.length;
873
- selection = EditorSelection.single(next.from - off, next.to - off);
873
+ selection = EditorSelection.single(next.from, next.to).map(changeSet);
874
874
  effects.push(announceMatch(view, next));
875
875
  effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main, view));
876
876
  }
877
877
  view.dispatch({
878
- changes,
878
+ changes: changeSet,
879
879
  selection,
880
880
  effects,
881
881
  userEvent: "input.replace"
@@ -1146,6 +1146,22 @@ const searchExtensions = [
1146
1146
  baseTheme$2
1147
1147
  ];
1148
1148
 
1149
+ var __defProp = Object.defineProperty;
1150
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
1151
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
1152
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
1153
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1154
+ var __spreadValues = (a, b) => {
1155
+ for (var prop in b || (b = {}))
1156
+ if (__hasOwnProp.call(b, prop))
1157
+ __defNormalProp(a, prop, b[prop]);
1158
+ if (__getOwnPropSymbols)
1159
+ for (var prop of __getOwnPropSymbols(b)) {
1160
+ if (__propIsEnum.call(b, prop))
1161
+ __defNormalProp(a, prop, b[prop]);
1162
+ }
1163
+ return a;
1164
+ };
1149
1165
  class SelectedDiagnostic {
1150
1166
  constructor(from, to, diagnostic) {
1151
1167
  this.from = from;
@@ -1165,6 +1181,7 @@ class LintState {
1165
1181
  diagnostics = diagnosticFilter(diagnostics, state);
1166
1182
  let sorted = diagnostics.slice().sort((a, b) => a.from - b.from || a.to - b.to);
1167
1183
  let deco = new RangeSetBuilder(), active = [], pos = 0;
1184
+ let scan = state.doc.iter(), scanPos = 0, docLen = state.doc.length;
1168
1185
  for (let i = 0; ; ) {
1169
1186
  let next = i == sorted.length ? null : sorted[i];
1170
1187
  if (!next && !active.length)
@@ -1175,6 +1192,8 @@ class LintState {
1175
1192
  to = active.reduce((p, d) => Math.min(p, d.to), next && next.from > from ? next.from : 1e8);
1176
1193
  } else {
1177
1194
  from = next.from;
1195
+ if (from > docLen)
1196
+ break;
1178
1197
  to = next.to;
1179
1198
  active.push(next);
1180
1199
  i++;
@@ -1190,8 +1209,31 @@ class LintState {
1190
1209
  break;
1191
1210
  }
1192
1211
  }
1212
+ to = Math.min(to, docLen);
1213
+ let widget = false;
1214
+ if (active.some((d) => d.from == from && (d.to == to || to == docLen))) {
1215
+ widget = from == to;
1216
+ if (!widget && to - from < 10) {
1217
+ let behind = from - (scanPos + scan.value.length);
1218
+ if (behind > 0) {
1219
+ scan.next(behind);
1220
+ scanPos = from;
1221
+ }
1222
+ for (let check = from; ; ) {
1223
+ if (check >= to) {
1224
+ widget = true;
1225
+ break;
1226
+ }
1227
+ if (!scan.lineBreak && scanPos + scan.value.length > check)
1228
+ break;
1229
+ check = scanPos + scan.value.length;
1230
+ scanPos += scan.value.length;
1231
+ scan.next();
1232
+ }
1233
+ }
1234
+ }
1193
1235
  let sev = maxSeverity(active);
1194
- if (active.some((d) => d.from == d.to || d.from == d.to - 1 && state.doc.lineAt(d.from).to == d.from)) {
1236
+ if (widget) {
1195
1237
  deco.add(from, from, Decoration.widget({
1196
1238
  widget: new DiagnosticWidget(sev),
1197
1239
  diagnostics: active.slice()
@@ -1205,6 +1247,8 @@ class LintState {
1205
1247
  }));
1206
1248
  }
1207
1249
  pos = to;
1250
+ if (pos == docLen)
1251
+ break;
1208
1252
  for (let i2 = 0; i2 < active.length; i2++)
1209
1253
  if (active[i2].to <= pos)
1210
1254
  active.splice(i2--, 1);
@@ -1337,17 +1381,27 @@ const lintKeymap = [
1337
1381
  ];
1338
1382
  const lintConfig = /* @__PURE__ */ Facet.define({
1339
1383
  combine(input) {
1340
- return Object.assign({ sources: input.map((i) => i.source).filter((x) => x != null) }, combineConfig(input.map((i) => i.config), {
1384
+ return __spreadValues({
1385
+ sources: input.map((i) => i.source).filter((x) => x != null)
1386
+ }, combineConfig(input.map((i) => i.config), {
1341
1387
  delay: 750,
1342
1388
  markerFilter: null,
1343
1389
  tooltipFilter: null,
1344
1390
  needsRefresh: null,
1345
1391
  hideOn: () => null
1346
1392
  }, {
1347
- needsRefresh: (a, b) => !a ? b : !b ? a : (u) => a(u) || b(u)
1393
+ delay: Math.max,
1394
+ markerFilter: combineFilter,
1395
+ tooltipFilter: combineFilter,
1396
+ needsRefresh: (a, b) => !a ? b : !b ? a : (u) => a(u) || b(u),
1397
+ hideOn: (a, b) => !a ? b : !b ? a : (t, x, y) => a(t, x, y) || b(t, x, y),
1398
+ autoPanel: (a, b) => a || b
1348
1399
  }));
1349
1400
  }
1350
1401
  });
1402
+ function combineFilter(a, b) {
1403
+ return !a ? b : !b ? a : (d, s) => b(a(d, s), s);
1404
+ }
1351
1405
  function assignKeys(actions) {
1352
1406
  let assigned = [];
1353
1407
  if (actions)
@@ -1382,9 +1436,10 @@ function renderDiagnostic(view, diagnostic, inPanel) {
1382
1436
  crelt("u", name.slice(keyIndex, keyIndex + 1)),
1383
1437
  name.slice(keyIndex + 1)
1384
1438
  ];
1439
+ let markClass = action.markClass ? " " + action.markClass : "";
1385
1440
  return crelt("button", {
1386
1441
  type: "button",
1387
- class: "cm-diagnosticAction",
1442
+ class: "cm-diagnosticAction" + markClass,
1388
1443
  onclick: click,
1389
1444
  onmousedown: click,
1390
1445
  "aria-label": ` Action: ${name}${keyIndex < 0 ? "" : ` (access key "${keys[i]})"`}.`
package/package.json CHANGED
@@ -17,7 +17,8 @@
17
17
  "build": "pkgroll",
18
18
  "dev": "pkgroll --watch",
19
19
  "pretest": "npm run-script build",
20
- "test": "exit 0 # some day we have tests here"
20
+ "test": "playwright test",
21
+ "test:e2e": "playwright test"
21
22
  },
22
23
  "description": "Advanced editor for Symfony Expression Language",
23
24
  "dependencies": {
@@ -32,7 +33,10 @@
32
33
  },
33
34
  "devDependencies": {
34
35
  "pkgroll": "^2.11.2",
35
- "typescript": "^5.8.2"
36
+ "typescript": "^5.8.2",
37
+ "@types/node": "^20.11.0",
38
+ "@playwright/test": "^1.40.0",
39
+ "playwright": "^1.40.0"
36
40
  },
37
41
  "license": "MIT",
38
42
  "repository": {
@@ -43,5 +47,5 @@
43
47
  "access": "public",
44
48
  "registry": "https://registry.npmjs.org/"
45
49
  },
46
- "version": "0.2.0"
50
+ "version": "1.0.0"
47
51
  }