1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 ChromeUtils.import("resource://gre/modules/Services.jsm");
7 var EXPORTED_SYMBOLS = ["PageStyleChild"];
9 ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
11 class PageStyleChild extends ActorChild {
13 return content.docShell.contentViewer;
16 sendStyleSheetInfo(mm) {
17 let content = mm.content;
18 let filteredStyleSheets = this._filterStyleSheets(this.getAllStyleSheets(content), content);
20 mm.sendAsyncMessage("PageStyle:StyleSheets", {
22 authorStyleDisabled: this.getViewer(content).authorStyleDisabled,
23 preferredStyleSheetSet: content.document.preferredStyleSheetSet,
27 getAllStyleSheets(frameset) {
28 let selfSheets = Array.slice(frameset.document.styleSheets);
29 let subSheets = Array.map(frameset.frames, frame => this.getAllStyleSheets(frame));
30 return selfSheets.concat(...subSheets);
34 let content = msg.target.content;
36 case "PageStyle:Switch":
37 this.getViewer(content).authorStyleDisabled = false;
38 this._stylesheetSwitchAll(content, msg.data.title);
41 case "PageStyle:Disable":
42 this.getViewer(content).authorStyleDisabled = true;
46 this.sendStyleSheetInfo(msg.target);
50 let win = event.target.ownerGlobal;
55 let mm = win.docShell.messageManager;
56 this.sendStyleSheetInfo(mm);
59 _stylesheetSwitchAll(frameset, title) {
60 if (!title || this._stylesheetInFrame(frameset, title)) {
61 this._stylesheetSwitchFrame(frameset, title);
64 for (let i = 0; i < frameset.frames.length; i++) {
65 // Recurse into sub-frames.
66 this._stylesheetSwitchAll(frameset.frames[i], title);
70 _stylesheetSwitchFrame(frame, title) {
71 var docStyleSheets = frame.document.styleSheets;
73 for (let i = 0; i < docStyleSheets.length; ++i) {
74 let docStyleSheet = docStyleSheets[i];
75 if (docStyleSheet.title) {
76 docStyleSheet.disabled = (docStyleSheet.title != title);
77 } else if (docStyleSheet.disabled) {
78 docStyleSheet.disabled = false;
83 _stylesheetInFrame(frame, title) {
84 return Array.some(frame.document.styleSheets, (styleSheet) => styleSheet.title == title);
87 _filterStyleSheets(styleSheets, content) {
90 for (let currentStyleSheet of styleSheets) {
91 if (!currentStyleSheet.title)
94 // Skip any stylesheets that don't match the screen media type.
95 if (currentStyleSheet.media.length > 0) {
96 let mediaQueryList = currentStyleSheet.media.mediaText;
97 if (!content.matchMedia(mediaQueryList).matches) {
104 if (!currentStyleSheet.ownerNode ||
105 // special-case style nodes, which have no href
106 currentStyleSheet.ownerNode.nodeName.toLowerCase() != "style") {
107 URI = Services.io.newURI(currentStyleSheet.href);
110 if (e.result != Cr.NS_ERROR_MALFORMED_URI) {
116 // We won't send data URIs all of the way up to the parent, as these
117 // can be arbitrarily large.
118 let sentURI = (!URI || URI.scheme == "data") ? null : URI.spec;
121 title: currentStyleSheet.title,
122 disabled: currentStyleSheet.disabled,