clapton 0.0.13 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/app/helpers/clapton/clapton_helper.rb +16 -1
- data/lib/clapton/engine.rb +20 -10
- data/lib/clapton/javascripts/dist/client.js +38 -27
- data/lib/clapton/javascripts/dist/components-for-test.js +439 -0
- data/lib/clapton/javascripts/dist/components.js +356 -382
- data/lib/clapton/javascripts/node_modules/diff-dom/LICENSE.txt +165 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/README.md +224 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/browser/diffDOM.js +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/browser/diffDOM.js.map +1 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/TraceLogger.d.ts +28 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/dom/apply.d.ts +4 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/dom/fromVirtual.d.ts +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/dom/index.d.ts +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/dom/undo.d.ts +3 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/helpers.d.ts +11 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/index.d.ts +10 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/types.d.ts +104 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/apply.d.ts +3 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/diff.d.ts +22 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/fromDOM.d.ts +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/fromString.d.ts +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/helpers.d.ts +40 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/index.d.ts +3 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/index.d.ts +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.d.ts +136 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.js +1996 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.js.map +1 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.min.js +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.min.js.map +1 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/module.js +1991 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/dist/module.js.map +1 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/index.html +62 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/package.json +54 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/rollup.config.mjs +67 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/TraceLogger.ts +143 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/dom/apply.ts +227 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/dom/fromVirtual.ts +83 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/dom/index.ts +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/dom/undo.ts +90 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/helpers.ts +40 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/index.ts +121 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/types.ts +154 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/apply.ts +349 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/diff.ts +855 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/fromDOM.ts +74 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/fromString.ts +239 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/helpers.ts +461 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/index.ts +3 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/src/index.ts +2 -0
- data/lib/clapton/javascripts/node_modules/diff-dom/tsconfig.json +103 -0
- data/lib/clapton/javascripts/rollup.config.mjs +17 -2
- data/lib/clapton/javascripts/src/actions/handle-action.ts +6 -6
- data/lib/clapton/javascripts/src/actions/initialize-actions.ts +6 -3
- data/lib/clapton/javascripts/src/channel/clapton-channel.js +6 -3
- data/lib/clapton/javascripts/src/client.ts +15 -15
- data/lib/clapton/javascripts/src/components-for-test.ts +29 -0
- data/lib/clapton/javascripts/src/components.ts +4 -1
- data/lib/clapton/javascripts/src/dom/update-component.ts +4 -4
- data/lib/clapton/javascripts/src/inputs/initialize-inputs.ts +2 -2
- data/lib/clapton/test_helper/base.rb +1 -1
- data/lib/clapton/version.rb +1 -2
- metadata +49 -3
- data/lib/clapton/javascripts/src/dom/update-component.spec.ts +0 -32
@@ -0,0 +1,74 @@
|
|
1
|
+
import { DiffDOMOptionsPartial, elementNodeType, textNodeType } from "../types"
|
2
|
+
import { checkElementType } from "../helpers"
|
3
|
+
|
4
|
+
export function nodeToObj(
|
5
|
+
aNode: Element,
|
6
|
+
options: DiffDOMOptionsPartial = { valueDiffing: true },
|
7
|
+
) {
|
8
|
+
const objNode: elementNodeType | textNodeType = {
|
9
|
+
nodeName: aNode.nodeName,
|
10
|
+
}
|
11
|
+
if (checkElementType(aNode, "Text", "Comment")) {
|
12
|
+
;(objNode as unknown as textNodeType).data = (
|
13
|
+
aNode as unknown as Text | Comment
|
14
|
+
).data
|
15
|
+
} else {
|
16
|
+
if (aNode.attributes && aNode.attributes.length > 0) {
|
17
|
+
objNode.attributes = {}
|
18
|
+
const nodeArray = Array.prototype.slice.call(aNode.attributes)
|
19
|
+
nodeArray.forEach(
|
20
|
+
(attribute) =>
|
21
|
+
(objNode.attributes[attribute.name] = attribute.value),
|
22
|
+
)
|
23
|
+
}
|
24
|
+
if (aNode.childNodes && aNode.childNodes.length > 0) {
|
25
|
+
objNode.childNodes = []
|
26
|
+
const nodeArray = Array.prototype.slice.call(aNode.childNodes)
|
27
|
+
nodeArray.forEach((childNode) =>
|
28
|
+
objNode.childNodes.push(nodeToObj(childNode, options)),
|
29
|
+
)
|
30
|
+
}
|
31
|
+
if (options.valueDiffing) {
|
32
|
+
if (checkElementType(aNode, "HTMLTextAreaElement")) {
|
33
|
+
objNode.value = (aNode as HTMLTextAreaElement).value
|
34
|
+
}
|
35
|
+
if (
|
36
|
+
checkElementType(aNode, "HTMLInputElement") &&
|
37
|
+
["radio", "checkbox"].includes(
|
38
|
+
(aNode as HTMLInputElement).type.toLowerCase(),
|
39
|
+
) &&
|
40
|
+
(aNode as HTMLInputElement).checked !== undefined
|
41
|
+
) {
|
42
|
+
objNode.checked = (aNode as HTMLInputElement).checked
|
43
|
+
} else if (
|
44
|
+
checkElementType(
|
45
|
+
aNode,
|
46
|
+
"HTMLButtonElement",
|
47
|
+
"HTMLDataElement",
|
48
|
+
"HTMLInputElement",
|
49
|
+
"HTMLLIElement",
|
50
|
+
"HTMLMeterElement",
|
51
|
+
"HTMLOptionElement",
|
52
|
+
"HTMLProgressElement",
|
53
|
+
"HTMLParamElement",
|
54
|
+
)
|
55
|
+
) {
|
56
|
+
objNode.value = (
|
57
|
+
aNode as
|
58
|
+
| HTMLButtonElement
|
59
|
+
| HTMLDataElement
|
60
|
+
| HTMLInputElement
|
61
|
+
| HTMLLIElement
|
62
|
+
| HTMLMeterElement
|
63
|
+
| HTMLOptionElement
|
64
|
+
| HTMLProgressElement
|
65
|
+
| HTMLParamElement
|
66
|
+
).value
|
67
|
+
}
|
68
|
+
if (checkElementType(aNode, "HTMLOptionElement")) {
|
69
|
+
objNode.selected = (aNode as HTMLOptionElement).selected
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
return objNode
|
74
|
+
}
|
@@ -0,0 +1,239 @@
|
|
1
|
+
import { DiffDOMOptionsPartial, nodeType } from "../types"
|
2
|
+
|
3
|
+
// from html-parse-stringify (MIT)
|
4
|
+
|
5
|
+
const tagRE =
|
6
|
+
/<\s*\/*[a-zA-Z:_][a-zA-Z0-9:_\-.]*\s*(?:"[^"]*"['"]*|'[^']*'['"]*|[^'"/>])*\/*\s*>|<!--(?:.|\n|\r)*?-->/g
|
7
|
+
|
8
|
+
const attrRE = /\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g
|
9
|
+
|
10
|
+
function unescape(string: string) {
|
11
|
+
return string
|
12
|
+
.replace(/</g, "<")
|
13
|
+
.replace(/>/g, ">")
|
14
|
+
.replace(/&/g, "&")
|
15
|
+
}
|
16
|
+
|
17
|
+
// create optimized lookup object for
|
18
|
+
// void elements as listed here:
|
19
|
+
// https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements
|
20
|
+
const lookup = {
|
21
|
+
area: true,
|
22
|
+
base: true,
|
23
|
+
br: true,
|
24
|
+
col: true,
|
25
|
+
embed: true,
|
26
|
+
hr: true,
|
27
|
+
img: true,
|
28
|
+
input: true,
|
29
|
+
keygen: true,
|
30
|
+
link: true,
|
31
|
+
menuItem: true,
|
32
|
+
meta: true,
|
33
|
+
param: true,
|
34
|
+
source: true,
|
35
|
+
track: true,
|
36
|
+
wbr: true,
|
37
|
+
}
|
38
|
+
|
39
|
+
const parseTag = (tag: string, caseSensitive: boolean) => {
|
40
|
+
const res = {
|
41
|
+
nodeName: "",
|
42
|
+
attributes: {},
|
43
|
+
}
|
44
|
+
let voidElement = false
|
45
|
+
let type = "tag"
|
46
|
+
|
47
|
+
let tagMatch = tag.match(/<\/?([^\s]+?)[/\s>]/)
|
48
|
+
if (tagMatch) {
|
49
|
+
res.nodeName =
|
50
|
+
caseSensitive || tagMatch[1] === "svg"
|
51
|
+
? tagMatch[1]
|
52
|
+
: tagMatch[1].toUpperCase()
|
53
|
+
if (lookup[tagMatch[1]] || tag.charAt(tag.length - 2) === "/") {
|
54
|
+
voidElement = true
|
55
|
+
}
|
56
|
+
|
57
|
+
// handle comment tag
|
58
|
+
if (res.nodeName.startsWith("!--")) {
|
59
|
+
const endIndex = tag.indexOf("-->")
|
60
|
+
return {
|
61
|
+
type: "comment",
|
62
|
+
node: {
|
63
|
+
nodeName: "#comment",
|
64
|
+
data: endIndex !== -1 ? tag.slice(4, endIndex) : "",
|
65
|
+
},
|
66
|
+
voidElement,
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
let reg = new RegExp(attrRE)
|
72
|
+
let result = null
|
73
|
+
let done = false
|
74
|
+
while (!done) {
|
75
|
+
result = reg.exec(tag)
|
76
|
+
|
77
|
+
if (result === null) {
|
78
|
+
done = true
|
79
|
+
} else if (result[0].trim()) {
|
80
|
+
if (result[1]) {
|
81
|
+
let attr = result[1].trim()
|
82
|
+
let arr = [attr, ""]
|
83
|
+
|
84
|
+
if (attr.indexOf("=") > -1) arr = attr.split("=")
|
85
|
+
res.attributes[arr[0]] = arr[1]
|
86
|
+
reg.lastIndex--
|
87
|
+
} else if (result[2])
|
88
|
+
res.attributes[result[2]] = result[3]
|
89
|
+
.trim()
|
90
|
+
.substring(1, result[3].length - 1)
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
return {
|
95
|
+
type,
|
96
|
+
node: res,
|
97
|
+
voidElement,
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
export const stringToObj = (
|
102
|
+
html: string,
|
103
|
+
options: DiffDOMOptionsPartial = {
|
104
|
+
valueDiffing: true,
|
105
|
+
caseSensitive: false,
|
106
|
+
},
|
107
|
+
) => {
|
108
|
+
const result: nodeType[] = []
|
109
|
+
let current: { type: string; node: nodeType; voidElement: boolean }
|
110
|
+
let level = -1
|
111
|
+
const arr: { type: string; node: nodeType; voidElement: boolean }[] = []
|
112
|
+
let inComponent = false,
|
113
|
+
insideSvg = false
|
114
|
+
|
115
|
+
// handle text at top level
|
116
|
+
if (html.indexOf("<") !== 0) {
|
117
|
+
const end = html.indexOf("<")
|
118
|
+
result.push({
|
119
|
+
nodeName: "#text",
|
120
|
+
data: end === -1 ? html : html.substring(0, end),
|
121
|
+
})
|
122
|
+
}
|
123
|
+
|
124
|
+
html.replace(tagRE, (tag: string, index: number) => {
|
125
|
+
if (inComponent) {
|
126
|
+
if (tag !== `</${current.node.nodeName}>`) {
|
127
|
+
return ""
|
128
|
+
} else {
|
129
|
+
inComponent = false
|
130
|
+
}
|
131
|
+
}
|
132
|
+
const isOpen = tag.charAt(1) !== "/"
|
133
|
+
const isComment = tag.startsWith("<!--")
|
134
|
+
const start = index + tag.length
|
135
|
+
const nextChar = html.charAt(start)
|
136
|
+
|
137
|
+
if (isComment) {
|
138
|
+
const comment = parseTag(tag, options.caseSensitive).node
|
139
|
+
|
140
|
+
// if we're at root, push new base node
|
141
|
+
if (level < 0) {
|
142
|
+
result.push(comment)
|
143
|
+
return ""
|
144
|
+
}
|
145
|
+
const parent = arr[level]
|
146
|
+
if (parent && comment.nodeName) {
|
147
|
+
if (!parent.node.childNodes) {
|
148
|
+
parent.node.childNodes = []
|
149
|
+
}
|
150
|
+
parent.node.childNodes.push(comment)
|
151
|
+
}
|
152
|
+
return ""
|
153
|
+
}
|
154
|
+
|
155
|
+
if (isOpen) {
|
156
|
+
current = parseTag(tag, options.caseSensitive || insideSvg)
|
157
|
+
if (current.node.nodeName === "svg") {
|
158
|
+
insideSvg = true
|
159
|
+
}
|
160
|
+
level++
|
161
|
+
if (
|
162
|
+
!current.voidElement &&
|
163
|
+
!inComponent &&
|
164
|
+
nextChar &&
|
165
|
+
nextChar !== "<"
|
166
|
+
) {
|
167
|
+
if (!current.node.childNodes) {
|
168
|
+
current.node.childNodes = []
|
169
|
+
}
|
170
|
+
const data = unescape(
|
171
|
+
html.slice(start, html.indexOf("<", start)),
|
172
|
+
)
|
173
|
+
current.node.childNodes.push({
|
174
|
+
nodeName: "#text",
|
175
|
+
data,
|
176
|
+
})
|
177
|
+
if (
|
178
|
+
options.valueDiffing &&
|
179
|
+
current.node.nodeName === "TEXTAREA"
|
180
|
+
) {
|
181
|
+
current.node.value = data
|
182
|
+
}
|
183
|
+
}
|
184
|
+
// if we're at root, push new base node
|
185
|
+
if (level === 0 && current.node.nodeName) {
|
186
|
+
result.push(current.node)
|
187
|
+
}
|
188
|
+
|
189
|
+
const parent = arr[level - 1]
|
190
|
+
if (parent && current.node.nodeName) {
|
191
|
+
if (!parent.node.childNodes) {
|
192
|
+
parent.node.childNodes = []
|
193
|
+
}
|
194
|
+
parent.node.childNodes.push(current.node)
|
195
|
+
}
|
196
|
+
arr[level] = current
|
197
|
+
}
|
198
|
+
if (!isOpen || current.voidElement) {
|
199
|
+
if (
|
200
|
+
level > -1 &&
|
201
|
+
(current.voidElement ||
|
202
|
+
(options.caseSensitive &&
|
203
|
+
current.node.nodeName === tag.slice(2, -1)) ||
|
204
|
+
(!options.caseSensitive &&
|
205
|
+
current.node.nodeName.toUpperCase() ===
|
206
|
+
tag.slice(2, -1).toUpperCase()))
|
207
|
+
) {
|
208
|
+
level--
|
209
|
+
// move current up a level to match the end tag
|
210
|
+
if (level > -1) {
|
211
|
+
if (current.node.nodeName === "svg") {
|
212
|
+
insideSvg = false
|
213
|
+
}
|
214
|
+
current = arr[level]
|
215
|
+
}
|
216
|
+
}
|
217
|
+
if (!inComponent && nextChar !== "<" && nextChar) {
|
218
|
+
// trailing text node
|
219
|
+
// if we're at the root, push a base text node. otherwise add as
|
220
|
+
// a child to the current node.
|
221
|
+
const childNodes =
|
222
|
+
level === -1 ? result : arr[level].node.childNodes || []
|
223
|
+
|
224
|
+
// calculate correct end of the data slice in case there's
|
225
|
+
// no tag after the text node.
|
226
|
+
const end = html.indexOf("<", start)
|
227
|
+
let data = unescape(
|
228
|
+
html.slice(start, end === -1 ? undefined : end),
|
229
|
+
)
|
230
|
+
childNodes.push({
|
231
|
+
nodeName: "#text",
|
232
|
+
data,
|
233
|
+
})
|
234
|
+
}
|
235
|
+
}
|
236
|
+
return ""
|
237
|
+
})
|
238
|
+
return result[0]
|
239
|
+
}
|