als-document 0.6.1 → 0.7.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/index.js DELETED
@@ -1,6 +0,0 @@
1
- let HtmlSelector = require('./selector/selector')
2
- let HtmlParser = require('./parser/parser')
3
- let Query = require('./query/query')
4
- let Document = require('./document/document')
5
-
6
- module.exports = {HtmlSelector,HtmlParser,Query,Document}
package/parser/parser.js DELETED
@@ -1,336 +0,0 @@
1
- class HtmlParser {
2
- static parse(html) {
3
- let result = new HtmlParser(html)
4
- return result.root
5
- }
6
- constructor(html='') {
7
- if(this.checkHtml(html)) {
8
- this.indexes = []
9
- this.events = []
10
- this.html = this.htmlString = html
11
- this.htmlString = this.htmlString.replace(/\<\!\-\-([\S\s]*?)\-\-\>/gm,'') // remove all comments
12
- this.removeScripts()
13
- this.removeStyles()
14
- this.removeEventStrings()
15
- this.root = this.parse()
16
- this.clean()
17
- }
18
- }
19
-
20
- clean() {
21
- let toDelete = ['events','indexes','scripts','styles','htmlString','html']
22
- toDelete.forEach(name => {
23
- delete this[name]
24
- });
25
- }
26
-
27
- checkHtml(html,isGood=false) {
28
- if(html == '') console.log('html parameter is empty')
29
- else if(typeof html !== 'string') console.log(`html parameter has to be string. Recieved ${typeof html}`)
30
- else isGood = true
31
- return isGood
32
- }
33
-
34
- removeScripts(scripts=[]) {
35
- let $scripts = this.htmlString.match(/\<script(.*?)\>[\S\s]*?\<\/script\>/gm)
36
- if($scripts !== null) $scripts.forEach((script,i) => {
37
- let inner = script.replace(/^\<script(.*?)\>/,'').replace(/\<\/script\>$/,'')
38
- scripts.push(inner)
39
- this.htmlString = this.htmlString.replace(inner,`{{{{script ${scripts.length-1}`)
40
- });
41
- this.scripts = scripts
42
- }
43
- removeStyles(styles=[]) {
44
- let $styles = this.htmlString.match(/\<style\>[\S\s]*?\<\/style\>/gm)
45
- if($styles !== null) $styles.forEach((style,i) => {
46
- let inner = style.replace(/^\<style\>/,'').replace(/\<\/style\>$/,'')
47
- styles.push(inner)
48
- this.htmlString = this.htmlString.replace(inner,`{{{{style ${styles.length-1}`)
49
- });
50
- this.styles = styles
51
- }
52
-
53
- removeEventStrings() {
54
- let eventsWithHtml = this.htmlString.match(/\son\w*\s*?\=\s*?\"(.*?)\"/g)
55
- if(eventsWithHtml !== null) {
56
- eventsWithHtml.forEach(event => {
57
- let array = event.split('=')
58
- let value = array.filter((v,i) => i>0 && i!=='').join('=')
59
- value = value.replace(/^\"/,'').replace(/\"$/,'')
60
- this.events.push(value)
61
- let newEvent = event.replace(value,`{{{{event ${this.events.length-1}`)
62
- this.htmlString = this.htmlString.replace(event,newEvent)
63
- })
64
- }
65
- }
66
-
67
- parse(htmlString=this.htmlString) {
68
- // Parse tags
69
- let elements = htmlString.match(/<("[^"]*"|'[^']*'|[^'">])*>/g)
70
- elements.forEach((tag,index) => {
71
- elements[index] = this.parseElement(tag)
72
- htmlString = htmlString.replace(tag,`<tag${index}>`)
73
- });
74
- // Parse inner text
75
- let inners = htmlString.match(/tag[\s\S]*?\</g)
76
- for (let i = inners.length-1; i >=0 ; i--) {
77
- let inner = inners[i];
78
- let tagIndex = inner.match(/(\d*)\>/)[1]
79
- inner = inner.replace(/tag.*\>/,'').slice(0, -1).trim()
80
- if(inner.length > 0) {
81
- elements.splice(parseInt(tagIndex)+1, 0, inner);
82
- }
83
- }
84
- this.elements = elements
85
- let root = this.getPairs()
86
- root.level = 0
87
- root.elements = this.elements
88
- this.innerHTML(root)
89
- return root
90
- }
91
-
92
- lookForPair(element,startIndex,parent,level) {
93
- element.parent = parent
94
- element.children = []
95
- let {tag} = element
96
- let count = 0
97
- let endIndex
98
- for (let index = startIndex+1; index < this.elements.length; index++) {
99
- const el = this.elements[index];
100
- if(el.tag == tag) {
101
- if(el.status == 'close') {
102
- if(count == 0) {
103
- endIndex = index
104
- el.level = level
105
- break
106
- } else count--
107
- } else if(el.status == 'open') count++
108
- }
109
- }
110
- if(!endIndex) endIndex = startIndex+1
111
- element.endIndex = endIndex
112
- let child = this.getPairs(element,startIndex+1,endIndex,level+1)
113
- return child
114
- }
115
-
116
- getPairs(parent={type:'root',children:[]},startIndex = 0,endIndex=this.elements.length,level=0,childIndex=0) {
117
- for(let index = startIndex; index < endIndex; index++) {
118
- if(this.indexes.includes(index)) continue
119
- let element = this.elements[index];
120
- let child
121
- if(typeof element == 'string') child = element
122
- else if(element.type == 'tag') {
123
- if(element.status == 'single') {
124
- child = element
125
- child.parent = parent
126
- } else if(element.status == 'open') {
127
- child = this.lookForPair(element,index,parent,level)
128
- } else element.index = index
129
- }
130
- this.addChild(parent,child,index,level)
131
- childIndex++
132
- }
133
- return parent
134
- }
135
-
136
- addScriptsAndStyles(parent,child,index) {
137
- if(parent.tag == 'script') {
138
- let scriptIndex = child.match(/(?<=\{\{\{\{script\s)(\d*)?/)
139
- if(scriptIndex !== null) {
140
- let i = parseInt(scriptIndex[0])
141
- if(typeof i == 'number') child = this.scripts[i]
142
- }
143
- }
144
- if(parent.tag == 'style') {
145
- let stylesIndex = child.match(/(?<=\{\{\{\{style\s)(\d*)?/)
146
- if(stylesIndex !== null) {
147
- let i = parseInt(stylesIndex[0])
148
- if(typeof i == 'number') child = this.styles[i]
149
- }
150
- }
151
- this.elements[index] = child
152
- return child
153
- }
154
-
155
- addChild(parent,child,index,level) {
156
- if(typeof child == 'string') {
157
- child = this.addScriptsAndStyles(parent,child,index)
158
- child = {type:'text',text:child,parent}
159
- this.elements[index] = child
160
- }
161
- if(child) {
162
- delete child.status
163
- if(child.type !== 'text') {
164
- this.innerHTML(child)
165
- this.outerHTML(child)
166
- this.innerText(child)
167
- }
168
- this.getElements(child)
169
- this.getAncestors(child)
170
- this.getAttribute(child)
171
- this.nextAndPrev(child)
172
- child.index = index
173
- child.level = level
174
- parent.children.push(child)
175
- }
176
- this.indexes.push(index)
177
- }
178
-
179
- getAttribute(element) {
180
- element.getAttribute = function(name) {
181
- let array = Object.keys(this.attribs).filter(key => key == name)
182
- return array.length > 0 ? this.attribs[array[0]] : null
183
- }
184
- }
185
-
186
- getAncestors(element) {
187
- Object.defineProperty(element, 'ancestors', { get() {
188
- let ancestors = []
189
- let parent = this.parent
190
- if(parent) while(parent.parent) {
191
- ancestors.unshift(parent)
192
- parent = parent.parent
193
- }
194
- return ancestors
195
- }});
196
- }
197
-
198
- nextAndPrev(element) {
199
- Object.defineProperty(element, 'childIndex', {
200
- get() {return this.parent.children.map(o => o.index).indexOf(this.index)}
201
- });
202
- Object.defineProperty(element, 'prev', {
203
- get() {
204
- let i = this.childIndex, brothers = this.parent.children
205
- return i == 0 ? null : brothers[i-1]
206
- }
207
- });
208
- Object.defineProperty(element, 'next', {
209
- get() {
210
- let i = this.childIndex, brothers = this.parent.children
211
- return i == brothers.length-1 ? null : brothers[i+1]
212
- }
213
- });
214
- }
215
-
216
- getElements(element,self=this) {
217
- if(element.type !== 'text')
218
- Object.defineProperty(element, 'elements', {
219
- configurable:true,
220
- get() {
221
- let endIndex = isNaN(this.endIndex) ? this.index + 1 : this.endIndex+1
222
- return self.elements.slice(this.index,endIndex)
223
- }
224
- });
225
- Object.defineProperty(element, '$elements', {
226
- configurable:true,
227
- get() {return self.elements}
228
- });
229
- Object.defineProperty(element, 'root', {
230
- configurable:true,
231
- get() {return self.root}
232
- });
233
- Object.defineProperty(element, 'html', {
234
- configurable:true,
235
- get() {return self}
236
- });
237
- }
238
-
239
- outerHTML(element) {
240
- Object.defineProperty(element, 'outerHTML', { get() {
241
- let {elements} = this
242
- return elements[0].text + this.innerHTML + elements[elements.length-1].text
243
- }});
244
- }
245
-
246
- innerText(element) {
247
- Object.defineProperty(element, 'innerText', { get() {
248
- if(element.children)
249
- return element.children.map(child => child.type == 'text' ? child.text : '').join('')
250
- else return ''
251
- }})
252
- }
253
- innerHTML(element) {
254
- element.tab = ' '
255
- element.n = '\n'
256
- Object.defineProperty(element, 'innerHTML', { get() {
257
- // let tab = ' ',result = '',firstLevel,space=''
258
- let {tab,n} = this
259
- let result = '',firstLevel,space=''
260
- let {elements} = this
261
- let endIndex = elements.length
262
- let end = endIndex-1,start=1
263
- if(this.type == 'root') {
264
- end = endIndex
265
- start = 0
266
- }
267
- for(let i = start; i < end; i++) {
268
- let element = elements[i]
269
- let {level,text} = element
270
- if(firstLevel == undefined) firstLevel = level
271
- if(i == end) space = ''
272
- else if(level) space = Array.from(Array(level-firstLevel).keys()).map(n => tab).join('')
273
- result += space + text
274
- if(endIndex > 3) result += n
275
- }
276
- return result
277
- }});
278
- }
279
-
280
- parseElement(tagString) {
281
- let type = 'tag'
282
- if(tagString == '<!DOCTYPE html>') return {tag:'!DOCTYPE html',status:'single',attribs:{},type,text:tagString}
283
- let status = 'close'
284
- let tag = tagString.match(/(?<=\<\/)(\w*\-?)*/)
285
- if(tag == null) {
286
- tag = tagString.match(/(?<=\<)(\w*\-?)*/)
287
- if(tag) {
288
- tag = tag[0]
289
- if(HtmlParser.singleTags.includes(tag)) status='single'
290
- else status = 'open'
291
- }
292
- } else tag = tag[0]
293
- let {classList,attribs,style,id,text} = this.parseAttributes(tagString)
294
- let obj = {tag,status,attribs,type,classList,text,style,id}
295
- return obj
296
- }
297
- static singleTags = ['comment','area','base','br','col','command','embed','hr','img','input','keygen','link','meta','param','source','track','wbr']
298
-
299
- parseAttributes(tagString,classList=[],attribs={},style={},id=null) {
300
- let text = tagString
301
- let attributes = tagString.match(/(?<=\s)(\w*\-?)*(\s*?\=\s*?\"[\s\S]*?\")?/g)
302
- if(attributes) attributes.forEach(attribString => {
303
- let [name,value] = attribString.split('=')
304
- if(value !== undefined && name !== '') {
305
- value = value.trim().replace(/^\"/,'').replace(/\"$/m,'')
306
- let eventIndex = value.match(/(?<=\{\{\{\{event\s)(\d*)?/)
307
- if(eventIndex !== null) {
308
- value = this.events[eventIndex[0]]
309
- text = tagString.replace(`{{{{event ${eventIndex[0]}`,value)
310
- }
311
- if(name == 'class') classList = value.split(/\s\s?\s?/)
312
- else if(name == 'style') style = this.parseInlineCss(value)
313
- else if(name == 'id') id = value
314
- attribs[name] = value
315
- } else if(name !== '') attribs[name] = undefined
316
- });
317
- return {classList,attribs,style,id,text}
318
- }
319
-
320
- parseInlineCss(textCss) {
321
- let rules = textCss.split(';')
322
- let styles = {}
323
- rules.forEach(rule => {
324
- let [prop,value] = rule.trim().split(':')
325
- if(rule !== '') {
326
- if(prop.match(/\w*\-\w*(-\w*)?/) !== null) {
327
- let words = prop.split('-')
328
- prop = words.map((w,i) => i==0 ? w : w[0].toUpperCase() + w.slice(1)).join('')
329
- }
330
- styles[prop] = value.trim()
331
- }
332
- });
333
- return styles
334
- }
335
- }
336
- try {module.exports = HtmlParser} catch {}
package/parser/test.js DELETED
@@ -1,233 +0,0 @@
1
- let Test = require('als-test')
2
- let {equal,greater,smaller,$greater, $smaller,mesureTime} = Test
3
- let Parser = require('./parser')
4
- // const htmlparser2 = require("htmlparser2");
5
-
6
- module.exports = new Test('HtmlParser tests',[
7
- {
8
- title:'Parse html for html1',
9
- result:function({html1}){
10
- this.vars.root1 = Parser.parse(html1)
11
- if(this.vars.root1.type == 'root')
12
- return `succesfully parsed with Parser.parse(html)`
13
- else {
14
- this.terminate = true
15
- return 'Something went wrong..'
16
- }
17
- },
18
- },
19
- // {
20
- // title:'Compare to htmlparser2',
21
- // expected:mesureTime(function({html2}){htmlparser2.parseDocument(html2);}),
22
- // result:mesureTime(function({html2}){Parser.parse(html2)}),
23
- // action:greater
24
- // },
25
- {
26
- title:'Parse html for html2',
27
- result:function({html2}){
28
- this.vars.root2 = Parser.parse(html2)
29
- if(this.vars.root2.type == 'root')
30
- return `succesfully parsed with Parser.parse(html)`
31
- else {
32
- this.terminate = true
33
- return 'Something went wrong..'
34
- }
35
- },
36
- },
37
- {
38
- title:'root1 element has 2 children',
39
- expected:2,
40
- result:function({root1}){
41
- return root1.children.length
42
- },
43
- action:equal
44
- },
45
- {
46
- title:'Check if element is right',
47
- expected:'body',
48
- result:function({root1}){
49
- this.vars.body1 = root1.children[1].children[1]
50
- return this.vars.body1.tag
51
- },
52
- action:equal
53
- },
54
- {
55
- title:'Check if element right',
56
- expected:'head',
57
- result:function({root1}){
58
- this.vars.head1 = root1.children[1].children[0]
59
- return this.vars.head1.tag
60
- },
61
- action:equal
62
- },
63
- {
64
- title:'body element has 4 children',
65
- expected:4,
66
- result:function({body1}){
67
- return body1.children.length
68
- },
69
- action:equal
70
- },
71
- {
72
- title:'Read title text',
73
- expected:'Document',
74
- result:function({head1}){
75
- return head1.children[3].children[0].text
76
- },
77
- action:equal
78
- },
79
- {
80
- title:'innerHTML',
81
- expected:'tab3 content',
82
- result:function({body1}){
83
- return body1.children[3].children[6].innerHTML
84
- },
85
- action:equal
86
- },
87
- {
88
- title:'innerHTML',
89
- expected:669,
90
- result:function({body1}){
91
- return body1.children[3].innerHTML.length
92
- },
93
- action:equal
94
- },
95
- {
96
- title:'outerHTML',
97
- expected:'<div class="tab-content p2 transition1">tab3 content</div>'.length,
98
- result:function({body1}){
99
- return body1.children[3].children[6].outerHTML.length
100
- },
101
- action:equal
102
- },
103
- {
104
- title:'ancestors',
105
- expected:3,
106
- result:function({body1}){
107
- return body1.children[3].children[6].ancestors.length
108
- },
109
- action:equal
110
- },
111
- {
112
- title:'elements',
113
- expected:25,
114
- result:function({body1}){
115
- return body1.children[3].elements.length
116
- },
117
- action:equal
118
- },
119
- {
120
- title:'children length',
121
- expected:15,
122
- result:function({root2}){
123
- this.vars.body2 = root2.children[0].children[1]
124
- return this.vars.body2.children.length
125
- },
126
- action:equal
127
- },
128
- {
129
- title:'id',
130
- expected:'tab2',
131
- result:function({body1}){
132
- return body1.children[3].children[1].id
133
- },
134
- action:equal
135
- },
136
- {
137
- title:'classList',
138
- expected:5,
139
- result:function({body2}){
140
- return body2.children[2].children[0].children[4].classList.length
141
- },
142
- action:equal
143
- },
144
- {
145
- title:'style',
146
- expected:'marginTop',
147
- result:function({body2}){
148
- let style = body2.children[2].children[0].children[4].style
149
- return Object.keys(style)[0]
150
- },
151
- action:equal
152
- },
153
- {
154
- title:'style length',
155
- expected:5,
156
- result:function({body2}){
157
- let style = body2.children[4].style
158
- return Object.keys(style).length
159
- },
160
- action:equal
161
- },
162
- {
163
- title:'style with multiple styles',
164
- expected:'605px',
165
- result:function({body2}){
166
- let style = body2.children[4].style
167
- return style.left
168
- },
169
- action:equal
170
- },
171
- {
172
- title:'attributs length',
173
- expected:6,
174
- result:function({body2}){
175
- let attribs = body2.children[2].children[0].children[0].attribs
176
- return Object.keys(attribs).length
177
- },
178
- action:equal
179
- },
180
- {
181
- title:'attribute content',
182
- expected:'_blank',
183
- result:function({body2}){
184
- return body2.children[2].children[0].children[0].attribs.target
185
- },
186
- action:equal
187
- },
188
- {
189
- title:'next',
190
- expected:'a#menuButton',
191
- result:function({body2}){
192
- let {tag,id} = body2.children[2].children[0].children[0].next
193
- return `${tag}#${id}`
194
- },
195
- action:equal
196
- },
197
- {
198
- title:'prev',
199
- expected:'a#tryhome',
200
- result:function({body2}){
201
- let {tag,id} = body2.children[2].children[0].children[1].prev
202
- return `${tag}#${id}`
203
- },
204
- action:equal
205
- },
206
- {
207
- title:'parent',
208
- expected:'div.w3-bar',
209
- result:function({body2}){
210
- let {tag,classList} = body2.children[2].children[0].children[1].parent
211
- return `${tag}.${classList[0]}`
212
- },
213
- action:equal
214
- },
215
- {
216
- title:'Single tags doesnt have children',
217
- expected:undefined,
218
- result:function({root2}){
219
- let head = root2.children[0].children[0]
220
- return head.children[1].children
221
- },
222
- action:equal
223
- },
224
- {
225
- title:'Text tag doesnt have children',
226
- expected:undefined,
227
- result:function({root2}){
228
- let head = root2.children[0].children[0]
229
- return head.children[0].children[0].children
230
- },
231
- action:equal
232
- },
233
- ])