Merge m-c to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-10-02 13:37:27 +02:00
commit e91d5a31b6
169 changed files with 2448 additions and 1114 deletions

View File

@ -26,6 +26,7 @@ const { contract } = require("./util/contract");
const { on, off, emit, setListeners } = require("./event/core");
const { EventTarget } = require("./event/target");
const domPanel = require("./panel/utils");
const { getDocShell } = require('./frame/utils');
const { events } = require("./panel/events");
const systemEvents = require("./system/events");
const { filter, pipe, stripListeners } = require("./event/utils");
@ -73,9 +74,26 @@ var panelContract = contract(merge({
contentStyleFile: merge(Object.create(loaderContract.rules.contentScriptFile), {
msg: 'The `contentStyleFile` option must be a local URL or an array of URLs'
}),
contextMenu: boolean
contextMenu: boolean,
allow: {
is: ['object', 'undefined', 'null'],
map: function (allow) { return { script: !allow || allow.script !== false }}
},
}, displayContract.rules, loaderContract.rules));
function Allow(panel) {
return {
get script() { return getDocShell(viewFor(panel).backgroundFrame).allowJavascript; },
set script(value) { return setScriptState(panel, value); },
};
}
function setScriptState(panel, value) {
let view = viewFor(panel);
getDocShell(view.backgroundFrame).allowJavascript = value;
getDocShell(view.viewFrame).allowJavascript = value;
view.setAttribute("sdkscriptenabled", "" + value);
}
function isDisposed(panel) !views.has(panel);
@ -147,7 +165,8 @@ const Panel = Class({
}
// Setup view
let view = domPanel.make();
let viewOptions = {allowJavascript: !model.allow || (model.allow.script !== false)};
let view = domPanel.make(null, viewOptions);
panels.set(view, this);
views.set(this, view);
@ -212,6 +231,12 @@ const Panel = Class({
workerFor(this).detach();
},
get allow() { return Allow(this); },
set allow(value) {
let allowJavascript = panelContract({ allow: value }).allow.script;
return setScriptState(this, value);
},
/* Public API: Panel.isShowing */
get isShowing() !isDisposed(this) && domPanel.isOpen(viewFor(this)),

View File

@ -14,7 +14,7 @@ const { platform } = require("../system");
const { getMostRecentBrowserWindow, getOwnerBrowserWindow,
getHiddenWindow, getScreenPixelsPerCSSPixel } = require("../window/utils");
const { create: createFrame, swapFrameLoaders } = require("../frame/utils");
const { create: createFrame, swapFrameLoaders, getDocShell } = require("../frame/utils");
const { window: addonWindow } = require("../addon/window");
const { isNil } = require("../lang/type");
const { data } = require('../self');
@ -247,10 +247,11 @@ function setupPanelFrame(frame) {
}
}
function make(document) {
function make(document, options) {
document = document || getMostRecentBrowserWindow().document;
let panel = document.createElementNS(XUL_NS, "panel");
panel.setAttribute("type", "arrow");
panel.setAttribute("sdkscriptenabled", "" + options.allowJavascript);
// Note that panel is a parent of `viewFrame` who's `docShell` will be
// configured at creation time. If `panel` and there for `viewFrame` won't
@ -259,7 +260,7 @@ function make(document) {
attach(panel, document);
let frameOptions = {
allowJavascript: true,
allowJavascript: options.allowJavascript,
allowPlugins: true,
allowAuth: true,
allowWindowControl: false,
@ -284,8 +285,16 @@ function make(document) {
// See Bug 886329
if (target !== this) return;
try { swapFrameLoaders(backgroundFrame, viewFrame); }
catch(error) { console.exception(error); }
try {
swapFrameLoaders(backgroundFrame, viewFrame);
// We need to re-set this because... swapFrameLoaders. Or something.
let shouldEnableScript = panel.getAttribute("sdkscriptenabled") == "true";
getDocShell(backgroundFrame).allowJavascript = shouldEnableScript;
getDocShell(viewFrame).allowJavascript = shouldEnableScript;
}
catch(error) {
console.exception(error);
}
events.emit(type, { subject: panel });
}
@ -331,6 +340,7 @@ function make(document) {
panel.backgroundFrame = backgroundFrame;
panel.viewFrame = viewFrame;
// Store event listener on the panel instance so that it won't be GC-ed
// while panel is alive.
@ -356,8 +366,10 @@ function detach(panel) {
exports.detach = detach;
function dispose(panel) {
panel.backgroundFrame.parentNode.removeChild(panel.backgroundFrame);
panel.backgroundFrame.remove();
panel.viewFrame.remove();
panel.backgroundFrame = null;
panel.viewFrame = null;
events.off("document-element-inserted", panel.onContentChange);
panel.onContentChange = null;
detach(panel);

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "bd8ff00faac97ad6a2df5a6217910b8d295d56a3",
"git_revision": "9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "69bb3f2fc1245710dbca570a4dfaedf57d39f56b",
"revision": "73f844def0a5b0a7e077b68e5e16ffd6753129da",
"repo_path": "integration/gaia-central"
}

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

View File

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9a682cb7bc8b7fde624a9b2b3c2d64415a08b04b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>

View File

@ -1929,12 +1929,7 @@ pref("browser.pocket.oAuthConsumerKey", "40249-e88c401e1b1f2242d9e441c4");
pref("browser.pocket.useLocaleList", true);
pref("browser.pocket.enabledLocales", "cs de en-GB en-US en-ZA es-ES es-MX fr hu it ja ja-JP-mac ko nl pl pt-BR pt-PT ru zh-CN zh-TW");
// View source tabs are only enabled by default for Dev. Ed and Nightly.
#ifdef RELEASE_BUILD
pref("view_source.tab", false);
#else
pref("view_source.tab", true);
#endif
// Enable ServiceWorkers for Push API consumers.
// Interception is still disabled on beta and release.

View File

@ -393,11 +393,11 @@ var FullScreen = {
textElem.setAttribute("hidden", true);
} else {
textElem.removeAttribute("hidden");
let hostLabel = document.getElementById("fullscreen-domain");
let hostElem = document.getElementById("fullscreen-domain");
// Document's principal's URI has a host. Display a warning including it.
let utils = {};
Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
hostLabel.value = utils.DownloadUtils.getURIHost(uri.spec)[0];
hostElem.textContent = utils.DownloadUtils.getURIHost(uri.spec)[0];
}
this._element.className = gIdentityHandler.fullscreenWarningClassName;

View File

@ -660,7 +660,7 @@ window[chromehidden~="toolbar"] toolbar:not(#nav-bar):not(#TabsToolbar):not(#pri
background: black;
}
#fullscreen-warning {
html|*#fullscreen-warning {
position: fixed;
z-index: 2147483647 !important;
visibility: visible;
@ -669,33 +669,33 @@ window[chromehidden~="toolbar"] toolbar:not(#nav-bar):not(#TabsToolbar):not(#pri
we use left: 50% with translateX(-50%). */
top: 0; left: 50%;
transform: translate(-50%, -100%);
/* We must specify a max-width, otherwise word-wrap:break-word doesn't
work in descendant <description> and <label> elements. Bug 630864. */
box-sizing: border-box;
width: -moz-max-content;
max-width: 95%;
pointer-events: none;
}
#fullscreen-warning:not([hidden]) {
html|*#fullscreen-warning:not([hidden]) {
display: flex;
}
#fullscreen-warning[onscreen] {
html|*#fullscreen-warning[onscreen] {
transform: translate(-50%, 50px);
}
#fullscreen-warning[ontop] {
html|*#fullscreen-warning[ontop] {
/* Use -10px to hide the border and border-radius on the top */
transform: translate(-50%, -10px);
}
#fullscreen-domain-text,
#fullscreen-generic-text {
html|*#fullscreen-domain-text,
html|*#fullscreen-generic-text {
word-wrap: break-word;
/* We must specify a min-width, otherwise word-wrap:break-word doesn't work. Bug 630864. */
min-width: 1px
}
#fullscreen-domain-text:not([hidden]) + #fullscreen-generic-text {
html|*#fullscreen-domain-text:not([hidden]) + html|*#fullscreen-generic-text {
display: none;
}
#fullscreen-exit-button {
html|*#fullscreen-exit-button {
pointer-events: auto;
}

View File

@ -84,6 +84,10 @@ function pktUIGetter(prop) {
Object.defineProperty(window, "pktUI", pktUIGetter("pktUI"));
Object.defineProperty(window, "pktUIMessaging", pktUIGetter("pktUIMessaging"));
XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
return Services.strings.createBundle('chrome://browser/locale/browser.properties');
});
const nsIWebNavigation = Ci.nsIWebNavigation;
var gLastBrowserCharset = null;
@ -4032,6 +4036,41 @@ function updateUserContextUIVisibility()
document.getElementById("menu_newUserContext").hidden = !userContextEnabled;
}
/**
* Updates the User Context UI indicators if the browser is in a non-default context
*/
function updateUserContextUIIndicator(browser)
{
let hbox = document.getElementById("userContext-icons");
if (!browser.hasAttribute("usercontextid")) {
hbox.removeAttribute("usercontextid");
return;
}
let label = document.getElementById("userContext-label");
let userContextId = browser.getAttribute("usercontextid");
hbox.setAttribute("usercontextid", userContextId);
switch (userContextId) {
case "1":
label.value = gBrowserBundle.GetStringFromName("usercontext.personal.label");
break;
case "2":
label.value = gBrowserBundle.GetStringFromName("usercontext.work.label");
break;
case "3":
label.value = gBrowserBundle.GetStringFromName("usercontext.banking.label");
break;
case "4":
label.value = gBrowserBundle.GetStringFromName("usercontext.shopping.label");
break;
// Display the context IDs for values outside the pre-defined range.
// Used for debugging, no localization necessary.
default:
label.value = "Context " + userContextId;
}
}
/**
* Makes the Character Encoding menu enabled or disabled as appropriate.
* To be called when the View menu or the app menu is opened.

View File

@ -768,6 +768,10 @@
hidden="true"
onclick="ReaderParent.buttonClick(event);"/>
</hbox>
<hbox id="userContext-icons">
<label id="userContext-label"/>
<image id="userContext-indicator"/>
</hbox>
<toolbarbutton id="urlbar-go-button"
class="chromeclass-toolbar-additional"
onclick="gURLBar.handleCommand(event);"
@ -1151,23 +1155,24 @@
#include ../../components/customizableui/content/customizeMode.inc.xul
</deck>
<hbox id="fullscreen-warning" hidden="true">
<description id="fullscreen-domain-text">
<html:div id="fullscreen-warning" hidden="true">
<html:div id="fullscreen-domain-text">
&fullscreenWarning.beforeDomain.label;
<label id="fullscreen-domain"/>
<html:span id="fullscreen-domain"/>
&fullscreenWarning.afterDomain.label;
</description>
<description id="fullscreen-generic-text">
</html:div>
<html:div id="fullscreen-generic-text">
&fullscreenWarning.generic.label;
</description>
<button id="fullscreen-exit-button"
</html:div>
<html:button id="fullscreen-exit-button"
onclick="FullScreen.exitDomFullScreen();">
#ifdef XP_MACOSX
label="&exitDOMFullscreenMac.button;"
&exitDOMFullscreenMac.button;
#else
label="&exitDOMFullscreen.button;"
&exitDOMFullscreen.button;
#endif
oncommand="FullScreen.exitDomFullScreen();"/>
</hbox>
</html:button>
</html:div>
<vbox id="browser-bottombox" layer="true">
<notificationbox id="global-notificationbox"/>

View File

@ -53,10 +53,6 @@
});
}
if (!this.chatbar) {
document.getAnonymousElementByAttribute(this, "anonid", "minimize").hidden = true;
document.getAnonymousElementByAttribute(this, "anonid", "close").hidden = true;
}
let contentWindow = this.contentWindow;
// process this._callbacks, then set to null so the chatbox creator
// knows to make new callbacks immediately.
@ -71,6 +67,7 @@
return;
this.removeEventListener("DOMContentLoaded", DOMContentLoaded, true);
this.isActive = !this.minimized;
this._chat.loadButtonSet(this, this.getAttribute("buttonSet"));
this._deferredChatLoaded.resolve(this);
}, true);
@ -92,6 +89,10 @@
document.getAnonymousElementByAttribute(this, "anonid", "content");
</field>
<field name="_chat" readonly="true">
Cu.import("resource:///modules/Chat.jsm", {}).Chat;
</field>
<property name="contentWindow">
<getter>
return this.content.contentWindow;
@ -171,10 +172,9 @@
<method name="setDecorationAttributes">
<parameter name="aTarget"/>
<body><![CDATA[
for (let attr of ["dark", "customSize"]) {
if (this.hasAttribute(attr))
aTarget.setAttribute(attr, this.getAttribute(attr));
}
if (this.hasAttribute("customSize"))
aTarget.setAttribute("customSize", this.getAttribute("customSize"));
this._chat.loadButtonSet(aTarget, this.getAttribute("buttonSet"));
]]></body>
</method>

View File

@ -1237,6 +1237,8 @@
this._adjustFocusAfterTabSwitch(this.mCurrentTab);
}
updateUserContextUIIndicator(gBrowser.selectedBrowser);
this.tabContainer._setPositionalAttributes();
if (!gMultiProcessBrowser) {
@ -1803,6 +1805,8 @@
var uriIsAboutBlank = !aURI || aURI == "about:blank";
if (aUserContextId)
t.setAttribute("usercontextid", aUserContextId);
t.setAttribute("crop", "end");
t.setAttribute("onerror", "this.removeAttribute('image');");
t.className = "tabbrowser-tab";
@ -2523,6 +2527,10 @@
aOurTab.setAttribute("soundplaying", "true");
modifiedAttrs.push("soundplaying");
}
if (aOtherTab.hasAttribute("usercontextid")) {
aOurTab.setAttribute("usercontextid", aOtherTab.getAttribute("usercontextid"));
modifiedAttrs.push("usercontextid");
}
// If the other tab is pending (i.e. has not been restored, yet)
// then do not switch docShells but retrieve the other tab's state

View File

@ -131,3 +131,68 @@ add_chat_task(function* testChatWindowChooser() {
privateWindow.close();
secondWindow.close();
});
add_chat_task(function* testButtonSet() {
let chatbox = yield promiseOpenChat("http://example.com#1");
let document = chatbox.ownerDocument;
// Expect all default buttons to be visible.
for (let buttonId of kDefaultButtonSet) {
let button = document.getAnonymousElementByAttribute(chatbox, "anonid", buttonId);
Assert.ok(!button.hidden, "Button '" + buttonId + "' should be visible");
}
let visible = new Set(["minimize", "close"]);
chatbox = yield promiseOpenChat("http://example.com#2", null, null, [...visible].join(","));
for (let buttonId of kDefaultButtonSet) {
let button = document.getAnonymousElementByAttribute(chatbox, "anonid", buttonId);
if (visible.has(buttonId)) {
Assert.ok(!button.hidden, "Button '" + buttonId + "' should be visible");
} else {
Assert.ok(button.hidden, "Button '" + buttonId + "' should NOT be visible");
}
}
});
add_chat_task(function* testCustomButton() {
let commanded = 0;
let customButton = {
id: "custom",
onCommand: function() {
++commanded;
}
};
Chat.registerButton(customButton);
let chatbox = yield promiseOpenChat("http://example.com#1");
let document = chatbox.ownerDocument;
let titlebarNode = document.getAnonymousElementByAttribute(chatbox, "class",
"chat-titlebar");
Assert.equal(titlebarNode.getElementsByClassName("chat-custom")[0], null,
"Custom chat button should not be in the toolbar yet.");
let visible = new Set(["minimize", "close", "custom"]);
Chat.loadButtonSet(chatbox, [...visible].join(","));
for (let buttonId of kDefaultButtonSet) {
let button = document.getAnonymousElementByAttribute(chatbox, "anonid", buttonId);
if (visible.has(buttonId)) {
Assert.ok(!button.hidden, "Button '" + buttonId + "' should be visible");
} else {
Assert.ok(button.hidden, "Button '" + buttonId + "' should NOT be visible");
}
}
let customButtonNode = titlebarNode.getElementsByClassName("chat-custom")[0];
Assert.ok(!customButtonNode.hidden, "Custom button should be visible");
let ev = document.createEvent("XULCommandEvent");
ev.initCommandEvent("command", true, true, document.defaultView, 0, false,
false, false, false, null);
customButtonNode.dispatchEvent(ev);
Assert.equal(commanded, 1, "Button should have been commanded once");
});

View File

@ -5,8 +5,9 @@
// Utility functions for Chat tests.
var Chat = Cu.import("resource:///modules/Chat.jsm", {}).Chat;
const kDefaultButtonSet = new Set(["minimize", "swap", "close"]);
function promiseOpenChat(url, mode, focus) {
function promiseOpenChat(url, mode, focus, buttonSet = null) {
let uri = Services.io.newURI(url, null, null);
let origin = uri.prePath;
let title = origin;
@ -28,6 +29,9 @@ function promiseOpenChat(url, mode, focus) {
}, true);
}
let chatbox = Chat.open(null, origin, title, url, mode, focus, callback);
if (buttonSet) {
chatbox.setAttribute("buttonSet", buttonSet);
}
return deferred.promise;
}

View File

@ -30,6 +30,12 @@ function init(event) {
fxButton.addEventListener("mousedown", PositionHandler);
updateIndicatorState();
// Alert accessibility implementations stuff just changed. We only need to do
// this initially, because changes after this will automatically fire alert
// events if things change materially.
let ev = new CustomEvent("AlertActive", {bubbles: true, cancelable: true});
document.documentElement.dispatchEvent(ev);
}
function updateIndicatorState() {

View File

@ -12,7 +12,7 @@
<window xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="webrtcIndicator"
html:role="alert"
role="alert"
windowtype="Browser:WebRTCGlobalIndicator"
onload="init(event);"
#ifdef XP_MACOSX

View File

@ -72,12 +72,14 @@ loop.conversation = (function(mozL10n) {
case "incoming":
case "outgoing": {
return (React.createElement(CallControllerView, {
chatWindowDetached: this.state.chatWindowDetached,
dispatcher: this.props.dispatcher,
mozLoop: this.props.mozLoop,
onCallTerminated: this.handleCallTerminated}));
}
case "room": {
return (React.createElement(DesktopRoomConversationView, {
chatWindowDetached: this.state.chatWindowDetached,
dispatcher: this.props.dispatcher,
mozLoop: this.props.mozLoop,
onCallTerminated: this.handleCallTerminated,
@ -138,10 +140,6 @@ loop.conversation = (function(mozL10n) {
loop.conversation._sdkDriver = sdkDriver;
// Create the stores.
var conversationAppStore = new loop.store.ConversationAppStore({
dispatcher: dispatcher,
mozLoop: navigator.mozLoop
});
var conversationStore = new loop.store.ConversationStore(dispatcher, {
client: client,
isDesktop: true,
@ -153,6 +151,11 @@ loop.conversation = (function(mozL10n) {
mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});
var conversationAppStore = new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop
});
var roomStore = new loop.store.RoomStore(dispatcher, {
mozLoop: navigator.mozLoop,
activeRoomStore: activeRoomStore
@ -176,10 +179,6 @@ loop.conversation = (function(mozL10n) {
windowId = hash[1];
}
window.addEventListener("unload", function(event) {
dispatcher.dispatch(new sharedActions.WindowUnload());
});
React.render(
React.createElement(AppControllerView, {
dispatcher: dispatcher,

View File

@ -72,12 +72,14 @@ loop.conversation = (function(mozL10n) {
case "incoming":
case "outgoing": {
return (<CallControllerView
chatWindowDetached={this.state.chatWindowDetached}
dispatcher={this.props.dispatcher}
mozLoop={this.props.mozLoop}
onCallTerminated={this.handleCallTerminated} />);
}
case "room": {
return (<DesktopRoomConversationView
chatWindowDetached={this.state.chatWindowDetached}
dispatcher={this.props.dispatcher}
mozLoop={this.props.mozLoop}
onCallTerminated={this.handleCallTerminated}
@ -138,10 +140,6 @@ loop.conversation = (function(mozL10n) {
loop.conversation._sdkDriver = sdkDriver;
// Create the stores.
var conversationAppStore = new loop.store.ConversationAppStore({
dispatcher: dispatcher,
mozLoop: navigator.mozLoop
});
var conversationStore = new loop.store.ConversationStore(dispatcher, {
client: client,
isDesktop: true,
@ -153,6 +151,11 @@ loop.conversation = (function(mozL10n) {
mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});
var conversationAppStore = new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop
});
var roomStore = new loop.store.RoomStore(dispatcher, {
mozLoop: navigator.mozLoop,
activeRoomStore: activeRoomStore
@ -176,10 +179,6 @@ loop.conversation = (function(mozL10n) {
windowId = hash[1];
}
window.addEventListener("unload", function(event) {
dispatcher.dispatch(new sharedActions.WindowUnload());
});
React.render(
<AppControllerView
dispatcher={dispatcher}

View File

@ -15,9 +15,13 @@ loop.store.ConversationAppStore = (function() {
/**
* Constructor
*
* @param {Object} options Options for the store. Should contain the dispatcher.
* @param {Object} options Options for the store. Should contain the
* activeRoomStore, dispatcher and mozLoop objects.
*/
var ConversationAppStore = function(options) {
if (!options.activeRoomStore) {
throw new Error("Missing option activeRoomStore");
}
if (!options.dispatcher) {
throw new Error("Missing option dispatcher");
}
@ -25,10 +29,21 @@ loop.store.ConversationAppStore = (function() {
throw new Error("Missing option mozLoop");
}
this._activeRoomStore = options.activeRoomStore;
this._dispatcher = options.dispatcher;
this._mozLoop = options.mozLoop;
this._rootObj = ("rootObject" in options) ? options.rootObject : window;
this._storeState = this.getInitialStoreState();
// Start listening for specific events, coming from the window object.
this._eventHandlers = {};
["unload", "LoopHangupNow", "socialFrameAttached", "socialFrameDetached"]
.forEach(function(eventName) {
var handlerName = eventName + "Handler";
this._eventHandlers[eventName] = this[handlerName].bind(this);
this._rootObj.addEventListener(eventName, this._eventHandlers[eventName]);
}.bind(this));
this._dispatcher.register(this, [
"getWindowData",
"showFeedbackForm"
@ -38,6 +53,7 @@ loop.store.ConversationAppStore = (function() {
ConversationAppStore.prototype = _.extend({
getInitialStoreState: function() {
return {
chatWindowDetached: false,
// How often to display the form. Convert seconds to ms.
feedbackPeriod: this._mozLoop.getLoopPref("feedback.periodSec") * 1000,
// Date when the feedback form was last presented. Convert to ms.
@ -62,7 +78,7 @@ loop.store.ConversationAppStore = (function() {
* @param {Object} state The new store state.
*/
setStoreState: function(state) {
this._storeState = state;
this._storeState = _.extend({}, this._storeState, state);
this.trigger("change");
},
@ -99,6 +115,64 @@ loop.store.ConversationAppStore = (function() {
this._dispatcher.dispatch(new loop.shared.actions.SetupWindowData(_.extend({
windowId: actionData.windowId}, windowData)));
},
/**
* Event handler; invoked when the 'unload' event is dispatched from the
* window object.
* It will dispatch a 'WindowUnload' action that other stores may listen to
* and will remove all event handlers attached to the window object.
*/
unloadHandler: function() {
this._dispatcher.dispatch(new loop.shared.actions.WindowUnload());
// Unregister event handlers.
var eventNames = Object.getOwnPropertyNames(this._eventHandlers);
eventNames.forEach(function(eventName) {
this._rootObj.removeEventListener(eventName, this._eventHandlers[eventName]);
}.bind(this));
this._eventHandlers = null;
},
/**
* Event handler; invoked when the 'LoopHangupNow' event is dispatched from
* the window object.
* It'll attempt to gracefully disconnect from an active session, or close
* the window when no session is currently active.
*/
LoopHangupNowHandler: function() {
switch (this.getStoreState().windowType) {
case "incoming":
case "outgoing":
this._dispatcher.dispatch(new loop.shared.actions.HangupCall());
break;
case "room":
if (this._activeRoomStore.getStoreState().used) {
this._dispatcher.dispatch(new loop.shared.actions.LeaveRoom());
} else {
loop.shared.mixins.WindowCloseMixin.closeWindow();
}
break;
default:
loop.shared.mixins.WindowCloseMixin.closeWindow();
break;
}
},
/**
* Event handler; invoked when the 'socialFrameAttached' event is dispatched
* from the window object.
*/
socialFrameAttachedHandler: function() {
this.setStoreState({ chatWindowDetached: false });
},
/**
* Event handler; invoked when the 'socialFrameDetached' event is dispatched
* from the window object.
*/
socialFrameDetachedHandler: function() {
this.setStoreState({ chatWindowDetached: true });
}
}, Backbone.Events);

View File

@ -579,6 +579,7 @@ loop.conversationViews = (function(mozL10n) {
propTypes: {
// local
audio: React.PropTypes.object,
chatWindowDetached: React.PropTypes.bool.isRequired,
// We pass conversationStore here rather than use the mixin, to allow
// easy configurability for the ui-showcase.
conversationStore: React.PropTypes.instanceOf(loop.store.ConversationStore).isRequired,
@ -715,7 +716,7 @@ loop.conversationViews = (function(mozL10n) {
screenSharePosterUrl: null,
showContextRoomName: false,
useDesktopPaths: true},
React.createElement(loop.shared.views.ConversationToolbar, {
React.createElement(sharedViews.ConversationToolbar, {
audio: this.props.audio,
dispatcher: this.props.dispatcher,
hangup: this.hangup,
@ -723,6 +724,7 @@ loop.conversationViews = (function(mozL10n) {
publishStream: this.publishStream,
settingsMenuItems: settingsMenuItems,
show: true,
showHangup: this.props.chatWindowDetached,
video: this.props.video})
)
)
@ -743,6 +745,7 @@ loop.conversationViews = (function(mozL10n) {
],
propTypes: {
chatWindowDetached: React.PropTypes.bool.isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
mozLoop: React.PropTypes.object.isRequired,
onCallTerminated: React.PropTypes.func.isRequired
@ -822,6 +825,7 @@ loop.conversationViews = (function(mozL10n) {
case CALL_STATES.ONGOING: {
return (React.createElement(OngoingConversationView, {
audio: { enabled: !this.state.audioMuted, visible: true},
chatWindowDetached: this.props.chatWindowDetached,
conversationStore: this.getStore(),
dispatcher: this.props.dispatcher,
mediaConnected: this.state.mediaConnected,

View File

@ -579,6 +579,7 @@ loop.conversationViews = (function(mozL10n) {
propTypes: {
// local
audio: React.PropTypes.object,
chatWindowDetached: React.PropTypes.bool.isRequired,
// We pass conversationStore here rather than use the mixin, to allow
// easy configurability for the ui-showcase.
conversationStore: React.PropTypes.instanceOf(loop.store.ConversationStore).isRequired,
@ -715,7 +716,7 @@ loop.conversationViews = (function(mozL10n) {
screenSharePosterUrl={null}
showContextRoomName={false}
useDesktopPaths={true}>
<loop.shared.views.ConversationToolbar
<sharedViews.ConversationToolbar
audio={this.props.audio}
dispatcher={this.props.dispatcher}
hangup={this.hangup}
@ -723,6 +724,7 @@ loop.conversationViews = (function(mozL10n) {
publishStream={this.publishStream}
settingsMenuItems={settingsMenuItems}
show={true}
showHangup={this.props.chatWindowDetached}
video={this.props.video} />
</sharedViews.MediaLayoutView>
</div>
@ -743,6 +745,7 @@ loop.conversationViews = (function(mozL10n) {
],
propTypes: {
chatWindowDetached: React.PropTypes.bool.isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
mozLoop: React.PropTypes.object.isRequired,
onCallTerminated: React.PropTypes.func.isRequired
@ -822,6 +825,7 @@ loop.conversationViews = (function(mozL10n) {
case CALL_STATES.ONGOING: {
return (<OngoingConversationView
audio={{ enabled: !this.state.audioMuted, visible: true }}
chatWindowDetached={this.props.chatWindowDetached}
conversationStore={this.getStore()}
dispatcher={this.props.dispatcher}
mediaConnected={this.state.mediaConnected}

View File

@ -729,19 +729,19 @@ loop.panel = (function(_, mozL10n) {
className: "dropdown-menu-item",
onClick: this.props.handleCopyButtonClick,
ref: "copyButton"},
mozL10n.get("copy_url_button2")
mozL10n.get("copy_link_menuitem")
),
React.createElement("li", {
className: "dropdown-menu-item",
onClick: this.props.handleEmailButtonClick,
ref: "emailButton"},
mozL10n.get("email_link_button")
mozL10n.get("email_link_menuitem")
),
React.createElement("li", {
className: "dropdown-menu-item",
onClick: this.props.handleDeleteButtonClick,
ref: "deleteButton"},
mozL10n.get("rooms_list_delete_tooltip")
mozL10n.get("delete_conversation_menuitem")
)
)
);

View File

@ -729,19 +729,19 @@ loop.panel = (function(_, mozL10n) {
className="dropdown-menu-item"
onClick={this.props.handleCopyButtonClick}
ref="copyButton">
{mozL10n.get("copy_url_button2")}
{mozL10n.get("copy_link_menuitem")}
</li>
<li
className="dropdown-menu-item"
onClick={this.props.handleEmailButtonClick}
ref="emailButton">
{mozL10n.get("email_link_button")}
{mozL10n.get("email_link_menuitem")}
</li>
<li
className="dropdown-menu-item"
onClick={this.props.handleDeleteButtonClick}
ref="deleteButton">
{mozL10n.get("rooms_list_delete_tooltip")}
{mozL10n.get("delete_conversation_menuitem")}
</li>
</ul>
);

View File

@ -191,6 +191,10 @@ loop.roomViews = (function(mozL10n) {
* Desktop room invitation view (overlay).
*/
var DesktopRoomInvitationView = React.createClass({displayName: "DesktopRoomInvitationView",
statics: {
TRIGGERED_RESET_DELAY: 2000
},
mixins: [sharedMixins.DropdownMenuMixin(".room-invitation-overlay")],
propTypes: {
@ -236,6 +240,16 @@ loop.roomViews = (function(mozL10n) {
}));
this.setState({copiedUrl: true});
setTimeout(this.resetTriggeredButtons, this.constructor.TRIGGERED_RESET_DELAY);
},
/**
* Reset state of triggered buttons if necessary
*/
resetTriggeredButtons: function() {
if (this.state.copiedUrl) {
this.setState({copiedUrl: false});
}
},
handleShareButtonClick: function(event) {
@ -252,14 +266,6 @@ loop.roomViews = (function(mozL10n) {
this.toggleDropdownMenu();
},
handleAddContextClick: function(event) {
event.preventDefault();
if (this.props.onAddContextClick) {
this.props.onAddContextClick();
}
},
handleEditContextClose: function() {
if (this.props.onEditContextClose) {
this.props.onEditContextClose();
@ -271,22 +277,12 @@ loop.roomViews = (function(mozL10n) {
return null;
}
var canAddContext = this.props.mozLoop.getLoopPref("contextInConversations.enabled") &&
// Don't show the link when we're showing the edit form already:
!this.props.showEditContext &&
// Don't show the link when there's already context data available:
!(this.props.roomData.roomContextUrls || this.props.roomData.roomDescription);
var cx = React.addons.classSet;
return (
React.createElement("div", {className: "room-invitation-overlay"},
React.createElement("div", {className: "room-invitation-content"},
React.createElement("p", {className: cx({hide: this.props.showEditContext})},
mozL10n.get("invite_header_text")
),
React.createElement("a", {className: cx({hide: !canAddContext, "room-invitation-addcontext": true}),
onClick: this.handleAddContextClick},
mozL10n.get("context_add_some_label")
mozL10n.get("invite_header_text2")
)
),
React.createElement("div", {className: cx({
@ -294,19 +290,21 @@ loop.roomViews = (function(mozL10n) {
"call-action-group": true,
hide: this.props.showEditContext
})},
React.createElement("button", {className: "btn btn-info btn-email",
onClick: this.handleEmailButtonClick},
mozL10n.get("email_link_button")
React.createElement("div", {className: cx({
"btn-copy": true,
"invite-button": true,
"triggered": this.state.copiedUrl
}),
onClick: this.handleCopyButtonClick},
React.createElement("img", {src: "loop/shared/img/svg/glyph-link-16x16.svg"}),
React.createElement("p", null, mozL10n.get(this.state.copiedUrl ?
"invite_copied_link_button" : "invite_copy_link_button"))
),
React.createElement("button", {className: "btn btn-info btn-copy",
onClick: this.handleCopyButtonClick},
this.state.copiedUrl ? mozL10n.get("copied_url_button") :
mozL10n.get("copy_url_button2")
),
React.createElement("button", {className: "btn btn-info btn-share",
onClick: this.handleShareButtonClick,
ref: "anchor"},
mozL10n.get("share_button3")
React.createElement("div", {className: "btn-email invite-button",
onClick: this.handleEmailButtonClick,
onMouseOver: this.resetTriggeredButtons},
React.createElement("img", {src: "loop/shared/img/svg/glyph-email-16x16.svg"}),
React.createElement("p", null, mozL10n.get("invite_email_link_button"))
)
),
React.createElement(SocialShareDropdown, {
@ -550,6 +548,7 @@ loop.roomViews = (function(mozL10n) {
],
propTypes: {
chatWindowDetached: React.PropTypes.bool.isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
// The poster URLs are for UI-showcase testing and development.
localPosterUrl: React.PropTypes.string,
@ -781,6 +780,7 @@ loop.roomViews = (function(mozL10n) {
screenShare: screenShareData,
settingsMenuItems: settingsMenuItems,
show: !shouldRenderEditContextView,
showHangup: this.props.chatWindowDetached,
video: {enabled: !this.state.videoMuted, visible: true}}),
React.createElement(DesktopRoomInvitationView, {
dispatcher: this.props.dispatcher,

View File

@ -191,6 +191,10 @@ loop.roomViews = (function(mozL10n) {
* Desktop room invitation view (overlay).
*/
var DesktopRoomInvitationView = React.createClass({
statics: {
TRIGGERED_RESET_DELAY: 2000
},
mixins: [sharedMixins.DropdownMenuMixin(".room-invitation-overlay")],
propTypes: {
@ -236,6 +240,16 @@ loop.roomViews = (function(mozL10n) {
}));
this.setState({copiedUrl: true});
setTimeout(this.resetTriggeredButtons, this.constructor.TRIGGERED_RESET_DELAY);
},
/**
* Reset state of triggered buttons if necessary
*/
resetTriggeredButtons: function() {
if (this.state.copiedUrl) {
this.setState({copiedUrl: false});
}
},
handleShareButtonClick: function(event) {
@ -252,14 +266,6 @@ loop.roomViews = (function(mozL10n) {
this.toggleDropdownMenu();
},
handleAddContextClick: function(event) {
event.preventDefault();
if (this.props.onAddContextClick) {
this.props.onAddContextClick();
}
},
handleEditContextClose: function() {
if (this.props.onEditContextClose) {
this.props.onEditContextClose();
@ -271,43 +277,35 @@ loop.roomViews = (function(mozL10n) {
return null;
}
var canAddContext = this.props.mozLoop.getLoopPref("contextInConversations.enabled") &&
// Don't show the link when we're showing the edit form already:
!this.props.showEditContext &&
// Don't show the link when there's already context data available:
!(this.props.roomData.roomContextUrls || this.props.roomData.roomDescription);
var cx = React.addons.classSet;
return (
<div className="room-invitation-overlay">
<div className="room-invitation-content">
<p className={cx({hide: this.props.showEditContext})}>
{mozL10n.get("invite_header_text")}
{mozL10n.get("invite_header_text2")}
</p>
<a className={cx({hide: !canAddContext, "room-invitation-addcontext": true})}
onClick={this.handleAddContextClick}>
{mozL10n.get("context_add_some_label")}
</a>
</div>
<div className={cx({
"btn-group": true,
"call-action-group": true,
hide: this.props.showEditContext
})}>
<button className="btn btn-info btn-email"
onClick={this.handleEmailButtonClick}>
{mozL10n.get("email_link_button")}
</button>
<button className="btn btn-info btn-copy"
onClick={this.handleCopyButtonClick}>
{this.state.copiedUrl ? mozL10n.get("copied_url_button") :
mozL10n.get("copy_url_button2")}
</button>
<button className="btn btn-info btn-share"
onClick={this.handleShareButtonClick}
ref="anchor">
{mozL10n.get("share_button3")}
</button>
<div className={cx({
"btn-copy": true,
"invite-button": true,
"triggered": this.state.copiedUrl
})}
onClick={this.handleCopyButtonClick}>
<img src="loop/shared/img/svg/glyph-link-16x16.svg" />
<p>{mozL10n.get(this.state.copiedUrl ?
"invite_copied_link_button" : "invite_copy_link_button")}</p>
</div>
<div className="btn-email invite-button"
onClick={this.handleEmailButtonClick}
onMouseOver={this.resetTriggeredButtons}>
<img src="loop/shared/img/svg/glyph-email-16x16.svg" />
<p>{mozL10n.get("invite_email_link_button")}</p>
</div>
</div>
<SocialShareDropdown
dispatcher={this.props.dispatcher}
@ -550,6 +548,7 @@ loop.roomViews = (function(mozL10n) {
],
propTypes: {
chatWindowDetached: React.PropTypes.bool.isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
// The poster URLs are for UI-showcase testing and development.
localPosterUrl: React.PropTypes.string,
@ -781,6 +780,7 @@ loop.roomViews = (function(mozL10n) {
screenShare={screenShareData}
settingsMenuItems={settingsMenuItems}
show={!shouldRenderEditContextView}
showHangup={this.props.chatWindowDetached}
video={{enabled: !this.state.videoMuted, visible: true}} />
<DesktopRoomInvitationView
dispatcher={this.props.dispatcher}

View File

@ -268,6 +268,41 @@ html[dir="rtl"] .conversation-toolbar-btn-box.btn-edit-entry {
width: 100%;
}
.call-action-group > .invite-button {
margin: 0 4px;
position: relative;
}
.call-action-group > .invite-button > img {
background-color: #00a9dc;
border-radius: 100%;
height: 28px;
width: 28px;
}
.call-action-group > .invite-button:hover > img {
background-color: #5cccee;
}
.call-action-group > .invite-button.triggered > img {
background-color: #56b397;
}
.call-action-group > .invite-button > p {
display: none;
/* Position the text under the button while centering it without impacting the
* rest of the layout */
left: -10rem;
margin: .5rem 0 0;
position: absolute;
right: -10rem;
}
.call-action-group > .invite-button.triggered > p,
.call-action-group > .invite-button:hover > p {
display: block;
}
.direct-call-failure,
.room-failure {
/* This flex allows us to not calculate the height of the logo area
@ -663,13 +698,13 @@ html[dir="rtl"] .room-conversation-wrapper header a {
.room-invitation-overlay {
position: absolute;
background: rgba(255, 255, 255, 0.6);
background: rgba(255, 255, 255, 0.85);
top: 0;
height: 100%;
right: 0;
left: 0;
text-align: center;
color: #fff;
color: #000;
z-index: 1010;
display: flex;
flex-flow: column nowrap;
@ -686,30 +721,7 @@ html[dir="rtl"] .room-conversation-wrapper header a {
}
.room-invitation-overlay .btn-group {
padding: 0 0 5rem 0;
}
.room-invitation-addcontext {
color: #0095dd;
padding-left: 1.5em;
margin-bottom: 1em;
background-image: url("../img/icons-10x10.svg#edit-active");
background-size: 1em 1em;
background-repeat: no-repeat;
background-position: left top;
font-size: 1em;
cursor: pointer;
}
.room-invitation-addcontext:hover,
.room-invitation-addcontext:hover:active {
text-decoration: underline;
}
html[dir="rtl"] .room-invitation-addcontext {
padding-left: 0;
padding-right: 1.5em;
background-position: right top;
padding: 0 0 10rem;
}
.share-service-dropdown {
@ -804,6 +816,7 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
text-shadow: 1px 1px 0 rgba(0,0,0,.3);
}
.room-invitation-content,
.room-context-header {
color: #333;
font-size: 1.2rem;

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#FFF" d="M12 10.4c0 .2-.1.4-.2.5-.1.1-.3.2-.5.2H4.7c-.2 0-.4-.1-.5-.2-.1-.1-.2-.3-.2-.5V6.9c.1.1.3.3.5.4 1 .7 1.8 1.2 2.2 1.5.1.1.3.2.4.3.1.1.2.1.4.2s.3.1.5.1.3 0 .5-.1.3-.1.4-.2c.1-.1.3-.2.4-.3.5-.4 1.2-.9 2.2-1.5.2-.1.4-.3.5-.4v3.5zm-.2-4.2c-.1.2-.3.4-.5.5-1.1.8-1.8 1.3-2.1 1.5 0 0-.1.1-.2.1-.1.2-.2.2-.3.3-.1 0-.1.1-.2.1-.1.1-.2.1-.3.1h-.4c-.1 0-.2-.1-.3-.1-.1-.1-.2-.1-.2-.1-.1-.1-.2-.1-.3-.2-.1-.1-.1-.1-.1-.2-.3-.1-.7-.4-1.2-.8-.5-.3-.8-.5-.9-.6-.2-.1-.4-.3-.6-.5S4 5.9 4 5.7c0-.2.1-.4.2-.6.1-.2.3-.2.5-.2h6.6c.2 0 .4.1.5.2.1.1.2.3.2.5s-.1.4-.2.6z"/></svg>

After

Width:  |  Height:  |  Size: 635 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#FFF" d="M12 11.6c0 .1 0 .2-.1.3s-.2.1-.3.1h-2V8.9h1l.2-1.2H9.5v-.8c0-.2 0-.3.1-.4.1-.1.2-.1.5-.1h.6V5.3h-.9c-.4-.1-.8 0-1.1.3-.3.3-.4.7-.4 1.2v.9h-1v1.2h1V12H4.4c-.1 0-.2 0-.3-.1-.1-.1-.1-.2-.1-.3V4.4c0-.1 0-.2.1-.3.1-.1.2-.1.3-.1h7.1c.1 0 .2 0 .3.1.2.1.2.2.2.3v7.2z"/></svg>

After

Width:  |  Height:  |  Size: 348 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#FFF" d="M12 9.9c0 .4-.1.7-.4 1l-.7.7c-.3.3-.6.4-1 .4s-.7-.1-1-.4l-1-1c-.3-.3-.4-.6-.4-1s.1-.7.4-1l-.4-.5c-.3.3-.6.4-1 .4s-.7-.1-1-.4l-1-1c-.4-.3-.5-.6-.5-1s.1-.7.4-1l.7-.7c.3-.3.6-.4 1-.4s.7.1 1 .4l1 1c.3.3.4.6.4 1s-.1.7-.4 1l.4.4c.3-.3.6-.4 1-.4s.7.1 1 .4l1 1c.4.4.5.7.5 1.1zM7.6 6.4c0-.1 0-.2-.1-.3l-1-1c-.1-.1-.2-.2-.4-.2-.1 0-.2.1-.3.2l-.7.7c-.1.1-.2.2-.2.3 0 .1 0 .2.1.3l1 1c.1.1.2.1.3.1.1 0 .3-.1.4-.2l-.1-.1v.1s0-.1-.1-.1l-.1-.1V7c0-.1 0-.2.1-.3s.2-.1.3-.1h.1s.1 0 .1.1l.1.1.1.1.1.1c.3-.3.3-.4.3-.6zm3.5 3.5c0-.1 0-.2-.1-.3l-1-1c-.2-.2-.3-.2-.4-.2-.1 0-.3.1-.4.2l.1.1.1.1s0 .1.1.1l.1.1v.1c0 .1 0 .2-.1.3s-.3.2-.4.2H9s-.1 0-.1-.1l-.1-.1-.1-.1c-.1 0-.1-.1-.2-.1-.1.1-.1.2-.1.4 0 .1 0 .2.1.3l1 1c.1.1.2.1.3.1.1 0 .2 0 .3-.1l.7-.7c.2-.1.3-.2.3-.3z"/></svg>

After

Width:  |  Height:  |  Size: 832 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#FFF" d="M6.5 4.3c.4-.5.9-.7 1.5-.7s1.1.2 1.5.6.6.9.6 1.5-.2 1.1-.6 1.5c-.4.6-.9.8-1.5.8s-1.1-.2-1.5-.6c-.5-.5-.7-1-.7-1.6 0-.6.2-1.1.7-1.5zm5.1 7.7c-.3.3-.6.4-1.1.4h-5c-.5 0-.8-.1-1.1-.4-.3-.3-.4-.7-.4-1.1v-.6s0-.4.1-.6c0-.2.1-.4.2-.6.1-.2.1-.4.2-.6.1-.2.2-.3.4-.5.1-.1.2-.2.4-.2s.4-.2.7-.2c0 0 .1 0 .2.1s.3.2.4.3l.6.3s.5.1.8.1c.3 0 .5 0 .8-.1l.6-.3c.2-.1.3-.2.4-.3.1 0 .2-.1.2-.1.2 0 .4 0 .6.1.2.1.4.2.5.3.1.1.2.3.4.5s.2.4.2.6c.1.2.1.4.2.6 0 .2.1.4.1.6v.6c0 .4-.1.8-.4 1.1z"/></svg>

After

Width:  |  Height:  |  Size: 556 B

View File

@ -376,7 +376,8 @@ loop.shared.views = (function(_, mozL10n) {
audio: {enabled: true, visible: true},
screenShare: {state: SCREEN_SHARE_STATES.INACTIVE, visible: false},
settingsMenuItems: null,
enableHangup: true
enableHangup: true,
showHangup: true
};
},
@ -397,6 +398,7 @@ loop.shared.views = (function(_, mozL10n) {
screenShare: React.PropTypes.object,
settingsMenuItems: React.PropTypes.array,
show: React.PropTypes.bool.isRequired,
showHangup: React.PropTypes.bool,
video: React.PropTypes.object.isRequired
},
@ -493,14 +495,17 @@ loop.shared.views = (function(_, mozL10n) {
});
return (
React.createElement("ul", {className: conversationToolbarCssClasses},
React.createElement("li", {className: "conversation-toolbar-btn-box btn-hangup-entry"},
React.createElement("button", {className: "btn btn-hangup",
disabled: !this.props.enableHangup,
onClick: this.handleClickHangup,
title: mozL10n.get("hangup_button_title")},
this._getHangupButtonLabel()
)
),
this.props.showHangup ?
React.createElement("li", {className: "conversation-toolbar-btn-box btn-hangup-entry"},
React.createElement("button", {className: "btn btn-hangup",
disabled: !this.props.enableHangup,
onClick: this.handleClickHangup,
title: mozL10n.get("hangup_button_title")},
this._getHangupButtonLabel()
)
) : null,
React.createElement("li", {className: "conversation-toolbar-btn-box"},
React.createElement("div", {className: mediaButtonGroupCssClasses},
React.createElement(MediaControlButton, {action: this.handleToggleVideo,

View File

@ -376,7 +376,8 @@ loop.shared.views = (function(_, mozL10n) {
audio: {enabled: true, visible: true},
screenShare: {state: SCREEN_SHARE_STATES.INACTIVE, visible: false},
settingsMenuItems: null,
enableHangup: true
enableHangup: true,
showHangup: true
};
},
@ -397,6 +398,7 @@ loop.shared.views = (function(_, mozL10n) {
screenShare: React.PropTypes.object,
settingsMenuItems: React.PropTypes.array,
show: React.PropTypes.bool.isRequired,
showHangup: React.PropTypes.bool,
video: React.PropTypes.object.isRequired
},
@ -493,14 +495,17 @@ loop.shared.views = (function(_, mozL10n) {
});
return (
<ul className={conversationToolbarCssClasses}>
<li className="conversation-toolbar-btn-box btn-hangup-entry">
<button className="btn btn-hangup"
disabled={!this.props.enableHangup}
onClick={this.handleClickHangup}
title={mozL10n.get("hangup_button_title")}>
{this._getHangupButtonLabel()}
</button>
</li>
{
this.props.showHangup ?
<li className="conversation-toolbar-btn-box btn-hangup-entry">
<button className="btn btn-hangup"
disabled={!this.props.enableHangup}
onClick={this.handleClickHangup}
title={mozL10n.get("hangup_button_title")}>
{this._getHangupButtonLabel()}
</button>
</li> : null
}
<li className="conversation-toolbar-btn-box">
<div className={mediaButtonGroupCssClasses}>
<MediaControlButton action={this.handleToggleVideo}

View File

@ -55,7 +55,11 @@ browser.jar:
content/browser/loop/shared/img/video-inverse-14x14@2x.png (content/shared/img/video-inverse-14x14@2x.png)
content/browser/loop/shared/img/dropdown-inverse.png (content/shared/img/dropdown-inverse.png)
content/browser/loop/shared/img/dropdown-inverse@2x.png (content/shared/img/dropdown-inverse@2x.png)
content/browser/loop/shared/img/svg/glyph-email-16x16.svg (content/shared/img/svg/glyph-email-16x16.svg)
content/browser/loop/shared/img/svg/glyph-facebook-16x16.svg (content/shared/img/svg/glyph-facebook-16x16.svg)
content/browser/loop/shared/img/svg/glyph-help-16x16.svg (content/shared/img/svg/glyph-help-16x16.svg)
content/browser/loop/shared/img/svg/glyph-link-16x16.svg (content/shared/img/svg/glyph-link-16x16.svg)
content/browser/loop/shared/img/svg/glyph-user-16x16.svg (content/shared/img/svg/glyph-user-16x16.svg)
content/browser/loop/shared/img/svg/exit.svg (content/shared/img/svg/exit.svg)
content/browser/loop/shared/img/svg/audio.svg (content/shared/img/svg/audio.svg)
content/browser/loop/shared/img/svg/audio-hover.svg (content/shared/img/svg/audio-hover.svg)

View File

@ -387,13 +387,9 @@ var MozLoopPushHandler = {
*/
initialize: function(options = {}) {
consoleLog.info("PushHandler: initialize options = ", options);
if (Services.io.offline) {
consoleLog.warn("PushHandler: IO offline");
return false;
}
if (this._initDone) {
return true;
return;
}
this._initDone = true;
@ -411,7 +407,6 @@ var MozLoopPushHandler = {
}
this._openSocket();
return true;
},
/**

View File

@ -88,6 +88,16 @@ const ROOM_CONTEXT_ADD = {
// See LOG_LEVELS in Console.jsm. Common examples: "All", "Info", "Warn", & "Error".
const PREF_LOG_LEVEL = "loop.debug.loglevel";
const kChatboxHangupButton = {
id: "loop-hangup",
visibleWhenUndocked: false,
onCommand: function(e, chatbox) {
let window = chatbox.content.contentWindow;
let event = new window.CustomEvent("LoopHangupNow");
window.dispatchEvent(event);
}
};
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
@ -905,6 +915,8 @@ var MozLoopServiceInternal = {
let url = this.getChatURL(windowId);
Chat.registerButton(kChatboxHangupButton);
let callback = chatbox => {
// We need to use DOMContentLoaded as otherwise the injection will happen
// in about:blank and then get lost.
@ -1014,11 +1026,11 @@ var MozLoopServiceInternal = {
return null;
// It's common for unit tests to overload Chat.open.
} else if (chatboxInstance.setAttribute) {
// Set properties that influence visual appeara nce of the chatbox right
// Set properties that influence visual appearance of the chatbox right
// away to circumvent glitches.
chatboxInstance.setAttribute("dark", true);
chatboxInstance.setAttribute("customSize", "loopDefault");
chatboxInstance.parentNode.setAttribute("customSize", "loopDefault");
Chat.loadButtonSet(chatboxInstance, "minimize,swap," + kChatboxHangupButton.id);
}
return windowId;
},

View File

@ -57,9 +57,6 @@ rooms_default_room_name_template=Conversation {{conversationLabel}}
## by the user specified conversation name.
rooms_welcome_title=Welcome to {{conversationName}}
rooms_leave_button_label=Leave
rooms_list_copy_url_tooltip=Copy Link
rooms_list_delete_tooltip=Delete conversation
rooms_list_deleteConfirmation_label=Are you sure?
rooms_new_room_button_label=Start a conversation
rooms_only_occupant_label2=You're the only one here.
rooms_panel_title=Choose a conversation or start a new one

View File

@ -6,9 +6,13 @@ describe("loop.store.ConversationAppStore", function () {
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var sandbox, dispatcher;
var sandbox, activeRoomStore, dispatcher, roomUsed;
beforeEach(function() {
roomUsed = false;
activeRoomStore = {
getStoreState: function() { return { used: roomUsed }; }
};
sandbox = sinon.sandbox.create();
dispatcher = new loop.Dispatcher();
sandbox.stub(dispatcher, "dispatch");
@ -19,17 +23,52 @@ describe("loop.store.ConversationAppStore", function () {
});
describe("#constructor", function() {
it("should throw an error if the activeRoomStore is missing", function() {
expect(function() {
new loop.store.ConversationAppStore({
dispatcher: dispatcher,
mozLoop: {}
});
}).to.Throw(/activeRoomStore/);
});
it("should throw an error if the dispatcher is missing", function() {
expect(function() {
new loop.store.ConversationAppStore({mozLoop: {}});
new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
mozLoop: {}
});
}).to.Throw(/dispatcher/);
});
it("should throw an error if mozLoop is missing", function() {
expect(function() {
new loop.store.ConversationAppStore({dispatcher: dispatcher});
new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
dispatcher: dispatcher
});
}).to.Throw(/mozLoop/);
});
it("should start listening to events on the window object", function() {
var fakeWindow = {
addEventListener: sinon.stub()
};
var store = new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
dispatcher: dispatcher,
mozLoop: { getLoopPref: function() {} },
rootObject: fakeWindow
});
var eventNames = Object.getOwnPropertyNames(store._eventHandlers);
sinon.assert.callCount(fakeWindow.addEventListener, eventNames.length);
eventNames.forEach(function(eventName) {
sinon.assert.calledWith(fakeWindow.addEventListener, eventName,
store._eventHandlers[eventName]);
});
});
});
describe("#getWindowData", function() {
@ -61,6 +100,7 @@ describe("loop.store.ConversationAppStore", function () {
};
store = new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
dispatcher: dispatcher,
mozLoop: fakeMozLoop
});
@ -73,9 +113,7 @@ describe("loop.store.ConversationAppStore", function () {
it("should fetch the window type from the mozLoop API", function() {
store.getWindowData(new sharedActions.GetWindowData(fakeGetWindowData));
expect(store.getStoreState()).eql({
windowType: "incoming"
});
expect(store.getStoreState().windowType).eql("incoming");
});
it("should have the feedback period in initial state", function() {
@ -135,4 +173,118 @@ describe("loop.store.ConversationAppStore", function () {
}, fakeWindowData)));
});
});
describe("Window object event handlers", function() {
var store, fakeWindow;
beforeEach(function() {
fakeWindow = {
addEventListener: sinon.stub(),
removeEventListener: sinon.stub()
};
store = new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
dispatcher: dispatcher,
mozLoop: { getLoopPref: function() {} },
rootObject: fakeWindow
});
});
describe("#unloadHandler", function() {
it("should dispatch a 'WindowUnload' action when invoked", function() {
store.unloadHandler();
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch, new sharedActions.WindowUnload());
});
it("should remove all registered event handlers from the window object", function() {
var eventHandlers = store._eventHandlers;
var eventNames = Object.getOwnPropertyNames(eventHandlers);
store.unloadHandler();
sinon.assert.callCount(fakeWindow.removeEventListener, eventNames.length);
expect(store._eventHandlers).to.eql(null);
eventNames.forEach(function(eventName) {
sinon.assert.calledWith(fakeWindow.removeEventListener, eventName,
eventHandlers[eventName]);
});
});
});
describe("#LoopHangupNowHandler", function() {
beforeEach(function() {
sandbox.stub(loop.shared.mixins.WindowCloseMixin, "closeWindow");
});
it("should dispatch the correct action for windowType 'incoming'", function() {
store.setStoreState({ windowType: "incoming" });
store.LoopHangupNowHandler();
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch, new sharedActions.HangupCall());
sinon.assert.notCalled(loop.shared.mixins.WindowCloseMixin.closeWindow);
});
it("should dispatch the correct action for windowType 'outgoing'", function() {
store.setStoreState({ windowType: "outgoing" });
store.LoopHangupNowHandler();
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch, new sharedActions.HangupCall());
sinon.assert.notCalled(loop.shared.mixins.WindowCloseMixin.closeWindow);
});
it("should dispatch the correct action when a room was used", function() {
store.setStoreState({ windowType: "room" });
roomUsed = true;
store.LoopHangupNowHandler();
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch, new sharedActions.LeaveRoom());
sinon.assert.notCalled(loop.shared.mixins.WindowCloseMixin.closeWindow);
});
it("should close the window when a room was not used", function() {
store.setStoreState({ windowType: "room" });
store.LoopHangupNowHandler();
sinon.assert.notCalled(dispatcher.dispatch);
sinon.assert.calledOnce(loop.shared.mixins.WindowCloseMixin.closeWindow);
});
it("should close the window for all other window types", function() {
store.setStoreState({ windowType: "foobar" });
store.LoopHangupNowHandler();
sinon.assert.notCalled(dispatcher.dispatch);
sinon.assert.calledOnce(loop.shared.mixins.WindowCloseMixin.closeWindow);
});
});
describe("#socialFrameAttachedHandler", function() {
it("should update the store correctly to reflect the attached state", function() {
store.setStoreState({ chatWindowDetached: true });
store.socialFrameAttachedHandler();
expect(store.getStoreState().chatWindowDetached).to.eql(false);
});
});
describe("#socialFrameDetachedHandler", function() {
it("should update the store correctly to reflect the detached state", function() {
store.socialFrameDetachedHandler();
expect(store.getStoreState().chatWindowDetached).to.eql(true);
});
});
});
});

View File

@ -528,6 +528,7 @@ describe("loop.conversationViews", function () {
describe("OngoingConversationView", function() {
function mountTestComponent(extraProps) {
var props = _.extend({
chatWindowDetached: false,
conversationStore: conversationStore,
dispatcher: dispatcher,
mozLoop: {},
@ -573,18 +574,6 @@ describe("loop.conversationViews", function () {
expect(view.getDOMNode().querySelector(".local video")).not.eql(null);
});
it("should dispatch a hangupCall action when the hangup button is pressed",
function() {
view = mountTestComponent();
var hangupBtn = view.getDOMNode().querySelector(".btn-hangup");
React.addons.TestUtils.Simulate.click(hangupBtn);
sinon.assert.calledWithMatch(dispatcher.dispatch,
sinon.match.hasOwn("name", "hangupCall"));
});
it("should dispatch a setMute action when the audio mute button is pressed",
function() {
view = mountTestComponent({
@ -648,6 +637,7 @@ describe("loop.conversationViews", function () {
function mountTestComponent() {
return TestUtils.renderIntoDocument(
React.createElement(loop.conversationViews.CallControllerView, {
chatWindowDetached: false,
dispatcher: dispatcher,
mozLoop: fakeMozLoop,
onCallTerminated: onCallTerminatedStub

View File

@ -177,6 +177,7 @@ describe("loop.conversation", function() {
activeRoomStore: activeRoomStore
});
conversationAppStore = new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop
});

View File

@ -14,7 +14,7 @@ describe("loop.roomViews", function () {
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var sandbox, dispatcher, roomStore, activeRoomStore, view;
var fakeWindow, fakeMozLoop, fakeContextURL;
var clock, fakeWindow, fakeMozLoop, fakeContextURL;
var favicon = "data:image/x-icon;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
beforeEach(function() {
@ -48,6 +48,8 @@ describe("loop.roomViews", function () {
setLoopPref: sandbox.stub()
};
clock = sandbox.useFakeTimers();
fakeWindow = {
close: sinon.stub(),
document: {},
@ -92,6 +94,7 @@ describe("loop.roomViews", function () {
afterEach(function() {
sandbox.restore();
clock.restore();
loop.shared.mixins.setRootObject(window);
view = null;
});
@ -250,82 +253,50 @@ describe("loop.roomViews", function () {
});
it("should dispatch a CopyRoomUrl action when the copy button is pressed", function() {
var copyBtn = view.getDOMNode().querySelector(".btn-copy");
React.addons.TestUtils.Simulate.click(copyBtn);
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWith(dispatcher.dispatch, new sharedActions.CopyRoomUrl({
roomUrl: "http://invalid",
from: "conversation"
}));
});
it("should change the text when the url has been copied", function() {
var copyBtn = view.getDOMNode().querySelector(".btn-copy");
React.addons.TestUtils.Simulate.click(copyBtn);
// copied_url_button is the l10n string.
expect(copyBtn.textContent).eql("copied_url_button");
});
});
describe("Share button", function() {
it("should dispatch a AddSocialShareProvider action when the share button is clicked", function() {
view = mountTestComponent();
var shareBtn = view.getDOMNode().querySelector(".btn-share");
React.addons.TestUtils.Simulate.click(shareBtn);
var copyBtn = view.getDOMNode().querySelector(".btn-copy");
React.addons.TestUtils.Simulate.click(copyBtn);
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWith(dispatcher.dispatch,
new sharedActions.AddSocialShareProvider());
sinon.assert.calledWith(dispatcher.dispatch, new sharedActions.CopyRoomUrl({
roomUrl: "http://invalid",
from: "conversation"
}));
});
it("should toggle the share dropdown when the share button is clicked", function() {
view = mountTestComponent({
socialShareProviders: [{
name: "foo",
origin: "https://foo",
iconURL: "http://example.com/foo.png"
}]
});
it("should change the text when the url has been copied", function() {
var copyBtn = view.getDOMNode().querySelector(".btn-copy");
React.addons.TestUtils.Simulate.click(copyBtn);
var shareBtn = view.getDOMNode().querySelector(".btn-share");
expect(copyBtn.textContent).eql("invite_copied_link_button");
});
React.addons.TestUtils.Simulate.click(shareBtn);
it("should keep the text for a while after the url has been copied", function() {
var copyBtn = view.getDOMNode().querySelector(".btn-copy");
React.addons.TestUtils.Simulate.click(copyBtn);
clock.tick(loop.roomViews.DesktopRoomInvitationView.TRIGGERED_RESET_DELAY / 2);
expect(view.state.showMenu).to.eql(true);
expect(view.refs.menu.props.show).to.eql(true);
expect(copyBtn.textContent).eql("invite_copied_link_button");
});
it("should reset the text a bit after the url has been copied", function() {
var copyBtn = view.getDOMNode().querySelector(".btn-copy");
React.addons.TestUtils.Simulate.click(copyBtn);
clock.tick(loop.roomViews.DesktopRoomInvitationView.TRIGGERED_RESET_DELAY);
expect(copyBtn.textContent).eql("invite_copy_link_button");
});
it("should reset the text after the url has been copied then mouse over another button", function() {
var copyBtn = view.getDOMNode().querySelector(".btn-copy");
React.addons.TestUtils.Simulate.click(copyBtn);
var emailBtn = view.getDOMNode().querySelector(".btn-email");
React.addons.TestUtils.Simulate.mouseOver(emailBtn);
expect(copyBtn.textContent).eql("invite_copy_link_button");
});
});
describe("Edit Context", function() {
it("should show the 'Add some context' link", function() {
view = mountTestComponent();
expect(view.getDOMNode().querySelector(
".room-invitation-addcontext")).to.not.eql(null);
});
it("should call a callback when the link is clicked", function() {
var onAddContextClick = sinon.stub();
view = mountTestComponent({
onAddContextClick: onAddContextClick
});
var node = view.getDOMNode();
expect(node.querySelector(".room-context")).to.eql(null);
var addLink = node.querySelector(".room-invitation-addcontext");
React.addons.TestUtils.Simulate.click(addLink);
sinon.assert.calledOnce(onAddContextClick);
});
it("should show the edit context view", function() {
view = mountTestComponent({
showEditContext: true
@ -351,6 +322,7 @@ describe("loop.roomViews", function () {
function mountTestComponent(props) {
props = _.extend({
chatWindowDetached: false,
dispatcher: dispatcher,
roomStore: roomStore,
mozLoop: fakeMozLoop,
@ -429,32 +401,6 @@ describe("loop.roomViews", function () {
sinon.match.hasOwn("name", "setMute"));
});
it("should dispatch a `LeaveRoom` action when the hangup button is pressed and the room has been used", function() {
view = mountTestComponent();
view.setState({used: true});
var hangupBtn = view.getDOMNode().querySelector(".btn-hangup");
React.addons.TestUtils.Simulate.click(hangupBtn);
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.LeaveRoom());
});
it("should close the window when the hangup button is pressed and the room has not been used", function() {
view = mountTestComponent();
view.setState({used: false});
var hangupBtn = view.getDOMNode().querySelector(".btn-hangup");
React.addons.TestUtils.Simulate.click(hangupBtn);
sinon.assert.calledOnce(fakeWindow.close);
});
describe("#componentWillUpdate", function() {
function expectActionDispatched(component) {
sinon.assert.calledOnce(dispatcher.dispatch);

View File

@ -503,7 +503,7 @@ describe("loop.shared.views", function() {
.eql("foo");
});
it("should accept a enableHangup optional prop", function() {
it("should accept an enableHangup optional prop", function() {
var comp = mountTestComponent({
enableHangup: false,
hangup: hangup,
@ -514,6 +514,16 @@ describe("loop.shared.views", function() {
.eql(true);
});
it("should accept a showHangup optional prop", function() {
var comp = mountTestComponent({
showHangup: false,
hangup: hangup,
publishStream: publishStream
});
expect(comp.getDOMNode().querySelector(".btn-hangup-entry")).to.eql(null);
});
it("should hangup when hangup button is clicked", function() {
var comp = mountTestComponent({
hangup: hangup,

View File

@ -7,13 +7,6 @@ var dummyCallback = () => {};
var mockWebSocket = new MockWebSocketChannel();
var pushServerRequestCount = 0;
add_test(function test_initalize_offline() {
Services.io.offline = true;
do_check_false(MozLoopPushHandler.initialize());
Services.io.offline = false;
run_next_test();
});
add_test(function test_initalize_missing_chanid() {
Assert.throws(() => MozLoopPushHandler.register(null, dummyCallback, dummyCallback));
run_next_test();
@ -30,7 +23,7 @@ add_test(function test_initalize_missing_notifycallback() {
});
add_test(function test_initalize_websocket() {
do_check_true(MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket}));
MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket});
MozLoopPushHandler.register(
"chan-1",
function(err, url, id) {
@ -192,7 +185,7 @@ add_test(function test_retry_pushurl() {
}
});
do_check_true(MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket}));
MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket});
});
function run_test() {

View File

@ -1222,6 +1222,7 @@
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
audio: { enabled: true, visible: true},
chatWindowDetached: false,
conversationStore: conversationStores[0],
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
@ -1240,6 +1241,7 @@
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
audio: { enabled: true, visible: true},
chatWindowDetached: false,
conversationStore: conversationStores[1],
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
@ -1257,6 +1259,7 @@
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
audio: { enabled: true, visible: true},
chatWindowDetached: false,
conversationStore: conversationStores[2],
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
@ -1275,6 +1278,7 @@
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
audio: { enabled: true, visible: true},
chatWindowDetached: false,
conversationStore: conversationStores[3],
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
@ -1293,6 +1297,7 @@
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
audio: { enabled: true, visible: true},
chatWindowDetached: false,
conversationStore: conversationStores[4],
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
@ -1388,6 +1393,7 @@
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
@ -1423,6 +1429,7 @@
scrollbars to appear */
React.createElement("div", {className: "fx-embedded overflow-hidden"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
@ -1440,6 +1447,7 @@
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
@ -1457,6 +1465,7 @@
width: 602},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
@ -1474,6 +1483,7 @@
width: 646},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
@ -1491,6 +1501,7 @@
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
onCallTerminated: function(){},
@ -1506,6 +1517,7 @@
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,

View File

@ -1222,6 +1222,7 @@
<div className="fx-embedded">
<OngoingConversationView
audio={{ enabled: true, visible: true }}
chatWindowDetached={false}
conversationStore={conversationStores[0]}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
@ -1240,6 +1241,7 @@
<div className="fx-embedded">
<OngoingConversationView
audio={{ enabled: true, visible: true }}
chatWindowDetached={false}
conversationStore={conversationStores[1]}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
@ -1257,6 +1259,7 @@
<div className="fx-embedded">
<OngoingConversationView
audio={{ enabled: true, visible: true }}
chatWindowDetached={false}
conversationStore={conversationStores[2]}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
@ -1275,6 +1278,7 @@
<div className="fx-embedded">
<OngoingConversationView
audio={{ enabled: true, visible: true }}
chatWindowDetached={false}
conversationStore={conversationStores[3]}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
@ -1293,6 +1297,7 @@
<div className="fx-embedded">
<OngoingConversationView
audio={{ enabled: true, visible: true }}
chatWindowDetached={false}
conversationStore={conversationStores[4]}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
@ -1388,6 +1393,7 @@
width={298}>
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
@ -1423,6 +1429,7 @@
scrollbars to appear */}
<div className="fx-embedded overflow-hidden">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
@ -1440,6 +1447,7 @@
width={298}>
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
@ -1457,6 +1465,7 @@
width={602}>
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
@ -1474,6 +1483,7 @@
width={646}>
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
@ -1491,6 +1501,7 @@
width={298}>
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
onCallTerminated={function(){}}
@ -1506,6 +1517,7 @@
width={298} >
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}

View File

@ -18,7 +18,6 @@ skip-if = os != "win" # This test tests the windows-specific app selection dialo
[browser_connection.js]
[browser_connection_bug388287.js]
[browser_cookies_exceptions.js]
skip-if = os == "linux" # See bug 1209521 for re-enabling on Linux
[browser_healthreport.js]
skip-if = !healthreport || (os == 'linux' && debug)
[browser_permissions.js]

View File

@ -3,6 +3,7 @@
function test() {
waitForExplicitFinish();
requestLongerTimeout(2);
testRunner.runTests();
}

View File

@ -67,7 +67,7 @@ function test() {
function checkSearchURL(event) {
is(event.originalTarget.URL,
"http://mochi.test:8888/browser/browser/components/search/test/?test=test+search&ie=utf-8&client=app&channel=contextsearch",
"http://mochi.test:8888/browser/browser/components/search/test/?test=test+search&ie=utf-8&channel=contextsearch",
"Checking context menu search URL");
// Remove the tab opened by the search
gBrowser.removeCurrentTab();

View File

@ -7,7 +7,6 @@
<Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/">
<Param name="test" value="{searchTerms}"/>
<Param name="ie" value="utf-8"/>
<MozParam name="client" condition="defaultEngine" trueValue="app-default" falseValue="app"/>
<MozParam name="channel" condition="purpose" purpose="keyword" value="keywordsearch"/>
<MozParam name="channel" condition="purpose" purpose="contextmenu" value="contextsearch"/>
</Url>

View File

@ -776,6 +776,24 @@ e10s.accessibilityNotice.disableAndRestart.accesskey = R
e10s.accessibilityNotice.dontDisable.label = Don't Disable
e10s.accessibilityNotice.dontDisable.accesskey = D
# LOCALIZATION NOTE (usercontext.personal.label,
# usercontext.work.label,
# usercontext.shopping.label,
# usercontext.banking.label):
# These strings specify the four default contexts included in support of the
# Contextual Identity / Containers project. Each context is meant to represent
# the context that the user is in when interacting with the site. Different
# contexts will store cookies and other information from those sites in
# different, isolated locations. You can enable the feature by typing
# about:config in the URL bar and changing privacy.userContext.enabled to true.
# Once enabled, you can open a new tab in a specific context by clicking
# File > New Container Tab > (1 of 4 contexts). Once opened, you will see these
# strings on the right-hand side of the URL bar.
usercontext.personal.label = Personal
usercontext.work.label = Work
usercontext.shopping.label = Shopping
usercontext.banking.label = Banking
muteTab.label = Mute Tab
muteTab.accesskey = M
unmuteTab.label = Unmute Tab

View File

@ -30,21 +30,14 @@ first_time_experience_button_label=Get Started
## user to create his or her first conversation.
first_time_experience_subheading=Join the conversation
invite_header_text=Invite someone to join you.
invite_header_text2=Invite a friend to join you
## LOCALIZATION_NOTE(invite_facebook_button, invite_facebook_triggered,
## invite_contacts_button, invite_contacts_triggered, invite_copy_button,
## invite_copy_triggered, invite_email_button, invite_email_triggered): These
## button/triggered pairs are labels under an iconic button that switch to the
## triggered text when clicked/activated.
invite_facebook_button=share on Facebook
invite_facebook_triggered=shared!
invite_contacts_button=share with contacts
invite_contacts_triggered=shared!
invite_copy_button=copy link
invite_copy_triggered=copied!
invite_email_button=email link
invite_email_triggered=emailed!
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
invite_copy_link_button=Copy Link
invite_copied_link_button=Copied!
invite_email_link_button=Email Link
invite_facebook_button2=Share on Facebook
# Status text
display_name_guest=Guest
@ -85,8 +78,12 @@ share_tweet=Join me for a video conversation on {{clientShortname2}}!
share_button3=Share Link
share_add_service_button=Add a Service
copy_url_button2=Copy Link
copied_url_button=Copied!
## LOCALIZATION NOTE (copy_link_menuitem, email_link_menuitem, delete_conversation_menuitem):
## These menu items are displayed from a panel's context menu for a conversation.
copy_link_menuitem=Copy Link
email_link_menuitem=Email Link
delete_conversation_menuitem=Delete conversation
panel_footer_signin_or_signup_link=Sign In or Sign Up
@ -291,10 +288,9 @@ contact_offline_title=This person is not online
## when the call didn't go through.
call_timeout_notification_text=Your call did not go through.
## LOCALIZATION NOTE (retry_call_button, cancel_button, email_link_button):
## LOCALIZATION NOTE (retry_call_button, cancel_button):
## These buttons are displayed when a call has failed.
retry_call_button=Retry
email_link_button=Email Link
cancel_button=Cancel
rejoin_button=Rejoin Conversation
@ -334,12 +330,9 @@ tour_label=Tour
## will be replaced by a number. For example "Conversation 1" or "Conversation 12".
rooms_default_room_name_template=Conversation {{conversationLabel}}
rooms_leave_button_label=Leave
rooms_list_copy_url_tooltip=Copy Link
## LOCALIZATION NOTE (rooms_list_recent_conversations): String is in all caps
## for emphasis reasons, it is a heading. Proceed as appropriate for locale.
rooms_list_recent_conversations=RECENT CONVERSATIONS
rooms_list_delete_tooltip=Delete conversation
rooms_list_deleteConfirmation_label=Are you sure?
rooms_change_failed_label=Conversation cannot be updated
rooms_new_room_button_label=Start a conversation
rooms_panel_title=Choose a conversation or start a new one
@ -370,18 +363,10 @@ context_inroom_header=Let's Talk About…
# to consider this as a stand-alone title. See example screenshot:
# https://bug1115342.bugzilla.mozilla.org/attachment.cgi?id=8563677
context_inroom_label2=Let's Talk About:
## LOCALIZATION_NOTE (context_edit_activate_label): {{title}} will be replaced
## by the title of the active tab, also known as the title of an HTML document.
## The quotes around the title are intentional.
context_edit_activate_label=Talk about "{{title}}"
context_edit_name_placeholder=Conversation Name
context_edit_comments_placeholder=Comments
context_add_some_label=Add some context
context_show_tooltip=Show Context
context_cancel_label=Cancel
context_done_label=Done
context_link_modified=This link was modified.
context_learn_more_link_label=Learn more.
conversation_settings_menu_edit_context=Edit Context
conversation_settings_menu_hide_context=Hide Context

View File

@ -5,7 +5,7 @@
// A module for working with chat windows.
this.EXPORTED_SYMBOLS = ["Chat"];
this.EXPORTED_SYMBOLS = ["Chat", "kDefaultButtonSet"];
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
@ -15,6 +15,11 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kDefaultButtonSet = new Set(["minimize", "swap", "close"]);
const kHiddenDefaultButtons = new Set(["minimize", "close"]);
let gCustomButtons = new Map();
// A couple of internal helper function.
function isWindowChromeless(win) {
// XXX - stolen from browser-social.js, but there's no obvious place to
@ -205,4 +210,100 @@ var Chat = {
}
return topMost;
},
}
/**
* Adds a button to the collection of custom buttons that can be added to the
* titlebar of a chatbox.
* For the button to be visible, `Chat#loadButtonSet` has to be called with
* the new buttons' ID in the buttonSet argument.
*
* @param {Object} button Button object that may contain the following fields:
* - {String} id Button identifier.
* - {Function} [onBuild] Function that returns a valid DOM node to
* represent the button.
* - {Function} [onCommand] Callback function that is invoked when the DOM
* node is clicked.
*/
registerButton: function(button) {
if (gCustomButtons.has(button.id))
return;
gCustomButtons.set(button.id, button);
},
/**
* Load a set of predefined buttons in a chatbox' titlebar.
*
* @param {XULDOMNode} chatbox Chatbox XUL element.
* @param {Set|String} buttonSet Set of buttons to show in the titlebar. This
* may be a comma-separated string or a predefined
* set object.
*/
loadButtonSet: function(chatbox, buttonSet = kDefaultButtonSet) {
if (!buttonSet)
return;
// When the buttonSet is coming from an XML attribute, it will be a string.
if (typeof buttonSet == "string") {
buttonSet = [for (button of buttonSet.split(",")) button.trim()];
}
// Make sure to keep the current set around.
chatbox.setAttribute("buttonSet", [...buttonSet].join(","));
let isUndocked = !chatbox.chatbar;
let document = chatbox.ownerDocument;
let titlebarNode = document.getAnonymousElementByAttribute(chatbox, "class",
"chat-titlebar");
let buttonsSeen = new Set();
for (let buttonId of buttonSet) {
buttonId = buttonId.trim();
buttonsSeen.add(buttonId);
let nodes, node;
if (kDefaultButtonSet.has(buttonId)) {
node = document.getAnonymousElementByAttribute(chatbox, "anonid", buttonId);
if (!node)
continue;
node.hidden = isUndocked && kHiddenDefaultButtons.has(buttonId) ? true : false;
} else if (gCustomButtons.has(buttonId)) {
let button = gCustomButtons.get(buttonId);
let buttonClass = "chat-" + buttonId;
// Custom buttons are not defined in the chatbox binding, thus not
// anonymous elements.
nodes = titlebarNode.getElementsByClassName(buttonClass);
node = nodes && nodes.length ? nodes[0] : null;
if (!node) {
// Allow custom buttons to build their own button node.
if (button.onBuild) {
node = button.onBuild(chatbox);
} else {
// We can also build a normal toolbarbutton to insert.
node = document.createElementNS(kNSXUL, "toolbarbutton");
node.classList.add(buttonClass);
node.classList.add("chat-toolbarbutton");
}
if (button.onCommand) {
node.addEventListener("command", e => {
button.onCommand(e, chatbox);
});
}
titlebarNode.appendChild(node);
}
// When the chat is undocked and the button wants to be visible then, it
// will be.
node.hidden = isUndocked && !button.visibleWhenUndocked;
} else {
Cu.reportError("Chatbox button '" + buttonId + "' could not be found!\n");
}
}
// Hide any button that is part of the default set, but not of the current set.
for (let button of kDefaultButtonSet) {
if (!buttonsSeen.has(button))
document.getAnonymousElementByAttribute(chatbox, "anonid", button).hidden = true;
}
}
};

View File

@ -1837,39 +1837,6 @@ toolbarbutton.chevron > .toolbarbutton-icon {
%include ../shared/social/chat.inc.css
.chat-titlebar {
background-color: #d9d9d9;
background-image: linear-gradient(@toolbarHighlight@, transparent);
}
.chat-titlebar[selected] {
background-color: #f0f0f0;
}
.chatbar-button {
-moz-appearance: none;
background-color: #d9d9d9;
background-image: linear-gradient(@toolbarHighlight@, transparent);
}
.chatbar-button > .toolbarbutton-icon {
-moz-margin-end: 0;
}
.chatbar-button:hover,
.chatbar-button[open="true"] {
background-color: #f0f0f0;
}
.chatbar-button[activity] {
background-image: radial-gradient(circle farthest-corner at center 3px, rgb(233,242,252) 3%, rgba(172,206,255,0.75) 40%, rgba(87,151,201,0.5) 80%, transparent);
}
chatbox {
border-top-left-radius: 2.5px;
border-top-right-radius: 2.5px;
}
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css

View File

@ -56,6 +56,7 @@ browser.jar:
skin/classic/browser/Toolbar.png
skin/classic/browser/Toolbar-inverted.png
skin/classic/browser/Toolbar-small.png
skin/classic/browser/webRTC-indicator.css
skin/classic/browser/loop/menuPanel.png (loop/menuPanel.png)
skin/classic/browser/loop/menuPanel@2x.png (loop/menuPanel@2x.png)
skin/classic/browser/loop/toolbar.png (loop/toolbar.png)

View File

@ -3438,43 +3438,6 @@ notification[value="loop-sharing-notification"] .messageImage {
%include ../shared/social/chat.inc.css
.chat-titlebar {
background-color: #d9d9d9;
background-image: linear-gradient(rgba(255,255,255,.43), transparent);
}
.chat-titlebar[selected] {
background-color: #f0f0f0;
}
.chatbar-button {
background-color: #d9d9d9;
background-image: linear-gradient(rgba(255,255,255,.43), transparent);
border-top-left-radius: @toolbarbuttonCornerRadius@;
border-top-right-radius: @toolbarbuttonCornerRadius@;
}
.chatbar-button:hover,
.chatbar-button[open="true"] {
background-color: #f0f0f0;
}
.chatbar-button[activity]:not([open]) {
background-image: radial-gradient(circle farthest-corner at center 2px, rgb(254,254,255) 3%, rgba(210,235,255,0.9) 12%, rgba(148,205,253,0.6) 30%, rgba(148,205,253,0.2) 70%);
}
chatbox {
border-top-left-radius: @toolbarbuttonCornerRadius@;
border-top-right-radius: @toolbarbuttonCornerRadius@;
}
window > chatbox {
border-top-left-radius: @toolbarbuttonCornerRadius@;
border-top-right-radius: @toolbarbuttonCornerRadius@;
border-bottom-left-radius: @toolbarbuttonCornerRadius@;
border-bottom-right-radius: @toolbarbuttonCornerRadius@;
}
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css

View File

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%endif
#fullscreen-warning {
html|*#fullscreen-warning {
align-items: center;
background: rgba(45, 62, 72, 0.9);
border: 2px solid #fafafa;
@ -14,39 +14,38 @@
font: message-box;
}
#fullscreen-warning::before {
html|*#fullscreen-warning::before {
margin: 0;
width: 24px; height: 24px;
}
#fullscreen-warning.verifiedIdentity::before,
#fullscreen-warning.verifiedDomain::before {
html|*#fullscreen-warning.verifiedIdentity::before,
html|*#fullscreen-warning.verifiedDomain::before {
content: url("chrome://browser/skin/fullscreen/secure.svg");
}
#fullscreen-warning.unknownIdentity::before {
html|*#fullscreen-warning.unknownIdentity::before {
content: url("chrome://browser/skin/fullscreen/insecure.svg");
}
#fullscreen-domain-text,
#fullscreen-generic-text {
html|*#fullscreen-domain-text,
html|*#fullscreen-generic-text {
font-size: 21px;
font-weight: lighter;
color: #fafafa;
margin: 0 16px;
}
#fullscreen-domain {
html|*#fullscreen-domain {
font-weight: bold;
margin: 0;
}
#fullscreen-exit-button {
padding: 0 30px;
html|*#fullscreen-exit-button {
padding: 5px 30px;
font: message-box;
font-size: 14px;
font-weight: lighter;
margin: 0;
height: 28px;
box-sizing: content-box;
}

View File

@ -145,7 +145,6 @@
skin/classic/browser/webRTC-shareScreen-64@2x.png (../shared/webrtc/webRTC-shareScreen-64@2x.png)
skin/classic/browser/webRTC-sharingScreen-16.png (../shared/webrtc/webRTC-sharingScreen-16.png)
skin/classic/browser/webRTC-sharingScreen-16@2x.png (../shared/webrtc/webRTC-sharingScreen-16@2x.png)
skin/classic/browser/webRTC-indicator.css (../shared/webrtc/indicator.css)
skin/classic/browser/webRTC-camera-white-16.png (../shared/webrtc/camera-white-16.png)
skin/classic/browser/webRTC-microphone-white-16.png (../shared/webrtc/microphone-white-16.png)
skin/classic/browser/webRTC-screen-white-16.png (../shared/webrtc/screen-white-16.png)

View File

@ -8,28 +8,42 @@
display: none;
}
use {
fill: #c1c1c1;
fill: #666;
}
use[id$="-hover"] {
fill: #4a4a4a;
}
use[id$="-active"] {
fill: #c1c1c1;
fill: #4a4a4a;
}
use[id$="-disabled"] {
fill: #c1c1c1;
fill: #666;
}
use[id$="-white"] {
fill: #fff;
}
</style>
<defs>
<polygon id="close-shape" points="10,1.717 8.336,0.049 5.024,3.369 1.663,0 0,1.668 3.36,5.037 0.098,8.307 1.762,9.975 5.025,6.705 8.311,10 9.975,8.332 6.688,5.037"/>
<path id="dropdown-shape" fill-rule="evenodd" d="M9,3L4.984,7L1,3H9z"/>
<polygon id="expand-shape" points="10,0 4.838,0 6.506,1.669 0,8.175 1.825,10 8.331,3.494 10,5.162"/>
<rect id="minimize-shape" y="3.6" width="10" height="2.8"/>
<g id="expand-shape">
<path fill-rule="evenodd" d="M9.429,7.072v2.143c0,0.531-0.188,0.985-0.566,1.363c-0.377,0.377-0.832,0.565-1.363,0.565H1.929 c-0.531,0-0.986-0.188-1.363-0.565C0.188,10.2,0,9.746,0,9.214V3.643c0-0.531,0.188-0.985,0.566-1.362 c0.377-0.378,0.832-0.566,1.363-0.566h4.714c0.062,0,0.114,0.021,0.154,0.061s0.06,0.092,0.06,0.154v0.428 c0,0.063-0.02,0.114-0.06,0.154S6.705,2.572,6.643,2.572H1.929c-0.295,0-0.547,0.104-0.757,0.314S0.857,3.348,0.857,3.643v5.571 c0,0.295,0.105,0.547,0.315,0.757s0.462,0.314,0.757,0.314H7.5c0.294,0,0.547-0.104,0.757-0.314 c0.209-0.21,0.314-0.462,0.314-0.757V7.072c0-0.062,0.02-0.114,0.061-0.154c0.04-0.04,0.091-0.061,0.154-0.061h0.428 c0.062,0,0.114,0.021,0.154,0.061S9.429,7.009,9.429,7.072z"/>
<path fill-rule="evenodd" d="M7.07,5.82L6.179,4.93C6.127,4.878,6.101,4.818,6.101,4.75s0.026-0.128,0.079-0.18l2.594-2.594L7.648,0.852 C7.549,0.753,7.5,0.636,7.5,0.5s0.049-0.252,0.148-0.351S7.864,0,8,0h3.5c0.136,0,0.252,0.05,0.351,0.149S12,0.365,12,0.5V4 c0,0.136-0.05,0.253-0.149,0.351C11.752,4.451,11.635,4.5,11.5,4.5c-0.136,0-0.253-0.05-0.352-0.149l-1.124-1.125L7.429,5.82 c-0.052,0.052-0.112,0.079-0.18,0.079"/>
</g>
<rect id="minimize-shape" y="7.5" width="10" height="2.2"/>
<path id="exit-shape" fill-rule="evenodd" d="M5.01905144,3.00017279 C5.01277908,3.00005776 5.0064926,3 5.00019251,3 L1.99980749,3 C1.44371665,3 1,3.44762906 1,3.99980749 L1,7.00019251 C1,7.55628335 1.44762906,8 1.99980749,8 L5.00019251,8 C5.00649341,8 5.01277988,7.99994253 5.01905144,7.99982809 L5.01905144,8.5391818 C5.01905144,10.078915 5.37554713,10.2645548 5.81530684,9.9314625 L10.8239665,6.13769619 C11.2653143,5.80340108 11.2637262,5.26455476 10.8239665,4.93146254 L5.81530684,1.13769619 C5.37395904,0.80340108 5.01905144,0.98023404 5.01905144,1.52997693 L5.01905144,3.00017279 Z M-1,1 L4,1 L4,2 L0,2 L0,9 L4,9 L4,10.0100024 L-1,10.0100021 L-1,1 Z" />
</defs>
<use id="close" xlink:href="#close-shape"/>
<use id="close-active" xlink:href="#close-shape"/>
<use id="close-disabled" xlink:href="#close-shape"/>
<use id="close-hover" xlink:href="#close-shape"/>
<use id="exit-white" xlink:href="#exit-shape"/>
<use id="expand" xlink:href="#expand-shape"/>
<use id="expand-active" xlink:href="#expand-shape"/>
<use id="expand-disabled" xlink:href="#expand-shape"/>
<use id="expand-hover" xlink:href="#expand-shape"/>
<use id="minimize" xlink:href="#minimize-shape"/>
<use id="minimize-active" xlink:href="#minimize-shape"/>
<use id="minimize-disabled" xlink:href="#minimize-shape"/>
<use id="minimize-hover" xlink:href="#minimize-shape"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -55,14 +55,6 @@
background: none;
}
.chat-toolbarbutton:hover {
background-color: rgba(255,255,255,.35);
}
.chat-toolbarbutton:hover:active {
background-color: rgba(255,255,255,.5);
}
.chat-toolbarbutton > .toolbarbutton-text {
display: none;
}
@ -76,7 +68,11 @@
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#close");
}
.chat-close-button:-moz-any(:hover,:hover:active) {
.chat-close-button:hover {
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#close-hover");
}
.chat-close-button:hover:active {
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#close-active");
}
@ -84,7 +80,11 @@
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#minimize");
}
.chat-minimize-button:-moz-any(:hover,:hover:active) {
.chat-minimize-button:hover {
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#minimize-hover");
}
:hover,:hover:active) {
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#minimize-active");
}
@ -93,7 +93,11 @@
transform: rotate(180deg);
}
.chat-swap-button:-moz-any(:hover,:hover:active) {
.chat-swap-button:hover {
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#expand-hover");
}
.chat-swap-button:hover:active {
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#expand-active");
}
@ -101,22 +105,46 @@ chatbar > chatbox > .chat-titlebar > .chat-swap-button {
transform: none;
}
.chat-loop-hangup {
list-style-image: url("chrome://browser/skin/social/chat-icons.svg#exit-white");
background-color: #d13f1a;
border: 1px solid #d13f1a;
border-top-right-radius: 4px;
width: 32px;
height: 26px;
margin-top: -6px;
margin-bottom: -5px;
-moz-margin-start: 6px;
-moz-margin-end: -5px;
}
.chat-toolbarbutton.chat-loop-hangup:-moz-any(:hover,:hover:active) {
background-color: #ef6745;
border-color: #ef6745;
}
.chat-title {
font-weight: bold;
color: black;
color: #666;
text-shadow: none;
cursor: inherit;
}
.chat-titlebar {
height: 30px;
min-height: 30px;
height: 26px;
min-height: 26px;
width: 100%;
margin: 0;
padding: 7px 6px;
border: none;
border-bottom: 1px solid #ccc;
padding: 5px 4px;
border: 1px solid #ebebeb;
border-bottom: 0;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
cursor: pointer;
background-color: #ebebeb;
}
.chat-titlebar[selected] {
background-color: #f0f0f0;
}
.chat-titlebar > .notification-anchor-icon {
@ -135,18 +163,6 @@ chatbar > chatbox > .chat-titlebar > .chat-swap-button {
background-position: 0 -10px;
}
chatbox[dark=true] > .chat-titlebar,
chatbox[dark=true] > .chat-titlebar[selected] {
border-bottom: none;
background-color: #000;
background-image: none;
}
chatbox[dark=true] > .chat-titlebar > hbox > .chat-title {
font-weight: normal;
color: #c1c1c1;
}
.chat-frame {
padding: 0;
margin: 0;
@ -161,6 +177,10 @@ chatbox[dark=true] > .chat-titlebar > hbox > .chat-title {
width: 21px;
border: 1px solid #ccc;
border-bottom: none;
background-color: #d9d9d9;
background-image: linear-gradient(rgba(255,255,255,.43), transparent);
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
@media (min-resolution: 2dppx) {
@ -169,6 +189,15 @@ chatbox[dark=true] > .chat-titlebar > hbox > .chat-title {
}
}
.chatbar-button:hover,
.chatbar-button[open="true"] {
background-color: #f0f0f0;
}
.chatbar-button[activity]:not([open]) {
background-image: radial-gradient(circle farthest-corner at center 2px, rgb(254,254,255) 3%, rgba(210,235,255,0.9) 12%, rgba(148,205,253,0.6) 30%, rgba(148,205,253,0.2) 70%);
}
.chatbar-button > .toolbarbutton-icon {
width: 16px;
}
@ -204,9 +233,18 @@ chatbar {
chatbox {
-moz-margin-start: 4px;
background-color: white;
border: 1px solid #ccc;
border-bottom: none;
background-color: transparent;
}
chatbar > chatbox {
/* Apply the same border-radius as the .chat-titlebar to make the box-shadow
go round nicely. */
border-top-left-radius: 4px;
border-top-right-radius: 4px;
box-shadow: 0 0 5px rgba(0,0,0,.3);
/* Offset the chatbox the same amount as the box-shadows' spread, to make it
visible. */
-moz-margin-end: 5px;
}
window > chatbox {
@ -214,4 +252,5 @@ window > chatbox {
margin: 0px;
border: none;
padding: 0px;
border-radius: 4px;
}

View File

@ -397,6 +397,31 @@
background-size: @tabCurveWidth@ 100%, calc(100% - (2 * @tabCurveWidth@)) 100%, @tabCurveWidth@ 100%;
}
/* User Context UI - change tab decoration depending on userContextId.
Defaults to gray for unknown usercontextids. */
.tabbrowser-tab[usercontextid] {
background-image: linear-gradient(to right, transparent 20%, #909090 30%, #909090 70%, transparent 80%);
background-size: auto 2px;
background-repeat: no-repeat;
}
/* Personal User Context */
.tabbrowser-tab[usercontextid="1"] {
background-image: linear-gradient(to right, transparent 20%, #00a7e0 30%, #00a7e0 70%, transparent 80%);
}
/* Work User Context */
.tabbrowser-tab[usercontextid="2"] {
background-image: linear-gradient(to right, transparent 20%, #f89c24 30%, #f89c24 70%, transparent 80%);
}
/* Banking User Context */
.tabbrowser-tab[usercontextid="3"] {
background-image: linear-gradient(to right, transparent 20%, #7dc14c 30%, #7dc14c 70%, transparent 80%);
}
/* Shopping User Context */
.tabbrowser-tab[usercontextid="4"] {
background-image: linear-gradient(to right, transparent 20%, #ee5195 30%, #ee5195 70%, transparent 80%);
}
/* Tab pointer-events */
.tabbrowser-tab {
pointer-events: none;

View File

@ -15,3 +15,55 @@
#menu_newUserContextTabShopping {
list-style-image: url("chrome://browser/skin/usercontext/shopping.svg");
}
/* URL Bar Decoration */
#userContext-indicator {
height: 16px;
width: 16px;
}
#userContext-label {
margin-inline-end: 3px;
color: #909090;
}
#userContext-icons:not([usercontextid]) {
display: none;
}
#userContext-icons {
-moz-box-align: center;
}
/* Personal User Context */
#userContext-icons[usercontextid="1"] > #userContext-label {
color: #00a7e0;
}
#userContext-icons[usercontextid="1"] > #userContext-indicator {
list-style-image: url("chrome://browser/skin/usercontext/personal.svg");
}
/* Work User Context */
#userContext-icons[usercontextid="2"] > #userContext-label {
color: #f89c24;
}
#userContext-icons[usercontextid="2"] > #userContext-indicator {
list-style-image: url("chrome://browser/skin/usercontext/work.svg");
}
/* Banking User Context */
#userContext-icons[usercontextid="3"] > #userContext-label {
color: #7dc14c;
}
#userContext-icons[usercontextid="3"] > #userContext-indicator {
list-style-image: url("chrome://browser/skin/usercontext/banking.svg");
}
/* Shopping User Context */
#userContext-icons[usercontextid="4"] > #userContext-label {
color: #ee5195;
}
#userContext-icons[usercontextid="4"] > #userContext-indicator {
list-style-image: url("chrome://browser/skin/usercontext/shopping.svg");
}

View File

@ -2612,39 +2612,6 @@ notification[value="loop-sharing-notification"] .messageImage {
%include ../shared/social/chat.inc.css
.chat-titlebar {
background-color: #c4cfde;
background-image: linear-gradient(rgba(255,255,255,.5), transparent);
}
.chat-titlebar[selected] {
background-color: #dae3f0;
}
.chatbar-button {
-moz-appearance: none;
background-color: #c4cfde;
background-image: linear-gradient(rgba(255,255,255,.5), transparent);
}
.chatbar-button > .toolbarbutton-icon {
-moz-margin-end: 0;
}
.chatbar-button:hover,
.chatbar-button[open="true"] {
background-color: #dae3f0;
}
.chatbar-button[activity]:not([open="true"]) {
background-image: radial-gradient(circle farthest-corner at center 3px, rgb(255,255,255) 3%, rgba(186,221,251,0.75) 40%, rgba(127,179,255,0.5) 80%, rgba(127,179,255,0.25));
}
chatbox {
border-top-left-radius: 2.5px;
border-top-right-radius: 2.5px;
}
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css

View File

@ -92,6 +92,7 @@ browser.jar:
skin/classic/browser/urlbar-history-dropmarker@2x.png
skin/classic/browser/urlbar-history-dropmarker-preWin10.png
skin/classic/browser/urlbar-history-dropmarker-preWin10@2x.png
skin/classic/browser/webRTC-indicator.css
skin/classic/browser/loop/menuPanel.png (loop/menuPanel.png)
skin/classic/browser/loop/menuPanel@2x.png (loop/menuPanel@2x.png)
skin/classic/browser/loop/menuPanel-aero.png (loop/menuPanel-aero.png)

View File

@ -0,0 +1,116 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
window {
border: 1px solid #ff9500;
}
#audioVideoButton,
#screenShareButton,
#firefoxButton {
height: 29px;
margin: 0;
-moz-appearance: none;
border-style: none;
}
#firefoxButton {
background-image: url("chrome://branding/content/icon48.png");
background-repeat: no-repeat;
background-size: 22px;
background-position: center center;
min-width: 29px;
background-color: white;
}
#firefoxButton:hover {
background-color: #f2f2f2;
}
#screenShareButton {
background-image: url("webRTC-screen-white-16.png");
background-position: center center;
background-repeat: no-repeat;
background-size: 16px;
min-width: 27px;
display: none;
}
window[sharingscreen] > #screenShareButton {
display: -moz-box;
}
#audioVideoButton {
display: none;
background-repeat: no-repeat;
}
/* When screen sharing, need to pull in the separator: */
window[sharingscreen] > #audioVideoButton {
margin-right: -1px;
}
/* Single icon button: */
window[sharingvideo] > #audioVideoButton,
window[sharingaudio] > #audioVideoButton {
display: -moz-box;
background-position: center center;
background-size: 16px;
min-width: 26px;
}
window[sharingvideo] > #audioVideoButton {
background-image: url("webRTC-camera-white-16.png");
}
window[sharingaudio] > #audioVideoButton {
background-image: url("webRTC-microphone-white-16.png");
}
/* Multi-icon button: */
window[sharingaudio][sharingvideo] > #audioVideoButton {
background-image: url("webRTC-camera-white-16.png"),
url("webRTC-microphone-white-16.png");
background-position: 6px center, 26px center;
background-size: 16px, 16px;
min-width: 46px;
}
/* Hover styles */
#audioVideoButton,
#screenShareButton {
background-color: #ffaa33;
}
#audioVideoButton:hover,
#screenShareButton:hover {
background-color: #ff9500;
}
/* Don't show the dropmarker for the type="menu" case */
#audioVideoButton > .box-inherit > .button-menu-dropmarker,
#screenShareButton > .box-inherit > .button-menu-dropmarker {
display: none;
}
/* Separator in case of screen sharing + video/audio sharing */
#shareSeparator {
width: 1px;
margin: 4px -1px 4px 0;
background-color: #FFCA80;
/* Separator needs to show above either button when they're hovered: */
position: relative;
z-index: 1;
display: none;
}
window[sharingscreen][sharingvideo] > #shareSeparator,
window[sharingscreen][sharingaudio] > #shareSeparator {
display: -moz-box;
}
:-moz-any(#audioVideoButton, #screenShareButton,
#firefoxButton):-moz-focusring > .button-box {
border: none;
}

View File

@ -379,7 +379,7 @@ BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
}
already_AddRefed<BasePrincipal>
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, OriginAttributes& aAttrs)
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs)
{
// If the URI is supposed to inherit the security context of whoever loads it,
// we shouldn't make a codebase principal for it.

View File

@ -159,7 +159,8 @@ public:
virtual bool IsCodebasePrincipal() const { return false; };
static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(nsIURI* aURI, OriginAttributes& aAttrs);
static already_AddRefed<BasePrincipal>
CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs);
static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(const nsACString& aOrigin);
const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }

View File

@ -229,7 +229,7 @@ Tools.canvasDebugger = {
id: "canvasdebugger",
ordinal: 6,
visibilityswitch: "devtools.canvasdebugger.enabled",
icon: "chrome://devtools/skin/themes/images/tool-styleeditor.svg",
icon: "chrome://devtools/skin/themes/images/tool-canvas.svg",
invertIconForLightTheme: true,
url: "chrome://devtools/content/canvasdebugger/canvasdebugger.xul",
label: l10n("ToolboxCanvasDebugger.label", canvasDebuggerStrings),

View File

@ -225,6 +225,7 @@ ToolSidebar.prototype = {
this._tabbox.tabs.appendChild(tab);
tab.setAttribute("label", ""); // Avoid showing "undefined" while the tab is loading
tab.setAttribute("id", this.TAB_ID_PREFIX + id);
tab.setAttribute("crop", "end");
// Add the tab to the allTabs menu if exists
let allTabsItem = this._addItemToAllTabsMenu(id, tab, selected);

View File

@ -298,6 +298,7 @@ devtools.jar:
skin/themes/images/profiler-stopwatch-checked.svg (themes/images/profiler-stopwatch-checked.svg)
skin/themes/images/tool-options.svg (themes/images/tool-options.svg)
skin/themes/images/tool-webconsole.svg (themes/images/tool-webconsole.svg)
skin/themes/images/tool-canvas.svg (themes/images/tool-canvas.svg)
skin/themes/images/tool-debugger.svg (themes/images/tool-debugger.svg)
skin/themes/images/tool-debugger-paused.svg (themes/images/tool-debugger-paused.svg)
skin/themes/images/tool-inspector.svg (themes/images/tool-inspector.svg)

View File

@ -1929,7 +1929,7 @@ MarkupContainer.prototype = {
// If this is the last child, use the closing <div.tag-line> of parent as indicator
this.markup.indicateDragTarget(this.elt.nextElementSibling ||
this.markup.getContainer(this.node.parentNode()).closeTagLine);
}, this.GRAB_DELAY);
}, this.markup.GRAB_DELAY);
},
/**

View File

@ -27,6 +27,10 @@ add_task(function*() {
ok(!el.isDragging, "isDragging should not be set to true immediately");
info("Waiting for 10ms");
yield wait(10);
ok(!el.isDragging, "isDragging should not be set to true after a brief wait");
info("Waiting " + (GRAB_DELAY + 1) + "ms");
yield wait(GRAB_DELAY + 1);
ok(el.isDragging, "isDragging true after GRAB_DELAY has passed");

View File

@ -319,18 +319,25 @@
handleCtrlTab="false">
<tabs>
<tab id="headers-tab"
crop="end"
label="&netmonitorUI.tab.headers;"/>
<tab id="cookies-tab"
crop="end"
label="&netmonitorUI.tab.cookies;"/>
<tab id="params-tab"
crop="end"
label="&netmonitorUI.tab.params;"/>
<tab id="response-tab"
crop="end"
label="&netmonitorUI.tab.response;"/>
<tab id="timings-tab"
crop="end"
label="&netmonitorUI.tab.timings;"/>
<tab id="security-tab"
crop="end"
label="&netmonitorUI.tab.security;"/>
<tab id="preview-tab"
crop="end"
label="&netmonitorUI.tab.preview;"/>
</tabs>
<tabpanels flex="1">

View File

@ -8,7 +8,7 @@ const { Ci, Cc } = require("chrome");
const { Services } = require("resource://gre/modules/Services.jsm");
const { DOMHelpers } = require("resource:///modules/devtools/client/shared/DOMHelpers.jsm");
const { Task } = require("resource://gre/modules/Task.jsm");
const { Promise } = require("promise");
const { Promise } = require("resource://gre/modules/Promise.jsm");
const { setTimeout } = require("sdk/timers");
const { getMostRecentBrowserWindow } = require("sdk/window/utils");

View File

@ -0,0 +1,8 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path opacity="0.2" d="M6.9 7.3h26l-.1 25.9-25.9-.1z"/>
<path opacity="0.5" d="M13 8.7H9.1c-.2 0-.4.2-.4.4V13c0 .2.2.4.4.4H13c.2 0 .4-.2.4-.4V9.1c0-.2-.2-.4-.4-.4zM13 17.9H9.1c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4H13c.2 0 .4-.2.4-.4v-3.9c0-.2-.2-.4-.4-.4zM13 27.1H9.1c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4H13c.2 0 .4-.2.4-.4v-3.9c0-.3-.2-.4-.4-.4zM17.6 13.3h-3.9c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4v-3.9c0-.2-.2-.4-.4-.4zM17.6 22.5h-3.9c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4v-3.9c0-.3-.2-.4-.4-.4zM22.2 8.7h-3.9c-.2 0-.4.2-.4.4V13c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4V9.1c-.1-.2-.2-.4-.4-.4zM22.2 17.9h-3.9c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4v-3.9c-.1-.2-.2-.4-.4-.4zM22.2 27.1h-3.9c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4v-3.9c0-.3-.2-.4-.4-.4zM26.8 13.3h-3.9c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4v-3.9c-.1-.2-.2-.4-.4-.4zM26.8 22.5h-3.9c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4v-3.9c-.1-.3-.2-.4-.4-.4zM31.4 8.7h-3.9c-.2 0-.4.2-.4.4V13c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4V9.1c-.1-.2-.2-.4-.4-.4zM31.4 17.9h-3.9c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4v-3.9c-.1-.2-.2-.4-.4-.4zM31.4 27.1h-3.9c-.2 0-.4.2-.4.4v3.9c0 .2.2.4.4.4h3.9c.2 0 .4-.2.4-.4v-3.9c-.1-.3-.2-.4-.4-.4z"/>
<path d="M34.1 5.3H5.9c-.4 0-.6.3-.6.6V34c0 .4.3.6.6.6h28.2c.4 0 .6-.3.6-.6V5.9c0-.3-.3-.6-.6-.6zm-2.9 25.9H9.3L9.2 9h22.1v22.2z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,6 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path fill="#71c054" fill-rule="evenodd" d="m8,1c-3.9,0-7,3.1-7,7 0,3.9 3.1,7 7,7 3.9,0 7-3.1 7-7 0-3.9-3.1-7-7-7zm2,11h-1-5c-.6,0-1-.4-1-1v-6c0-.6 .4-1 1-1h5 1l4,4-4,4z"/>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="green">
<path d="M20 4.1c-8.8 0-15.9 7-15.9 15.9s7 15.9 15.9 15.9 15.9-7 15.9-15.9S28.8 4.1 20 4.1zm0 27.2c-6.3 0-11.3-5-11.3-11.3S13.7 8.7 20 8.7s11.3 5 11.3 11.3-5 11.3-11.3 11.3z"/>
<path d="M27.8 19.1l-3.5-3.5c-.3-.3-.6-.4-.9-.4h-9.8c-.3 0-.6.3-.6.6l.1 8.3c0 .3.3.6.6.6h10.1l.6-.3 3.5-3.5c.4-.6.4-1.3-.1-1.8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 478 B

After

Width:  |  Height:  |  Size: 631 B

View File

@ -1,10 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g fill="#edf0f1" fill-rule="evenodd">
<path d="m8,1c-3.9,0-7,3.1-7,7 0,3.9 3.1,7 7,7 3.9,0 7-3.1 7-7 0-3.9-3.1-7-7-7zm0,12c-2.8,0-5-2.2-5-5 0-2.8 2.2-5 5-5 2.8,0 5,2.2 5,5 0,2.8-2.2,5-5,5z"/>
<path d="m6,5c.6,0 1,.4 1,1v4c0,.6-.4,1-1,1-.6,0-1-.4-1-1v-4c0-.6 .4-1 1-1z"/>
<path d="m10,5c.6,0 1,.4 1,1v4c0,.6-.4,1-1,1-.6,0-1-.4-1-1v-4c0-.6 .4-1 1-1z"/>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M20 4.1c-8.8 0-15.9 7-15.9 15.9s7 15.9 15.9 15.9 15.9-7 15.9-15.9S28.8 4.1 20 4.1zm0 27.2c-6.3 0-11.3-5-11.3-11.3S13.7 8.7 20 8.7s11.3 5 11.3 11.3-5 11.3-11.3 11.3z"/>
<path d="M15.5 13.2c1.4 0 2.3.9 2.3 2.3v9.1c0 1.4-.9 2.3-2.3 2.3s-2.3-.9-2.3-2.3v-9.1c0-1.4.9-2.3 2.3-2.3zM24.5 13.2c1.4 0 2.3.9 2.3 2.3v9.1c0 1.4-.9 2.3-2.3 2.3s-2.3-.9-2.3-2.3v-9.1c.1-1.4 1-2.3 2.3-2.3z"/>
</svg>

Before

Width:  |  Height:  |  Size: 676 B

After

Width:  |  Height:  |  Size: 713 B

View File

@ -1,12 +1,6 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg width="16" xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 16 16">
<path fill="#eef0f2" fill-rule="evenodd" d="M2,4v9h11V4H2z M11,11H4V6h7V11z"/>
<g opacity=".8">
<path opacity=".8" fill="#eef0f2" fill-rule="evenodd" d="M0,8h2v1H0V8z"/>
<path opacity=".8" fill="#eef0f2" fill-rule="evenodd" d="M13,8h2v1h-2V8z"/>
<path opacity=".8" fill="#eef0f2" fill-rule="evenodd" d="M7,2h1v2H7V2z"/>
<path opacity=".8" fill="#eef0f2" fill-rule="evenodd" d="M7,13h1v2H7V13z"/>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M36.1 18h-2V9.6c0-1.5-1.2-2.6-2.6-2.6h-9V5c0-1.1-.9-2.1-2.1-2.1-1.1 0-2.1.9-2.1 2.1v2H8.5C7 6.9 5.9 8.1 5.9 9.6V18h-2c-1.1 0-2.1.9-2.1 2.1 0 1.1.9 2.1 2.1 2.1h2v8.4c0 1.5 1.2 2.6 2.6 2.6h9.8v2c0 1.1.9 2 2.1 2 1.1 0 2.1-.9 2.1-2v-2h9c1.5 0 2.6-1.2 2.6-2.6v-8.4h2c1.1 0 2.1-.9 2.1-2.1s-1-2.1-2.1-2.1zm-6.6 10.4H10.9v-17h18.6v17z"/>
</svg>

Before

Width:  |  Height:  |  Size: 726 B

After

Width:  |  Height:  |  Size: 663 B

View File

@ -1,39 +1,9 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg width="17" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 16">
<g fill="#edf0f1" fill-rule="evenodd">
<path opacity=".1" d="M2.1,0h12.8C16,0,17,1,17,2.1v10.6c0,1.2-1,2.1-2.1,2.1H2.1c-1.2,0-2.1-1-2.1-2.1V2.1C0,1,1,0,2.1,0z"/>
<path d="m2.1,2.1h9.6c.6,0 1.1,.5 1.1,1.1 0,.6-.5,1.1-1.1,1.1h-9.6c-.6,0-1.1-.5-1.1-1.1 .1-.6 .5-1.1 1.1-1.1z"/>
</g>
<g opacity=".7">
<g opacity=".75">
<path fill="#edf0f1" fill-rule="evenodd" d="m7.4,5.3h7.4c.6,0 1.1,.5 1.1,1.1 0,.6-.5,1.1-1.1,1.1h-7.4c-.5-.1-1-.5-1-1.1 0-.6 .5-1.1 1-1.1z"/>
</g>
<g opacity=".85">
<path fill="#edf0f1" d="m14.9,5.7c.4,0 .7,.3 .7,.7s-.4,.6-.7,.6h-7.5c-.3,0-.6-.3-.6-.6s.3-.7 .7-.7h7.4m0-.4h-7.5c-.6,0-1.1,.5-1.1,1.1 0,.6 .5,1.1 1.1,1.1h7.4c.6,0 1.1-.5 1.1-1.1 0-.6-.4-1.1-1-1.1z"/>
</g>
</g>
<g opacity=".75">
<path fill="#edf0f1" fill-rule="evenodd" d="m5.3,8.5h3.2c.6,0 1.1,.5 1.1,1.1 0,.6-.5,1.1-1.1,1.1h-3.2c-.6,0-1.1-.5-1.1-1.1 .1-.6 .5-1.1 1.1-1.1z"/>
</g>
<g opacity=".85">
<path fill="#edf0f1" d="m8.5,8.9c.4,0 .7,.3 .7,.7 0,.4-.3,.7-.7,.7h-3.2c-.4,0-.7-.3-.7-.7 0-.4 .3-.7 .7-.7h3.2m0-.4h-3.2c-.6,0-1.1,.5-1.1,1.1 0,.6 .5,1.1 1.1,1.1h3.2c.6,0 1.1-.5 1.1-1.1 0-.6-.5-1.1-1.1-1.1z"/>
</g>
<g opacity=".7">
<g opacity=".75">
<path fill="#edf0f1" fill-rule="evenodd" d="m4.3,11.7h2.1c.6,0 1.1,.5 1.1,1.1 0,.6-.5,1.1-1.1,1.1h-2.1c-.6,0-1.1-.5-1.1-1.1 0-.6 .5-1.1 1.1-1.1z"/>
</g>
<g opacity=".85">
<path fill="#edf0f1" d="m6.4,12.1c.4,0 .7,.3 .7,.7 0,.4-.3,.7-.7,.7h-2.1c-.4,0-.7-.3-.7-.7 0-.4 .3-.7 .7-.7h2.1m0-.4h-2.1c-.6,0-1.1,.5-1.1,1.1 0,.6 .5,1.1 1.1,1.1h2.1c.6,0 1.1-.5 1.1-1.1-.1-.6-.5-1.1-1.1-1.1z"/>
</g>
</g>
<g opacity=".05" fill="#edf0f1" fill-rule="evenodd">
<path d="m7.4,14.3v-13.8c0-.3-.2-.5-.5-.5-.3,0-.5,.2-.5,.5v13.8c0,.3 .2,.5 .5,.5 .3,.1 .5-.2 .5-.5z"/>
<path d="m4.2,14.3v-13.8c0-.3-.2-.5-.5-.5-.3,0-.5,.2-.5,.5v13.8c0,.3 .2,.5 .5,.5 .3,.1 .5-.2 .5-.5z"/>
<path d="m1,14.6c0-.1 0-.1 0-.2v-13.9c0-.1 0-.1 0-.2-.6,.4-1,1-1,1.8v10.6c0,.8 .4,1.5 1,1.9z"/>
<path d="m16,.3c0,.1 0,.1 0,.2v13.8c0,.1 0,.1 0,.2 .6-.4 1-1 1-1.8v-10.6c0-.7-.4-1.4-1-1.8z"/>
<path d="m13.8,14.3v-13.8c0-.3-.2-.5-.5-.5-.3,0-.5,.2-.5,.5v13.8c0,.3 .2,.5 .5,.5 .3,.1 .5-.2 .5-.5z"/>
<path d="m10.6,14.3v-13.8c0-.3-.2-.5-.5-.5-.3,0-.5,.2-.5,.5v13.8c0,.3 .2,.5 .5,.5 .3,.1 .5-.2 .5-.5z"/>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M28.2 10.6H4.6c-1 0-1.9-.8-1.9-1.9s.8-1.9 1.9-1.9h23.6c1 0 1.9.8 1.9 1.9s-.8 1.9-1.9 1.9z"/>
<path opacity="0.75" d="M35.4 18.1H16.7c-1 0-1.9-.8-1.9-1.9s.8-1.9 1.9-1.9h18.7c1 0 1.9.8 1.9 1.9s-.9 1.9-1.9 1.9z"/>
<path d="M21 25.6h-8.7c-1 0-1.9-.8-1.9-1.9s.8-1.9 1.9-1.9H21c1 0 1.9.8 1.9 1.9s-.9 1.9-1.9 1.9z"/>
<path opacity="0.75" d="M12.3 33.2H6.4c-1 0-1.9-.8-1.9-1.9 0-1 .8-1.9 1.9-1.9h5.9c1 0 1.9.8 1.9 1.9 0 1.1-.8 1.9-1.9 1.9z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 780 B

View File

@ -1,17 +1,8 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="#71c054" fill-rule="evenodd">
<path d="m8,1c-3.9,0-7,3.1-7,7s3.1,7 7,7c3.9,0 7-3.1 7-7s-3.1-7-7-7zm-.1,12c-2.8,0-5-2.2-5-5 0-2.8 2.2-5 5-5s5,2.2 5,5c0,2.8-2.2,5-5,5z"/>
<path d="m8,6.9c.6,0 1.1,.5 1.1,1.1 0,.6-.5,1.1-1.1,1.1-.6,0-1.1-.5-1.1-1.1 0-.6 .5-1.1 1.1-1.1z"/>
<path d="m11.3,4.6l-3.9,2.5 1.5,1.4 2.4-3.9z"/>
<path opacity=".4" d="m4.6,10c.7,1.2 2,2 3.4,2 1.5,0 2.7-.8 3.4-2h-6.8z"/>
<g opacity=".3">
<path d="m7.1,5.1l-.6-1.3-.9,.4 .7,1.3c.2-.1 .5-.3 .8-.4z"/>
<path d="m9.8,5.6l.7-1.4-.9-.4-.7,1.3c.3,.2 .6,.3 .9,.5z"/>
<path d="m10.8,7c.1,.3 .2,.7 .2,1h2v-1h-2.2z"/>
<path d="m5,8c0-.3 .1-.7 .2-1h-2.2l-.1,1h2.1z"/>
</g>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="#71c054">
<path d="M17.6 18.4c-.7.2-1.3.9-1.5 1.6-.2 1.2.6 2.3 1.7 2.5.8.1 1.5-.2 2-.7l6-6.9-8.2 3.5z"/>
<path d="M12.3 24.5c1.6 2.7 4.5 4.5 7.7 4.5 3.4 0 6.1-1.8 7.7-4.5H12.3z"/>
<path d="M20 4.3c-8.8 0-15.9 7-15.9 15.7 0 8.8 7 15.7 15.9 15.7 8.8 0 15.9-7 15.9-15.7 0-8.8-7.1-15.7-15.9-15.7zm-.2 26.9c-6 0-10.7-4.4-11.3-10.1H9.9c1.4 0 2.3-.9 2.3-2.2 0-1.3-.9-2.2-2.3-2.2h-1c.6-2.1 1.9-3.9 3.5-5.3l.5.8c.6 1.2 1.9 1.6 3.1.9s1.6-1.8.9-3l-.5-.9c1-.3 2.1-.5 3.3-.5 1.3 0 2.5.2 3.7.6l-.4 1c-.6 1.2-.3 2.4.9 3s2.4.3 3.1-.9l.4-.7c1.5 1.3 2.6 3 3.2 5h-.9c-1.4 0-2.3.9-2.3 2.2 0 1.3.9 2.2 2.3 2.2H31.1c-.6 5.8-5.4 10.1-11.3 10.1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1001 B

After

Width:  |  Height:  |  Size: 944 B

View File

@ -1,17 +1,8 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="#edf0f1" fill-rule="evenodd">
<path d="m8,1c-3.9,0-7,3.1-7,7s3.1,7 7,7c3.9,0 7-3.1 7-7s-3.1-7-7-7zm-.1,12c-2.8,0-5-2.2-5-5 0-2.8 2.2-5 5-5s5,2.2 5,5c0,2.8-2.2,5-5,5z"/>
<path d="m8,6.9c.6,0 1.1,.5 1.1,1.1 0,.6-.5,1.1-1.1,1.1-.6,0-1.1-.5-1.1-1.1 0-.6 .5-1.1 1.1-1.1z"/>
<path d="m11.3,4.6l-3.9,2.5 1.5,1.4 2.4-3.9z"/>
<path opacity=".4" d="m4.6,10c.7,1.2 2,2 3.4,2 1.5,0 2.7-.8 3.4-2h-6.8z"/>
<g opacity=".3">
<path d="m7.1,5.1l-.6-1.3-.9,.4 .7,1.3c.2-.1 .5-.3 .8-.4z"/>
<path d="m9.8,5.6l.7-1.4-.9-.4-.7,1.3c.3,.2 .6,.3 .9,.5z"/>
<path d="m10.8,7c.1,.3 .2,.7 .2,1h2v-1h-2.2z"/>
<path d="m5,8c0-.3 .1-.7 .2-1h-2.2l-.1,1h2.1z"/>
</g>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M17.6 18.4c-.7.2-1.3.9-1.5 1.6-.2 1.2.6 2.3 1.7 2.5.8.1 1.5-.2 2-.7l6-6.9-8.2 3.5z"/>
<path opacity="0.5" d="M12.3 24.5c1.6 2.7 4.5 4.5 7.7 4.5 3.4 0 6.1-1.8 7.7-4.5H12.3z"/>
<path d="M20 4.3c-8.8 0-15.9 7-15.9 15.7 0 8.8 7 15.7 15.9 15.7 8.8 0 15.9-7 15.9-15.7 0-8.8-7.1-15.7-15.9-15.7zm-.2 26.9c-6 0-10.7-4.4-11.3-10.1H9.9c1.4 0 2.3-.9 2.3-2.2 0-1.3-.9-2.2-2.3-2.2h-1c.6-2.1 1.9-3.9 3.5-5.3l.5.8c.6 1.2 1.9 1.6 3.1.9s1.6-1.8.9-3l-.5-.9c1-.3 2.1-.5 3.3-.5 1.3 0 2.5.2 3.7.6l-.4 1c-.6 1.2-.3 2.4.9 3s2.4.3 3.1-.9l.4-.7c1.5 1.3 2.6 3 3.2 5h-.9c-1.4 0-2.3.9-2.3 2.2 0 1.3.9 2.2 2.3 2.2H31.1c-.6 5.8-5.4 10.1-11.3 10.1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1001 B

After

Width:  |  Height:  |  Size: 961 B

View File

@ -1,9 +1,6 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g fill="#edf0f1" fill-rule="evenodd">
<path opacity=".3" d="m1.1,6.3c0-.3 .3-.6 .6-.6h4.6c.3,0 .6,.3 .6,.6s-.3,.6-.6,.6h-4.6c-.3,0-.6-.3-.6-.6zm12,1.7h-10.2c-.4,0-.6,.3-.6,.6 0,.3 .3,.6 .6,.6h10.3c.3,0 .6-.3 .6-.6-.1-.3-.3-.6-.7-.6zm-5.7,3.4c.3,0 .6-.3 .6-.6 0-.3-.3-.6-.6-.6h-4.5c-.3,0-.6,.3-.6,.6 0,.3 .3,.6 .6,.6h4.5zm2.3,1.2h-8c-.3,0-.6,.3-.6,.6 0,.3 .3,.6 .6,.6h8c.3,0 .6-.3 .6-.6 0-.4-.3-.6-.6-.6z"/>
<path d="m14.3,2.3h-.6v1.1c0,.6-.5,1.1-1.1,1.1-.6,0-1.1-.5-1.1-1.1v-.5c0,.3 .3,.6 .6,.6 .3,0 .6-.3 .6-.6v-.6-1.7c0-.1 0-.2-.1-.3-.1-.1-.1-.1-.2-.2-.2-.1-.3-.1-.4-.1-.3,0-.6,.3-.6,.6v1.7h-1.1v1.1c0,.6-.5,1.1-1.1,1.1-.7,.1-1.2-.4-1.2-1.1v-.5c0,.3 .3,.6 .6,.6 .3,0 .6-.3 .6-.6v-.6-1.7c0-.1 0-.2-.1-.3-.1-.1-.2-.2-.3-.2-.1-.1-.1-.1-.2-.1-.3,0-.6,.3-.6,.6v1.7h-1.1v1.1c0,.6-.5,1.1-1.1,1.1-.6,0-1.1-.5-1.1-1.1v-.5c0,.3 .3,.6 .6,.6 .3,0 .6-.3 .6-.6v-.6-1.7c0-.1 0-.2-.1-.3-.3-.1-.3-.2-.4-.2-.1-.1-.2-.1-.3-.1-.3,0-.5,.3-.5,.6v1.7h-1.2v1.1c0,.6-.5,1.1-1.1,1.1-.6,0-1.1-.5-1.1-1.1v-.5c0,.3 .3,.6 .6,.6 .3,0 .6-.3 .6-.6v-.6-1.7c0-.1 0-.2-.1-.3-.2-.1-.2-.2-.3-.2-.1-.1-.2-.1-.3-.1-.3,0-.6,.3-.6,.6v1.7h-.5c-.3,0-.6,.2-.6,.6v12.6c0,.2 .3,.5 .6,.5h13.7c.3,0 .6-.3 .6-.6v-12.5c0-.4-.3-.6-.6-.6zm-12.6,3.4h4.6c.3,0 .6,.3 .6,.6s-.3,.6-.6,.6h-4.6c-.3,0-.6-.3-.6-.6s.3-.6 .6-.6zm8,8h-8c-.3,0-.6-.3-.6-.6 0-.3 .3-.6 .6-.6h8c.3,0 .6,.3 .6,.6 0,.4-.3,.6-.6,.6zm-7.4-2.8c0-.3 .3-.6 .6-.6h4.6c.3,0 .6,.3 .6,.6 0,.3-.3,.6-.6,.6h-4.6c-.4-.1-.6-.3-.6-.6zm10.8-1.8h-10.2c-.3,0-.6-.3-.6-.6 0-.2 .2-.5 .6-.5h10.3c.3,0 .6,.3 .6,.6-.1,.3-.3,.5-.7,.5z"/>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M33.9 7.3h-1.2v2.2c0 1.2-1 2.2-2.2 2.2-1.2 0-2.2-1-2.2-2.2v-.1c0 .6.6 1.1 1.2 1.1.7 0 1.2-.5 1.2-1.1v-5c0-.6-.6-1.1-1.2-1.1-.7 0-1.2.5-1.2 1.1v2.9h-5.4v2.2c0 1.2-1 2.2-2.2 2.2-1.4.2-2.4-.8-2.4-2.2v-.1c0 .6.6 1.1 1.2 1.1.7 0 1.2-.5 1.2-1.1v-5c0-.6-.6-1.1-1.2-1.1-.7 0-1.2.5-1.2 1.1v2.9H13v2.2c0 1.2-1 2.2-2.2 2.2-1.2 0-2.2-1-2.2-2.1.1.5.6.9 1.2.9.7 0 1.2-.5 1.2-1.1v-5c0-.6-.6-1.1-1.2-1.1s-1.3.5-1.3 1.1v2.9H6.1c-.6 0-1.2.4-1.2 1.2v25.6c0 .4.6 1 1.2 1H34c.6 0 1.2-.6 1.2-1.2V8.5c0-.8-.7-1.2-1.3-1.2zm-25 8.8h15.2c.7 0 1.2.6 1.2 1.2 0 .7-.6 1.2-1.2 1.2H8.9c-.7 0-1.2-.6-1.2-1.2s.5-1.2 1.2-1.2zm16.6 14.6H9.1c-.7 0-1.2-.6-1.2-1.2 0-.7.6-1.2 1.2-1.2h16.4c.7 0 1.2.6 1.2 1.2 0 .7-.5 1.2-1.2 1.2zm5.6-6H11.5c-.7 0-1.2-.6-1.2-1.2 0-.7.6-1.2 1.2-1.2h19.6c.7 0 1.2.6 1.2 1.2s-.5 1.2-1.2 1.2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,26 +1,9 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<rect x="2" y="2" width="12" height="12" fill="#edf0f1" fill-opacity=".1"/>
<polygon points="2,2 14,14 2,14" fill="#edf0f1" fill-opacity=".35"/>
<rect x="2.5" y="2.5" width="11" height="11" fill="none" stroke="#edf0f1" stroke-width="1"/>
<g fill="#edf0f1" fill-opacity=".65">
<polygon points="3,3 5,3 5,5"/>
<rect x="11" y="3" width="2" height="2"/>
<rect x="7" y="3" width="2" height="2"/>
<polygon points="5,5 7,5 7,7"/>
<rect x="9" y="5" width="2" height="2"/>
<polygon points="7,7 9,7 9,9"/>
<rect x="11" y="7" width="2" height="2"/>
<polygon points="9,9 11,9 11,11"/>
<polygon points="11,11 13,11 13,13"/>
</g>
<line x1="3" y1="3" x2="13" y2="13" stroke="#edf0f1" stroke-width="1"/>
<g fill="#edf0f1">
<circle cx="2" cy="2" r="1"/>
<circle cx="14" cy="2" r="1"/>
<circle cx="2" cy="14" r="1"/>
<circle cx="14" cy="14" r="1"/>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path opacity="0.2" d="M7.3 7.7l25.1 25.1-25.1-.1z"/>
<path d="M27.8 25.7l-13-13c-.7-.7-1.8-.7-2.5 0s-.7 1.8 0 2.5l12.9 12.9c.3.3.8.5 1.2.5.5 0 .9-.2 1.2-.5.9-.6.9-1.7.2-2.4z"/>
<path opacity="0.5" d="M27.5 12.5h-3.8c-.2 0-.3.2-.3.3v3.8c0 .2.2.3.3.3h3.8c.2 0 .3-.2.3-.3v-3.8c.1-.2-.1-.3-.3-.3zm.2 8.9h-3.8c-.1 0-.2.1-.3.1l4.3 4.3c.1-.1.1-.2.1-.3v-3.8c0-.2-.1-.3-.3-.3zm-4.5-4.6h-3.8c-.1 0-.2.1-.3.1l4.3 4.3c.1-.1.1-.2.1-.3v-3.8c0-.1-.1-.3-.3-.3zm-4.5-4.4h-3.8c-.1 0-.2.1-.3.1l4.3 4.3c.1-.1.1-.2.1-.3v-3.8c0-.1-.1-.3-.3-.3z"/>
<path d="M34.2 31.8V8.1c1.3 0 2.4-1.1 2.4-2.4s-1.1-2.4-2.4-2.4c-1.3 0-2.4 1.1-2.4 2.4H8.2c0-1.3-1.1-2.4-2.4-2.4-1.3 0-2.4 1.1-2.4 2.4 0 1.2.9 2.2 2 2.3v23.8c-1.1.2-2 1.2-2 2.3 0 1.3 1.1 2.4 2.4 2.4 1.2 0 2.2-.9 2.3-2h23.8c.2 1.1 1.2 2 2.3 2 1.3 0 2.4-1.1 2.4-2.4 0-1.2-1.1-2.3-2.4-2.3zm-4-1.2H9.5V9.8h20.7v20.8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,10 +1,8 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg width="16" xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 16 16">
<g fill="#edf0f1">
<path d="m1.3,12.5v-2.4c0,0 0,2.5 6.7,2.5 6.7,0 6.7-2.5 6.7-2.5v2.4c0,0 0,2.7-6.8,2.7-6.6,0-6.6-2.7-6.6-2.7z"/>
<path d="m14.7,3.4c0-1.4-3-2.5-6.7-2.5s-6.7,1.1-6.7,2.5c0,.2 0,.3 .1,.5-.1-.3-.1-.4-.1-.4v1.5c0,0 0,2.7 6.7,2.7 6.7,0 6.8-2.7 6.8-2.7v-1.6c0,.1 0,.2-.1,.5-0-.2-0-.3-0-.5z"/>
<path d="m1.3,8.7v-2.4c0,0 0,2.5 6.7,2.5 6.7,0 6.7-2.5 6.7-2.5v2.4c0,0 0,2.7-6.8,2.7-6.6-0-6.6-2.7-6.6-2.7z"/>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M19.8 17.2c-14.1 0-13.5-4.4-13.5-5.3v-2c0-4 8-5 13.5-5 5.6 0 13.8 1.1 13.8 5v2c0 .9.3 5.3-13.8 5.3z"/>
<path d="M19.8 21.6c-14.4 0-13.5-4.9-13.5-4.9V21c0 .9-.6 5.5 13.3 5.5 14.3 0 14-4.6 14-5.5v-4c.1 0 .8 4.6-13.8 4.6z"/>
<path d="M19.8 30.4c-14.4 0-13.5-4.9-13.5-4.9v4.2c0 .9-.6 5.5 13.3 5.5 14.3 0 14-4.6 14-5.5v-3.9c.1 0 .8 4.6-13.8 4.6z"/>
</svg>

Before

Width:  |  Height:  |  Size: 740 B

After

Width:  |  Height:  |  Size: 685 B

View File

@ -1,9 +1,6 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" viewBox="0 0 17 16">
<g fill="#edf0f1" fill-rule="evenodd">
<path d="m10,11.1 0,2.3-7.8,0 0-11.2 5.6-0 1.1,1.1 1.7-1.6-1.7-1.7-8.9,0 0,15.6 12.2,0 0-6.7z"/>
<path d="M6.7,7.8L14.5,0l2.2,2.2L8.9,10l-3.3,1.1L6.7,7.8z"/>
</g>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M11 18.7c.3-.5.4-1.1.4-1.9v-5-.6c0-.2.1-.3.2-.4.1-.1.2-.2.4-.3.1-.1.4-.1.9-.1h.9c1.2 0 2.1-1 2.1-2.3 0-1.2-.9-2.2-2-2.3H11.1c-.7 0-1.3.1-1.8.3-.5 0-1 .3-1.4.8-.4.4-.8.9-1 1.6-.2.6-.3 1.4-.3 2.2v5.4c0 .4-.1.6-.3.8-.2.2-.5.4-.8.5-.3.1-.5.2-.8.2-.4 0 0 .1-.2.1h-.1c-1.1.1-1.9 1.1-1.9 2.2 0 1.2.8 2.1 1.9 2.2.2.1-.1 0 .3.1.3 0 .5.1.8.3.3.1.6.3.8.5.2.2.3.5.3.8v5.4c0 .9.1 1.6.4 2.2.2.6.6 1.2 1 1.6.4.4.9.7 1.5.9.6.2 1.2.3 1.8.3h3.1c1.2 0 2.1-1 2.1-2.3 0-1.2-.9-2.3-2.1-2.3h-1.3c-.5 0-.8-.1-.9-.1-.2-.1-.3-.2-.4-.3-.1-.1-.2-.3-.2-.4v-5.6c0-.8-.1-1.4-.4-1.9-.3-.5-.6-.9-.9-1.1-.3-.1-.4-.2-.5-.2.1-.1.2-.1.3-.2.4-.3.7-.7.9-1.1zM29 18.7c-.3-.5-.4-1.1-.4-1.9v-5-.6c0-.2-.1-.3-.2-.4-.1-.1-.2-.2-.4-.3-.1-.1-.4-.1-.9-.1h-.8-.1c-1.2 0-2.1-1-2.1-2.3 0-1.2.9-2.2 2-2.3H28.9c.7 0 1.3.1 1.8.3.6.2 1.1.5 1.5.9.4.4.8.9 1 1.6.2.6.3 1.4.3 2.2v5.4c0 .4.1.6.3.8.2.2.5.4.8.5.3.1.5.2.8.2.4 0 0 .1.2.1h.1c1.1.1 1.9 1.1 1.9 2.2 0 1.2-.8 2.1-1.9 2.2-.2.1.1 0-.3.1-.3 0-.5.1-.8.3-.3.1-.6.3-.8.5-.2.2-.3.5-.3.8v5.4c0 .9-.1 1.6-.4 2.2-.2.6-.6 1.2-1 1.6-.4.4-.9.7-1.5.9-.6.2-1.2.3-1.8.3h-3-.1c-1.2 0-2.1-1-2.1-2.3 0-1.2.9-2.3 2.1-2.3H27c.5 0 .8-.1.9-.1.2-.1.3-.2.4-.3.1-.1.2-.3.2-.4v-5.6c0-.8.1-1.4.4-1.9.3-.5.6-.9.9-1.1.1-.1.2-.1.3-.2-.1-.1-.2-.1-.3-.2-.3-.4-.6-.8-.8-1.2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,6 +1,6 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="-6.167 -16.135 100 100">
<path fill="none" stroke="#edf0f1" stroke-width="8" stroke-linecap="round" stroke-miterlimit="10" d="M86.666,33.864 c-0.797,5.297-3.467,32.799-10.518,32.866c-7.086,0.066-9.973-27.596-10.9-32.866C64.322,28.597,61.436,0.933,54.35,1 c-7.105,0.068-9.644,27.561-10.517,32.864c-0.874,5.305-3.412,32.799-10.517,32.866c-7.087,0.066-9.974-27.596-10.899-32.866 C21.49,28.597,18.604,0.933,11.517,1C4.466,1.067,1.796,28.569,1,33.864"/>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M32.4 34.7c-3.9 0-5.1-6.2-6.1-13.2-.1-.5-.1-.9-.2-1.1-.1-.3-.1-.7-.2-1.3-.7-5-1.4-7.4-1.8-8.6-.5 1.2-1.1 3.7-1.7 8.6-.1.6-.1 1-.2 1.3 0 .3-.1.7-.2 1.2-.9 6.9-2.1 13.2-6 13.2s-5.1-6.2-6.1-13.2c-.1-.5-.1-.9-.2-1.1-.1-.3-.1-.7-.2-1.3-.7-5-1.4-7.4-1.8-8.6-.5 1.2-1.1 3.7-1.8 8.9-.1.4-.1.8-.1 1-.2 1.2-1.3 2-2.4 1.8-1.2-.2-2-1.3-1.8-2.4 0-.2.1-.5.1-.9C2.7 10.2 4 5.3 7.6 5.3c3.9 0 5.1 6.2 6.1 13.2.1.5.1.9.2 1.2 0 .3.1.7.2 1.3.7 5 1.4 7.4 1.8 8.7.5-1.2 1.1-3.7 1.7-8.6.1-.6.1-1 .2-1.3 0-.3.1-.7.2-1.2.9-6.9 2.1-13.2 6-13.2s5.1 6.2 6.1 13.2c.1.5.1.9.2 1.2 0 .3.1.7.2 1.3.7 5 1.4 7.4 1.8 8.6.5-1.2 1.1-3.7 1.8-8.9.1-.4.1-.8.1-1 .2-1.2 1.3-2 2.4-1.8 1.2.2 2 1.3 1.8 2.4 0 .2-.1.5-.1.9-1 8.5-2.3 13.4-5.9 13.4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 749 B

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,6 +1,6 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#edf0f1" fill-rule="evenodd" d="M2,2h5.4l6.5,6.5L7.4,15H2l6.5-6.5L2,2z"/>
</svg>
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="whitesmoke">
<path d="M16.3 15.4L7.7 6.9c-.3-.3-.7-.5-1.1-.5H4.3c-.7 0-1.2.4-1.5 1-.2.6-.1 1.3.4 1.8l7.4 7.4-7.1 7.1c-.5.5-.6 1.2-.4 1.8.3.6.8 1 1.5 1h2.3c.4 0 .8-.2 1.1-.5l8.3-8.3c.6-.6.6-1.6 0-2.3zM34.9 33.6H9.2c-1.3 0-2.4-1.1-2.4-2.4 0-1.3 1.1-2.4 2.4-2.4h25.7c1.3 0 2.4 1.1 2.4 2.4 0 1.3-1.1 2.4-2.4 2.4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 623 B

View File

@ -474,7 +474,7 @@ a {
.message .theme-twisty {
display: inline-block;
vertical-align: middle;
margin: 0 3px 0 0;
margin: 3px 3px 0 0;
}
.stacktrace li {

View File

@ -4,8 +4,16 @@
"use strict";
const {Ci} = require("chrome");
const l10n = require("gcli/l10n");
function getContentViewer(context) {
let {window} = context.environment;
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.contentViewer;
}
exports.items = [
{
name: "media",
@ -13,7 +21,7 @@ exports.items = [
},
{
item: "command",
runAt: "client",
runAt: "server",
name: "media emulate",
description: l10n.lookup("mediaEmulateDesc"),
manual: l10n.lookup("mediaEmulateManual"),
@ -22,29 +30,27 @@ exports.items = [
name: "type",
description: l10n.lookup("mediaEmulateType"),
type: {
name: "selection",
data: [
"braille", "embossed", "handheld", "print", "projection",
"screen", "speech", "tty", "tv"
]
name: "selection",
data: [
"braille", "embossed", "handheld", "print", "projection",
"screen", "speech", "tty", "tv"
]
}
}
],
exec: function(args, context) {
let markupDocumentViewer = context.environment.chromeWindow
.gBrowser.markupDocumentViewer;
markupDocumentViewer.emulateMedium(args.type);
let contentViewer = getContentViewer(context);
contentViewer.emulateMedium(args.type);
}
},
{
item: "command",
runAt: "client",
runAt: "server",
name: "media reset",
description: l10n.lookup("mediaResetDesc"),
exec: function(args, context) {
let markupDocumentViewer = context.environment.chromeWindow
.gBrowser.markupDocumentViewer;
markupDocumentViewer.stopEmulatingMedium();
let contentViewer = getContentViewer(context);
contentViewer.stopEmulatingMedium();
}
}
];

View File

@ -23,7 +23,7 @@ interface nsIDOMElement;
* can be queried for various information about where the load is
* happening.
*/
[scriptable, uuid(1220e340-b337-4c35-aaa1-f51362763621)]
[scriptable, uuid(96014778-d30b-4fee-8902-a3481788907b)]
interface nsILoadContext : nsISupports
{
/**
@ -148,7 +148,7 @@ interface nsILoadContext : nsISupports
JS::Rooted<JS::Value> v(jsapi.cx());
nsresult rv = GetOriginAttributes(&v);
NS_ENSURE_SUCCESS(rv, false);
MOZ_ASSERT(v.isObject());
NS_ENSURE_TRUE(v.isObject(), false);
JS::Rooted<JSObject*> obj(jsapi.cx(), &v.toObject());
// If we're JS-implemented, the object will be left in a different (System-Principaled)

View File

@ -151,6 +151,10 @@ this.AppsUtils = {
topWindow : null,
appId: aAppId,
isInBrowserElement: aIsBrowser,
originAttributes: {
appId: aAppId,
inBrowser: aIsBrowser
},
usePrivateBrowsing: false,
isContent: false,

View File

@ -3468,6 +3468,10 @@ this.DOMApplicationRegistry = {
// nsILoadContext
appId: aOldApp.installerAppId,
isInBrowserElement: aOldApp.installerIsBrowser,
originAttributes: {
appId: aOldApp.installerAppId,
inBrowser: aOldApp.installerIsBrowser
},
usePrivateBrowsing: false,
isContent: false,
associatedWindow: null,

Some files were not shown because too many files have changed in this diff Show More