98 lines
1.9 KiB
JavaScript
98 lines
1.9 KiB
JavaScript
|
/*
|
||
|
Module Dependencies
|
||
|
*/
|
||
|
var htmlparser = require('htmlparser2'),
|
||
|
_ = require('underscore'),
|
||
|
isTag = require('./utils').isTag;
|
||
|
|
||
|
/*
|
||
|
Parser
|
||
|
*/
|
||
|
exports = module.exports = function(content, options) {
|
||
|
var dom = evaluate(content, options);
|
||
|
|
||
|
// Generic root element
|
||
|
var root = {
|
||
|
type: 'root',
|
||
|
name: 'root',
|
||
|
parent: null,
|
||
|
prev: null,
|
||
|
next: null,
|
||
|
children: []
|
||
|
};
|
||
|
|
||
|
// Update the dom using the root
|
||
|
update(dom, root);
|
||
|
|
||
|
return root;
|
||
|
};
|
||
|
|
||
|
var evaluate = exports.evaluate = function(content, options) {
|
||
|
// options = options || $.fn.options;
|
||
|
|
||
|
var handler = new htmlparser.DomHandler(options),
|
||
|
parser = new htmlparser.Parser(handler, options);
|
||
|
|
||
|
parser.write(content);
|
||
|
parser.done();
|
||
|
|
||
|
return connect(handler.dom);
|
||
|
};
|
||
|
|
||
|
var connect = exports.connect = function(dom, parent) {
|
||
|
parent = parent || null;
|
||
|
|
||
|
var prevElem = null;
|
||
|
|
||
|
_.each(dom, function(elem) {
|
||
|
// If tag and no attributes, add empty object
|
||
|
if (isTag(elem.type) && elem.attribs === undefined)
|
||
|
elem.attribs = {};
|
||
|
|
||
|
// Set parent
|
||
|
elem.parent = parent;
|
||
|
|
||
|
// Previous Sibling
|
||
|
elem.prev = prevElem;
|
||
|
|
||
|
// Next sibling
|
||
|
elem.next = null;
|
||
|
if (prevElem) prevElem.next = elem;
|
||
|
|
||
|
// Run through the children
|
||
|
if (elem.children)
|
||
|
connect(elem.children, elem);
|
||
|
else if (isTag(elem.type))
|
||
|
elem.children = [];
|
||
|
|
||
|
// Get ready for next element
|
||
|
prevElem = elem;
|
||
|
});
|
||
|
|
||
|
return dom;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
Update the dom structure, for one changed layer
|
||
|
|
||
|
* Much faster than reconnecting
|
||
|
*/
|
||
|
var update = exports.update = function(arr, parent) {
|
||
|
// normalize
|
||
|
if (!Array.isArray(arr)) arr = [arr];
|
||
|
|
||
|
// Update neighbors
|
||
|
for (var i = 0; i < arr.length; i++) {
|
||
|
arr[i].prev = arr[i - 1] || null;
|
||
|
arr[i].next = arr[i + 1] || null;
|
||
|
arr[i].parent = parent || null;
|
||
|
}
|
||
|
|
||
|
// Update parent
|
||
|
parent.children = arr;
|
||
|
|
||
|
return parent;
|
||
|
};
|
||
|
|
||
|
// module.exports = $.extend(exports);
|