browser/components/sessionstore/src/PageStyle.jsm

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:e74858a09a44
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 file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 "use strict";
6
7 this.EXPORTED_SYMBOLS = ["PageStyle"];
8
9 const Ci = Components.interfaces;
10
11 /**
12 * The external API exported by this module.
13 */
14 this.PageStyle = Object.freeze({
15 collect: function (docShell, frameTree) {
16 return PageStyleInternal.collect(docShell, frameTree);
17 },
18
19 restore: function (docShell, frameList, pageStyle) {
20 PageStyleInternal.restore(docShell, frameList, pageStyle);
21 },
22
23 restoreTree: function (docShell, data) {
24 PageStyleInternal.restoreTree(docShell, data);
25 }
26 });
27
28 // Signifies that author style level is disabled for the page.
29 const NO_STYLE = "_nostyle";
30
31 let PageStyleInternal = {
32 /**
33 * Collects the selected style sheet sets for all reachable frames.
34 */
35 collect: function (docShell, frameTree) {
36 let result = frameTree.map(({document: doc}) => {
37 let style;
38
39 if (doc) {
40 // http://dev.w3.org/csswg/cssom/#persisting-the-selected-css-style-sheet-set
41 style = doc.selectedStyleSheetSet || doc.lastStyleSheetSet;
42 }
43
44 return style ? {pageStyle: style} : null;
45 });
46
47 let markupDocumentViewer =
48 docShell.contentViewer.QueryInterface(Ci.nsIMarkupDocumentViewer);
49
50 if (markupDocumentViewer.authorStyleDisabled) {
51 result = result || {};
52 result.disabled = true;
53 }
54
55 return result && Object.keys(result).length ? result : null;
56 },
57
58 /**
59 * Restore the selected style sheet of all the frames in frameList
60 * to match |pageStyle|.
61 * @param docShell the root docshell of all the frames
62 * @param frameList a list of [frame, data] pairs, where frame is a
63 * DOM window and data is the session restore data associated with
64 * it.
65 * @param pageStyle the title of the style sheet to apply
66 */
67 restore: function (docShell, frameList, pageStyle) {
68 let disabled = pageStyle == NO_STYLE;
69
70 let markupDocumentViewer =
71 docShell.contentViewer.QueryInterface(Ci.nsIMarkupDocumentViewer);
72 markupDocumentViewer.authorStyleDisabled = disabled;
73
74 for (let [frame, data] of frameList) {
75 Array.forEach(frame.document.styleSheets, function(aSS) {
76 aSS.disabled = aSS.title && aSS.title != pageStyle;
77 });
78 }
79 },
80
81 /**
82 * Restores pageStyle data for the current frame hierarchy starting at the
83 * |docShell's| current DOMWindow using the given pageStyle |data|.
84 *
85 * Warning: If the current frame hierarchy doesn't match that of the given
86 * |data| object we will silently discard data for unreachable frames. We may
87 * as well assign page styles to the wrong frames if some were reordered or
88 * removed.
89 *
90 * @param docShell (nsIDocShell)
91 * @param data (object)
92 * {
93 * disabled: true, // when true, author styles will be disabled
94 * pageStyle: "Dusk",
95 * children: [
96 * null,
97 * {pageStyle: "Mozilla", children: [ ... ]}
98 * ]
99 * }
100 */
101 restoreTree: function (docShell, data) {
102 let disabled = data.disabled || false;
103 let markupDocumentViewer =
104 docShell.contentViewer.QueryInterface(Ci.nsIMarkupDocumentViewer);
105 markupDocumentViewer.authorStyleDisabled = disabled;
106
107 function restoreFrame(root, data) {
108 if (data.hasOwnProperty("pageStyle")) {
109 root.document.selectedStyleSheetSet = data.pageStyle;
110 }
111
112 if (!data.hasOwnProperty("children")) {
113 return;
114 }
115
116 let frames = root.frames;
117 data.children.forEach((child, index) => {
118 if (child && index < frames.length) {
119 restoreFrame(frames[index], child);
120 }
121 });
122 }
123
124 let ifreq = docShell.QueryInterface(Ci.nsIInterfaceRequestor);
125 restoreFrame(ifreq.getInterface(Ci.nsIDOMWindow), data);
126 }
127 };

mercurial