--- a/mobile/app/mobile.js
+++ b/mobile/app/mobile.js
@@ -175,23 +175,23 @@ pref("extensions.ignoreMTimeChanges", fa
pref("extensions.logging.enabled", false);
pref("extensions.hideInstallButton", true);
pref("extensions.showMismatchUI", false);
pref("extensions.hideUpdateButton", false);
pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%");
/* preferences for the Get Add-ons pane */
-pref("extensions.getAddons.showPane", true);
-pref("extensions.getAddons.browseAddons", "https://addons.mozilla.org/%LOCALE%/mobile/");
+pref("extensions.getAddons.cache.enabled", true);
pref("extensions.getAddons.maxResults", 5);
pref("extensions.getAddons.recommended.browseURL", "https://addons.mozilla.org/%LOCALE%/mobile/recommended/");
pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/mobile/api/%API_VERSION%/list/featured/all/10/%OS%/%VERSION%");
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/mobile/search?q=%TERMS%");
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/mobile/api/%API_VERSION%/search/%TERMS%/all/10/%OS%/%VERSION%");
+pref("extensions.getAddons.browseAddons", "https://addons.mozilla.org/%LOCALE%/mobile/");
/* blocklist preferences */
pref("extensions.blocklist.enabled", true);
pref("extensions.blocklist.interval", 86400);
pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/2/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
/* block popups by default, and notify the user about blocked popups */
--- a/mobile/chrome/content/aboutHome.xhtml
+++ b/mobile/chrome/content/aboutHome.xhtml
@@ -202,17 +202,17 @@
let titlePart = document.createElement("div");
titlePart.textContent = title;
titlePart.className = "title";
inner.appendChild(titlePart);
outer.appendChild(inner);
list.appendChild(outer);
}
-
+
if (allPageURLs.length > 0) {
document.getElementById("loadingTabs").style.display = "none";
if (allPageURLs.length > 1) {
let outer = document.createElement("div");
outer.className = "openall";
outer.textContent = document.getElementById("text-openalltabs").textContent;
outer.setAttribute("role", "button");
@@ -229,33 +229,38 @@
}
}
function initWeave() {
let chromeWin = getChromeWin();
if ("WeaveGlue" in chromeWin) {
chromeWin.Services.obs.addObserver(updateWeaveButton, "weave:service:login:finish", false);
chromeWin.Services.obs.addObserver(updateWeaveButton, "weave:service:logout:finish", false);
+
+ updateWeaveButton();
}
else {
document.getElementById("remoteTabs").style.display = "none";
}
}
function uninitWeave() {
let chromeWin = getChromeWin();
if ("WeaveGlue" in chromeWin) {
chromeWin.Services.obs.removeObserver(updateWeaveButton, "weave:service:login:finish");
chromeWin.Services.obs.removeObserver(updateWeaveButton, "weave:service:logout:finish");
}
}
function updateWeaveButton() {
- let isDisabled = !getChromeWin().Weave.Service.isLoggedIn;
- document.getElementById("remoteTabs").setAttribute("disabled", isDisabled);
+ let chromeWin = getChromeWin();
+ if (chromeWin.Weave) {
+ let isDisabled = !chromeWin.Weave.Service.isLoggedIn;
+ document.getElementById("remoteTabs").setAttribute("disabled", isDisabled);
+ }
}
function openRemoteTabs() {
getChromeWin().CommandUpdater.doCommand("cmd_remoteTabs");
}
function goToAddons(aSearchString) {
let chromeWin = getChromeWin();
--- a/mobile/chrome/content/bindings.xml
+++ b/mobile/chrome/content/bindings.xml
@@ -353,17 +353,17 @@
<handler event="click" button="0">
<![CDATA[
if (this.control)
this.control._fireOpen(event, this);
]]>
</handler>
<handler event="contextmenu" phase="capturing">
<![CDATA[
- if (!this.uri)
+ if (!this.uri || this._isEditing)
return;
let data = {
target: this,
json: {
types: ["edit-bookmark"],
label: this.uri.spec
}};
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -2284,33 +2284,17 @@ var MenuListHelperUI = {
evt.initCommandEvent("command", true, true, window, 0, false, false, false, false, null);
this._currentList.dispatchEvent(evt);
}
this.hide();
},
sizeToContent: function sizeToContent() {
- // Make sure the container is at least sized to the content
- let popup = this._popup;
- let preferredHeight = 0;
- for (let i=0; i<popup.childElementCount; i++) {
- preferredHeight += popup.children[i].getBoundingClientRect().height;
- }
-
- // Ensure to reset the assigned width/height to have the default's one set
- // by the content
- popup.width = popup.height = "";
-
- let rect = popup.getBoundingClientRect();
- let height = Math.min(preferredHeight, 0.75 * window.innerWidth);
- let width = Math.min(rect.width, 0.75 * window.innerWidth);
-
- popup.height = height;
- popup.width = width;
+ this._popup.maxWidth = window.innerWidth * 0.75;
},
handleEvent: function handleEvent(aEvent) {
this.sizeToContent();
}
}
var ContextHelper = {
@@ -2376,45 +2360,34 @@ var ContextHelper = {
this.popupState = null;
this._panel.hidden = true;
window.removeEventListener("resize", this, true);
BrowserUI.popPopup();
},
sizeToContent: function sizeToContent() {
- // Make sure the container is at least sized to the content
- let popup = this._popup;
- let preferredHeight = 0;
- for (let i=0; i<popup.childElementCount; i++) {
- preferredHeight += popup.children[i].getBoundingClientRect().height;
- }
-
- // Ensure to reset the assigned width/height to have the default's one set
- // by the content
- popup.width = popup.height = "";
-
- let rect = popup.getBoundingClientRect();
- let height = Math.min(preferredHeight, 0.75 * window.innerWidth);
- let width = Math.min(rect.width, 0.75 * window.innerWidth);
-
- popup.height = height;
- popup.width = width;
+ this._popup.maxWidth = window.innerWidth * 0.75;
},
handleEvent: function handleEvent(aEvent) {
this.sizeToContent();
}
};
var ContextCommands = {
openInNewTab: function cc_openInNewTab() {
Browser.addTab(ContextHelper.popupState.linkURL, false, Browser.selectedTab);
},
+ saveLink: function cc_saveLink() {
+ let browser = ContextHelper.popupState.target;
+ saveURL(ContextHelper.popupState.linkURL, null, "SaveLinkTitle", false, false, browser.documentURI);
+ },
+
saveImage: function cc_saveImage() {
let browser = ContextHelper.popupState.target;
saveImageURL(ContextHelper.popupState.mediaURL, null, "SaveImageTitle", false, false, browser.documentURI);
},
shareLink: function cc_shareLink() {
let state = ContextHelper.popupState;
SharingUI.show(state.linkURL, state.linkTitle);
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -532,20 +532,23 @@
</vbox>
</hbox>
<hbox id="context-container" class="window-width window-height context-block" top="0" left="0" hidden="true">
<vbox id="context-popup" class="dialog-dark">
<hbox id="context-header">
<label id="context-hint" crop="center" flex="1"/>
</hbox>
- <richlistbox id="context-commands" onclick="ContextHelper.hide();">
+ <richlistbox id="context-commands" onclick="ContextHelper.hide();" flex="1">
<richlistitem class="context-command" id="context-openinnewtab" type="link-saveable" onclick="ContextCommands.openInNewTab();">
<label value="&contextOpenInNewTab.label;"/>
</richlistitem>
+ <richlistitem class="context-command" id="context-savelink" type="link-saveable" onclick="ContextCommands.saveLink();">
+ <label value="&contextSaveLink.label;"/>
+ </richlistitem>
<richlistitem class="context-command" id="context-saveimage" type="image-loaded" onclick="ContextCommands.saveImage();">
<label value="&contextSaveImage.label;"/>
</richlistitem>
<richlistitem class="context-command" id="context-share-link" type="link-shareable" onclick="ContextCommands.shareLink();">
<label value="&contextShareLink.label;"/>
</richlistitem>
<richlistitem class="context-command" id="context-share-image" type="image-shareable" onclick="ContextCommands.shareMedia();">
<label value="&contextShareImage.label;"/>
--- a/mobile/chrome/content/extensions.js
+++ b/mobile/chrome/content/extensions.js
@@ -275,23 +275,27 @@ var ExtensionsView = {
this.hideOptions();
},
getAddonsFromLocal: function ev_getAddonsFromLocal() {
this.clearSection("local");
let self = this;
AddonManager.getAddonsByTypes(["extension", "theme", "locale"], function(items) {
+ let anyUpdateable = false;
for (let i = 0; i < items.length; i++) {
let addon = items[i];
let appManaged = (addon.scope == AddonManager.SCOPE_APPLICATION);
let opType = self._getOpTypeForOperations(addon.pendingOperations);
- let updateable = (addon.permissions & AddonManager.PERM_CAN_UPDATE) > 0;
+ let updateable = (addon.permissions & AddonManager.PERM_CAN_UPGRADE) > 0;
let uninstallable = (addon.permissions & AddonManager.PERM_CAN_UNINSTALL) > 0;
+ if (updateable)
+ anyUpdateable = true;
+
let listitem = self._createItem(addon, "local");
listitem.setAttribute("isDisabled", !addon.isActive);
listitem.setAttribute("appDisabled", addon.appDisabled);
listitem.setAttribute("appManaged", appManaged);
listitem.setAttribute("description", addon.description);
listitem.setAttribute("optionsURL", addon.optionsURL);
listitem.setAttribute("opType", opType);
listitem.setAttribute("updateable", updateable);
@@ -325,20 +329,21 @@ var ExtensionsView = {
listitem.setAttribute("appManaged", isDefault(engine));
listitem.setAttribute("description", engine.description || defaultDescription);
listitem.setAttribute("optionsURL", "");
listitem.setAttribute("opType", engine.hidden ? "needs-disable" : "");
listitem.setAttribute("updateable", "false");
self._list.insertBefore(listitem, self._repoItem);
}
- if (engines.length + items.length == 0) {
+ if (engines.length + items.length == 0)
self.displaySectionMessage("local", strings.getString("addonsLocalNone.label"), null, true);
+
+ if (!anyUpdateable)
document.getElementById("addons-update-all").disabled = true;
- }
});
},
enable: function ev_enable(aItem) {
let opType;
if (aItem.getAttribute("type") == "search") {
aItem.setAttribute("isDisabled", false);
aItem._engine.hidden = false;
@@ -594,37 +599,41 @@ var ExtensionsView = {
this._list.selectedItem.focus();
},
observe: function ev_observe(aSubject, aTopic, aData) {
if (!document)
return;
let json = aSubject.QueryInterface(Ci.nsISupportsString).data;
- let addon = JSON.parse(json);
+ let update = JSON.parse(json);
let strings = Elements.browserBundle;
- let element = this.getElementForAddon(addon.id);
+ let element = this.getElementForAddon(update.id);
if (!element)
return;
+ let addon = element.addon;
+
switch (aTopic) {
case "addon-update-started":
element.setAttribute("updateStatus", strings.getString("addonUpdate.checking"));
break;
case "addon-update-ended":
let updateable = false;
let statusMsg = null;
switch (aData) {
case "update":
- statusMsg = strings.getFormattedString("addonUpdate.updating", [addon.version]);
+ statusMsg = strings.getFormattedString("addonUpdate.updating", [update.version]);
updateable = true;
break;
case "compatibility":
statusMsg = strings.getString("addonUpdate.compatibility");
+ if (addon.pendingOperations & AddonManager.PENDING_INSTALL || addon.pendingOperations & AddonManager.PENDING_UPGRADE)
+ updateable = true;
break;
case "error":
statusMsg = strings.getString("addonUpdate.error");
break;
case "no-update":
// Ignore if no updated was found. Just let the message go blank.
//statusMsg = strings.getString("addonUpdate.noupdate");
break;
--- a/mobile/components/HelperAppDialog.js
+++ b/mobile/components/HelperAppDialog.js
@@ -49,79 +49,22 @@ Cu.import("resource://gre/modules/Servic
function HelperAppLauncherDialog() { }
HelperAppLauncherDialog.prototype = {
classID: Components.ID("{e9d277a0-268a-4ec2-bb8c-10fdf3e44611}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
show: function hald_show(aLauncher, aContext, aReason) {
- const NS_BINDING_ABORTED = 0x804b0002;
-
- let window = aContext.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowInternal);
-
- let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
-
- let flags = (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
- (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1);
-
- let title = bundle.GetStringFromName("helperApp.title");
- let message = bundle.GetStringFromName("helperApp.prompt");
- message += "\n " + aLauncher.suggestedFileName;
-
- let type = aLauncher.MIMEInfo.description;
- if (type == "") {
- try {
- type = aLauncher.MIMEInfo.primaryExtension.toUpperCase();
- } catch (e) {
- type = aLauncher.MIMEInfo.MIMEType;
- }
- }
- message += "\n " + type;
-
- let open = bundle.GetStringFromName("helperApp.open");
- let save = bundle.GetStringFromName("helperApp.save");
- let nothing = bundle.GetStringFromName("helperApp.nothing");
-
// Check to see if we can open this file or not
if (aLauncher.MIMEInfo.hasDefaultHandler) {
- flags += (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_2);
-
- let choice = Services.prompt.confirmEx(window,
- title, message,
- flags, save, open, nothing,
- null, {});
-
- if (choice == 0) {
- aLauncher.saveToDisk(null, false);
- }
- else if (choice == 1) {
- aLauncher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.useSystemDefault;
- aLauncher.launchWithApplication(null, false);
- }
- else {
- try {
- aLauncher.cancel(NS_BINDING_ABORTED);
- } catch(e) {}
- }
+ aLauncher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.useSystemDefault;
+ aLauncher.launchWithApplication(null, false);
} else {
- let choice = Services.prompt.confirmEx(window,
- title, message,
- flags, save, nothing, null,
- null, {});
-
- if (choice == 0) {
- aLauncher.saveToDisk(null, false);
- }
- else {
- try {
- aLauncher.cancel(NS_BINDING_ABORTED);
- } catch(e) {}
- }
+ aLauncher.saveToDisk(null, false);
}
},
promptForSaveToFile: function hald_promptForSaveToFile(aLauncher, aContext, aDefaultFile, aSuggestedFileExt, aForcePrompt) {
let file = null;
let prefs = Services.prefs;
--- a/mobile/locales/en-US/chrome/browser.dtd
+++ b/mobile/locales/en-US/chrome/browser.dtd
@@ -82,16 +82,17 @@
<!ENTITY consoleCodeEval.label "Code:">
<!ENTITY consoleClear.label "Clear">
<!ENTITY consoleEvaluate.label "…">
<!ENTITY consoleErrFile.label "Source File:">
<!ENTITY consoleErrLine.label "Line:">
<!ENTITY consoleErrColumn.label "Column:">
<!ENTITY contextOpenInNewTab.label "Open Link in New Tab">
+<!ENTITY contextSaveLink.label "Save Link">
<!ENTITY contextSaveImage.label "Save Image">
<!ENTITY contextShareLink.label "Share Link">
<!ENTITY contextShareImage.label "Share Image">
<!ENTITY contextSaveVideo.label "Save Video">
<!ENTITY contextShareVideo.label "Share Video">
<!ENTITY contextEditBookmark.label "Edit">
<!ENTITY contextRemoveBookmark.label "Remove">
--- a/mobile/locales/en-US/chrome/browser.properties
+++ b/mobile/locales/en-US/chrome/browser.properties
@@ -142,17 +142,10 @@ homepage.custom2=Custom Page
# Page Actions
pageactions.saveas.pdf=Save As PDF
pageactions.geo=Location
pageactions.popup=Popups
pageactions.offline-app=Offline Storage
pageactions.password=Password
-# Helper App Dialog (Save/Open)
-helperApp.title=Opening File
-helperApp.prompt=What would you like to do with:
-helperApp.open=Open
-helperApp.save=Save
-helperApp.nothing=Nothing
-
# Open Search
opensearch.searchWith=Search With:
--- a/mobile/themes/core/browser.css
+++ b/mobile/themes/core/browser.css
@@ -1535,29 +1535,33 @@ pageaction:hover:active > vbox > .pageac
-moz-border-radius: 8px;
}
#menulist-popup > label:not([value=""]) + #menulist-commands {
-moz-border-radius-topleft: 0px;
-moz-border-radius-topright: 0px;
}
-.menulist-command {
+.menulist-command,
+.menulist-command[selected] {
-moz-box-align: center;
background-color: rgb(245,245,245);
min-width: 200px; /* keep the command from being too narrow */
}
.menulist-command > image {
width: 32px;
height: 32px;
}
.menulist-command:first-child {
background: -moz-linear-gradient(top, rgb(255,255,255), rgb(245,245,245));
+}
+
+#menulist-popup > #menulist-title[value=""] + #menulist-commands > .menulist-command:first-child {
-moz-border-radius: 8px 8px 0 0;
}
.menulist-command:last-child {
background: -moz-linear-gradient(top, rgb(245,245,245), rgb(215,215,215));
-moz-border-radius: 0 0 8px 8px;
}