This commit is contained in:
@@ -0,0 +1,354 @@
|
||||
/** First-party DOM for summon page JS. Wraps the HTML tree; no host objects leak. */
|
||||
|
||||
function bareSummonClassList(node) {
|
||||
return {
|
||||
add: function () {
|
||||
var set = (node.attrs.class || '').split(/\s+/).filter(Boolean)
|
||||
var i
|
||||
for (i = 0; i < arguments.length; i++) {
|
||||
var n = String(arguments[i] || '')
|
||||
if (n && set.indexOf(n) < 0) set.push(n)
|
||||
}
|
||||
node.attrs.class = set.join(' ')
|
||||
},
|
||||
remove: function () {
|
||||
var set = (node.attrs.class || '').split(/\s+/).filter(Boolean)
|
||||
var i
|
||||
for (i = 0; i < arguments.length; i++) {
|
||||
var n = String(arguments[i] || '')
|
||||
var x = set.indexOf(n)
|
||||
if (x >= 0) set.splice(x, 1)
|
||||
}
|
||||
node.attrs.class = set.join(' ')
|
||||
},
|
||||
contains: function (n) {
|
||||
return (node.attrs.class || '').split(/\s+/).indexOf(String(n || '')) >= 0
|
||||
},
|
||||
toggle: function (n) {
|
||||
n = String(n || '')
|
||||
if (this.contains(n)) this.remove(n)
|
||||
else this.add(n)
|
||||
},
|
||||
toString: function () {
|
||||
return node.attrs.class || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function bareSummonWrapNode(node, env) {
|
||||
if (!node) return null
|
||||
if (node._el) return node._el
|
||||
if (node.type === 'text') {
|
||||
var tn = {
|
||||
nodeType: 3,
|
||||
nodeName: '#text',
|
||||
get data() {
|
||||
return node.text || ''
|
||||
},
|
||||
set data(v) {
|
||||
node.text = String(v)
|
||||
},
|
||||
get textContent() {
|
||||
return node.text || ''
|
||||
},
|
||||
set textContent(v) {
|
||||
node.text = String(v)
|
||||
}
|
||||
}
|
||||
node._el = tn
|
||||
return tn
|
||||
}
|
||||
var el = {
|
||||
nodeType: 1,
|
||||
nodeName: String(node.name || '').toUpperCase(),
|
||||
tagName: String(node.name || '').toUpperCase(),
|
||||
_node: node,
|
||||
get id() {
|
||||
return node.attrs.id || ''
|
||||
},
|
||||
set id(v) {
|
||||
node.attrs.id = String(v == null ? '' : v)
|
||||
},
|
||||
get className() {
|
||||
return node.attrs.class || ''
|
||||
},
|
||||
set className(v) {
|
||||
node.attrs.class = String(v == null ? '' : v)
|
||||
},
|
||||
get classList() {
|
||||
return bareSummonClassList(node)
|
||||
},
|
||||
get href() {
|
||||
return node.attrs.href || ''
|
||||
},
|
||||
set href(v) {
|
||||
node.attrs.href = String(v == null ? '' : v)
|
||||
},
|
||||
get src() {
|
||||
return node.attrs.src || ''
|
||||
},
|
||||
set src(v) {
|
||||
node.attrs.src = String(v == null ? '' : v)
|
||||
},
|
||||
get value() {
|
||||
return node.attrs.value != null ? String(node.attrs.value) : ''
|
||||
},
|
||||
set value(v) {
|
||||
node.attrs.value = String(v == null ? '' : v)
|
||||
},
|
||||
get textContent() {
|
||||
return bareSummonTextContent(node)
|
||||
},
|
||||
set textContent(v) {
|
||||
node.children = [
|
||||
{
|
||||
type: 'text',
|
||||
text: String(v == null ? '' : v),
|
||||
parent: node,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
get innerHTML() {
|
||||
return bareSummonSerializeInner(node)
|
||||
},
|
||||
set innerHTML(v) {
|
||||
var kids = bareSummonParseFragment(String(v == null ? '' : v))
|
||||
var i
|
||||
for (i = 0; i < kids.length; i++) kids[i].parent = node
|
||||
node.children = kids
|
||||
},
|
||||
getAttribute: function (k) {
|
||||
k = String(k || '').toLowerCase()
|
||||
return node.attrs && node.attrs[k] != null ? String(node.attrs[k]) : null
|
||||
},
|
||||
setAttribute: function (k, v) {
|
||||
node.attrs[String(k || '').toLowerCase()] = String(v == null ? '' : v)
|
||||
},
|
||||
removeAttribute: function (k) {
|
||||
delete node.attrs[String(k || '').toLowerCase()]
|
||||
},
|
||||
hasAttribute: function (k) {
|
||||
return (
|
||||
node.attrs &&
|
||||
Object.prototype.hasOwnProperty.call(
|
||||
node.attrs,
|
||||
String(k || '').toLowerCase()
|
||||
)
|
||||
)
|
||||
},
|
||||
appendChild: function (child) {
|
||||
var cn = child && child._node ? child._node : child
|
||||
if (!cn || !cn.type) return child
|
||||
if (cn.parent && cn.parent.children) {
|
||||
var ix = cn.parent.children.indexOf(cn)
|
||||
if (ix >= 0) cn.parent.children.splice(ix, 1)
|
||||
}
|
||||
cn.parent = node
|
||||
node.children.push(cn)
|
||||
return bareSummonWrapNode(cn, env)
|
||||
},
|
||||
removeChild: function (child) {
|
||||
var cn = child && child._node ? child._node : child
|
||||
var ix = node.children.indexOf(cn)
|
||||
if (ix >= 0) {
|
||||
node.children.splice(ix, 1)
|
||||
cn.parent = null
|
||||
}
|
||||
return child
|
||||
},
|
||||
insertBefore: function (child, ref) {
|
||||
var cn = child && child._node ? child._node : child
|
||||
var rn = ref && ref._node ? ref._node : ref
|
||||
if (cn.parent && cn.parent.children) {
|
||||
var px = cn.parent.children.indexOf(cn)
|
||||
if (px >= 0) cn.parent.children.splice(px, 1)
|
||||
}
|
||||
cn.parent = node
|
||||
var at = rn ? node.children.indexOf(rn) : -1
|
||||
if (at < 0) node.children.push(cn)
|
||||
else node.children.splice(at, 0, cn)
|
||||
return bareSummonWrapNode(cn, env)
|
||||
},
|
||||
querySelector: function (sel) {
|
||||
var hits = bareSummonQueryAll(node, sel, 1)
|
||||
return hits[0] ? bareSummonWrapNode(hits[0], env) : null
|
||||
},
|
||||
querySelectorAll: function (sel) {
|
||||
return bareSummonQueryAll(node, sel, 500).map(function (n) {
|
||||
return bareSummonWrapNode(n, env)
|
||||
})
|
||||
},
|
||||
getElementsByTagName: function (name) {
|
||||
name = String(name || '').toLowerCase()
|
||||
return bareSummonQueryAll(node, name === '*' ? '*' : name, 500).map(
|
||||
function (n) {
|
||||
return bareSummonWrapNode(n, env)
|
||||
}
|
||||
)
|
||||
},
|
||||
getElementsByClassName: function (name) {
|
||||
return bareSummonQueryAll(node, '.' + String(name || ''), 500).map(
|
||||
function (n) {
|
||||
return bareSummonWrapNode(n, env)
|
||||
}
|
||||
)
|
||||
},
|
||||
addEventListener: function (type, fn) {
|
||||
if (!node._listeners) node._listeners = {}
|
||||
var t = String(type || '')
|
||||
if (!node._listeners[t]) node._listeners[t] = []
|
||||
node._listeners[t].push(fn)
|
||||
},
|
||||
removeEventListener: function (type, fn) {
|
||||
var t = String(type || '')
|
||||
var arr = node._listeners && node._listeners[t]
|
||||
if (!arr) return
|
||||
node._listeners[t] = arr.filter(function (x) {
|
||||
return x !== fn
|
||||
})
|
||||
},
|
||||
click: function () {
|
||||
var arr = (node._listeners && node._listeners.click) || []
|
||||
var i
|
||||
for (i = 0; i < arr.length; i++) {
|
||||
try {
|
||||
arr[i].call(el)
|
||||
} catch (e) {
|
||||
if (env && env.console && env.console.error) env.console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Object.defineProperty(el, 'style', {
|
||||
get: function () {
|
||||
if (!node._styleProxy) {
|
||||
var decl = bareSummonParseDeclarations(node.attrs.style || '')
|
||||
node._styleProxy = decl
|
||||
}
|
||||
return node._styleProxy
|
||||
}
|
||||
})
|
||||
Object.defineProperty(el, 'children', {
|
||||
get: function () {
|
||||
return (node.children || [])
|
||||
.filter(function (c) {
|
||||
return c.type === 'element'
|
||||
})
|
||||
.map(function (c) {
|
||||
return bareSummonWrapNode(c, env)
|
||||
})
|
||||
}
|
||||
})
|
||||
Object.defineProperty(el, 'childNodes', {
|
||||
get: function () {
|
||||
return (node.children || []).map(function (c) {
|
||||
return bareSummonWrapNode(c, env)
|
||||
})
|
||||
}
|
||||
})
|
||||
Object.defineProperty(el, 'parentNode', {
|
||||
get: function () {
|
||||
return node.parent ? bareSummonWrapNode(node.parent, env) : null
|
||||
}
|
||||
})
|
||||
Object.defineProperty(el, 'firstChild', {
|
||||
get: function () {
|
||||
var c = node.children && node.children[0]
|
||||
return c ? bareSummonWrapNode(c, env) : null
|
||||
}
|
||||
})
|
||||
node._el = el
|
||||
return el
|
||||
}
|
||||
|
||||
function bareSummonFlushInlineStyle(node) {
|
||||
if (!node) return
|
||||
if (node._styleProxy) {
|
||||
var bits = []
|
||||
var k
|
||||
for (k in node._styleProxy) {
|
||||
if (Object.prototype.hasOwnProperty.call(node._styleProxy, k)) {
|
||||
bits.push(k + ':' + node._styleProxy[k])
|
||||
}
|
||||
}
|
||||
node.attrs.style = bits.join(';')
|
||||
}
|
||||
var ch = node.children || []
|
||||
var i
|
||||
for (i = 0; i < ch.length; i++) bareSummonFlushInlineStyle(ch[i])
|
||||
}
|
||||
|
||||
function bareSummonCreateDocumentApi(doc, env) {
|
||||
env = env || {}
|
||||
var api = {
|
||||
nodeType: 9,
|
||||
nodeName: '#document',
|
||||
documentElement: bareSummonWrapNode(doc.html, env),
|
||||
head: bareSummonWrapNode(doc.head, env),
|
||||
body: bareSummonWrapNode(doc.body, env),
|
||||
get title() {
|
||||
return doc.title || ''
|
||||
},
|
||||
set title(v) {
|
||||
doc.title = String(v == null ? '' : v)
|
||||
},
|
||||
getElementById: function (id) {
|
||||
var hits = bareSummonQueryAll(doc.root, '#' + String(id || ''), 1)
|
||||
return hits[0] ? bareSummonWrapNode(hits[0], env) : null
|
||||
},
|
||||
querySelector: function (sel) {
|
||||
var hits = bareSummonQueryAll(doc.root, sel, 1)
|
||||
return hits[0] ? bareSummonWrapNode(hits[0], env) : null
|
||||
},
|
||||
querySelectorAll: function (sel) {
|
||||
return bareSummonQueryAll(doc.root, sel, 500).map(function (n) {
|
||||
return bareSummonWrapNode(n, env)
|
||||
})
|
||||
},
|
||||
getElementsByTagName: function (name) {
|
||||
name = String(name || '').toLowerCase()
|
||||
return bareSummonQueryAll(doc.root, name === '*' ? '*' : name, 500).map(
|
||||
function (n) {
|
||||
return bareSummonWrapNode(n, env)
|
||||
}
|
||||
)
|
||||
},
|
||||
getElementsByClassName: function (name) {
|
||||
return bareSummonQueryAll(doc.root, '.' + String(name || ''), 500).map(
|
||||
function (n) {
|
||||
return bareSummonWrapNode(n, env)
|
||||
}
|
||||
)
|
||||
},
|
||||
createElement: function (name) {
|
||||
return bareSummonWrapNode(
|
||||
bareSummonCreateNode(
|
||||
'element',
|
||||
String(name || 'div').toLowerCase(),
|
||||
{}
|
||||
),
|
||||
env
|
||||
)
|
||||
},
|
||||
createTextNode: function (text) {
|
||||
return bareSummonWrapNode(
|
||||
{
|
||||
type: 'text',
|
||||
text: String(text == null ? '' : text),
|
||||
parent: null,
|
||||
children: []
|
||||
},
|
||||
env
|
||||
)
|
||||
},
|
||||
createDocumentFragment: function () {
|
||||
return bareSummonWrapNode(
|
||||
bareSummonCreateNode('element', 'fragment', {}),
|
||||
env
|
||||
)
|
||||
}
|
||||
}
|
||||
env.document = api
|
||||
return api
|
||||
}
|
||||
Reference in New Issue
Block a user