Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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/. */
4 "use strict";
6 module.metadata = {
7 "stability": "experimental",
8 "engines": {
9 "Firefox": "> 28"
10 }
11 };
13 const { Cu, Ci } = require("chrome");
14 const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
15 const { subscribe, send, Reactor, foldp, lift, merges, keepIf } = require("../../event/utils");
16 const { InputPort } = require("../../input/system");
17 const { OutputPort } = require("../../output/system");
18 const { LastClosed } = require("../../input/browser");
19 const { pairs, keys, object, each } = require("../../util/sequence");
20 const { curry, compose } = require("../../lang/functional");
21 const { getFrameElement, getOuterId,
22 getByOuterId, getOwnerBrowserWindow } = require("../../window/utils");
23 const { patch, diff } = require("diffpatcher/index");
24 const { encode } = require("../../base64");
25 const { Frames } = require("../../input/frame");
27 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
28 const HTML_NS = "http://www.w3.org/1999/xhtml";
29 const OUTER_FRAME_URI = module.uri.replace(/\.js$/, ".html");
31 const mailbox = new OutputPort({ id: "frame-mailbox" });
33 const frameID = frame => frame.id.replace("outer-", "");
34 const windowID = compose(getOuterId, getOwnerBrowserWindow);
36 const getOuterFrame = (windowID, frameID) =>
37 getByOuterId(windowID).document.getElementById("outer-" + frameID);
39 const listener = ({target, source, data, origin, timeStamp}) => {
40 // And sent received message to outbox so that frame API model
41 // will deal with it.
42 if (source && source !== target) {
43 const frame = getFrameElement(target);
44 const id = frameID(frame);
45 send(mailbox, object([id, {
46 outbox: {type: "message",
47 source: {id: id, ownerID: windowID(frame)},
48 data: data,
49 origin: origin,
50 timeStamp: timeStamp}}]));
51 }
52 };
54 // Utility function used to create frame with a given `state` and
55 // inject it into given `window`.
56 const registerFrame = ({id, url}) => {
57 CustomizableUI.createWidget({
58 id: id,
59 type: "custom",
60 removable: true,
61 onBuild: document => {
62 let view = document.createElementNS(XUL_NS, "toolbaritem");
63 view.setAttribute("id", id);
64 view.setAttribute("flex", 2);
66 let innerFrame = document.createElementNS(HTML_NS, "iframe");
67 innerFrame.setAttribute("id", id);
68 innerFrame.setAttribute("src", url);
69 innerFrame.setAttribute("seamless", "seamless");
70 innerFrame.setAttribute("sandbox", "allow-scripts");
71 innerFrame.setAttribute("scrolling", "no");
72 innerFrame.setAttribute("data-is-sdk-inner-frame", true);
73 innerFrame.setAttribute("style", [ "border:none",
74 "position:absolute", "width:100%", "top: 0",
75 "left: 0", "overflow: hidden"].join(";"));
77 let outerFrame = document.createElementNS(XUL_NS, "iframe");
78 outerFrame.setAttribute("src", OUTER_FRAME_URI + "#" +
79 encode(innerFrame.outerHTML));
80 outerFrame.setAttribute("id", "outer-" + id);
81 outerFrame.setAttribute("data-is-sdk-outer-frame", true);
82 outerFrame.setAttribute("type", "content");
83 outerFrame.setAttribute("transparent", true);
84 outerFrame.setAttribute("flex", 2);
85 outerFrame.setAttribute("style", "overflow: hidden;");
86 outerFrame.setAttribute("scrolling", "no");
87 outerFrame.setAttribute("disablehistory", true);
88 outerFrame.setAttribute("seamless", "seamless");
90 view.appendChild(outerFrame);
92 return view;
93 }
94 });
95 };
97 const unregisterFrame = CustomizableUI.destroyWidget;
99 const deliverMessage = curry((frameID, data, windowID) => {
100 const frame = getOuterFrame(windowID, frameID);
101 const content = frame && frame.contentWindow;
103 if (content)
104 content.postMessage(data, content.location.origin);
105 });
107 const updateFrame = (id, {inbox, owners}, present) => {
108 if (inbox) {
109 const { data, target:{ownerID}, source } = present[id].inbox;
110 if (ownerID)
111 deliverMessage(id, data, ownerID);
112 else
113 each(deliverMessage(id, data), keys(present[id].owners));
114 }
116 each(setupView(id), pairs(owners));
117 };
119 const setupView = curry((frameID, [windowID, state]) => {
120 if (state && state.readyState === "loading") {
121 const frame = getOuterFrame(windowID, frameID);
122 // Setup a message listener on contentWindow.
123 frame.contentWindow.addEventListener("message", listener);
124 }
125 });
128 const reactor = new Reactor({
129 onStep: (present, past) => {
130 const delta = diff(past, present);
132 // Apply frame changes
133 each(([id, update]) => {
134 if (update === null)
135 unregisterFrame(id);
136 else if (past[id])
137 updateFrame(id, update, present);
138 else
139 registerFrame(update);
140 }, pairs(delta));
141 },
142 onEnd: state => each(unregisterFrame, keys(state))
143 });
144 reactor.run(Frames);