create-element-ns
Advanced tools
Comparing version 0.0.1 to 0.1.0
53
api.js
var is = require('./is') | ||
var elementDecorators = { | ||
//default | ||
'': setOther, | ||
// node API | ||
children: setChildren, | ||
//nodeName: null, | ||
textContent: setProp, | ||
// element API | ||
className: setProp, | ||
id: setProp, | ||
innerHTML: setProp, | ||
tagName: null, | ||
xmlns: null, | ||
//convenience non-standard items to either force properties or attributes | ||
var decorators = { | ||
a: setAttributes, | ||
attrs: setAttributes, | ||
attributes: setAttributes, | ||
p: setProperties, | ||
props: setProperties, | ||
properties: setProperties, | ||
} | ||
var htmlDecorators = { | ||
contentEditable: setProp, | ||
children: setChildren, | ||
dataset: setObj, | ||
style: setStyle, | ||
tabIndex: setProp | ||
s: setStyle, | ||
} | ||
var svgDecorators = { | ||
id: null, // read only property, revert to defaults with attributes | ||
} | ||
var api = { | ||
@@ -34,7 +20,3 @@ document: typeof document !== 'undefined' ? document : null, | ||
}, | ||
decorators: { | ||
element: elementDecorators, | ||
html: defaults(htmlDecorators, elementDecorators), | ||
svg: defaults(svgDecorators, elementDecorators), | ||
} | ||
decorators: decorators | ||
} | ||
@@ -55,5 +37,2 @@ | ||
} | ||
function setProp(e, k, v) { | ||
e[k] = v | ||
} | ||
function setObj(e, k, o) { | ||
@@ -63,9 +42,12 @@ for (var ki in o) e[k][ki] = o[ki] | ||
function setStyle(e, k, v) { | ||
if (typeof v === 'object') setObj(e, k, v) | ||
if (e.namespaceURI) e.setAttribute(k, styleString(v)) | ||
else if (typeof v === 'object') setObj(e, k, v) | ||
else e[k].cssText = v | ||
} | ||
function setOther(e, k, v) { | ||
if (k[0] === 'o' && k[1] === 'n' && is.function(v)) e[k] = v | ||
else setAttribute(e, k, v) | ||
function styleString(s) { | ||
return is.object(s) ? Object.keys(s).map(styleToString, s).join(';') : s | ||
} | ||
function styleToString(k) { | ||
return k + ':' + this[k] | ||
} | ||
function setAttribute(e, k, v) { | ||
@@ -90,6 +72,1 @@ var cIdx = k.indexOf(':') | ||
} | ||
// utils | ||
function defaults(t, s) { | ||
for (var k in s) if (t[k] === undefined) t[k] = s[k] | ||
return t | ||
} |
@@ -45,5 +45,3 @@ var parse = require('./sel'), | ||
: is.object(def) ? def | ||
: null | ||
if (!cfg) throw Error('invalid element definition') | ||
//if (cfg.prefix) throw Error('invalid element definition') | ||
: {} | ||
@@ -59,3 +57,2 @@ var xmlns = cfg.xmlns || api.namespaces[cfg.prefix] || ns, | ||
if (decorators[k]) decorators[k](el, k, cfg[k]) | ||
else decorators[''](el, k, cfg[k]) | ||
} | ||
@@ -62,0 +59,0 @@ return el |
@@ -10,8 +10,8 @@ var elm = require('./elm'), | ||
html: { | ||
el: elm(api.decorators.html), | ||
fn: elm(api.decorators.html, true) | ||
el: elm(api.decorators), | ||
fn: elm(api.decorators, true) | ||
}, | ||
svg: { | ||
el: elm(api.decorators.svg, false, api.namespaces.svg), | ||
fn: elm(api.decorators.svg, true, api.namespaces.svg) | ||
el: elm(api.decorators, false, api.namespaces.svg), | ||
fn: elm(api.decorators, true, api.namespaces.svg) | ||
} | ||
@@ -18,0 +18,0 @@ } |
{ | ||
"name": "create-element-ns", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"description": "dom createElement hyperscript with svg, namespace and selector support", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -21,3 +21,3 @@ <!-- markdownlint-disable MD004 MD007 MD010 MD041 MD022 MD024 MD032 MD036 --> | ||
var divEl1 = createHtmlEl('div.c1#i1[style="color:blue"].c2', {onclick: function() {}}), | ||
divEl2 = createHtmlEl('.i1', {className: 'c1 c2', style:{color: 'blue'}, onclick: function() {}}) | ||
divEl2 = createHtmlEl('.i1', {style: {color: 'blue'}, props:{className: 'c1 c2', , onclick: function() {}}}) | ||
@@ -66,3 +66,4 @@ // namespace in different ways | ||
* `definition`: a string selector, `elementFactory` or DOM Element | ||
* `options`: an optional object of attributes and properties or an optional `elementDecorator` | ||
* `options`: an optional `qualifier` object of attributes and properties or an optional `elementDecorator` function | ||
* `qualifier`: {properties:{}, attributes:{}, style:{}, dataset:{}}. Alias `s`, `a`, `p`, `d`, `props`, `attrs` | ||
* `elementDecorator(el) => el'` modifies an element directly | ||
@@ -69,0 +70,0 @@ * `content`: optional series of string, Element and arrays of strings and Elements |
57
sel.js
var markers = { | ||
tag: { | ||
'#': {m: 'v', k: 'id', f: reset, x: 'tag'}, | ||
'.': {m: 'v', k: 'className', f: append, x: 'tag'}, | ||
'[': {m: 'k', k: '', f: replaceTrue, x: 'key'}, | ||
'#': {m: 'v', f: setId, x: 'tag'}, | ||
'.': {m: 'v', f: appendClass, x: 'tag'}, | ||
'[': {m: 'k', k: '', f: setAttribute, x: 'key'}, | ||
}, | ||
@@ -18,16 +18,14 @@ key: { | ||
module.exports = function parseSel(sel) { | ||
var att = {} | ||
var res = {tagName: '', attributes: {}} | ||
var ctx = { | ||
x: markers.tag, | ||
c: markers.tag, | ||
m: 'v', | ||
k: 'tagName', | ||
v: '', | ||
f: reset | ||
f: setTN | ||
} | ||
for (var i=0; i<sel.length; ++i) { | ||
var act = ctx.x[sel[i]] | ||
var act = ctx.c[sel[i]] | ||
if (act) { | ||
if(act.f) { | ||
ctx.f(att, ctx.k, ctx.v) | ||
if(act.f) { // callback and reset | ||
ctx.f(res, ctx) | ||
ctx.k = act.k | ||
@@ -38,26 +36,33 @@ ctx.f = act.f | ||
if (act.m) ctx.m = act.m | ||
if (act.x) ctx.x = markers[act.x] | ||
if (act.x) ctx.c = markers[act.x] | ||
} | ||
else ctx[ctx.m] += sel[i] | ||
} | ||
ctx.f(att, ctx.k, ctx.v) | ||
return checkTagPrefix(att) | ||
ctx.f(res, ctx) | ||
return checkTagNS(res) | ||
} | ||
function reset(att, k, v) { | ||
if (v) att[k] = v | ||
function setId(res, ctx) { | ||
res.attributes.id = ctx.v | ||
} | ||
function replaceTrue(att, k, v) { | ||
att[k] = v || true | ||
function setTN(res, ctx) { | ||
res.tagName = ctx.v | ||
} | ||
function append(att, k, v) { | ||
if (v) att[k] = att[k] ? att[k] + ' ' + v : v | ||
function setAttribute(res, ctx) { | ||
if (ctx.k === 'xmlns') res.xmlns = ctx.v | ||
else res.attributes[ctx.k] = ctx.v || true | ||
} | ||
function checkTagPrefix(att) { | ||
var tagIndex = att.tagName && att.tagName.indexOf(':') | ||
function appendClass(res, ctx) { | ||
var att = res.attributes | ||
if (ctx.v) { | ||
if (att.class) att.class += ' ' + ctx.v | ||
else att.class = ctx.v | ||
} | ||
} | ||
function checkTagNS(res) { | ||
var tagIndex = res.tagName.indexOf(':') | ||
if (tagIndex >= 0) { | ||
att.prefix = att.tagName.slice(0, tagIndex) | ||
att.tagName = att.tagName.slice(tagIndex+1) | ||
res.prefix = res.tagName.slice(0, tagIndex) | ||
res.tagName = res.tagName.slice(tagIndex+1) | ||
} | ||
return att | ||
return res | ||
} |
@@ -48,7 +48,7 @@ var jsdom = require('jsdom').jsdom, | ||
ct('===', el.style.color, 'blue') | ||
ct('===', el.getAttribute('style'), 'color: blue;') | ||
ct('===', el.getAttribute('style'), 'color:blue') | ||
}) | ||
ct('decorators', function() { | ||
var handler = function(){}, | ||
el = htm('div', {className: 'c1 c2', id: 'i1', style:{color: 'blue'}, onclick: handler}) | ||
el = htm('div', {style:{color: 'blue'}, p:{className: 'c1 c2', id: 'i1', onclick: handler}}) | ||
ct('===', el.nodeName, 'DIV') | ||
@@ -58,4 +58,4 @@ ct('===', el.id, 'i1') | ||
ct('===', el.style.color, 'blue') | ||
ct('===', el.getAttribute('style'), 'color: blue;') | ||
ct('===', el.onclick.constructor, Function) | ||
ct('===', el.getAttribute('style'), 'color:blue') | ||
//ct('===', el.onclick.constructor, Function) | ||
}) | ||
@@ -70,6 +70,16 @@ ct('element namespace', function() { | ||
}) | ||
ct('styles', function() { //font-weight: bold; color: red; font-size:150%; | ||
var el0 = svg('circle[style=font-size:150%;color:blue;]'), | ||
el1 = htm('svg:circle[style=font-size:150%;color:blue]'), | ||
el2 = svg('circle', {style: {'font-size':'150%', color:'blue'}}), | ||
el3 = htm('', {style: {'font-size':'150%', color:'blue'}}) | ||
ct('===', el0.getAttribute('style'), 'font-size:150%;color:blue;') | ||
ct('===', el1.getAttribute('style'), 'font-size:150%;color:blue') | ||
ct('===', el2.getAttribute('style'), 'font-size:150%;color:blue') | ||
ct('===', el3.getAttribute('style'), 'font-size:150%;color:blue') | ||
}) | ||
ct('attribute namespace', function() { | ||
var el0 = svg('circle[xmlns:xlink="http://www.w3.org/1999/xlink"]'), | ||
el1 = svg('circle[xmlns:xlink="http://www.w3.org/1999/xlink"]'), | ||
el2 = htm('circle', {'xmlns:xlink':'http://www.w3.org/2000/svg'}) | ||
el2 = htm('circle', {a: {'xmlns:xlink':'http://www.w3.org/2000/svg'}}) | ||
ct('===', el0.hasAttributeNS('xmlns','xlink'), true) | ||
@@ -79,3 +89,3 @@ ct('===', el1.hasAttributeNS('xmlns','xlink'), true) | ||
}) | ||
ct('attribute namespace', function() { | ||
ct('function decorators', function() { | ||
var fac = main.html.fn, | ||
@@ -88,3 +98,3 @@ el0 = fac('div') | ||
ct('===', el0(dec).textContent, 'x') | ||
ct('===', el0({textContent: 'y'}).textContent, 'y') | ||
ct('===', el0({p:{textContent: 'y'}}).textContent, 'y') | ||
}) | ||
@@ -91,0 +101,0 @@ ct('forced properties and attributes', function() { |
@@ -5,25 +5,24 @@ var ct = require('cotest') | ||
ct('single tag', function(){ | ||
ct('{==}', sel('div'), {tagName: 'div'}) | ||
ct('{==}', sel(''), {}) | ||
ct('{==}', sel('div'), {tagName: 'div', attributes: {}}) | ||
ct('{==}', sel(''), {tagName: '', attributes: {}}) | ||
}) | ||
ct('mixed classes and id', function(){ | ||
ct('{==}', sel('.c1#i1.c2'), {id: 'i1', className: 'c1 c2'}) | ||
ct('{==}', sel('div#i1.c1.c2'), {tagName: 'div', id: 'i1', className: 'c1 c2'}) | ||
ct('{==}', sel('div.c1.c2#i1'), {tagName: 'div', id: 'i1', className: 'c1 c2'}) | ||
ct('{==}', sel('..##..##'), {}) | ||
ct('{==}', sel('.c1#i1.c2'), {tagName: '', attributes: {id: 'i1', class: 'c1 c2'}}) | ||
ct('{==}', sel('div#i1.c1.c2'), {tagName: 'div', attributes: {id: 'i1', class: 'c1 c2'}}) | ||
ct('{==}', sel('div.c1.c2#i1'), {tagName: 'div', attributes: {id: 'i1', class: 'c1 c2'}}) | ||
ct('{==}', sel('..##..##'), {tagName: '', attributes: {id: ''}}) | ||
}) | ||
ct('mixed classes and id as attributes', function(){ | ||
ct('{==}', sel('.c1#i1.c2[id=i2][className=c3]'), {id: 'i2', className: 'c3'}) | ||
ct('{==}', sel('.c1#i1.c2[id="i2"][className="c3"]'), {id: 'i2', className: 'c3'}) | ||
ct('{==}', sel('div#i1[class=c3].c1.c2'), {tagName: 'div', id: 'i1', className: 'c1 c2', class: 'c3'}) | ||
ct('{==}', sel('div#i1[class="c3"].c1.c2'), {tagName: 'div', id: 'i1', className: 'c1 c2', class: 'c3'}) | ||
ct('{==}', sel('.c1#i1.c2[id=i2][class=c3]'), {tagName: '', attributes: {id: 'i2', class: 'c3'}}) | ||
ct('{==}', sel('.c1#i1.c2[id="i2"][class="c3"]'), {tagName: '', attributes: {id: 'i2', class: 'c3'}}) | ||
ct('{==}', sel('div#i1[class=c3].c1.c2'), {tagName: 'div', attributes: {id: 'i1', class: 'c3 c1 c2'}}) | ||
ct('{==}', sel('div#i1[class="c3"].c1.c2'), {tagName: 'div', attributes: {id: 'i1', class: 'c3 c1 c2'}}) | ||
}) | ||
ct('tag namespace prefix', function(){ | ||
ct('{==}', sel('svg:circle'), {prefix: 'svg', tagName: 'circle'}) | ||
ct('{==}', sel('svg:circle'), {prefix: 'svg', tagName: 'circle', attributes: {}}) | ||
}) | ||
ct('markers in attribute values', function() { | ||
ct('{==}', sel('[a=b.c]').a, 'b.c') | ||
ct('{==}', sel('[a:b=c]')['a:b'], 'c') | ||
ct('{==}', sel('[a:b=c.d]')['a:b'], 'c.d') | ||
ct('{==}', sel('[a=b.c]').attributes.a, 'b.c') | ||
ct('{==}', sel('[a:b=c]').attributes['a:b'], 'c') | ||
ct('{==}', sel('[a:b=c.d]').attributes['a:b'], 'c.d') | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15037
80
375