11'use strict'
22
33var xtend = require ( 'xtend' )
4+ var html = require ( 'property-information/html' )
5+ var svg = require ( 'property-information/svg' )
6+ var find = require ( 'property-information/find' )
47var toH = require ( 'hast-to-hyperscript' )
5- var NS = require ( 'web-namespaces' )
8+ var ns = require ( 'web-namespaces' )
69var zwitch = require ( 'zwitch' )
7- var mapz = require ( 'mapz' )
810
911module . exports = transform
1012
11- var own = { } . hasOwnProperty
12- var one = zwitch ( 'type' )
13- var all = mapz ( one , { key : 'children' , indices : false } )
13+ var ignoredSpaces = [ 'svg' , 'html' ]
1414
15- var customProps = [
16- 'sourceCodeLocation' ,
17- 'childNodes' ,
18- 'content' ,
19- 'parentNode' ,
20- 'namespaceURI'
21- ]
15+ var one = zwitch ( 'type' )
2216
2317one . handlers . root = root
2418one . handlers . element = element
2519one . handlers . text = text
2620one . handlers . comment = comment
2721one . handlers . doctype = doctype
2822
29- /* Map of tag-names starting new namespaces. */
30- var namespaces = {
31- math : NS . mathml ,
32- svg : NS . svg
23+ // Transform a tree from HAST to Parse5’s AST.
24+ function transform ( tree , space ) {
25+ return one ( tree , space === 'svg' ? svg : html )
3326}
3427
35- /* Map of attributes with namespaces. */
36- var attributeSpaces = {
37- 'xlink:actuate' : { prefix : 'xlink' , name : 'actuate' , namespace : NS . xlink } ,
38- 'xlink:arcrole' : { prefix : 'xlink' , name : 'arcrole' , namespace : NS . xlink } ,
39- 'xlink:href' : { prefix : 'xlink' , name : 'href' , namespace : NS . xlink } ,
40- 'xlink:role' : { prefix : 'xlink' , name : 'role' , namespace : NS . xlink } ,
41- 'xlink:show' : { prefix : 'xlink' , name : 'show' , namespace : NS . xlink } ,
42- 'xlink:title' : { prefix : 'xlink' , name : 'title' , namespace : NS . xlink } ,
43- 'xlink:type' : { prefix : 'xlink' , name : 'type' , namespace : NS . xlink } ,
44- 'xml:base' : { prefix : 'xml' , name : 'base' , namespace : NS . xml } ,
45- 'xml:lang' : { prefix : 'xml' , name : 'lang' , namespace : NS . xml } ,
46- 'xml:space' : { prefix : 'xml' , name : 'space' , namespace : NS . xml } ,
47- xmlns : { prefix : '' , name : 'xmlns' , namespace : NS . xmlns } ,
48- 'xmlns:xlink' : { prefix : 'xmlns' , name : 'xlink' , namespace : NS . xmlns }
28+ function root ( node , schema ) {
29+ var data = node . data || { }
30+ var mode = data . quirksMode ? 'quirks' : 'no-quirks'
31+
32+ return patch ( node , { nodeName : '#document' , mode : mode } , schema )
4933}
5034
51- /* Transform a tree from HAST to Parse5’s AST. */
52- function transform ( tree ) {
53- return patch ( one ( tree ) , null , NS . html )
35+ function fragment ( node , schema ) {
36+ return patch ( node , { nodeName : '#document-fragment' } , schema )
5437}
5538
56- function root ( node ) {
57- var data = node . data || { }
58- var qs = own . call ( data , 'quirksMode' ) ? Boolean ( data . quirksMode ) : false
39+ function doctype ( node , schema ) {
40+ return patch (
41+ node ,
42+ {
43+ nodeName : '#documentType' ,
44+ name : node . name ,
45+ publicId : node . public || '' ,
46+ systemId : node . system || ''
47+ } ,
48+ schema
49+ )
50+ }
5951
60- return {
61- nodeName : '#document' ,
62- mode : qs ? 'quirks' : 'no-quirks' ,
63- childNodes : all ( node )
64- }
52+ function text ( node , schema ) {
53+ return patch ( node , { nodeName : '#text' , value : node . value } , schema )
54+ }
55+
56+ function comment ( node , schema ) {
57+ return patch ( node , { nodeName : '#comment' , data : node . value } , schema )
6558}
6659
67- function element ( node ) {
68- var shallow = xtend ( node )
60+ function element ( node , schema ) {
61+ var space = schema . space
62+ var shallow = xtend ( node , { children : [ ] } )
6963
70- shallow . children = [ ]
64+ return toH ( h , shallow , { space : space } )
7165
72- return toH ( function ( name , attrs ) {
66+ function h ( name , attrs ) {
7367 var values = [ ]
74- var content
68+ var p5
7569 var value
7670 var key
71+ var info
72+ var pos
7773
7874 for ( key in attrs ) {
75+ info = find ( schema , key )
7976 value = { name : key , value : attrs [ key ] }
8077
81- if ( own . call ( attributeSpaces , key ) ) {
82- value = xtend ( value , attributeSpaces [ key ] )
78+ if ( info . space && ignoredSpaces . indexOf ( info . space ) === - 1 ) {
79+ pos = key . indexOf ( ':' )
80+
81+ if ( pos === - 1 ) {
82+ value . prefix = ''
83+ } else {
84+ value . name = key . slice ( pos + 1 )
85+ value . prefix = key . slice ( 0 , pos )
86+ }
87+ value . namespace = ns [ info . space ]
8388 }
8489
8590 values . push ( value )
8691 }
8792
93+ p5 = patch ( node , { nodeName : name , tagName : name , attrs : values } , schema )
94+
8895 if ( name === 'template' ) {
89- content = transform ( shallow . content )
90- delete content . mode
91- content . nodeName = '#document-fragment'
96+ p5 . content = fragment ( shallow . content , schema )
9297 }
9398
94- return wrap (
95- node ,
96- {
97- nodeName : node . tagName ,
98- tagName : node . tagName ,
99- attrs : values ,
100- childNodes : node . children ? all ( node ) : [ ]
101- } ,
102- content
103- )
104- } , shallow )
99+ return p5
100+ }
105101}
106102
107- function doctype ( node ) {
108- return wrap ( node , {
109- nodeName : '#documentType' ,
110- name : node . name ,
111- publicId : node . public || '' ,
112- systemId : node . system || ''
113- } )
114- }
103+ // Patch specific properties.
104+ function patch ( node , p5 , parentSchema ) {
105+ var schema = parentSchema
106+ var position = node . position
107+ var children = node . children
108+ var childNodes = [ ]
109+ var length = children ? children . length : 0
110+ var index = - 1
111+ var child
112+
113+ if ( node . type === 'element' ) {
114+ if ( schema . space === 'html' && node . tagName === 'svg' ) {
115+ schema = svg
116+ }
115117
116- function text ( node ) {
117- return wrap ( node , {
118- nodeName : '#text' ,
119- value : node . value
120- } )
121- }
118+ p5 . namespaceURI = ns [ schema . space ]
119+ }
122120
123- function comment ( node ) {
124- return wrap ( node , {
125- nodeName : '#comment' ,
126- data : node . value
127- } )
128- }
121+ while ( ++ index < length ) {
122+ child = one ( children [ index ] , schema )
123+ child . parentNode = p5
124+ childNodes [ index ] = child
125+ }
129126
130- /* Patch position. */
131- function wrap ( node , ast , content ) {
132- var position = node . position
127+ if ( node . type === 'element' || node . type === 'root' ) {
128+ p5 . childNodes = childNodes
129+ }
133130
134131 if ( position && position . start && position . end ) {
135- ast . sourceCodeLocation = {
132+ p5 . sourceCodeLocation = {
136133 startLine : position . start . line ,
137134 startCol : position . start . column ,
138135 startOffset : position . start . offset ,
@@ -142,59 +139,5 @@ function wrap(node, ast, content) {
142139 }
143140 }
144141
145- if ( content ) {
146- ast . content = content
147- }
148-
149- return ast
150- }
151-
152- /* Patch a tree recursively, by adding namespaces
153- * and parent references where needed. */
154- function patch ( node , parent , ns ) {
155- var location = node . sourceCodeLocation
156- var children = node . childNodes
157- var name = node . tagName
158- var replacement = { }
159- var length
160- var index
161- var key
162-
163- for ( key in node ) {
164- if ( customProps . indexOf ( key ) === - 1 ) {
165- replacement [ key ] = node [ key ]
166- }
167- }
168-
169- if ( own . call ( namespaces , name ) ) {
170- ns = namespaces [ name ]
171- }
172-
173- if ( own . call ( replacement , 'tagName' ) ) {
174- replacement . namespaceURI = ns
175- }
176-
177- if ( children ) {
178- replacement . childNodes = children
179- length = children . length
180- index = - 1
181-
182- while ( ++ index < length ) {
183- children [ index ] = patch ( children [ index ] , replacement , ns )
184- }
185- }
186-
187- if ( name === 'template' ) {
188- replacement . content = patch ( node . content , null , ns )
189- }
190-
191- if ( parent ) {
192- replacement . parentNode = parent
193- }
194-
195- if ( location ) {
196- replacement . sourceCodeLocation = location
197- }
198-
199- return replacement
142+ return p5
200143}
0 commit comments