Last active
July 5, 2016 20:47
-
-
Save sukima/92afbfbe20855a43a2387f75422a5bf8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*\ | |
title: $:/plugins/sukima/dombuilder/dombuilder.js | |
type: application/javascript | |
module-type: library | |
Micro DSL for DOM creation and stringification. | |
\*/ | |
/** | |
* @module Utils | |
* @author Devin Weaver | |
*/ | |
/*jshint node: true, browser: true */ | |
(function(root, factory) { | |
if (typeof define === 'function' && define.amd) { | |
define([], factory); | |
} else if (typeof module === 'object' && module.exports) { | |
module.exports = factory(); | |
} else { | |
root.DomBuilder = factory(); | |
} | |
})(this, function() { | |
/** | |
* Helper utility to construct complex DOM nodes easily. | |
* | |
* @class DomBuilder | |
* @constructor | |
* @param {DomBuilder|DOMElement|String} [root=div] A DOM element or string. | |
* If `root` is a DomBuilder it will become `root` instead | |
* @param {DOMDocument} [document=window.document] the document object used | |
* to create elements | |
* @public | |
*/ | |
function DomBuilder(root, document) { | |
if (root instanceof DomBuilder) { | |
return root; | |
} | |
if (!(this instanceof DomBuilder)) { | |
return new DomBuilder(root, document); | |
} | |
this.document = document || window.document; | |
this.tag = root || 'div'; | |
this.elements = []; | |
this.attributes = {}; | |
this.namespace = null; | |
this.parent = null; | |
} | |
DomBuilder.prototype._addElement = function(element) { | |
var el = new DomBuilder(element, this.document); | |
el.parent = this; | |
this.elements.push(el); | |
return el; | |
}; | |
/** | |
* @method add | |
* @param {DomBuilder|DOMElement|String} element the element to add to this | |
* DomBuilders elements list | |
* @return {DomBuilder} the new child element (DomBuilder) unless `element` | |
* is a DomBuilder in which case `this` is returned | |
* @chainable | |
* @public | |
*/ | |
DomBuilder.prototype.add = function add(element) { | |
var el = this._addElement(element); | |
return (element instanceof DomBuilder) ? this : el; | |
}; | |
/** | |
* @method text | |
* @param {String} the text to append | |
* @chainable | |
* @public | |
*/ | |
DomBuilder.prototype.text = function text(content) { | |
var node = this.document.createTextNode(content); | |
this._addElement(node); | |
return this; | |
}; | |
/** | |
* @method attr | |
* @param {String} name the attribute name | |
* @param {String} value the attribute value | |
* @chainable | |
* @public | |
*/ | |
DomBuilder.prototype.attr = function attr(name, value) { | |
this.attributes[name] = $tw.utils.htmlEncode(value); | |
return this; | |
}; | |
/** | |
* @method end | |
* @return {DomBuilder} the parent DomBuilder in the hierarchy | |
* @chainable | |
* @public | |
*/ | |
DomBuilder.prototype.end = function end() { | |
return this.parent || this; | |
}; | |
/** | |
* @method toDOM | |
* @param {DOMDocument} [document=this.document] the document object to | |
* propagate down the recursion chain | |
* @return {DOMElement} the compiled DOMElement with its child hierarchy | |
* @public | |
*/ | |
DomBuilder.prototype.toDOM = function toDOM(document) { | |
var node, name; | |
document = document || this.document; | |
if (typeof this.tag === 'string') { | |
node = (this.namespace) ? | |
document.createElementNS(this.namespace, this.tag) : | |
document.createElement(this.tag); | |
} else { | |
node = this.tag; | |
} | |
for (name in this.attributes) { | |
node.setAttribute(name, this.attributes[name]); | |
} | |
this.elements.forEach(function(element) { | |
node.appendChild(element.toDOM(document)); | |
}); | |
return node; | |
}; | |
/** | |
* @method toString | |
* @return {String} the HTML for this DomBuilder's hierarchy | |
* @public | |
*/ | |
DomBuilder.prototype.toString = function toString() { | |
return this.toDOM().outerHTML; | |
}; | |
/** | |
* The tag (or DOMElement) for this node. | |
* @property tag | |
* @type {String|DOMElement} | |
* @default div | |
* @private | |
*/ | |
/** | |
* List of child elements for this DomBuilders hierarchy level. | |
* @property elements | |
* @type {Array} | |
* @private | |
*/ | |
/** | |
* List of attributes to apply to this DOMElement. | |
* @property attributes | |
* @type {Object} | |
* @private | |
*/ | |
/** | |
* The namespace for this DOMElement. | |
* @property namespace | |
* @type {String} | |
* @default null | |
* @private | |
*/ | |
/** | |
* The parent DomBuilder in the hierarchy. | |
* @property parent | |
* @type {DomBuilder} | |
* @default null | |
* @private | |
*/ | |
return DomBuilder; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*\ | |
title: ExamplePlugin.js | |
type: application/javascript | |
module-type: macro | |
Example macro using the DomBuilder. | |
\*/ | |
/*jshint node: true, browser: true */ | |
/*global $tw: false */ | |
(function() { | |
exports.name = 'example'; | |
exports.run = function(filter) { | |
return $tw.utils.DomBuilder('pre', this.document) | |
.add('code') | |
.add('div') | |
.attr('class', 'tc-alert') | |
.add('span').text('this is some text in a span').end() | |
.add('div') | |
.attr('class', 'my-title') | |
.renderText(this.wiki.getTiddlerText('$:/SiteTitle')) | |
.end() | |
.add('div') | |
.attr('class', 'my-tiddler') | |
.renderTiddler('GettingStarted').end() | |
.end() | |
.end() | |
.toString(); | |
}; | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*\ | |
title: $:/plugins/sukima/dombuilder/tw-dombuilder.js | |
type: application/javascript | |
module-type: utils | |
Defines $tw.utils.DomBuilder and extends DomBuilder with Tiddly Wiki addons. | |
\*/ | |
/** | |
* @module Utils | |
* @author Devin Weaver | |
*/ | |
/*jshint node: true, browser: true */ | |
/*global $tw: false */ | |
(function() { | |
/** | |
* @class DomBuilder | |
*/ | |
var DomBuilder = require('$:/plugins/sukima/dombuilder/dombuilder'); | |
/** | |
* Render a tiddler's text and construct a node tre for it. | |
* | |
* Will auto wrap the output in a `div` but will continue the chain so the | |
* wrapped div can be modified with `add()`, `text()`, and `attr()`. | |
* | |
* @method renderTiddler | |
* @param {String} title the tiddler title to render | |
* @return {DomBuilder} a wrapped DomBuilder with the rendered nodes within | |
* @chainable | |
* @public | |
*/ | |
DomBuilder.prototype.renderTiddler = function renderTiddler(title) { | |
var widgetNode = $tw.wiki.makeWidget($tw.wiki.parseTiddler(title)); | |
var container = new DomBuilder('div', this.document).toDOM(); | |
widgetNode.render(container, null); | |
return this.add(container); | |
}; | |
/** | |
* Render TiddlyWiki text and add it as a text node. | |
* | |
* @method renderText | |
* @param {String} text the tiddlywiki text to render | |
* @return {DomBuilder} a wrapped DomBuilder with the rendered nodes within | |
* @chainable | |
* @public | |
*/ | |
DomBuilder.prototype.renderText = function renderText(text) { | |
var rendered = | |
$tw.wiki.renderText('text/plain', 'text/vnd.tiddlywiki', text); | |
return this.text(rendered); | |
}; | |
$tw.utils.DomBuilder = DomBuilder; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment