зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c.
This commit is contained in:
Коммит
e507d01d4b
|
@ -1084,8 +1084,11 @@ HyperTextAccessible::GetTextAtOffset(int32_t aOffset,
|
|||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
case BOUNDARY_WORD_END:
|
||||
*aStartOffset = FindWordBoundary(offset, eDirPrevious, eEndWord);
|
||||
*aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
|
||||
// Ignore the spec and follow what WebKitGtk does because Orca expects it,
|
||||
// i.e. return a next word at word end offset of the current word
|
||||
// (WebKitGtk behavior) instead the current word (AKT spec).
|
||||
*aEndOffset = FindWordBoundary(offset, eDirNext, eEndWord);
|
||||
*aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord);
|
||||
return GetText(*aStartOffset, *aEndOffset, aText);
|
||||
|
||||
case BOUNDARY_LINE_START:
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "IUnknownImpl.h"
|
||||
|
||||
#include "nsDebug.h"
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
|
|
@ -336,19 +336,9 @@
|
|||
|
||||
// BOUNDARY_WORD_END
|
||||
testTextAtOffset(0, BOUNDARY_WORD_END, "oneword", 0, 7, IDs);
|
||||
testTextAtOffset(8, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
|
||||
"div", kOk, kOk, kOk,
|
||||
"divbr", kTodo, kTodo, kTodo,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"editablebr", kTodo, kTodo, kTodo,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextAtOffset(9, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
|
||||
"div", kOk, kOk, kOk,
|
||||
"divbr", kTodo, kTodo, kTodo,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"editablebr", kTodo, kTodo, kTodo,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextAtOffset(12, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
|
||||
testTextAtOffset(8, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
|
||||
testTextAtOffset(9, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
|
||||
testTextAtOffset(12, BOUNDARY_WORD_END, " words", 12, 18, IDs);
|
||||
testTextAtOffset(13, BOUNDARY_WORD_END, " words", 12, 18,
|
||||
"div", kOk, kOk, kOk,
|
||||
"divbr", kOk, kOk, kOk,
|
||||
|
|
|
@ -315,10 +315,10 @@
|
|||
// BOUNDARY_WORD_END
|
||||
testTextAtOffset(0, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
|
||||
testTextAtOffset(1, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
|
||||
testTextAtOffset(5, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
|
||||
testTextAtOffset(5, BOUNDARY_WORD_END, " my", 5, 8, IDs);
|
||||
testTextAtOffset(6, BOUNDARY_WORD_END, " my", 5, 8, IDs);
|
||||
testTextAtOffset(7, BOUNDARY_WORD_END, " my", 5, 8, IDs);
|
||||
testTextAtOffset(8, BOUNDARY_WORD_END, " my", 5, 8, IDs);
|
||||
testTextAtOffset(8, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
|
||||
testTextAtOffset(9, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
|
||||
testTextAtOffset(10, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
|
||||
testTextAtOffset(14, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
|
||||
|
|
|
@ -342,20 +342,21 @@
|
|||
// BOUNDARY_WORD_END
|
||||
testTextAtOffset(0, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
|
||||
testTextAtOffset(4, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
|
||||
testTextAtOffset(5, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
|
||||
testTextAtOffset(5, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
|
||||
testTextAtOffset(6, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
|
||||
testTextAtOffset(8, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
|
||||
testTextAtOffset(9, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
|
||||
testTextAtOffset(9, BOUNDARY_WORD_END, " Robin", 9, 16, IDs);
|
||||
testTextAtOffset(10, BOUNDARY_WORD_END, " Robin", 9, 16, IDs);
|
||||
testTextAtOffset(11, BOUNDARY_WORD_END, " Robin", 9, 16, IDs);
|
||||
testTextAtOffset(15, BOUNDARY_WORD_END, " Robin", 9, 16, IDs);
|
||||
testTextAtOffset(16, BOUNDARY_WORD_END, " Robin", 9, 16, IDs);
|
||||
testTextAtOffset(16, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
|
||||
testTextAtOffset(17, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
|
||||
testTextAtOffset(18, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
|
||||
testTextAtOffset(19, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
|
||||
testTextAtOffset(20, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
|
||||
testTextAtOffset(21, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
|
||||
testTextAtOffset(22, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
|
||||
testTextAtOffset(22, BOUNDARY_WORD_END, " ran", 16, 22, ["input", "div", "editable"]);
|
||||
testTextAtOffset(22, BOUNDARY_WORD_END, " ran\n", 16, 23, [ "textarea" ]);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
|
|
@ -92,6 +92,9 @@ endif
|
|||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
RCINCLUDE = splash.rc
|
||||
# Rebuild firefox.exe if the manifest changes - it's included by splash.rc.
|
||||
# (this dependency should really be just for firefox.exe, not other targets)
|
||||
EXTRA_DEPS += $(PROGRAM).manifest
|
||||
ifndef GNU_CC
|
||||
RCFLAGS += -DMOZ_PHOENIX -I$(srcdir)
|
||||
else
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
</ms_asmv3:requestedPrivileges>
|
||||
</ms_asmv3:security>
|
||||
</ms_asmv3:trustInfo>
|
||||
<ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
<dpiAware>true</dpiAware>
|
||||
</ms_asmv3:windowsSettings>
|
||||
</ms_asmv3:application>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -47,6 +47,8 @@
|
|||
|
||||
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]) : "";
|
||||
|
||||
switch (mode) {
|
||||
case "compactInfo":
|
||||
|
@ -77,7 +79,11 @@
|
|||
let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
|
||||
|
||||
let productName = brandBundle.GetStringFromName("brandShortName");
|
||||
let providerName = Social && Social.provider && Social.provider.name;
|
||||
let provider = Social && Social.provider;
|
||||
if (config.origin) {
|
||||
provider = Social && Social._getProviderFromOrigin(config.origin);
|
||||
}
|
||||
let providerName = provider && provider.name;
|
||||
|
||||
// Sets up the error message
|
||||
let msg = browserBundle.formatStringFromName("social.error.message", [productName, providerName], 2);
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
<menuitem id="context-marklink"
|
||||
accesskey="&social.marklink.accesskey;"
|
||||
oncommand="gContextMenu.markLink();"/>
|
||||
<menuitem id="context-sharelink"
|
||||
label="&shareLinkCmd.label;"
|
||||
accesskey="&shareLinkCmd.accesskey;"
|
||||
oncommand="gContextMenu.shareLink();"/>
|
||||
<menuitem id="context-savelink"
|
||||
label="&saveLinkCmd.label;"
|
||||
accesskey="&saveLinkCmd.accesskey;"
|
||||
|
@ -160,6 +164,10 @@
|
|||
label="&saveImageCmd.label;"
|
||||
accesskey="&saveImageCmd.accesskey;"
|
||||
oncommand="gContextMenu.saveMedia();"/>
|
||||
<menuitem id="context-shareimage"
|
||||
label="&shareImageCmd.label;"
|
||||
accesskey="&shareImageCmd.accesskey;"
|
||||
oncommand="gContextMenu.shareImage();"/>
|
||||
<menuitem id="context-sendimage"
|
||||
label="&emailImageCmd.label;"
|
||||
accesskey="&emailImageCmd.accesskey;"
|
||||
|
@ -176,6 +184,10 @@
|
|||
label="&saveVideoCmd.label;"
|
||||
accesskey="&saveVideoCmd.accesskey;"
|
||||
oncommand="gContextMenu.saveMedia();"/>
|
||||
<menuitem id="context-sharevideo"
|
||||
label="&shareVideoCmd.label;"
|
||||
accesskey="&shareVideoCmd.accesskey;"
|
||||
oncommand="gContextMenu.shareVideo();"/>
|
||||
<menuitem id="context-saveaudio"
|
||||
label="&saveAudioCmd.label;"
|
||||
accesskey="&saveAudioCmd.accesskey;"
|
||||
|
@ -228,6 +240,10 @@
|
|||
<menuitem id="context-markpage"
|
||||
accesskey="&social.markpage.accesskey;"
|
||||
command="Social:TogglePageMark"/>
|
||||
<menuitem id="context-sharepage"
|
||||
label="&sharePageCmd.label;"
|
||||
accesskey="&sharePageCmd.accesskey;"
|
||||
oncommand="SocialShare.sharePage();"/>
|
||||
<menuitem id="context-savepage"
|
||||
label="&savePageCmd.label;"
|
||||
accesskey="&savePageCmd.accesskey2;"
|
||||
|
@ -271,6 +287,10 @@
|
|||
oncommand="AddKeywordForSearchField();"/>
|
||||
<menuitem id="context-searchselect"
|
||||
oncommand="BrowserSearch.loadSearchFromContext(getBrowserSelection());"/>
|
||||
<menuitem id="context-shareselect"
|
||||
label="&shareSelectCmd.label;"
|
||||
accesskey="&shareSelectCmd.accesskey;"
|
||||
oncommand="gContextMenu.shareSelect(getBrowserSelection());"/>
|
||||
<menuseparator id="frame-sep"/>
|
||||
<menu id="frame" label="&thisFrameMenu.label;" accesskey="&thisFrameMenu.accesskey;">
|
||||
<menupopup>
|
||||
|
|
|
@ -39,8 +39,13 @@ var gSafeBrowsing = {
|
|||
getReportURL: function(name) {
|
||||
var reportUrl = SafeBrowsing.getReportURL(name);
|
||||
|
||||
var pageUrl = gBrowser.currentURI.asciiSpec;
|
||||
reportUrl += "&url=" + encodeURIComponent(pageUrl);
|
||||
var pageUri = gBrowser.currentURI.clone();
|
||||
|
||||
// Remove the query to avoid including potentially sensitive data
|
||||
if (pageUri instanceof Ci.nsIURL)
|
||||
pageUri.query = '';
|
||||
|
||||
reportUrl += "&url=" + encodeURIComponent(pageUri.asciiSpec);
|
||||
|
||||
return reportUrl;
|
||||
}
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
<command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
|
||||
<command id="Browser:ToggleAddonBar" oncommand="toggleAddonBar();"/>
|
||||
<command id="Social:TogglePageMark" oncommand="SocialMark.togglePageMark();" disabled="true"/>
|
||||
<command id="Social:SharePage" oncommand="SocialShare.sharePage();" disabled="true"/>
|
||||
<command id="Social:ToggleSidebar" oncommand="Social.toggleSidebar();"/>
|
||||
<command id="Social:ToggleNotifications" oncommand="Social.toggleNotifications();" hidden="true"/>
|
||||
<command id="Social:FocusChat" oncommand="SocialChatBar.focus();" hidden="true" disabled="true"/>
|
||||
|
|
|
@ -7,6 +7,7 @@ let SocialUI,
|
|||
SocialChatBar,
|
||||
SocialFlyout,
|
||||
SocialMark,
|
||||
SocialShare,
|
||||
SocialMenu,
|
||||
SocialToolbar,
|
||||
SocialSidebar;
|
||||
|
@ -20,6 +21,12 @@ const PANEL_MIN_WIDTH = 330;
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "SharedFrame",
|
||||
"resource:///modules/SharedFrame.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "OpenGraphBuilder", function() {
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/Social.jsm", tmp);
|
||||
return tmp.OpenGraphBuilder;
|
||||
});
|
||||
|
||||
SocialUI = {
|
||||
// Called on delayed startup to initialize the UI
|
||||
init: function SocialUI_init() {
|
||||
|
@ -43,6 +50,7 @@ SocialUI = {
|
|||
|
||||
SocialChatBar.init();
|
||||
SocialMark.init();
|
||||
SocialShare.init();
|
||||
SocialMenu.init();
|
||||
SocialToolbar.init();
|
||||
SocialSidebar.init();
|
||||
|
@ -87,6 +95,7 @@ SocialUI = {
|
|||
|
||||
SocialFlyout.unload();
|
||||
SocialChatBar.update();
|
||||
SocialShare.update();
|
||||
SocialSidebar.update();
|
||||
SocialMark.update();
|
||||
SocialToolbar.update();
|
||||
|
@ -97,6 +106,7 @@ SocialUI = {
|
|||
this._updateActiveUI();
|
||||
// and the multi-provider menu
|
||||
SocialToolbar.populateProviderMenus();
|
||||
SocialShare.populateProviderMenu();
|
||||
break;
|
||||
|
||||
// Provider-specific notifications
|
||||
|
@ -384,7 +394,13 @@ function sizeSocialPanelToContent(panel, iframe) {
|
|||
if (!doc || !doc.body) {
|
||||
return;
|
||||
}
|
||||
// We need an element to use for sizing our panel. See if the body defines
|
||||
// an id for that element, otherwise use the body itself.
|
||||
let body = doc.body;
|
||||
let bodyId = body.getAttribute("contentid");
|
||||
if (bodyId) {
|
||||
body = doc.getElementById(bodyId) || doc.body;
|
||||
}
|
||||
// offsetHeight/Width don't include margins, so account for that.
|
||||
let cs = doc.defaultView.getComputedStyle(body);
|
||||
let computedHeight = parseInt(cs.marginTop) + body.offsetHeight + parseInt(cs.marginBottom);
|
||||
|
@ -566,6 +582,301 @@ SocialFlyout = {
|
|||
}
|
||||
}
|
||||
|
||||
SocialShare = {
|
||||
// Called once, after window load, when the Social.provider object is initialized
|
||||
init: function() {},
|
||||
|
||||
get panel() {
|
||||
return document.getElementById("social-share-panel");
|
||||
},
|
||||
|
||||
get iframe() {
|
||||
// first element is our menu vbox.
|
||||
if (this.panel.childElementCount == 1)
|
||||
return null;
|
||||
else
|
||||
return this.panel.lastChild;
|
||||
},
|
||||
|
||||
_createFrame: function() {
|
||||
let panel = this.panel;
|
||||
if (!SocialUI.enabled || this.iframe)
|
||||
return;
|
||||
this.panel.hidden = false;
|
||||
// create and initialize the panel for this window
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("type", "content");
|
||||
iframe.setAttribute("class", "social-share-frame");
|
||||
iframe.setAttribute("flex", "1");
|
||||
panel.appendChild(iframe);
|
||||
this.populateProviderMenu();
|
||||
},
|
||||
|
||||
getSelectedProvider: function() {
|
||||
let provider;
|
||||
let lastProviderOrigin = this.iframe && this.iframe.getAttribute("origin");
|
||||
if (lastProviderOrigin) {
|
||||
provider = Social._getProviderFromOrigin(lastProviderOrigin);
|
||||
}
|
||||
if (!provider)
|
||||
provider = Social.provider || Social.defaultProvider;
|
||||
// if our provider has no shareURL, select the first one that does
|
||||
if (provider && !provider.shareURL) {
|
||||
let providers = [p for (p of Social.providers) if (p.shareURL)];
|
||||
provider = providers.length > 0 && providers[0];
|
||||
}
|
||||
return provider;
|
||||
},
|
||||
|
||||
populateProviderMenu: function() {
|
||||
if (!this.iframe)
|
||||
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) {
|
||||
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");
|
||||
button.setAttribute("class", "toolbarbutton share-provider-button");
|
||||
button.setAttribute("type", "radio");
|
||||
button.setAttribute("group", "share-providers");
|
||||
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;");
|
||||
if (provider == selectedProvider) {
|
||||
this.defaultButton = button;
|
||||
}
|
||||
hbox.appendChild(button);
|
||||
}
|
||||
if (!this.defaultButton) {
|
||||
this.defaultButton = hbox.firstChild
|
||||
}
|
||||
this.defaultButton.setAttribute("checked", "true");
|
||||
this.panel.firstChild.hidden = false;
|
||||
},
|
||||
|
||||
get shareButton() {
|
||||
return document.getElementById("social-share-button");
|
||||
},
|
||||
|
||||
canSharePage: function(aURI) {
|
||||
// we do not enable sharing from private sessions
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(window))
|
||||
return false;
|
||||
|
||||
if (!aURI || !(aURI.schemeIs('http') || aURI.schemeIs('https')))
|
||||
return false;
|
||||
|
||||
// The share button and context menus are disabled if the current tab has
|
||||
// defined no-store. However, a share from other content is still possible
|
||||
// (eg. via mozSocial or future use of web activities). If the URI is not
|
||||
// the current tab URI, we cannot validate the no-store header on the URI.
|
||||
if (aURI != gBrowser.currentURI)
|
||||
return true;
|
||||
|
||||
// we want to ensure this is a successful load and that the page is locally
|
||||
// cacheable since that is a common mechanism for sensitive pages to avoid
|
||||
// storing sensitive data in cache.
|
||||
let channel = gBrowser.docShell.currentDocumentChannel;
|
||||
let httpChannel;
|
||||
try {
|
||||
httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
|
||||
} catch (e) {
|
||||
/* Not an HTTP channel. */
|
||||
Cu.reportError("cannot share without httpChannel");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Continue only if we have a 2xx status code.
|
||||
try {
|
||||
if (!httpChannel.requestSucceeded)
|
||||
return false;
|
||||
} catch (e) {
|
||||
// Can't get response information from the httpChannel
|
||||
// because mResponseHead is not available.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cache-Control: no-store.
|
||||
if (httpChannel.isNoStoreResponse()) {
|
||||
Cu.reportError("cannot share cache-control: no-share");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
update: function() {
|
||||
let shareButton = this.shareButton;
|
||||
shareButton.hidden = !SocialUI.enabled ||
|
||||
[p for (p of Social.providers) if (p.shareURL)].length == 0;
|
||||
shareButton.disabled = shareButton.hidden || !this.canSharePage(gBrowser.currentURI);
|
||||
|
||||
// also update the relevent command's disabled state so the keyboard
|
||||
// shortcut only works when available.
|
||||
let cmd = document.getElementById("Social:SharePage");
|
||||
cmd.setAttribute("disabled", shareButton.disabled ? "true" : "false");
|
||||
},
|
||||
|
||||
onShowing: function() {
|
||||
this.shareButton.setAttribute("open", "true");
|
||||
},
|
||||
|
||||
onHidden: function() {
|
||||
this.shareButton.removeAttribute("open");
|
||||
this.iframe.setAttribute("src", "data:text/plain;charset=utf8,")
|
||||
this.currentShare = null;
|
||||
},
|
||||
|
||||
setErrorMessage: function() {
|
||||
let iframe = this.iframe;
|
||||
if (!iframe)
|
||||
return;
|
||||
|
||||
iframe.removeAttribute("src");
|
||||
iframe.webNavigation.loadURI("about:socialerror?mode=compactInfo&origin=" +
|
||||
encodeURIComponent(iframe.getAttribute("origin")),
|
||||
null, null, null, null);
|
||||
sizeSocialPanelToContent(this.panel, iframe);
|
||||
},
|
||||
|
||||
sharePage: function(providerOrigin, graphData) {
|
||||
// if providerOrigin is undefined, we use the last-used provider, or the
|
||||
// current/default provider. The provider selection in the share panel
|
||||
// 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
|
||||
// in mozSocial API, or via nsContentMenu calls. If it is present, it MUST
|
||||
// define at least url. If it is undefined, we're sharing the current url in
|
||||
// the browser tab.
|
||||
let sharedURI = graphData ? Services.io.newURI(graphData.url, null, null) :
|
||||
gBrowser.currentURI;
|
||||
if (!this.canSharePage(sharedURI))
|
||||
return;
|
||||
|
||||
// the point of this action type is that we can use existing share
|
||||
// endpoints (e.g. oexchange) that do not support additional
|
||||
// socialapi functionality. One tweak is that we shoot an event
|
||||
// containing the open graph data.
|
||||
let pageData = graphData ? graphData : this.currentShare;
|
||||
if (!pageData || sharedURI == gBrowser.currentURI) {
|
||||
pageData = OpenGraphBuilder.getData(gBrowser);
|
||||
if (graphData) {
|
||||
// overwrite data retreived from page with data given to us as a param
|
||||
for (let p in graphData) {
|
||||
pageData[p] = graphData[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.currentShare = pageData;
|
||||
|
||||
let shareEndpoint = this._generateShareEndpointURL(provider.shareURL, pageData);
|
||||
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
// if we've already loaded this provider/page share endpoint, we don't want
|
||||
// to add another load event listener.
|
||||
let reload = true;
|
||||
let endpointMatch = shareEndpoint == iframe.getAttribute("src");
|
||||
let docLoaded = iframe.contentDocument && iframe.contentDocument.readyState == "complete";
|
||||
if (endpointMatch && docLoaded) {
|
||||
reload = shareEndpoint != iframe.contentDocument.location.spec;
|
||||
}
|
||||
if (!reload) {
|
||||
this._dynamicResizer.start(this.panel, iframe);
|
||||
iframe.docShell.isActive = true;
|
||||
iframe.docShell.isAppTab = true;
|
||||
let evt = iframe.contentDocument.createEvent("CustomEvent");
|
||||
evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(pageData));
|
||||
iframe.contentDocument.documentElement.dispatchEvent(evt);
|
||||
} else {
|
||||
// first time load, wait for load and dispatch after load
|
||||
iframe.addEventListener("load", function panelBrowserOnload(e) {
|
||||
iframe.removeEventListener("load", panelBrowserOnload, true);
|
||||
iframe.docShell.isActive = true;
|
||||
iframe.docShell.isAppTab = true;
|
||||
setTimeout(function() {
|
||||
if (SocialShare._dynamicResizer) { // may go null if hidden quickly
|
||||
SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
|
||||
}
|
||||
}, 0);
|
||||
let evt = iframe.contentDocument.createEvent("CustomEvent");
|
||||
evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(pageData));
|
||||
iframe.contentDocument.documentElement.dispatchEvent(evt);
|
||||
}, true);
|
||||
}
|
||||
// always ensure that origin belongs to the endpoint
|
||||
let uri = Services.io.newURI(shareEndpoint, null, null);
|
||||
iframe.setAttribute("origin", provider.origin);
|
||||
iframe.setAttribute("src", shareEndpoint);
|
||||
|
||||
let navBar = document.getElementById("nav-bar");
|
||||
let anchor = navBar.getAttribute("mode") == "text" ?
|
||||
document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-text") :
|
||||
document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-icon");
|
||||
this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
Social.setErrorListener(iframe, this.setErrorMessage.bind(this));
|
||||
},
|
||||
|
||||
_generateShareEndpointURL: function(shareURL, pageData) {
|
||||
// support for existing share endpoints by supporting their querystring
|
||||
// arguments. parse the query string template and do replacements where
|
||||
// necessary the query names may be different than ours, so we could see
|
||||
// u=%{url} or url=%{url}
|
||||
let [shareEndpoint, queryString] = shareURL.split("?");
|
||||
let query = {};
|
||||
if (queryString) {
|
||||
queryString.split('&').forEach(function (val) {
|
||||
let [name, value] = val.split('=');
|
||||
let p = /%\{(.+)\}/.exec(value);
|
||||
if (!p) {
|
||||
// preserve non-template query vars
|
||||
query[name] = value;
|
||||
} else if (pageData[p[1]]) {
|
||||
query[name] = pageData[p[1]];
|
||||
} else if (p[1] == "body") {
|
||||
// build a body for emailers
|
||||
let body = "";
|
||||
if (pageData.title)
|
||||
body += pageData.title + "\n\n";
|
||||
if (pageData.description)
|
||||
body += pageData.description + "\n\n";
|
||||
if (pageData.text)
|
||||
body += pageData.text + "\n\n";
|
||||
body += pageData.url;
|
||||
query["body"] = body;
|
||||
}
|
||||
});
|
||||
}
|
||||
var str = [];
|
||||
for (let p in query)
|
||||
str.push(p + "=" + encodeURIComponent(query[p]));
|
||||
if (str.length)
|
||||
shareEndpoint = shareEndpoint + "?" + str.join("&");
|
||||
return shareEndpoint;
|
||||
}
|
||||
};
|
||||
|
||||
SocialMark = {
|
||||
// Called once, after window load, when the Social.provider object is initialized
|
||||
init: function SSB_init() {
|
||||
|
@ -598,7 +909,7 @@ SocialMark = {
|
|||
return;
|
||||
this.toggleURIMark(gBrowser.currentURI, aCallback)
|
||||
},
|
||||
|
||||
|
||||
toggleURIMark: function(aURI, aCallback) {
|
||||
let update = function(marked) {
|
||||
this._updateMarkState(marked);
|
||||
|
@ -694,13 +1005,17 @@ SocialToolbar = {
|
|||
|
||||
// Called when the Social.provider changes
|
||||
updateProvider: function () {
|
||||
let provider = Social.provider || Social.defaultProvider;
|
||||
let provider = Social.provider;
|
||||
if (provider) {
|
||||
this.button.setAttribute("label", provider.name);
|
||||
this.button.setAttribute("tooltiptext", provider.name);
|
||||
this.button.style.listStyleImage = "url(" + provider.iconURL + ")";
|
||||
|
||||
this.updateProfile();
|
||||
} else {
|
||||
this.button.setAttribute("label", gNavigatorBundle.getString("service.toolbarbutton.label"));
|
||||
this.button.setAttribute("tooltiptext", gNavigatorBundle.getString("service.toolbarbutton.tooltiptext"));
|
||||
this.button.style.removeProperty("list-style-image");
|
||||
}
|
||||
this.updateButton();
|
||||
},
|
||||
|
@ -994,11 +1309,12 @@ SocialToolbar = {
|
|||
menu.removeChild(providerMenuSep.previousSibling);
|
||||
}
|
||||
// only show a selection if enabled and there is more than one
|
||||
if (!SocialUI.enabled || Social.providers.length < 2) {
|
||||
let providers = [p for (p of Social.providers) if (p.workerURL || p.sidebarURL)];
|
||||
if (providers.length < 2) {
|
||||
providerMenuSep.hidden = true;
|
||||
return;
|
||||
}
|
||||
for (let provider of Social.providers) {
|
||||
for (let provider of providers) {
|
||||
let menuitem = document.createElement("menuitem");
|
||||
menuitem.className = "menuitem-iconic social-provider-menuitem";
|
||||
menuitem.setAttribute("image", provider.iconURL);
|
||||
|
|
|
@ -3406,6 +3406,7 @@ function BrowserToolboxCustomizeDone(aToolboxChanged) {
|
|||
XULBrowserWindow.asyncUpdateUI();
|
||||
BookmarksMenuButton.updateStarState();
|
||||
SocialMark.updateMarkState();
|
||||
SocialShare.update();
|
||||
}
|
||||
|
||||
TabsInTitlebar.allowedBy("customizing-toolbars", true);
|
||||
|
@ -3880,6 +3881,7 @@ var XULBrowserWindow = {
|
|||
// Update starring UI
|
||||
BookmarksMenuButton.updateStarState();
|
||||
SocialMark.updateMarkState();
|
||||
SocialShare.update();
|
||||
}
|
||||
|
||||
// Show or hide browser chrome based on the whitelist
|
||||
|
|
|
@ -205,6 +205,19 @@
|
|||
</vbox>
|
||||
</panel>
|
||||
|
||||
<panel id="social-share-panel"
|
||||
class="social-panel"
|
||||
type="arrow"
|
||||
orient="horizontal"
|
||||
onpopupshowing="SocialShare.onShowing()"
|
||||
onpopuphidden="SocialShare.onHidden()"
|
||||
consumeoutsideclicks="true"
|
||||
hidden="true">
|
||||
<vbox class="social-share-toolbar">
|
||||
<vbox id="social-share-provider-buttons" flex="1"/>
|
||||
</vbox>
|
||||
</panel>
|
||||
|
||||
<panel id="social-notification-panel"
|
||||
class="social-panel"
|
||||
type="arrow"
|
||||
|
@ -704,6 +717,13 @@
|
|||
onclick="BrowserGoHome(event);"
|
||||
aboutHomeOverrideTooltip="&abouthome.pageTitle;"/>
|
||||
|
||||
<toolbarbutton id="social-share-button"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
hidden="true"
|
||||
label="&sharePageCmd.label;"
|
||||
tooltiptext="&sharePageCmd.label;"
|
||||
command="Social:SharePage"/>
|
||||
|
||||
<toolbaritem id="social-toolbar-item"
|
||||
class="chromeclass-toolbar-additional"
|
||||
removable="false"
|
||||
|
@ -741,7 +761,7 @@
|
|||
label="&social.toggleNotifications.label;"
|
||||
accesskey="&social.toggleNotifications.accesskey;"/>
|
||||
<menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
|
||||
<menuseparator class="social-statusarea-separator"/>
|
||||
<menuseparator/>
|
||||
<menuseparator class="social-provider-menu" hidden="true"/>
|
||||
<menuitem class="social-addons-menuitem" command="Social:Addons"
|
||||
label="&social.addons.label;"/>
|
||||
|
|
|
@ -318,6 +318,19 @@ nsContextMenu.prototype = {
|
|||
}.bind(this));
|
||||
}
|
||||
this.showItem("context-marklink", enableLinkMark);
|
||||
|
||||
// SocialShare
|
||||
let shareButton = SocialShare.shareButton;
|
||||
let shareEnabled = shareButton && !shareButton.disabled && !this.onSocial;
|
||||
let pageShare = shareEnabled && !(this.isContentSelected ||
|
||||
this.onTextInput || this.onLink || this.onImage ||
|
||||
this.onVideo || this.onAudio);
|
||||
this.showItem("context-sharepage", pageShare);
|
||||
this.showItem("context-shareselect", shareEnabled && this.isContentSelected);
|
||||
this.showItem("context-sharelink", shareEnabled && (this.onLink || this.onPlainTextLink) && !this.onMailtoLink);
|
||||
this.showItem("context-shareimage", shareEnabled && this.onImage);
|
||||
this.showItem("context-sharevideo", shareEnabled && this.onVideo);
|
||||
this.setItemAttr("context-sharevideo", "disabled", !this.mediaURL);
|
||||
},
|
||||
|
||||
initSpellingItems: function() {
|
||||
|
@ -1498,6 +1511,22 @@ nsContextMenu.prototype = {
|
|||
SocialMark.toggleURIMark(this.linkURI);
|
||||
},
|
||||
|
||||
shareLink: function CM_shareLink() {
|
||||
SocialShare.sharePage(null, { url: this.linkURI.spec });
|
||||
},
|
||||
|
||||
shareImage: function CM_shareImage() {
|
||||
SocialShare.sharePage(null, { url: this.imageURL, previews: [ this.mediaURL ] });
|
||||
},
|
||||
|
||||
shareVideo: function CM_shareVideo() {
|
||||
SocialShare.sharePage(null, { url: this.mediaURL, source: this.mediaURL });
|
||||
},
|
||||
|
||||
shareSelect: function CM_shareSelect(selection) {
|
||||
SocialShare.sharePage(null, { url: this.browser.currentURI.spec, text: selection });
|
||||
},
|
||||
|
||||
savePageAs: function CM_savePageAs() {
|
||||
saveDocument(this.browser.contentDocument);
|
||||
},
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="focus">
|
||||
<handler event="focus" phase="capturing">
|
||||
this.parentNode.selectedChat = this;
|
||||
</handler>
|
||||
<handler event="DOMTitleChanged"><![CDATA[
|
||||
|
@ -155,10 +155,10 @@
|
|||
<binding id="chatbar">
|
||||
<content>
|
||||
<xul:hbox align="end" pack="end" anonid="innerbox" class="chatbar-innerbox" mousethrough="always" flex="1">
|
||||
<xul:spacer flex="1" anonid="spacer" class="chatbar-overflow-spacer"/>
|
||||
<xul:toolbarbutton anonid="nub" class="chatbar-button" type="menu" collapsed="true" mousethrough="never">
|
||||
<xul:menupopup anonid="nubMenu" oncommand="document.getBindingParent(this).showChat(event.target.chat)"/>
|
||||
</xul:toolbarbutton>
|
||||
<xul:spacer flex="1" anonid="spacer" class="chatbar-overflow-spacer"/>
|
||||
<children/>
|
||||
</xul:hbox>
|
||||
</content>
|
||||
|
|
|
@ -32,6 +32,7 @@ _BROWSER_FILES = \
|
|||
browser_social_window.js \
|
||||
social_activate.html \
|
||||
social_activate_iframe.html \
|
||||
browser_share.js \
|
||||
social_panel.html \
|
||||
social_mark_image.png \
|
||||
social_sidebar.html \
|
||||
|
@ -39,6 +40,7 @@ _BROWSER_FILES = \
|
|||
social_flyout.html \
|
||||
social_window.html \
|
||||
social_worker.js \
|
||||
share.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
|
||||
let baseURL = "https://example.com/browser/browser/base/content/test/social/";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example.com",
|
||||
sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
|
||||
workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
|
||||
iconURL: "https://example.com/browser/browser/base/content/test/moz.png",
|
||||
shareURL: "https://example.com/browser/browser/base/content/test/social/share.html"
|
||||
};
|
||||
runSocialTestWithProvider(manifest, function (finishcb) {
|
||||
runSocialTests(tests, undefined, undefined, finishcb);
|
||||
});
|
||||
}
|
||||
|
||||
let corpus = [
|
||||
{
|
||||
url: baseURL+"opengraph/opengraph.html",
|
||||
options: {
|
||||
// og:title
|
||||
title: ">This is my title<",
|
||||
// og:description
|
||||
description: "A test corpus file for open graph tags we care about",
|
||||
//medium: this.getPageMedium(),
|
||||
//source: this.getSourceURL(),
|
||||
// og:url
|
||||
url: "https://www.mozilla.org/",
|
||||
//shortUrl: this.getShortURL(),
|
||||
// og:image
|
||||
previews:["https://www.mozilla.org/favicon.png"],
|
||||
// og:site_name
|
||||
siteName: ">My simple test page<"
|
||||
}
|
||||
},
|
||||
{
|
||||
// tests that og:url doesn't override the page url if it is bad
|
||||
url: baseURL+"opengraph/og_invalid_url.html",
|
||||
options: {
|
||||
description: "A test corpus file for open graph tags passing a bad url",
|
||||
url: baseURL+"opengraph/og_invalid_url.html",
|
||||
previews: [],
|
||||
siteName: "Evil chrome delivering website"
|
||||
}
|
||||
},
|
||||
{
|
||||
url: baseURL+"opengraph/shorturl_link.html",
|
||||
options: {
|
||||
previews: ["http://example.com/1234/56789.jpg"],
|
||||
url: "http://www.example.com/photos/56789/",
|
||||
shortUrl: "http://imshort/p/abcde"
|
||||
}
|
||||
},
|
||||
{
|
||||
url: baseURL+"opengraph/shorturl_linkrel.html",
|
||||
options: {
|
||||
previews: ["http://example.com/1234/56789.jpg"],
|
||||
url: "http://www.example.com/photos/56789/",
|
||||
shortUrl: "http://imshort/p/abcde"
|
||||
}
|
||||
},
|
||||
{
|
||||
url: baseURL+"opengraph/shortlink_linkrel.html",
|
||||
options: {
|
||||
previews: ["http://example.com/1234/56789.jpg"],
|
||||
url: "http://www.example.com/photos/56789/",
|
||||
shortUrl: "http://imshort/p/abcde"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function loadURLInTab(url, callback) {
|
||||
info("Loading tab with "+url);
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
|
||||
tab.linkedBrowser.addEventListener("load", function listener() {
|
||||
is(tab.linkedBrowser.currentURI.spec, url, "tab loaded")
|
||||
tab.linkedBrowser.removeEventListener("load", listener, true);
|
||||
callback(tab);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function hasoptions(testOptions, options) {
|
||||
let msg;
|
||||
for (let option in testOptions) {
|
||||
let data = testOptions[option];
|
||||
info("data: "+JSON.stringify(data));
|
||||
let message_data = options[option];
|
||||
info("message_data: "+JSON.stringify(message_data));
|
||||
if (Array.isArray(data)) {
|
||||
// the message may have more array elements than we are testing for, this
|
||||
// is ok since some of those are hard to test. So we just test that
|
||||
// anything in our test data IS in the message.
|
||||
ok(Array.every(data, function(item) { return message_data.indexOf(item) >= 0 }), "option "+option);
|
||||
} else {
|
||||
is(message_data, data, "option "+option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tests = {
|
||||
testSharePage: function(next) {
|
||||
let panel = document.getElementById("social-flyout-panel");
|
||||
let port = Social.provider.getWorkerPort();
|
||||
ok(port, "provider has a port");
|
||||
let testTab;
|
||||
let testIndex = 0;
|
||||
let testData = corpus[testIndex++];
|
||||
|
||||
function runOneTest() {
|
||||
loadURLInTab(testData.url, function(tab) {
|
||||
testTab = tab;
|
||||
SocialShare.sharePage();
|
||||
});
|
||||
}
|
||||
|
||||
port.onmessage = function (e) {
|
||||
let topic = e.data.topic;
|
||||
switch (topic) {
|
||||
case "got-sidebar-message":
|
||||
// open a tab with share data, then open the share panel
|
||||
runOneTest();
|
||||
break;
|
||||
case "got-share-data-message":
|
||||
gBrowser.removeTab(testTab);
|
||||
hasoptions(testData.options, e.data.result);
|
||||
testData = corpus[testIndex++];
|
||||
if (testData) {
|
||||
runOneTest();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
port.postMessage({topic: "test-init"});
|
||||
}
|
||||
}
|
|
@ -65,12 +65,16 @@ function startTestAndWaitForSidebar(callback) {
|
|||
let topic = e.data.topic;
|
||||
switch (topic) {
|
||||
case "got-sidebar-message":
|
||||
// if sidebar loaded too fast, we need a backup ping
|
||||
case "got-isVisible-response":
|
||||
isSidebarLoaded = true;
|
||||
maybeCallback();
|
||||
break;
|
||||
case "test-init-done":
|
||||
if (isSidebarLoaded)
|
||||
maybeCallback();
|
||||
else
|
||||
port.postMessage({topic: "test-isVisible"});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +106,7 @@ function test() {
|
|||
// tab.linkedBrowser.contentWindow.focus()
|
||||
// but instead we must do:
|
||||
tab.linkedBrowser.contentDocument.getElementById("theinput").focus();
|
||||
cb();
|
||||
waitForCondition(function() isTabFocused(), cb, "tab should have focus");
|
||||
}
|
||||
let postSubTest = function(cb) {
|
||||
window.SocialChatBar.chatbar.removeAll();
|
||||
|
@ -138,10 +142,12 @@ var tests = {
|
|||
ok(isTabFocused(), "tab should still be focused");
|
||||
// re-request the same chat via user event.
|
||||
openChatViaUser();
|
||||
is(SocialChatBar.chatbar.childElementCount, 1, "still exactly 1 chat open");
|
||||
// should now be focused
|
||||
ok(isChatFocused(SocialChatBar.chatbar.firstElementChild), "chat should be focused");
|
||||
next();
|
||||
waitForCondition(function() isChatFocused(SocialChatBar.chatbar.selectedChat),
|
||||
function() {
|
||||
is(SocialChatBar.chatbar.childElementCount, 1, "still exactly 1 chat open");
|
||||
is(SocialChatBar.chatbar.selectedChat, SocialChatBar.chatbar.firstElementChild, "chat should be selected");
|
||||
next();
|
||||
}, "chat should be focused");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -153,8 +159,11 @@ var tests = {
|
|||
startTestAndWaitForSidebar(function(port) {
|
||||
openChatViaUser();
|
||||
ok(SocialChatBar.chatbar.firstElementChild, "chat opened");
|
||||
ok(isChatFocused(SocialChatBar.chatbar.firstElementChild), "chat should be focused");
|
||||
next();
|
||||
waitForCondition(function() isChatFocused(SocialChatBar.chatbar.selectedChat),
|
||||
function() {
|
||||
is(SocialChatBar.chatbar.selectedChat, SocialChatBar.chatbar.firstElementChild, "chat is selected");
|
||||
next();
|
||||
}, "chat should be focused");
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -168,10 +177,14 @@ var tests = {
|
|||
openChatViaWorkerMessage(port, chatUrl, function() {
|
||||
is(chatbar.childElementCount, 1, "exactly 1 chat open");
|
||||
ok(chatbar.firstElementChild.minimized, "chat is minimized");
|
||||
// bug 865086 opening minimized still sets the window as selected
|
||||
todo(chatbar.selectedChat != chatbar.firstElementChild, "chat is not selected");
|
||||
ok(isTabFocused(), "tab should be focused");
|
||||
openChatViaSidebarMessage(port, {stealFocus: 1, id: 1}, function() {
|
||||
is(chatbar.childElementCount, 1, "still 1 chat open");
|
||||
ok(!chatbar.firstElementChild.minimized, "chat no longer minimized");
|
||||
// bug 865086 because we marked it selected on open, it still is
|
||||
todo(chatbar.selectedChat != chatbar.firstElementChild, "chat is not selected");
|
||||
ok(isTabFocused(), "tab should still be focused");
|
||||
next();
|
||||
});
|
||||
|
@ -192,9 +205,13 @@ var tests = {
|
|||
ok(isTabFocused(), "tab should still be focused");
|
||||
// pretend we clicked on the titlebar
|
||||
chatbox.onTitlebarClick({button: 0});
|
||||
ok(!chatbox.minimized, "chat should have been restored");
|
||||
ok(isChatFocused(chatbox), "chat should be focused");
|
||||
next();
|
||||
waitForCondition(function() isChatFocused(SocialChatBar.chatbar.selectedChat),
|
||||
function() {
|
||||
ok(!chatbox.minimized, "chat should have been restored");
|
||||
ok(isChatFocused(chatbox), "chat should be focused");
|
||||
is(chatbox, SocialChatBar.chatbar.selectedChat, "chat is marked selected");
|
||||
next();
|
||||
}, "chat should have focus");
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -211,11 +228,19 @@ var tests = {
|
|||
let chat2 = chat1.nextElementSibling || chat1.previousElementSibling;
|
||||
chatbar.selectedChat = chat1;
|
||||
chatbar.focus();
|
||||
ok(isChatFocused(chat1), "first chat should be focused");
|
||||
chat1.minimized = true;
|
||||
// minimizing the chat with focus should give it to another.
|
||||
ok(isChatFocused(chat2), "second chat should be focused");
|
||||
next();
|
||||
waitForCondition(function() isChatFocused(chat1),
|
||||
function() {
|
||||
is(chat1, SocialChatBar.chatbar.selectedChat, "chat1 is marked selected");
|
||||
isnot(chat2, SocialChatBar.chatbar.selectedChat, "chat2 is not marked selected");
|
||||
chat1.minimized = true;
|
||||
waitForCondition(function() isChatFocused(chat2),
|
||||
function() {
|
||||
// minimizing the chat with focus should give it to another.
|
||||
isnot(chat1, SocialChatBar.chatbar.selectedChat, "chat1 is not marked selected");
|
||||
is(chat2, SocialChatBar.chatbar.selectedChat, "chat2 is marked selected");
|
||||
next();
|
||||
}, "chat2 should have focus");
|
||||
}, "chat1 should have focus");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -269,30 +294,32 @@ var tests = {
|
|||
let chat2 = chat1.nextElementSibling || chat1.previousElementSibling;
|
||||
chatbar.selectedChat = chat2;
|
||||
chatbar.focus();
|
||||
ok(isChatFocused(chat2), "new chat is focused");
|
||||
// Our chats have 3 focusable elements, so it takes 4 TABs to move
|
||||
// to the new chat.
|
||||
sendTabAndWaitForFocus(chat2, "input1", function() {
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input1",
|
||||
"first input field has focus");
|
||||
ok(isChatFocused(chat2), "new chat still focused after first tab");
|
||||
sendTabAndWaitForFocus(chat2, "input2", function() {
|
||||
ok(isChatFocused(chat2), "new chat still focused after tab");
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
|
||||
"second input field has focus");
|
||||
sendTabAndWaitForFocus(chat2, "iframe", function() {
|
||||
waitForCondition(function() isChatFocused(chatbar.selectedChat),
|
||||
function() {
|
||||
// Our chats have 3 focusable elements, so it takes 4 TABs to move
|
||||
// to the new chat.
|
||||
sendTabAndWaitForFocus(chat2, "input1", function() {
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input1",
|
||||
"first input field has focus");
|
||||
ok(isChatFocused(chat2), "new chat still focused after first tab");
|
||||
sendTabAndWaitForFocus(chat2, "input2", function() {
|
||||
ok(isChatFocused(chat2), "new chat still focused after tab");
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "iframe",
|
||||
"iframe has focus");
|
||||
// this tab now should move to the next chat, but focus the
|
||||
// document element itself (hence the null eltid)
|
||||
sendTabAndWaitForFocus(chat1, null, function() {
|
||||
ok(isChatFocused(chat1), "first chat is focused");
|
||||
next();
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
|
||||
"second input field has focus");
|
||||
sendTabAndWaitForFocus(chat2, "iframe", function() {
|
||||
ok(isChatFocused(chat2), "new chat still focused after tab");
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "iframe",
|
||||
"iframe has focus");
|
||||
// this tab now should move to the next chat, but focus the
|
||||
// document element itself (hence the null eltid)
|
||||
sendTabAndWaitForFocus(chat1, null, function() {
|
||||
ok(isChatFocused(chat1), "first chat is focused");
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}, "chat should have focus");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -310,17 +337,24 @@ var tests = {
|
|||
chat.addEventListener("DOMContentLoaded", function DOMContentLoaded() {
|
||||
chat.removeEventListener("DOMContentLoaded", DOMContentLoaded);
|
||||
chat.iframe.contentDocument.getElementById("input2").focus();
|
||||
is(chat.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
|
||||
"correct input field has focus");
|
||||
// set focus to the tab.
|
||||
let tabb = gBrowser.getBrowserForTab(gBrowser.selectedTab);
|
||||
Services.focus.moveFocus(tabb.contentWindow, null, Services.focus.MOVEFOCUS_ROOT, 0);
|
||||
ok(isTabFocused(), "tab took focus");
|
||||
chatbar.focus();
|
||||
ok(isChatFocused(chat), "chat took focus");
|
||||
is(chat.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
|
||||
"correct input field still has focus");
|
||||
next();
|
||||
waitForCondition(function() isChatFocused(chat),
|
||||
function() {
|
||||
is(chat.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
|
||||
"correct input field has focus");
|
||||
// set focus to the tab.
|
||||
let tabb = gBrowser.getBrowserForTab(gBrowser.selectedTab);
|
||||
Services.focus.moveFocus(tabb.contentWindow, null, Services.focus.MOVEFOCUS_ROOT, 0);
|
||||
waitForCondition(function() isTabFocused(),
|
||||
function() {
|
||||
chatbar.focus();
|
||||
waitForCondition(function() isChatFocused(chat),
|
||||
function() {
|
||||
is(chat.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
|
||||
"correct input field still has focus");
|
||||
next();
|
||||
}, "chat took focus");
|
||||
}, "tab has focus");
|
||||
}, "chat took focus");
|
||||
});
|
||||
});
|
||||
},
|
||||
|
|
|
@ -49,7 +49,16 @@ var tests = {
|
|||
observeProviderSet(function () {
|
||||
waitForProviderLoad(function() {
|
||||
checkUIStateMatchesProvider(gProviders[1]);
|
||||
next();
|
||||
// disable social, click on the provider menuitem to switch providers
|
||||
Social.enabled = false;
|
||||
let menu = document.getElementById("social-statusarea-popup");
|
||||
let el = menu.getElementsByAttribute("origin", gProviders[0].origin);
|
||||
is(el.length, 1, "selected provider menu item exists");
|
||||
el[0].click();
|
||||
waitForProviderLoad(function() {
|
||||
checkUIStateMatchesProvider(gProviders[0]);
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
Social.activateFromOrigin("https://test1.example.com");
|
||||
|
|
|
@ -190,8 +190,13 @@ function checkSocialUI(win) {
|
|||
isbool(!win.SocialMark.button.hidden, markVisible, "SocialMark button visible?");
|
||||
isbool(!win.SocialMark.button.disabled, canMark, "SocialMark button enabled?");
|
||||
isbool(!doc.getElementById("social-toolbar-item").hidden, active, "toolbar items visible?");
|
||||
if (active)
|
||||
is(win.SocialToolbar.button.style.listStyleImage, 'url("' + Social.defaultProvider.iconURL + '")', "toolbar button has provider icon");
|
||||
if (active) {
|
||||
if (!enabled) {
|
||||
ok(!win.SocialToolbar.button.style.listStyleImage, "toolbar button is default icon");
|
||||
} else {
|
||||
is(win.SocialToolbar.button.style.listStyleImage, 'url("' + Social.defaultProvider.iconURL + '")', "toolbar button has provider icon");
|
||||
}
|
||||
}
|
||||
// the menus should always have the provider name
|
||||
if (provider) {
|
||||
for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
# 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/.
|
||||
|
||||
DIRS += ['opengraph']
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# 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/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = @relativesrcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
_BROWSER_FILES = \
|
||||
opengraph.html \
|
||||
og_invalid_url.html \
|
||||
shortlink_linkrel.html \
|
||||
shorturl_link.html \
|
||||
shorturl_linkrel.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs:: $(_BROWSER_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
|
@ -1,6 +1,4 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<html xmlns:og="http://ogp.me/ns#">
|
||||
<head>
|
||||
<meta property="og:url" content="chrome://browser/content/aboutDialog.xul"/>
|
||||
<meta property="og:site_name" content="Evil chrome delivering website"/>
|
||||
<meta property="og:description"
|
||||
content="A test corpus file for open graph tags passing a bad url"/>
|
||||
</head>
|
||||
<body>
|
||||
Open Graph Test Page
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<html xmlns:og="http://ogp.me/ns#">
|
||||
<head>
|
||||
<meta property="og:title" content=">This is my title<"/>
|
||||
<meta property="og:url" content="https://www.mozilla.org"/>
|
||||
<meta property="og:image" content="https://www.mozilla.org/favicon.png"/>
|
||||
<meta property="og:site_name" content=">My simple test page<"/>
|
||||
<meta property="og:description"
|
||||
content="A test corpus file for open graph tags we care about"/>
|
||||
</head>
|
||||
<body>
|
||||
Open Graph Test Page
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
|
||||
<link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
|
||||
<link rel="shortlink" href="http://imshort/p/abcde" />
|
||||
</head>
|
||||
<body>
|
||||
link[rel='shortlink']
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
|
||||
<link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
|
||||
<link id="shorturl" rev="canonical" type="text/html" href="http://imshort/p/abcde" />
|
||||
</head>
|
||||
<body>
|
||||
link id="shorturl"
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,25 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Test Image</title>
|
||||
|
||||
<meta name="description" content="Iron man in a tutu" />
|
||||
<meta name="title" content="Test Image" />
|
||||
|
||||
<meta name="medium" content="image" />
|
||||
<link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
|
||||
<link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
|
||||
<link id="shorturl" href="http://imshort/p/abcde" />
|
||||
|
||||
<meta property="og:title" content="TestImage" />
|
||||
<meta property="og:type" content="photos:photo" />
|
||||
<meta property="og:url" content="http://www.example.com/photos/56789/" />
|
||||
<meta property="og:site_name" content="My Photo Site" />
|
||||
<meta property="og:description" content="Iron man in a tutu" />
|
||||
<meta property="og:image" content="http://example.com/1234/56789.jpg" />
|
||||
<meta property="og:image:width" content="480" />
|
||||
<meta property="og:image:height" content="640" />
|
||||
</head>
|
||||
<body>
|
||||
link[rel='shorturl']
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
var shareData;
|
||||
addEventListener("OpenGraphData", function(e) {
|
||||
shareData = JSON.parse(e.detail);
|
||||
var port = navigator.mozSocial.getWorker().port;
|
||||
port.postMessage({topic: "share-data-message", result: shareData});
|
||||
// share windows self-close
|
||||
window.close();
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p>This is a test social share window.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -133,6 +133,10 @@ onconnect = function(e) {
|
|||
case "test-isVisible-response":
|
||||
testPort.postMessage({topic: "got-isVisible-response", result: event.data.result});
|
||||
break;
|
||||
case "share-data-message":
|
||||
if (testPort)
|
||||
testPort.postMessage({topic:"got-share-data-message", result: event.data.result});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
MOCHITEST_BROWSER_FILES = \
|
||||
head.js \
|
||||
browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js \
|
||||
browser_privatebrowsing_aboutSessionRestore.js \
|
||||
browser_privatebrowsing_certexceptionsui.js \
|
||||
browser_privatebrowsing_concurrent.js \
|
||||
browser_privatebrowsing_concurrent_page.html \
|
||||
|
@ -32,6 +34,7 @@ MOCHITEST_BROWSER_FILES = \
|
|||
browser_privatebrowsing_localStorage_page1.html \
|
||||
browser_privatebrowsing_localStorage_page2.html \
|
||||
browser_privatebrowsing_nonbrowser.js \
|
||||
browser_privatebrowsing_noSessionRestoreMenuOption.js \
|
||||
browser_privatebrowsing_opendir.js \
|
||||
browser_privatebrowsing_openlocation.js \
|
||||
browser_privatebrowsing_openLocationLastURL.js \
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/* 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/. */
|
||||
|
||||
// This test checks that the Session Restore about:home button
|
||||
// is disabled in private mode
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
function testNoSessionRestoreButton() {
|
||||
let win = OpenBrowserWindow({private: true});
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
executeSoon(function() {
|
||||
info("The second private window got loaded");
|
||||
let newTab = win.gBrowser.addTab("about:home");
|
||||
win.gBrowser.selectedTab = newTab;
|
||||
let tabBrowser = win.gBrowser.getBrowserForTab(newTab);
|
||||
tabBrowser.addEventListener("load", function tabLoadListener() {
|
||||
tabBrowser.removeEventListener("load", tabLoadListener, true);
|
||||
executeSoon(function() {
|
||||
info("about:home got loaded");
|
||||
let sessionRestoreButton = win.gBrowser
|
||||
.contentDocument
|
||||
.getElementById("restorePreviousSession");
|
||||
is(win.getComputedStyle(sessionRestoreButton).display,
|
||||
"none", "The Session Restore about:home button should be disabled");
|
||||
win.close();
|
||||
finish();
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
let win = OpenBrowserWindow({private: true});
|
||||
win.addEventListener("load", function onload() {
|
||||
win.removeEventListener("load", onload, false);
|
||||
executeSoon(function() {
|
||||
info("The first private window got loaded");
|
||||
win.close();
|
||||
testNoSessionRestoreButton();
|
||||
});
|
||||
}, false);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* 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/. */
|
||||
|
||||
// This test checks that the session restore button from about:sessionrestore
|
||||
// is disabled in private mode
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
function testNoSessionRestoreButton() {
|
||||
let win = OpenBrowserWindow({private: true});
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
executeSoon(function() {
|
||||
info("The second private window got loaded");
|
||||
let newTab = win.gBrowser.addTab("about:sessionrestore");
|
||||
win.gBrowser.selectedTab = newTab;
|
||||
let tabBrowser = win.gBrowser.getBrowserForTab(newTab);
|
||||
tabBrowser.addEventListener("load", function tabLoadListener() {
|
||||
tabBrowser.removeEventListener("load", tabLoadListener, true);
|
||||
executeSoon(function() {
|
||||
info("about:sessionrestore got loaded");
|
||||
let restoreButton = win.gBrowser.contentDocument
|
||||
.getElementById("errorTryAgain");
|
||||
ok(restoreButton.disabled,
|
||||
"The Restore about:sessionrestore button should be disabled");
|
||||
win.close();
|
||||
finish();
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
let win = OpenBrowserWindow({private: true});
|
||||
win.addEventListener("load", function onload() {
|
||||
win.removeEventListener("load", onload, false);
|
||||
executeSoon(function() {
|
||||
info("The first private window got loaded");
|
||||
win.close();
|
||||
testNoSessionRestoreButton();
|
||||
});
|
||||
}, false);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* 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/. */
|
||||
|
||||
// This test checks that the Session Restore menu option is not enabled in private mode
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
function testNoSessionRestoreMenuItem() {
|
||||
let win = OpenBrowserWindow({private: true});
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
ok(true, "The second private window got loaded");
|
||||
let srCommand = win.document.getElementById("Browser:RestoreLastSession");
|
||||
ok(srCommand, "The Session Restore command should exist");
|
||||
is(PrivateBrowsingUtils.isWindowPrivate(win), true,
|
||||
"PrivateBrowsingUtils should report the correct per-window private browsing status");
|
||||
is(srCommand.hasAttribute("disabled"), true,
|
||||
"The Session Restore command should be disabled in private browsing mode");
|
||||
win.close();
|
||||
finish();
|
||||
}, false);
|
||||
}
|
||||
|
||||
let win = OpenBrowserWindow({private: true});
|
||||
win.addEventListener("load", function onload() {
|
||||
win.removeEventListener("load", onload, false);
|
||||
ok(true, "The first private window got loaded");
|
||||
win.gBrowser.addTab("about:mozilla");
|
||||
win.close();
|
||||
testNoSessionRestoreMenuItem();
|
||||
}, false);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux32
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
# PGO
|
||||
mk_add_options MOZ_PGO=1
|
||||
mk_add_options PROFILE_GEN_SCRIPT='EXTRA_TEST_ARGS=10 $(MAKE) -C $(MOZ_OBJDIR) pgo-profile-run'
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
|
@ -1,25 +1,7 @@
|
|||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux32/beta"
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux32
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
# PGO
|
||||
mk_add_options MOZ_PGO=1
|
||||
mk_add_options PROFILE_GEN_SCRIPT='EXTRA_TEST_ARGS=10 $(MAKE) -C $(MOZ_OBJDIR) pgo-profile-run'
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
# PGO
|
||||
mk_add_options MOZ_PGO=1
|
||||
mk_add_options PROFILE_GEN_SCRIPT='EXTRA_TEST_ARGS=10 $(MAKE) -C $(MOZ_OBJDIR) pgo-profile-run'
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
|
@ -1,25 +1,7 @@
|
|||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux64/beta"
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
# PGO
|
||||
mk_add_options MOZ_PGO=1
|
||||
mk_add_options PROFILE_GEN_SCRIPT='EXTRA_TEST_ARGS=10 $(MAKE) -C $(MOZ_OBJDIR) pgo-profile-run'
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
. $topsrcdir/build/macosx/universal/mozconfig
|
||||
|
||||
# Universal builds override the default of browser (bug 575283 comment 29)
|
||||
ac_add_options --enable-application=browser
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
|
@ -1,21 +1,7 @@
|
|||
. $topsrcdir/build/macosx/universal/mozconfig
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/beta"
|
||||
|
||||
# Universal builds override the default of browser (bug 575283 comment 29)
|
||||
ac_add_options --enable-application=browser
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
. "$topsrcdir/browser/config/mozconfigs/common"
|
||||
|
||||
# for pgo
|
||||
mk_add_options MOZ_PGO=1
|
||||
mk_add_options PROFILE_GEN_SCRIPT='$(MAKE) -C $(MOZ_OBJDIR) pgo-profile-run'
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-jemalloc
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
if test -z "${_PYMAKE}"; then
|
||||
mk_add_options MOZ_MAKE_FLAGS=-j1
|
||||
fi
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010
|
||||
fi
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
|
@ -1,33 +1,7 @@
|
|||
. "$topsrcdir/browser/config/mozconfigs/common"
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
. "$topsrcdir/browser/config/mozconfigs/win32/beta"
|
||||
|
||||
# for pgo
|
||||
mk_add_options MOZ_PGO=1
|
||||
mk_add_options PROFILE_GEN_SCRIPT='$(MAKE) -C $(MOZ_OBJDIR) pgo-profile-run'
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-jemalloc
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
if test -z "${_PYMAKE}"; then
|
||||
mk_add_options MOZ_MAKE_FLAGS=-j1
|
||||
fi
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010
|
||||
fi
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
Content-Type: text/cache-manifest; charset=ISO-8859-1
|
||||
Last-Modified: Tue, 23 Apr 9998 11:41:13 GMT
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
Content-Type: text/cache-manifest
|
||||
Last-Modified: Tue, 23 Apr 9998 11:41:13 GMT
|
||||
|
|
|
@ -15,7 +15,6 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
browser_dbg_clean-exit.js \
|
||||
browser_dbg_cmd.js \
|
||||
$(browser_dbg_cmd_break.js disabled until bug 722727 is fixed) \
|
||||
browser_dbg_createChrome.js \
|
||||
$(browser_dbg_createRemote.js disabled for intermittent failures, bug 753225) \
|
||||
browser_dbg_debuggerstatement.js \
|
||||
browser_dbg_listtabs.js \
|
||||
|
@ -138,6 +137,14 @@ MOCHITEST_BROWSER_PAGES = \
|
|||
test-location-changes-bp.html \
|
||||
$(NULL)
|
||||
|
||||
ifneq (Linux,$(OS_ARCH))
|
||||
MOCHITEST_BROWSER_TESTS += \
|
||||
browser_dbg_createChrome.js \
|
||||
$(NULL)
|
||||
else
|
||||
$(browser_dbg_createChrome.js disabled to fix for ubuntu hangs, bug 847558)
|
||||
endif
|
||||
|
||||
MOCHITEST_BROWSER_FILES_PARTS = MOCHITEST_BROWSER_TESTS MOCHITEST_BROWSER_PAGES
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -116,6 +116,17 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
|||
<!ENTITY bookmarkThisPageCmd.label "Bookmark This Page">
|
||||
<!ENTITY bookmarkThisPageCmd.commandkey "d">
|
||||
<!ENTITY markPageCmd.commandkey "l">
|
||||
<!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 shareImageCmd.label "Share This Image">
|
||||
<!ENTITY shareImageCmd.accesskey "s">
|
||||
<!ENTITY shareSelectCmd.label "Share Selection">
|
||||
<!ENTITY shareSelectCmd.accesskey "s">
|
||||
<!ENTITY shareVideoCmd.label "Share This Video">
|
||||
<!ENTITY shareVideoCmd.accesskey "s">
|
||||
<!ENTITY subscribeToPageMenupopup.label "Subscribe to This Page">
|
||||
<!ENTITY subscribeToPageMenuitem.label "Subscribe to This Page…">
|
||||
<!ENTITY addCurPagesCmd.label "Bookmark All Tabs…">
|
||||
|
|
|
@ -375,6 +375,9 @@ fullscreen.entered=%S is now fullscreen.
|
|||
# LOCALIZATION NOTE (fullscreen.rememberDecision): displayed when we enter HTML5 fullscreen mode, %S is the domain name of the focused website (e.g. mozilla.com).
|
||||
fullscreen.rememberDecision=Remember decision for %S
|
||||
|
||||
service.toolbarbutton.label=Services
|
||||
service.toolbarbutton.tooltiptext=Services
|
||||
|
||||
# LOCALIZATION NOTE (social.install.description): %1$S is the hostname of the social provider, %2$S is brandShortName (e.g. Firefox)
|
||||
service.install.description=Would you like to enable services from %1$S to display in your %2$S toolbar and sidebar?
|
||||
service.install.ok.label=Enable Services
|
||||
|
|
|
@ -10,6 +10,10 @@ Components.utils.import("resource://services-sync/main.js");
|
|||
* Wraps a list/grid control implementing nsIDOMXULSelectControlElement and
|
||||
* fills it with the user's synced tabs.
|
||||
*
|
||||
* Note, the Sync module takes care of initializing the sync service. We should
|
||||
* not make calls that start sync or sync tabs since this module loads really
|
||||
* early during startup.
|
||||
*
|
||||
* @param aSet Control implementing nsIDOMXULSelectControlElement.
|
||||
* @param aSetUIAccess The UI element that should be hidden when Sync is
|
||||
* disabled. Must sanely support 'hidden' attribute.
|
||||
|
@ -22,13 +26,10 @@ function RemoteTabsView(aSet, aSetUIAccess) {
|
|||
|
||||
// Sync uses special voodoo observers.
|
||||
// If you want to change this code, talk to the fx-si team
|
||||
Weave.Svc.Obs.add("weave:service:setup-complete", this);
|
||||
Weave.Svc.Obs.add("weave:service:sync:finish", this);
|
||||
Weave.Svc.Obs.add("weave:service:start-over", this);
|
||||
if (this.isSyncEnabled() ) {
|
||||
this.populateTabs();
|
||||
this.populateGrid();
|
||||
this.setUIAccessVisible(true);
|
||||
}
|
||||
else {
|
||||
this.setUIAccessVisible(false);
|
||||
|
@ -46,10 +47,6 @@ RemoteTabsView.prototype = {
|
|||
|
||||
observe: function(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "weave:service:setup-complete":
|
||||
this.populateTabs();
|
||||
this.setUIAccessVisible(true);
|
||||
break;
|
||||
case "weave:service:sync:finish":
|
||||
this.populateGrid();
|
||||
break;
|
||||
|
@ -72,7 +69,7 @@ RemoteTabsView.prototype = {
|
|||
// Clear grid, We don't know what has happened to tabs since last sync
|
||||
// Also can result in duplicate tabs(bug 864614)
|
||||
this._set.clearAll();
|
||||
|
||||
let show = false;
|
||||
for (let [guid, client] in Iterator(tabsEngine.getAllClients())) {
|
||||
client.tabs.forEach(function({title, urlHistory, icon}) {
|
||||
let url = urlHistory[0];
|
||||
|
@ -80,6 +77,7 @@ RemoteTabsView.prototype = {
|
|||
return;
|
||||
}
|
||||
seenURLs.add(url);
|
||||
show = true;
|
||||
|
||||
// If we wish to group tabs by client, we should be looking for records
|
||||
// of {type:client, clientName, class:{mobile, desktop}} and will
|
||||
|
@ -90,14 +88,10 @@ RemoteTabsView.prototype = {
|
|||
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
|
||||
populateTabs: function populateTabs() {
|
||||
Weave.Service.scheduler.scheduleNextSync(0);
|
||||
this.setUIAccessVisible(show);
|
||||
},
|
||||
|
||||
destruct: function destruct() {
|
||||
Weave.Svc.Obs.remove("weave:service:setup-complete", this);
|
||||
Weave.Svc.Obs.remove("weave:engine:sync:finish", this);
|
||||
Weave.Svc.Obs.remove("weave:service:logout:start-over", this);
|
||||
},
|
||||
|
|
|
@ -257,7 +257,6 @@ TopSitesView.prototype = {
|
|||
case "MozAppbarDismissing":
|
||||
// clean up when the context appbar is dismissed - we don't remember selections
|
||||
this._lastSelectedSites = null;
|
||||
this._set.clearSelection();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1,3 +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/. */
|
||||
"use strict";
|
||||
|
||||
var Appbar = {
|
||||
get appbar() { return document.getElementById('appbar'); },
|
||||
get consoleButton() { return document.getElementById('console-button'); },
|
||||
|
@ -13,6 +18,7 @@ var Appbar = {
|
|||
|
||||
init: function Appbar_init() {
|
||||
window.addEventListener('MozAppbarShowing', this, false);
|
||||
window.addEventListener('MozAppbarDismissing', this, false);
|
||||
window.addEventListener('MozPrecisePointer', this, false);
|
||||
window.addEventListener('MozImprecisePointer', this, false);
|
||||
window.addEventListener('MozContextActionsChange', this, false);
|
||||
|
@ -40,6 +46,13 @@ var Appbar = {
|
|||
this._updatePinButton();
|
||||
this._updateStarButton();
|
||||
break;
|
||||
case 'MozAppbarDismissing':
|
||||
if (this.activeTileset) {
|
||||
this.activeTileset.clearSelection();
|
||||
}
|
||||
this.clearContextualActions();
|
||||
this.activeTileset = null;
|
||||
break;
|
||||
case 'MozPrecisePointer':
|
||||
case 'MozImprecisePointer':
|
||||
this._updateZoomButtons();
|
||||
|
@ -162,7 +175,8 @@ var Appbar = {
|
|||
}
|
||||
}
|
||||
},
|
||||
showContextualActions: function(aVerbs){
|
||||
|
||||
showContextualActions: function(aVerbs) {
|
||||
let doc = document;
|
||||
// button element id to action verb lookup
|
||||
let buttonsMap = new Map();
|
||||
|
@ -195,6 +209,11 @@ var Appbar = {
|
|||
}
|
||||
});
|
||||
},
|
||||
|
||||
clearContextualActions: function() {
|
||||
this.showContextualActions([]);
|
||||
},
|
||||
|
||||
_onTileSelectionChanged: function _onTileSelectionChanged(aEvent){
|
||||
let activeTileset = aEvent.target;
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<bindings
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<binding id="cssthrobberBinding" extends="xul:box">
|
||||
<content>
|
||||
<html:div class="progressContainer">
|
||||
<html:div class="progressBall progressBall" />
|
||||
<html:div class="progressBall progressBall" />
|
||||
<html:div class="progressBall progressBall" />
|
||||
<html:div class="progressBall progressBall" />
|
||||
<html:div class="progressBall progressBall" />
|
||||
</html:div>
|
||||
</content>
|
||||
</binding>
|
||||
</bindings>
|
|
@ -354,14 +354,7 @@ BookmarksView.prototype = {
|
|||
for (let bookmarkId of this._toRemove) {
|
||||
this._bookmarkService.removeItem(bookmarkId);
|
||||
}
|
||||
|
||||
this._toRemove = null;
|
||||
this._set.clearSelection();
|
||||
|
||||
// Clear context app bar
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("MozContextActionsChange", true, false);
|
||||
this._set.dispatchEvent(event);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ let ScriptContexts = {};
|
|||
["SSLExceptions", "chrome://browser/content/exceptions.js"],
|
||||
["ItemPinHelper", "chrome://browser/content/helperui/ItemPinHelper.js"],
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
["WeaveGlue", "chrome://browser/content/sync.js"],
|
||||
["Sync", "chrome://browser/content/sync.js"],
|
||||
["SyncPairDevice", "chrome://browser/content/sync.js"],
|
||||
["RemoteTabsView", "chrome://browser/content/RemoteTabs.js"],
|
||||
["RemoteTabsPanelView", "chrome://browser/content/RemoteTabs.js"],
|
||||
|
|
|
@ -77,6 +77,7 @@ var BrowserUI = {
|
|||
get _back() { return document.getElementById("cmd_back"); },
|
||||
get _forward() { return document.getElementById("cmd_forward"); },
|
||||
|
||||
lastKnownGoodURL: "", //used when the user wants to escape unfinished url entry
|
||||
init: function() {
|
||||
// listen content messages
|
||||
messageManager.addMessageListener("DOMTitleChanged", this);
|
||||
|
@ -147,7 +148,7 @@ var BrowserUI = {
|
|||
FindHelperUI.init();
|
||||
PdfJs.init();
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
WeaveGlue.init();
|
||||
Sync.init();
|
||||
#endif
|
||||
} catch(ex) {
|
||||
Util.dumpLn("Exception in delay load module:", ex.message);
|
||||
|
@ -642,6 +643,7 @@ var BrowserUI = {
|
|||
|
||||
_setURI: function _setURI(aURL) {
|
||||
this._edit.value = aURL;
|
||||
this.lastKnownGoodURL = aURL;
|
||||
},
|
||||
|
||||
_urlbarClicked: function _urlbarClicked() {
|
||||
|
@ -727,6 +729,7 @@ var BrowserUI = {
|
|||
aEvent.preventDefault();
|
||||
|
||||
if (this._edit.popupOpen) {
|
||||
this._edit.value = this.lastKnownGoodURL;
|
||||
this._edit.closePopup();
|
||||
StartUI.hide();
|
||||
ContextUI.dismiss();
|
||||
|
@ -747,8 +750,9 @@ var BrowserUI = {
|
|||
}
|
||||
|
||||
// Check open modal elements
|
||||
if (DialogUI.modals.length > 0)
|
||||
if (DialogUI.modals.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check open panel
|
||||
if (PanelUI.isVisible) {
|
||||
|
@ -1041,7 +1045,7 @@ var BrowserUI = {
|
|||
break;
|
||||
case "cmd_remoteTabs":
|
||||
if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
|
||||
WeaveGlue.open();
|
||||
Sync.open();
|
||||
} else {
|
||||
PanelUI.show("remotetabs-container");
|
||||
}
|
||||
|
@ -1478,7 +1482,7 @@ var SyncPanelUI = {
|
|||
Elements.syncFlyout.addEventListener("PopupChanged", function onShow(aEvent) {
|
||||
if (aEvent.detail && aEvent.target === Elements.syncFlyout) {
|
||||
Elements.syncFlyout.removeEventListener("PopupChanged", onShow, false);
|
||||
WeaveGlue.init();
|
||||
Sync.init();
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@ flyoutpanel {
|
|||
-moz-binding: url('chrome://browser/content/bindings/flyoutpanel.xml#flyoutpanelBinding');
|
||||
}
|
||||
|
||||
cssthrobber {
|
||||
-moz-binding: url('chrome://browser/content/bindings/cssthrobber.xml#cssthrobberBinding');
|
||||
}
|
||||
|
||||
settings {
|
||||
-moz-binding: url("chrome://mozapps/content/extensions/setting.xml#settings");
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/forms.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/cssthrobber.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
|
||||
|
@ -284,7 +285,7 @@
|
|||
<scrollbox id="snapped-scrollbox" orient="vertical" flex="1">
|
||||
<vbox id="snapped-topsites">
|
||||
<label class="meta-section-title" value="&startTopSitesHeader.label;"/>
|
||||
<richgrid id="snapped-topsites-grid" rows="8" columns="1" flex="1"/>
|
||||
<richgrid id="snapped-topsites-grid" class="canSnapTiles" rows="8" columns="1" flex="1"/>
|
||||
</vbox>
|
||||
<label class="meta-section-title" value="&startBookmarksHeader.label;"
|
||||
onclick="PanelUI.show('bookmarks-container');"/>
|
||||
|
@ -401,19 +402,37 @@
|
|||
</flyoutpanel>
|
||||
|
||||
<flyoutpanel id="sync-flyoutpanel" headertext="&syncHeader.title;">
|
||||
<setting id="sync-connect" title="&sync.notconnected;" type="control">
|
||||
<button label="&sync.connect;" oncommand="WeaveGlue.tryConnect();" />
|
||||
<description>&sync.setup.description;</description>
|
||||
<description id="sync-accountinfo" collapsed="true"></description>
|
||||
<description id="sync-lastsync" collapsed="true"></description>
|
||||
<description id="sync-errordescription" collapsed="true"></description>
|
||||
<setting id="sync-connect" type="control" collapsed="true">
|
||||
<button label="&sync.setupbutton.label;" oncommand="Sync.tryConnect();" />
|
||||
</setting>
|
||||
<setting id="sync-connected" class="setting-group" title="&sync.connected;" type="control" collapsed="true">
|
||||
<setting id="sync-connected" class="setting-group" type="control" collapsed="true">
|
||||
<button id="sync-pairdevice" label="&sync.pair.button;" oncommand="SyncPairDevice.open();" />
|
||||
</setting>
|
||||
<setting id="sync-sync" class="setting-subgroup" type="control" collapsed="true">
|
||||
<button id="sync-syncButton" label="&sync.syncNow2;" oncommand="WeaveGlue.sync();"/>
|
||||
</setting>
|
||||
<setting id="sync-device" class="setting-subgroup" type="string" title="&sync.deviceName;" onchange="WeaveGlue.changeName(this);" collapsed="true"/>
|
||||
<setting id="sync-device" class="setting-subgroup" type="string" title="&sync.deviceName;" onchange="Sync.changeName(this);" collapsed="true"/>
|
||||
<setting id="sync-disconnect" class="setting-subgroup" type="control" collapsed="true">
|
||||
<button label="&sync.disconnect;" oncommand="WeaveGlue.disconnect();" />
|
||||
<button label="&sync.removebutton.label;" oncommand="Sync.onDisconnect();" />
|
||||
</setting>
|
||||
<vbox id="sync-disconnectwarnpanel" collapsed="true">
|
||||
<description id="sync-disconnectwarntitle"></description>
|
||||
<description id="sync-disconnectwarnmsg">&sync.removewarn.note;</description>
|
||||
<hbox>
|
||||
<spacer flex="1" />
|
||||
<button label="&sync.setup.cancel;" oncommand="Sync.onCancelDisconnect();" />
|
||||
<button label="&sync.setup.remove;" oncommand="Sync.disconnect();" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox id="sync-disconnectthrobber" collapsed="true">
|
||||
<hbox>
|
||||
<spacer flex="1" />
|
||||
<cssthrobber id="syncdisconnectthrobber" />
|
||||
<label>&sync.removethrobber.label;</label>
|
||||
<spacer flex="1" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
</flyoutpanel>
|
||||
|
||||
<flyoutpanel id="prefs-flyoutpanel" headertext="&optionsHeader.title;">
|
||||
|
@ -478,12 +497,12 @@
|
|||
<dialog id="syncsetup-dialog" class="content-dialog" flex="1">
|
||||
<vbox class="prompt-inner">
|
||||
<hbox class="prompt-title">
|
||||
<description>&sync.setup.title;</description>
|
||||
<description>&sync.setup2.title;</description>
|
||||
</hbox>
|
||||
<vbox id="syncsetup-simple" class="syncsetup-page" flex="1">
|
||||
<scrollbox id="sync-message" class="prompt-message" orient="vertical" flex="1">
|
||||
<description class="syncsetup-desc" flex="1">&sync.setup.pair2;</description>
|
||||
<description class="link" flex="1" onclick="WeaveGlue.openTutorial();">&sync.setup.tutorial;</description>
|
||||
<description class="link" flex="1" onclick="Sync.openTutorial();">&sync.setup.tutorial;</description>
|
||||
<separator/>
|
||||
<vbox flex="1" pack="center" align="start">
|
||||
<description id="syncsetup-code1" class="syncsetup-code">....</description>
|
||||
|
@ -491,11 +510,11 @@
|
|||
<description id="syncsetup-code3" class="syncsetup-code">....</description>
|
||||
</vbox>
|
||||
<separator/>
|
||||
<description class="link" flex="1" onclick="WeaveGlue.openManual();">&sync.fallback;</description>
|
||||
<description class="link" flex="1" onclick="Sync.openManual();">&sync.fallback;</description>
|
||||
<separator flex="1"/>
|
||||
</scrollbox>
|
||||
<hbox class="prompt-buttons">
|
||||
<button class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
|
||||
<button oncommand="Sync.close();">&sync.setup.cancel;</button>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox id="syncsetup-waiting" class="syncsetup-page" flex="1" hidden="true">
|
||||
|
@ -505,26 +524,26 @@
|
|||
<description id="syncsetup-waitingdownload-desc" class="syncsetup-desc" hidden="true" flex="1">&sync.setup.waitingdownload;</description>
|
||||
</vbox>
|
||||
<hbox class="prompt-buttons" pack="center" align="end">
|
||||
<button id="syncsetup-waiting-cancel" class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
|
||||
<button id="syncsetup-waiting-close" class="prompt-button" hidden="true" oncommand="WeaveGlue.close();">&sync.setup.close;</button>
|
||||
<button id="syncsetup-waiting-cancel" oncommand="Sync.close();">&sync.setup.cancel;</button>
|
||||
<button id="syncsetup-waiting-close" hidden="true" oncommand="Sync.close();">&sync.setup.close;</button>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox id="syncsetup-fallback" class="syncsetup-page" flex="1" hidden="true">
|
||||
<scrollbox class="prompt-message" orient="vertical" flex="1">
|
||||
<description class="syncsetup-desc" flex="1">&sync.setup.manual;</description>
|
||||
<separator/>
|
||||
<textbox id="syncsetup-account" class="prompt-edit" placeholder="&sync.account;" oninput="WeaveGlue.canConnect();"/>
|
||||
<textbox id="syncsetup-password" class="prompt-edit" placeholder="&sync.password;" type="password" oninput="WeaveGlue.canConnect();"/>
|
||||
<textbox id="syncsetup-synckey" class="prompt-edit" placeholder="&sync.recoveryKey;" oninput="WeaveGlue.canConnect();"/>
|
||||
<textbox id="syncsetup-account" class="prompt-edit" placeholder="&sync.account;" oninput="Sync.canConnect();"/>
|
||||
<textbox id="syncsetup-password" class="prompt-edit" placeholder="&sync.password;" type="password" oninput="Sync.canConnect();"/>
|
||||
<textbox id="syncsetup-synckey" class="prompt-edit" placeholder="&sync.recoveryKey;" oninput="Sync.canConnect();"/>
|
||||
<separator class="thin"/>
|
||||
<checkbox id="syncsetup-usecustomserver" label="&sync.customServer;" oncommand="WeaveGlue.toggleCustomServer();"/>
|
||||
<checkbox id="syncsetup-usecustomserver" label="&sync.customServer;" oncommand="Sync.toggleCustomServer();"/>
|
||||
<textbox id="syncsetup-customserver" class="prompt-edit" placeholder="&sync.serverURL;"/>
|
||||
<separator flex="1"/>
|
||||
</scrollbox>
|
||||
<hbox class="prompt-buttons">
|
||||
<button class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
|
||||
<button oncommand="Sync.close();">&sync.setup.cancel;</button>
|
||||
<separator/>
|
||||
<button id="syncsetup-button-connect" class="prompt-button" oncommand="WeaveGlue.close(); WeaveGlue.connect();">&sync.setup.connect;</button>
|
||||
<button id="syncsetup-button-connect" oncommand="Sync.close(); Sync.connect();">&sync.setup.connect2;</button>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
@ -540,7 +559,7 @@
|
|||
<vbox id="syncpair-simple" class="syncsetup-page" flex="1">
|
||||
<vbox id="sync-message" class="prompt-message" orient="vertical" flex="1">
|
||||
<description class="syncsetup-desc" flex="1">&sync.pair.description;</description>
|
||||
<description class="link" flex="1" onclick="SyncPairDevice.close(); WeaveGlue.openTutorial();">&sync.setup.tutorial;</description>
|
||||
<description class="link" flex="1" onclick="SyncPairDevice.close(); Sync.openTutorial();">&sync.setup.tutorial;</description>
|
||||
<separator/>
|
||||
<vbox align="center" flex="1">
|
||||
<textbox id="syncpair-code1" class="syncsetup-code" oninput="SyncPairDevice.onTextBoxInput(this);"/>
|
||||
|
@ -549,8 +568,8 @@
|
|||
</vbox>
|
||||
</vbox>
|
||||
<hbox class="prompt-buttons" pack="center">
|
||||
<button class="prompt-button" oncommand="SyncPairDevice.close();">&sync.setup.cancel;</button>
|
||||
<button id="syncpair-connectbutton" class="prompt-button" disabled="true" oncommand="SyncPairDevice.connect();">&sync.setup.connect;</button>
|
||||
<button oncommand="SyncPairDevice.close();">&sync.setup.cancel;</button>
|
||||
<button id="syncpair-connectbutton" disabled="true" oncommand="SyncPairDevice.connect();">&sync.setup.connect2;</button>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
|
|
@ -194,7 +194,6 @@ HistoryView.prototype = {
|
|||
this._set.dispatchEvent(event);
|
||||
|
||||
this._toRemove = null;
|
||||
this._set.clearSelection();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<a name="webservices"/>
|
||||
<h3>&rights2.webservices-header;</h3>
|
||||
|
||||
<p>&rights2.webservices-a;<a href="about:rights#disabling-webservices" onclick="showDisablingServices();">&rights2.webservices-b;</a>&rights2.webservices-c;</p>
|
||||
<p>&rights2.webservices-a;<a href="about:rights#disabling-webservices" onclick="showDisablingServices();">&rights2.webservices-b;</a>&rights3.webservices-c;</p>
|
||||
|
||||
<div id="disabling-webservices-container" style="margin-left:40px;">
|
||||
<a name="disabling-webservices"/>
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
</vbox>
|
||||
|
||||
<hbox id="prompt-confirm-buttons-box" class="prompt-buttons">
|
||||
<button class="prompt-button button-default" label="&ok.label;" command="cmd_ok"/>
|
||||
<button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
|
||||
<button class="button-default" label="&ok.label;" command="cmd_ok"/>
|
||||
<button label="&cancel.label;" command="cmd_cancel"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</dialog>
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
</vbox>
|
||||
|
||||
<hbox class="prompt-buttons">
|
||||
<button class="prompt-button" label="&ok.label;" command="cmd_ok"/>
|
||||
<button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
|
||||
<button label="&ok.label;" command="cmd_ok"/>
|
||||
<button label="&cancel.label;" command="cmd_cancel"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</dialog>
|
||||
|
|
|
@ -56,8 +56,8 @@
|
|||
</vbox>
|
||||
|
||||
<hbox class="prompt-buttons">
|
||||
<button class="prompt-button button-default" label="&ok.label;" command="cmd_ok"/>
|
||||
<button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
|
||||
<button class="button-default" label="&ok.label;" command="cmd_ok"/>
|
||||
<button label="&cancel.label;" command="cmd_cancel"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</dialog>
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
</vbox>
|
||||
|
||||
<hbox class="prompt-buttons">
|
||||
<button class="prompt-button button-default" label="&ok.label;" command="cmd_ok"/>
|
||||
<button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
|
||||
<button class="button-default" label="&ok.label;" command="cmd_ok"/>
|
||||
<button label="&cancel.label;" command="cmd_cancel"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</dialog>
|
||||
|
|
|
@ -66,7 +66,7 @@ Sanitizer.prototype = {
|
|||
syncAccount: {
|
||||
clear: function ()
|
||||
{
|
||||
WeaveGlue.disconnect();
|
||||
Sync.disconnect();
|
||||
},
|
||||
|
||||
get canClear()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
let WeaveGlue = {
|
||||
let Sync = {
|
||||
setupData: null,
|
||||
_boundOnEngineSync: null, // Needed to unhook the observers in close().
|
||||
_boundOnServiceSync: null,
|
||||
|
@ -12,6 +12,21 @@ let WeaveGlue = {
|
|||
_progressBar: null,
|
||||
_progressValue: 0,
|
||||
_progressMax: null,
|
||||
_disconnecting: false,
|
||||
|
||||
get _isSetup() {
|
||||
if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
|
||||
return false;
|
||||
}
|
||||
// check for issues related to failed logins that do not have anything to
|
||||
// do with network, server, and other non-client issues. See the login
|
||||
// failure status codes in sync service.
|
||||
return (Weave.Status.login != Weave.LOGIN_FAILED_NO_USERNAME &&
|
||||
Weave.Status.login != Weave.LOGIN_FAILED_NO_PASSWORD &&
|
||||
Weave.Status.login != Weave.LOGIN_FAILED_NO_PASSPHRASE &&
|
||||
Weave.Status.login != Weave.LOGIN_FAILED_INVALID_PASSPHRASE &&
|
||||
Weave.Status.login != Weave.LOGIN_FAILED_LOGIN_REJECTED);
|
||||
},
|
||||
|
||||
init: function init() {
|
||||
if (this._bundle) {
|
||||
|
@ -24,6 +39,7 @@ let WeaveGlue = {
|
|||
|
||||
if (service.ready) {
|
||||
this._init();
|
||||
Weave.Service.scheduler.scheduleNextSync(10*1000); // ten seconds after we startup
|
||||
} else {
|
||||
Services.obs.addObserver(this, "weave:service:ready", false);
|
||||
service.ensureLoaded();
|
||||
|
@ -65,24 +81,18 @@ let WeaveGlue = {
|
|||
|
||||
_init: function () {
|
||||
this._bundle = Services.strings.createBundle("chrome://browser/locale/sync.properties");
|
||||
this._msg = document.getElementById("prefs-messages");
|
||||
|
||||
this._addListeners();
|
||||
|
||||
this.setupData = { account: "", password: "" , synckey: "", serverURL: "" };
|
||||
|
||||
if (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED) {
|
||||
// Put the settings UI into a state of "connecting..." if we are going to auto-connect
|
||||
this._elements.connect.firstChild.disabled = true;
|
||||
this._elements.connect.setAttribute("title", this._bundle.GetStringFromName("connecting.label"));
|
||||
|
||||
try {
|
||||
this._elements.device.value = Services.prefs.getCharPref("services.sync.client.name");
|
||||
} catch(e) {}
|
||||
} else if (Weave.Status.login != Weave.LOGIN_FAILED_NO_USERNAME) {
|
||||
if (this._isSetup) {
|
||||
this.loadSetupData();
|
||||
}
|
||||
|
||||
// Update the state of the ui
|
||||
this._updateUI();
|
||||
|
||||
this._boundOnEngineSync = this.onEngineSync.bind(this);
|
||||
this._boundOnServiceSync = this.onServiceSync.bind(this);
|
||||
this._progressBar = document.getElementById("syncsetup-progressbar");
|
||||
|
@ -370,40 +380,39 @@ let WeaveGlue = {
|
|||
Weave.Service.identity.syncKey = this.setupData.synckey;
|
||||
Weave.Service.persistLogin();
|
||||
Weave.Svc.Obs.notify("weave:service:setup-complete");
|
||||
setTimeout(function () { Weave.Service.sync(); }, 0);
|
||||
this.sync();
|
||||
},
|
||||
|
||||
disconnect: function disconnect() {
|
||||
// Save credentials for undo
|
||||
let undoData = this.setupData;
|
||||
|
||||
// Remove all credentials
|
||||
this.setupData = null;
|
||||
Weave.Service.startOver();
|
||||
|
||||
let message = this._bundle.GetStringFromName("notificationDisconnect.label");
|
||||
let button = this._bundle.GetStringFromName("notificationDisconnect.button");
|
||||
let buttons = [ {
|
||||
label: button,
|
||||
accessKey: "",
|
||||
callback: function() { WeaveGlue.connect(undoData); }
|
||||
} ];
|
||||
this.showMessage(message, "undo-disconnect", buttons);
|
||||
|
||||
// Hide the notification when the panel is changed or closed.
|
||||
let panel = document.getElementById("prefs-container");
|
||||
panel.addEventListener("ToolPanelHidden", function onHide(aEvent) {
|
||||
panel.removeEventListener(aEvent.type, onHide, false);
|
||||
let notification = WeaveGlue._msg.getNotificationWithValue("undo-disconnect");
|
||||
if (notification)
|
||||
notification.close();
|
||||
}, false);
|
||||
|
||||
// called when the user taps the disconnect button
|
||||
onDisconnect: function onDisconnect() {
|
||||
Weave.Service.logout();
|
||||
let bundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
||||
let brandName = bundle.GetStringFromName("brandShortName");
|
||||
let warnStr = this._bundle.formatStringFromName("sync.disconnectPrompt", [brandName], 1);
|
||||
this._elements.disconnectwarntitle.textContent = warnStr;
|
||||
this._elements.disconnectwarnpanel.collapsed = false;
|
||||
},
|
||||
|
||||
// called when the user taps the cancel button on
|
||||
// the disconnect warning panel.
|
||||
onCancelDisconnect: function onCancelDisconnect() {
|
||||
this._elements.disconnectwarnpanel.collapsed = true;
|
||||
this._updateUI();
|
||||
Weave.Service.login();
|
||||
},
|
||||
|
||||
// called when the user taps the remove button on
|
||||
// the disconnect warning panel.
|
||||
disconnect: function disconnect() {
|
||||
this._elements.disconnectwarnpanel.collapsed = true;
|
||||
this.setupData = null;
|
||||
this._disconnecting = true;
|
||||
this._updateUI();
|
||||
Weave.Service.startOver();
|
||||
},
|
||||
|
||||
sync: function sync() {
|
||||
Weave.Service.sync();
|
||||
Weave.Service.scheduler.scheduleNextSync(0);
|
||||
},
|
||||
|
||||
_addListeners: function _addListeners() {
|
||||
|
@ -412,27 +421,23 @@ let WeaveGlue = {
|
|||
"weave:service:sync:error", "weave:service:login:start",
|
||||
"weave:service:login:finish", "weave:service:login:error",
|
||||
"weave:ui:login:error",
|
||||
"weave:service:start-over", "weave:service:start-over:finish",
|
||||
"weave:service:logout:finish"];
|
||||
|
||||
// For each topic, add WeaveGlue the observer
|
||||
// For each topic, add Sync the observer
|
||||
topics.forEach(function(topic) {
|
||||
Services.obs.addObserver(WeaveGlue, topic, false);
|
||||
Services.obs.addObserver(Sync, topic, false);
|
||||
});
|
||||
|
||||
// Remove them on unload
|
||||
addEventListener("unload", function() {
|
||||
topics.forEach(function(topic) {
|
||||
Services.obs.removeObserver(WeaveGlue, topic);
|
||||
Services.obs.removeObserver(Sync, topic);
|
||||
});
|
||||
}, false);
|
||||
},
|
||||
|
||||
get _elements() {
|
||||
// Do a quick test to see if the options exist yet
|
||||
let syncButton = document.getElementById("sync-syncButton");
|
||||
if (syncButton == null)
|
||||
return null;
|
||||
|
||||
// Get all the setting nodes from the add-ons display
|
||||
let elements = {};
|
||||
let setupids = ["account", "password", "synckey", "usecustomserver", "customserver"];
|
||||
|
@ -440,7 +445,9 @@ let WeaveGlue = {
|
|||
elements[id] = document.getElementById("syncsetup-" + id);
|
||||
});
|
||||
|
||||
let settingids = ["device", "connect", "connected", "disconnect", "sync", "pairdevice"];
|
||||
let settingids = ["device", "connect", "connected", "disconnect", "lastsync", "pairdevice",
|
||||
"errordescription", "accountinfo", "disconnectwarnpanel", "disconnectthrobber",
|
||||
"disconnectwarntitle"];
|
||||
settingids.forEach(function(id) {
|
||||
elements[id] = document.getElementById("sync-" + id);
|
||||
});
|
||||
|
@ -450,6 +457,87 @@ let WeaveGlue = {
|
|||
return this._elements = elements;
|
||||
},
|
||||
|
||||
_updateUI: function _updateUI() {
|
||||
if (this._elements == null)
|
||||
return;
|
||||
|
||||
let connect = this._elements.connect;
|
||||
let connected = this._elements.connected;
|
||||
let device = this._elements.device;
|
||||
let disconnect = this._elements.disconnect;
|
||||
let lastsync = this._elements.lastsync;
|
||||
let pairdevice = this._elements.pairdevice;
|
||||
let accountinfo = this._elements.accountinfo;
|
||||
let disconnectthrobber = this._elements.disconnectthrobber;
|
||||
|
||||
// This gets updated when an error occurs
|
||||
this._elements.errordescription.collapsed = true;
|
||||
|
||||
let isConfigured = (!this._loginError && this._isSetup);
|
||||
|
||||
// If we're in the process of disconnecting we are no longer configured.
|
||||
if (this._disconnecting) {
|
||||
isConfigured = false;
|
||||
// display the throbber with the appropriate message
|
||||
disconnectthrobber.collapsed = false;
|
||||
} else {
|
||||
disconnectthrobber.collapsed = true;
|
||||
}
|
||||
|
||||
connect.collapsed = isConfigured;
|
||||
connected.collapsed = !isConfigured;
|
||||
lastsync.collapsed = !isConfigured;
|
||||
device.collapsed = !isConfigured;
|
||||
disconnect.collapsed = !isConfigured;
|
||||
|
||||
if (this._disconnecting) {
|
||||
connect.collapsed = true;
|
||||
}
|
||||
|
||||
// Set the device name text edit to configured name or the auto generated
|
||||
// name if we aren't set up.
|
||||
try {
|
||||
device.value = Services.prefs.getCharPref("services.sync.client.name");
|
||||
} catch(ex) {
|
||||
device.value = Weave.Service.clientsEngine.localName || "";
|
||||
}
|
||||
|
||||
// Account information header
|
||||
accountinfo.collapsed = true;
|
||||
try {
|
||||
let account = Weave.Service.identity.account;
|
||||
if (account != null && isConfigured) {
|
||||
let accountStr = this._bundle.formatStringFromName("account.label", [account], 1);
|
||||
accountinfo.textContent = accountStr;
|
||||
accountinfo.collapsed = false;
|
||||
}
|
||||
} catch (ex) {}
|
||||
|
||||
// If we're already locked, a sync is in progress..
|
||||
if (Weave.Service.locked && isConfigured) {
|
||||
connect.firstChild.disabled = true;
|
||||
}
|
||||
|
||||
// Show the day-of-week and time (HH:MM) of last sync
|
||||
let lastSync = Weave.Svc.Prefs.get("lastSync");
|
||||
lastsync.textContent = "";
|
||||
if (lastSync != null) {
|
||||
let syncDate = new Date(lastSync).toLocaleFormat("%A %I:%M %p");
|
||||
let dateStr = this._bundle.formatStringFromName("lastSync2.label", [syncDate], 1);
|
||||
lastsync.textContent = dateStr;
|
||||
}
|
||||
|
||||
// Check the lock again on a timeout since it's set after observers notify
|
||||
setTimeout(function(self) {
|
||||
// Prevent certain actions when the service is locked
|
||||
if (Weave.Service.locked) {
|
||||
connect.firstChild.disabled = true;
|
||||
} else {
|
||||
connect.firstChild.disabled = false;
|
||||
}
|
||||
}, 100, this);
|
||||
},
|
||||
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
if (aTopic == "weave:service:ready") {
|
||||
Services.obs.removeObserver(this, aTopic);
|
||||
|
@ -460,24 +548,27 @@ let WeaveGlue = {
|
|||
// Make sure we're online when connecting/syncing
|
||||
Util.forceOnline();
|
||||
|
||||
if (aTopic == "weave:service:start-over") {
|
||||
this._disconnecting = true;
|
||||
} else if (aTopic == "weave:service:start-over:finish") {
|
||||
this._disconnecting = false;
|
||||
}
|
||||
|
||||
// Can't do anything before settings are loaded
|
||||
if (this._elements == null)
|
||||
return;
|
||||
|
||||
// Make some aliases
|
||||
let connect = this._elements.connect;
|
||||
let connected = this._elements.connected;
|
||||
let device = this._elements.device;
|
||||
let disconnect = this._elements.disconnect;
|
||||
let sync = this._elements.sync;
|
||||
let pairdevice = this._elements.pairdevice;
|
||||
// Update the state of the ui
|
||||
this._updateUI();
|
||||
|
||||
let errormsg = this._elements.errordescription;
|
||||
let accountinfo = this._elements.accountinfo;
|
||||
|
||||
// Show what went wrong with login if necessary
|
||||
if (aTopic == "weave:ui:login:error") {
|
||||
this._loginError = true;
|
||||
connect.setAttribute("desc", Weave.Utils.getErrorString(Weave.Status.login));
|
||||
} else {
|
||||
connect.removeAttribute("desc");
|
||||
errormsg.textContent = Weave.Utils.getErrorString(Weave.Status.login);
|
||||
errormsg.collapsed = false;
|
||||
}
|
||||
|
||||
if (aTopic == "weave:service:login:finish") {
|
||||
|
@ -487,52 +578,11 @@ let WeaveGlue = {
|
|||
this.loadSetupData();
|
||||
}
|
||||
|
||||
let isConfigured = (!this._loginError && Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED);
|
||||
|
||||
connect.collapsed = isConfigured;
|
||||
connected.collapsed = !isConfigured;
|
||||
|
||||
if (!isConfigured) {
|
||||
connect.setAttribute("title", this._bundle.GetStringFromName("notconnected.label"));
|
||||
connect.firstChild.disabled = false;
|
||||
}
|
||||
|
||||
sync.collapsed = !isConfigured;
|
||||
device.collapsed = !isConfigured;
|
||||
disconnect.collapsed = !isConfigured;
|
||||
|
||||
// Check the lock on a timeout because it's set just after notifying
|
||||
setTimeout(function(self) {
|
||||
// Prevent certain actions when the service is locked
|
||||
if (Weave.Service.locked) {
|
||||
connect.firstChild.disabled = true;
|
||||
sync.firstChild.disabled = true;
|
||||
|
||||
if (aTopic == "weave:service:login:start")
|
||||
connect.setAttribute("title", self._bundle.GetStringFromName("connecting.label"));
|
||||
|
||||
if (aTopic == "weave:service:sync:start")
|
||||
sync.setAttribute("title", self._bundle.GetStringFromName("lastSyncInProgress2.label"));
|
||||
} else {
|
||||
connect.firstChild.disabled = false;
|
||||
sync.firstChild.disabled = false;
|
||||
}
|
||||
}, 0, this);
|
||||
|
||||
// Dynamically generate some strings
|
||||
let accountStr = this._bundle.formatStringFromName("account.label", [Weave.Service.identity.account], 1);
|
||||
disconnect.setAttribute("title", accountStr);
|
||||
|
||||
// Show the day-of-week and time (HH:MM) of last sync
|
||||
let lastSync = Weave.Svc.Prefs.get("lastSync");
|
||||
if (lastSync != null) {
|
||||
let syncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
|
||||
let dateStr = this._bundle.formatStringFromName("lastSync2.label", [syncDate], 1);
|
||||
sync.setAttribute("title", dateStr);
|
||||
}
|
||||
|
||||
// Check for a storage format update, update the user and load the Sync update page
|
||||
if (aTopic =="weave:service:sync:error") {
|
||||
errormsg.textContent = Weave.Utils.getErrorString(Weave.Status.sync);
|
||||
errormsg.collapsed = false;
|
||||
|
||||
let clientOutdated = false, remoteOutdated = false;
|
||||
if (Weave.Status.sync == Weave.VERSION_OUT_OF_DATE) {
|
||||
clientOutdated = true;
|
||||
|
@ -565,8 +615,6 @@ let WeaveGlue = {
|
|||
Browser.addTab("https://services.mozilla.com/update/", true, Browser.selectedTab);
|
||||
}
|
||||
}
|
||||
|
||||
device.value = Weave.Service.clientsEngine.localName || "";
|
||||
},
|
||||
|
||||
changeName: function changeName(aInput) {
|
||||
|
@ -575,14 +623,6 @@ let WeaveGlue = {
|
|||
aInput.value = Weave.Service.clientsEngine.localName;
|
||||
},
|
||||
|
||||
showMessage: function showMessage(aMsg, aValue, aButtons) {
|
||||
let notification = this._msg.getNotificationWithValue(aValue);
|
||||
if (notification)
|
||||
return;
|
||||
|
||||
this._msg.appendNotification(aMsg, aValue, "", this._msg.PRIORITY_WARNING_LOW, aButtons);
|
||||
},
|
||||
|
||||
_validateServer: function _validateServer(aURL) {
|
||||
let uri = Weave.Utils.makeURI(aURL);
|
||||
|
||||
|
@ -595,7 +635,7 @@ let WeaveGlue = {
|
|||
},
|
||||
|
||||
openTutorial: function _openTutorial() {
|
||||
WeaveGlue.close();
|
||||
Sync.close();
|
||||
|
||||
let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
|
||||
let url = formatter.formatURLPref("app.sync.tutorialURL");
|
||||
|
|
|
@ -26,6 +26,7 @@ chrome.jar:
|
|||
content/bindings/appbar.xml (content/bindings/appbar.xml)
|
||||
content/bindings/flyoutpanel.xml (content/bindings/flyoutpanel.xml)
|
||||
content/bindings/selectionoverlay.xml (content/bindings/selectionoverlay.xml)
|
||||
content/bindings/cssthrobber.xml (content/bindings/cssthrobber.xml)
|
||||
|
||||
content/prompt/alert.xul (content/prompt/alert.xul)
|
||||
content/prompt/confirm.xul (content/prompt/confirm.xul)
|
||||
|
|
|
@ -1,47 +1,48 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Globals
|
||||
|
||||
Components.utils.import("resource://services-sync/main.js");
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test(s)
|
||||
|
||||
function test() {
|
||||
is(Weave.Status.checkSetup(), Weave.CLIENT_NOT_CONFIGURED, "Sync should be disabled on start");
|
||||
// check start page is hidden
|
||||
|
||||
let vbox = document.getElementById("start-remotetabs");
|
||||
ok(vbox.hidden, "remote tabs in the start page should be hidden when sync is not enabled");
|
||||
// check container link is hidden
|
||||
let menulink = document.getElementById("menuitem-remotetabs");
|
||||
ok(menulink.hidden, "link to container should be hidden when sync is not enabled");
|
||||
|
||||
// hacky-fake sync setup and enabled. Note the Sync Tracker will spit
|
||||
// a number of warnings about undefined ids
|
||||
Weave.Status._authManager.username = "jane doe"; // must set username before key
|
||||
Weave.Status._authManager.basicPassword = "goatcheesesalad";
|
||||
Weave.Status._authManager.syncKey = "a-bcdef-abcde-acbde-acbde-acbde";
|
||||
// check that it worked
|
||||
isnot(Weave.Status.checkSetup(), Weave.CLIENT_NOT_CONFIGURED, "Sync is enabled");
|
||||
Weave.Svc.Obs.notify("weave:service:setup-complete");
|
||||
|
||||
// start page grid should be visible
|
||||
ok(vbox, "remote tabs grid is present on start page");
|
||||
//PanelUI.show("remotetabs-container");
|
||||
is(vbox.hidden, false, "remote tabs should be visible in start page when sync is enabled");
|
||||
// container link should be visible
|
||||
is(menulink.hidden, false, "link to container should be visible when sync is enabled");
|
||||
|
||||
// hacky-fake sync disable
|
||||
Weave.Status._authManager.deleteSyncCredentials();
|
||||
Weave.Svc.Obs.notify("weave:service:start-over");
|
||||
is(Weave.Status.checkSetup(), Weave.CLIENT_NOT_CONFIGURED, "Sync has been disabled");
|
||||
ok(vbox.hidden, "remote tabs in the start page should be hidden when sync is not enabled");
|
||||
ok(menulink.hidden, "link to container should be hidden when sync is not enabled");
|
||||
|
||||
}
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Globals
|
||||
|
||||
Components.utils.import("resource://services-sync/main.js");
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test(s)
|
||||
|
||||
function test() {
|
||||
runTests();
|
||||
}
|
||||
|
||||
gTests.push({
|
||||
desc: "Test sync tabs from other devices UI",
|
||||
run: function run() {
|
||||
if (StartUI.isStartPageVisible)
|
||||
return;
|
||||
|
||||
yield addTab("about:start");
|
||||
yield waitForCondition(() => StartUI.isStartPageVisible);
|
||||
yield hideContextUI();
|
||||
|
||||
is(Weave.Status.checkSetup(), Weave.CLIENT_NOT_CONFIGURED, "Sync should be disabled on start");
|
||||
|
||||
let vbox = document.getElementById("start-remotetabs");
|
||||
ok(vbox.hidden, "remote tabs in the start page should be hidden when sync is not enabled");
|
||||
|
||||
// check container link is hidden
|
||||
let menulink = document.getElementById("menuitem-remotetabs");
|
||||
ok(menulink.hidden, "link to container should be hidden when sync is not enabled");
|
||||
|
||||
RemoteTabsStartView._view.setUIAccessVisible(true);
|
||||
|
||||
// start page grid should be visible
|
||||
ok(vbox, "remote tabs grid is present on start page");
|
||||
is(vbox.hidden, false, "remote tabs should be visible in start page when sync is enabled");
|
||||
|
||||
RemoteTabsStartView._view.setUIAccessVisible(false);
|
||||
|
||||
ok(vbox.hidden, "remote tabs in the start page should be hidden when sync is not enabled");
|
||||
ok(menulink.hidden, "link to container should be hidden when sync is not enabled");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/* -*- Mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
||||
/* 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/. */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function CapturePicker() {
|
||||
this.messageManager = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
|
||||
}
|
||||
|
||||
CapturePicker.prototype = {
|
||||
_file: null,
|
||||
_mode: -1,
|
||||
_result: -1,
|
||||
_shown: false,
|
||||
_title: "",
|
||||
_type: "",
|
||||
_window: null,
|
||||
|
||||
//
|
||||
// nsICapturePicker
|
||||
//
|
||||
init: function(aWindow, aTitle, aMode) {
|
||||
this._window = aWindow;
|
||||
this._title = aTitle;
|
||||
this._mode = aMode;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if (this._shown)
|
||||
throw Cr.NS_ERROR_UNEXPECTED;
|
||||
|
||||
this._shown = true;
|
||||
|
||||
let res = this.messageManager.sendSyncMessage("CapturePicker:Show", { title: this._title, mode: this._mode, type: this._type })[0];
|
||||
if (res.value)
|
||||
this._file = res.path;
|
||||
|
||||
return (res.value ? Ci.nsICapturePicker.RETURN_OK : Ci.nsICapturePicker.RETURN_CANCEL);
|
||||
},
|
||||
|
||||
modeMayBeAvailable: function(aMode) {
|
||||
if (aMode != Ci.nsICapturePicker.MODE_STILL)
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
|
||||
get file() {
|
||||
if (this._file) {
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(this._file);
|
||||
let utils = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
return utils.wrapDOMFile(file);
|
||||
} else {
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
}
|
||||
},
|
||||
|
||||
get type() {
|
||||
return this._type;
|
||||
},
|
||||
|
||||
set type(aNewType) {
|
||||
if (this._shown)
|
||||
throw Cr.NS_ERROR_UNEXPECTED;
|
||||
else
|
||||
this._type = aNewType;
|
||||
},
|
||||
|
||||
// QI
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICapturePicker]),
|
||||
|
||||
// XPCOMUtils factory
|
||||
classID: Components.ID("{cb5a47f0-b58c-4fc3-b61a-358ee95f8238}"),
|
||||
};
|
||||
|
||||
var components = [ CapturePicker ];
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
|
|
@ -30,7 +30,6 @@ EXTRA_COMPONENTS = \
|
|||
ContentDispatchChooser.js \
|
||||
FormAutoComplete.js \
|
||||
LoginManagerPrompter.js \
|
||||
CapturePicker.js \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_SAFE_BROWSING
|
||||
|
|
|
@ -419,7 +419,6 @@ Prompt.prototype = {
|
|||
|
||||
if (bTitle) {
|
||||
let button = doc.createElement("button");
|
||||
button.className = "prompt-button";
|
||||
this.setLabelForNode(button, bTitle);
|
||||
if (i == defaultButton) {
|
||||
button.setAttribute("command", "cmd_ok");
|
||||
|
|
|
@ -3,25 +3,32 @@
|
|||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
|
||||
<!-- flyout header -->
|
||||
<!ENTITY syncHeader.title "Sync">
|
||||
<!ENTITY sync.notconnected "Not connected">
|
||||
<!ENTITY sync.connect "Connect">
|
||||
<!ENTITY sync.connected "Connected">
|
||||
<!ENTITY sync.deviceName "This device">
|
||||
<!ENTITY sync.disconnect "Disconnect">
|
||||
<!-- not connected yet -->
|
||||
<!ENTITY sync.setup.description "Access your bookmarks, passwords, and open tabs across your devices">
|
||||
<!ENTITY sync.setupbutton.label "Set up Sync">
|
||||
<!-- sync now button -->
|
||||
<!ENTITY sync.syncNow2 "Sync now">
|
||||
<!-- device name text edit -->
|
||||
<!ENTITY sync.deviceName "This device">
|
||||
<!-- remove this device button -->
|
||||
<!ENTITY sync.removebutton.label "Remove this device">
|
||||
<!ENTITY sync.removewarn.note "Your browser data on this device will remain intact, but you will no longer be able to sync with this account.">
|
||||
<!ENTITY sync.removethrobber.label "Removing device">
|
||||
|
||||
<!ENTITY sync.setup.title "Connect to Sync">
|
||||
<!ENTITY sync.setup2.title "Set up Sync">
|
||||
<!ENTITY sync.setup.pair2 "To activate, select "Pair a device" on your other device.">
|
||||
<!ENTITY sync.fallback "I'm not near my computer…">
|
||||
<!ENTITY sync.fallback "Enter or edit account information…">
|
||||
<!ENTITY sync.setup.manual "Enter your Sync account information">
|
||||
<!ENTITY sync.account "Account Name">
|
||||
<!ENTITY sync.password "Password">
|
||||
<!ENTITY sync.recoveryKey "Recovery Key">
|
||||
<!ENTITY sync.customServer "Use custom server">
|
||||
<!ENTITY sync.serverURL "Server URL">
|
||||
<!ENTITY sync.setup.connect "Connect">
|
||||
<!ENTITY sync.setup.connect2 "Add device">
|
||||
<!ENTITY sync.setup.cancel "Cancel">
|
||||
<!ENTITY sync.setup.remove "Remove">
|
||||
<!ENTITY sync.setup.tutorial "Show me how">
|
||||
<!ENTITY sync.setup.waiting2 "Waiting for other device…">
|
||||
|
||||
|
|
|
@ -2,15 +2,18 @@
|
|||
# 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/.
|
||||
|
||||
# Mobile Sync
|
||||
# LOCALIZATION NOTE: Used in the default os description when a new account
|
||||
# is being set up. Should be unique to Metro, so that it does not conflict
|
||||
# with Desktop. See /services/sync/modules/engines/clients.js locaName.
|
||||
sync.defaultAccountApplication=Metro %S
|
||||
|
||||
sync.disconnectPrompt=Remove Windows 8 style %S from your Sync Account?
|
||||
|
||||
# %S is the date and time at which the last sync successfully completed
|
||||
lastSync2.label=Last sync: %S
|
||||
lastSyncInProgress2.label=Last sync: in progress…
|
||||
|
||||
# %S is the username logged in
|
||||
account.label=Account: %S
|
||||
notconnected.label=Not connected
|
||||
connecting.label=Connecting…
|
||||
|
||||
notificationDisconnect.label=Your Firefox Sync account has been removed
|
||||
|
|
|
@ -416,7 +416,6 @@ pref("editor.singleLine.pasteNewlines", 2);
|
|||
#ifdef MOZ_SERVICES_SYNC
|
||||
// sync service
|
||||
pref("services.sync.registerEngines", "Tab,Bookmarks,Form,History,Password,Prefs");
|
||||
pref("services.sync.autoconnectDelay", 5);
|
||||
|
||||
// prefs to sync by default
|
||||
pref("services.sync.prefs.sync.browser.startup.sessionRestore", true);
|
||||
|
|
|
@ -720,6 +720,31 @@ flyoutpanel > settings:first-child {
|
|||
width: 400px;
|
||||
}
|
||||
|
||||
#sync-disconnectwarntitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#sync-disconnectthrobber {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
#disconnectthrobber {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
#syncdisconnectthrobber .progressContainer {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#syncdisconnectthrobber .progressBall {
|
||||
margin: 2px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* About flyout pane */
|
||||
|
||||
#about-flyoutpanel {
|
||||
|
@ -871,6 +896,10 @@ setting[type="radio"] > vbox {
|
|||
-moz-box-orient: horizontal;
|
||||
}
|
||||
|
||||
[viewstate="snapped"] .canSnapTiles .richgrid-item-desc {
|
||||
-moz-margin-start: 8px;
|
||||
}
|
||||
|
||||
/* if snapped, hide the fullscreen awesome screen, if viewstate is anything
|
||||
* other than snapped, hide the snapped awesome screen */
|
||||
#start[viewstate="snapped"],
|
||||
|
@ -1170,17 +1199,3 @@ setting[type="radio"] > vbox {
|
|||
margin-left: -18px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Capture picker ------------------------------------------------------------- */
|
||||
|
||||
#capturepicker-video {
|
||||
border: @border_width_tiny@ solid white;
|
||||
}
|
||||
|
||||
#capturepicker-container {
|
||||
margin: @margin_normal@;
|
||||
}
|
||||
|
||||
#capturepicker-container.vertical {
|
||||
height: 330px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/* 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/. */
|
||||
|
||||
%filter substitution
|
||||
%include defines.inc
|
||||
|
||||
.progressContainer {
|
||||
}
|
||||
|
||||
.progressBall {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
transform: rotate(225deg);
|
||||
animation: orbit 7.15s infinite;
|
||||
}
|
||||
|
||||
.progressBall:nth-child(1) {
|
||||
animation-delay: 1.56s;
|
||||
}
|
||||
|
||||
.progressBall:nth-child(2) {
|
||||
animation-delay: 0.31s;
|
||||
}
|
||||
|
||||
.progressBall:nth-child(3) {
|
||||
animation-delay: 0.62s;
|
||||
}
|
||||
|
||||
.progressBall:nth-child(4) {
|
||||
animation-delay: 0.94s;
|
||||
}
|
||||
|
||||
.progressBall:nth-child(5) {
|
||||
animation-delay: 1.25s;
|
||||
}
|
||||
|
||||
.progressBall:nth-child(1)::after,
|
||||
.progressBall:nth-child(2)::after,
|
||||
.progressBall:nth-child(3)::after,
|
||||
.progressBall:nth-child(4)::after,
|
||||
.progressBall:nth-child(5)::after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
background: #0095dd;
|
||||
left:0px;
|
||||
top:0px;
|
||||
}
|
||||
|
||||
|
||||
@keyframes orbit {
|
||||
0% {
|
||||
opacity: 1;
|
||||
z-index:99;
|
||||
transform: rotate(180deg);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
7% {
|
||||
opacity: 1;
|
||||
transform: rotate(300deg);
|
||||
animation-timing-function: linear;
|
||||
origin:0%;
|
||||
}
|
||||
|
||||
30% {
|
||||
opacity: 1;
|
||||
transform:rotate(410deg);
|
||||
animation-timing-function: ease-in-out;
|
||||
origin:7%;
|
||||
}
|
||||
|
||||
39% {
|
||||
opacity: 1;
|
||||
transform: rotate(645deg);
|
||||
animation-timing-function: linear;
|
||||
origin:30%;
|
||||
}
|
||||
|
||||
70% {
|
||||
opacity: 1;
|
||||
transform: rotate(770deg);
|
||||
animation-timing-function: ease-out;
|
||||
origin:39%;
|
||||
}
|
||||
|
||||
75% {
|
||||
opacity: 1;
|
||||
transform: rotate(900deg);
|
||||
animation-timing-function: ease-out;
|
||||
origin:70%;
|
||||
}
|
||||
|
||||
76%, 100% {
|
||||
opacity: 0;
|
||||
transform:rotate(900deg);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ chrome.jar:
|
|||
skin/aboutPage.css (aboutPage.css)
|
||||
skin/about.css (about.css)
|
||||
* skin/flyoutpanel.css (flyoutpanel.css)
|
||||
* skin/cssthrobber.css (cssthrobber.css)
|
||||
* skin/browser.css (browser.css)
|
||||
* skin/content.css (content.css)
|
||||
skin/config.css (config.css)
|
||||
|
|
|
@ -572,7 +572,7 @@ richgriditem[customColor] .richgrid-icon-box {
|
|||
.richgrid-item-desc {
|
||||
width: @tile_width@;
|
||||
font-size: @metro_font_normal@;
|
||||
margin-left: 0px !important;
|
||||
margin-left: 0px;
|
||||
padding-left: 0px !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["Social"];
|
||||
this.EXPORTED_SYMBOLS = ["Social", "OpenGraphBuilder"];
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
|
@ -20,6 +20,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "unescapeService",
|
||||
"@mozilla.org/feed-unescapehtml;1",
|
||||
"nsIScriptableUnescapeHTML");
|
||||
|
||||
// Add a pref observer for the enabled state
|
||||
function prefObserver(subject, topic, data) {
|
||||
let enable = Services.prefs.getBoolPref("social.enabled");
|
||||
|
@ -434,3 +438,118 @@ SocialErrorListener.prototype = {
|
|||
onStatusChange: function SPL_onStatusChange() {},
|
||||
onSecurityChange: function SPL_onSecurityChange() {},
|
||||
};
|
||||
|
||||
|
||||
this.OpenGraphBuilder = {
|
||||
getData: function(browser) {
|
||||
let res = {
|
||||
url: this._validateURL(browser, browser.currentURI.spec),
|
||||
title: browser.contentDocument.title,
|
||||
previews: []
|
||||
};
|
||||
this._getMetaData(browser, res);
|
||||
this._getLinkData(browser, res);
|
||||
this._getPageData(browser, res);
|
||||
return res;
|
||||
},
|
||||
|
||||
_getMetaData: function(browser, o) {
|
||||
// query for standardized meta data
|
||||
let els = browser.contentDocument
|
||||
.querySelectorAll("head > meta[property], head > meta[name]");
|
||||
if (els.length < 1)
|
||||
return;
|
||||
let url;
|
||||
for (let el of els) {
|
||||
let value = el.getAttribute("content")
|
||||
if (!value)
|
||||
continue;
|
||||
value = unescapeService.unescape(value.trim());
|
||||
switch (el.getAttribute("property") || el.getAttribute("name")) {
|
||||
case "title":
|
||||
case "og:title":
|
||||
o.title = value;
|
||||
break;
|
||||
case "description":
|
||||
case "og:description":
|
||||
o.description = value;
|
||||
break;
|
||||
case "og:site_name":
|
||||
o.siteName = value;
|
||||
break;
|
||||
case "medium":
|
||||
case "og:type":
|
||||
o.medium = value;
|
||||
break;
|
||||
case "og:video":
|
||||
url = this._validateURL(browser, value);
|
||||
if (url)
|
||||
o.source = url;
|
||||
break;
|
||||
case "og:url":
|
||||
url = this._validateURL(browser, value);
|
||||
if (url)
|
||||
o.url = url;
|
||||
break;
|
||||
case "og:image":
|
||||
url = this._validateURL(browser, value);
|
||||
if (url)
|
||||
o.previews.push(url);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_getLinkData: function(browser, o) {
|
||||
let els = browser.contentDocument
|
||||
.querySelectorAll("head > link[rel], head > link[id]");
|
||||
for (let el of els) {
|
||||
let url = el.getAttribute("href");
|
||||
if (!url)
|
||||
continue;
|
||||
url = this._validateURL(browser, unescapeService.unescape(url.trim()));
|
||||
switch (el.getAttribute("rel") || el.getAttribute("id")) {
|
||||
case "shorturl":
|
||||
case "shortlink":
|
||||
o.shortUrl = url;
|
||||
break;
|
||||
case "canonicalurl":
|
||||
case "canonical":
|
||||
o.url = url;
|
||||
break;
|
||||
case "image_src":
|
||||
o.previews.push(url);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// scrape through the page for data we want
|
||||
_getPageData: function(browser, o) {
|
||||
if (o.previews.length < 1)
|
||||
o.previews = this._getImageUrls(browser);
|
||||
},
|
||||
|
||||
_validateURL: function(browser, url) {
|
||||
let uri = Services.io.newURI(browser.currentURI.resolve(url), null, null);
|
||||
if (["http", "https", "ftp", "ftps"].indexOf(uri.scheme) < 0)
|
||||
return null;
|
||||
uri.userPass = "";
|
||||
return uri.spec;
|
||||
},
|
||||
|
||||
_getImageUrls: function(browser) {
|
||||
let l = [];
|
||||
let els = browser.contentDocument.querySelectorAll("img");
|
||||
for (let el of els) {
|
||||
let content = el.getAttribute("src");
|
||||
if (content) {
|
||||
l.push(this._validateURL(browser, unescapeService.unescape(content)));
|
||||
// we don't want a billion images
|
||||
if (l.length > 5)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1441,6 +1441,64 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
list-style-image: url("chrome://browser/skin/Info.png");
|
||||
}
|
||||
|
||||
|
||||
/* social share panel */
|
||||
|
||||
.social-share-frame {
|
||||
background: linear-gradient(to bottom, rgba(242,242,242,.99), rgba(242,242,242,.95));
|
||||
border-left: 1px solid #f8f8f8;
|
||||
width: 330px;
|
||||
height: 150px;
|
||||
/* we resize our panels dynamically, make it look nice */
|
||||
transition: height 100ms ease-out, width 100ms ease-out;
|
||||
}
|
||||
|
||||
#social-share-button {
|
||||
list-style-image: url("chrome://browser/skin/social/share-button.png");
|
||||
}
|
||||
|
||||
#social-share-button[open],
|
||||
#social-share-button:hover:active {
|
||||
list-style-image: url("chrome://browser/skin/social/share-button-active.png");
|
||||
}
|
||||
|
||||
.social-share-toolbar {
|
||||
border-right: 1px solid #dedede;
|
||||
background: linear-gradient(to bottom, rgba(247,247,247,.99), rgba(247,247,247,.95));
|
||||
}
|
||||
|
||||
#social-share-provider-buttons {
|
||||
border-right: 1px solid #fbfbfb;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button {
|
||||
padding: 6px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button[checked],
|
||||
#social-share-provider-buttons > .share-provider-button:active {
|
||||
padding: 5px;
|
||||
border: 1px solid #b5b5b8;
|
||||
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button[checked] {
|
||||
background: linear-gradient(to bottom, #d9d9d9, #e3e3e3);
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-icon {
|
||||
width: 16px;
|
||||
min-height: 16px;
|
||||
max-height: 16px;
|
||||
}
|
||||
|
||||
/* social recommending panel */
|
||||
|
||||
#social-mark-button {
|
||||
|
@ -2094,6 +2152,11 @@ toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
|
|||
-moz-margin-end: 2px;
|
||||
}
|
||||
|
||||
#social-provider-button {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
list-style-image: url(chrome://browser/skin/social/services-16.png);
|
||||
}
|
||||
|
||||
#social-provider-button > .toolbarbutton-menu-dropmarker {
|
||||
display: none;
|
||||
}
|
||||
|
@ -2189,12 +2252,14 @@ toolbar[iconsize="small"] .toolbarbutton-badge-container {
|
|||
.chatbar-button {
|
||||
-moz-appearance: none;
|
||||
background-color: #d9d9d9;
|
||||
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
|
||||
}
|
||||
|
||||
.chatbar-button > .toolbarbutton-icon {
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
|
||||
.chatbar-button:hover,
|
||||
.chatbar-button[open="true"] {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
|
|
@ -105,6 +105,8 @@ browser.jar:
|
|||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/social/share-button.png (social/share-button.png)
|
||||
skin/classic/browser/social/share-button-active.png (social/share-button-active.png)
|
||||
skin/classic/browser/social/chat-close.png (social/chat-close.png)
|
||||
skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
|
||||
skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.3 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.3 KiB |
|
@ -1655,6 +1655,62 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
|
|||
}
|
||||
}
|
||||
|
||||
/* social share panel */
|
||||
.social-share-frame {
|
||||
background: linear-gradient(to bottom, rgba(242,242,242,.99), rgba(242,242,242,.95));
|
||||
border-left: 1px solid #f8f8f8;
|
||||
width: 330px;
|
||||
height: 150px;
|
||||
/* we resize our panels dynamically, make it look nice */
|
||||
transition: height 100ms ease-out, width 100ms ease-out;
|
||||
}
|
||||
|
||||
#social-share-button {
|
||||
list-style-image: url("chrome://browser/skin/social/share-button.png");
|
||||
}
|
||||
|
||||
#social-share-button[open],
|
||||
#social-share-button:hover:active {
|
||||
list-style-image: url("chrome://browser/skin/social/share-button-active.png");
|
||||
}
|
||||
|
||||
.social-share-toolbar {
|
||||
border-right: 1px solid #dedede;
|
||||
background: linear-gradient(to bottom, rgba(247,247,247,.99), rgba(247,247,247,.95));
|
||||
}
|
||||
|
||||
#social-share-provider-buttons {
|
||||
border-right: 1px solid #fbfbfb;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button {
|
||||
padding: 6px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button[checked],
|
||||
#social-share-provider-buttons > .share-provider-button:active {
|
||||
padding: 5px;
|
||||
border: 1px solid #b5b5b8;
|
||||
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button[checked] {
|
||||
background: linear-gradient(to bottom, #d9d9d9, #e3e3e3);
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-icon {
|
||||
width: 16px;
|
||||
min-height: 16px;
|
||||
max-height: 16px;
|
||||
}
|
||||
|
||||
/* social recommending panel */
|
||||
|
||||
#social-mark-button {
|
||||
|
@ -3628,8 +3684,19 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
#social-toolbar-item > toolbaritem {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#social-provider-button {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
list-style-image: url(chrome://browser/skin/social/services-16.png);
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#social-provider-button {
|
||||
list-style-image: url(chrome://browser/skin/social/services-16@2x.png);
|
||||
}
|
||||
}
|
||||
|
||||
#social-provider-button > .toolbarbutton-menu-dropmarker {
|
||||
|
@ -3749,10 +3816,36 @@ toolbar[mode="icons"] > *|* > .toolbarbutton-badge[badge]:not([badge=""]):-moz-l
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.social-panel-frame {
|
||||
/* fixup rounded corners for osx panels */
|
||||
.social-panel > .social-panel-frame {
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
#social-share-panel {
|
||||
margin-top: 3px;
|
||||
max-height: 600px;
|
||||
min-height: 100px;
|
||||
max-width: 800px;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.social-share-frame {
|
||||
border-top-left-radius: none;
|
||||
border-bottom-left-radius: none;
|
||||
border-top-right-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
}
|
||||
|
||||
#social-share-panel > .social-share-toolbar {
|
||||
border-top-left-radius: inherit;
|
||||
border-bottom-left-radius: inherit;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons {
|
||||
border-top-left-radius: inherit;
|
||||
border-bottom-left-radius: inherit;
|
||||
}
|
||||
|
||||
/* === end of social toolbar provider menu === */
|
||||
|
||||
%include ../shared/social/chat.inc.css
|
||||
|
@ -3768,13 +3861,17 @@ toolbar[mode="icons"] > *|* > .toolbarbutton-badge[badge]:not([badge=""]):-moz-l
|
|||
|
||||
.chatbar-button {
|
||||
background-color: #d9d9d9;
|
||||
background-image: linear-gradient(rgba(255,255,255,.43), rgba(255,255,255,0));
|
||||
border-top-left-radius: @toolbarbuttonCornerRadius@;
|
||||
border-top-right-radius: @toolbarbuttonCornerRadius@;
|
||||
}
|
||||
|
||||
.chatbar-button:hover,
|
||||
.chatbar-button[open="true"] {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.chatbar-button[activity] {
|
||||
.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%);
|
||||
}
|
||||
|
||||
|
|
|
@ -172,6 +172,8 @@ browser.jar:
|
|||
skin/classic/browser/social/services-16@2x.png (social/services-16@2x.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/social/services-64@2x.png (social/services-64@2x.png)
|
||||
skin/classic/browser/social/share-button.png (social/share-button.png)
|
||||
skin/classic/browser/social/share-button-active.png (social/share-button-active.png)
|
||||
skin/classic/browser/social/chat-close.png (social/chat-close.png)
|
||||
skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png (tabbrowser/alltabs-box-bkgnd-icon.png)
|
||||
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.3 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.3 KiB |
|
@ -1,3 +1,3 @@
|
|||
%filter substitution
|
||||
|
||||
%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #downloads-indicator, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-button, #feed-button, #alltabs-button, #tabview-button, #webrtc-status-button
|
||||
%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #downloads-indicator, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-button, #feed-button, #alltabs-button, #tabview-button, #webrtc-status-button, #social-share-button
|
||||
|
|
|
@ -73,13 +73,12 @@
|
|||
|
||||
.chatbar-button {
|
||||
list-style-image: url("chrome://browser/skin/social/services-16.png");
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
height: 21px;
|
||||
width: 21px;
|
||||
border-top: 1px solid #ccc;
|
||||
-moz-border-end: 1px solid #ccc;
|
||||
border: 1px solid #ccc;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
|
@ -95,15 +94,6 @@
|
|||
max-width: 16px;
|
||||
}
|
||||
|
||||
.chatbar-button > .toolbarbutton-icon {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.chatbar-button:hover > .toolbarbutton-icon,
|
||||
.chatbar-button[open="true"] > .toolbarbutton-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.chatbar-button[open="true"] {
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
}
|
||||
|
|
|
@ -1713,6 +1713,93 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
|
||||
/* social share panel */
|
||||
|
||||
#social-share-panel > iframe {
|
||||
background: linear-gradient(to bottom, #f0f4f7, #fafbfc);
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
#social-share-button {
|
||||
list-style-image: url(chrome://browser/skin/social/share-button.png);
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
.social-share-toolbar {
|
||||
border-right: 1px solid #e2e5e8;
|
||||
background: linear-gradient(to bottom, #ffffff, #f5f7fa);
|
||||
}
|
||||
|
||||
#social-share-provider-buttons {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button {
|
||||
-moz-appearance: none;
|
||||
padding: 5px;
|
||||
margin: 1px;
|
||||
border: none;
|
||||
background: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button[checked="true"]:not([disabled="true"]),
|
||||
#social-share-provider-buttons > .share-provider-button:hover,
|
||||
#social-share-provider-buttons > .share-provider-button:active {
|
||||
padding: 4px;
|
||||
border: 1px solid #aeb8c1;
|
||||
box-shadow: inset 1px 1px 1px rgba(10, 31, 51, 0.1);
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button[checked="true"]:not([disabled="true"]) {
|
||||
background: linear-gradient(to bottom, rgba(230,232,234,.65), #d2d5d9);
|
||||
}
|
||||
|
||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-icon {
|
||||
width: 16px;
|
||||
min-height: 16px;
|
||||
max-height: 16px;
|
||||
}
|
||||
|
||||
/* fixup corners for share panel */
|
||||
.social-panel > .social-panel-frame {
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
#social-share-panel {
|
||||
max-height: 600px;
|
||||
min-height: 100px;
|
||||
max-width: 800px;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.social-share-frame {
|
||||
background: linear-gradient(to bottom, #f0f4f7, #fafbfc);
|
||||
width: 330px;
|
||||
height: 150px;
|
||||
border-top-left-radius: none;
|
||||
border-bottom-left-radius: none;
|
||||
border-top-right-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
/* we resize our panels dynamically, make it look nice */
|
||||
transition: height 100ms ease-out, width 100ms ease-out;
|
||||
}
|
||||
|
||||
#social-share-panel > .social-share-toolbar {
|
||||
border-top-left-radius: inherit;
|
||||
border-bottom-left-radius: inherit;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons {
|
||||
border-top-left-radius: inherit;
|
||||
border-bottom-left-radius: inherit;
|
||||
}
|
||||
|
||||
/* social recommending panel */
|
||||
|
||||
#social-mark-button {
|
||||
|
@ -2765,6 +2852,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
|||
|
||||
#social-provider-button {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
list-style-image: url(chrome://browser/skin/social/services-16.png);
|
||||
}
|
||||
|
||||
#social-provider-button > .toolbarbutton-menu-dropmarker {
|
||||
|
@ -2913,12 +3001,14 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
|||
.chatbar-button {
|
||||
-moz-appearance: none;
|
||||
background-color: #c4cfde;
|
||||
background-image: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0));
|
||||
}
|
||||
|
||||
.chatbar-button > .toolbarbutton-icon {
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
|
||||
.chatbar-button:hover,
|
||||
.chatbar-button[open="true"] {
|
||||
background-color: #dae3f0;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,8 @@ browser.jar:
|
|||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/social/share-button.png (social/share-button.png)
|
||||
skin/classic/browser/social/share-button-active.png (social/share-button-active.png)
|
||||
skin/classic/browser/social/chat-close.png (social/chat-close.png)
|
||||
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
|
||||
skin/classic/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
|
||||
|
@ -373,6 +375,8 @@ browser.jar:
|
|||
skin/classic/aero/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/aero/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/aero/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/aero/browser/social/share-button.png (social/share-button.png)
|
||||
skin/classic/aero/browser/social/share-button-active.png (social/share-button-active.png)
|
||||
skin/classic/aero/browser/social/chat-close.png (social/chat-close.png)
|
||||
skin/classic/aero/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
|
||||
skin/classic/aero/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -93,6 +93,7 @@ _LEAKTEST_DIR = $(DEPTH)/_leaktest
|
|||
_LEAKTEST_FILES = \
|
||||
automation.py \
|
||||
automationutils.py \
|
||||
$(topsrcdir)/testing/profiles/prefs_general.js \
|
||||
leaktest.py \
|
||||
bloatcycle.html \
|
||||
$(topsrcdir)/build/pgo/server-locations.txt \
|
||||
|
|
|
@ -43,6 +43,8 @@ except:
|
|||
import mozcrash
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
_DEFAULT_PREFERENCE_FILE = os.path.join(SCRIPT_DIR, 'prefs_general.js')
|
||||
|
||||
_DEFAULT_WEB_SERVER = "127.0.0.1"
|
||||
_DEFAULT_HTTP_PORT = 8888
|
||||
_DEFAULT_SSL_PORT = 4443
|
||||
|
@ -433,11 +435,14 @@ class Automation(object):
|
|||
manifestFile.write(manifest)
|
||||
manifestFile.close()
|
||||
|
||||
def initializeProfile(self, profileDir, extraPrefs=[],
|
||||
useServerLocations=False,
|
||||
initialProfile=None):
|
||||
def initializeProfile(self, profileDir,
|
||||
extraPrefs=None,
|
||||
useServerLocations=False,
|
||||
initialProfile=None,
|
||||
prefsPath=_DEFAULT_PREFERENCE_FILE):
|
||||
" Sets up the standard testing profile."
|
||||
|
||||
extraPrefs = extraPrefs or []
|
||||
prefs = []
|
||||
# Start with a clean slate.
|
||||
shutil.rmtree(profileDir, True)
|
||||
|
@ -452,125 +457,9 @@ class Automation(object):
|
|||
self.setupPermissionsDatabase(profileDir,
|
||||
{'allowXULXBL':[(l.host, 'noxul' not in l.options) for l in locations]});
|
||||
|
||||
# NOTE: For refactoring purposes we are temporarily storing these prefs
|
||||
# in two locations. If you update a pref below, please also update
|
||||
# it in source/testing/profiles/prefs_general.js.
|
||||
# See bug 830430 for more details.
|
||||
part = """\
|
||||
user_pref("browser.console.showInPanel", true);
|
||||
user_pref("browser.dom.window.dump.enabled", true);
|
||||
user_pref("browser.firstrun.show.localepicker", false);
|
||||
user_pref("browser.firstrun.show.uidiscovery", false);
|
||||
user_pref("browser.startup.page", 0); // use about:blank, not browser.startup.homepage
|
||||
user_pref("browser.ui.layout.tablet", 0); // force tablet UI off
|
||||
user_pref("dom.allow_scripts_to_close_windows", true);
|
||||
user_pref("dom.disable_open_during_load", false);
|
||||
user_pref("dom.experimental_forms", true); // on for testing
|
||||
user_pref("dom.experimental_forms_range", true); // on for testing
|
||||
user_pref("dom.max_script_run_time", 0); // no slow script dialogs
|
||||
user_pref("hangmonitor.timeout", 0); // no hang monitor
|
||||
user_pref("dom.max_chrome_script_run_time", 0);
|
||||
user_pref("dom.popup_maximum", -1);
|
||||
user_pref("dom.send_after_paint_to_content", true);
|
||||
user_pref("dom.successive_dialog_time_limit", 0);
|
||||
user_pref("signed.applets.codebase_principal_support", true);
|
||||
user_pref("browser.shell.checkDefaultBrowser", false);
|
||||
user_pref("shell.checkDefaultClient", false);
|
||||
user_pref("browser.warnOnQuit", false);
|
||||
user_pref("accessibility.typeaheadfind.autostart", false);
|
||||
user_pref("javascript.options.showInConsole", true);
|
||||
user_pref("devtools.errorconsole.enabled", true);
|
||||
user_pref("devtools.debugger.remote-port", 6023);
|
||||
user_pref("layout.debug.enable_data_xbl", true);
|
||||
user_pref("browser.EULA.override", true);
|
||||
user_pref("javascript.options.jit_hardening", true);
|
||||
user_pref("gfx.color_management.force_srgb", true);
|
||||
user_pref("network.manage-offline-status", false);
|
||||
user_pref("dom.min_background_timeout_value", 1000);
|
||||
user_pref("test.mousescroll", true);
|
||||
user_pref("security.default_personal_cert", "Select Automatically"); // Need to client auth test be w/o any dialogs
|
||||
user_pref("network.http.prompt-temp-redirect", false);
|
||||
user_pref("media.cache_size", 100);
|
||||
user_pref("media.volume_scale", "0.01");
|
||||
user_pref("security.warn_viewing_mixed", false);
|
||||
user_pref("app.update.enabled", false);
|
||||
user_pref("app.update.staging.enabled", false);
|
||||
user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
|
||||
user_pref("dom.w3c_touch_events.enabled", 1);
|
||||
user_pref("dom.undo_manager.enabled", true);
|
||||
user_pref("dom.webcomponents.enabled", true);
|
||||
// Set a future policy version to avoid the telemetry prompt.
|
||||
user_pref("toolkit.telemetry.prompted", 999);
|
||||
user_pref("toolkit.telemetry.notifiedOptOut", 999);
|
||||
// Existing tests assume there is no font size inflation.
|
||||
user_pref("font.size.inflation.emPerLine", 0);
|
||||
user_pref("font.size.inflation.minTwips", 0);
|
||||
|
||||
// Only load extensions from the application and user profile
|
||||
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
|
||||
user_pref("extensions.enabledScopes", 5);
|
||||
// Disable metadata caching for installed add-ons by default
|
||||
user_pref("extensions.getAddons.cache.enabled", false);
|
||||
// Disable intalling any distribution add-ons
|
||||
user_pref("extensions.installDistroAddons", false);
|
||||
|
||||
user_pref("geo.wifi.uri", "http://%(server)s/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
|
||||
user_pref("geo.wifi.testing", true);
|
||||
user_pref("geo.ignore.location_filter", true);
|
||||
|
||||
user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others
|
||||
|
||||
// Make url-classifier updates so rare that they won't affect tests
|
||||
user_pref("urlclassifier.updateinterval", 172800);
|
||||
// Point the url-classifier to the local testing server for fast failures
|
||||
user_pref("browser.safebrowsing.gethashURL", "http://%(server)s/safebrowsing-dummy/gethash");
|
||||
user_pref("browser.safebrowsing.keyURL", "http://%(server)s/safebrowsing-dummy/newkey");
|
||||
user_pref("browser.safebrowsing.updateURL", "http://%(server)s/safebrowsing-dummy/update");
|
||||
// Point update checks to the local testing server for fast failures
|
||||
user_pref("extensions.update.url", "http://%(server)s/extensions-dummy/updateURL");
|
||||
user_pref("extensions.update.background.url", "http://%(server)s/extensions-dummy/updateBackgroundURL");
|
||||
user_pref("extensions.blocklist.url", "http://%(server)s/extensions-dummy/blocklistURL");
|
||||
user_pref("extensions.hotfix.url", "http://%(server)s/extensions-dummy/hotfixURL");
|
||||
// Turn off extension updates so they don't bother tests
|
||||
user_pref("extensions.update.enabled", false);
|
||||
// Make sure opening about:addons won't hit the network
|
||||
user_pref("extensions.webservice.discoverURL", "http://%(server)s/extensions-dummy/discoveryURL");
|
||||
// Make sure AddonRepository won't hit the network
|
||||
user_pref("extensions.getAddons.maxResults", 0);
|
||||
user_pref("extensions.getAddons.get.url", "http://%(server)s/extensions-dummy/repositoryGetURL");
|
||||
user_pref("extensions.getAddons.getWithPerformance.url", "http://%(server)s/extensions-dummy/repositoryGetWithPerformanceURL");
|
||||
user_pref("extensions.getAddons.search.browseURL", "http://%(server)s/extensions-dummy/repositoryBrowseURL");
|
||||
user_pref("extensions.getAddons.search.url", "http://%(server)s/extensions-dummy/repositorySearchURL");
|
||||
// Make sure that opening the plugins check page won't hit the network
|
||||
user_pref("plugins.update.url", "http://%(server)s/plugins-dummy/updateCheckURL");
|
||||
|
||||
// Existing tests don't wait for the notification button security delay
|
||||
user_pref("security.notification_enable_delay", 0);
|
||||
|
||||
// Make enablePrivilege continue to work for test code. :-(
|
||||
user_pref("security.turn_off_all_security_so_that_viruses_can_take_over_this_computer", true);
|
||||
|
||||
// In the default configuration, we bypass XBL scopes (a security feature) for
|
||||
// domains whitelisted for remote XUL, so that intranet apps and such continue
|
||||
// to work without major rewrites. However, we also use the whitelist mechanism
|
||||
// to run our XBL tests in automation, in which case we really want to be testing
|
||||
// the configuration that we ship to users without special whitelisting. So we
|
||||
// use an additional pref here to allow automation to use the "normal" behavior.
|
||||
user_pref("dom.use_xbl_scopes_for_remote_xul", true);
|
||||
|
||||
// Get network events.
|
||||
user_pref("network.activity.blipIntervalMilliseconds", 250);
|
||||
|
||||
// Don't allow the Data Reporting service to prompt for policy acceptance.
|
||||
user_pref("datareporting.policy.dataSubmissionPolicyBypassAcceptance", true);
|
||||
|
||||
// Point Firefox Health Report at a local server. We don't care if it actually
|
||||
// works. It just can't hit the default production endpoint.
|
||||
user_pref("datareporting.healthreport.documentServerURI", "http://%(server)s/healthreport/");
|
||||
|
||||
// Make sure CSS error reporting is enabled for tests
|
||||
user_pref("layout.css.report_errors", true);
|
||||
""" % { "server" : self.webServer + ":" + str(self.httpPort) }
|
||||
f = open(prefsPath, 'r')
|
||||
part = f.read() % {"server" : "%s:%s" % (self.webServer, self.httpPort)}
|
||||
f.close()
|
||||
prefs.append(part)
|
||||
|
||||
if useServerLocations:
|
||||
|
@ -619,16 +508,15 @@ function FindProxyForURL(url, host)
|
|||
"sslport": self.sslPort }
|
||||
pacURL = "".join(pacURL.splitlines())
|
||||
|
||||
part += """
|
||||
part = """
|
||||
user_pref("network.proxy.type", 2);
|
||||
user_pref("network.proxy.autoconfig_url", "%(pacURL)s");
|
||||
|
||||
user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless to others
|
||||
""" % {"pacURL": pacURL}
|
||||
prefs.append(part)
|
||||
else:
|
||||
part = 'user_pref("network.proxy.type", 0);\n'
|
||||
prefs.append(part)
|
||||
prefs.append(part)
|
||||
|
||||
for v in extraPrefs:
|
||||
thispref = v.split("=", 1)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Define indicating that this build is prior to one of the early betas. To be
|
||||
# unset mid-way through the beta cycle.
|
||||
EARLY_BETA_OR_EARLIER=1
|
|
@ -47,6 +47,22 @@ toolkit/library
|
|||
profile
|
||||
services
|
||||
startupcache
|
||||
browser
|
||||
toolkit/mozapps/extensions
|
||||
browser/app
|
||||
browser/base
|
||||
browser/components
|
||||
browser/devtools
|
||||
browser/locales
|
||||
browser/modules
|
||||
browser/themes
|
||||
toolkit
|
||||
toolkit/components
|
||||
toolkit/content
|
||||
toolkit/crashreporter
|
||||
toolkit/devtools
|
||||
toolkit/forgetaboutsite
|
||||
toolkit/identity
|
||||
toolkit/modules
|
||||
toolkit/mozapps/extensions
|
||||
toolkit/profile
|
||||
toolkit/themes
|
||||
toolkit/webapps
|
||||
|
|
|
@ -22,10 +22,17 @@ SEARCH_PATHS = [
|
|||
'xpcom/idl-parser',
|
||||
'testing',
|
||||
'testing/xpcshell',
|
||||
'testing/marionette/client',
|
||||
'testing/marionette/client/marionette',
|
||||
'testing/mozbase/mozcrash',
|
||||
'testing/mozbase/mozlog',
|
||||
'testing/mozbase/mozprocess',
|
||||
'testing/mozbase/mozdevice',
|
||||
'testing/mozbase/mozfile',
|
||||
'testing/mozbase/mozhttpd',
|
||||
'testing/mozbase/mozlog',
|
||||
'testing/mozbase/moznetwork',
|
||||
'testing/mozbase/mozprocess',
|
||||
'testing/mozbase/mozprofile',
|
||||
'testing/mozbase/mozrunner',
|
||||
'testing/mozbase/mozinfo',
|
||||
]
|
||||
|
||||
|
@ -38,6 +45,7 @@ MACH_MODULES = [
|
|||
'python/mozbuild/mozbuild/config.py',
|
||||
'python/mozbuild/mozbuild/mach_commands.py',
|
||||
'python/mozbuild/mozbuild/frontend/mach_commands.py',
|
||||
'testing/marionette/mach_commands.py',
|
||||
'testing/mochitest/mach_commands.py',
|
||||
'testing/xpcshell/mach_commands.py',
|
||||
'tools/mach_commands.py',
|
||||
|
|
|
@ -25,3 +25,6 @@ if [ -z "$CXX" ]; then
|
|||
fi
|
||||
|
||||
ac_add_options --with-ccache
|
||||
|
||||
# Enable ECMAScript Internationalization API
|
||||
ac_add_options --enable-intl-api
|
||||
|
|
|
@ -120,16 +120,6 @@ class B2GRemoteAutomation(Automation):
|
|||
self._devicemanager.removeDir(remote_dump_dir)
|
||||
return crashed
|
||||
|
||||
def initializeProfile(self, profileDir, extraPrefs=[],
|
||||
useServerLocations=False,
|
||||
initialProfile=None):
|
||||
# add b2g specific prefs
|
||||
extraPrefs.extend(["browser.manifestURL='dummy (bug 772307)'"])
|
||||
return Automation.initializeProfile(self, profileDir,
|
||||
extraPrefs,
|
||||
useServerLocations,
|
||||
initialProfile)
|
||||
|
||||
def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
|
||||
# if remote profile is specified, use that instead
|
||||
if (self._remoteProfile):
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче