clapton 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/app/helpers/clapton/clapton_helper.rb +16 -1
  4. data/lib/clapton/engine.rb +14 -10
  5. data/lib/clapton/javascripts/dist/client.js +31 -19
  6. data/lib/clapton/javascripts/dist/components-for-test.js +439 -0
  7. data/lib/clapton/javascripts/dist/components.js +356 -382
  8. data/lib/clapton/javascripts/node_modules/diff-dom/LICENSE.txt +165 -0
  9. data/lib/clapton/javascripts/node_modules/diff-dom/README.md +224 -0
  10. data/lib/clapton/javascripts/node_modules/diff-dom/browser/diffDOM.js +2 -0
  11. data/lib/clapton/javascripts/node_modules/diff-dom/browser/diffDOM.js.map +1 -0
  12. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/TraceLogger.d.ts +28 -0
  13. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/dom/apply.d.ts +4 -0
  14. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/dom/fromVirtual.d.ts +2 -0
  15. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/dom/index.d.ts +2 -0
  16. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/dom/undo.d.ts +3 -0
  17. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/helpers.d.ts +11 -0
  18. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/index.d.ts +10 -0
  19. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/types.d.ts +104 -0
  20. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/apply.d.ts +3 -0
  21. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/diff.d.ts +22 -0
  22. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/fromDOM.d.ts +2 -0
  23. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/fromString.d.ts +2 -0
  24. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/helpers.d.ts +40 -0
  25. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/diffDOM/virtual/index.d.ts +3 -0
  26. data/lib/clapton/javascripts/node_modules/diff-dom/dist/dts/index.d.ts +2 -0
  27. data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.d.ts +136 -0
  28. data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.js +1996 -0
  29. data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.js.map +1 -0
  30. data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.min.js +2 -0
  31. data/lib/clapton/javascripts/node_modules/diff-dom/dist/index.min.js.map +1 -0
  32. data/lib/clapton/javascripts/node_modules/diff-dom/dist/module.js +1991 -0
  33. data/lib/clapton/javascripts/node_modules/diff-dom/dist/module.js.map +1 -0
  34. data/lib/clapton/javascripts/node_modules/diff-dom/index.html +62 -0
  35. data/lib/clapton/javascripts/node_modules/diff-dom/package.json +54 -0
  36. data/lib/clapton/javascripts/node_modules/diff-dom/rollup.config.mjs +67 -0
  37. data/lib/clapton/javascripts/node_modules/diff-dom/src/TraceLogger.ts +143 -0
  38. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/dom/apply.ts +227 -0
  39. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/dom/fromVirtual.ts +83 -0
  40. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/dom/index.ts +2 -0
  41. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/dom/undo.ts +90 -0
  42. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/helpers.ts +40 -0
  43. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/index.ts +121 -0
  44. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/types.ts +154 -0
  45. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/apply.ts +349 -0
  46. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/diff.ts +855 -0
  47. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/fromDOM.ts +74 -0
  48. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/fromString.ts +239 -0
  49. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/helpers.ts +461 -0
  50. data/lib/clapton/javascripts/node_modules/diff-dom/src/diffDOM/virtual/index.ts +3 -0
  51. data/lib/clapton/javascripts/node_modules/diff-dom/src/index.ts +2 -0
  52. data/lib/clapton/javascripts/node_modules/diff-dom/tsconfig.json +103 -0
  53. data/lib/clapton/javascripts/rollup.config.mjs +17 -2
  54. data/lib/clapton/javascripts/src/actions/initialize-actions.ts +6 -3
  55. data/lib/clapton/javascripts/src/channel/clapton-channel.js +6 -3
  56. data/lib/clapton/javascripts/src/client.ts +15 -15
  57. data/lib/clapton/javascripts/src/components-for-test.ts +29 -0
  58. data/lib/clapton/javascripts/src/components.ts +4 -1
  59. data/lib/clapton/javascripts/src/dom/update-component.ts +3 -2
  60. data/lib/clapton/javascripts/src/inputs/initialize-inputs.ts +2 -2
  61. data/lib/clapton/test_helper/base.rb +1 -1
  62. data/lib/clapton/version.rb +1 -1
  63. metadata +49 -3
  64. 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(/&lt;/g, "<")
13
+ .replace(/&gt;/g, ">")
14
+ .replace(/&amp;/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
+ }