Fix the domMock cssText implementation
This commit is contained in:
parent
f0082473f9
commit
bffe87e053
2 changed files with 99 additions and 20 deletions
|
|
@ -75,11 +75,69 @@ module.exports = function() {
|
||||||
function removeAttribute(name) {
|
function removeAttribute(name) {
|
||||||
delete this.attributes[name]
|
delete this.attributes[name]
|
||||||
}
|
}
|
||||||
|
var declListTokenizer = /;|"(?:\\.|[^"\n])*"|'(?:\\.|[^'\n])*'/g
|
||||||
|
/**
|
||||||
|
* This will split a semicolon-separated CSS declaration list into an array of
|
||||||
|
* individual declarations, ignoring semicolons in strings.
|
||||||
|
*
|
||||||
|
* Comments are also stripped.
|
||||||
|
*
|
||||||
|
* @param {string} declList
|
||||||
|
* @return {string[]}
|
||||||
|
*/
|
||||||
|
function splitDeclList(declList) {
|
||||||
|
var indices = [], res = [], inParen = 0, match
|
||||||
|
|
||||||
|
// remove comments, preserving comments in strings.
|
||||||
|
declList = declList.replace(
|
||||||
|
/("(?:\\.|[^"\n])*"|'(?:\\.|[^'\n])*')|\/\*[\s\S]*?\*\//g,
|
||||||
|
function(m, str){
|
||||||
|
return str || ''
|
||||||
|
}
|
||||||
|
)
|
||||||
|
/*eslint-disable no-cond-assign*/
|
||||||
|
while (match = declListTokenizer.exec(declList)) {
|
||||||
|
if (match[0] === ";") indices.push(match.index)
|
||||||
|
}
|
||||||
|
/*eslint-enable no-cond-assign*/
|
||||||
|
for (var i = indices.length; i--;){
|
||||||
|
res.unshift(declList.slice(indices[i] + 1))
|
||||||
|
declList = declList.slice(0, indices[i])
|
||||||
|
}
|
||||||
|
res.unshift(declList)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
var activeElement
|
var activeElement
|
||||||
var $window = {
|
var $window = {
|
||||||
document: {
|
document: {
|
||||||
createElement: function(tag, is) {
|
createElement: function(tag, is) {
|
||||||
|
var cssText = ""
|
||||||
var style = {}
|
var style = {}
|
||||||
|
Object.defineProperty(style, "cssText", {
|
||||||
|
get: function() {return cssText},
|
||||||
|
set: function (value) {
|
||||||
|
var buf = []
|
||||||
|
if (typeof value === "string") {
|
||||||
|
for (var key in style) style[key] = ""
|
||||||
|
var rules = splitDeclList(value)
|
||||||
|
for (var i = 0; i < rules.length; i++) {
|
||||||
|
var rule = rules[i]
|
||||||
|
var colonIndex = rule.indexOf(":")
|
||||||
|
if (colonIndex > -1) {
|
||||||
|
var rawKey = rule.slice(0, colonIndex).trim()
|
||||||
|
var key = rawKey.replace(/-\D/g, function(match) {return match[1].toUpperCase()})
|
||||||
|
var value = rule.slice(colonIndex + 1).trim()
|
||||||
|
if (key !== "cssText") {
|
||||||
|
style[key] = value
|
||||||
|
buf.push(rawKey + ": " + value + ";")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cssText = buf.join(" ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
var events = {}
|
var events = {}
|
||||||
var element = {
|
var element = {
|
||||||
nodeType: 1,
|
nodeType: 1,
|
||||||
|
|
@ -140,21 +198,6 @@ module.exports = function() {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style#Setting_style
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style#Setting_style
|
||||||
throw new Error("setting element.style is not portable")
|
throw new Error("setting element.style is not portable")
|
||||||
},
|
},
|
||||||
set cssText(value) {
|
|
||||||
if (typeof value === "string") {
|
|
||||||
for (var key in style) style[key] = ""
|
|
||||||
var rules = value.split(";")
|
|
||||||
for (var i = 0; i < rules.length; i++) {
|
|
||||||
var rule = rules[i]
|
|
||||||
var colonIndex = rule.indexOf(":")
|
|
||||||
if (colonIndex > -1) {
|
|
||||||
var key = rule.slice(0, colonIndex).trim().replace(/-\D/g, function(match) {return match[1].toUpperCase()})
|
|
||||||
var value = rule.slice(colonIndex + 1).trim()
|
|
||||||
style[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
get className() {
|
get className() {
|
||||||
return this.attributes["class"] ? this.attributes["class"].nodeValue : ""
|
return this.attributes["class"] ? this.attributes["class"].nodeValue : ""
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -474,20 +474,56 @@ o.spec("domMock", function() {
|
||||||
|
|
||||||
o(typeof div.style).equals("object")
|
o(typeof div.style).equals("object")
|
||||||
})
|
})
|
||||||
o("setting cssText string works", function() {
|
o("setting style.cssText string works", function() {
|
||||||
var div = $document.createElement("div")
|
var div = $document.createElement("div")
|
||||||
div.cssText = "background-color: red; border-bottom: 1px solid red;"
|
div.style.cssText = "background-color: red; border-bottom: 1px solid red;"
|
||||||
|
|
||||||
o(div.style.backgroundColor).equals("red")
|
o(div.style.backgroundColor).equals("red")
|
||||||
o(div.style.borderBottom).equals("1px solid red")
|
o(div.style.borderBottom).equals("1px solid red")
|
||||||
})
|
})
|
||||||
o("removing via setting cssText string works", function() {
|
o("removing via setting style.cssText string works", function() {
|
||||||
var div = $document.createElement("div")
|
var div = $document.createElement("div")
|
||||||
div.cssText = "background: red;"
|
div.style.cssText = "background: red;"
|
||||||
div.cssText = ""
|
div.style.cssText = ""
|
||||||
|
|
||||||
o(div.style.background).equals("")
|
o(div.style.background).equals("")
|
||||||
})
|
})
|
||||||
|
o("the final semicolon is optional when setting style.cssText", function() {
|
||||||
|
var div = $document.createElement("div")
|
||||||
|
div.style.cssText = "background: red"
|
||||||
|
|
||||||
|
o(div.style.background).equals("red")
|
||||||
|
o(div.style.cssText).equals("background: red;")
|
||||||
|
})
|
||||||
|
o("'cssText' as a property name is ignored when setting style.cssText", function(){
|
||||||
|
var div = $document.createElement("div")
|
||||||
|
div.style.cssText = "cssText: red;"
|
||||||
|
|
||||||
|
o(div.style.cssText).equals("")
|
||||||
|
})
|
||||||
|
o("setting style.cssText that has a semi-colon in a strings", function(){
|
||||||
|
var div = $document.createElement("div")
|
||||||
|
div.style.cssText = "background: url(';'); font-family: \";\""
|
||||||
|
|
||||||
|
o(div.style.background).equals("url(';')")
|
||||||
|
o(div.style.fontFamily).equals("\";\"")
|
||||||
|
o(div.style.cssText).equals("background: url(';'); font-family: \";\";")
|
||||||
|
})
|
||||||
|
o("comments in style.cssText are stripped", function(){
|
||||||
|
var div = $document.createElement("div")
|
||||||
|
div.style.cssText = "/**/background/*:*/: /*>;)*/red/**/;/**/"
|
||||||
|
|
||||||
|
o(div.style.background).equals("red")
|
||||||
|
o(div.style.cssText).equals("background: red;")
|
||||||
|
|
||||||
|
})
|
||||||
|
o("comments in strings in style.cssText are preserved", function(){
|
||||||
|
var div = $document.createElement("div")
|
||||||
|
div.style.cssText = "background: url('/*foo*/')"
|
||||||
|
|
||||||
|
o(div.style.background).equals("url('/*foo*/')")
|
||||||
|
|
||||||
|
})
|
||||||
o("setting style throws", function () {
|
o("setting style throws", function () {
|
||||||
var err = false
|
var err = false
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue