diff --git a/mobile/app/Makefile.in b/mobile/app/Makefile.in
index ace34ad00830..69cc75f27a67 100644
--- a/mobile/app/Makefile.in
+++ b/mobile/app/Makefile.in
@@ -42,6 +42,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
+DIRS = profile/extensions
+
PREF_JS_EXPORTS = $(srcdir)/mobile.js
DIST_FILES = application.ini
diff --git a/mobile/app/profile/extensions/Makefile.in b/mobile/app/profile/extensions/Makefile.in
new file mode 100644
index 000000000000..cfb83eeb08d0
--- /dev/null
+++ b/mobile/app/profile/extensions/Makefile.in
@@ -0,0 +1,59 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation .
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Finkle
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/rules.mk
+
+ifeq (beta,$(MOZ_UPDATE_CHANNEL))
+EXTENSIONS = \
+ feedback@mobile.mozilla.org \
+ $(NULL)
+
+define _INSTALL_EXTENSIONS
+$(PYTHON) $(topsrcdir)/config/nsinstall.py $(wildcard $(srcdir)/$(dir)/*) $(DIST)/bin/extensions/$(dir)
+
+endef # do not remove the blank line!
+
+libs::
+ $(foreach dir,$(EXTENSIONS),$(_INSTALL_EXTENSIONS))
+endif
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/chrome.manifest b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/chrome.manifest
new file mode 100644
index 000000000000..49bb5554d98f
--- /dev/null
+++ b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/chrome.manifest
@@ -0,0 +1,5 @@
+content feedback content/
+skin feedback classic/1.0 skin/
+locale feedback en-US locale/en-US/
+
+overlay chrome://browser/content/browser.xul chrome://feedback/content/overlay.xul
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.js b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.js
new file mode 100644
index 000000000000..136e7157abc8
--- /dev/null
+++ b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.js
@@ -0,0 +1,84 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Feedback.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Finkle
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var Feedback = {
+ init: function(aEvent) {
+ let appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
+ document.getElementById("feedback-about").setAttribute("desc", appInfo.version);
+ },
+
+ openReadme: function() {
+ let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
+ let url = formatter.formatURLPref("app.releaseNotesURL");
+ BrowserUI.newTab(url);
+ },
+
+ updateRestart: function updateRestart() {
+ let msg = document.getElementById("feedback-messages");
+ if (msg) {
+ let strings = Elements.browserBundle;
+
+ let value = "restart-app";
+ let notification = msg.getNotificationWithValue(value);
+ if (notification)
+ return;
+
+ let restartCallback = function(aNotification, aDescription) {
+ // Notify all windows that an application quit has been requested
+ var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
+ Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
+
+ // If nothing aborted, quit the app
+ if (cancelQuit.data == false) {
+ let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
+ appStartup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
+ }
+ };
+
+ let buttons = [ {
+ label: strings.getString("notificationRestart.button"),
+ accessKey: "",
+ callback: restartCallback
+ } ];
+
+ let message = strings.getString("notificationRestart.normal");
+ msg.appendNotification(message, value, "", msg.PRIORITY_WARNING_LOW, buttons);
+ }
+ }
+};
+
+window.addEventListener("load", Feedback.init, false);
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.xul b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.xul
new file mode 100644
index 000000000000..76986120d9d1
--- /dev/null
+++ b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.xul
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+%feedbackDTD;
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/install.rdf b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/install.rdf
new file mode 100644
index 000000000000..05b28bae65f1
--- /dev/null
+++ b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/install.rdf
@@ -0,0 +1,26 @@
+
+
+
+
+ feedback@mobile.mozilla.org
+ 1.0.0
+ 2
+
+
+
+
+ {a23983c0-fd0e-11dc-95ff-0800200c9a66}
+ 2.0b1pre
+ 2.*
+
+
+
+
+ Beta Tester Tools
+ Help make Firefox better by giving feedback.
+ Mozilla Corporation
+ chrome://feedback/skin/dino-32.png
+
+
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/locale/en-US/overlay.dtd b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/locale/en-US/overlay.dtd
new file mode 100644
index 000000000000..82e0aedcbf48
--- /dev/null
+++ b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/locale/en-US/overlay.dtd
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/beta-32.png b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/beta-32.png
new file mode 100644
index 000000000000..1f047258fc9c
Binary files /dev/null and b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/beta-32.png differ
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/dino-32.png b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/dino-32.png
new file mode 100644
index 000000000000..35b3a174a558
Binary files /dev/null and b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/dino-32.png differ
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/happy-32.png b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/happy-32.png
new file mode 100644
index 000000000000..49e38c58680a
Binary files /dev/null and b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/happy-32.png differ
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/overlay.css b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/overlay.css
new file mode 100644
index 000000000000..1bf07658e280
--- /dev/null
+++ b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/overlay.css
@@ -0,0 +1,16 @@
+#tool-feedback {
+ list-style-image: url("chrome://feedback/skin/beta-32.png");
+}
+
+#tool-feedback[checked="true"] {
+ -moz-border-image: url("chrome://browser/skin/images/toggledarkboth-active-64.png") 10 repeat repeat;
+}
+
+
+#feedback-feedback-happy {
+ list-style-image: url("chrome://feedback/skin/happy-32.png");
+}
+
+#feedback-feedback-sad {
+ list-style-image: url("chrome://feedback/skin/sad-32.png");
+}
diff --git a/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/sad-32.png b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/sad-32.png
new file mode 100644
index 000000000000..a59db1ffbf43
Binary files /dev/null and b/mobile/app/profile/extensions/feedback@mobile.mozilla.org/skin/sad-32.png differ
diff --git a/mobile/chrome/content/bindings.xml b/mobile/chrome/content/bindings.xml
index 77727e948d69..eb8742ebce47 100644
--- a/mobile/chrome/content/bindings.xml
+++ b/mobile/chrome/content/bindings.xml
@@ -13,7 +13,7 @@
-
+
-
+
diff --git a/mobile/chrome/content/browser-ui.js b/mobile/chrome/content/browser-ui.js
index 2ee00892127d..4da8de9f548f 100644
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -2497,11 +2497,11 @@ var BadgeHandlers = {
_lastUpdate: 0,
_lastCount: 0,
url: "http://mail.google.com",
- updateBadge: function(aItem) {
+ updateBadge: function(aBadge) {
// Use the cache if possible
let now = Date.now();
if (this._lastCount && this._lastUpdate > now - 1000) {
- aItem.setAttribute("badge", this._lastCount);
+ aBadge.set(this._lastCount);
return;
}
@@ -2523,7 +2523,7 @@ var BadgeHandlers = {
} else {
this._lastCount = 0;
}
- this._lastCount = BadgeHandlers.setNumberBadge(aItem, this._lastCount);
+ this._lastCount = BadgeHandlers.setNumberBadge(aBadge, this._lastCount);
}
};
req.send(null);
@@ -2551,12 +2551,12 @@ var BadgeHandlers = {
return aValue;
},
- setNumberBadge: function(aItem, aValue) {
+ setNumberBadge: function(aBadge, aValue) {
if (parseInt(aValue) != 0) {
aValue = this.clampBadge(aValue);
- aItem.setAttribute("badge", aValue);
+ aBadge.set(aValue);
} else {
- aItem.removeAttribute("badge");
+ aBadge.set("");
}
return aValue;
}
diff --git a/mobile/chrome/content/downloads.js b/mobile/chrome/content/downloads.js
index e0bbc7d942af..80b796edf6b5 100644
--- a/mobile/chrome/content/downloads.js
+++ b/mobile/chrome/content/downloads.js
@@ -73,23 +73,26 @@ var DownloadsView = {
},
_createItem: function dv__createItem(aAttrs) {
- let item = document.createElement("richlistitem");
-
- // Copy the attributes from the argument into the item
- for (let attr in aAttrs)
- item.setAttribute(attr, aAttrs[attr]);
-
- // Initialize other attributes
- item.setAttribute("typeName", "download");
- item.setAttribute("id", "dl-" + aAttrs.id);
- item.setAttribute("downloadID", aAttrs.id);
- item.setAttribute("iconURL", "moz-icon://" + aAttrs.file + "?size=32");
- item.setAttribute("lastSeconds", Infinity);
-
- // Initialize more complex attributes
- this._updateTime(item);
- this._updateStatus(item);
+ // Make sure this doesn't already exist
+ let item = this.getElementForDownload(aAttrs.id);
+ if (!item) {
+ item = document.createElement("richlistitem");
+ // Copy the attributes from the argument into the item
+ for (let attr in aAttrs)
+ item.setAttribute(attr, aAttrs[attr]);
+
+ // Initialize other attributes
+ item.setAttribute("typeName", "download");
+ item.setAttribute("id", "dl-" + aAttrs.id);
+ item.setAttribute("downloadID", aAttrs.id);
+ item.setAttribute("iconURL", "moz-icon://" + aAttrs.file + "?size=32");
+ item.setAttribute("lastSeconds", Infinity);
+
+ // Initialize more complex attributes
+ this._updateTime(item);
+ this._updateStatus(item);
+ }
return item;
},
@@ -370,11 +373,14 @@ var DownloadsView = {
removeDownload: function dv_removeDownload(aItem) {
this._dlmgr.removeDownload(aItem.getAttribute("downloadID"));
+ let f = this._getLocalFile(aItem.getAttribute("file"));
+ if (f.exists())
+ f.remove(false);
},
cancelDownload: function dv_cancelDownload(aItem) {
this._dlmgr.cancelDownload(aItem.getAttribute("downloadID"));
- var f = this._getLocalFile(aItem.getAttribute("file"));
+ let f = this._getLocalFile(aItem.getAttribute("file"));
if (f.exists())
f.remove(false);
},
diff --git a/mobile/chrome/content/forms.js b/mobile/chrome/content/forms.js
index 7093d6bbdc43..8c821be172f7 100644
--- a/mobile/chrome/content/forms.js
+++ b/mobile/chrome/content/forms.js
@@ -65,9 +65,8 @@ function FormAssistant() {
addMessageListener("FormAssist:AutoComplete", this);
addEventListener("keyup", this, false);
-
- // change on rotation/resize
addEventListener("resize", this, false);
+ addEventListener("focus", this, true);
};
FormAssistant.prototype = {
@@ -189,54 +188,60 @@ FormAssistant.prototype = {
if (!this._enabled || !this.currentElement)
return;
- // change zoom on resize/rotation
- if (aEvent.type == "resize") {
- sendAsyncMessage("FormAssist:Resize");
- } else {
- let currentElement = this.currentElement;
- switch (aEvent.keyCode) {
- case aEvent.DOM_VK_DOWN:
- if (currentElement instanceof HTMLInputElement && !this._isAutocomplete(currentElement)) {
- if (this._hasKeyListener(currentElement))
- return;
- }
- else if (currentElement instanceof HTMLTextAreaElement) {
- let existSelection = currentElement.selectionEnd - currentElement.selectionStart;
- let isEnd = (currentElement.textLength == currentElement.selectionEnd);
- if (!isEnd || existSelection)
- return;
- }
+ switch (aEvent.type) {
+ case "resize":
+ sendAsyncMessage("FormAssist:Resize");
+ break;
+ case "focus":
+ let focusedIndex = this._getIndexForElement(gFocusManager.focusedElement);
+ if (focusedIndex != -1 && this.currentIndex != focusedIndex)
+ this.currentIndex = focusedIndex;
+ break;
+ case "keyup":
+ let currentElement = this.currentElement;
+ switch (aEvent.keyCode) {
+ case aEvent.DOM_VK_DOWN:
+ if (currentElement instanceof HTMLInputElement && !this._isAutocomplete(currentElement)) {
+ if (this._hasKeyListener(currentElement))
+ return;
+ }
+ else if (currentElement instanceof HTMLTextAreaElement) {
+ let existSelection = currentElement.selectionEnd - currentElement.selectionStart;
+ let isEnd = (currentElement.textLength == currentElement.selectionEnd);
+ if (!isEnd || existSelection)
+ return;
+ }
- this.currentIndex++;
- break;
+ this.currentIndex++;
+ break;
- case aEvent.DOM_VK_UP:
- if (currentElement instanceof HTMLInputElement && !this._isAutocomplete(currentElement)) {
- if (this._hasKeyListener(currentElement))
- return;
- }
- else if (currentElement instanceof HTMLTextAreaElement) {
- let existSelection = currentElement.selectionEnd - currentElement.selectionStart;
- let isStart = (currentElement.selectionEnd == 0);
- if (!isStart || existSelection)
- return;
- }
+ case aEvent.DOM_VK_UP:
+ if (currentElement instanceof HTMLInputElement && !this._isAutocomplete(currentElement)) {
+ if (this._hasKeyListener(currentElement))
+ return;
+ }
+ else if (currentElement instanceof HTMLTextAreaElement) {
+ let existSelection = currentElement.selectionEnd - currentElement.selectionStart;
+ let isStart = (currentElement.selectionEnd == 0);
+ if (!isStart || existSelection)
+ return;
+ }
- this.currentIndex--;
- break;
+ this.currentIndex--;
+ break;
- case aEvent.DOM_VK_RETURN:
- break;
+ case aEvent.DOM_VK_RETURN:
+ break;
- default:
- if (this._isAutocomplete(aEvent.target))
- sendAsyncMessage("FormAssist:AutoComplete", this._getJSON());
- break;
- }
+ default:
+ if (this._isAutocomplete(aEvent.target))
+ sendAsyncMessage("FormAssist:AutoComplete", this._getJSON());
+ break;
+ }
- let caretRect = this._getCaretRect();
- if (!caretRect.isEmpty())
- sendAsyncMessage("FormAssist:Update", { caretRect: caretRect });
+ let caretRect = this._getCaretRect();
+ if (!caretRect.isEmpty())
+ sendAsyncMessage("FormAssist:Update", { caretRect: caretRect });
}
},
@@ -381,16 +386,20 @@ FormAssistant.prototype = {
elements = elements.sort(orderByTabIndex);
// retrieve the correct index
- let currentIndex = -1;
- for (let i = 0; i < elements.length; i++) {
- if (elements[i] == aElement) {
- currentIndex = i;
- break;
- }
- }
+ let currentIndex = this._getIndexForElement(aElement);
return currentIndex;
},
+ _getIndexForElement: function(aElement) {
+ let currentIndex = -1;
+ let elements = this._elements;
+ for (let i = 0; i < elements.length; i++) {
+ if (elements[i] == aElement)
+ return i;
+ }
+ return -1;
+ },
+
_getJSON: function() {
let element = this.currentElement;
let list = getListForElement(element);
diff --git a/mobile/components/AutoCompleteCache.js b/mobile/components/AutoCompleteCache.js
index a7b54f0bd0b8..effa8e476882 100644
--- a/mobile/components/AutoCompleteCache.js
+++ b/mobile/components/AutoCompleteCache.js
@@ -208,6 +208,7 @@ var AutoCompleteUtils = {
// Add back functions to the result
result.getValueAt = function(index) this.data[index][0];
+ result.getLabelAt = function(index) this.data[index][0];
result.getCommentAt = function(index) this.data[index][1];
result.getStyleAt = function(index) this.data[index][2];
result.getImageAt = function(index) this.data[index][3];
diff --git a/mobile/components/ContentPermissionPrompt.js b/mobile/components/ContentPermissionPrompt.js
index 8c203c00975f..cd2b80014f9a 100644
--- a/mobile/components/ContentPermissionPrompt.js
+++ b/mobile/components/ContentPermissionPrompt.js
@@ -7,6 +7,28 @@ Cu.import("resource://gre/modules/Services.jsm");
const kCountBeforeWeRemember = 5;
+function setPagePermission(type, uri, allow) {
+ let pm = Services.perms;
+ let contentPrefs = Services.contentPrefs;
+ let contentPrefName = type + ".request.remember";
+
+ if (!contentPrefs.hasPref(uri, contentPrefName))
+ contentPrefs.setPref(uri, contentPrefName, 0);
+
+ let count = contentPrefs.getPref(uri, contentPrefName);
+
+ if (allow == false)
+ count--;
+ else
+ count++;
+
+ contentPrefs.setPref(uri, contentPrefName, count);
+ if (count == kCountBeforeWeRemember)
+ pm.add(uri, type, Ci.nsIPermissionManager.ALLOW_ACTION);
+ else if (count == -kCountBeforeWeRemember)
+ pm.add(uri, type, Ci.nsIPermissionManager.DENY_ACTION);
+}
+
function ContentPermissionPrompt() {}
ContentPermissionPrompt.prototype = {
@@ -14,97 +36,80 @@ ContentPermissionPrompt.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
- prompt: function(aRequest) {
- if (aRequest.type != "geolocation")
- return;
+ getChromeWindow: function getChromeWindow(aWindow) {
+ let chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .QueryInterface(Ci.nsIDOMChromeWindow);
+ return chromeWin;
+ },
+
+ getNotificationBoxForRequest: function getNotificationBoxForRequest(request) {
+ let notificationBox = null;
+ if (request.window) {
+ let requestingWindow = request.window.top;
+ let chromeWin = this.getChromeWindow(requestingWindow).wrappedJSObject;
+ return chromeWin.getNotificationBox(requestingWindow);
+ }
+
+ let chromeWin = request.element.ownerDocument.defaultView;
+ return chromeWin.Browser.getNotificationBox();
+ },
+
+ handleExistingPermission: function handleExistingPermission(request) {
+ let result = Services.perms.testExactPermission(request.uri, request.type);
+ if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
+ request.allow();
+ return true;
+ }
+ if (result == Ci.nsIPermissionManager.DENY_ACTION) {
+ request.cancel();
+ return true;
+ }
+ return false;
+ },
+
+ prompt: function(request) {
+ // returns true if the request was handled
+ if (this.handleExistingPermission(request))
+ return;
let pm = Services.perms;
- let result = pm.testExactPermission(aRequest.uri, "geo");
-
- if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
- aRequest.allow();
+ let notificationBox = this.getNotificationBoxForRequest(request);
+ let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+
+ let notification = notificationBox.getNotificationWithValue(request.type);
+ if (notification)
return;
- } else if (result == Ci.nsIPermissionManager.DENY_ACTION) {
- aRequest.cancel();
- return;
- }
- function setPagePermission(aUri, aAllow) {
- let contentPrefs = Services.contentPrefs;
+ let buttons = [{
+ label: browserBundle.GetStringFromName(request.type + ".allow"),
+ accessKey: null,
+ callback: function(notification) {
+ setPagePermission(request.type, request.uri, true);
+ request.allow();},
+ },
+ {
+ label: browserBundle.GetStringFromName(request.type + ".dontAllow"),
+ accessKey: null,
+ callback: function(notification) {
+ setPagePermission(request.type, request.uri, false);
+ request.cancel();},
+ }];
- if (!contentPrefs.hasPref(aRequest.uri, "geo.request.remember"))
- contentPrefs.setPref(aRequest.uri, "geo.request.remember", 0);
+ let message = browserBundle.formatStringFromName(request.type + ".siteWantsTo",
+ [request.uri.host], 1);
+ let newBar = notificationBox.appendNotification(message,
+ request.type,
+ "", // Notifications in Fennec do not display images.
+ notificationBox.PRIORITY_WARNING_MEDIUM,
+ buttons);
+ return;
+ },
- let count = contentPrefs.getPref(aRequest.uri, "geo.request.remember");
-
- if (aAllow == false)
- count--;
- else
- count++;
-
- contentPrefs.setPref(aRequest.uri, "geo.request.remember", count);
-
- if (count == kCountBeforeWeRemember)
- pm.add(aUri, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
- else if (count == -kCountBeforeWeRemember)
- pm.add(aUri, "geo", Ci.nsIPermissionManager.DENY_ACTION);
- }
-
- function getChromeWindow(aWindow) {
- let chromeWin = aWindow
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow)
- .QueryInterface(Ci.nsIDOMChromeWindow);
- return chromeWin;
- }
-
- let notificationBox = null;
- if (aRequest.window) {
- let requestingWindow = aRequest.window.top;
- let chromeWin = getChromeWindow(requestingWindow).wrappedJSObject;
- notificationBox = chromeWin.getNotificationBox(requestingWindow);
- } else {
- let chromeWin = aRequest.element.ownerDocument.defaultView;
- notificationBox = chromeWin.Browser.getNotificationBox();
- }
-
- let notification = notificationBox.getNotificationWithValue("geolocation");
- if (!notification) {
- let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
-
- let buttons = [{
- label: browserBundle.GetStringFromName("geolocation.share"),
- accessKey: null,
- callback: function(notification) {
- setPagePermission(aRequest.uri, true);
- aRequest.allow();
- },
- },
- {
- label: browserBundle.GetStringFromName("geolocation.dontShare"),
- accessKey: null,
- callback: function(notification) {
- setPagePermission(aRequest.uri, false);
- aRequest.cancel();
- },
- }];
-
- let message = browserBundle.formatStringFromName("geolocation.siteWantsToKnow",
- [aRequest.uri.host], 1);
-
- let newBar = notificationBox.appendNotification(message,
- "geolocation",
- "chrome://browser/skin/images/geo-16.png",
- notificationBox.PRIORITY_WARNING_MEDIUM,
- buttons);
- // Make this a geolocation notification.
- newBar.setAttribute("type", "geo");
- }
- }
};
diff --git a/mobile/components/FormAutoComplete.js b/mobile/components/FormAutoComplete.js
index 32759d75e94d..e823a7c47550 100644
--- a/mobile/components/FormAutoComplete.js
+++ b/mobile/components/FormAutoComplete.js
@@ -139,8 +139,10 @@ FormAutoComplete.prototype = {
},
autoCompleteSearch: function autoCompleteSearch(aName, aQuery, aField, aPrev) {
- LOG("autocomplete search", Array.slice(arguments));
+ if (!Services.prefs.getBoolPref("browser.formfill.enable"))
+ return;
+ LOG("autocomplete search", Array.slice(arguments));
let result = Cc["@mozilla.org/autocomplete/simple-result;1"].createInstance(Ci.nsIAutoCompleteSimpleResult);
result.setSearchString(aQuery);
diff --git a/mobile/components/LoginManager.js b/mobile/components/LoginManager.js
index 2e0265c95401..85193080812c 100644
--- a/mobile/components/LoginManager.js
+++ b/mobile/components/LoginManager.js
@@ -684,6 +684,10 @@ UserAutoCompleteResult.prototype = {
return this.logins[index].username;
},
+ getLabelAt : function (index) {
+ return this.getValueAt(index);
+ },
+
getCommentAt : function (index) {
return "";
},
diff --git a/mobile/components/MobileComponents.manifest b/mobile/components/MobileComponents.manifest
index fa6dd93b5e31..87b326a7467d 100644
--- a/mobile/components/MobileComponents.manifest
+++ b/mobile/components/MobileComponents.manifest
@@ -42,6 +42,7 @@ component {C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5} ContentPermissionPrompt.js
contract @mozilla.org/content-permission/prompt;1 {C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}
# AlertsService.js
+
component {fe33c107-82a4-41d6-8c64-5353267e04c9} AlertsService.js
contract @mozilla.org/system-alerts-service;1 {fe33c107-82a4-41d6-8c64-5353267e04c9}
diff --git a/mobile/locales/en-US/chrome/browser.properties b/mobile/locales/en-US/chrome/browser.properties
index 2bf4fbf441ef..762bc543047a 100644
--- a/mobile/locales/en-US/chrome/browser.properties
+++ b/mobile/locales/en-US/chrome/browser.properties
@@ -122,9 +122,14 @@ identity.unknown.tooltip=This web site does not supply identity information.
identity.ownerUnknown2=(unknown)
# Geolocation UI
-geolocation.share=Share
-geolocation.dontShare=Don't share
-geolocation.siteWantsToKnow=%S wants your location.
+geolocation.allow=Share
+geolocation.dontAllow=Don't share
+geolocation.siteWantsTo=%S wants your location.
+
+# Desktop notification UI
+desktop-notification.allow=Allow
+desktop-notification.dontAllow=Don't allow
+desktop-notification.siteWantsTo=%S wants use notifications.
# New Tab Popup
# LOCALIZATION NOTE (newtabpopup): Semi-colon list of plural forms.
diff --git a/mobile/makefiles.sh b/mobile/makefiles.sh
index 11c8a353d385..92eb63d75387 100644
--- a/mobile/makefiles.sh
+++ b/mobile/makefiles.sh
@@ -41,6 +41,7 @@ dom/locales/Makefile
toolkit/locales/Makefile
security/manager/locales/Makefile
mobile/app/Makefile
+mobile/app/profile/extensions/Makefile
$MOZ_BRANDING_DIRECTORY/Makefile
$MOZ_BRANDING_DIRECTORY/locales/Makefile
mobile/chrome/Makefile
diff --git a/mobile/themes/core/browser.css b/mobile/themes/core/browser.css
index d696ebf3c422..7e58ed467005 100644
--- a/mobile/themes/core/browser.css
+++ b/mobile/themes/core/browser.css
@@ -693,49 +693,6 @@ placeitem[ui="manage"] > .bookmark-manage > image {
visibility: collapse;
}
-.tool-search {
- list-style-image: url("chrome://browser/skin/images/navigation-magnifier-30.png");
- -moz-margin-end: 8px;
-}
-
-.searchengine {
- -moz-box-orient: horizontal;
- min-width: 140px !important;
-}
-
-.searchengine .radio-icon {
- display: block;
- width: 32px;
- height: 32px;
- -moz-margin-end: 8px;
-}
-
-#autocomplete_navbuttons {
- padding: 4px 0; /* half core spacing & none (autorepeat arrows compensate) */
-}
-
-#autocomplete_navbuttons .autorepeatbutton-down {
- list-style-image: url(images/arrowrightdark-16.png);
-}
-
-#autocomplete_navbuttons .autorepeatbutton-down:-moz-locale-dir(rtl) {
- list-style-image: url(images/arrowleftdark-16.png);
-}
-
-#autocomplete_navbuttons .autorepeatbutton-up {
- list-style-image: url(images/arrowleftdark-16.png);
-}
-
-#autocomplete_navbuttons .autorepeatbutton-up:-moz-locale-dir(rtl) {
- list-style-image: url(images/arrowrightdark-16.png);
-}
-
-/* force the autorepeat buttons to create a 'padding' when collapsed */
-#autocomplete_navbuttons autorepeatbutton[collapsed="true"],
-#autocomplete_navbuttons autorepeatbutton[disabled="true"] {
- visibility: hidden;
-}
-
.autocomplete-items {
background-color: white;
}
@@ -855,7 +812,9 @@ autocompleteresult[class="remotetabs-item-title"] {
}
autocompleteresult[class="history-item-title"] .bookmark-item-url,
-autocompleteresult[class="remotetabs-item-title"] .bookmark-item-url {
+autocompleteresult[class="history-item-title"] .autocomplete-item-tags,
+autocompleteresult[class="remotetabs-item-title"] .bookmark-item-url,
+autocompleteresult[class="remotetabs-item-title"] .autocomplete-item-tags {
display: none;
}
diff --git a/mobile/themes/core/images/geo-16.png b/mobile/themes/core/images/geo-16.png
deleted file mode 100644
index 9ae4c5a25748..000000000000
Binary files a/mobile/themes/core/images/geo-16.png and /dev/null differ
diff --git a/mobile/themes/core/jar.mn b/mobile/themes/core/jar.mn
index 5f24dcdd3bca..993ee6362263 100644
--- a/mobile/themes/core/jar.mn
+++ b/mobile/themes/core/jar.mn
@@ -140,4 +140,3 @@ chrome.jar:
skin/images/task-close-40.png (images/task-close-40.png)
skin/images/task-back-40.png (images/task-back-40.png)
skin/images/task-back-rtl-40.png (images/task-back-rtl-40.png)
- skin/images/geo-16.png (images/geo-16.png)