@ -53,144 +53,140 @@ module.exports = config => {
} ,
/ * *
* Fetch data from node
* @ param { HTMLElement } el DOM
* Get data from the node element
* @ param { HTMLElement } el DOM element to traverse
* @ return { Array < Object > }
* /
parseNode ( el ) {
var result = [ ] ;
var nodes = el . childNodes ;
const result = [ ] ;
const nodes = el . childNodes ;
for ( var i = 0 , len = nodes . length ; i < len ; i ++ ) {
var node = nodes [ i ] ;
var model = { } ;
var attrs = node . attributes || [ ] ;
var attrsLen = attrs . length ;
var prevI = result . length - 1 ;
var prevSib = result [ prevI ] ;
var ct = this . compTypes ;
if ( ct ) {
var obj = '' ;
/ *
for ( var cType in ct ) {
var component = ct [ cType ] . model ;
obj = component . isComponent ( node ) ;
if ( obj )
break ;
} * /
for ( var it = 0 ; it < ct . length ; it ++ ) {
var component = ct [ it ] . model ;
obj = component . isComponent ( node ) ;
if ( obj )
break ;
const node = nodes [ i ] ;
const attrs = node . attributes || [ ] ;
const attrsLen = attrs . length ;
const nodePrev = result [ result . length - 1 ] ;
const nodeChild = node . childNodes . length ;
const ct = this . compTypes ;
let model = { } ;
// Start with understanding what kind of component it is
if ( ct ) {
let obj = '' ;
// Iterate over all available Component Types and
// the first with a valid result will be that component
for ( let it = 0 ; it < ct . length ; it ++ ) {
obj = ct [ it ] . model . isComponent ( node ) ;
if ( obj ) break ;
}
model = obj ;
}
if ( ! model . tagName )
// Set tag name if not yet done
if ( ! model . tagName ) {
model . tagName = node . tagName ? node . tagName . toLowerCase ( ) : '' ;
}
if ( attrsLen )
if ( attrsLen ) {
model . attributes = { } ;
}
// Stor e attributes
for ( var j = 0 ; j < attrsLen ; j ++ ) {
var nodeName = attrs [ j ] . nodeName ;
var nodeValue = attrs [ j ] . nodeValue ;
// Pars e attributes
for ( let j = 0 ; j < attrsLen ; j ++ ) {
const nodeName = attrs [ j ] . nodeName ;
let nodeValue = attrs [ j ] . nodeValue ;
//Isolate few attributes
if ( nodeName == 'style' )
// Isolate attributes
if ( nodeName == 'style' ) {
model . style = this . parseStyle ( nodeValue ) ;
else if ( nodeName == 'class' )
} else if ( nodeName == 'class' ) {
model . classes = this . parseClass ( nodeValue ) ;
else if ( nodeName == 'contenteditable' )
} else if ( nodeName == 'contenteditable' ) {
continue ;
else if ( nodeName . indexOf ( modelAttrStart ) === 0 ) {
} else if ( nodeName . indexOf ( modelAttrStart ) === 0 ) {
const modelAttr = nodeName . replace ( modelAttrStart , '' ) ;
const valueLen = nodeValue . length ;
const firstChar = nodeValue && nodeValue . substr ( 0 , 1 ) ;
const lastChar = nodeValue && nodeValue . substr ( valueLen - 1 ) ;
nodeValue = nodeValue === 'true' ? true : nodeValue ;
nodeValue = nodeValue === 'false' ? false : nodeValue ;
// Try to json parse where is possible
// Try to parse JSON where it's possible
// I can get false positive here (eg. a selector '[data-attr]')
// so put it under try/catch and let fail silently
try {
nodeValue = ( firstChar == '{' && lastChar == '}' ) ||
( firstChar == '[' && lastChar == ']' ) ? JSON . parse ( nodeValue ) : nodeValue ;
} catch ( e ) { }
model [ modelAttr ] = nodeValue ;
} else {
model . attributes [ nodeName ] = nodeValue ;
}
}
// Check for nested elements but avoid it if already provided
if ( nodeChild && ! model . components ) {
// Avoid infinite nested text nodes
const firstChild = node . childNodes [ 0 ] ;
var nodeChild = node . childNodes . length ;
// Check for nested elements and avoid them if an array
// was already given
if ( nodeChild && ! model . components ) {
// Avoid infinite text nodes nesting
var firstChild = node . childNodes [ 0 ] ;
if ( nodeChild === 1 && firstChild . nodeType === 3 ) {
if ( ! model . type ) {
model . type = 'text' ;
}
// If there is only one child and it's a TEXTNODE
// just make it content of the current node
if ( nodeChild === 1 && firstChild . nodeType === 3 ) {
! model . type && ( model . type = 'text' ) ;
model . content = firstChild . nodeValue ;
} else {
var parsed = this . parseNode ( node ) ;
// From: <div> <span>TEST</span> </div> <-- span is text type
// TO: <div> TEST </div> <-- div become text type
if ( parsed . length == 1 && parsed [ 0 ] . type == 'text' &&
parsed [ 0 ] . tagName == TEXT_NODE ) {
model . type = 'text' ;
model . content = parsed [ 0 ] . content ;
} else
model . components = parsed ;
} else {
model . components = this . parseNode ( node ) ;
}
}
// Check if it's a text node and if could be moved to the prevous model
if ( model . type == 'textnode' ) {
var prevIsText = prevSib && prevSib . type == 'textnode' ;
if ( prevIsText ) {
prevSib . content += model . content ;
if ( model . type == 'textnode' ) {
if ( nodePrev && nodePrev . type == 'textnode' ) {
nodePrev . content += model . content ;
continue ;
}
// Throw away empty nodes (keep spaces)
var content = node . nodeValue ;
if ( content != ' ' && ! content . trim ( ) ) {
const content = node . nodeValue ;
if ( content != ' ' && ! content . trim ( ) ) {
continue ;
}
}
// If all children are texts and there is some textnode the parent should
// be text too otherwise I'm unable to edit texnodes
var comps = model . components ;
if ( ! model . type && comps ) {
var allTxt = 1 ;
var foundTextNode = 0 ;
for ( var ci = 0 ; ci < comps . length ; ci ++ ) {
var comp = comps [ ci ] ;
if ( comp . type != 'text' &&
comp . type != 'textnode' &&
c . textTags . indexOf ( comp . tagName ) < 0 ) {
const comps = model . components ;
if ( ! model . type && comps ) {
let allTxt = 1 ;
let foundTextNode = 0 ;
for ( let ci = 0 ; ci < comps . length ; ci ++ ) {
const comp = comps [ ci ] ;
const cType = comp . type ;
if ( [ 'text' , 'textnode' ] . indexOf ( cType ) < 0 &&
c . textTags . indexOf ( comp . tagName ) < 0 ) {
allTxt = 0 ;
break ;
}
if ( comp . type == 'textnode' )
if ( cType == 'textnode' ) {
foundTextNode = 1 ;
}
}
if ( allTxt && foundTextNode )
if ( allTxt && foundTextNode ) {
model . type = 'text' ;
}
}
// If tagName is still empty and is not a textnode, do not push it
if ( ! model . tagName && model . type != 'textnode' )
if ( ! model . tagName && model . type != 'textnode' ) {
continue ;
}
result . push ( model ) ;
}