forked from RubyLouvre/avalon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path15 HTML.js
131 lines (129 loc) · 5.25 KB
/
15 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/************************************************************************
* HTML处理(parseHTML, innerHTML, clearHTML) *
************************************************************************/
// We have to close these tags to support XHTML
var tagHooks = {
area: [1, "<map>", "</map>"],
param: [1, "<object>", "</object>"],
col: [2, "<table><colgroup>", "</colgroup></table>"],
legend: [1, "<fieldset>", "</fieldset>"],
option: [1, "<select multiple='multiple'>", "</select>"],
thead: [1, "<table>", "</table>"],
tr: [2, "<table>", "</table>"],
td: [3, "<table><tr>", "</tr></table>"],
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>"] //div可以不用闭合
}
tagHooks.th = tagHooks.td
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")
var rhtml = /<|&#?\w+;/
avalon.parseHTML = function (html) {
var fragment = avalonFragment.cloneNode(false)
if (typeof html !== "string") {
return fragment
}
if (!rhtml.test(html)) {
fragment.appendChild(DOC.createTextNode(html))
return fragment
}
html = html.replace(rxhtml, "<$1></$2>").trim()
var tag = (rtagName.exec(html) || ["", ""])[1].toLowerCase(),
//取得其标签名
wrap = tagHooks[tag] || tagHooks._default,
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)
}
}) // jshint ignore:line
neo.text = el.text
el.parentNode.replaceChild(neo, el) //替换节点
}
}
}
if (!W3C) { //fix IE
var target = wrap[1] === "X<div>" ? wrapper.lastChild.firstChild : wrapper.lastChild
if (target && target.tagName === "TABLE" && tag !== "tbody") {
//IE6-7处理 <thead> --> <thead>,<tbody>
//<tfoot> --> <tfoot>,<tbody>
//<table> --> <table><tbody></table>
for (els = target.childNodes, i = 0; el = els[i++]; ) {
if (el.tagName === "TBODY" && !el.innerHTML) {
target.removeChild(el)
break
}
}
}
els = wrapper.getElementsByTagName("br")
var 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)
}
}
}
//移除我们为了符合套嵌关系而添加的标签
for (i = wrap[0]; i--; wrapper = wrapper.lastChild) {
}
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
}