forked from RubyLouvre/avalon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path10 HTML.js
117 lines (113 loc) · 4.71 KB
/
10 HTML.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/************************************************************************
* HTML处理(parseHTML, innerHTML, clearHTML) *
************************************************************************/
//parseHTML的辅助变量
var tagHooks = {
area: [1, "<map>"],
param: [1, "<object>"],
col: [2, "<table><tbody></tbody><colgroup>", "</table>"],
legend: [1, "<fieldset>"],
option: [1, "<select multiple='multiple'>"],
thead: [1, "<table>", "</table>"],
//如果这里不写</tbody></table>,在IE6-9会在多出一个奇怪的caption标签
tr: [2, "<table><tbody>", "</tbody></table>"],
//如果这里不写</tr></tbody></table>,在IE6-9会在多出一个奇怪的caption标签
th: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
td: [3, "<table><tbody><tr>"],
g: [1, '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">', '</svg>'],
//IE6-8在用innerHTML生成节点时,不能直接创建no-scope元素与HTML5的新标签
_default: W3C ? [0, ""] : [1, "X<div>"] //div可以不用闭合
}
tagHooks.optgroup = tagHooks.option
tagHooks.tbody = tagHooks.tfoot = tagHooks.colgroup = tagHooks.caption = tagHooks.thead
String("circle,defs,ellipse,image,line,path,polygon,polyline,rect,symbol,text,use").replace(rword, function(tag) {
tagHooks[tag] = tagHooks.g //处理SVG
})
var rtagName = /<([\w:]+)/ //取得其tagName
var rxhtml = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig
var rcreate = W3C ? /[^\d\D]/ : /(<(?:script|link|style|meta|noscript))/ig
var scriptTypes = oneObject(["", "text/javascript", "text/ecmascript", "application/ecmascript", "application/javascript"])
var rnest = /<(?:tb|td|tf|th|tr|col|opt|leg|cap|area)/ //需要处理套嵌关系的标签
var script = DOC.createElement("script")
avalon.parseHTML = function(html) {
if (typeof html !== "string" ) {
return DOC.createDocumentFragment()
}
html = html.replace(rxhtml, "<$1></$2>").trim()
var tag = (rtagName.exec(html) || ["", ""])[1].toLowerCase(),
//取得其标签名
wrap = tagHooks[tag] || tagHooks._default,
fragment = hyperspace.cloneNode(false),
wrapper = cinerator,
firstChild, neo
if (!W3C) { //fix IE
html = html.replace(rcreate, "<br class=msNoScope>$1") //在link style script等标签之前添加一个补丁
}
wrapper.innerHTML = wrap[1] + html + (wrap[2] || "")
var els = wrapper.getElementsByTagName("script")
if (els.length) { //使用innerHTML生成的script节点不会发出请求与执行text属性
for (var i = 0, el; el = els[i++]; ) {
if (scriptTypes[el.type]) {
//以偷龙转凤方式恢复执行脚本功能
neo = script.cloneNode(false) //FF不能省略参数
ap.forEach.call(el.attributes, function(attr) {
if (attr && attr.specified) {
neo[attr.name] = attr.value //复制其属性
neo.setAttribute(attr.name, attr.value)
}
})
neo.text = el.text
el.parentNode.replaceChild(neo, el) //替换节点
}
}
}
//移除我们为了符合套嵌关系而添加的标签
for (i = wrap[0]; i--; wrapper = wrapper.lastChild) {
}
if (!W3C) { //fix IE
els = wrapper.getElementsByTagName("br"), n = els.length
while (el = els[--n]) {
if (el.className === "msNoScope") {
el.parentNode.removeChild(el)
}
}
for (els = wrapper.all, i = 0; el = els[i++]; ) { //fix VML
if (isVML(el)) {
fixVML(el)
}
}
}
while (firstChild = wrapper.firstChild) { // 将wrapper上的节点转移到文档碎片上!
fragment.appendChild(firstChild)
}
return fragment
}
function isVML(src) {
var nodeName = src.nodeName
return nodeName.toLowerCase() === nodeName && src.scopeName && src.outerText === ""
}
function fixVML(node) {
if (node.currentStyle.behavior !== "url(#default#VML)") {
node.style.behavior = "url(#default#VML)"
node.style.display = "inline-block"
node.style.zoom = 1 //hasLayout
}
}
avalon.innerHTML = function(node, html) {
if (!W3C && (!rcreate.test(html) && !rnest.test(html))) {
try {
node.innerHTML = html
return
} catch (e) {
}
}
var a = this.parseHTML(html)
this.clearHTML(node).appendChild(a)
}
avalon.clearHTML = function(node) {
node.textContent = ""
while (node.firstChild) {
node.removeChild(node.firstChild)
}
return node
}