зеркало из https://github.com/mozilla/gecko-dev.git
Merge fx-team to m-c. a=merge
This commit is contained in:
Коммит
48b16e2ff1
|
@ -1588,6 +1588,15 @@ pref("services.push.serverURL", "wss://push.services.mozilla.com/");
|
|||
|
||||
pref("social.sidebar.unload_timeout_ms", 10000);
|
||||
|
||||
// activation from inside of share panel is possible if activationPanelEnabled
|
||||
// is true. Pref'd off for release while usage testing is done through beta.
|
||||
#ifdef RELEASE_BUILD
|
||||
pref("social.share.activationPanelEnabled", false);
|
||||
#else
|
||||
pref("social.share.activationPanelEnabled", true);
|
||||
#endif
|
||||
pref("social.shareDirectory", "https://activations.cdn.mozilla.net/en-US/sharePanel.html");
|
||||
|
||||
pref("dom.identity.enabled", false);
|
||||
|
||||
// Block insecure active content on https pages
|
||||
|
|
|
@ -43,12 +43,17 @@
|
|||
|
||||
function parseQueryString() {
|
||||
let url = document.documentURI;
|
||||
let queryString = url.replace(/^about:socialerror\??/, "");
|
||||
var searchParams = new URLSearchParams(url);
|
||||
|
||||
let modeMatch = queryString.match(/mode=([^&]+)/);
|
||||
let mode = modeMatch && modeMatch[1] ? modeMatch[1] : "";
|
||||
let originMatch = queryString.match(/origin=([^&]+)/);
|
||||
config.origin = originMatch && originMatch[1] ? decodeURIComponent(originMatch[1]) : "";
|
||||
let mode = searchParams.get("mode");
|
||||
config.directory = searchParams.get("directory");
|
||||
config.origin = searchParams.get("origin");
|
||||
let encodedURL = searchParams.get("url");
|
||||
let url = decodeURIComponent(encodedURL);
|
||||
if (config.directory) {
|
||||
let URI = Services.io.newURI(url, null, null);
|
||||
config.origin = Services.scriptSecurityManager.getNoAppCodebasePrincipal(URI).origin;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case "compactInfo":
|
||||
|
@ -59,10 +64,6 @@
|
|||
document.getElementById("btnCloseSidebar").style.display = 'none';
|
||||
//intentional fall-through
|
||||
case "tryAgain":
|
||||
let urlMatch = queryString.match(/url=([^&]+)/);
|
||||
let encodedURL = urlMatch && urlMatch[1] ? urlMatch[1] : "";
|
||||
let url = decodeURIComponent(encodedURL);
|
||||
|
||||
config.tryAgainCallback = loadQueryURL;
|
||||
config.queryURL = url;
|
||||
break;
|
||||
|
@ -80,7 +81,7 @@
|
|||
|
||||
let productName = brandBundle.GetStringFromName("brandShortName");
|
||||
let provider = Social._getProviderFromOrigin(config.origin);
|
||||
let providerName = provider && provider.name;
|
||||
let providerName = provider ? provider.name : config.origin;
|
||||
|
||||
// Sets up the error message
|
||||
let msg = browserBundle.formatStringFromName("social.error.message", [productName, providerName], 2);
|
||||
|
|
|
@ -45,6 +45,7 @@ ul {
|
|||
|
||||
#errorTryAgain {
|
||||
margin-top: 1.2em;
|
||||
min-width: 150px
|
||||
}
|
||||
|
||||
#errorContainer {
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
#endif
|
||||
<command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
|
||||
<command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
|
||||
<command id="Social:SharePage" oncommand="SocialShare.sharePage();" disabled="true"/>
|
||||
<command id="Social:SharePage" oncommand="SocialShare.sharePage();"/>
|
||||
<command id="Social:ToggleSidebar" oncommand="SocialSidebar.toggleSidebar();" hidden="true"/>
|
||||
<command id="Social:ToggleNotifications" oncommand="Social.toggleNotifications();" hidden="true"/>
|
||||
<command id="Social:Addons" oncommand="BrowserOpenAddonsMgr('addons://list/service');"/>
|
||||
|
|
|
@ -183,7 +183,7 @@ SocialUI = {
|
|||
// about:home or the share panel, we bypass the enable prompt. Any website
|
||||
// activation, such as from the activations directory or a providers website
|
||||
// will still get the prompt.
|
||||
_activationEventHandler: function SocialUI_activationHandler(e, aBypassUserEnable=false) {
|
||||
_activationEventHandler: function SocialUI_activationHandler(e, options={}) {
|
||||
let targetDoc;
|
||||
let node;
|
||||
if (e.target instanceof HTMLDocument) {
|
||||
|
@ -197,7 +197,9 @@ SocialUI = {
|
|||
if (!(targetDoc instanceof HTMLDocument))
|
||||
return;
|
||||
|
||||
if (!aBypassUserEnable && targetDoc.defaultView != content)
|
||||
// The share panel iframe will not match "content" so it passes a bypass
|
||||
// flag
|
||||
if (!options.bypassContentCheck && targetDoc.defaultView != content)
|
||||
return;
|
||||
|
||||
// If we are in PB mode, we silently do nothing (bug 829404 exists to
|
||||
|
@ -233,11 +235,25 @@ SocialUI = {
|
|||
if (provider.sidebarURL) {
|
||||
SocialSidebar.show(provider.origin);
|
||||
}
|
||||
if (provider.shareURL) {
|
||||
// make this new provider the selected provider. If the panel hasn't
|
||||
// been opened, we need to make the frame first.
|
||||
SocialShare._createFrame();
|
||||
SocialShare.iframe.setAttribute('src', 'data:text/plain;charset=utf8,');
|
||||
SocialShare.iframe.setAttribute('origin', provider.origin);
|
||||
// get the right button selected
|
||||
SocialShare.populateProviderMenu();
|
||||
if (SocialShare.panel.state == "open") {
|
||||
SocialShare.sharePage(provider.origin);
|
||||
}
|
||||
}
|
||||
if (provider.postActivationURL) {
|
||||
openUILinkIn(provider.postActivationURL, "tab");
|
||||
// if activated from an open share panel, we load the landing page in
|
||||
// a background tab
|
||||
gBrowser.loadOneTab(provider.postActivationURL, {inBackground: SocialShare.panel.state == "open"});
|
||||
}
|
||||
});
|
||||
}, aBypassUserEnable);
|
||||
}, options);
|
||||
},
|
||||
|
||||
showLearnMore: function() {
|
||||
|
@ -290,10 +306,10 @@ SocialUI = {
|
|||
// called on tab/urlbar/location changes and after customization. Update
|
||||
// anything that is tab specific.
|
||||
updateState: function() {
|
||||
SocialShare.update();
|
||||
if (!SocialUI.enabled)
|
||||
return;
|
||||
SocialMarks.update();
|
||||
SocialShare.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -434,6 +450,12 @@ SocialFlyout = {
|
|||
}
|
||||
|
||||
SocialShare = {
|
||||
get _dynamicResizer() {
|
||||
delete this._dynamicResizer;
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
return this._dynamicResizer;
|
||||
},
|
||||
|
||||
// Share panel may be attached to the overflow or menu button depending on
|
||||
// customization, we need to manage open state of the anchor.
|
||||
get anchor() {
|
||||
|
@ -452,15 +474,27 @@ SocialShare = {
|
|||
return this.panel.lastChild;
|
||||
},
|
||||
|
||||
get activationPanelEnabled () {
|
||||
// ability to pref off for release
|
||||
return Services.prefs.getBoolPref("social.share.activationPanelEnabled");
|
||||
},
|
||||
|
||||
_activationHandler: function(event) {
|
||||
if (!SocialShare.activationPanelEnabled)
|
||||
return;
|
||||
SocialUI._activationEventHandler(event, { bypassContentCheck: true, bypassInstallPanel: true });
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
if (this.iframe) {
|
||||
this.iframe.removeEventListener("ActivateSocialFeature", this._activationHandler, true, true);
|
||||
this.iframe.remove();
|
||||
}
|
||||
},
|
||||
|
||||
_createFrame: function() {
|
||||
let panel = this.panel;
|
||||
if (!SocialUI.enabled || this.iframe)
|
||||
if (this.iframe)
|
||||
return;
|
||||
this.panel.hidden = false;
|
||||
// create and initialize the panel for this window
|
||||
|
@ -472,6 +506,7 @@ SocialShare = {
|
|||
iframe.setAttribute("disableglobalhistory", "true");
|
||||
iframe.setAttribute("flex", "1");
|
||||
panel.appendChild(iframe);
|
||||
this.iframe.addEventListener("ActivateSocialFeature", this._activationHandler, true, true);
|
||||
this.populateProviderMenu();
|
||||
},
|
||||
|
||||
|
@ -481,11 +516,19 @@ SocialShare = {
|
|||
if (lastProviderOrigin) {
|
||||
provider = Social._getProviderFromOrigin(lastProviderOrigin);
|
||||
}
|
||||
// if we are able to activate a provider we don't need to do anything fancy
|
||||
// here, the user will land on the activation panel if no previously
|
||||
// selected provider is available.
|
||||
if (this.activationPanelEnabled)
|
||||
return provider;
|
||||
|
||||
// if they have a provider selected in the sidebar use that for the initial
|
||||
// default in share
|
||||
if (!provider)
|
||||
provider = SocialSidebar.provider;
|
||||
// if our provider has no shareURL, select the first one that does
|
||||
// if our provider has no shareURL, select the first one that does. If we
|
||||
// have no selected provider and activation is available, default to that
|
||||
// panel.
|
||||
if (!provider || !provider.shareURL) {
|
||||
let providers = [p for (p of Social.providers) if (p.shareURL)];
|
||||
provider = providers.length > 0 && providers[0];
|
||||
|
@ -498,17 +541,12 @@ SocialShare = {
|
|||
return;
|
||||
let providers = [p for (p of Social.providers) if (p.shareURL)];
|
||||
let hbox = document.getElementById("social-share-provider-buttons");
|
||||
// selectable providers are inserted before the provider-menu seperator,
|
||||
// remove any menuitems in that area
|
||||
while (hbox.firstChild) {
|
||||
// remove everything before the add-share-provider button (which should also
|
||||
// be lastChild if any share providers were added)
|
||||
let addButton = document.getElementById("add-share-provider");
|
||||
while (hbox.firstChild != addButton) {
|
||||
hbox.removeChild(hbox.firstChild);
|
||||
}
|
||||
// reset our share toolbar
|
||||
// only show a selection if there is more than one
|
||||
if (!SocialUI.enabled || providers.length < 2) {
|
||||
this.panel.firstChild.hidden = true;
|
||||
return;
|
||||
}
|
||||
let selectedProvider = this.getSelectedProvider();
|
||||
for (let provider of providers) {
|
||||
let button = document.createElement("toolbarbutton");
|
||||
|
@ -518,17 +556,16 @@ SocialShare = {
|
|||
button.setAttribute("image", provider.iconURL);
|
||||
button.setAttribute("tooltiptext", provider.name);
|
||||
button.setAttribute("origin", provider.origin);
|
||||
button.setAttribute("oncommand", "SocialShare.sharePage(this.getAttribute('origin')); this.checked=true;");
|
||||
button.setAttribute("oncommand", "SocialShare.sharePage(this.getAttribute('origin'));");
|
||||
if (provider == selectedProvider) {
|
||||
this.defaultButton = button;
|
||||
}
|
||||
hbox.appendChild(button);
|
||||
hbox.insertBefore(button, addButton);
|
||||
}
|
||||
if (!this.defaultButton) {
|
||||
this.defaultButton = hbox.firstChild
|
||||
this.defaultButton = this.activationPanelEnabled ? addButton : hbox.firstChild;
|
||||
}
|
||||
this.defaultButton.setAttribute("checked", "true");
|
||||
this.panel.firstChild.hidden = false;
|
||||
},
|
||||
|
||||
get shareButton() {
|
||||
|
@ -560,8 +597,8 @@ SocialShare = {
|
|||
let shareButton = widget.forWindow(window).node;
|
||||
// hidden state is based on available share providers and location of
|
||||
// button. It's always visible and disabled in the customization palette.
|
||||
shareButton.hidden = !SocialUI.enabled || (widget.areaType &&
|
||||
[p for (p of Social.providers) if (p.shareURL)].length == 0);
|
||||
shareButton.hidden = !this.activationPanelEnabled && (!SocialUI.enabled || (widget.areaType &&
|
||||
[p for (p of Social.providers) if (p.shareURL)].length == 0));
|
||||
let disabled = !widget.areaType || shareButton.hidden || !this.canSharePage(gBrowser.currentURI);
|
||||
|
||||
// 1. update the relevent command's disabled state so the keyboard
|
||||
|
@ -577,6 +614,9 @@ SocialShare = {
|
|||
cmd.removeAttribute("disabled");
|
||||
shareButton.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
// enable or disable the activation panel
|
||||
document.getElementById("add-share-provider").hidden = !this.activationPanelEnabled;
|
||||
},
|
||||
|
||||
_onclick: function() {
|
||||
|
@ -608,10 +648,15 @@ SocialShare = {
|
|||
if (!iframe)
|
||||
return;
|
||||
|
||||
iframe.removeAttribute("src");
|
||||
iframe.webNavigation.loadURI("about:socialerror?mode=compactInfo&origin=" +
|
||||
encodeURIComponent(iframe.getAttribute("origin")),
|
||||
null, null, null, null);
|
||||
let url;
|
||||
let origin = iframe.getAttribute("origin");
|
||||
if (!origin && this.activationPanelEnabled) {
|
||||
// directory site is down
|
||||
url = "about:socialerror?mode=tryAgainOnly&directory=1&url=" + encodeURIComponent(iframe.getAttribute("src"));
|
||||
} else {
|
||||
url = "about:socialerror?mode=compactInfo&origin=" + encodeURIComponent(origin);
|
||||
}
|
||||
iframe.webNavigation.loadURI(url, null, null, null, null);
|
||||
sizeSocialPanelToContent(this.panel, iframe);
|
||||
},
|
||||
|
||||
|
@ -621,13 +666,6 @@ SocialShare = {
|
|||
// will call sharePage with an origin for us to switch to.
|
||||
this._createFrame();
|
||||
let iframe = this.iframe;
|
||||
let provider;
|
||||
if (providerOrigin)
|
||||
provider = Social._getProviderFromOrigin(providerOrigin);
|
||||
else
|
||||
provider = this.getSelectedProvider();
|
||||
if (!provider || !provider.shareURL)
|
||||
return;
|
||||
|
||||
// graphData is an optional param that either defines the full set of data
|
||||
// to be shared, or partial data about the current page. It is set by a call
|
||||
|
@ -659,20 +697,25 @@ SocialShare = {
|
|||
}
|
||||
this.currentShare = pageData;
|
||||
|
||||
let provider;
|
||||
if (providerOrigin)
|
||||
provider = Social._getProviderFromOrigin(providerOrigin);
|
||||
else
|
||||
provider = this.getSelectedProvider();
|
||||
if (!provider || !provider.shareURL) {
|
||||
this.showDirectory();
|
||||
return;
|
||||
}
|
||||
// check the menu button
|
||||
let hbox = document.getElementById("social-share-provider-buttons");
|
||||
let btn = hbox.querySelector("[origin='" + provider.origin + "']");
|
||||
btn.checked = true;
|
||||
|
||||
let shareEndpoint = OpenGraphBuilder.generateEndpointURL(provider.shareURL, pageData);
|
||||
|
||||
let size = provider.getPageSize("share");
|
||||
if (size) {
|
||||
if (this._dynamicResizer) {
|
||||
this._dynamicResizer.stop();
|
||||
this._dynamicResizer = null;
|
||||
}
|
||||
let {width, height} = size;
|
||||
width += this.panel.boxObject.width - iframe.boxObject.width;
|
||||
height += this.panel.boxObject.height - iframe.boxObject.height;
|
||||
this.panel.sizeTo(width, height);
|
||||
} else {
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
}
|
||||
|
||||
// if we've already loaded this provider/page share endpoint, we don't want
|
||||
|
@ -684,7 +727,7 @@ SocialShare = {
|
|||
reload = shareEndpoint != iframe.contentDocument.location.spec;
|
||||
}
|
||||
if (!reload) {
|
||||
if (this._dynamicResizer)
|
||||
if (!size)
|
||||
this._dynamicResizer.start(this.panel, iframe);
|
||||
iframe.docShell.isActive = true;
|
||||
iframe.docShell.isAppTab = true;
|
||||
|
@ -702,7 +745,13 @@ SocialShare = {
|
|||
// should close the window when done.
|
||||
iframe.contentWindow.opener = iframe.contentWindow;
|
||||
setTimeout(function() {
|
||||
if (SocialShare._dynamicResizer) { // may go null if hidden quickly
|
||||
if (size) {
|
||||
let panel = SocialShare.panel;
|
||||
let {width, height} = size;
|
||||
width += panel.boxObject.width - iframe.boxObject.width;
|
||||
height += panel.boxObject.height - iframe.boxObject.height;
|
||||
panel.sizeTo(width, height);
|
||||
} else {
|
||||
SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
|
||||
}
|
||||
}, 0);
|
||||
|
@ -723,10 +772,32 @@ SocialShare = {
|
|||
let uri = Services.io.newURI(shareEndpoint, null, null);
|
||||
iframe.setAttribute("origin", provider.origin);
|
||||
iframe.setAttribute("src", shareEndpoint);
|
||||
this._openPanel();
|
||||
},
|
||||
|
||||
showDirectory: function() {
|
||||
let url = Services.prefs.getCharPref("social.shareDirectory");
|
||||
this._createFrame();
|
||||
let iframe = this.iframe;
|
||||
iframe.removeAttribute("origin");
|
||||
iframe.setAttribute("src", url);
|
||||
iframe.addEventListener("load", function panelBrowserOnload(e) {
|
||||
iframe.removeEventListener("load", panelBrowserOnload, true);
|
||||
SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
|
||||
|
||||
iframe.addEventListener("unload", function panelBrowserOnload(e) {
|
||||
iframe.removeEventListener("unload", panelBrowserOnload, true);
|
||||
SocialShare._dynamicResizer.stop();
|
||||
}, true);
|
||||
|
||||
}, true);
|
||||
this._openPanel();
|
||||
},
|
||||
|
||||
_openPanel: function() {
|
||||
let anchor = document.getAnonymousElementByAttribute(this.anchor, "class", "toolbarbutton-icon");
|
||||
this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
Social.setErrorListener(iframe, this.setErrorMessage.bind(this));
|
||||
Social.setErrorListener(this.iframe, this.setErrorMessage.bind(this));
|
||||
Services.telemetry.getHistogramById("SOCIAL_TOOLBAR_BUTTONS").add(0);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -320,6 +320,14 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
|
|||
min-width: 25ch;
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
.searchbar-engine-image,
|
||||
.searchbar-engine-menuitem > .menu-iconic-left > .menu-iconic-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
#urlbar,
|
||||
.searchbar-textbox {
|
||||
/* Setting a width and min-width to let the location & search bars maintain
|
||||
|
@ -472,6 +480,20 @@ toolbarbutton.bookmark-item {
|
|||
max-width: 13em;
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
.alltabs-popup > .menuitem-iconic > .menu-iconic-left > .menu-iconic-icon,
|
||||
.menuitem-with-favicon > .menu-iconic-left > .menu-iconic-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
|
||||
.bookmark-item > .toolbarbutton-icon,
|
||||
.bookmark-item > .menu-iconic-left > .menu-iconic-icon,
|
||||
#personal-bookmarks[cui-areatype="toolbar"] > #bookmarks-toolbar-placeholder > .toolbarbutton-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
#editBMPanel_tagsSelector {
|
||||
/* override default listbox width from xul.css */
|
||||
width: auto;
|
||||
|
@ -629,6 +651,13 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
|||
height: 16px;
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
.ctrlTab-favicon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
.ctrlTab-preview {
|
||||
-moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#ctrlTab-preview");
|
||||
}
|
||||
|
@ -832,6 +861,15 @@ chatbar {
|
|||
max-height: 0;
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
#social-sidebar-favico,
|
||||
.social-status-button,
|
||||
.chat-status-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
/** See bug 872317 for why the following rule is necessary. */
|
||||
|
||||
#downloads-button {
|
||||
|
@ -1000,6 +1038,15 @@ chatbox:-moz-full-screen-ancestor > .chat-titlebar {
|
|||
list-style-image: none;
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
#PanelUI-recentlyClosedWindows > toolbarbutton > .toolbarbutton-icon,
|
||||
#PanelUI-recentlyClosedTabs > toolbarbutton > .toolbarbutton-icon,
|
||||
#PanelUI-historyItems > toolbarbutton > .toolbarbutton-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
#customization-panelHolder {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
|
|
@ -246,7 +246,11 @@
|
|||
onpopuphidden="SocialShare.onHidden()"
|
||||
hidden="true">
|
||||
<vbox class="social-share-toolbar">
|
||||
<arrowscrollbox id="social-share-provider-buttons" orient="vertical" flex="1"/>
|
||||
<arrowscrollbox id="social-share-provider-buttons" orient="vertical" flex="1">
|
||||
<toolbarbutton id="add-share-provider" class="toolbarbutton share-provider-button" type="radio"
|
||||
group="share-providers" tooltiptext="&findShareServices.label;"
|
||||
oncommand="SocialShare.showDirectory()"/>
|
||||
</arrowscrollbox>
|
||||
</vbox>
|
||||
</panel>
|
||||
|
||||
|
|
|
@ -334,7 +334,7 @@ nsContextMenu.prototype = {
|
|||
let shareEnabled = shareButton && !shareButton.disabled && !this.onSocial;
|
||||
let pageShare = shareEnabled && !(this.isContentSelected ||
|
||||
this.onTextInput || this.onLink || this.onImage ||
|
||||
this.onVideo || this.onAudio);
|
||||
this.onVideo || this.onAudio || this.onCanvas);
|
||||
this.showItem("context-sharepage", pageShare);
|
||||
this.showItem("context-shareselect", shareEnabled && this.isContentSelected);
|
||||
this.showItem("context-sharelink", shareEnabled && (this.onLink || this.onPlainTextLink) && !this.onMailtoLink);
|
||||
|
|
|
@ -44,6 +44,13 @@ tabpanels {
|
|||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
.tab-icon-image {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-icon-image:not([src]):not([pinned]),
|
||||
.tab-throbber:not([busy]),
|
||||
.tab-throbber[busy] + .tab-icon-image {
|
||||
|
|
|
@ -89,6 +89,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for text");
|
||||
// Context menu for plain text
|
||||
plainTextItems = ["context-navigation", null,
|
||||
["context-back", false,
|
||||
|
@ -96,6 +97,7 @@ function runTest(testNum) {
|
|||
"context-reload", true,
|
||||
"context-bookmarkpage", true], null,
|
||||
"---", null,
|
||||
"context-sharepage", true,
|
||||
"context-savepage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
|
@ -110,6 +112,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for text link");
|
||||
// Context menu for text link
|
||||
if (perWindowPrivateBrowsing) {
|
||||
checkContextMenu(["context-openlinkintab", true,
|
||||
|
@ -117,6 +120,7 @@ function runTest(testNum) {
|
|||
"context-openlinkprivate", true,
|
||||
"---", null,
|
||||
"context-bookmarklink", true,
|
||||
"context-sharelink", true,
|
||||
"context-savelink", true,
|
||||
"context-copylink", true,
|
||||
"context-searchselect", true
|
||||
|
@ -126,6 +130,7 @@ function runTest(testNum) {
|
|||
"context-openlink", true,
|
||||
"---", null,
|
||||
"context-bookmarklink", true,
|
||||
"context-sharelink", true,
|
||||
"context-savelink", true,
|
||||
"context-copylink", true,
|
||||
"context-searchselect", true
|
||||
|
@ -136,6 +141,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for mailto link");
|
||||
// Context menu for text mailto-link
|
||||
checkContextMenu(["context-copyemail", true,
|
||||
"context-searchselect", true
|
||||
|
@ -145,12 +151,14 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for image");
|
||||
// Context menu for an image
|
||||
checkContextMenu(["context-viewimage", true,
|
||||
"context-copyimage-contents", true,
|
||||
"context-copyimage", true,
|
||||
"---", null,
|
||||
"context-saveimage", true,
|
||||
"context-shareimage", true,
|
||||
"context-sendimage", true,
|
||||
"context-setDesktopBackground", true,
|
||||
"context-viewimageinfo", true
|
||||
|
@ -160,6 +168,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for canvas");
|
||||
// Context menu for a canvas
|
||||
checkContextMenu(["context-viewimage", true,
|
||||
"context-saveimage", true,
|
||||
|
@ -170,6 +179,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for video_ok");
|
||||
// Context menu for a video (with a VALID media source)
|
||||
checkContextMenu(["context-media-play", true,
|
||||
"context-media-mute", true,
|
||||
|
@ -186,6 +196,7 @@ function runTest(testNum) {
|
|||
"context-copyvideourl", true,
|
||||
"---", null,
|
||||
"context-savevideo", true,
|
||||
"context-sharevideo", true,
|
||||
"context-video-saveimage", true,
|
||||
"context-sendvideo", true
|
||||
].concat(inspectItems));
|
||||
|
@ -194,6 +205,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for audio_in_video");
|
||||
// Context menu for a video (with an audio-only file)
|
||||
checkContextMenu(["context-media-play", true,
|
||||
"context-media-mute", true,
|
||||
|
@ -214,6 +226,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for video_bad");
|
||||
// Context menu for a video (with an INVALID media source)
|
||||
checkContextMenu(["context-media-play", false,
|
||||
"context-media-mute", false,
|
||||
|
@ -230,6 +243,7 @@ function runTest(testNum) {
|
|||
"context-copyvideourl", true,
|
||||
"---", null,
|
||||
"context-savevideo", true,
|
||||
"context-sharevideo", true,
|
||||
"context-video-saveimage", false,
|
||||
"context-sendvideo", true
|
||||
].concat(inspectItems));
|
||||
|
@ -238,6 +252,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for video_bad2");
|
||||
// Context menu for a video (with an INVALID media source)
|
||||
checkContextMenu(["context-media-play", false,
|
||||
"context-media-mute", false,
|
||||
|
@ -254,6 +269,7 @@ function runTest(testNum) {
|
|||
"context-copyvideourl", false,
|
||||
"---", null,
|
||||
"context-savevideo", false,
|
||||
"context-sharevideo", false,
|
||||
"context-video-saveimage", false,
|
||||
"context-sendvideo", false
|
||||
].concat(inspectItems));
|
||||
|
@ -262,6 +278,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for iframe");
|
||||
// Context menu for an iframe
|
||||
checkContextMenu(["context-navigation", null,
|
||||
["context-back", false,
|
||||
|
@ -269,6 +286,7 @@ function runTest(testNum) {
|
|||
"context-reload", true,
|
||||
"context-bookmarkpage", true], null,
|
||||
"---", null,
|
||||
"context-sharepage", true,
|
||||
"context-savepage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
|
@ -296,6 +314,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for video_in_iframe");
|
||||
// Context menu for a video in an iframe
|
||||
checkContextMenu(["context-media-play", true,
|
||||
"context-media-mute", true,
|
||||
|
@ -312,6 +331,7 @@ function runTest(testNum) {
|
|||
"context-copyvideourl", true,
|
||||
"---", null,
|
||||
"context-savevideo", true,
|
||||
"context-sharevideo", true,
|
||||
"context-video-saveimage", true,
|
||||
"context-sendvideo", true,
|
||||
"frame", null,
|
||||
|
@ -332,12 +352,14 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for image_in_iframe");
|
||||
// Context menu for an image in an iframe
|
||||
checkContextMenu(["context-viewimage", true,
|
||||
"context-copyimage-contents", true,
|
||||
"context-copyimage", true,
|
||||
"---", null,
|
||||
"context-saveimage", true,
|
||||
"context-shareimage", true,
|
||||
"context-sendimage", true,
|
||||
"context-setDesktopBackground", true,
|
||||
"context-viewimageinfo", true,
|
||||
|
@ -359,6 +381,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for textarea");
|
||||
// Context menu for textarea before spell check initialization finishes
|
||||
checkContextMenu(["context-undo", false,
|
||||
"---", null,
|
||||
|
@ -376,6 +399,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for textarea, wait for spell check");
|
||||
// Context menu for textarea after spell check initialization finishes
|
||||
checkContextMenu(["*chubbiness", true, // spelling suggestion
|
||||
"spell-add-to-dictionary", true,
|
||||
|
@ -401,6 +425,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for text");
|
||||
// Re-check context menu for plain text to make sure it hasn't changed
|
||||
checkContextMenu(plainTextItems);
|
||||
closeContextMenu();
|
||||
|
@ -408,6 +433,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for textarea after word added");
|
||||
// Context menu for textarea after a word has been added
|
||||
// to the dictionary
|
||||
checkContextMenu(["spell-undo-add-to-dictionary", true,
|
||||
|
@ -433,6 +459,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for contenteditable");
|
||||
// Context menu for contenteditable
|
||||
checkContextMenu(["spell-no-suggestions", false,
|
||||
"spell-add-to-dictionary", true,
|
||||
|
@ -458,12 +485,14 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for link");
|
||||
executeCopyCommand("cmd_copyLink", "http://mozilla.com/");
|
||||
closeContextMenu();
|
||||
openContextMenuFor(pagemenu); // Invoke context menu for next test.
|
||||
},
|
||||
|
||||
function () {
|
||||
info("context menu for pagemenu");
|
||||
// Context menu for element with assigned content context menu
|
||||
checkContextMenu(["context-navigation", null,
|
||||
["context-back", false,
|
||||
|
@ -491,6 +520,7 @@ function runTest(testNum) {
|
|||
"---", null,
|
||||
"+Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}], null,
|
||||
"---", null,
|
||||
"context-sharepage", true,
|
||||
"context-savepage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
|
@ -516,6 +546,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for fullscreen mode");
|
||||
// Context menu for DOM Fullscreen mode (NOTE: this is *NOT* on an img)
|
||||
checkContextMenu(["context-navigation", null,
|
||||
["context-back", false,
|
||||
|
@ -525,6 +556,7 @@ function runTest(testNum) {
|
|||
"---", null,
|
||||
"context-leave-dom-fullscreen", true,
|
||||
"---", null,
|
||||
"context-sharepage", true,
|
||||
"context-savepage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
|
@ -546,6 +578,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for element with assigned content context menu");
|
||||
// Context menu for element with assigned content context menu
|
||||
// The shift key should bypass content context menu processing
|
||||
checkContextMenu(["context-navigation", null,
|
||||
|
@ -554,6 +587,7 @@ function runTest(testNum) {
|
|||
"context-reload", true,
|
||||
"context-bookmarkpage", true], null,
|
||||
"---", null,
|
||||
"context-sharepage", true,
|
||||
"context-savepage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
|
@ -568,6 +602,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for text selection");
|
||||
// Context menu for selected text
|
||||
if (SpecialPowers.Services.appinfo.OS == "Darwin") {
|
||||
// This test is only enabled on Mac due to bug 736399.
|
||||
|
@ -575,6 +610,7 @@ function runTest(testNum) {
|
|||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-searchselect", true,
|
||||
"context-shareselect", true,
|
||||
"context-viewpartialsource-selection", true
|
||||
].concat(inspectItems));
|
||||
}
|
||||
|
@ -584,6 +620,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for text selection with url pattern");
|
||||
// Context menu for selected text which matches valid URL pattern
|
||||
if (SpecialPowers.Services.appinfo.OS == "Darwin") {
|
||||
// This test is only enabled on Mac due to bug 736399.
|
||||
|
@ -594,11 +631,13 @@ function runTest(testNum) {
|
|||
"context-openlinkprivate", true,
|
||||
"---", null,
|
||||
"context-bookmarklink", true,
|
||||
"context-sharelink", true,
|
||||
"context-savelink", true,
|
||||
"context-copy", true,
|
||||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-searchselect", true,
|
||||
"context-shareselect", true,
|
||||
"context-viewpartialsource-selection", true
|
||||
].concat(inspectItems));
|
||||
} else {
|
||||
|
@ -607,11 +646,13 @@ function runTest(testNum) {
|
|||
"context-openlink", true,
|
||||
"---", null,
|
||||
"context-bookmarklink", true,
|
||||
"context-sharelink", true,
|
||||
"context-savelink", true,
|
||||
"context-copy", true,
|
||||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-searchselect", true,
|
||||
"context-shareselect", true,
|
||||
"context-viewpartialsource-selection", true
|
||||
].concat(inspectItems));
|
||||
}
|
||||
|
@ -624,6 +665,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for imagelink");
|
||||
// Context menu for image link
|
||||
if (perWindowPrivateBrowsing) {
|
||||
checkContextMenu(["context-openlinkintab", true,
|
||||
|
@ -631,6 +673,7 @@ function runTest(testNum) {
|
|||
"context-openlinkprivate", true,
|
||||
"---", null,
|
||||
"context-bookmarklink", true,
|
||||
"context-sharelink", true,
|
||||
"context-savelink", true,
|
||||
"context-copylink", true,
|
||||
"---", null,
|
||||
|
@ -639,6 +682,7 @@ function runTest(testNum) {
|
|||
"context-copyimage", true,
|
||||
"---", null,
|
||||
"context-saveimage", true,
|
||||
"context-shareimage", true,
|
||||
"context-sendimage", true,
|
||||
"context-setDesktopBackground", true,
|
||||
"context-viewimageinfo", true
|
||||
|
@ -648,6 +692,7 @@ function runTest(testNum) {
|
|||
"context-openlink", true,
|
||||
"---", null,
|
||||
"context-bookmarklink", true,
|
||||
"context-sharelink", true,
|
||||
"context-savelink", true,
|
||||
"context-copylink", true,
|
||||
"---", null,
|
||||
|
@ -656,6 +701,7 @@ function runTest(testNum) {
|
|||
"context-copyimage", true,
|
||||
"---", null,
|
||||
"context-saveimage", true,
|
||||
"context-shareimage", true,
|
||||
"context-sendimage", true,
|
||||
"context-setDesktopBackground", true,
|
||||
"context-viewimageinfo", true
|
||||
|
@ -667,6 +713,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for select_inputtext");
|
||||
// Context menu for selected text in input
|
||||
checkContextMenu(["context-undo", false,
|
||||
"---", null,
|
||||
|
@ -686,6 +733,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for selected text in input[type='password']");
|
||||
// Context menu for selected text in input[type="password"]
|
||||
checkContextMenu(["context-undo", false,
|
||||
"---", null,
|
||||
|
@ -709,6 +757,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for click-to-play blocked plugin");
|
||||
// Context menu for click-to-play blocked plugin
|
||||
checkContextMenu(["context-navigation", null,
|
||||
["context-back", false,
|
||||
|
@ -719,6 +768,7 @@ function runTest(testNum) {
|
|||
"context-ctp-play", true,
|
||||
"context-ctp-hide", true,
|
||||
"---", null,
|
||||
"context-sharepage", true,
|
||||
"context-savepage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
|
@ -734,12 +784,14 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for image with longdesc");
|
||||
// Context menu for an image with longdesc
|
||||
checkContextMenu(["context-viewimage", true,
|
||||
"context-copyimage-contents", true,
|
||||
"context-copyimage", true,
|
||||
"---", null,
|
||||
"context-saveimage", true,
|
||||
"context-shareimage", true,
|
||||
"context-sendimage", true,
|
||||
"context-setDesktopBackground", true,
|
||||
"context-viewimageinfo", true,
|
||||
|
@ -750,6 +802,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for iframe with srcdoc attribute set");
|
||||
// Context menu for an iframe with srcdoc attribute set
|
||||
checkContextMenu(["context-navigation", null,
|
||||
["context-back", false,
|
||||
|
@ -757,6 +810,7 @@ function runTest(testNum) {
|
|||
"context-reload", true,
|
||||
"context-bookmarkpage", true], null,
|
||||
"---", null,
|
||||
"context-sharepage", true,
|
||||
"context-savepage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
|
@ -779,6 +833,7 @@ function runTest(testNum) {
|
|||
},
|
||||
|
||||
function () {
|
||||
info("context menu for text input field with spellcheck=false");
|
||||
// Context menu for text input field with spellcheck=false
|
||||
checkContextMenu(["context-undo", false,
|
||||
"---", null,
|
||||
|
|
|
@ -198,6 +198,7 @@ function runTest(testNum) {
|
|||
"context-reload", true,
|
||||
"context-bookmarkpage", true], null,
|
||||
"---", null,
|
||||
"context-sharepage", true,
|
||||
"context-savepage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
|
|
|
@ -11,6 +11,7 @@ support-files =
|
|||
opengraph/shorturl_linkrel.html
|
||||
microdata.html
|
||||
share.html
|
||||
share_activate.html
|
||||
social_activate.html
|
||||
social_activate_iframe.html
|
||||
social_chat.html
|
||||
|
|
|
@ -10,10 +10,46 @@ let manifest = { // normal provider
|
|||
iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png",
|
||||
shareURL: "https://example.com/browser/browser/base/content/test/social/share.html"
|
||||
};
|
||||
let activationPage = "https://example.com/browser/browser/base/content/test/social/share_activate.html";
|
||||
|
||||
function waitForProviderEnabled(cb) {
|
||||
Services.obs.addObserver(function providerSet(subject, topic, data) {
|
||||
Services.obs.removeObserver(providerSet, "social:provider-enabled");
|
||||
info("social:provider-enabled observer was notified");
|
||||
cb();
|
||||
}, "social:provider-enabled", false);
|
||||
}
|
||||
|
||||
function sendActivationEvent(callback) {
|
||||
// hack Social.lastEventReceived so we don't hit the "too many events" check.
|
||||
Social.lastEventReceived = 0;
|
||||
let doc = SocialShare.iframe.contentDocument;
|
||||
// if our test has a frame, use it
|
||||
let button = doc.getElementById("activation");
|
||||
ok(!!button, "got the activation button");
|
||||
EventUtils.synthesizeMouseAtCenter(button, {}, doc.defaultView);
|
||||
if (callback)
|
||||
executeSoon(callback);
|
||||
}
|
||||
|
||||
function waitForEvent(iframe, eventName, callback) {
|
||||
iframe.addEventListener(eventName, function load() {
|
||||
info("page load is "+iframe.contentDocument.location.href);
|
||||
if (iframe.contentDocument.location.href != "data:text/plain;charset=utf8,") {
|
||||
iframe.removeEventListener(eventName, load, true);
|
||||
executeSoon(callback);
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setCharPref("social.shareDirectory", activationPage);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref("social.directories");
|
||||
Services.prefs.clearUserPref("social.shareDirectory");
|
||||
Services.prefs.clearUserPref("social.share.activationPanelEnabled");
|
||||
});
|
||||
runSocialTests(tests);
|
||||
}
|
||||
|
||||
|
@ -75,11 +111,10 @@ let corpus = [
|
|||
function loadURLInTab(url, callback) {
|
||||
info("Loading tab with "+url);
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
|
||||
tab.linkedBrowser.addEventListener("load", function listener() {
|
||||
waitForEvent(tab.linkedBrowser, "load", () => {
|
||||
is(tab.linkedBrowser.currentURI.spec, url, "tab loaded")
|
||||
tab.linkedBrowser.removeEventListener("load", listener, true);
|
||||
executeSoon(function() { callback(tab) });
|
||||
}, true);
|
||||
callback(tab)
|
||||
});
|
||||
}
|
||||
|
||||
function hasoptions(testOptions, options) {
|
||||
|
@ -110,7 +145,6 @@ var tests = {
|
|||
checkSocialUI();
|
||||
// share should not be enabled since we only have about:blank page
|
||||
let shareButton = SocialShare.shareButton;
|
||||
is(shareButton.disabled, true, "share button is disabled");
|
||||
// verify the attribute for proper css
|
||||
is(shareButton.getAttribute("disabled"), "true", "share button attribute is disabled");
|
||||
// button should be visible
|
||||
|
@ -128,7 +162,6 @@ var tests = {
|
|||
checkSocialUI();
|
||||
// share should not be enabled since we only have about:blank page
|
||||
let shareButton = SocialShare.shareButton;
|
||||
is(shareButton.disabled, false, "share button is enabled");
|
||||
// verify the attribute for proper css
|
||||
ok(!shareButton.hasAttribute("disabled"), "share button is enabled");
|
||||
// button should be visible
|
||||
|
@ -149,7 +182,7 @@ var tests = {
|
|||
function runOneTest() {
|
||||
loadURLInTab(testData.url, function(tab) {
|
||||
testTab = tab;
|
||||
SocialShare.sharePage();
|
||||
SocialShare.sharePage(manifest.origin);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -241,5 +274,46 @@ var tests = {
|
|||
SocialShare.sharePage(manifest.origin, null, target);
|
||||
});
|
||||
});
|
||||
},
|
||||
testSharePanelActivation: function(next) {
|
||||
let testTab;
|
||||
// cleared in the cleanup function
|
||||
Services.prefs.setCharPref("social.directories", "https://example.com");
|
||||
Services.prefs.setBoolPref("social.share.activationPanelEnabled", true);
|
||||
// make the iframe so we can wait on the load
|
||||
SocialShare._createFrame();
|
||||
let iframe = SocialShare.iframe;
|
||||
|
||||
waitForEvent(iframe, "load", () => {
|
||||
waitForCondition(() => {
|
||||
// sometimes the iframe is ready before the panel is open, we need to
|
||||
// wait for both conditions
|
||||
return SocialShare.panel.state == "open";
|
||||
}, () => {
|
||||
is(iframe.contentDocument.location.href, activationPage, "activation page loaded");
|
||||
waitForProviderEnabled(() => {
|
||||
let provider = Social._getProviderFromOrigin(manifest.origin);
|
||||
let port = provider.getWorkerPort();
|
||||
ok(!!port, "got port");
|
||||
port.onmessage = function (e) {
|
||||
let topic = e.data.topic;
|
||||
info("got topic "+topic+"\n");
|
||||
switch (topic) {
|
||||
case "got-share-data-message":
|
||||
ok(true, "share completed");
|
||||
gBrowser.removeTab(testTab);
|
||||
SocialService.uninstallProvider(manifest.origin, next);
|
||||
break;
|
||||
}
|
||||
}
|
||||
port.postMessage({topic: "test-init"});
|
||||
});
|
||||
sendActivationEvent();
|
||||
}, "share panel did not open and load share page");
|
||||
});
|
||||
loadURLInTab(activationPage, function(tab) {
|
||||
testTab = tab;
|
||||
SocialShare.sharePage();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<html>
|
||||
<!-- 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/. -->
|
||||
<head>
|
||||
<title>Activation test</title>
|
||||
</head>
|
||||
<script>
|
||||
|
||||
var data = {
|
||||
// currently required
|
||||
"name": "Demo Social Service",
|
||||
// browser_share.js serves this page from "https://example.com"
|
||||
"origin": "https://example.com",
|
||||
"iconURL": "chrome://branding/content/icon16.png",
|
||||
"icon32URL": "chrome://branding/content/favicon32.png",
|
||||
"icon64URL": "chrome://branding/content/icon64.png",
|
||||
"workerURL": "/browser/browser/base/content/test/social/social_worker.js",
|
||||
"shareURL": "/browser/browser/base/content/test/social/share.html"
|
||||
}
|
||||
|
||||
function activate(node) {
|
||||
node.setAttribute("data-service", JSON.stringify(data));
|
||||
var event = new CustomEvent("ActivateSocialFeature");
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
|
||||
</script>
|
||||
<body>
|
||||
|
||||
nothing to see here
|
||||
|
||||
<button id="activation" onclick="activate(this, true)">Activate the share provider</button>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -166,6 +166,7 @@ let CustomizableUIInternal = {
|
|||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button",
|
||||
"social-share-button",
|
||||
];
|
||||
|
||||
if (gPalette.has("switch-to-metro-button")) {
|
||||
|
@ -207,7 +208,6 @@ let CustomizableUIInternal = {
|
|||
"downloads-button",
|
||||
"home-button",
|
||||
"loop-call-button",
|
||||
"social-share-button",
|
||||
],
|
||||
defaultCollapsed: false,
|
||||
}, true);
|
||||
|
|
|
@ -27,7 +27,7 @@ add_task(function testWrapUnwrap() {
|
|||
// Creating and destroying a widget should correctly deal with panel placeholders
|
||||
add_task(function testPanelPlaceholders() {
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
is(panel.querySelectorAll(".panel-customization-placeholder").length, isInWin8() ? 1 : 2, "The number of placeholders should be correct.");
|
||||
is(panel.querySelectorAll(".panel-customization-placeholder").length, isInWin8() ? 3 : 1, "The number of placeholders should be correct.");
|
||||
CustomizableUI.createWidget({id: kTestWidget2, label: 'Pretty label', tooltiptext: 'Pretty tooltip', defaultArea: CustomizableUI.AREA_PANEL});
|
||||
let elem = document.getElementById(kTestWidget2);
|
||||
let wrapper = document.getElementById("wrapper-" + kTestWidget2);
|
||||
|
@ -35,7 +35,7 @@ add_task(function testPanelPlaceholders() {
|
|||
ok(wrapper, "There should be a wrapper");
|
||||
is(wrapper.firstChild.id, kTestWidget2, "Wrapper should have test widget");
|
||||
is(wrapper.parentNode, panel, "Wrapper should be in panel");
|
||||
is(panel.querySelectorAll(".panel-customization-placeholder").length, isInWin8() ? 3 : 1, "The number of placeholders should be correct.");
|
||||
is(panel.querySelectorAll(".panel-customization-placeholder").length, isInWin8() ? 2 : 3, "The number of placeholders should be correct.");
|
||||
CustomizableUI.destroyWidget(kTestWidget2);
|
||||
wrapper = document.getElementById("wrapper-" + kTestWidget2);
|
||||
ok(!wrapper, "There should be a wrapper");
|
||||
|
|
|
@ -22,7 +22,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(zoomControls, printButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -48,7 +49,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(zoomControls, savePageButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -72,7 +74,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(zoomControls, newWindowButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -95,7 +98,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(zoomControls, historyPanelMenu);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -122,7 +126,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(zoomControls, preferencesButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -149,7 +154,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterInsert);
|
||||
simulateItemDrag(openFileButton, zoomControls);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterInsert);
|
||||
|
@ -188,7 +194,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterInsert);
|
||||
simulateItemDrag(openFileButton, editControls);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterInsert);
|
||||
|
@ -224,7 +231,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(editControls, zoomControls);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -248,7 +256,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(editControls, newWindowButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -275,7 +284,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(editControls, privateBrowsingButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -302,7 +312,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(editControls, savePageButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -328,7 +339,8 @@ add_task(function() {
|
|||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"edit-controls",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(editControls, panel);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -353,7 +365,8 @@ add_task(function() {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
let paletteChildElementCount = palette.childElementCount;
|
||||
simulateItemDrag(editControls, palette);
|
||||
|
@ -377,7 +390,8 @@ add_task(function() {
|
|||
yield startCustomizing();
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
let numPlaceholders = isInWin8() ? 1 : 2;
|
||||
let numPlaceholders = isInWin8() ? 3 : 1;
|
||||
is(numPlaceholders, panel.getElementsByClassName("panel-customization-placeholder").length, "correct number of placeholders");
|
||||
for (let i = 0; i < numPlaceholders; i++) {
|
||||
// NB: We can't just iterate over all of the placeholders
|
||||
// because each drag-drop action recreates them.
|
||||
|
@ -393,7 +407,8 @@ add_task(function() {
|
|||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"edit-controls",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
simulateItemDrag(editControls, placeholder);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
@ -423,6 +438,8 @@ add_task(function() {
|
|||
yield startCustomizing();
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
let numPlaceholders = isInWin8() ? 3 : 1;
|
||||
is(panel.getElementsByClassName("panel-customization-placeholder").length, numPlaceholders, "correct number of placeholders");
|
||||
let target = panel.getElementsByClassName("panel-customization-placeholder")[0];
|
||||
let placementsAfterMove = ["zoom-controls",
|
||||
"new-window-button",
|
||||
|
@ -435,18 +452,22 @@ add_task(function() {
|
|||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"edit-controls",
|
||||
"developer-button"];
|
||||
"developer-button",
|
||||
"social-share-button"];
|
||||
addSwitchToMetroButtonInWindows8(placementsAfterMove);
|
||||
if (isInWin8()) {
|
||||
placementsAfterMove.splice(10, 1);
|
||||
placementsAfterMove.push("edit-controls");
|
||||
}
|
||||
simulateItemDrag(editControls, target);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
let itemToDrag = "sync-button";
|
||||
let button = document.getElementById(itemToDrag);
|
||||
placementsAfterMove.splice(11, 0, itemToDrag);
|
||||
if (isInWin8()) {
|
||||
placementsAfterMove[10] = placementsAfterMove[11];
|
||||
placementsAfterMove[11] = placementsAfterMove[12];
|
||||
placementsAfterMove[12] = placementsAfterMove[13];
|
||||
placementsAfterMove[13] = "edit-controls";
|
||||
placementsAfterMove.push(itemToDrag);
|
||||
} else {
|
||||
placementsAfterMove.splice(10, 1, itemToDrag);
|
||||
placementsAfterMove.push("edit-controls");
|
||||
}
|
||||
simulateItemDrag(button, editControls);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
|
|
|
@ -11,15 +11,13 @@ add_task(function() {
|
|||
yield startCustomizing();
|
||||
let btn = document.getElementById("open-file-button");
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
|
||||
|
||||
CustomizableUI.removeWidgetFromArea("social-share-button");
|
||||
if (isInWin8()) {
|
||||
CustomizableUI.removeWidgetFromArea("switch-to-metro-button");
|
||||
placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
|
||||
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
|
||||
} else {
|
||||
ok(CustomizableUI.inDefaultState, "Should be in default state.");
|
||||
}
|
||||
let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
|
||||
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
|
||||
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placements);
|
||||
is(getVisiblePlaceholderCount(panel), 2, "Should only have 2 visible placeholders before exiting");
|
||||
|
@ -28,6 +26,7 @@ add_task(function() {
|
|||
yield startCustomizing();
|
||||
is(getVisiblePlaceholderCount(panel), 2, "Should only have 2 visible placeholders after re-entering");
|
||||
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_PANEL);
|
||||
if (isInWin8()) {
|
||||
CustomizableUI.addWidgetToArea("switch-to-metro-button", CustomizableUI.AREA_PANEL);
|
||||
}
|
||||
|
@ -39,6 +38,7 @@ add_task(function() {
|
|||
yield startCustomizing();
|
||||
let btn = document.getElementById("open-file-button");
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
CustomizableUI.removeWidgetFromArea("social-share-button");
|
||||
let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
|
||||
|
||||
let placementsAfterAppend = placements;
|
||||
|
@ -49,7 +49,7 @@ add_task(function() {
|
|||
}
|
||||
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
|
||||
is(CustomizableUI.inDefaultState, isInWin8(), "Should only be in default state if on Win8");
|
||||
ok(!CustomizableUI.inDefaultState, "Should not be in default state");
|
||||
is(getVisiblePlaceholderCount(panel), 1, "Should only have 1 visible placeholder before exiting");
|
||||
|
||||
yield endCustomizing();
|
||||
|
@ -63,26 +63,24 @@ add_task(function() {
|
|||
btn = document.getElementById("open-file-button");
|
||||
simulateItemDrag(btn, palette);
|
||||
}
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_PANEL);
|
||||
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
|
||||
});
|
||||
|
||||
// Two orphaned items should have one placeholder next to them (case 2).
|
||||
add_task(function() {
|
||||
yield startCustomizing();
|
||||
let btn = document.getElementById("add-ons-button");
|
||||
let btn2 = document.getElementById("developer-button");
|
||||
let btn3 = document.getElementById("switch-to-metro-button");
|
||||
let buttonsToMove = ["add-ons-button", "developer-button", "social-share-button"];
|
||||
if (isInWin8()) {
|
||||
buttonsToMove.push("switch-to-metro-button");
|
||||
}
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
let palette = document.getElementById("customization-palette");
|
||||
let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
|
||||
|
||||
let placementsAfterAppend = placements.filter(p => p != btn.id && p != btn2.id);
|
||||
simulateItemDrag(btn, palette);
|
||||
simulateItemDrag(btn2, palette);
|
||||
|
||||
if (isInWin8()) {
|
||||
placementsAfterAppend = placementsAfterAppend.filter(p => p != btn3.id);
|
||||
simulateItemDrag(btn3, palette);
|
||||
let placementsAfterAppend = placements.filter(p => buttonsToMove.indexOf(p) < 0);
|
||||
for (let i in buttonsToMove) {
|
||||
CustomizableUI.removeWidgetFromArea(buttonsToMove[i]);
|
||||
}
|
||||
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
|
||||
|
@ -93,11 +91,8 @@ add_task(function() {
|
|||
yield startCustomizing();
|
||||
is(getVisiblePlaceholderCount(panel), 1, "Should only have 1 visible placeholder after re-entering");
|
||||
|
||||
simulateItemDrag(btn, panel);
|
||||
simulateItemDrag(btn2, panel);
|
||||
|
||||
if (isInWin8()) {
|
||||
simulateItemDrag(btn3, panel);
|
||||
for (let i in buttonsToMove) {
|
||||
CustomizableUI.addWidgetToArea(buttonsToMove[i], CustomizableUI.AREA_PANEL);
|
||||
}
|
||||
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placements);
|
||||
|
@ -112,6 +107,7 @@ add_task(function() {
|
|||
let metroBtn = document.getElementById("switch-to-metro-button");
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
let palette = document.getElementById("customization-palette");
|
||||
CustomizableUI.removeWidgetFromArea("social-share-button");
|
||||
let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
|
||||
|
||||
placements.pop();
|
||||
|
@ -133,6 +129,7 @@ add_task(function() {
|
|||
is(getVisiblePlaceholderCount(panel), 3, "Should have 3 visible placeholders after re-entering");
|
||||
|
||||
simulateItemDrag(developerButton, panel);
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_PANEL);
|
||||
if (isInWin8()) {
|
||||
simulateItemDrag(metroBtn, panel);
|
||||
}
|
||||
|
@ -141,10 +138,10 @@ add_task(function() {
|
|||
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
|
||||
});
|
||||
|
||||
// The default placements should have two placeholders at the bottom (or 1 in win8).
|
||||
// The default placements should have one placeholder at the bottom (or 3 in metro-enabled win8).
|
||||
add_task(function() {
|
||||
yield startCustomizing();
|
||||
let numPlaceholders = isInWin8() ? 1 : 2;
|
||||
let numPlaceholders = isInWin8() ? 3 : 1;
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
ok(CustomizableUI.inDefaultState, "Should be in default state.");
|
||||
is(getVisiblePlaceholderCount(panel), numPlaceholders, "Should have " + numPlaceholders + " visible placeholders before exiting");
|
||||
|
|
|
@ -14,3 +14,12 @@ tree[type="places"] {
|
|||
menupopup[placespopup="true"] {
|
||||
-moz-binding: url("chrome://browser/content/places/menu.xml#places-popup-base");
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
#bookmarksChildren,
|
||||
.sidebar-placesTreechildren,
|
||||
.placesTree > treechildren {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,3 +23,11 @@
|
|||
listitem.offlineapp {
|
||||
-moz-binding: url("chrome://browser/content/preferences/handlers.xml#offlineapp");
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
#handlersView > richlistitem,
|
||||
.actionsMenu > menupopup > menuitem > .menu-iconic-left {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,13 @@ body {
|
|||
position: absolute;
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
.favicon > img {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
|
|
|
@ -13,7 +13,6 @@ const DEFAULT_MAX_CHILDREN = 100;
|
|||
const COLLAPSE_ATTRIBUTE_LENGTH = 120;
|
||||
const COLLAPSE_DATA_URL_REGEX = /^data.+base64/;
|
||||
const COLLAPSE_DATA_URL_LENGTH = 60;
|
||||
const CONTAINER_FLASHING_DURATION = 500;
|
||||
const NEW_SELECTION_HIGHLIGHTER_TIMER = 1000;
|
||||
|
||||
const {UndoStack} = require("devtools/shared/undo");
|
||||
|
@ -112,6 +111,11 @@ function MarkupView(aInspector, aFrame, aControllerWindow) {
|
|||
exports.MarkupView = MarkupView;
|
||||
|
||||
MarkupView.prototype = {
|
||||
/**
|
||||
* How long does a node flash when it mutates (in ms).
|
||||
*/
|
||||
CONTAINER_FLASHING_DURATION: 500,
|
||||
|
||||
_selectedContainer: null,
|
||||
|
||||
_initTooltips: function() {
|
||||
|
@ -1578,7 +1582,7 @@ MarkupContainer.prototype = {
|
|||
}
|
||||
this._flashMutationTimer = contentWin.setTimeout(() => {
|
||||
this.flashed = false;
|
||||
}, CONTAINER_FLASHING_DURATION);
|
||||
}, this.markup.CONTAINER_FLASHING_DURATION);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -55,6 +55,10 @@ const TEST_DATA = [{
|
|||
let test = asyncTest(function*() {
|
||||
let {inspector} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
// Make sure mutated nodes flash for a very long time so we can more easily
|
||||
// assert they do
|
||||
inspector.markup.CONTAINER_FLASHING_DURATION = 1000 * 60 * 60;
|
||||
|
||||
info("Getting the <ul.list> root node to test mutations on");
|
||||
let rootNode = getNode(".list");
|
||||
let rootNodeFront = yield getNodeFront(".list", inspector);
|
||||
|
@ -88,4 +92,9 @@ function* assertNodeFlashing(nodeFront, inspector) {
|
|||
ok(container, "Markup container for node found");
|
||||
ok(container.tagState.classList.contains("theme-bg-contrast"),
|
||||
"Markup container for node is flashing");
|
||||
|
||||
// Clear the mutation flashing timeout now that we checked the node was flashing
|
||||
let markup = inspector.markup;
|
||||
markup._frame.contentWindow.clearTimeout(container._flashMutationTimer);
|
||||
container._flashMutationTimer = null;
|
||||
}
|
||||
|
|
|
@ -140,17 +140,18 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
|||
<!ENTITY editThisBookmarkCmd.label "Edit This Bookmark">
|
||||
<!ENTITY bookmarkThisPageCmd.commandkey "d">
|
||||
<!ENTITY markPageCmd.commandkey "l">
|
||||
<!ENTITY findShareServices.label "Find more Share services…">
|
||||
<!ENTITY sharePageCmd.label "Share This Page">
|
||||
<!ENTITY sharePageCmd.commandkey "S">
|
||||
<!ENTITY sharePageCmd.accesskey "s">
|
||||
<!ENTITY shareLinkCmd.label "Share This Link">
|
||||
<!ENTITY shareLinkCmd.accesskey "s">
|
||||
<!ENTITY shareLinkCmd.accesskey "h">
|
||||
<!ENTITY shareImageCmd.label "Share This Image">
|
||||
<!ENTITY shareImageCmd.accesskey "s">
|
||||
<!ENTITY shareImageCmd.accesskey "r">
|
||||
<!ENTITY shareSelectCmd.label "Share Selection">
|
||||
<!ENTITY shareSelectCmd.accesskey "s">
|
||||
<!ENTITY shareSelectCmd.accesskey "r">
|
||||
<!ENTITY shareVideoCmd.label "Share This Video">
|
||||
<!ENTITY shareVideoCmd.accesskey "s">
|
||||
<!ENTITY shareVideoCmd.accesskey "r">
|
||||
<!ENTITY feedsMenu.label "Subscribe">
|
||||
<!ENTITY subscribeToPageMenupopup.label "Subscribe to This Page">
|
||||
<!ENTITY subscribeToPageMenuitem.label "Subscribe to This Page…">
|
||||
|
|
|
@ -363,6 +363,7 @@ SocialErrorListener.prototype = {
|
|||
if (failure && aStatus != Components.results.NS_BINDING_ABORTED) {
|
||||
aRequest.cancel(Components.results.NS_BINDING_ABORTED);
|
||||
let provider = Social._getProviderFromOrigin(this.iframe.getAttribute("origin"));
|
||||
if (provider && !provider.errorState)
|
||||
provider.errorState = "content-error";
|
||||
this.setErrorMessage(aWebProgress.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler);
|
||||
|
@ -373,7 +374,7 @@ SocialErrorListener.prototype = {
|
|||
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
|
||||
aRequest.cancel(Components.results.NS_BINDING_ABORTED);
|
||||
let provider = Social._getProviderFromOrigin(this.iframe.getAttribute("origin"));
|
||||
if (!provider.errorState)
|
||||
if (provider && !provider.errorState)
|
||||
provider.errorState = "content-error";
|
||||
schedule(function() {
|
||||
this.setErrorMessage(aWebProgress.QueryInterface(Ci.nsIDocShell)
|
||||
|
|
|
@ -387,14 +387,6 @@ toolbarbutton.bookmark-item > menupopup {
|
|||
opacity: 0.7;
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
.bookmark-item > .toolbarbutton-icon,
|
||||
.bookmark-item > .menu-iconic-left > .menu-iconic-icon,
|
||||
#personal-bookmarks[cui-areatype="toolbar"] > #bookmarks-toolbar-placeholder > .toolbarbutton-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
#bookmarks-toolbar-placeholder {
|
||||
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
|
||||
}
|
||||
|
@ -1321,6 +1313,11 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-ic
|
|||
width: 16px;
|
||||
}
|
||||
|
||||
#add-share-provider {
|
||||
list-style-image: url(chrome://browser/skin/menuPanel-small@2x.png);
|
||||
-moz-image-region: rect(0px, 192px, 32px, 160px);
|
||||
}
|
||||
|
||||
#loop-call-button > .toolbarbutton-badge-container {
|
||||
list-style-image: url("chrome://browser/skin/loop/toolbar@2x.png");
|
||||
-moz-image-region: rect(0, 36px, 36px, 0);
|
||||
|
@ -2798,7 +2795,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
|
||||
.tab-icon-image {
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png");
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
|
||||
.tab-throbber[busy] {
|
||||
|
|
|
@ -47,11 +47,6 @@
|
|||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
.searchbar-engine-image,
|
||||
.searchbar-engine-menuitem > .menu-iconic-left > .menu-iconic-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
|
||||
.searchbar-engine-image {
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png");
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ prefpane {
|
|||
#typeColumn > .treecol-sortdirection[sortDirection=descending],
|
||||
#actionColumn > .treecol-sortdirection[sortDirection=descending] {
|
||||
-moz-appearance: none;
|
||||
list-style-image: url("chrome://browser/skin/preferences/in-content/sorter.png");
|
||||
list-style-image: url("chrome://browser/skin/in-content/sorter.png");
|
||||
}
|
||||
|
||||
#typeColumn > .treecol-sortdirection[sortDirection=descending],
|
||||
|
@ -182,7 +182,7 @@ prefpane {
|
|||
#actionColumn > .treecol-sortdirection[sortDirection=descending] {
|
||||
width: 12px;
|
||||
height: 8px;
|
||||
list-style-image: url("chrome://browser/skin/preferences/in-content/sorter@2x.png");
|
||||
list-style-image: url("chrome://browser/skin/in-content/sorter@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -218,3 +218,8 @@ toolbarpaletteitem[place="palette"] > #zoom-controls > #zoom-out-button {
|
|||
toolbarpaletteitem[place="palette"] > #zoom-controls > #zoom-in-button {
|
||||
-moz-image-region: rect(0px, 96px, 16px, 80px);
|
||||
}
|
||||
|
||||
#add-share-provider {
|
||||
list-style-image: url(chrome://browser/skin/menuPanel-small.png);
|
||||
-moz-image-region: rect(0px, 96px, 16px, 80px);
|
||||
}
|
|
@ -19,16 +19,11 @@
|
|||
}
|
||||
|
||||
.glyphShape-style-hover-gear {
|
||||
fill: url(#gradient-linear-hover-gear);
|
||||
}
|
||||
.glyphShape-style-hover-gear-dropshadow {
|
||||
fill: #000;
|
||||
fill-opacity: .5;
|
||||
filter: url(#filter-shadow-drop);
|
||||
fill: #4a90e2;
|
||||
}
|
||||
|
||||
.glyphShape-style-hover-pin {
|
||||
fill: #0092e5;
|
||||
fill: #4a90e2;
|
||||
}
|
||||
|
||||
.glyphShape-style-hover-delete {
|
||||
|
@ -57,14 +52,6 @@
|
|||
<feGaussianBlur in="filter-shadow-drop-offset" stdDeviation="1" result="filter-shadow-drop-blur"/>
|
||||
</filter>
|
||||
|
||||
<linearGradient id="gradient-linear-hover-gear"
|
||||
x1="0%" y1="0%"
|
||||
x2="0%" y2="100%"
|
||||
spreadMethod="pad">
|
||||
<stop offset="0%" stop-color="#a1a0a0" stop-opacity="1"/>
|
||||
<stop offset="100%" stop-color="#676767" stop-opacity="1"/>
|
||||
</linearGradient>
|
||||
|
||||
<path id="glyphShape-gear" d="M28,16c0-1.7,0.9-3.1,2-3.3c-0.4-1.5-0.9-2.9-1.7-4.2c-0.9,0.7-2.6,0.3-3.8-0.9c-1.2-1.2-1.6-2.8-0.9-3.8 c-1.3-0.8-2.7-1.4-4.2-1.7c-0.2,1.1-1.6,2-3.3,2S13,3.1,12.8,2c-1.5,0.4-2.9,0.9-4.2,1.7c0.7,0.9,0.3,2.6-0.9,3.8 c-1.4,1.1-3,1.5-4,0.9C2.9,9.7,2.4,11.2,2,12.7c1.1,0.2,2,1.6,2,3.3s-0.9,3.1-2,3.3c0.4,1.5,0.9,2.9,1.7,4.2 c0.9-0.7,2.6-0.3,3.8,0.9c1.2,1.2,1.6,2.8,0.9,3.8c1.3,0.8,2.7,1.4,4.2,1.7c0.2-1.1,1.6-2,3.3-2s3.1,0.9,3.3,2 c1.5-0.4,2.9-0.9,4.2-1.7c-0.7-0.9-0.3-2.6,0.9-3.8c1.3-1.2,2.8-1.6,3.8-0.9c0.8-1.3,1.4-2.7,1.7-4.2C28.9,19.1,28,17.7,28,16z M16,24c-4.4,0-8-3.6-8-8s3.6-8,8-8s8,3.6,8,8S20.4,24,16,24z" />
|
||||
|
||||
<circle id="glyphShape-circle" cx="16" cy="16" r="14" />
|
||||
|
@ -79,7 +66,6 @@
|
|||
</g>
|
||||
|
||||
<g id="icon-gear-default" transform="translate(32)">
|
||||
<use xlink:href="#glyphShape-gear" class="glyphShape-style-hover-gear-dropshadow" />
|
||||
<use xlink:href="#glyphShape-gear" class="glyphShape-style-hover-gear" />
|
||||
</g>
|
||||
|
||||
|
|
До Ширина: | Высота: | Размер: 4.7 KiB После Ширина: | Высота: | Размер: 4.2 KiB |
|
@ -133,7 +133,7 @@ public class TabCounter extends ThemedTextSwitcher
|
|||
|
||||
@Override
|
||||
public View makeView() {
|
||||
return mInflater.inflate(mLayoutId, this, false);
|
||||
return mInflater.inflate(mLayoutId, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,16 @@ const SEARCH_RESPONSE_SUGGESTION_JSON = "application/x-suggestions+json";
|
|||
const DEFAULT_FORM_HISTORY_PARAM = "searchbar-history";
|
||||
const HTTP_OK = 200;
|
||||
const REMOTE_TIMEOUT = 500; // maximum time (ms) to wait before giving up on a remote suggestions
|
||||
const BROWSER_SUGGEST_PREF = "browser.search.suggest.enabled";
|
||||
|
||||
/**
|
||||
* Remote search suggestions will be shown if gRemoteSuggestionsEnabled
|
||||
* is true. Global because only one pref observer is needed for all instances.
|
||||
*/
|
||||
let gRemoteSuggestionsEnabled = Services.prefs.getBoolPref(BROWSER_SUGGEST_PREF);
|
||||
Services.prefs.addObserver(BROWSER_SUGGEST_PREF, function(aSubject, aTopic, aData) {
|
||||
gRemoteSuggestionsEnabled = Services.prefs.getBoolPref(BROWSER_SUGGEST_PREF);
|
||||
}, false);
|
||||
|
||||
/**
|
||||
* SearchSuggestionController.jsm exists as a helper module to allow multiple consumers to request and display
|
||||
|
@ -124,7 +134,7 @@ this.SearchSuggestionController.prototype = {
|
|||
this._searchString = searchTerm;
|
||||
|
||||
// Remote results
|
||||
if (searchTerm && this.maxRemoteResults &&
|
||||
if (searchTerm && gRemoteSuggestionsEnabled && this.maxRemoteResults &&
|
||||
engine.supportsResponseType(SEARCH_RESPONSE_SUGGESTION_JSON)) {
|
||||
this._deferredRemoteResult = this._fetchRemote(searchTerm, engine, privateMode);
|
||||
promises.push(this._deferredRemoteResult.promise);
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
* 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/. */
|
||||
|
||||
const BROWSER_SUGGEST_PREF = "browser.search.suggest.enabled";
|
||||
const XPCOM_SHUTDOWN_TOPIC = "xpcom-shutdown";
|
||||
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
@ -28,8 +24,6 @@ function SuggestAutoComplete() {
|
|||
SuggestAutoComplete.prototype = {
|
||||
|
||||
_init: function() {
|
||||
this._addObservers();
|
||||
this._suggestEnabled = Services.prefs.getBoolPref(BROWSER_SUGGEST_PREF);
|
||||
this._suggestionController = new SearchSuggestionController(obj => this.onResultsReturned(obj));
|
||||
},
|
||||
|
||||
|
@ -39,11 +33,6 @@ SuggestAutoComplete.prototype = {
|
|||
return this._suggestionLabel = bundle.GetStringFromName("suggestion_label");
|
||||
},
|
||||
|
||||
/**
|
||||
* Search suggestions will be shown if this._suggestEnabled is true.
|
||||
*/
|
||||
_suggestEnabled: null,
|
||||
|
||||
/**
|
||||
* The object implementing nsIAutoCompleteObserver that we notify when
|
||||
* we have found results
|
||||
|
@ -178,32 +167,6 @@ SuggestAutoComplete.prototype = {
|
|||
this._suggestionController.stop();
|
||||
},
|
||||
|
||||
/**
|
||||
* nsIObserver
|
||||
*/
|
||||
observe: function SAC_observe(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
|
||||
this._suggestEnabled = Services.prefs.getBoolPref(BROWSER_SUGGEST_PREF);
|
||||
break;
|
||||
case XPCOM_SHUTDOWN_TOPIC:
|
||||
this._removeObservers();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_addObservers: function SAC_addObservers() {
|
||||
Services.prefs.addObserver(BROWSER_SUGGEST_PREF, this, false);
|
||||
|
||||
Services.obs.addObserver(this, XPCOM_SHUTDOWN_TOPIC, false);
|
||||
},
|
||||
|
||||
_removeObservers: function SAC_removeObservers() {
|
||||
Services.prefs.removeObserver(BROWSER_SUGGEST_PREF, this);
|
||||
|
||||
Services.obs.removeObserver(this, XPCOM_SHUTDOWN_TOPIC);
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteSearch,
|
||||
Ci.nsIAutoCompleteObserver])
|
||||
|
|
|
@ -278,6 +278,49 @@ add_task(function* one_of_each() {
|
|||
do_check_eq(result.remote[0], "letter B");
|
||||
});
|
||||
|
||||
add_task(function* local_result_returned_remote_result_disabled() {
|
||||
Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
|
||||
let controller = new SearchSuggestionController();
|
||||
controller.maxLocalResults = 1;
|
||||
controller.maxRemoteResults = 1;
|
||||
let result = yield controller.fetch("letter ", false, getEngine);
|
||||
do_check_eq(result.term, "letter ");
|
||||
do_check_eq(result.local.length, 1);
|
||||
do_check_eq(result.local[0], "letter A");
|
||||
do_check_eq(result.remote.length, 0);
|
||||
Services.prefs.clearUserPref("browser.search.suggest.enabled");
|
||||
});
|
||||
|
||||
add_task(function* local_result_returned_remote_result_disabled_after_creation_of_controller() {
|
||||
let controller = new SearchSuggestionController();
|
||||
controller.maxLocalResults = 1;
|
||||
controller.maxRemoteResults = 1;
|
||||
Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
|
||||
let result = yield controller.fetch("letter ", false, getEngine);
|
||||
do_check_eq(result.term, "letter ");
|
||||
do_check_eq(result.local.length, 1);
|
||||
do_check_eq(result.local[0], "letter A");
|
||||
do_check_eq(result.remote.length, 0);
|
||||
});
|
||||
|
||||
add_task(function* one_of_each_disabled_before_creation_enabled_after_creation_of_controller() {
|
||||
Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
|
||||
let controller = new SearchSuggestionController();
|
||||
controller.maxLocalResults = 1;
|
||||
controller.maxRemoteResults = 1;
|
||||
Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
|
||||
let result = yield controller.fetch("letter ", false, getEngine);
|
||||
do_check_eq(result.term, "letter ");
|
||||
do_check_eq(result.local.length, 1);
|
||||
do_check_eq(result.local[0], "letter A");
|
||||
do_check_eq(result.remote.length, 1);
|
||||
do_check_eq(result.remote[0], "letter B");
|
||||
});
|
||||
|
||||
add_task(function* clear_suggestions_pref() {
|
||||
Services.prefs.clearUserPref("browser.search.suggest.enabled");
|
||||
});
|
||||
|
||||
add_task(function* one_local_zero_remote() {
|
||||
let controller = new SearchSuggestionController();
|
||||
controller.maxLocalResults = 1;
|
||||
|
|
|
@ -585,11 +585,10 @@ this.SocialService = {
|
|||
action, [], options);
|
||||
},
|
||||
|
||||
installProvider: function(aDOMDocument, data, installCallback, aBypassUserEnable=false) {
|
||||
installProvider: function(aDOMDocument, data, installCallback, options={}) {
|
||||
let manifest;
|
||||
let installOrigin = aDOMDocument.nodePrincipal.origin;
|
||||
|
||||
if (data) {
|
||||
let installType = getOriginActivationType(installOrigin);
|
||||
// if we get data, we MUST have a valid manifest generated from the data
|
||||
manifest = this._manifestFromData(installType, data, aDOMDocument.nodePrincipal);
|
||||
|
@ -604,7 +603,6 @@ this.SocialService = {
|
|||
// activation from about: uris, we need to be sure to use the updated
|
||||
// origin on the manifest.
|
||||
installOrigin = manifest.origin;
|
||||
}
|
||||
|
||||
let id = getAddonIDFromOrigin(installOrigin);
|
||||
AddonManager.getAddonByID(id, function(aAddon) {
|
||||
|
@ -613,7 +611,7 @@ this.SocialService = {
|
|||
aAddon.userDisabled = false;
|
||||
}
|
||||
schedule(function () {
|
||||
this._installProvider(aDOMDocument, manifest, aBypassUserEnable, aManifest => {
|
||||
this._installProvider(aDOMDocument, manifest, options, aManifest => {
|
||||
this._notifyProviderListeners("provider-installed", aManifest.origin);
|
||||
installCallback(aManifest);
|
||||
});
|
||||
|
@ -621,43 +619,21 @@ this.SocialService = {
|
|||
}.bind(this));
|
||||
},
|
||||
|
||||
_installProvider: function(aDOMDocument, manifest, aBypassUserEnable, installCallback) {
|
||||
let sourceURI = aDOMDocument.location.href;
|
||||
let installOrigin = aDOMDocument.nodePrincipal.origin;
|
||||
_installProvider: function(aDOMDocument, manifest, options, installCallback) {
|
||||
if (!manifest)
|
||||
throw new Error("Cannot install provider without manifest data");
|
||||
|
||||
let installType = getOriginActivationType(installOrigin);
|
||||
let installer;
|
||||
switch(installType) {
|
||||
case "foreign":
|
||||
if (!Services.prefs.getBoolPref("social.remote-install.enabled"))
|
||||
let installType = getOriginActivationType(aDOMDocument.nodePrincipal.origin);
|
||||
if (installType == "foreign" && !Services.prefs.getBoolPref("social.remote-install.enabled"))
|
||||
throw new Error("Remote install of services is disabled");
|
||||
if (!manifest)
|
||||
throw new Error("Cannot install provider without manifest data");
|
||||
|
||||
installer = new AddonInstaller(sourceURI, manifest, installCallback);
|
||||
this._showInstallNotification(aDOMDocument, installer);
|
||||
break;
|
||||
case "internal":
|
||||
// double check here since "builtin" falls through this as well.
|
||||
aBypassUserEnable = installType == "internal" && manifest.oneclick;
|
||||
case "directory":
|
||||
// a manifest is requried, and will have been vetted by reviewers. We
|
||||
// also handle in-product installations without the verification step.
|
||||
if (aBypassUserEnable) {
|
||||
installer = new AddonInstaller(sourceURI, manifest, installCallback);
|
||||
let installer = new AddonInstaller(aDOMDocument.location.href, manifest, installCallback);
|
||||
let bypassPanel = options.bypassInstallPanel ||
|
||||
(installType == "internal" && manifest.oneclick);
|
||||
if (bypassPanel)
|
||||
installer.install();
|
||||
return;
|
||||
}
|
||||
// a manifest is required, we'll catch a missing manifest below.
|
||||
if (!manifest)
|
||||
throw new Error("Cannot install provider without manifest data");
|
||||
installer = new AddonInstaller(sourceURI, manifest, installCallback);
|
||||
else
|
||||
this._showInstallNotification(aDOMDocument, installer);
|
||||
break;
|
||||
default:
|
||||
throw new Error("SocialService.installProvider: Invalid install type "+installType+"\n");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
createWrapper: function(manifest) {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/* 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/. */
|
||||
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
.ac-site-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ toolkit.jar:
|
|||
* content/global/xul.css (xul.css)
|
||||
content/global/textbox.css (textbox.css)
|
||||
content/global/menulist.css (menulist.css)
|
||||
content/global/autocomplete.css (autocomplete.css)
|
||||
content/global/about.js (about.js)
|
||||
content/global/about.xhtml (about.xhtml)
|
||||
content/global/aboutAbout.js (aboutAbout.js)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<binding id="autocomplete" role="xul:combobox"
|
||||
extends="chrome://global/content/bindings/textbox.xml#textbox">
|
||||
<resources>
|
||||
<stylesheet src="chrome://global/content/autocomplete.css"/>
|
||||
<stylesheet src="chrome://global/skin/autocomplete.css"/>
|
||||
</resources>
|
||||
|
||||
|
@ -598,6 +599,7 @@
|
|||
|
||||
<binding id="autocomplete-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-base-popup">
|
||||
<resources>
|
||||
<stylesheet src="chrome://global/content/autocomplete.css"/>
|
||||
<stylesheet src="chrome://global/skin/tree.css"/>
|
||||
<stylesheet src="chrome://global/skin/autocomplete.css"/>
|
||||
</resources>
|
||||
|
@ -929,6 +931,7 @@ extends="chrome://global/content/bindings/popup.xml#popup">
|
|||
|
||||
<binding id="autocomplete-rich-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-base-popup">
|
||||
<resources>
|
||||
<stylesheet src="chrome://global/content/autocomplete.css"/>
|
||||
<stylesheet src="chrome://global/skin/autocomplete.css"/>
|
||||
</resources>
|
||||
|
||||
|
|
|
@ -448,13 +448,11 @@ let Option = Class({
|
|||
},
|
||||
|
||||
write: function(arg, ctx, name) {
|
||||
if (!arg) {
|
||||
return undefined;
|
||||
}
|
||||
let v = arg[name] || undefined;
|
||||
if (v === undefined) {
|
||||
// Ignore if arg is undefined or null; allow other falsy values
|
||||
if (arg == undefined || arg[name] == undefined) {
|
||||
return undefined;
|
||||
}
|
||||
let v = arg[name];
|
||||
return this.type.write(v, ctx);
|
||||
},
|
||||
read: function(v, ctx, outArgs, name) {
|
||||
|
|
|
@ -132,8 +132,18 @@ let RootActor = protocol.ActorClass({
|
|||
oneway: true
|
||||
}),
|
||||
|
||||
emitFalsyOptions: method(function() {
|
||||
events.emit(this, "falsyOptions", { zero: 0, farce: false });
|
||||
}, {
|
||||
oneway: true
|
||||
}),
|
||||
|
||||
events: {
|
||||
"oneway": { a: Arg(0) }
|
||||
"oneway": { a: Arg(0) },
|
||||
"falsyOptions": {
|
||||
zero: Option(0),
|
||||
farce: Option(0)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -223,7 +233,7 @@ function run_test()
|
|||
trace.expectReceive({"from":"<actorid>"});
|
||||
do_check_true(typeof(ret.option1) === "undefined");
|
||||
do_check_true(typeof(ret.option2) === "undefined");
|
||||
}).then(ret => {
|
||||
}).then(() => {
|
||||
// Explicitly call an optional argument...
|
||||
return rootClient.optionalArgs(5, 10);
|
||||
}).then(ret => {
|
||||
|
@ -268,6 +278,18 @@ function run_test()
|
|||
});
|
||||
do_check_true(typeof(rootClient.testOneWay("hello")) === "undefined");
|
||||
return deferred.promise;
|
||||
}).then(() => {
|
||||
let deferred = promise.defer();
|
||||
rootClient.on("falsyOptions", res => {
|
||||
trace.expectSend({"type":"emitFalsyOptions", "to":"<actorid>"});
|
||||
trace.expectReceive({"type":"falsyOptions", "farce":false, "zero": 0, "from":"<actorid>"});
|
||||
|
||||
do_check_true(res.zero === 0);
|
||||
do_check_true(res.farce === false);
|
||||
deferred.resolve();
|
||||
});
|
||||
rootClient.emitFalsyOptions();
|
||||
return deferred.promise;
|
||||
}).then(() => {
|
||||
client.close(() => {
|
||||
do_test_finished();
|
||||
|
|
|
@ -262,6 +262,7 @@ add_task(function* testUpdateButton() {
|
|||
yield gInstallDeferred.promise;
|
||||
|
||||
Assert.equal(gInstalledAddonId, OPENH264_PLUGIN_ID);
|
||||
delete OpenH264Scope.GMPInstallManager;
|
||||
});
|
||||
|
||||
add_task(function* test_cleanup() {
|
||||
|
|
|
@ -114,12 +114,6 @@ treechildren.autocomplete-treebody::-moz-tree-cell-text(selected) {
|
|||
-moz-margin-end: 5px;
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
image.ac-site-icon {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
.ac-type-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
|
Загрузка…
Ссылка в новой задаче