Skip to content

Commit 9446e7a

Browse files
committed
Merge pull request #47 from webup/gh-pages
support -moz-document rule
2 parents 39d7ecf + 3a5e02d commit 9446e7a

5 files changed

Lines changed: 218 additions & 6 deletions

File tree

lib/CSSDocumentRule.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//.CommonJS
2+
var CSSOM = {
3+
CSSRule: require("./CSSRule").CSSRule,
4+
MatcherList: require("./MatcherList").MatcherList
5+
};
6+
///CommonJS
7+
8+
9+
/**
10+
* @constructor
11+
* @see https://developer.mozilla.org/en/CSS/@-moz-document
12+
*/
13+
CSSOM.CSSDocumentRule = function CSSDocumentRule() {
14+
CSSOM.CSSRule.call(this);
15+
this.matcher = new CSSOM.MatcherList;
16+
this.cssRules = [];
17+
};
18+
19+
CSSOM.CSSDocumentRule.prototype = new CSSOM.CSSRule;
20+
CSSOM.CSSDocumentRule.prototype.constructor = CSSOM.CSSDocumentRule;
21+
CSSOM.CSSDocumentRule.prototype.type = 10;
22+
//FIXME
23+
//CSSOM.CSSDocumentRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
24+
//CSSOM.CSSDocumentRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
25+
26+
CSSOM.CSSDocumentRule.prototype.__defineGetter__("cssText", function() {
27+
var cssTexts = [];
28+
for (var i=0, length=this.cssRules.length; i < length; i++) {
29+
cssTexts.push(this.cssRules[i].cssText);
30+
}
31+
return "@-moz-document " + this.matcher.matcherText + " {" + cssTexts.join("") + "}";
32+
});
33+
34+
35+
//.CommonJS
36+
exports.CSSDocumentRule = CSSOM.CSSDocumentRule;
37+
///CommonJS

lib/MatcherList.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//.CommonJS
2+
var CSSOM = {};
3+
///CommonJS
4+
5+
6+
/**
7+
* @constructor
8+
* @see https://developer.mozilla.org/en/CSS/@-moz-document
9+
*/
10+
CSSOM.MatcherList = function MatcherList(){
11+
this.length = 0;
12+
};
13+
14+
CSSOM.MatcherList.prototype = {
15+
16+
constructor: CSSOM.MatcherList,
17+
18+
/**
19+
* @return {string}
20+
*/
21+
get matcherText() {
22+
return Array.prototype.join.call(this, ", ");
23+
},
24+
25+
/**
26+
* @param {string} value
27+
*/
28+
set matcherText(value) {
29+
// just a temporary solution, actually it may be wrong by just split the value with ',', because a url can include ','.
30+
var values = value.split(",");
31+
var length = this.length = values.length;
32+
for (var i=0; i<length; i++) {
33+
this[i] = values[i].trim();
34+
}
35+
},
36+
37+
/**
38+
* @param {string} matcher
39+
*/
40+
appendMatcher: function(matcher) {
41+
if (Array.prototype.indexOf.call(this, matcher) === -1) {
42+
this[this.length] = matcher;
43+
this.length++;
44+
}
45+
},
46+
47+
/**
48+
* @param {string} matcher
49+
*/
50+
deleteMatcher: function(matcher) {
51+
var index = Array.prototype.indexOf.call(this, matcher);
52+
if (index !== -1) {
53+
Array.prototype.splice.call(this, index, 1);
54+
}
55+
}
56+
57+
};
58+
59+
60+
//.CommonJS
61+
exports.MatcherList = CSSOM.MatcherList;
62+
///CommonJS

lib/parse.js

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,19 @@ CSSOM.parse = function parse(token) {
3131
"atRule": true,
3232
"importRule-begin": true,
3333
"importRule": true,
34-
"atBlock": true
34+
"atBlock": true,
35+
'documentRule-begin': true
3536
};
3637

3738
var styleSheet = new CSSOM.CSSStyleSheet;
3839

39-
// @type CSSStyleSheet|CSSMediaRule|CSSFontFaceRule|CSSKeyframesRule
40+
// @type CSSStyleSheet|CSSMediaRule|CSSFontFaceRule|CSSKeyframesRule|CSSDocumentRule
4041
var currentScope = styleSheet;
4142

42-
// @type CSSMediaRule|CSSKeyframesRule
43+
// @type CSSMediaRule|CSSKeyframesRule|CSSDocumentRule
4344
var parentRule;
4445

45-
var selector, name, value, priority="", styleRule, mediaRule, importRule, fontFaceRule, keyframesRule, keyframeRule;
46+
var selector, name, value, priority="", styleRule, mediaRule, importRule, fontFaceRule, keyframesRule, keyframeRule, documentRule;
4647

4748
var atKeyframesRegExp = /@(-(?:\w+-)+)?keyframes/g;
4849

