123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- // Copyright 2008 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- goog.provide('goog.cssomTest');
- goog.setTestOnly('goog.cssomTest');
- goog.require('goog.array');
- goog.require('goog.cssom');
- goog.require('goog.cssom.CssRuleType');
- goog.require('goog.testing.jsunit');
- goog.require('goog.userAgent');
- // Since sheet cssom_test1.css's first line is to import
- // cssom_test2.css, we should get 2 before one in the string.
- var cssText = '.css-link-1 { display: block; } ' +
- '.css-import-2 { display: block; } ' +
- '.css-import-1 { display: block; } ' +
- '.css-style-1 { display: block; } ' +
- '.css-style-2 { display: block; } ' +
- '.css-style-3 { display: block; }';
- var replacementCssText = '.css-repl-1 { display: block; }';
- var isIe7 = goog.userAgent.IE &&
- (goog.userAgent.compare(goog.userAgent.VERSION, '7.0') == 0);
- // We're going to toLowerCase cssText before testing, because IE returns
- // CSS property names in UPPERCASE, and the function shouldn't
- // "fix" the text as it would be expensive and rarely of use.
- // Same goes for the trailing whitespace in IE.
- // Same goes for fixing the optimized removal of trailing ; in rules.
- // Also needed for Opera.
- function fixCssTextForIe(cssText) {
- cssText = cssText.toLowerCase().replace(/\s*$/, '');
- if (cssText.match(/[^;] \}/)) {
- cssText = cssText.replace(/([^;]) \}/g, '$1; }');
- }
- return cssText;
- }
- function testGetFileNameFromStyleSheet() {
- var styleSheet = {'href': 'http://foo.com/something/filename.css'};
- assertEquals(
- 'filename.css', goog.cssom.getFileNameFromStyleSheet(styleSheet));
- styleSheet = {'href': 'https://foo.com:123/something/filename.css'};
- assertEquals(
- 'filename.css', goog.cssom.getFileNameFromStyleSheet(styleSheet));
- styleSheet = {'href': 'http://foo.com/something/filename.css?bar=bas'};
- assertEquals(
- 'filename.css', goog.cssom.getFileNameFromStyleSheet(styleSheet));
- styleSheet = {'href': 'filename.css?bar=bas'};
- assertEquals(
- 'filename.css', goog.cssom.getFileNameFromStyleSheet(styleSheet));
- styleSheet = {'href': 'filename.css'};
- assertEquals(
- 'filename.css', goog.cssom.getFileNameFromStyleSheet(styleSheet));
- }
- function testGetAllCssStyleSheets() {
- var styleSheets = goog.cssom.getAllCssStyleSheets();
- assertEquals(4, styleSheets.length);
- // Makes sure they're in the right cascade order.
- assertEquals(
- 'cssom_test_link_1.css',
- goog.cssom.getFileNameFromStyleSheet(styleSheets[0]));
- assertEquals(
- 'cssom_test_import_2.css',
- goog.cssom.getFileNameFromStyleSheet(styleSheets[1]));
- assertEquals(
- 'cssom_test_import_1.css',
- goog.cssom.getFileNameFromStyleSheet(styleSheets[2]));
- // Not an external styleSheet
- assertNull(goog.cssom.getFileNameFromStyleSheet(styleSheets[3]));
- }
- function testGetAllCssText() {
- var allCssText = goog.cssom.getAllCssText();
- // In IE7, a CSSRule object gets included twice and replaces another
- // existing CSSRule object. We aren't using
- // goog.testing.ExpectedFailures since it brings in additional CSS
- // which breaks a lot of our expectations about the number of rules
- // present in a style sheet.
- if (!isIe7) {
- assertEquals(cssText, fixCssTextForIe(allCssText));
- }
- }
- function testGetAllCssStyleRules() {
- var allCssRules = goog.cssom.getAllCssStyleRules();
- assertEquals(6, allCssRules.length);
- }
- function testAddCssText() {
- var newCssText = '.css-add-1 { display: block; }';
- var newCssNode = goog.cssom.addCssText(newCssText);
- assertEquals(document.styleSheets.length, 3);
- var allCssText = goog.cssom.getAllCssText();
- // In IE7, a CSSRule object gets included twice and replaces another
- // existing CSSRule object. We aren't using
- // goog.testing.ExpectedFailures since it brings in additional CSS
- // which breaks a lot of our expectations about the number of rules
- // present in a style sheet.
- if (!isIe7) {
- // Opera inserts the CSSRule to the first position. And fixCssText
- // is also needed to clean up whitespace.
- if (goog.userAgent.OPERA) {
- assertEquals(newCssText + ' ' + cssText, fixCssTextForIe(allCssText));
- } else {
- assertEquals(cssText + ' ' + newCssText, fixCssTextForIe(allCssText));
- }
- }
- var cssRules = goog.cssom.getAllCssStyleRules();
- assertEquals(7, cssRules.length);
- // Remove the new stylesheet now so it doesn't interfere with other
- // tests.
- newCssNode.parentNode.removeChild(newCssNode);
- // Sanity check.
- cssRules = goog.cssom.getAllCssStyleRules();
- assertEquals(6, cssRules.length);
- }
- function testAddCssRule() {
- // test that addCssRule correctly adds the rule to the style
- // sheet.
- var styleSheets = goog.cssom.getAllCssStyleSheets();
- var styleSheet = styleSheets[3];
- var newCssRule = '.css-addCssRule { display: block; }';
- var rules = styleSheet.rules || styleSheet.cssRules;
- var origNumberOfRules = rules.length;
- goog.cssom.addCssRule(styleSheet, newCssRule, 1);
- rules = styleSheet.rules || styleSheet.cssRules;
- var newNumberOfRules = rules.length;
- assertEquals(newNumberOfRules, origNumberOfRules + 1);
- // Remove the added rule so we don't mess up other tests.
- goog.cssom.removeCssRule(styleSheet, 1);
- }
- function testAddCssRuleAtPos() {
- // test that addCssRule correctly adds the rule to the style
- // sheet at the specified position.
- var styleSheets = goog.cssom.getAllCssStyleSheets();
- var styleSheet = styleSheets[3];
- var newCssRule = '.css-addCssRulePos { display: block; }';
- var rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- var origNumberOfRules = rules.length;
- // Firefox croaks if we try to insert a CSSRule at an index that
- // contains a CSSImport Rule. Since we deal only with CSSStyleRule
- // objects, we find the first CSSStyleRule and return its index.
- //
- // NOTE(user): We could have unified the code block below for all
- // browsers but IE6 horribly mangled up the stylesheet by creating
- // duplicate instances of a rule when removeCssRule was invoked
- // just after addCssRule with the looping construct in. This is
- // perfectly fine since IE's styleSheet.rules does not contain
- // references to anything but CSSStyleRules.
- var pos = 0;
- if (styleSheet.cssRules) {
- pos = goog.array.findIndex(rules, function(rule) {
- return rule.type == goog.cssom.CssRuleType.STYLE;
- });
- }
- goog.cssom.addCssRule(styleSheet, newCssRule, pos);
- rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- var newNumberOfRules = rules.length;
- assertEquals(newNumberOfRules, origNumberOfRules + 1);
- // Remove the added rule so we don't mess up other tests.
- goog.cssom.removeCssRule(styleSheet, pos);
- rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- assertEquals(origNumberOfRules, rules.length);
- }
- function testAddCssRuleNoIndex() {
- // How well do we handle cases where the optional index is
- // not passed in?
- var styleSheets = goog.cssom.getAllCssStyleSheets();
- var styleSheet = styleSheets[3];
- var rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- var origNumberOfRules = rules.length;
- var newCssRule = '.css-addCssRuleNoIndex { display: block; }';
- // Try inserting the rule without specifying an index.
- // Make sure we don't throw an exception, and that we added
- // the entry.
- goog.cssom.addCssRule(styleSheet, newCssRule);
- rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- var newNumberOfRules = rules.length;
- assertEquals(newNumberOfRules, origNumberOfRules + 1);
- // Remove the added rule so we don't mess up the other tests.
- goog.cssom.removeCssRule(styleSheet, newNumberOfRules - 1);
- rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- assertEquals(origNumberOfRules, rules.length);
- }
- function testGetParentStyleSheetAfterGetAllCssStyleRules() {
- var cssRules = goog.cssom.getAllCssStyleRules();
- var cssRule = cssRules[4];
- var parentStyleSheet = goog.cssom.getParentStyleSheet(cssRule);
- var styleSheets = goog.cssom.getAllCssStyleSheets();
- var styleSheet = styleSheets[3];
- assertEquals(styleSheet, parentStyleSheet);
- }
- function testGetCssRuleIndexInParentStyleSheetAfterGetAllCssStyleRules() {
- var cssRules = goog.cssom.getAllCssStyleRules();
- var cssRule = cssRules[4];
- // Note here that this is correct - IE's styleSheet.rules does not
- // contain references to anything but CSSStyleRules while FF and others
- // include anything that inherits from the CSSRule interface.
- // See http://dev.w3.org/csswg/cssom/#cssrule.
- var parentStyleSheet = goog.cssom.getParentStyleSheet(cssRule);
- var ruleIndex = goog.isDefAndNotNull(parentStyleSheet.cssRules) ? 2 : 1;
- assertEquals(
- ruleIndex, goog.cssom.getCssRuleIndexInParentStyleSheet(cssRule));
- }
- function testGetCssRuleIndexInParentStyleSheetNonStyleRule() {
- // IE's styleSheet.rules only contain CSSStyleRules.
- if (!goog.userAgent.IE) {
- var styleSheets = goog.cssom.getAllCssStyleSheets();
- var styleSheet = styleSheets[3];
- var newCssRule = '@media print { .css-nonStyle { display: block; } }';
- goog.cssom.addCssRule(styleSheet, newCssRule);
- var rules = styleSheet.rules || styleSheet.cssRules;
- var cssRule = rules[rules.length - 1];
- assertEquals(goog.cssom.CssRuleType.MEDIA, cssRule.type);
- // Make sure we don't throw an exception.
- goog.cssom.getCssRuleIndexInParentStyleSheet(cssRule, styleSheet);
- // Remove the added rule.
- goog.cssom.removeCssRule(styleSheet, rules.length - 1);
- }
- }
- // Tests the scenario where we have a known stylesheet and index.
- function testReplaceCssRuleWithStyleSheetAndIndex() {
- var styleSheets = goog.cssom.getAllCssStyleSheets();
- var styleSheet = styleSheets[3];
- var rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- var index = 2;
- var origCssRule = rules[index];
- var origCssText =
- fixCssTextForIe(goog.cssom.getCssTextFromCssRule(origCssRule));
- goog.cssom.replaceCssRule(origCssRule, replacementCssText, styleSheet, index);
- var rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- var newCssRule = rules[index];
- var newCssText = goog.cssom.getCssTextFromCssRule(newCssRule);
- assertEquals(replacementCssText, fixCssTextForIe(newCssText));
- // Now we need to re-replace our rule, to preserve parity for the other
- // tests.
- goog.cssom.replaceCssRule(newCssRule, origCssText, styleSheet, index);
- var rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- var nowCssRule = rules[index];
- var nowCssText = goog.cssom.getCssTextFromCssRule(nowCssRule);
- assertEquals(origCssText, fixCssTextForIe(nowCssText));
- }
- function testReplaceCssRuleUsingGetAllCssStyleRules() {
- var cssRules = goog.cssom.getAllCssStyleRules();
- var origCssRule = cssRules[4];
- var origCssText =
- fixCssTextForIe(goog.cssom.getCssTextFromCssRule(origCssRule));
- // notice we don't pass in the stylesheet or index.
- goog.cssom.replaceCssRule(origCssRule, replacementCssText);
- var styleSheets = goog.cssom.getAllCssStyleSheets();
- var styleSheet = styleSheets[3];
- var rules = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
- var index = goog.isDefAndNotNull(styleSheet.cssRules) ? 2 : 1;
- var newCssRule = rules[index];
- var newCssText =
- fixCssTextForIe(goog.cssom.getCssTextFromCssRule(newCssRule));
- assertEquals(replacementCssText, newCssText);
- // try getting it the other way around too.
- var cssRules = goog.cssom.getAllCssStyleRules();
- var newCssRule = cssRules[4];
- var newCssText =
- fixCssTextForIe(goog.cssom.getCssTextFromCssRule(newCssRule));
- assertEquals(replacementCssText, newCssText);
- // Now we need to re-replace our rule, to preserve parity for the other
- // tests.
- goog.cssom.replaceCssRule(newCssRule, origCssText);
- var cssRules = goog.cssom.getAllCssStyleRules();
- var nowCssRule = cssRules[4];
- var nowCssText =
- fixCssTextForIe(goog.cssom.getCssTextFromCssRule(nowCssRule));
- assertEquals(origCssText, nowCssText);
- }
|