1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is BlueGriffon.
16 * The Initial Developer of the Original Code is
17 * Disruptive Innovations SARL.
18 * Portions created by the Initial Developer are Copyright (C) 2006
19 * the Initial Developer. All Rights Reserved.
22 * Daniel Glazman <daniel.glazman@disruptive-innovations.com>, Original author
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 getStyleSheets: function CssUtils_getStyleSheets(aDoc)
41 return aDoc.styleSheets;
44 _enumerateStyleSheet: function CssUtils__enumerateStyleSheet(aSheet, aCallback)
46 if (aCallback(aSheet))
48 var rules = aSheet.cssRules;
49 for (var j = 0; j < rules.length; j++)
51 var rule = rules.item(j);
54 case CSSRule.IMPORT_RULE:
55 this._enumerateStyleSheet(rule.styleSheet, aCallback);
57 case CSSRule.MEDIA_RULE:
58 this._enumerateStyleSheet(rule, aCallback);
67 enumerateStyleSheets: function CssUtils_enumerateStyleSheets(aDocument, aCallback)
69 var stylesheetsList = aDocument.styleSheets;
70 for (var i = 0; i < stylesheetsList.length; i++)
72 var sheet = stylesheetsList.item(i);
73 this._enumerateStyleSheet(sheet, aCallback);
77 getComputedStyle: function CssUtils_getComputedStyle(aElt)
79 return aElt.ownerDocument.defaultView.getComputedStyle(aElt, "");
82 findClassesInSelector: function CssUtils_findClassesInSelector(aSelector)
84 return aSelector.match( /\.-?([_a-z]|[\200-\377]|((\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?)|\\[^\r\n\f0-9a-f]))([_a-z0-9-]|[\200-\377]|((\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?)|\\[^\r\n\f0-9a-f]))*/gi );
87 findIdsInSelector: function CssUtils_findClassesInSelector(aSelector)
89 return aSelector.match( /#-?([_a-z]|[\200-\377]|((\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?)|\\[^\r\n\f0-9a-f]))([_a-z0-9-]|[\200-\377]|((\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?)|\\[^\r\n\f0-9a-f]))*/gi );
92 getCssHintsFromDocument: function CssUtils_getAllClassesFromDocument(aDocument, aDetector)
96 function enumerateClass(aSheet)
98 var cssRules = aSheet.cssRules;
99 for (var i = 0; i < cssRules.length; i++)
101 var rule = cssRules.item(i);
102 if (rule.type == CSSRule.STYLE_RULE)
104 var selectorText = rule.selectorText;
105 var matches = aDetector(selectorText);
107 for (var j = 0; j < matches.length; j++)
108 classList.push(matches[j].substr(1));
114 CssUtils.enumerateStyleSheets(aDocument, enumerateClass);
119 getAllClassesForDocument: function CssUtils_getAllClassesForDocument(aDocument)
121 return this.getCssHintsFromDocument(aDocument, this.findClassesInSelector);
124 getAllIdsForDocument: function CssUtils_getAllClassesForDocument(aDocument)
126 return this.getCssHintsFromDocument(aDocument, this.findIdsInSelector);
129 getAllLocalRulesForSelector: function CssUtils_getAllLocalRulesForSelector(aDocument, aSelector)
133 function enumerateRules(aSheet)
135 if (aSheet.ownerNode instanceof HTMLStyleElement)
137 var cssRules = aSheet.cssRules;
138 for (var i = 0; i < cssRules.length; i++)
140 var rule = cssRules.item(i);
141 if (rule.type == CSSRule.STYLE_RULE)
143 var selectorText = rule.selectorText;
144 if (selectorText == aSelector)
145 ruleList.push({rule:rule, index:i});
153 CssUtils.enumerateStyleSheets(aDocument, enumerateRules);
158 deleteAllLocalRulesForSelector: function CssUtils_deleteAllLocalRulesForSelector(aDocument, aSelector, aDeclarations)
160 var ruleList = this.getAllLocalRulesForSelector(aDocument, aSelector);
161 var l = ruleList.length;
162 for (var i = 0; i < l; i++)
164 var rule = ruleList[i].rule;
165 var parentRule = rule.parentRule;
166 var parentStyleSheet = rule.parentStyleSheet;
167 if (rule.type == CSSRule.STYLE_RULE && !parentRule)
171 for (var j = 0; j < aDeclarations.length; j++)
172 rule.style.removeProperty(aDeclarations[j].property);
173 if (!rule.style.length)
174 parentStyleSheet.deleteRule(ruleList[i].index);
177 parentStyleSheet.deleteRule(ruleList[i].index);
179 this.reserializeEmbeddedStylesheet(parentStyleSheet);
183 getStyleSheetForScreen: function CssUtils_getStyleSheetForScreen(aDocument)
185 var styleElements = aDocument.getElementsByTagName("style");
186 var stylesheet = null;
187 if (styleElements.length)
189 // try to find a stylesheet for the correct media
190 for (var i = 0; !stylesheet && i < styleElements.length; i++)
192 var styleElement = styleElements[i];
193 if (styleElement.hasAttribute("media"))
195 var mediaAttr = styleElement.getAttribute("media");
196 if (mediaAttr.indexOf("screen") != -1||
197 mediaAttr.indexOf("all") != -1)
198 stylesheet = styleElement.sheet;
201 stylesheet = styleElement.sheet;
206 var styleElement = aDocument.createElement("style");
207 styleElement.setAttribute("type", "text/css");
208 var textNode = aDocument.createTextNode("/* created by BlueGriffon */");
209 styleElement.appendChild(textNode);
210 aDocument.getElementsByTagName("head")[0].appendChild(styleElement);
211 stylesheet = styleElement.sheet;
216 addRuleForSelector: function CssUtils_addRuleForSelector(aDocument, aSelector, aDeclarations)
218 this.deleteAllLocalRulesForSelector(aDocument, aSelector, aDeclarations);
219 var ruleList = this.getAllLocalRulesForSelector(aDocument, aSelector);
221 if (!ruleList || !ruleList.length)
223 var stylesheet = this.getStyleSheetForScreen(aDocument);
224 var str = stylesheet.ownerNode.textContent;
225 str += "\n" + aSelector + " {";
226 for (var j = 0; j < aDeclarations.length; j++)
228 var property = aDeclarations[j].property;
229 var value = aDeclarations[j].value;
230 var priority = aDeclarations[j].priority;
231 str += "\n " + property + ": " +
233 (priority ? " !important;" : ";");
236 stylesheet.ownerNode.firstChild.data = str;
240 var rule = ruleList[ruleList.length -1].rule;
241 for (var j = 0; j < aDeclarations.length; j++)
243 var property = aDeclarations[j].property;
244 var value = aDeclarations[j].value;
245 var priority = aDeclarations[j].priority ? " !important" : "";
247 rule.style.setProperty(property,
252 this.reserializeEmbeddedStylesheet(rule.parentStyleSheet);
255 reserializeEmbeddedStylesheet: function CssUtils_reserializeEmbeddedStylesheet(aSheet)
257 var cssRules = aSheet.cssRules;
259 for (var i = 0; i < cssRules.length; i++)
261 var rule = cssRules[i];
264 case CSSRule.CHARSET_RULE:
265 case CSSRule.IMPORT_RULE:
266 str += (i ? "\n" : "") + rule.cssText;
268 case CSSRule.STYLE_RULE:
270 str += (i ? "\n" : "") + rule.selectorText + " {\n " +
271 rule.style.cssText.replace( /;/g , ";\n");
272 /*var declarations = rule.style;
273 for (var j = 0; j < declarations.length; j++)
275 var property = declarations.item(j);
276 var value = declarations.getPropertyValue(property);
277 var priority = declarations.getPropertyPriority(property);
278 str += "\n " + property + ": " +
280 (priority ? ";" : " !important;");
289 var styleElt = aSheet.ownerNode;
290 var child = styleElt.firstChild;
293 var tmp = child.nextSibling;
294 styleElt.removeChild(child);
297 var textNode = styleElt.ownerDocument.createTextNode(str);
298 styleElt.appendChild(textNode);
301 getUseCSSPref: function()
304 var useCSS = GetPrefs().getIntPref("bluegriffon.css.policy");
307 catch(e) { dump("Cannot get preference bluegriffon.css.policy; defaulting to HTML attributes") }