diff --git a/CLOBBER b/CLOBBER
index 37b2285a1c32..d15932f19fab 100644
--- a/CLOBBER
+++ b/CLOBBER
@@ -22,9 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
-Bug 1105308 - Cleanup BluetoothUtils.{cpp,h}
-
-This patch set moves some files around and requires a rebuild
-of the build system's dependency information.
-
-Merge day clobber
+Bug 1066383 - Clobber needed due to build system not reliably picking up an IDL removal.
diff --git a/b2g/components/LogShake.jsm b/b2g/components/LogShake.jsm
index 7fd4a0fd494c..2da6506ed8b0 100644
--- a/b2g/components/LogShake.jsm
+++ b/b2g/components/LogShake.jsm
@@ -262,12 +262,16 @@ function getSdcardPrefix() {
return volumeService.getVolumeByName('sdcard').mountPoint;
}
+function getLogDirectoryRoot() {
+ return 'logs';
+}
+
function getLogDirectory() {
let d = new Date();
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000);
let timestamp = d.toISOString().slice(0, -5).replace(/[:T]/g, '-');
// return directory name of format 'logs/timestamp/'
- return OS.Path.join('logs', timestamp);
+ return timestamp;
}
/**
@@ -281,9 +285,10 @@ function saveLogs(logArrays) {
});
}
- let sdcardPrefix, dirName;
+ let sdcardPrefix, dirNameRoot, dirName;
try {
sdcardPrefix = getSdcardPrefix();
+ dirNameRoot = getLogDirectoryRoot();
dirName = getLogDirectory();
} catch(e) {
// Return promise failed with exception e
@@ -291,33 +296,39 @@ function saveLogs(logArrays) {
return Promise.reject(e);
}
- debug('making a directory all the way from '+sdcardPrefix+' to '+(sdcardPrefix + '/' + dirName));
- return OS.File.makeDir(OS.Path.join(sdcardPrefix, dirName), {from: sdcardPrefix})
- .then(function() {
- // Now the directory is guaranteed to exist, save the logs
- let logFilenames = [];
- let saveRequests = [];
+ debug('making a directory all the way from '+sdcardPrefix+' to '+(sdcardPrefix + '/' + dirNameRoot + '/' + dirName));
+ let logsRoot = OS.Path.join(sdcardPrefix, dirNameRoot);
+ return OS.File.makeDir(logsRoot, {from: sdcardPrefix}).then(
+ function() {
+ let logsDir = OS.Path.join(logsRoot, dirName);
+ return OS.File.makeDir(logsDir, {ignoreExisting: false}).then(
+ function() {
+ // Now the directory is guaranteed to exist, save the logs
+ let logFilenames = [];
+ let saveRequests = [];
- for (let logLocation in logArrays) {
- debug('requesting save of ' + logLocation);
- let logArray = logArrays[logLocation];
- // The filename represents the relative path within the SD card, not the
- // absolute path because Gaia will refer to it using the DeviceStorage
- // API
- let filename = OS.Path.join(dirName, getLogFilename(logLocation));
- logFilenames.push(filename);
- let saveRequest = OS.File.writeAtomic(OS.Path.join(sdcardPrefix, filename), logArray);
- saveRequests.push(saveRequest);
- }
+ for (let logLocation in logArrays) {
+ debug('requesting save of ' + logLocation);
+ let logArray = logArrays[logLocation];
+ // The filename represents the relative path within the SD card, not the
+ // absolute path because Gaia will refer to it using the DeviceStorage
+ // API
+ let filename = OS.Path.join(dirNameRoot, dirName, getLogFilename(logLocation));
+ logFilenames.push(filename);
+ let saveRequest = OS.File.writeAtomic(OS.Path.join(sdcardPrefix, filename), logArray);
+ saveRequests.push(saveRequest);
+ }
- return Promise.all(saveRequests).then(function() {
- debug('returning logfilenames: '+logFilenames.toSource());
- return {
- logFilenames: logFilenames,
- logPrefix: dirName
- };
+ return Promise.all(saveRequests).then(
+ function() {
+ debug('returning logfilenames: '+logFilenames.toSource());
+ return {
+ logFilenames: logFilenames,
+ logPrefix: OS.Path.join(dirNameRoot, dirName)
+ };
+ });
+ });
});
- });
}
LogShake.init();
diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 4d97b2b66713..e30db4ea6c80 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -12,10 +12,10 @@
-
+
-
+
@@ -113,7 +113,7 @@
-
+
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index b8e313a63f1b..3e01ee2c593d 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 32afd2fa4ce0..05f78ea89633 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 6cf8daedb49d..84d94e8a5902 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -12,10 +12,10 @@
-
+
-
+
@@ -113,7 +113,7 @@
-
+
@@ -130,7 +130,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index b8e313a63f1b..3e01ee2c593d 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 07b0daa266cc..16389265c201 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -12,10 +12,10 @@
-
+
-
+
@@ -113,7 +113,7 @@
-
+
@@ -137,9 +137,11 @@
-
+
+
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index c187faaddb84..33f051fbb55d 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 268db5789540..579ec00f4971 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
- "revision": "24f27472ae6ddb6c819227cb3b7d398a6925ef86",
+ "revision": "b60aedd37a5ccdb71893d31761988bcc17a82676",
"repo_path": "integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index c3ccf6c249a8..f5626e39599b 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 4befdd30e25e..3509fad831b5 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 413f4e5dc31d..0d6d16d4654b 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 29a9290d3b16..6fd6417cb997 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in
index 59ace3c21438..024bbc6d7b06 100644
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -401,6 +401,8 @@
@BINPATH@/components/nsSidebar.js
@BINPATH@/components/nsAsyncShutdown.manifest
@BINPATH@/components/nsAsyncShutdown.js
+@BINPATH@/components/htmlMenuBuilder.js
+@BINPATH@/components/htmlMenuBuilder.manifest
; WiFi, NetworkManager, NetworkStats
#ifdef MOZ_WIDGET_GONK
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index d6e4b1de03a3..c886033e57ed 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -259,10 +259,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
"nsICrashReporter");
#endif
-XPCOMUtils.defineLazyGetter(this, "PageMenu", function() {
+XPCOMUtils.defineLazyGetter(this, "PageMenuParent", function() {
let tmp = {};
Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
- return new tmp.PageMenu();
+ return new tmp.PageMenuParent();
});
/**
diff --git a/browser/base/content/content.js b/browser/base/content/content.js
index b2356a6fe4e7..9fc0fd64847e 100644
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -43,6 +43,11 @@ XPCOMUtils.defineLazyGetter(this, "SimpleServiceDiscovery", function() {
});
return ssdp;
});
+XPCOMUtils.defineLazyGetter(this, "PageMenuChild", function() {
+ let tmp = {};
+ Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
+ return new tmp.PageMenuChild();
+});
// TabChildGlobal
var global = this;
@@ -102,6 +107,10 @@ addMessageListener("SecondScreen:tab-mirror", function(message) {
}
});
+addMessageListener("ContextMenu:DoCustomCommand", function(message) {
+ PageMenuChild.executeMenu(message.data);
+});
+
addEventListener("DOMFormHasPassword", function(event) {
InsecurePasswordUtils.checkForInsecurePasswords(event.target);
LoginManagerContent.onFormPassword(event);
@@ -148,7 +157,8 @@ let handleContentContextMenu = function (event) {
InlineSpellCheckerContent.initContextMenu(event, editFlags, this);
}
- sendSyncMessage("contextmenu", { editFlags, spellInfo, addonInfo }, { event, popupNode: event.target });
+ let customMenuItems = PageMenuChild.build(event.target);
+ sendSyncMessage("contextmenu", { editFlags, spellInfo, customMenuItems, addonInfo }, { event, popupNode: event.target });
}
else {
// Break out to the parent window and pass the add-on info along
diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js
index 4dc54af0cdcc..196882fd942f 100644
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -24,10 +24,15 @@ nsContextMenu.prototype = {
return;
this.hasPageMenu = false;
- // FIXME (bug 1047751) - The page menu is disabled in e10s.
- if (!aIsShift && !this.isRemote) {
- this.hasPageMenu = PageMenu.maybeBuildAndAttachMenu(this.target,
- aXulMenu);
+ if (!aIsShift) {
+ if (this.isRemote) {
+ this.hasPageMenu =
+ PageMenuParent.addToPopup(gContextMenuContentData.customMenuItems,
+ this.browser, aXulMenu);
+ }
+ else {
+ this.hasPageMenu = PageMenuParent.buildAndAddToPopup(this.target, aXulMenu);
+ }
}
this.isFrameImage = document.getElementById("isFrameImage");
@@ -1766,7 +1771,7 @@ nsContextMenu.prototype = {
}
// Check if this is a page menu item:
- if (e.target.hasAttribute(PageMenu.GENERATEDITEMID_ATTR)) {
+ if (e.target.hasAttribute(PageMenuParent.GENERATEDITEMID_ATTR)) {
this._telemetryClickID = "custom-page-item";
} else {
this._telemetryClickID = (e.target.id || "unknown").replace(/^context-/i, "");
diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml
index b081551681c6..87d36f9722f0 100644
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3175,6 +3175,7 @@
browser: browser,
editFlags: aMessage.data.editFlags,
spellInfo: spellInfo,
+ customMenuItems: aMessage.data.customMenuItems,
addonInfo: aMessage.data.addonInfo };
let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
let event = gContextMenuContentData.event;
diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini
index 7322e5b95d66..a1232ad10570 100644
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -72,6 +72,7 @@ support-files =
redirect_bug623155.sjs
searchSuggestionEngine.sjs
searchSuggestionEngine.xml
+ subtst_contextmenu.html
test-mixedcontent-securityerrors.html
test_bug435035.html
test_bug462673.html
@@ -486,4 +487,5 @@ skip-if = e10s # bug 1100687 - test directly manipulates content (content.docume
[browser_mcb_redirect.js]
skip-if = e10s # bug 1084504 - [e10s] Mixed content detection does not take redirection into account
[browser_windowactivation.js]
+[browser_contextmenu_childprocess.js]
[browser_bug963945.js]
diff --git a/browser/base/content/test/general/browser_contextmenu_childprocess.js b/browser/base/content/test/general/browser_contextmenu_childprocess.js
new file mode 100644
index 000000000000..c967137919ff
--- /dev/null
+++ b/browser/base/content/test/general/browser_contextmenu_childprocess.js
@@ -0,0 +1,87 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const gBaseURL = "https://example.com/browser/browser/base/content/test/general/";
+
+add_task(function *() {
+ let tab = gBrowser.addTab();
+ let browser = gBrowser.getBrowserForTab(tab);
+
+ gBrowser.selectedTab = tab;
+ yield promiseTabLoadEvent(tab, gBaseURL + "subtst_contextmenu.html");
+
+ let popupShownPromise = promiseWaitForEvent(window, "popupshown", true);
+
+ // Get the point of the element with the page menu (test-pagemenu) and
+ // synthesize a right mouse click there.
+ let eventDetails = { type : "contextmenu", button : 2 };
+ let rect = browser.contentWindow.document.getElementById("test-pagemenu").getBoundingClientRect();
+ EventUtils.synthesizeMouse(browser, rect.x + rect.width / 2, rect.y + rect.height / 2, eventDetails, window);
+
+ let event = yield popupShownPromise;
+
+ let contextMenu = document.getElementById("contentAreaContextMenu");
+ checkMenu(contextMenu);
+ contextMenu.hidePopup();
+ gBrowser.removeCurrentTab();
+});
+
+function checkItems(menuitem, arr)
+{
+ for (let i = 0; i < arr.length; i += 2) {
+ let str = arr[i];
+ let details = arr[i + 1];
+ if (str == "---") {
+ is(menuitem.localName, "menuseparator", "menuseparator");
+ }
+ else if ("children" in details) {
+ is(menuitem.localName, "menu", "submenu");
+ is(menuitem.getAttribute("label"), str, str + " label");
+ checkItems(menuitem.firstChild.firstChild, details.children);
+ }
+ else {
+ is(menuitem.localName, "menuitem", str + " menuitem");
+
+ is(menuitem.getAttribute("label"), str, str + " label");
+ is(menuitem.getAttribute("type"), details.type, str + " type");
+ is(menuitem.getAttribute("image"), details.icon ? gBaseURL + details.icon : "", str + " icon");
+
+ if (details.checked)
+ is(menuitem.getAttribute("checked"), "true", str + " checked");
+ else
+ ok(!menuitem.hasAttribute("checked"), str + " checked");
+
+ if (details.disabled)
+ is(menuitem.getAttribute("disabled"), "true", str + " disabled");
+ else
+ ok(!menuitem.hasAttribute("disabled"), str + " disabled");
+ }
+
+ menuitem = menuitem.nextSibling;
+ }
+}
+
+function checkMenu(contextMenu)
+{
+ let items = [ "Plain item", {type: "", icon: "", checked: false, disabled: false},
+ "Disabled item", {type: "", icon: "", checked: false, disabled: true},
+ "Item w/ textContent", {type: "", icon: "", checked: false, disabled: false},
+ "---", null,
+ "Checkbox", {type: "checkbox", icon: "", checked: true, disabled: false},
+ "---", null,
+ "Radio1", {type: "checkbox", icon: "", checked: true, disabled: false},
+ "Radio2", {type: "checkbox", icon: "", checked: false, disabled: false},
+ "Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
+ "---", null,
+ "Item w/ icon", {type: "", icon: "favicon.ico", checked: false, disabled: false},
+ "Item w/ bad icon", {type: "", icon: "", checked: false, disabled: false},
+ "---", null,
+ "Submenu", { children:
+ ["Radio1", {type: "checkbox", icon: "", checked: false, disabled: false},
+ "Radio2", {type: "checkbox", icon: "", checked: true, disabled: false},
+ "Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
+ "---", null,
+ "Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}] }
+ ];
+ checkItems(contextMenu.childNodes[2], items);
+}
diff --git a/browser/base/content/test/general/test_contextmenu.html b/browser/base/content/test/general/test_contextmenu.html
index edb7c705d502..c87ae2b5c40e 100644
--- a/browser/base/content/test/general/test_contextmenu.html
+++ b/browser/base/content/test/general/test_contextmenu.html
@@ -495,7 +495,7 @@ function runTest(testNum) {
"context-viewinfo", true
].concat(inspectItems));
- invokeItemAction("0");
+ invokeItemAction("1");
closeContextMenu();
// run mozRequestFullScreen on the element we're testing
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index 0feaf0fe704f..a2f944bb616d 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -542,6 +542,8 @@
@RESPATH@/components/Identity.manifest
@RESPATH@/components/recording-cmdline.js
@RESPATH@/components/recording-cmdline.manifest
+@RESPATH@/components/htmlMenuBuilder.js
+@RESPATH@/components/htmlMenuBuilder.manifest
@RESPATH@/components/PermissionSettings.js
@RESPATH@/components/PermissionSettings.manifest
diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in
index 679c3ef0b67e..c7cb1a39413b 100644
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -77,7 +77,7 @@ SEARCHPLUGINS_PATH := $(FINAL_TARGET)/searchplugins
# metro build call a searchplugins target for search engine plugins
.PHONY: searchplugins
SEARCHPLUGINS_TARGET := libs searchplugins
-SEARCHPLUGINS := $(foreach plugin,$(addsuffix .xml,$(SEARCHPLUGINS_NAMES)),$(or $(wildcard $(call MERGE_FILE,searchplugins/$(plugin))),$(info Missing searchplugin: $(plugin))))
+SEARCHPLUGINS := $(foreach plugin,$(addsuffix .xml,$(SEARCHPLUGINS_NAMES)),$(or $(wildcard $(call EN_US_OR_L10N_FILE,searchplugins/$(plugin))),$(info Missing searchplugin: $(plugin))))
# Some locale-specific search plugins may have preprocessor directives, but the
# default en-US ones do not.
SEARCHPLUGINS_FLAGS := --silence-missing-directive-warnings
diff --git a/config/config.mk b/config/config.mk
index 948a71af2092..141dda16fa5f 100644
--- a/config/config.mk
+++ b/config/config.mk
@@ -614,6 +614,13 @@ MERGE_FILE = $(LOCALE_SRCDIR)/$(1)
endif
MERGE_FILES = $(foreach f,$(1),$(call MERGE_FILE,$(f)))
+# These marcros are similar to MERGE_FILE, but no merging, and en-US first.
+# They're used for searchplugins, for example.
+EN_US_OR_L10N_FILE = $(firstword \
+ $(wildcard $(srcdir)/en-US/$(1)) \
+ $(LOCALE_SRCDIR)/$(1) )
+EN_US_OR_L10N_FILES = $(foreach f,$(1),$(call EN_US_OR_L10N_FILE,$(f)))
+
ifneq (WINNT,$(OS_ARCH))
RUN_TEST_PROGRAM = $(LIBXUL_DIST)/bin/run-mozilla.sh
endif # ! WINNT
diff --git a/config/makefiles/xpidl/Makefile.in b/config/makefiles/xpidl/Makefile.in
index 178b7f2168f9..2c2b1b76627b 100644
--- a/config/makefiles/xpidl/Makefile.in
+++ b/config/makefiles/xpidl/Makefile.in
@@ -22,48 +22,39 @@ include $(topsrcdir)/config/rules.mk
# As an optimization to reduce overall CPU usage, we process all .idl
# belonging to a module with a single command invocation. This prevents
# redundant parsing of .idl files and significantly reduces CPU cycles.
-#
-# Future improvement: Headers are currently written to a local directory then
-# installed in the distribution directory. It is preferable to write headers
-# directly into the distribution directory. However, PGO builds remove the dist
-# directory via rm -rf (with no regards to manifests). Since the cost of
-# processing XPIDL files is not trivial, it is preferrable to cache the headers
-# and reinstall them rather than regenerate them. Ideally the dist pruning is
-# performed with manifests. At that time we can write headers directly to the
-# dist directory.
# For dependency files.
idl_deps_dir := .deps
-# Where we put our final, linked .xpt files.
-idl_xpt_dir := xpt
-
dist_idl_dir := $(DIST)/idl
dist_include_dir := $(DIST)/include
process_py := $(topsrcdir)/python/mozbuild/mozbuild/action/xpidl-process.py
-# TODO we should use py_action, but that would require extra directories to be
-# in the virtualenv.
-idlprocess := $(PYTHON_PATH) $(PLY_INCLUDE) -I$(IDL_PARSER_DIR) -I$(IDL_PARSER_CACHE_DIR) \
- $(process_py) --cache-dir $(IDL_PARSER_CACHE_DIR) $(dist_idl_dir) \
- $(dist_include_dir) $(idl_xpt_dir) $(idl_deps_dir)
-
ifdef LIBXUL_SDK
-idlprocess += -I$(LIBXUL_SDK)/idl
+libxul_sdk_includes := -I$(LIBXUL_SDK)/idl
endif
+# TODO we should use py_action, but that would require extra directories to be
+# in the virtualenv.
+%.xpt:
+ @echo "$(@F)"
+ $(PYTHON_PATH) $(PLY_INCLUDE) -I$(IDL_PARSER_DIR) -I$(IDL_PARSER_CACHE_DIR) \
+ $(process_py) --cache-dir $(IDL_PARSER_CACHE_DIR) $(dist_idl_dir) \
+ $(dist_include_dir) $(@D) $(idl_deps_dir) $(libxul_sdk_includes) \
+ $(basename $(notdir $@ $(filter %.idl,$^)))
+
xpidl_modules := @xpidl_modules@
+xpt_files := @xpt_files@
@xpidl_rules@
-linked_xpt_files := $(addprefix $(idl_xpt_dir)/,$(addsuffix .xpt,$(xpidl_modules)))
depends_files := $(foreach root,$(xpidl_modules),$(idl_deps_dir)/$(root).pp)
-GARBAGE += $(linked_xpt_files) $(depends_files)
+GARBAGE += $(xpt_files) $(depends_files)
-xpidl:: $(linked_xpt_files)
+xpidl:: $(xpt_files)
-$(linked_xpt_files): $(process_py) $(call mkdir_deps,$(idl_deps_dir) $(dist_include_dir) $(idl_xpt_dir))
+$(xpt_files): $(process_py) $(call mkdir_deps,$(idl_deps_dir) $(dist_include_dir))
$(call include_deps,$(depends_files))
diff --git a/config/rules.mk b/config/rules.mk
index cec5deec5eeb..f5f21f5a13a4 100644
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1157,11 +1157,6 @@ endif
ifdef XPT_NAME #{
ifndef NO_DIST_INSTALL
-_XPT_NAME_FILES := $(DEPTH)/config/makefiles/xpidl/xpt/$(XPT_NAME)
-_XPT_NAME_DEST := $(FINAL_TARGET)/components
-_XPT_NAME_TARGET := misc
-INSTALL_TARGETS += _XPT_NAME
-
ifndef NO_INTERFACES_MANIFEST
misc:: $(call mkdir_deps,$(FINAL_TARGET)/components)
$(call py_action,buildlist,$(FINAL_TARGET)/components/interfaces.manifest 'interfaces $(XPT_NAME)')
diff --git a/configure.in b/configure.in
index 6d612e1d50e4..26f0ef5ea9e4 100644
--- a/configure.in
+++ b/configure.in
@@ -286,6 +286,7 @@ if test -n "$gonkdir" ; then
21)
GONK_INCLUDES="-I$gonkdir/frameworks/native/include -I$gonkdir/frameworks/av/include -I$gonkdir/frameworks/av/include/media -I$gonkdir/frameworks/av/include/camera -I$gonkdir/frameworks/native/include/media/openmax -I$gonkdir/frameworks/av/media/libstagefright/include"
MOZ_AUDIO_OFFLOAD=1
+ MOZ_OMX_DECODER=1
AC_SUBST(MOZ_AUDIO_OFFLOAD)
AC_DEFINE(MOZ_AUDIO_OFFLOAD)
MOZ_FMP4=
diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp
index 5fe40e37cd7a..f1f66db2f044 100644
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -819,7 +819,12 @@ NotifyOffThreadScriptLoadCompletedRunnable::Run()
{
MOZ_ASSERT(NS_IsMainThread());
- nsresult rv = mLoader->ProcessOffThreadRequest(mRequest, &mToken);
+ // We want these to be dropped on the main thread, once we return from this
+ // function.
+ nsRefPtr request = mRequest.forget();
+ nsRefPtr loader = mLoader.forget();
+
+ nsresult rv = loader->ProcessOffThreadRequest(request, &mToken);
if (mToken) {
// The result of the off thread parse was not actually needed to process
diff --git a/dom/bluetooth/BluetoothRilListener.cpp b/dom/bluetooth/BluetoothRilListener.cpp
index 650d3c533e65..998337954873 100644
--- a/dom/bluetooth/BluetoothRilListener.cpp
+++ b/dom/bluetooth/BluetoothRilListener.cpp
@@ -101,13 +101,6 @@ MobileConnectionListener::NotifyDataChanged()
return NS_OK;
}
-NS_IMETHODIMP
-MobileConnectionListener::NotifyUssdReceived(const nsAString & message,
- bool sessionEnded)
-{
- return NS_OK;
-}
-
NS_IMETHODIMP
MobileConnectionListener::NotifyDataError(const nsAString & message)
{
diff --git a/dom/bluetooth2/BluetoothRilListener.cpp b/dom/bluetooth2/BluetoothRilListener.cpp
index 650d3c533e65..998337954873 100644
--- a/dom/bluetooth2/BluetoothRilListener.cpp
+++ b/dom/bluetooth2/BluetoothRilListener.cpp
@@ -101,13 +101,6 @@ MobileConnectionListener::NotifyDataChanged()
return NS_OK;
}
-NS_IMETHODIMP
-MobileConnectionListener::NotifyUssdReceived(const nsAString & message,
- bool sessionEnded)
-{
- return NS_OK;
-}
-
NS_IMETHODIMP
MobileConnectionListener::NotifyDataError(const nsAString & message)
{
diff --git a/dom/html/HTMLMenuElement.cpp b/dom/html/HTMLMenuElement.cpp
index 8553534119f5..a15e7d0ea79f 100644
--- a/dom/html/HTMLMenuElement.cpp
+++ b/dom/html/HTMLMenuElement.cpp
@@ -9,11 +9,13 @@
#include "mozilla/EventDispatcher.h"
#include "mozilla/dom/HTMLMenuElementBinding.h"
#include "mozilla/dom/HTMLMenuItemElement.h"
+#include "nsIMenuBuilder.h"
#include "nsAttrValueInlines.h"
#include "nsContentUtils.h"
-#include "nsXULContextMenuBuilder.h"
#include "nsIURI.h"
+#define HTMLMENUBUILDER_CONTRACTID "@mozilla.org/content/html-menu-builder;1"
+
NS_IMPL_NS_NEW_HTML_ELEMENT(Menu)
namespace mozilla {
@@ -97,12 +99,8 @@ HTMLMenuElement::CreateBuilder(nsIMenuBuilder** _retval)
{
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
- *_retval = nullptr;
-
- if (mType == MENU_TYPE_CONTEXT) {
- NS_ADDREF(*_retval = new nsXULContextMenuBuilder());
- }
-
+ nsCOMPtr builder = CreateBuilder();
+ builder.swap(*_retval);
return NS_OK;
}
@@ -113,8 +111,9 @@ HTMLMenuElement::CreateBuilder()
return nullptr;
}
- nsCOMPtr ret = new nsXULContextMenuBuilder();
- return ret.forget();
+ nsCOMPtr builder = do_CreateInstance(HTMLMENUBUILDER_CONTRACTID);
+ NS_WARN_IF(!builder);
+ return builder.forget();
}
NS_IMETHODIMP
diff --git a/dom/html/htmlMenuBuilder.js b/dom/html/htmlMenuBuilder.js
new file mode 100644
index 000000000000..863fc4d74b13
--- /dev/null
+++ b/dom/html/htmlMenuBuilder.js
@@ -0,0 +1,132 @@
+/* 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 component is used to build the menus for the HTML contextmenu attribute.
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+// A global value that is used to identify each menu item. It is
+// incremented with each one that is found.
+var gGeneratedId = 1;
+
+function HTMLMenuBuilder() {
+ this.currentNode = null;
+ this.root = null;
+ this.items = {};
+ this.nestedStack = [];
+};
+
+// Building is done in two steps:
+// The first generates a hierarchical JS object that contains the menu structure.
+// This object is returned by toJSONString.
+//
+// The second step can take this structure and generate a XUL menu hierarchy or
+// other UI from this object. The default UI is done in PageMenu.jsm.
+//
+// When a multi-process browser is used, the first step is performed by the child
+// process and the second step is performed by the parent process.
+
+HTMLMenuBuilder.prototype =
+{
+ classID: Components.ID("{51c65f5d-0de5-4edc-9058-60e50cef77f8}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIMenuBuilder]),
+
+ currentNode: null,
+ root: null,
+ items: {},
+ nestedStack: [],
+
+ toJSONString: function() {
+ return JSON.stringify(this.root);
+ },
+
+ openContainer: function(aLabel) {
+ if (!this.currentNode) {
+ this.root = {
+ type: "menu",
+ children: []
+ };
+ this.currentNode = this.root;
+ }
+ else {
+ let parent = this.currentNode;
+ this.currentNode = {
+ type: "menu",
+ label: aLabel,
+ children: []
+ };
+ parent.children.push(this.currentNode);
+ this.nestedStack.push(parent);
+ }
+ },
+
+ addItemFor: function(aElement, aCanLoadIcon) {
+ if (!("children" in this.currentNode)) {
+ return;
+ }
+
+ let item = {
+ type: "menuitem",
+ label: aElement.label
+ };
+
+ let elementType = aElement.type;
+ if (elementType == "checkbox" || elementType == "radio") {
+ item.checkbox = true;
+
+ if (aElement.checked) {
+ item.checked = true;
+ }
+ }
+
+ let icon = aElement.icon;
+ if (icon.length > 0 && aCanLoadIcon) {
+ item.icon = icon;
+ }
+
+ if (aElement.disabled) {
+ item.disabled = true;
+ }
+
+ item.id = gGeneratedId++;
+ this.currentNode.children.push(item);
+
+ this.items[item.id] = aElement;
+ },
+
+ addSeparator: function() {
+ if (!("children" in this.currentNode)) {
+ return;
+ }
+
+ this.currentNode.children.push({ type: "separator"});
+ },
+
+ undoAddSeparator: function() {
+ if (!("children" in this.currentNode)) {
+ return;
+ }
+
+ let children = this.currentNode.children;
+ if (children.length && children[children.length - 1].type == "separator") {
+ children.pop();
+ }
+ },
+
+ closeContainer: function() {
+ this.currentNode = this.nestedStack.length ? this.nestedStack.pop() : this.root;
+ },
+
+ click: function(id) {
+ let item = this.items[id];
+ if (item) {
+ item.click();
+ }
+ }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HTMLMenuBuilder]);
diff --git a/dom/html/htmlMenuBuilder.manifest b/dom/html/htmlMenuBuilder.manifest
new file mode 100644
index 000000000000..b245f8fe2de5
--- /dev/null
+++ b/dom/html/htmlMenuBuilder.manifest
@@ -0,0 +1,3 @@
+component {51c65f5d-0de5-4edc-9058-60e50cef77f8} htmlMenuBuilder.js
+contract @mozilla.org/content/html-menu-builder;1 {51c65f5d-0de5-4edc-9058-60e50cef77f8}
+
diff --git a/dom/html/moz.build b/dom/html/moz.build
index cd725e70d2a4..97f6d1799026 100644
--- a/dom/html/moz.build
+++ b/dom/html/moz.build
@@ -215,6 +215,11 @@ SOURCES += [
'PluginDocument.cpp',
]
+EXTRA_COMPONENTS += [
+ 'htmlMenuBuilder.js',
+ 'htmlMenuBuilder.manifest'
+]
+
FAIL_ON_WARNINGS = True
MSVC_ENABLE_PGO = True
diff --git a/dom/html/nsIMenuBuilder.idl b/dom/html/nsIMenuBuilder.idl
index a925fbcb709e..02664480fa46 100644
--- a/dom/html/nsIMenuBuilder.idl
+++ b/dom/html/nsIMenuBuilder.idl
@@ -11,7 +11,7 @@ interface nsIDOMHTMLMenuItemElement;
* An interface used to construct native toolbar or context menus from