Browse Source

Start refactoring ParserHtml

pull/600/head
Artur Arseniev 9 years ago
parent
commit
f69556219b
  1. 103
      src/parser/model/ParserHtml.js

103
src/parser/model/ParserHtml.js

@ -53,95 +53,92 @@ 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 = {};
}
// Store attributes
for (var j = 0; j < attrsLen; j++){
var nodeName = attrs[j].nodeName;
var nodeValue = attrs[j].nodeValue;
// Parse 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);
} else {
const 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' &&
@ -155,9 +152,9 @@ module.exports = config => {
// 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';
var prevIsText = nodePrev && nodePrev.type == 'textnode';
if(prevIsText){
prevSib.content += model.content;
nodePrev.content += model.content;
continue;
}
// Throw away empty nodes (keep spaces)

Loading…
Cancel
Save