source Node.js
Full url: ./document/Node.js
/**
* @memberof smx
* @mixes Node-Core
* @mixes Node-Attributes
* @mixes Node-Traversal
*
* @description
* The Node class wraps an XMLNode and provides an easy to use api
* to interact with it.
*
* This class can be further extended by mixins from custom modules.
*/
class Node {
/**
* @constructor
* @param {XMLNode} xmlNode
*/
constructor(xmlNode) {
//require nodeType === 1 --> Node.ELEMENT_NODE
if(xmlNode.nodeType!==1)
throw(new Error('Node constructor requires ELEMENT_NODE'));
/**
* Original XMLNode for reference
* @type {XMLNode}
* @protected
*/
this[0] = xmlNode;
}
/**
* Direct access to XMLNode's id attribute.
* @type {String}
* @readonly
*/
get id() {
return this[0].getAttribute('id');
}
/**
* Direct access to XMLNode name
* @type {String}
* @readonly
*/
get name() {
return this[0].nodeName;
}
/**
* Gets node name based on inner XMLNode.nodeName,
* default is `smx`, posible values are `txt`, `md`, `html`, ...
* @type {String}
* @readonly
*/
get type() {
if(this[0].getAttribute)
return this[0].getAttribute('type') || 'smx';
else
return 'smx';
}
/**
* Gets node className based on inner XMLNode class attribute
* @type {String}
* @readonly
*/
get className() {
if(this[0].getAttribute)
return this[0].getAttribute('class');
else
return '';
}
/**
* Gets the owner SMXDoxument
* @type {SMXDocument}
* @readonly
*/
get document() {
return this._document;
}
/**
* Gets browser url hash
* @type {String}
* @readonly
*/
get hash() {
return '#!/' + this.uri;
}
/**
* Gets Uniform Resource Identifier.
* Concatenation of id values from parent nodes up to document root
* @type {String}
* @readonly
*/
get uri() {
let hash = this.id + '/';
if (this.parent) return this.parent.uri + hash;
else return hash;
}
/**
* Gets Uniform Resource Locator
* Concatenation of path values from parent nodes up to document root
* @type {String}
* @readonly
*/
get url() {
let path = this[0].getAttribute('path');
var result;
if (this.parent) {
if (!path)
result = this.parent.url;
else {
//add trail slash
let trail = path.substr(-1);
if (trail != '/') path += '/';
result = this.parent.url + path;
}
} else {
if (path){
//add trail slash
let trail = path.substr(-1);
if (trail != '/') path += '/';
result = path;
}
}
//remove double slashes
if (result) result = result.replace(/(https?:\/\/)|(\/)+/g, "$1$2");
return result;
}
/**
* Gets source file url for this node
* @type {String}
* @readonly
*/
get src() {
var result = '';
let file = this[0].getAttribute('file');
if (!file)
result = (this.parent) ? this.parent.src : undefined;
else
result = this.url + file;
//remove double slashes
if (result) result = result.replace(/(https?:\/\/)|(\/)+/g, "$1$2");
return result;
}
/**
* Gets parent node
* @type {SMXNode}
* @readonly
*/
get parent() {
return this.document.wrap(this[0].parentNode);
}
/**
* Gets ancestors nodes, ordered from outer to inner.
* @type {SMXNode[]}
* @readonly
*/
get ancestors() {
var a = [];
var p = this;
while(p.parent){
p = p.parent;
a.unshift(p);
}
return a;
}
/**
* Gets root node
* @type {SMXNode}
* @readonly
*/
get root() {
return this.ancestors[0] || this;
}
/**
* Gets children nodes
* @type {SMXNode[]}
* @readonly
*/
get children() {
//non smx nodes should have no children
if(this.type!=='smx') return [];
else return this.document.wrap(this[0].childNodes);
}
/**
* Gets first child node
* @type {SMXNode}
* @readonly
*/
get first() {
return this.children.shift();
}
/**
* Gets last child node
* @type {SMXNode}
* @readonly
*/
get last() {
return this.children.pop();
}
/**
* Gets previous sibling node
* @type {SMXNode}
* @readonly
*/
get previous(){
return this.document.wrap(this[0].previousElementSibling || this[0].previousSibling);
}
/**
* Gets next sibling node
* @type {SMXNode}
* @readonly
*/
get next(){
return this.document.wrap(this[0].nextElementSibling || this[0].nextSibling);
}
}
//import Node extensions
import NodeCore from './Node-Core.js';
import NodeTraversal from './Node-Traversal.js';
import NodeAttributes from './Node-Attributes.js';
//extends Node prototype
Object.assign(Node.prototype, NodeCore);
Object.assign(Node.prototype, NodeTraversal);
Object.assign(Node.prototype, NodeAttributes);
export default Node;