Skip to content

Instantly share code, notes, and snippets.

@andybluntish
Last active August 29, 2015 14:26
Show Gist options
  • Save andybluntish/977b01c0c830553b3d85 to your computer and use it in GitHub Desktop.
Save andybluntish/977b01c0c830553b3d85 to your computer and use it in GitHub Desktop.
HTML Renderer
import Ember from 'ember';
const {
on,
get
} = Ember;
export default Ember.Component.extend({
classNames: ['html-element'],
_setup: on('init', function() {
const tagName = get(this, 'tagName');
const attributes = get(this, 'attributes');
const id = get(this, 'attributes.id');
const classNames = get(this, 'attributes.classNames');
const bindings = [];
if (id) {
this.elementId = id;
}
if (tagName) {
this.tagName = tagName;
}
if (classNames) {
this.classNames = this.classNames || [];
this.classNames = this.classNames.concat([classNames]);
}
for (var prop in attributes) {
if (attributes.hasOwnProperty(prop) && ['id', 'classNames'].indexOf(prop) === -1) {
this[prop] = attributes[prop];
bindings.push(prop);
}
}
this.attributeBindings = bindings;
})
});
import Ember from 'ember';
import HTMLElementComponent from './html-element';
export default HTMLElementComponent.extend({
classNames: ['special-element'],
clicks: 0,
click() {
this.element.style.background = 'orange';
window.setTimeout(() => {
this.element.style.background = 'white';
}, 500);
this.incrementProperty('clicks');
}
});
import Ember from 'ember';
export default Ember.Controller.extend({
appName:'HTML Renderer',
elements: Ember.computed.alias('model')
});
/**
* JsonDocument
*
* @param {HTMLElement} el - HTML element to parse.
* @throws {TypeError} Argument el must be a single instance of HTMLElement.
*/
var JsonDocument = (function() {
var _tagNameAttr = 'tagName';
var _componentNameAttr = 'componentName';
var _attributesAttr = 'attributes';
var _contentAttr = 'textContent';
var _childrenAttr = 'children';
function JsonDocument(el) {
if (!(el instanceof HTMLElement)) {
throw new TypeError ('Invalid Document() argument. Must be a single instance of HTMLElement.');
}
return _parse(el);
}
// Parse DOM
function _parse(node) {
if ([1, 3].indexOf(node.nodeType) === -1) {
return false;
}
var obj = {};
obj[_tagNameAttr] = node.nodeName;
obj[_componentNameAttr] = 'html-element';
if (node.nodeType === 1) { // element node
// Attributes
if (node.attributes && node.attributes.length > 0) {
obj[_attributesAttr] = {};
for (var i = 0, attributesLen = node.attributes.length, attr, attrName; i < attributesLen; i++) {
attr = node.attributes[i];
attrName = attr.nodeName === 'class' ? 'classNames' : attr.nodeName;
obj[_attributesAttr][attrName] = attr.nodeValue;
}
if (obj[_attributesAttr].classNames && obj[_attributesAttr].classNames.indexOf('something-special') > -1) {
obj[_componentNameAttr] = 'special-element';
}
}
} else { // non-element node (text, comment, etc...)
// Text content
obj[_contentAttr] = node.nodeValue;
}
// Child nodes
if (node.hasChildNodes()) {
var children = [];
// Recursively parse child nodes
for (var j = 0, childrenLen = node.childNodes.length, child; j < childrenLen; j++) {
child = _parse(node.childNodes[j]);
// Filter out empty #text nodes
if (child && !(child[_tagNameAttr] === '#text' && child[_contentAttr].trim() === '')) {
children.push(child);
}
}
obj[_childrenAttr] = children;
}
return obj;
}
return JsonDocument;
})();
var HTML = '<!-- Input -->\
<div id="pane">\
\
<!-- New Article -->\
<article id="article" class="h-entry">\
<header>\
<h1 class="p-name">\
<a class="u-url" href=/articles/1>Heading for the Article</a>\
</h1>\
\
<p class="subhead">Subhead for the Article</p>\
</header>\
\
<div data-foo="bar" class="e-content">\
<h1>Lorem Ipsum<br>Dolor Sit Amet</h1>\
\
<p class="something-special">Itaque earum rerum hic tenetur a sapiente delectus. Laboris nisi ut aliquip ex ea commodo consequat. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam. Excepteur sint occaecat cupidatat non proident, sunt in culpa. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae.</p>\
\
<figure class="image">\
<img src="//placehold.it/400x300" alt="placeholder">\
<figcaption>\
<p>\
<span class="number">1.1</span>\
<span class="caption">Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit.</span>\
</p>\
</figcaption>\
</figure>\
\
<h2>At Vero</h2>\
<p>Corrupti quos dolores et quas molestias excepturi sint occaecati. Non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit.</p>\
\
<ul>\
<li>Inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</li>\
<li>At vero eos et accusamus.</li>\
</ul>\
\
<h3>Nam Libero Tempore</h3>\
<p>Eaque ipsa quae ab illo inventore veritatis et quasi. Laboris nisi ut aliquip ex ea commodo consequat. Non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Totam rem aperiam.</p>\
\
<table>\
<caption>Table example</caption>\
<thead>\
<tr>\
<th>One</th>\
<th>Two</th>\
<th>Three</th>\
<th>Four</th>\
<th>Five</th>\
</tr>\
</thead>\
<tbody>\
<tr>\
<td>a</td>\
<td>b</td>\
<td>c</td>\
<td>d</td>\
<td>e</td>\
</tr>\
<tr>\
<td>f</td>\
<td>g</td>\
<td>h</td>\
<td>i</td>\
<td>j</td>\
</tr>\
<tr>\
<td>k</td>\
<td>l</td>\
<td>m</td>\
<td>n</td>\
<td>o</td>\
</tr>\
<tr>\
<td>p</td>\
<td>q</td>\
<td>r</td>\
<td>s</td>\
<td>t</td>\
</tr>\
<tr>\
<td>u</td>\
<td>v</td>\
<td>w</td>\
<td>x</td>\
<td>y</td>\
</tr>\
<tr>\
<td>z</td>\
<td><span class="something-special">&hearts;</span></td>\
<td>&clubs;</td>\
<td>&diams;</td>\
<td>&spades;</td>\
</tr>\
</tbody>\
</table>\
\
<h4>Et Harum Qidem Rerum</h4>\
<p>Inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque. Eaque ipsa quae ab illo inventore veritatis et quasi. Totam rem aperiam. Nihil molestiae consequatur, vel illum qui dolorem eum.</p>\
\
<ol>\
<li>Eaque ipsa quae ab illo inventore veritatis et quasi.</li>\
<li>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</li>\
<li>Quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</li>\
<li>Architecto beatae vitae dicta sunt explicabo.</li>\
</ol>\
\
<h5>Porro Quisquam</h5>\
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem. Et harum quidem rerum facilis est et expedita distinctio. Quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Eaque ipsa quae ab illo inventore veritatis et quasi. Nihil molestiae consequatur, vel illum qui dolorem eum.</p>\
</div>\
\
<footer>\
<p class="meta">Published <time class="dt-published" datetime="2014-11-06T23:50:24.948Z">Fri Nov 07 2014</time>. This entry was posted in <span class="p-category">articles</span>, and tagged with <a href="/tag/foo" class="tag">foo</a>, <a href="/tag/bar" class="tag">bar</a>, <a href="/tag/baz" class="tag">baz</a>.</p>\
</footer>\
</article>\
</div>';
var container = document.createElement('div');
var fragment = document.createDocumentFragment();
container.innerHTML = HTML;
fragment.appendChild(container);
var myDoc = new JsonDocument(container.querySelector('#pane'));
export default JSON.stringify([myDoc], null, 2);
import Ember from 'ember';
import data from '../data';
export default Ember.Route.extend({
model() {
console.log(data);
let d = JSON.parse(data);
return d;
}
});
<style>
.subhead { background: yellow; }
[data-foo] {
background: pink;
}
.special-element {
background: white;
border: 3px solid blue;
padding: 0.5em;
}
</style>
<h1>{{appName}}</h1>
{{#each elements as |child|}}
{{~component child.componentName
tagName=child.tagName
attributes=child.attributes
content=child.content
children=child.children
~}}
{{/each}}
{{~#each children as |child|~}}
{{~#if child.textContent~}}
{{~child.textContent~}}
{{~else~}}
{{~component child.componentName
tagName=child.tagName
attributes=child.attributes
content=child.content
children=child.children
~}}
{{~/if~}}
{{~/each~}}
<b>[{{clicks}}]</b>&nbsp;
{{~#each children as |child|~}}
{{~#if child.textContent~}}
{{~child.textContent~}}
{{~else~}}
{{~component child.componentName
tagName=child.tagName
attributes=child.attributes
content=child.content
children=child.children
~}}
{{~/if~}}
{{~/each~}}
{
"version": "0.4.6",
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.13.5/ember.js",
"ember-data": "https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.13.5/ember-data.js",
"ember-template-compiler": "https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.13.5/ember-template-compiler.js"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment