occam-dom 4.0.16 → 5.0.2

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 (56) hide show
  1. package/bin/main.js +15 -0
  2. package/example.js +38032 -0
  3. package/index.html +47 -0
  4. package/lib/constants.js +13 -0
  5. package/lib/example/constants.js +22 -0
  6. package/lib/example/utilities/query.js +23 -0
  7. package/lib/example/utilities/token.js +28 -0
  8. package/lib/example/view/div/sizeable.js +39 -0
  9. package/lib/example/view/input/maximumDepth.js +143 -0
  10. package/lib/example/view/input.js +39 -0
  11. package/lib/example/view/subHeading.js +39 -0
  12. package/lib/example/view/textarea/content.js +142 -0
  13. package/lib/example/view/textarea/expressions.js +143 -0
  14. package/lib/example/view/textarea/outerNodes.js +147 -0
  15. package/lib/example/view/textarea/parseTree/inner.js +157 -0
  16. package/lib/example/view/textarea/parseTree/outer.js +126 -0
  17. package/lib/example/view/textarea/parseTree.js +148 -0
  18. package/lib/example/view/textarea.js +39 -0
  19. package/lib/example/view.js +245 -0
  20. package/lib/example.js +19 -0
  21. package/lib/index.js +27 -0
  22. package/lib/node.js +302 -0
  23. package/lib/parseTree/childNodes.js +164 -0
  24. package/lib/parseTree/horizontalBranch.js +120 -0
  25. package/lib/parseTree/node.js +145 -0
  26. package/lib/parseTree/string.js +109 -0
  27. package/lib/parseTree/verticalBranch.js +184 -0
  28. package/lib/parseTree.js +191 -0
  29. package/lib/utilities/node.js +81 -0
  30. package/package.json +3 -2
  31. package/src/constants.js +3 -0
  32. package/src/example/constants.js +4 -0
  33. package/src/example/utilities/query.js +21 -0
  34. package/src/example/utilities/token.js +19 -0
  35. package/src/example/view/div/sizeable.js +12 -0
  36. package/src/example/view/input/maximumDepth.js +35 -0
  37. package/src/example/view/input.js +14 -0
  38. package/src/example/view/subHeading.js +16 -0
  39. package/src/example/view/textarea/content.js +33 -0
  40. package/src/example/view/textarea/expressions.js +39 -0
  41. package/src/example/view/textarea/outerNodes.js +48 -0
  42. package/src/example/view/textarea/parseTree/inner.js +24 -0
  43. package/src/example/view/textarea/parseTree/outer.js +17 -0
  44. package/src/example/view/textarea/parseTree.js +28 -0
  45. package/src/example/view/textarea.js +18 -0
  46. package/src/example/view.js +137 -0
  47. package/src/example.js +21 -0
  48. package/src/index.js +4 -0
  49. package/src/node.js +221 -0
  50. package/src/parseTree/childNodes.js +108 -0
  51. package/src/parseTree/horizontalBranch.js +32 -0
  52. package/src/parseTree/node.js +77 -0
  53. package/src/parseTree/string.js +18 -0
  54. package/src/parseTree/verticalBranch.js +77 -0
  55. package/src/parseTree.js +141 -0
  56. package/src/utilities/node.js +104 -0
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ default: function() {
13
+ return _default;
14
+ },
15
+ topmostNodeFromOuterNodes: function() {
16
+ return topmostNodeFromOuterNodes;
17
+ }
18
+ });
19
+ var _node = /*#__PURE__*/ _interop_require_default(require("../node"));
20
+ function _interop_require_default(obj) {
21
+ return obj && obj.__esModule ? obj : {
22
+ default: obj
23
+ };
24
+ }
25
+ function topmostNodeFromOuterNodes(Class, outerNodes) {
26
+ if (outerNodes === undefined) {
27
+ outerNodes = Class; ///
28
+ Class = _node.default; ///
29
+ }
30
+ var nodes = outerNodes; ///
31
+ orderNodes(nodes);
32
+ var topmostNode = _node.default.fromNothing(), outerNodeToNodeMap = new WeakMap();
33
+ outerNodes.forEach(function(outerNode) {
34
+ var ancestorNodes = outerNode.getAncestorNodes();
35
+ var parentNode = topmostNode; ///
36
+ ancestorNodes.some(function(ancestorNode) {
37
+ var _$outerNode = ancestorNode, node = outerNodeToNodeMap.get(_$outerNode) || null;
38
+ if (node !== null) {
39
+ parentNode = node; ///
40
+ return true;
41
+ }
42
+ });
43
+ var node = Class.fromOuterNode(outerNode), childNode = node; ///
44
+ parentNode.addChildNode(childNode);
45
+ outerNodeToNodeMap.set(outerNode, node);
46
+ });
47
+ return topmostNode;
48
+ }
49
+ var _default = {
50
+ topmostNodeFromOuterNodes: topmostNodeFromOuterNodes
51
+ };
52
+ function orderNodes(nodes) {
53
+ nodes.sort(function(nodeA, nodeB) {
54
+ var nodeALessThanNodeB = isLessThan(nodeA, nodeB), result = nodeALessThanNodeB ? -1 : +1;
55
+ return result;
56
+ });
57
+ }
58
+ function isLessThan(nodeA, nodeB) {
59
+ var lessThan = null;
60
+ var ancestorNodesA = ancestorNodesFromNode(nodeA), ancestorNodesB = ancestorNodesFromNode(nodeB), ancestorNodesALength = ancestorNodesA.length, ancestorNodesBLength = ancestorNodesB.length, minimumAncestorNodesLength = Math.min(ancestorNodesALength, ancestorNodesBLength);
61
+ for(var index = 0; index < minimumAncestorNodesLength; index++){
62
+ var ancestorNodeA = ancestorNodesA[index], ancestorNodeB = ancestorNodesB[index];
63
+ if (ancestorNodeA !== ancestorNodeB) {
64
+ var parentIndex = index - 1, ancestorNodeAParentNode = ancestorNodesA[parentIndex], parentNode = ancestorNodeAParentNode, childNodeA = ancestorNodeA, childNodeB = ancestorNodeB, indexA = parentNode.indexOfChildNode(childNodeA), indexB = parentNode.indexOfChildNode(childNodeB);
65
+ lessThan = indexA < indexB;
66
+ break;
67
+ }
68
+ }
69
+ if (lessThan === null) {
70
+ lessThan = ancestorNodesALength < ancestorNodesBLength;
71
+ }
72
+ return lessThan;
73
+ }
74
+ function ancestorNodesFromNode(node) {
75
+ var ancestorNodes = node.getAncestorNodes();
76
+ ancestorNodes.unshift(node);
77
+ ancestorNodes.reverse();
78
+ return ancestorNodes;
79
+ }
80
+
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsaXRpZXMvbm9kZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IE5vZGUgZnJvbSBcIi4uL25vZGVcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHRvcG1vc3ROb2RlRnJvbU91dGVyTm9kZXMoQ2xhc3MsIG91dGVyTm9kZXMpIHtcbiAgaWYgKG91dGVyTm9kZXMgPT09IHVuZGVmaW5lZCkge1xuICAgIG91dGVyTm9kZXMgPSBDbGFzczsgLy8vXG5cbiAgICBDbGFzcyA9IE5vZGU7ICAvLy9cbiAgfVxuXG4gIGNvbnN0IG5vZGVzID0gb3V0ZXJOb2RlczsgLy8vXG5cbiAgb3JkZXJOb2Rlcyhub2Rlcyk7XG5cbiAgY29uc3QgdG9wbW9zdE5vZGUgPSBOb2RlLmZyb21Ob3RoaW5nKCksXG4gICAgICAgIG91dGVyTm9kZVRvTm9kZU1hcCA9IG5ldyBXZWFrTWFwKCk7XG5cbiAgb3V0ZXJOb2Rlcy5mb3JFYWNoKChvdXRlck5vZGUpID0+IHtcbiAgICBjb25zdCBhbmNlc3Rvck5vZGVzID0gb3V0ZXJOb2RlLmdldEFuY2VzdG9yTm9kZXMoKTtcblxuICAgIGxldCBwYXJlbnROb2RlID0gdG9wbW9zdE5vZGU7IC8vL1xuXG4gICAgYW5jZXN0b3JOb2Rlcy5zb21lKChhbmNlc3Rvck5vZGUpID0+IHtcbiAgICAgIGNvbnN0IG91dGVyTm9kZSA9IGFuY2VzdG9yTm9kZSwgLy8vXG4gICAgICAgICAgICBub2RlID0gb3V0ZXJOb2RlVG9Ob2RlTWFwLmdldChvdXRlck5vZGUpIHx8IG51bGw7XG5cbiAgICAgIGlmIChub2RlICE9PSBudWxsKSB7XG4gICAgICAgIHBhcmVudE5vZGUgPSBub2RlOyAgLy8vXG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBub2RlID0gQ2xhc3MuZnJvbU91dGVyTm9kZShvdXRlck5vZGUpLFxuICAgICAgICAgIGNoaWxkTm9kZSA9IG5vZGU7ICAvLy9cblxuICAgIHBhcmVudE5vZGUuYWRkQ2hpbGROb2RlKGNoaWxkTm9kZSk7XG5cbiAgICBvdXRlck5vZGVUb05vZGVNYXAuc2V0KG91dGVyTm9kZSwgbm9kZSk7XG4gIH0pO1xuXG4gIHJldHVybiB0b3Btb3N0Tm9kZTtcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICB0b3Btb3N0Tm9kZUZyb21PdXRlck5vZGVzXG59O1xuXG5mdW5jdGlvbiBvcmRlck5vZGVzKG5vZGVzKSB7XG4gIG5vZGVzLnNvcnQoKG5vZGVBLCBub2RlQikgPT4ge1xuICAgIGNvbnN0IG5vZGVBTGVzc1RoYW5Ob2RlQiA9IGlzTGVzc1RoYW4obm9kZUEsIG5vZGVCKSxcbiAgICAgICAgICByZXN1bHQgPSBub2RlQUxlc3NUaGFuTm9kZUIgP1xuICAgICAgICAgICAgICAgICAgICAgLTEgOlxuICAgICAgICAgICAgICAgICAgICAgICArMTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpc0xlc3NUaGFuKG5vZGVBLCBub2RlQikge1xuICBsZXQgbGVzc1RoYW4gPSBudWxsO1xuXG4gIGNvbnN0IGFuY2VzdG9yTm9kZXNBID0gYW5jZXN0b3JOb2Rlc0Zyb21Ob2RlKG5vZGVBKSxcbiAgICAgICAgYW5jZXN0b3JOb2Rlc0IgPSBhbmNlc3Rvck5vZGVzRnJvbU5vZGUobm9kZUIpLFxuICAgICAgICBhbmNlc3Rvck5vZGVzQUxlbmd0aCA9IGFuY2VzdG9yTm9kZXNBLmxlbmd0aCxcbiAgICAgICAgYW5jZXN0b3JOb2Rlc0JMZW5ndGggPSBhbmNlc3Rvck5vZGVzQi5sZW5ndGgsXG4gICAgICAgIG1pbmltdW1BbmNlc3Rvck5vZGVzTGVuZ3RoID0gTWF0aC5taW4oYW5jZXN0b3JOb2Rlc0FMZW5ndGgsIGFuY2VzdG9yTm9kZXNCTGVuZ3RoKTtcblxuICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbWluaW11bUFuY2VzdG9yTm9kZXNMZW5ndGg7IGluZGV4KyspIHtcbiAgICBjb25zdCBhbmNlc3Rvck5vZGVBID0gYW5jZXN0b3JOb2Rlc0FbaW5kZXhdLFxuICAgICAgICAgIGFuY2VzdG9yTm9kZUIgPSBhbmNlc3Rvck5vZGVzQltpbmRleF07XG5cbiAgICBpZiAoYW5jZXN0b3JOb2RlQSAhPT0gYW5jZXN0b3JOb2RlQikge1xuICAgICAgY29uc3QgcGFyZW50SW5kZXggPSBpbmRleCAtIDEsXG4gICAgICAgICAgICBhbmNlc3Rvck5vZGVBUGFyZW50Tm9kZSA9IGFuY2VzdG9yTm9kZXNBW3BhcmVudEluZGV4XSxcbiAgICAgICAgICAgIHBhcmVudE5vZGUgPSBhbmNlc3Rvck5vZGVBUGFyZW50Tm9kZSwgLy8vXG4gICAgICAgICAgICBjaGlsZE5vZGVBID0gYW5jZXN0b3JOb2RlQSwgLy8vXG4gICAgICAgICAgICBjaGlsZE5vZGVCID0gYW5jZXN0b3JOb2RlQiwgLy8vXG4gICAgICAgICAgICBpbmRleEEgPSBwYXJlbnROb2RlLmluZGV4T2ZDaGlsZE5vZGUoY2hpbGROb2RlQSksXG4gICAgICAgICAgICBpbmRleEIgPSBwYXJlbnROb2RlLmluZGV4T2ZDaGlsZE5vZGUoY2hpbGROb2RlQik7XG5cbiAgICAgIGxlc3NUaGFuID0gKGluZGV4QSA8IGluZGV4Qik7XG5cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChsZXNzVGhhbiA9PT0gbnVsbCkge1xuICAgIGxlc3NUaGFuID0gKGFuY2VzdG9yTm9kZXNBTGVuZ3RoIDwgYW5jZXN0b3JOb2Rlc0JMZW5ndGgpO1xuICB9XG5cbiAgcmV0dXJuIGxlc3NUaGFuO1xufVxuXG5mdW5jdGlvbiBhbmNlc3Rvck5vZGVzRnJvbU5vZGUobm9kZSkge1xuICBjb25zdCBhbmNlc3Rvck5vZGVzID0gbm9kZS5nZXRBbmNlc3Rvck5vZGVzKCk7XG5cbiAgYW5jZXN0b3JOb2Rlcy51bnNoaWZ0KG5vZGUpO1xuXG4gIGFuY2VzdG9yTm9kZXMucmV2ZXJzZSgpO1xuXG4gIHJldHVybiBhbmNlc3Rvck5vZGVzO1xufSJdLCJuYW1lcyI6WyJ0b3Btb3N0Tm9kZUZyb21PdXRlck5vZGVzIiwiQ2xhc3MiLCJvdXRlck5vZGVzIiwidW5kZWZpbmVkIiwiTm9kZSIsIm5vZGVzIiwib3JkZXJOb2RlcyIsInRvcG1vc3ROb2RlIiwiZnJvbU5vdGhpbmciLCJvdXRlck5vZGVUb05vZGVNYXAiLCJXZWFrTWFwIiwiZm9yRWFjaCIsIm91dGVyTm9kZSIsImFuY2VzdG9yTm9kZXMiLCJnZXRBbmNlc3Rvck5vZGVzIiwicGFyZW50Tm9kZSIsInNvbWUiLCJhbmNlc3Rvck5vZGUiLCJub2RlIiwiZ2V0IiwiZnJvbU91dGVyTm9kZSIsImNoaWxkTm9kZSIsImFkZENoaWxkTm9kZSIsInNldCIsInNvcnQiLCJub2RlQSIsIm5vZGVCIiwibm9kZUFMZXNzVGhhbk5vZGVCIiwiaXNMZXNzVGhhbiIsInJlc3VsdCIsImxlc3NUaGFuIiwiYW5jZXN0b3JOb2Rlc0EiLCJhbmNlc3Rvck5vZGVzRnJvbU5vZGUiLCJhbmNlc3Rvck5vZGVzQiIsImFuY2VzdG9yTm9kZXNBTGVuZ3RoIiwibGVuZ3RoIiwiYW5jZXN0b3JOb2Rlc0JMZW5ndGgiLCJtaW5pbXVtQW5jZXN0b3JOb2Rlc0xlbmd0aCIsIk1hdGgiLCJtaW4iLCJpbmRleCIsImFuY2VzdG9yTm9kZUEiLCJhbmNlc3Rvck5vZGVCIiwicGFyZW50SW5kZXgiLCJhbmNlc3Rvck5vZGVBUGFyZW50Tm9kZSIsImNoaWxkTm9kZUEiLCJjaGlsZE5vZGVCIiwiaW5kZXhBIiwiaW5kZXhPZkNoaWxkTm9kZSIsImluZGV4QiIsInVuc2hpZnQiLCJyZXZlcnNlIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7SUE2Q0EsT0FFRTtlQUZGOztJQXpDZ0JBLHlCQUF5QjtlQUF6QkE7OzsyREFGQzs7Ozs7O0FBRVYsU0FBU0EsMEJBQTBCQyxLQUFLLEVBQUVDLFVBQVU7SUFDekQsSUFBSUEsZUFBZUMsV0FBVztRQUM1QkQsYUFBYUQsT0FBTyxHQUFHO1FBRXZCQSxRQUFRRyxhQUFJLEVBQUcsR0FBRztJQUNwQjtJQUVBLElBQU1DLFFBQVFILFlBQVksR0FBRztJQUU3QkksV0FBV0Q7SUFFWCxJQUFNRSxjQUFjSCxhQUFJLENBQUNJLFdBQVcsSUFDOUJDLHFCQUFxQixJQUFJQztJQUUvQlIsV0FBV1MsT0FBTyxDQUFDLFNBQUNDO1FBQ2xCLElBQU1DLGdCQUFnQkQsVUFBVUUsZ0JBQWdCO1FBRWhELElBQUlDLGFBQWFSLGFBQWEsR0FBRztRQUVqQ00sY0FBY0csSUFBSSxDQUFDLFNBQUNDO1lBQ2xCLElBQU1MLGNBQVlLLGNBQ1pDLE9BQU9ULG1CQUFtQlUsR0FBRyxDQUFDUCxnQkFBYztZQUVsRCxJQUFJTSxTQUFTLE1BQU07Z0JBQ2pCSCxhQUFhRyxNQUFPLEdBQUc7Z0JBRXZCLE9BQU87WUFDVDtRQUNGO1FBRUEsSUFBTUEsT0FBT2pCLE1BQU1tQixhQUFhLENBQUNSLFlBQzNCUyxZQUFZSCxNQUFPLEdBQUc7UUFFNUJILFdBQVdPLFlBQVksQ0FBQ0Q7UUFFeEJaLG1CQUFtQmMsR0FBRyxDQUFDWCxXQUFXTTtJQUNwQztJQUVBLE9BQU9YO0FBQ1Q7SUFFQSxXQUFlO0lBQ2JQLDJCQUFBQTtBQUNGO0FBRUEsU0FBU00sV0FBV0QsS0FBSztJQUN2QkEsTUFBTW1CLElBQUksQ0FBQyxTQUFDQyxPQUFPQztRQUNqQixJQUFNQyxxQkFBcUJDLFdBQVdILE9BQU9DLFFBQ3ZDRyxTQUFTRixxQkFDRSxDQUFDLElBQ0MsQ0FBQztRQUVwQixPQUFPRTtJQUNUO0FBQ0Y7QUFFQSxTQUFTRCxXQUFXSCxLQUFLLEVBQUVDLEtBQUs7SUFDOUIsSUFBSUksV0FBVztJQUVmLElBQU1DLGlCQUFpQkMsc0JBQXNCUCxRQUN2Q1EsaUJBQWlCRCxzQkFBc0JOLFFBQ3ZDUSx1QkFBdUJILGVBQWVJLE1BQU0sRUFDNUNDLHVCQUF1QkgsZUFBZUUsTUFBTSxFQUM1Q0UsNkJBQTZCQyxLQUFLQyxHQUFHLENBQUNMLHNCQUFzQkU7SUFFbEUsSUFBSyxJQUFJSSxRQUFRLEdBQUdBLFFBQVFILDRCQUE0QkcsUUFBUztRQUMvRCxJQUFNQyxnQkFBZ0JWLGNBQWMsQ0FBQ1MsTUFBTSxFQUNyQ0UsZ0JBQWdCVCxjQUFjLENBQUNPLE1BQU07UUFFM0MsSUFBSUMsa0JBQWtCQyxlQUFlO1lBQ25DLElBQU1DLGNBQWNILFFBQVEsR0FDdEJJLDBCQUEwQmIsY0FBYyxDQUFDWSxZQUFZLEVBQ3JENUIsYUFBYTZCLHlCQUNiQyxhQUFhSixlQUNiSyxhQUFhSixlQUNiSyxTQUFTaEMsV0FBV2lDLGdCQUFnQixDQUFDSCxhQUNyQ0ksU0FBU2xDLFdBQVdpQyxnQkFBZ0IsQ0FBQ0Y7WUFFM0NoQixXQUFZaUIsU0FBU0U7WUFFckI7UUFDRjtJQUNGO0lBRUEsSUFBSW5CLGFBQWEsTUFBTTtRQUNyQkEsV0FBWUksdUJBQXVCRTtJQUNyQztJQUVBLE9BQU9OO0FBQ1Q7QUFFQSxTQUFTRSxzQkFBc0JkLElBQUk7SUFDakMsSUFBTUwsZ0JBQWdCSyxLQUFLSixnQkFBZ0I7SUFFM0NELGNBQWNxQyxPQUFPLENBQUNoQztJQUV0QkwsY0FBY3NDLE9BQU87SUFFckIsT0FBT3RDO0FBQ1QifQ==
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "occam-dom",
3
3
  "author": "James Smith",
