Skip to content

Commit 83b14c9

Browse files
committed
local deep query selector copy
SQUASHED: AUTO-COMMIT-src-client-reactive-new-rewriting-implementation.md,fixed-unstable-import-for-lively-smaug,Merge-branch-gh-pages-of-https-github.com-LivelyKernel-lively4-core-into-gh-pages,
1 parent b14b6cd commit 83b14c9

File tree

9 files changed

+388
-7
lines changed

9 files changed

+388
-7
lines changed

src/client/lively.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ export default class Lively {
14731473
var pattern = patternOrPosition;
14741474
}
14751475

1476-
if (!url || !url.match(/^[a-z]+:\/\//)) url = lively4url;
1476+
if (!url || !url.match(/^[a-z]+:/)) url = lively4url;
14771477
var livelyContainer;
14781478
var containerPromise;
14791479
let existingFound = false;

src/client/reactive/new-rewriting-implementation.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ function foo() {
5656

5757
thus, while analysing an expression, dependencies are still gathered, but outside the analysis, we only need to check one global boolean (which requires not only less redundant computation but also is more JIT friendly because we do not have centralized functions that are hard to optimize).
5858

59+
### advantages
60+
61+
- low impact on standard js expectations
62+
- no 'cannot read [prop] of obj' anymore
63+
- low perf impact
64+
5965
### caveats
6066

6167
1. arrow functionExpressions may need to be rewritten to have a block as body
@@ -82,8 +88,10 @@ idea: instead of a central data structutr, keep refereces to aexprs for locals i
8288

8389
idea: local variables only need to be tracked, if
8490
- they leave their initial scope of declaration (= there is at least one read (#TODO: not sure if a read requires tracking) or write access to that variable in a different first-class functions' scope, i.e. it can be passed around)
91+
- having `eval` in a subscope allows to read/write any local variable, thus, those also need to be rewritten
8592
- they are not constant (there is a write operations somewhere for them)
8693

94+
8795
# Benchmarks
8896

8997
- need to compare performance to all other strategies

src/components/tools/lively-plugin-explorer-playground.workspace

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"/test.js",
55
"/karma.conf.js"
66
],
7-
"plugin": "src/client/reactive/babel-plugin-active-expression-rewriting/index.js",
7+
"plugin": "src/client/reactive/babel-plugin-polymorphic-identifiers/babel-plugin-polymorphic-identifiers.js",
88
"options": {
99
"autoUpdateAST": true,
1010
"autoUpdateTransformation": true,
@@ -15,11 +15,10 @@
1515
},
1616
"pluginSelection": [
1717
{
18-
"url": "src/client/reactive/babel-plugin-active-expression-rewriting/index.js"
18+
"url": "src/client/reactive/babel-plugin-polymorphic-identifiers/babel-plugin-polymorphic-identifiers.js"
1919
}
2020
],
2121
"openPlugins": [
22-
"src/client/reactive/babel-plugin-active-expression-rewriting/index.js",
23-
"demos/tom/playground.js"
22+
"src/client/reactive/babel-plugin-polymorphic-identifiers/babel-plugin-polymorphic-identifiers.js"
2423
]
2524
}

src/components/tools/lively-smaug.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"enable aexpr";
22

33
import Morph from 'src/components/widgets/lively-morph.js';
4-
import { querySelectorAllDeep } from 'https://raw.githubusercontent.com/Georgegriff/query-selector-shadow-dom/master/src/querySelectorDeep.js';
4+
import { querySelectorAllDeep } from 'src/external/querySelectorDeep/querySelectorDeep.js';
55
import d3 from "src/external/d3.v5.js";
66
import {copyTextToClipboard} from 'utils';
77

src/components/widgets/lively-code-tip.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default class CodeTip extends Morph {
3030
"Make your code simpler to understand with the extract method feature 'Alt+M'.",
3131
"You can find many useful shortcuts under 'Right-click' --> 'Documentation'.",
3232
"'that' can be used to reference the last component you used the 'halo-menu' (Alt+Click) on.",
33-
"'Ctrl+Shift+F' opens the global text search (which is case sensitive!).",
33+
"'Ctrl+Shift+F' opens the global text search (which allows for regular expressions and is case sensitive!).",
3434
"This could be your tip! Add new tips in lively-code-tip.js",
3535
"Use 'Alt+P' to switch between markdown code and its visualization in the codemirror.",
3636
"When editing a js file, press 'F7' to open the associated HTML file (if it exists) and vice versa.",
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/* istanbul ignore file */
2+
3+
4+
// normalize-selector-rev-02.js
5+
/*
6+
author: kyle simpson (@getify)
7+
original source: https://gist.github.com/getify/9679380
8+
9+
modified for tests by david kaye (@dfkaye)
10+
21 march 2014
11+
12+
rev-02 incorporate kyle's changes 3/2/42014
13+
*/
14+
15+
export function normalizeSelector(sel) {
16+
// save unmatched text, if any
17+
function saveUnmatched() {
18+
if (unmatched) {
19+
// whitespace needed after combinator?
20+
if (tokens.length > 0 && /^[~+>]$/.test(tokens[tokens.length - 1])) {
21+
tokens.push(" ");
22+
}
23+
24+
// save unmatched text
25+
tokens.push(unmatched);
26+
}
27+
}
28+
29+
var tokens = [],
30+
match,
31+
unmatched,
32+
regex,
33+
state = [0],
34+
next_match_idx = 0,
35+
prev_match_idx,
36+
not_escaped_pattern = /(?:[^\\]|(?:^|[^\\])(?:\\\\)+)$/,
37+
whitespace_pattern = /^\s+$/,
38+
state_patterns = [
39+
/\s+|\/\*|["'>~+[(]/g, // general
40+
/\s+|\/\*|["'[\]()]/g, // [..] set
41+
/\s+|\/\*|["'[\]()]/g, // (..) set
42+
null, // string literal (placeholder)
43+
/\*\//g, // comment
44+
];
45+
sel = sel.trim();
46+
47+
// eslint-disable-next-line no-constant-condition
48+
while (true) {
49+
unmatched = "";
50+
51+
regex = state_patterns[state[state.length - 1]];
52+
53+
regex.lastIndex = next_match_idx;
54+
match = regex.exec(sel);
55+
56+
// matched text to process?
57+
if (match) {
58+
prev_match_idx = next_match_idx;
59+
next_match_idx = regex.lastIndex;
60+
61+
// collect the previous string chunk not matched before this token
62+
if (prev_match_idx < next_match_idx - match[0].length) {
63+
unmatched = sel.substring(
64+
prev_match_idx,
65+
next_match_idx - match[0].length
66+
);
67+
}
68+
69+
// general, [ ] pair, ( ) pair?
70+
if (state[state.length - 1] < 3) {
71+
saveUnmatched();
72+
73+
// starting a [ ] pair?
74+
if (match[0] === "[") {
75+
state.push(1);
76+
}
77+
// starting a ( ) pair?
78+
else if (match[0] === "(") {
79+
state.push(2);
80+
}
81+
// starting a string literal?
82+
else if (/^["']$/.test(match[0])) {
83+
state.push(3);
84+
state_patterns[3] = new RegExp(match[0], "g");
85+
}
86+
// starting a comment?
87+
else if (match[0] === "/*") {
88+
state.push(4);
89+
}
90+
// ending a [ ] or ( ) pair?
91+
else if (/^[\])]$/.test(match[0]) && state.length > 0) {
92+
state.pop();
93+
}
94+
// handling whitespace or a combinator?
95+
else if (/^(?:\s+|[~+>])$/.test(match[0])) {
96+
// need to insert whitespace before?
97+
if (
98+
tokens.length > 0 &&
99+
!whitespace_pattern.test(tokens[tokens.length - 1]) &&
100+
state[state.length - 1] === 0
101+
) {
102+
// add normalized whitespace
103+
tokens.push(" ");
104+
}
105+
106+
// case-insensitive attribute selector CSS L4
107+
if (
108+
state[state.length - 1] === 1 &&
109+
tokens.length === 5 &&
110+
tokens[2].charAt(tokens[2].length - 1) === "="
111+
) {
112+
tokens[4] = " " + tokens[4];
113+
}
114+
115+
// whitespace token we can skip?
116+
if (whitespace_pattern.test(match[0])) {
117+
continue;
118+
}
119+
}
120+
121+
// save matched text
122+
tokens.push(match[0]);
123+
}
124+
// otherwise, string literal or comment
125+
else {
126+
// save unmatched text
127+
tokens[tokens.length - 1] += unmatched;
128+
129+
// unescaped terminator to string literal or comment?
130+
if (not_escaped_pattern.test(tokens[tokens.length - 1])) {
131+
// comment terminator?
132+
if (state[state.length - 1] === 4) {
133+
// ok to drop comment?
134+
if (
135+
tokens.length < 2 ||
136+
whitespace_pattern.test(tokens[tokens.length - 2])
137+
) {
138+
tokens.pop();
139+
}
140+
// otherwise, turn comment into whitespace
141+
else {
142+
tokens[tokens.length - 1] = " ";
143+
}
144+
145+
// handled already
146+
match[0] = "";
147+
}
148+
149+
state.pop();
150+
}
151+
152+
// append matched text to existing token
153+
tokens[tokens.length - 1] += match[0];
154+
}
155+
}
156+
// otherwise, end of processing (no more matches)
157+
else {
158+
unmatched = sel.substr(next_match_idx);
159+
saveUnmatched();
160+
161+
break;
162+
}
163+
}
164+
165+
return tokens.join("").trim();
166+
}

0 commit comments

Comments
 (0)