@@ -133,7 +134,14 @@ CSSOM.parse = function parse(token) {
133134

134135
// At-rule
135136
case "@":
136-
if (token.indexOf("@media", i) === i) {
137+
if (token.indexOf("@-moz-document", i) === i) {
138+
state = "documentRule-begin";
139+
documentRule = new CSSOM.CSSDocumentRule;
140+
documentRule.__starts = i;
141+
i += "-moz-document".length;
142+
buffer = "";
143+
break;
144+
} else if (token.indexOf("@media", i) === i) {
137145
state = "atBlock";
138146
mediaRule = new CSSOM.CSSMediaRule;
139147
mediaRule.__starts = i;
@@ -205,6 +213,16 @@ CSSOM.parse = function parse(token) {
205213
styleRule.__starts = i;
206214
buffer = "";
207215
state = "before-name";
216+
} else if (state === "documentRule-begin") {
217+
// FIXME: what if this '{' is in the url text of the match function?
218+
documentRule.matcher.matcherText = buffer.trim();
219+
if (parentRule) {
220+
documentRule.parentRule = parentRule;
221+
}
222+
currentScope = parentRule = documentRule;
223+
documentRule.parentStyleSheet = styleSheet;
224+
buffer = "";
225+
state = "before-selector";
208226
}
209227
break;
210228

@@ -302,7 +320,7 @@ CSSOM.parse = function parse(token) {
302320
case "keyframeRule-begin":
303321
case "before-selector":
304322
case "selector":
305-
// End of media rule.
323+
// End of media/document rule.
306324
if (!parentRule) {
307325
parseError("Unexpected }");
308326
}
@@ -355,4 +373,5 @@ CSSOM.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration
355373
CSSOM.CSSKeyframeRule = require('./CSSKeyframeRule').CSSKeyframeRule;
356374
CSSOM.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule;
357375
CSSOM.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression;
376+
CSSOM.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule;
358377
///CommonJS

spec/parse.spec.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,98 @@ var TESTS = [
934934
result.cssRules[0].cssRules[0].style.parentRule = result.cssRules[0].cssRules[0];
935935
result.cssRules[0].cssRules[1].style.parentRule = result.cssRules[0].cssRules[1];
936936
result.cssRules[0].cssRules[2].style.parentRule = result.cssRules[0].cssRules[2];
937+
return result;
938+
})()
939+
},
940+
{
941+
input: "@-moz-document url(http://www.w3.org/), url-prefix(http://www.w3.org/Style/), domain(mozilla.org), regexp(\"https:.*\")\n{\n/*comments*/\nbody { color: purple; background: yellow; }\n}",
942+
result: (function() {
943+
var result = {
944+
cssRules: [
945+
{
946+
matcher: {
947+
0: "url(http://www.w3.org/)",
948+
1: "url-prefix(http://www.w3.org/Style/)",
949+
2: "domain(mozilla.org)",
950+
3: "regexp(\"https:.*\")",
951+
length: 4
952+
},
953+
cssRules: [
954+
{
955+
selectorText: "body",
956+
style: {
957+
0: "color",
958+
1: "background",
959+
length: 2,
960+
__starts: 138,
961+
color: "purple",
962+
background: "yellow"
963+
},
964+
__starts: 133,
965+
__ends: 176
966+
}
967+
],
968+
parentRule: null,
969+
__starts: 0,
970+
__ends: 178
971+
}
972+
],
973+
parentStyleSheet: null
974+
};
975+
result.cssRules[0].parentStyleSheet = result.cssRules[0].cssRules[0].parentStyleSheet = result;
976+
result.cssRules[0].cssRules[0].parentRule = result.cssRules[0];
977+
result.cssRules[0].cssRules[0].style.parentRule = result.cssRules[0].cssRules[0];
978+
979+
return result;
980+
})()
981+
},
982+
{
983+
input: "a{}@-moz-document/**/url-prefix(http://www.w3.org/Style/){body { color: purple; background: yellow; }}",
984+
result: (function(){
985+
var result = {
986+
cssRules: [
987+
{
988+
selectorText: 'a',
989+
style: {
990+
length: 0,
991+
__starts: 1
992+
},
993+
parentRule: null,
994+
__starts: 0,
995+
__ends: 3
996+
},
997+
{
998+
matcher: {
999+
0: "url-prefix(http://www.w3.org/Style/)",
1000+
length: 1
1001+
},
1002+
cssRules: [
1003+
{
1004+
selectorText: "body",
1005+
style: {
1006+
0: "color",
1007+
1: "background",
1008+
length: 2,
1009+
__starts: 64,
1010+
color: "purple",
1011+
background: "yellow"
1012+
},
1013+
__starts: 59,
1014+
__ends: 102
1015+
}
1016+
],
1017+
parentRule: null,
1018+
__starts: 3,
1019+
__ends: 103
1020+
}
1021+
],
1022+
parentStyleSheet: null
1023+
};
1024+
result.cssRules[0].parentStyleSheet = result.cssRules[1].parentStyleSheet = result.cssRules[1].cssRules[0].parentStyleSheet = result;
1025+
result.cssRules[1].cssRules[0].parentRule = result.cssRules[1];
1026+
result.cssRules[1].cssRules[0].style.parentRule = result.cssRules[1].cssRules[0];
1027+
result.cssRules[0].style.parentRule = result.cssRules[0];
1028+
9371029
return result;
9381030
})()
9391031
}

src/files.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ exports.files = [
1010
"CSSStyleSheet",
1111
"CSSKeyframesRule",
1212
"CSSKeyframeRule",
13+
"MatcherList",
14+
"CSSDocumentRule",
1315
"CSSValue",
1416
"CSSValueExpression",
1517
"parse",

0 commit comments

Comments
 (0)