4
- "version": "4.0.16",
4
+ "version": "5.0.2",
5
5
  "license": "MIT, Anti-996",
6
6
  "homepage": "https://github.com/djalbat/occam-dom",
7
7
  "description": "Occam's DOM related functionality.",
@@ -10,7 +10,8 @@
10
10
  "url": "https://github.com/djalbat/occam-dom"
11
11
  },
12
12
  "dependencies": {
13
- "occam-parsers": "^23.0.111"
13
+ "occam-parsers": "^23.0.114",
14
+ "occam-query": "^4.1.73"
14
15
  },
15
16
  "devDependencies": {
16
17
  "@swc/core": "^1.5.6",
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+
3
+ export const EMPTY_STRING = "";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export const SPACE = 2;
4
+ export const EMPTY_STRING = "";
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ import { arrayUtilities } from "necessary";
4
+ import { queryUtilities } from "occam-query";
5
+
6
+ const { push } = arrayUtilities,
7
+ { queryByExpressionString } = queryUtilities;
8
+
9
+ export function queryByExpressions(node, expressions, maximumDepth) {
10
+ const nodes = expressions.reduce((nodes, expression) => {
11
+ const expressionString = expression, ///
12
+ expressionNodes = queryByExpressionString(node, expressionString, maximumDepth);
13
+
14
+ push(nodes, expressionNodes);
15
+
16
+ return nodes;
17
+ }, []);
18
+
19
+ return nodes;
20
+ }
21
+
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ export function tokenIndexFromTerminalNodeAndTokens(terminalNode, tokens) {
4
+ const significantToken = terminalNode.getSignificantToken(),
5
+ significantTokenIndex = tokens.indexOf(significantToken),
6
+ tokenIndex = `(${significantTokenIndex})`;
7
+
8
+ return tokenIndex;
9
+ }
10
+
11
+ export function tokenIndexesFromNonTerminalNodeAndTokens(nonTerminalNode, tokens) {
12
+ const firstSignificantTokenIndex = nonTerminalNode.getFirstSignificantTokenIndex(tokens),
13
+ lastSignificantTokenIndex = nonTerminalNode.getLastSignificantTokenIndex(tokens),
14
+ tokenIndexes = (firstSignificantTokenIndex !== lastSignificantTokenIndex) ?
15
+ `(${firstSignificantTokenIndex}-${lastSignificantTokenIndex})` :
16
+ `(${firstSignificantTokenIndex})`;
17
+
18
+ return tokenIndexes;
19
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ import withStyle from "easy-with-style"; ///
4
+
5
+ import { SizeableDiv } from "easy-layout";
6
+
7
+ export default withStyle(SizeableDiv)`
8
+
9
+ width: 48rem;
10
+ min-width: 24rem;
11
+
12
+ `;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ import Input from "../input";
4
+
5
+ export default class MaximumDepthInput extends Input {
6
+ getMaximumDepth() {
7
+ const value = this.getValue(),
8
+ maximumDepth = Number(value);
9
+
10
+ return maximumDepth;
11
+ }
12
+
13
+ setMaximumDepth(maximumDepth) {
14
+ const value = maximumDepth; ///
15
+
16
+ this.setValue(value);
17
+ }
18
+
19
+ parentContext() {
20
+ const getMaximumDepth = this.getMaximumDepth.bind(this),
21
+ setMaximumDepth = this.setMaximumDepth.bind(this),
22
+ setMaximumDepthReadOnly = this.setReadOnly.bind(this); ///;
23
+
24
+ return ({
25
+ getMaximumDepth,
26
+ setMaximumDepth,
27
+ setMaximumDepthReadOnly
28
+ });
29
+ }
30
+
31
+ static defaultProperties = {
32
+ className: "maximum-depth",
33
+ spellCheck: "false"
34
+ };
35
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ import withStyle from "easy-with-style"; ///
4
+
5
+ import { Input } from "easy";
6
+
7
+ export default withStyle(Input)`
8
+
9
+ border: 1px solid darkgrey;
10
+ padding: 0.25rem;
11
+ font-size: 1.2rem;
12
+ font-family: monospace;
13
+
14
+ `;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ import withStyle from "easy-with-style"; ///
4
+
5
+ const SubHeading = withStyle.h2`
6
+
7
+ margin: 1rem 0 0.5rem 0;
8
+ font-size: 2rem;
9
+
10
+ :first-of-type {
11
+ margin-top: 0;
12
+ }
13
+
14
+ `;
15
+
16
+ export default SubHeading;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ import Textarea from "../textarea";
4
+
5
+ export default class ContentTextarea extends Textarea {
6
+ getContent() {
7
+ const value = this.getValue(),
8
+ content = value; ///
9
+
10
+ return content;
11
+ }
12
+
13
+ setContent(content) {
14
+ const value = content;
15
+
16
+ this.setValue(value);
17
+ }
18
+
19
+ parentContext() {
20
+ const getContent = this.getContent.bind(this),
21
+ setContent = this.setContent.bind(this);
22
+
23
+ return ({
24
+ getContent,
25
+ setContent
26
+ });
27
+ }
28
+
29
+ static defaultProperties = {
30
+ className: "content",
31
+ spellCheck: "false"
32
+ };
33
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ import Textarea from "../textarea";
4
+
5
+ import { SPACE } from "../../constants";
6
+
7
+ export default class ExpressionsTextarea extends Textarea {
8
+ getExpressions() {
9
+ const value = this.getValue(),
10
+ expressionString = value, ///
11
+ expressions = JSON.parse(expressionString); ///
12
+
13
+ return expressions;
14
+ }
15
+
16
+ setExpressions(expressions) {
17
+ const space = SPACE,
18
+ replacer = null,
19
+ expressionsString = JSON.stringify(expressions, replacer, space),
20
+ value = expressionsString; ///
21
+
22
+ this.setValue(value);
23
+ }
24
+
25
+ parentContext() {
26
+ const getExpressions = this.getExpressions.bind(this),
27
+ setExpressions = this.setExpressions.bind(this); ///;
28
+
29
+ return ({
30
+ getExpressions,
31
+ setExpressions
32
+ });
33
+ }
34
+
35
+ static defaultProperties = {
36
+ className: "expressions",
37
+ spellCheck: "false"
38
+ };
39
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ import Textarea from "../textarea";
4
+
5
+ import { EMPTY_STRING } from "../../constants";
6
+ import { tokenIndexFromTerminalNodeAndTokens, tokenIndexesFromNonTerminalNodeAndTokens } from "../../utilities/token"
7
+
8
+ export default class OuterNodesTextarea extends Textarea {
9
+ setOuterNodes(outerNodes, tokens) {
10
+ const nodes = outerNodes, ///
11
+ value = nodes.reduce((value, node) => {
12
+ const nodeTerminalNode = node.isTerminalNode();
13
+
14
+ if (nodeTerminalNode) {
15
+ const terminalNode = node, ///
16
+ significantToken = terminalNode.getSignificantToken(),
17
+ significantTokenType = significantToken.getType(),
18
+ tokenIndex = tokenIndexFromTerminalNodeAndTokens(terminalNode, tokens);
19
+
20
+ value = `${value}[${significantTokenType}]${tokenIndex}\n`;
21
+ } else {
22
+ const nonTerminalNode = node, ///
23
+ ruleName = nonTerminalNode.getRuleName(),
24
+ tokenIndexes = tokenIndexesFromNonTerminalNodeAndTokens(nonTerminalNode, tokens);
25
+
26
+ value = `${value}${ruleName}${tokenIndexes}\n`;
27
+ }
28
+
29
+ return value;
30
+ }, EMPTY_STRING);
31
+
32
+ this.setValue(value);
33
+ }
34
+
35
+ parentContext() {
36
+ const setOuterNodes = this.setOuterNodes.bind(this);
37
+
38
+ return ({
39
+ setOuterNodes
40
+ });
41
+ }
42
+
43
+ static defaultProperties = {
44
+ className: "outer-nodes",
45
+ spellCheck: "false",
46
+ readOnly: true
47
+ };
48
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ import ParseTreeTextarea from "../../textarea/parseTree";
4
+
5
+ export default class InnerParseTreeTextarea extends ParseTreeTextarea {
6
+ setParseTree(parseTree) {
7
+ parseTree.shiftLine(); //
8
+ parseTree.shiftLine(); //
9
+
10
+ super.setParseTree(parseTree);
11
+ }
12
+
13
+ parentContext() {
14
+ const setInnerParseTree = this.setParseTree.bind(this); ///
15
+
16
+ return ({
17
+ setInnerParseTree
18
+ });
19
+ }
20
+
21
+ static defaultProperties = {
22
+ className: "inner"
23
+ };
24
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ import ParseTreeTextarea from "../../textarea/parseTree";
4
+
5
+ export default class OuterParseTreeTextarea extends ParseTreeTextarea {
6
+ parentContext() {
7
+ const setOuterParseTree = this.setParseTree.bind(this); ///
8
+
9
+ return ({
10
+ setOuterParseTree
11
+ });
12
+ }
13
+
14
+ static defaultProperties = {
15
+ className: "outer"
16
+ };
17
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ import withStyle from "easy-with-style"; ///
4
+
5
+ import Textarea from "../textarea";
6
+
7
+ class ParseTreeTextarea extends Textarea {
8
+ setParseTree(parseTree) {
9
+ parseTree.shiftLine(); //
10
+
11
+ const parseTreeString = parseTree.asString(),
12
+ value = parseTreeString; ///
13
+
14
+ this.setValue(value);
15
+ }
16
+
17
+ static defaultProperties = {
18
+ className: "parse-tree",
19
+ spellCheck: "false",
20
+ readOnly: true
21
+ };
22
+ }
23
+
24
+ export default withStyle(ParseTreeTextarea)`
25
+
26
+ height: 32rem;
27
+
28
+ `;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ import withStyle from "easy-with-style"; ///
4
+
5
+ import { Textarea } from "easy";
6
+
7
+ export default withStyle(Textarea)`
8
+
9
+ border: 1px solid darkgrey;
10
+ height: 12rem;
11
+ resize: vertical;
12
+ padding: 0.25rem;
13
+ font-size: 1.2rem;
14
+ line-height: 1.5rem;
15
+ white-space: pre;
16
+ font-family: monospace;
17
+
18
+ `;
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+
3
+ import withStyle from "easy-with-style"; ///
4
+
5
+ import { Element } from "easy";
6
+ import { nodeUtilities } from "../index" ///
7
+ import { CSSLexer, CSSParser } from "with-style";
8
+ import { RowsDiv, ColumnDiv, ColumnsDiv, VerticalSplitterDiv } from "easy-layout";
9
+
10
+ import SubHeading from "./view/subHeading";
11
+ import SizeableDiv from "./view/div/sizeable";
12
+ import ContentTextarea from "./view/textarea/content";
13
+ import MaximumDepthInput from "./view/input/maximumDepth";
14
+ import OuterNodesTextarea from "./view/textarea/outerNodes";
15
+ import ExpressionsTextarea from "./view/textarea/expressions";
16
+ import OuterParseTreeTextarea from "./view/textarea/parseTree/outer";
17
+ import InnerParseTreeTextarea from "./view/textarea/parseTree/inner";
18
+
19
+ import { queryByExpressions } from "./utilities/query";
20
+
21
+ const { topmostNodeFromOuterNodes: topmostInnerNodeFromOuterNodes } = nodeUtilities;
22
+
23
+ const cssLexer = CSSLexer.fromNothing(),
24
+ cssParser = CSSParser.fromNothing();
25
+
26
+ class View extends Element {
27
+ keyUpHandler = (event, element) => {
28
+ const content = this.getContent(),
29
+ tokens = cssLexer.tokenise(content),
30
+ node = cssParser.parse(tokens);
31
+
32
+ if (node === null) {
33
+ return;
34
+ }
35
+
36
+ const outerNode = node, ///
37
+ expressions = this.getExpressions(),
38
+ maximumDepth = this.getMaximumDepth(),
39
+ outerNodes = queryByExpressions(outerNode, expressions, maximumDepth),
40
+ topmostInnerNode = topmostInnerNodeFromOuterNodes(outerNodes),
41
+ innerNode = topmostInnerNode, ///
42
+ outerParseTree = outerNode.asParseTree(tokens),
43
+ innerParseTree = innerNode.asParseTree();
44
+
45
+ this.setOuterNodes(outerNodes, tokens); ///
46
+
47
+ this.setOuterParseTree(outerParseTree);
48
+
49
+ this.setInnerParseTree(innerParseTree);
50
+ }
51
+
52
+ childElements() {
53
+ return ([
54
+
55
+ <ColumnsDiv>
56
+ <SizeableDiv>
57
+ <RowsDiv>
58
+ <SubHeading>
59
+ Content
60
+ </SubHeading>
61
+ <ContentTextarea onKeyUp={this.keyUpHandler} />
62
+ <SubHeading>
63
+ Expressions
64
+ </SubHeading>
65
+ <ExpressionsTextarea onKeyUp={this.keyUpHandler} />
66
+ <SubHeading>
67
+ Maximum depth
68
+ </SubHeading>
69
+ <MaximumDepthInput onKeyUp={this.keyUpHandler} />
70
+ <SubHeading>
71
+ Outer nodes
72
+ </SubHeading>
73
+ <OuterNodesTextarea/>
74
+ </RowsDiv>
75
+ </SizeableDiv>
76
+ <VerticalSplitterDiv />
77
+ <ColumnDiv>
78
+ <RowsDiv>
79
+ <SubHeading>
80
+ Outer parse tree
81
+ </SubHeading>
82
+ <OuterParseTreeTextarea/>
83
+ <SubHeading>
84
+ Inner parse tree
85
+ </SubHeading>
86
+ <InnerParseTreeTextarea/>
87
+ </RowsDiv>
88
+ </ColumnDiv>
89
+ </ColumnsDiv>
90
+
91
+ ]);
92
+ }
93
+
94
+ initialise() {
95
+ this.assignContext();
96
+
97
+ const { initialContent, initialExpressions, initialMaximumDepth } = this.constructor,
98
+ content = initialContent, ///
99
+ maximumDepth = initialMaximumDepth, ///
100
+ expressions = initialExpressions; ///
101
+
102
+ this.setContent(content);
103
+
104
+ this.setMaximumDepth(maximumDepth);
105
+
106
+ this.setExpressions(expressions);
107
+
108
+ this.keyUpHandler(); ///
109
+ }
110
+
111
+ static initialContent = `.view {
112
+ background: red;
113
+ }
114
+ `;
115
+
116
+ static initialExpressions = [
117
+ "//term",
118
+ "//ruleSet",
119
+ "//selectors",
120
+ "//propertyName",
121
+ "//@identifier"
122
+ ];
123
+
124
+ static initialMaximumDepth = 5;
125
+
126
+ static tagName = "div";
127
+
128
+ static defaultProperties = {
129
+ className: "view"
130
+ };
131
+ }
132
+
133
+ export default withStyle(View)`
134
+
135
+ padding: 1rem;
136
+
137
+ `;
package/src/example.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ import "juxtapose";
4
+
5
+ import withStyle from "easy-with-style"; ///
6
+
7
+ import { Body } from "easy";
8
+
9
+ import View from "./example/view";
10
+
11
+ const { renderStyles } = withStyle;
12
+
13
+ const body = new Body();
14
+
15
+ renderStyles();
16
+
17
+ body.mount(
18
+
19
+ <View/>
20
+
21
+ );
package/src/index.js ADDED
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export { default as Node } from "./node";
4
+ export { default as nodeUtilities } from "./utilities/node";