This commit is contained in:
Ryan VanderMeulen 2014-12-22 17:55:32 -05:00
Родитель f9e95a3452 af2b511479
Коммит 93534bdf01
49 изменённых файлов: 742 добавлений и 824 удалений

Просмотреть файл

@ -22,9 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Bug 1105308 - Cleanup BluetoothUtils.{cpp,h} Bug 1066383 - Clobber needed due to build system not reliably picking up an IDL removal.
This patch set moves some files around and requires a rebuild
of the build system's dependency information.
Merge day clobber

Просмотреть файл

@ -401,6 +401,8 @@
@BINPATH@/components/nsSidebar.js @BINPATH@/components/nsSidebar.js
@BINPATH@/components/nsAsyncShutdown.manifest @BINPATH@/components/nsAsyncShutdown.manifest
@BINPATH@/components/nsAsyncShutdown.js @BINPATH@/components/nsAsyncShutdown.js
@BINPATH@/components/htmlMenuBuilder.js
@BINPATH@/components/htmlMenuBuilder.manifest
; WiFi, NetworkManager, NetworkStats ; WiFi, NetworkManager, NetworkStats
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK

Просмотреть файл

@ -259,10 +259,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
"nsICrashReporter"); "nsICrashReporter");
#endif #endif
XPCOMUtils.defineLazyGetter(this, "PageMenu", function() { XPCOMUtils.defineLazyGetter(this, "PageMenuParent", function() {
let tmp = {}; let tmp = {};
Cu.import("resource://gre/modules/PageMenu.jsm", tmp); Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
return new tmp.PageMenu(); return new tmp.PageMenuParent();
}); });
/** /**

Просмотреть файл

@ -43,6 +43,11 @@ XPCOMUtils.defineLazyGetter(this, "SimpleServiceDiscovery", function() {
}); });
return ssdp; return ssdp;
}); });
XPCOMUtils.defineLazyGetter(this, "PageMenuChild", function() {
let tmp = {};
Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
return new tmp.PageMenuChild();
});
// TabChildGlobal // TabChildGlobal
var global = this; 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) { addEventListener("DOMFormHasPassword", function(event) {
InsecurePasswordUtils.checkForInsecurePasswords(event.target); InsecurePasswordUtils.checkForInsecurePasswords(event.target);
LoginManagerContent.onFormPassword(event); LoginManagerContent.onFormPassword(event);
@ -148,7 +157,8 @@ let handleContentContextMenu = function (event) {
InlineSpellCheckerContent.initContextMenu(event, editFlags, this); 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 { else {
// Break out to the parent window and pass the add-on info along // Break out to the parent window and pass the add-on info along

Просмотреть файл

@ -24,10 +24,15 @@ nsContextMenu.prototype = {
return; return;
this.hasPageMenu = false; this.hasPageMenu = false;
// FIXME (bug 1047751) - The page menu is disabled in e10s. if (!aIsShift) {
if (!aIsShift && !this.isRemote) { if (this.isRemote) {
this.hasPageMenu = PageMenu.maybeBuildAndAttachMenu(this.target, this.hasPageMenu =
aXulMenu); PageMenuParent.addToPopup(gContextMenuContentData.customMenuItems,
this.browser, aXulMenu);
}
else {
this.hasPageMenu = PageMenuParent.buildAndAddToPopup(this.target, aXulMenu);
}
} }
this.isFrameImage = document.getElementById("isFrameImage"); this.isFrameImage = document.getElementById("isFrameImage");
@ -1766,7 +1771,7 @@ nsContextMenu.prototype = {
} }
// Check if this is a page menu item: // 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"; this._telemetryClickID = "custom-page-item";
} else { } else {
this._telemetryClickID = (e.target.id || "unknown").replace(/^context-/i, ""); this._telemetryClickID = (e.target.id || "unknown").replace(/^context-/i, "");

Просмотреть файл

@ -3175,6 +3175,7 @@
browser: browser, browser: browser,
editFlags: aMessage.data.editFlags, editFlags: aMessage.data.editFlags,
spellInfo: spellInfo, spellInfo: spellInfo,
customMenuItems: aMessage.data.customMenuItems,
addonInfo: aMessage.data.addonInfo }; addonInfo: aMessage.data.addonInfo };
let popup = browser.ownerDocument.getElementById("contentAreaContextMenu"); let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
let event = gContextMenuContentData.event; let event = gContextMenuContentData.event;

Просмотреть файл

@ -72,6 +72,7 @@ support-files =
redirect_bug623155.sjs redirect_bug623155.sjs
searchSuggestionEngine.sjs searchSuggestionEngine.sjs
searchSuggestionEngine.xml searchSuggestionEngine.xml
subtst_contextmenu.html
test-mixedcontent-securityerrors.html test-mixedcontent-securityerrors.html
test_bug435035.html test_bug435035.html
test_bug462673.html test_bug462673.html
@ -486,4 +487,5 @@ skip-if = e10s # bug 1100687 - test directly manipulates content (content.docume
[browser_mcb_redirect.js] [browser_mcb_redirect.js]
skip-if = e10s # bug 1084504 - [e10s] Mixed content detection does not take redirection into account skip-if = e10s # bug 1084504 - [e10s] Mixed content detection does not take redirection into account
[browser_windowactivation.js] [browser_windowactivation.js]
[browser_contextmenu_childprocess.js]
[browser_bug963945.js] [browser_bug963945.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);
}

Просмотреть файл

@ -495,7 +495,7 @@ function runTest(testNum) {
"context-viewinfo", true "context-viewinfo", true
].concat(inspectItems)); ].concat(inspectItems));
invokeItemAction("0"); invokeItemAction("1");
closeContextMenu(); closeContextMenu();
// run mozRequestFullScreen on the element we're testing // run mozRequestFullScreen on the element we're testing

Просмотреть файл

@ -542,6 +542,8 @@
@RESPATH@/components/Identity.manifest @RESPATH@/components/Identity.manifest
@RESPATH@/components/recording-cmdline.js @RESPATH@/components/recording-cmdline.js
@RESPATH@/components/recording-cmdline.manifest @RESPATH@/components/recording-cmdline.manifest
@RESPATH@/components/htmlMenuBuilder.js
@RESPATH@/components/htmlMenuBuilder.manifest
@RESPATH@/components/PermissionSettings.js @RESPATH@/components/PermissionSettings.js
@RESPATH@/components/PermissionSettings.manifest @RESPATH@/components/PermissionSettings.manifest

Просмотреть файл

@ -77,7 +77,7 @@ SEARCHPLUGINS_PATH := $(FINAL_TARGET)/searchplugins
# metro build call a searchplugins target for search engine plugins # metro build call a searchplugins target for search engine plugins
.PHONY: searchplugins .PHONY: searchplugins
SEARCHPLUGINS_TARGET := libs 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 # Some locale-specific search plugins may have preprocessor directives, but the
# default en-US ones do not. # default en-US ones do not.
SEARCHPLUGINS_FLAGS := --silence-missing-directive-warnings SEARCHPLUGINS_FLAGS := --silence-missing-directive-warnings

Просмотреть файл

@ -614,6 +614,13 @@ MERGE_FILE = $(LOCALE_SRCDIR)/$(1)
endif endif
MERGE_FILES = $(foreach f,$(1),$(call MERGE_FILE,$(f))) 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)) ifneq (WINNT,$(OS_ARCH))
RUN_TEST_PROGRAM = $(LIBXUL_DIST)/bin/run-mozilla.sh RUN_TEST_PROGRAM = $(LIBXUL_DIST)/bin/run-mozilla.sh
endif # ! WINNT endif # ! WINNT

Просмотреть файл

@ -22,48 +22,39 @@ include $(topsrcdir)/config/rules.mk
# As an optimization to reduce overall CPU usage, we process all .idl # As an optimization to reduce overall CPU usage, we process all .idl
# belonging to a module with a single command invocation. This prevents # belonging to a module with a single command invocation. This prevents
# redundant parsing of .idl files and significantly reduces CPU cycles. # 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. # For dependency files.
idl_deps_dir := .deps idl_deps_dir := .deps
# Where we put our final, linked .xpt files.
idl_xpt_dir := xpt
dist_idl_dir := $(DIST)/idl dist_idl_dir := $(DIST)/idl
dist_include_dir := $(DIST)/include dist_include_dir := $(DIST)/include
process_py := $(topsrcdir)/python/mozbuild/mozbuild/action/xpidl-process.py 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 ifdef LIBXUL_SDK
idlprocess += -I$(LIBXUL_SDK)/idl libxul_sdk_includes := -I$(LIBXUL_SDK)/idl
endif 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@ xpidl_modules := @xpidl_modules@
xpt_files := @xpt_files@
@xpidl_rules@ @xpidl_rules@
linked_xpt_files := $(addprefix $(idl_xpt_dir)/,$(addsuffix .xpt,$(xpidl_modules)))
depends_files := $(foreach root,$(xpidl_modules),$(idl_deps_dir)/$(root).pp) 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)) $(call include_deps,$(depends_files))

Просмотреть файл

@ -1157,11 +1157,6 @@ endif
ifdef XPT_NAME #{ ifdef XPT_NAME #{
ifndef NO_DIST_INSTALL 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 ifndef NO_INTERFACES_MANIFEST
misc:: $(call mkdir_deps,$(FINAL_TARGET)/components) misc:: $(call mkdir_deps,$(FINAL_TARGET)/components)
$(call py_action,buildlist,$(FINAL_TARGET)/components/interfaces.manifest 'interfaces $(XPT_NAME)') $(call py_action,buildlist,$(FINAL_TARGET)/components/interfaces.manifest 'interfaces $(XPT_NAME)')

Просмотреть файл

@ -819,7 +819,12 @@ NotifyOffThreadScriptLoadCompletedRunnable::Run()
{ {
MOZ_ASSERT(NS_IsMainThread()); 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<nsScriptLoadRequest> request = mRequest.forget();
nsRefPtr<nsScriptLoader> loader = mLoader.forget();
nsresult rv = loader->ProcessOffThreadRequest(request, &mToken);
if (mToken) { if (mToken) {
// The result of the off thread parse was not actually needed to process // The result of the off thread parse was not actually needed to process

Просмотреть файл

@ -9,11 +9,13 @@
#include "mozilla/EventDispatcher.h" #include "mozilla/EventDispatcher.h"
#include "mozilla/dom/HTMLMenuElementBinding.h" #include "mozilla/dom/HTMLMenuElementBinding.h"
#include "mozilla/dom/HTMLMenuItemElement.h" #include "mozilla/dom/HTMLMenuItemElement.h"
#include "nsIMenuBuilder.h"
#include "nsAttrValueInlines.h" #include "nsAttrValueInlines.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsXULContextMenuBuilder.h"
#include "nsIURI.h" #include "nsIURI.h"
#define HTMLMENUBUILDER_CONTRACTID "@mozilla.org/content/html-menu-builder;1"
NS_IMPL_NS_NEW_HTML_ELEMENT(Menu) NS_IMPL_NS_NEW_HTML_ELEMENT(Menu)
namespace mozilla { namespace mozilla {
@ -97,12 +99,8 @@ HTMLMenuElement::CreateBuilder(nsIMenuBuilder** _retval)
{ {
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR); NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
*_retval = nullptr; nsCOMPtr<nsIMenuBuilder> builder = CreateBuilder();
builder.swap(*_retval);
if (mType == MENU_TYPE_CONTEXT) {
NS_ADDREF(*_retval = new nsXULContextMenuBuilder());
}
return NS_OK; return NS_OK;
} }
@ -113,8 +111,9 @@ HTMLMenuElement::CreateBuilder()
return nullptr; return nullptr;
} }
nsCOMPtr<nsIMenuBuilder> ret = new nsXULContextMenuBuilder(); nsCOMPtr<nsIMenuBuilder> builder = do_CreateInstance(HTMLMENUBUILDER_CONTRACTID);
return ret.forget(); NS_WARN_IF(!builder);
return builder.forget();
} }
NS_IMETHODIMP NS_IMETHODIMP

132
dom/html/htmlMenuBuilder.js Normal file
Просмотреть файл

@ -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]);

Просмотреть файл

@ -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}

Просмотреть файл

@ -215,6 +215,11 @@ SOURCES += [
'PluginDocument.cpp', 'PluginDocument.cpp',
] ]
EXTRA_COMPONENTS += [
'htmlMenuBuilder.js',
'htmlMenuBuilder.manifest'
]
FAIL_ON_WARNINGS = True FAIL_ON_WARNINGS = True
MSVC_ENABLE_PGO = True MSVC_ENABLE_PGO = True

Просмотреть файл

@ -11,7 +11,7 @@ interface nsIDOMHTMLMenuItemElement;
* An interface used to construct native toolbar or context menus from <menu> * An interface used to construct native toolbar or context menus from <menu>
*/ */
[scriptable, uuid(12724737-f7db-43b4-94ab-708a7b86e115)] [scriptable, uuid(93F4A48F-D043-4F45-97FD-9771EA1AF976)]
interface nsIMenuBuilder : nsISupports interface nsIMenuBuilder : nsISupports
{ {
@ -49,4 +49,28 @@ interface nsIMenuBuilder : nsISupports
*/ */
void closeContainer(); void closeContainer();
/**
* Returns a JSON string representing the menu hierarchy. For a context menu,
* it will be of the form:
* {
* type: "menu",
* children: [
* {
* type: "menuitem",
* label: "label",
* icon: "image.png"
* },
* {
* type: "separator",
* },
* ];
*/
AString toJSONString();
/**
* Invoke the action of the menuitem with assigned id aGeneratedItemId.
*
* @param aGeneratedItemId the menuitem id
*/
void click(in DOMString aGeneratedItemId);
}; };

Просмотреть файл

@ -70,6 +70,7 @@ GStreamerReader::GStreamerReader(AbstractMediaDecoder* aDecoder)
mMP3FrameParser(aDecoder->GetResource()->GetLength()), mMP3FrameParser(aDecoder->GetResource()->GetLength()),
mDataOffset(0), mDataOffset(0),
mUseParserDuration(false), mUseParserDuration(false),
mLastParserDuration(-1),
#if GST_VERSION_MAJOR >= 1 #if GST_VERSION_MAJOR >= 1
mAllocator(nullptr), mAllocator(nullptr),
mBufferPool(nullptr), mBufferPool(nullptr),

Просмотреть файл

@ -7,6 +7,7 @@
#include "AudioBufferSourceNode.h" #include "AudioBufferSourceNode.h"
#include "mozilla/dom/AudioBufferSourceNodeBinding.h" #include "mozilla/dom/AudioBufferSourceNodeBinding.h"
#include "mozilla/dom/AudioParam.h" #include "mozilla/dom/AudioParam.h"
#include "mozilla/FloatingPoint.h"
#include "nsMathUtils.h" #include "nsMathUtils.h"
#include "AudioNodeEngine.h" #include "AudioNodeEngine.h"
#include "AudioNodeStream.h" #include "AudioNodeStream.h"
@ -110,7 +111,7 @@ public:
mBeginProcessing = mStart + 0.5; mBeginProcessing = mStart + 0.5;
break; break;
case AudioBufferSourceNode::DOPPLERSHIFT: case AudioBufferSourceNode::DOPPLERSHIFT:
mDopplerShift = aParam > 0 && aParam == aParam ? aParam : 1.0; mDopplerShift = (aParam <= 0 || mozilla::IsNaN(aParam)) ? 1.0 : aParam;
break; break;
default: default:
NS_ERROR("Bad AudioBufferSourceNodeEngine double parameter."); NS_ERROR("Bad AudioBufferSourceNodeEngine double parameter.");
@ -415,7 +416,7 @@ public:
} else { } else {
playbackRate = mPlaybackRateTimeline.GetValueAtTime(mSource->GetCurrentPosition()); playbackRate = mPlaybackRateTimeline.GetValueAtTime(mSource->GetCurrentPosition());
} }
if (playbackRate <= 0 || playbackRate != playbackRate) { if (playbackRate <= 0 || mozilla::IsNaN(playbackRate)) {
playbackRate = 1.0f; playbackRate = 1.0f;
} }

Просмотреть файл

@ -181,7 +181,7 @@ namespace WebAudioUtils {
static_assert(mozilla::IsFloatingPoint<FloatType>::value == true, static_assert(mozilla::IsFloatingPoint<FloatType>::value == true,
"FloatType must be a floating point type"); "FloatType must be a floating point type");
if (f != f) { if (mozilla::IsNaN(f)) {
// It is the responsibility of the caller to deal with NaN values. // It is the responsibility of the caller to deal with NaN values.
// If we ever get to this point, we have a serious bug to fix. // If we ever get to this point, we have a serious bug to fix.
NS_RUNTIMEABORT("We should never see a NaN here"); NS_RUNTIMEABORT("We should never see a NaN here");

Просмотреть файл

@ -691,40 +691,72 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
gfx::BackendType::NONE, gfx::BackendType::NONE,
layers::TextureFlags::DEFAULT, layers::TextureFlags::DEFAULT,
layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT); layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
if (!textureClient) { if (textureClient) {
return; RefPtr<layers::GrallocTextureClientOGL> grallocTextureClient =
static_cast<layers::GrallocTextureClientOGL*>(textureClient.get());
android::sp<android::GraphicBuffer> destBuffer = grallocTextureClient->GetGraphicBuffer();
void* destMem = nullptr;
destBuffer->lock(android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destMem);
uint8_t* dstPtr = static_cast<uint8_t*>(destMem);
int32_t yStride = destBuffer->getStride();
// Align to 16 bytes boundary
int32_t uvStride = ((yStride / 2) + 15) & ~0x0F;
libyuv::ConvertToI420(srcPtr, size,
dstPtr, yStride,
dstPtr + (yStride * dstHeight + (uvStride * dstHeight / 2)), uvStride,
dstPtr + (yStride * dstHeight), uvStride,
0, 0,
aWidth, aHeight,
aWidth, aHeight,
static_cast<libyuv::RotationMode>(mRotation),
libyuv::FOURCC_NV21);
destBuffer->unlock();
layers::GrallocImage::GrallocData data;
data.mPicSize = gfx::IntSize(dstWidth, dstHeight);
data.mGraphicBuffer = textureClient;
videoImage->SetData(data);
} else {
// Handle out of gralloc case.
image = mImageContainer->CreateImage(ImageFormat::PLANAR_YCBCR);
layers::PlanarYCbCrImage* videoImage = static_cast<layers::PlanarYCbCrImage*>(image.get());
uint8_t* dstPtr = videoImage->AllocateAndGetNewBuffer(size);
libyuv::ConvertToI420(srcPtr, size,
dstPtr, dstWidth,
dstPtr + (dstWidth * dstHeight), half_width,
dstPtr + (dstWidth * dstHeight * 5 / 4), half_width,
0, 0,
aWidth, aHeight,
aWidth, aHeight,
static_cast<libyuv::RotationMode>(mRotation),
ConvertPixelFormatToFOURCC(graphicBuffer->getPixelFormat()));
const uint8_t lumaBpp = 8;
const uint8_t chromaBpp = 4;
layers::PlanarYCbCrData data;
data.mYChannel = dstPtr;
data.mYSize = IntSize(dstWidth, dstHeight);
data.mYStride = dstWidth * lumaBpp / 8;
data.mCbCrStride = dstWidth * chromaBpp / 8;
data.mCbChannel = dstPtr + dstHeight * data.mYStride;
data.mCrChannel = data.mCbChannel + data.mCbCrStride * (dstHeight / 2);
data.mCbCrSize = IntSize(dstWidth / 2, dstHeight / 2);
data.mPicX = 0;
data.mPicY = 0;
data.mPicSize = IntSize(dstWidth, dstHeight);
data.mStereoMode = StereoMode::MONO;
videoImage->SetDataNoCopy(data);
} }
RefPtr<layers::GrallocTextureClientOGL> grallocTextureClient =
static_cast<layers::GrallocTextureClientOGL*>(textureClient.get());
android::sp<android::GraphicBuffer> destBuffer = grallocTextureClient->GetGraphicBuffer();
void* destMem = nullptr;
destBuffer->lock(android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destMem);
uint8_t* dstPtr = static_cast<uint8_t*>(destMem);
int32_t yStride = destBuffer->getStride();
// Align to 16 bytes boundary
int32_t uvStride = ((yStride / 2) + 15) & ~0x0F;
libyuv::ConvertToI420(srcPtr, size,
dstPtr, yStride,
dstPtr + (yStride * dstHeight + (uvStride * dstHeight / 2)), uvStride,
dstPtr + (yStride * dstHeight), uvStride,
0, 0,
aWidth, aHeight,
aWidth, aHeight,
static_cast<libyuv::RotationMode>(mRotation),
libyuv::FOURCC_NV21);
destBuffer->unlock();
graphicBuffer->unlock(); graphicBuffer->unlock();
layers::GrallocImage::GrallocData data;
data.mPicSize = gfx::IntSize(dstWidth, dstHeight);
data.mGraphicBuffer = textureClient;
videoImage->SetData(data);
// Implicitly releases last preview image. // Implicitly releases last preview image.
mImage = image.forget(); mImage = image.forget();
} }
@ -767,9 +799,14 @@ MediaEngineGonkVideoSource::OnNewMediaBufferFrame(MediaBuffer* aBuffer)
MonitorAutoLock enter(mMonitor); MonitorAutoLock enter(mMonitor);
if (mImage) { if (mImage) {
GonkCameraImage* cameraImage = static_cast<GonkCameraImage*>(mImage.get()); if (mImage->AsGrallocImage()) {
// MediaEngineGonkVideoSource expects that GrallocImage is GonkCameraImage.
cameraImage->SetBuffer(aBuffer); // See Bug 938034.
GonkCameraImage* cameraImage = static_cast<GonkCameraImage*>(mImage.get());
cameraImage->SetBuffer(aBuffer);
} else {
LOG(("mImage is non-GrallocImage"));
}
uint32_t len = mSources.Length(); uint32_t len = mSources.Length();
for (uint32_t i = 0; i < len; i++) { for (uint32_t i = 0; i < len; i++) {
@ -780,12 +817,15 @@ MediaEngineGonkVideoSource::OnNewMediaBufferFrame(MediaBuffer* aBuffer)
// Unfortunately, clock in gonk camera looks like is a different one // Unfortunately, clock in gonk camera looks like is a different one
// comparing to MSG. As result, it causes time inaccurate. (frames be // comparing to MSG. As result, it causes time inaccurate. (frames be
// queued in MSG longer and longer as time going by in device like Frame) // queued in MSG longer and longer as time going by in device like Frame)
AppendToTrack(mSources[i], cameraImage, mTrackID, 1); AppendToTrack(mSources[i], mImage, mTrackID, 1);
} }
} }
// Clear MediaBuffer immediately, it prevents MediaBuffer is kept in if (mImage->AsGrallocImage()) {
// MediaStreamGraph thread. GonkCameraImage* cameraImage = static_cast<GonkCameraImage*>(mImage.get());
cameraImage->ClearBuffer(); // Clear MediaBuffer immediately, it prevents MediaBuffer is kept in
// MediaStreamGraph thread.
cameraImage->ClearBuffer();
}
} }
return NS_OK; return NS_OK;

Просмотреть файл

@ -40,11 +40,11 @@ partial interface HTMLMenuElement {
/** /**
* Creates a native menu builder. The builder type is dependent on menu type. * Creates a native menu builder. The builder type is dependent on menu type.
* Currently, it returns nsXULContextMenuBuilder for context menus. * Currently, it returns the @mozilla.org/content/html-menu-builder;1
* Toolbar menus are not yet supported (the method returns null). * component. Toolbar menus are not yet supported (the method returns null).
*/ */
[ChromeOnly] [ChromeOnly]
MenuBuilder createBuilder(); MenuBuilder? createBuilder();
/* /*
* Builds a menu by iterating over menu children. * Builds a menu by iterating over menu children.

Просмотреть файл

@ -12,7 +12,6 @@ if CONFIG['MOZ_XUL']:
DIRS += ['templates'] DIRS += ['templates']
XPIDL_SOURCES += [ XPIDL_SOURCES += [
'nsIXULContextMenuBuilder.idl',
'nsIXULOverlayProvider.idl', 'nsIXULOverlayProvider.idl',
] ]
@ -23,7 +22,6 @@ if CONFIG['MOZ_XUL']:
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'nsXULCommandDispatcher.cpp', 'nsXULCommandDispatcher.cpp',
'nsXULContentSink.cpp', 'nsXULContentSink.cpp',
'nsXULContextMenuBuilder.cpp',
'nsXULElement.cpp', 'nsXULElement.cpp',
'nsXULPopupListener.cpp', 'nsXULPopupListener.cpp',
'nsXULPrototypeCache.cpp', 'nsXULPrototypeCache.cpp',

Просмотреть файл

@ -1,38 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsISupports.idl"
interface nsIDOMDocumentFragment;
/**
* An interface for initialization of XUL context menu builder
* and for triggering of menuitem actions with assigned identifiers.
*/
[scriptable, uuid(eb6b42c0-2f1c-4760-b5ca-bdc9b3ec77d4)]
interface nsIXULContextMenuBuilder : nsISupports
{
/**
* Initialize builder before building.
*
* @param aDocumentFragment the fragment that will be used to append top
* level elements
*
* @param aGeneratedItemIdAttrName the name of the attribute that will be
* used to mark elements as generated and for menuitem identification
*/
void init(in nsIDOMDocumentFragment aDocumentFragment,
in AString aGeneratedItemIdAttrName);
/**
* Invoke the action of the menuitem with assigned id aGeneratedItemId.
*
* @param aGeneratedItemId the menuitem id
*/
void click(in DOMString aGeneratedItemId);
};

Просмотреть файл

@ -1,230 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsContentCreatorFunctions.h"
#include "nsIContent.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMHTMLMenuItemElement.h"
#include "nsXULContextMenuBuilder.h"
#include "nsIDocument.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
using namespace mozilla::dom;
nsXULContextMenuBuilder::nsXULContextMenuBuilder()
: mCurrentGeneratedItemId(0)
{
}
nsXULContextMenuBuilder::~nsXULContextMenuBuilder()
{
}
NS_IMPL_CYCLE_COLLECTION(nsXULContextMenuBuilder, mFragment, mDocument,
mCurrentNode, mElements)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULContextMenuBuilder)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULContextMenuBuilder)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULContextMenuBuilder)
NS_INTERFACE_MAP_ENTRY(nsIMenuBuilder)
NS_INTERFACE_MAP_ENTRY(nsIXULContextMenuBuilder)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMenuBuilder)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsXULContextMenuBuilder::OpenContainer(const nsAString& aLabel)
{
if (!mFragment) {
return NS_ERROR_NOT_INITIALIZED;
}
if (!mCurrentNode) {
mCurrentNode = mFragment;
} else {
nsCOMPtr<Element> menu;
nsresult rv = CreateElement(nsGkAtoms::menu, nullptr, getter_AddRefs(menu));
NS_ENSURE_SUCCESS(rv, rv);
menu->SetAttr(kNameSpaceID_None, nsGkAtoms::label, aLabel, false);
nsCOMPtr<Element> menuPopup;
rv = CreateElement(nsGkAtoms::menupopup, nullptr,
getter_AddRefs(menuPopup));
NS_ENSURE_SUCCESS(rv, rv);
rv = menu->AppendChildTo(menuPopup, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = mCurrentNode->AppendChildTo(menu, false);
NS_ENSURE_SUCCESS(rv, rv);
mCurrentNode = menuPopup;
}
return NS_OK;
}
NS_IMETHODIMP
nsXULContextMenuBuilder::AddItemFor(nsIDOMHTMLMenuItemElement* aElement,
bool aCanLoadIcon)
{
if (!mFragment) {
return NS_ERROR_NOT_INITIALIZED;
}
nsCOMPtr<Element> menuitem;
nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(aElement);
nsresult rv = CreateElement(nsGkAtoms::menuitem, element,
getter_AddRefs(menuitem));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString type;
aElement->GetType(type);
if (type.EqualsLiteral("checkbox") || type.EqualsLiteral("radio")) {
// The menu is only temporary, so we don't need to handle
// the radio type precisely.
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("checkbox"), false);
bool checked;
aElement->GetChecked(&checked);
if (checked) {
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::checked,
NS_LITERAL_STRING("true"), false);
}
}
nsAutoString label;
aElement->GetLabel(label);
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::label, label, false);
nsAutoString icon;
aElement->GetIcon(icon);
if (!icon.IsEmpty()) {
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
NS_LITERAL_STRING("menuitem-iconic"), false);
if (aCanLoadIcon) {
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::image, icon, false);
}
}
bool disabled;
aElement->GetDisabled(&disabled);
if (disabled) {
menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled,
NS_LITERAL_STRING("true"), false);
}
return mCurrentNode->AppendChildTo(menuitem, false);
}
NS_IMETHODIMP
nsXULContextMenuBuilder::AddSeparator()
{
if (!mFragment) {
return NS_ERROR_NOT_INITIALIZED;
}
nsCOMPtr<Element> menuseparator;
nsresult rv = CreateElement(nsGkAtoms::menuseparator, nullptr,
getter_AddRefs(menuseparator));
NS_ENSURE_SUCCESS(rv, rv);
return mCurrentNode->AppendChildTo(menuseparator, false);
}
NS_IMETHODIMP
nsXULContextMenuBuilder::UndoAddSeparator()
{
if (!mFragment) {
return NS_ERROR_NOT_INITIALIZED;
}
uint32_t count = mCurrentNode->GetChildCount();
if (!count ||
mCurrentNode->GetChildAt(count - 1)->Tag() != nsGkAtoms::menuseparator) {
return NS_OK;
}
mCurrentNode->RemoveChildAt(count - 1, false);
return NS_OK;
}
NS_IMETHODIMP
nsXULContextMenuBuilder::CloseContainer()
{
if (!mFragment) {
return NS_ERROR_NOT_INITIALIZED;
}
if (mCurrentNode == mFragment) {
mCurrentNode = nullptr;
} else {
nsIContent* parent = mCurrentNode->GetParent();
mCurrentNode = parent->GetParent();
}
return NS_OK;
}
NS_IMETHODIMP
nsXULContextMenuBuilder::Init(nsIDOMDocumentFragment* aDocumentFragment,
const nsAString& aGeneratedItemIdAttrName)
{
NS_ENSURE_ARG_POINTER(aDocumentFragment);
mFragment = do_QueryInterface(aDocumentFragment);
mDocument = mFragment->GetOwnerDocument();
mGeneratedItemIdAttr = do_GetAtom(aGeneratedItemIdAttrName);
return NS_OK;
}
NS_IMETHODIMP
nsXULContextMenuBuilder::Click(const nsAString& aGeneratedItemId)
{
nsresult rv;
int32_t idx = nsString(aGeneratedItemId).ToInteger(&rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIDOMHTMLElement> element = mElements.SafeObjectAt(idx);
if (element) {
element->DOMClick();
}
}
return NS_OK;
}
nsresult
nsXULContextMenuBuilder::CreateElement(nsIAtom* aTag,
nsIDOMHTMLElement* aHTMLElement,
Element** aResult)
{
*aResult = nullptr;
nsRefPtr<mozilla::dom::NodeInfo> nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(
aTag, nullptr, kNameSpaceID_XUL, nsIDOMNode::ELEMENT_NODE);
nsresult rv = NS_NewElement(aResult, nodeInfo.forget(), NOT_FROM_PARSER);
if (NS_FAILED(rv)) {
return rv;
}
nsAutoString generateditemid;
if (aHTMLElement) {
mElements.AppendObject(aHTMLElement);
generateditemid.AppendInt(mCurrentGeneratedItemId++);
}
(*aResult)->SetAttr(kNameSpaceID_None, mGeneratedItemIdAttr, generateditemid,
false);
return NS_OK;
}

Просмотреть файл

@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsIMenuBuilder.h"
#include "nsIXULContextMenuBuilder.h"
#include "nsCycleCollectionParticipant.h"
class nsIAtom;
class nsIContent;
class nsIDocument;
class nsIDOMHTMLElement;
namespace mozilla {
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla
class nsXULContextMenuBuilder : public nsIMenuBuilder,
public nsIXULContextMenuBuilder
{
public:
nsXULContextMenuBuilder();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULContextMenuBuilder,
nsIMenuBuilder)
NS_DECL_NSIMENUBUILDER
NS_DECL_NSIXULCONTEXTMENUBUILDER
protected:
virtual ~nsXULContextMenuBuilder();
nsresult CreateElement(nsIAtom* aTag,
nsIDOMHTMLElement* aHTMLElement,
mozilla::dom::Element** aResult);
nsCOMPtr<nsIContent> mFragment;
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsIAtom> mGeneratedItemIdAttr;
nsCOMPtr<nsIContent> mCurrentNode;
int32_t mCurrentGeneratedItemId;
nsCOMArray<nsIDOMHTMLElement> mElements;
};

Просмотреть файл

@ -216,7 +216,7 @@ SharedFrameMetricsHelper::UpdateFromCompositorFrameMetrics(
fabsf(contentMetrics.mDisplayPort.x - compositorMetrics.mDisplayPort.x) <= 2 && fabsf(contentMetrics.mDisplayPort.x - compositorMetrics.mDisplayPort.x) <= 2 &&
fabsf(contentMetrics.mDisplayPort.y - compositorMetrics.mDisplayPort.y) <= 2 && fabsf(contentMetrics.mDisplayPort.y - compositorMetrics.mDisplayPort.y) <= 2 &&
fabsf(contentMetrics.mDisplayPort.width - compositorMetrics.mDisplayPort.width) <= 2 && fabsf(contentMetrics.mDisplayPort.width - compositorMetrics.mDisplayPort.width) <= 2 &&
fabsf(contentMetrics.mDisplayPort.height - compositorMetrics.mDisplayPort.height)) { fabsf(contentMetrics.mDisplayPort.height - compositorMetrics.mDisplayPort.height) <= 2) {
return false; return false;
} }

Просмотреть файл

@ -96,150 +96,6 @@ TextureTargetForAndroidPixelFormat(android::PixelFormat aFormat)
} }
} }
GrallocTextureSourceOGL::GrallocTextureSourceOGL(CompositorOGL* aCompositor,
GrallocTextureHostOGL* aTextureHost,
android::GraphicBuffer* aGraphicBuffer,
gfx::SurfaceFormat aFormat)
: mCompositor(aCompositor)
, mTextureHost(aTextureHost)
, mGraphicBuffer(aGraphicBuffer)
, mEGLImage(0)
, mFormat(aFormat)
, mNeedsReset(true)
{
MOZ_ASSERT(mGraphicBuffer.get());
}
GrallocTextureSourceOGL::~GrallocTextureSourceOGL()
{
DeallocateDeviceData();
mCompositor = nullptr;
}
void
GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
{
/*
* The job of this function is to ensure that the texture is tied to the
* android::GraphicBuffer, so that texturing will source the GraphicBuffer.
*
* To this effect we create an EGLImage wrapping this GraphicBuffer,
* using EGLImageCreateFromNativeBuffer, and then we tie this EGLImage to our
* texture using fEGLImageTargetTexture2D.
*/
MOZ_ASSERT(gl());
if (!IsValid() || !gl()->MakeCurrent()) {
return;
}
GLuint tex = GetGLTexture();
GLuint textureTarget = GetTextureTarget();
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(textureTarget, tex);
ApplyFilterToBoundTexture(gl(), aFilter, textureTarget);
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mTextureHost) {
// Wait until it's ready.
mTextureHost->WaitAcquireFenceSyncComplete();
}
#endif
}
bool GrallocTextureSourceOGL::Lock()
{
MOZ_ASSERT(IsValid());
if (!IsValid()) {
return false;
}
if (!gl()->MakeCurrent()) {
NS_WARNING("Failed to make the gl context current");
return false;
}
mTexture = mCompositor->GetTemporaryTexture(GetTextureTarget(), LOCAL_GL_TEXTURE0);
GLuint textureTarget = GetTextureTarget();
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(textureTarget, mTexture);
if (!mEGLImage) {
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
}
gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
return true;
}
bool
GrallocTextureSourceOGL::IsValid() const
{
return !!gl() && !!mGraphicBuffer.get() && !!mCompositor;
}
gl::GLContext*
GrallocTextureSourceOGL::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
void
GrallocTextureSourceOGL::SetCompositor(Compositor* aCompositor)
{
if (mCompositor && !aCompositor) {
DeallocateDeviceData();
}
mCompositor = static_cast<CompositorOGL*>(aCompositor);
}
GLenum
GrallocTextureSourceOGL::GetTextureTarget() const
{
MOZ_ASSERT(gl());
MOZ_ASSERT(mGraphicBuffer.get());
if (!gl() || !mGraphicBuffer.get()) {
return LOCAL_GL_TEXTURE_EXTERNAL;
}
// SGX has a quirk that only TEXTURE_EXTERNAL works and any other value will
// result in black pixels when trying to draw from bound textures.
// Unfortunately, using TEXTURE_EXTERNAL on Adreno has a terrible effect on
// performance.
// See Bug 950050.
if (gl()->Renderer() == gl::GLRenderer::SGX530 ||
gl()->Renderer() == gl::GLRenderer::SGX540) {
return LOCAL_GL_TEXTURE_EXTERNAL;
}
return TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
}
gfx::IntSize
GrallocTextureSourceOGL::GetSize() const
{
if (!IsValid()) {
NS_WARNING("Trying to access the size of an invalid GrallocTextureSourceOGL");
return gfx::IntSize(0, 0);
}
return gfx::IntSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight());
}
void
GrallocTextureSourceOGL::DeallocateDeviceData()
{
if (mEGLImage) {
MOZ_ASSERT(mCompositor);
if (!gl() || !gl()->MakeCurrent()) {
return;
}
EGLImageDestroy(gl(), mEGLImage);
mEGLImage = EGL_NO_IMAGE;
}
}
GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags, GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
const NewSurfaceDescriptorGralloc& aDescriptor) const NewSurfaceDescriptorGralloc& aDescriptor)
: TextureHost(aFlags) : TextureHost(aFlags)
@ -272,9 +128,6 @@ void
GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor) GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
{ {
mCompositor = static_cast<CompositorOGL*>(aCompositor); mCompositor = static_cast<CompositorOGL*>(aCompositor);
if (mTilingTextureSource) {
mTilingTextureSource->SetCompositor(mCompositor);
}
if (mGLTextureSource) { if (mGLTextureSource) {
mGLTextureSource->SetCompositor(mCompositor); mGLTextureSource->SetCompositor(mCompositor);
} }
@ -312,10 +165,6 @@ GrallocTextureHostOGL::GetFormat() const
void void
GrallocTextureHostOGL::DeallocateSharedData() GrallocTextureHostOGL::DeallocateSharedData()
{ {
if (mTilingTextureSource) {
mTilingTextureSource->ForgetBuffer();
mTilingTextureSource = nullptr;
}
if (mGLTextureSource) { if (mGLTextureSource) {
mGLTextureSource = nullptr; mGLTextureSource = nullptr;
} }
@ -339,10 +188,6 @@ GrallocTextureHostOGL::DeallocateSharedData()
void void
GrallocTextureHostOGL::ForgetSharedData() GrallocTextureHostOGL::ForgetSharedData()
{ {
if (mTilingTextureSource) {
mTilingTextureSource->ForgetBuffer();
mTilingTextureSource = nullptr;
}
if (mGLTextureSource) { if (mGLTextureSource) {
mGLTextureSource = nullptr; mGLTextureSource = nullptr;
} }
@ -351,9 +196,6 @@ GrallocTextureHostOGL::ForgetSharedData()
void void
GrallocTextureHostOGL::DeallocateDeviceData() GrallocTextureHostOGL::DeallocateDeviceData()
{ {
if (mTilingTextureSource) {
mTilingTextureSource->DeallocateDeviceData();
}
if (mGLTextureSource) { if (mGLTextureSource) {
mGLTextureSource = nullptr; mGLTextureSource = nullptr;
} }
@ -387,77 +229,24 @@ GrallocTextureHostOGL::GetRenderState()
TemporaryRef<gfx::DataSourceSurface> TemporaryRef<gfx::DataSourceSurface>
GrallocTextureHostOGL::GetAsSurface() { GrallocTextureHostOGL::GetAsSurface() {
if (mTilingTextureSource) { android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
return mTilingTextureSource->GetAsSurface();
} else {
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
uint8_t* grallocData;
int32_t rv = graphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&grallocData));
RefPtr<gfx::DataSourceSurface> grallocTempSurf =
gfx::Factory::CreateWrappingDataSourceSurface(grallocData,
graphicBuffer->getStride() * android::bytesPerPixel(graphicBuffer->getPixelFormat()),
GetSize(), GetFormat());
RefPtr<gfx::DataSourceSurface> surf = CreateDataSourceSurfaceByCloning(grallocTempSurf);
graphicBuffer->unlock();
return surf.forget();
}
}
TemporaryRef<gfx::DataSourceSurface>
GrallocTextureSourceOGL::GetAsSurface() {
if (!IsValid()) {
return nullptr;
}
uint8_t* grallocData; uint8_t* grallocData;
int32_t rv = mGraphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&grallocData)); int32_t rv = graphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&grallocData));
if (rv) {
return nullptr;
}
RefPtr<gfx::DataSourceSurface> grallocTempSurf = RefPtr<gfx::DataSourceSurface> grallocTempSurf =
gfx::Factory::CreateWrappingDataSourceSurface(grallocData, gfx::Factory::CreateWrappingDataSourceSurface(grallocData,
mGraphicBuffer->getStride() * android::bytesPerPixel(mGraphicBuffer->getPixelFormat()), graphicBuffer->getStride() * android::bytesPerPixel(graphicBuffer->getPixelFormat()),
GetSize(), GetFormat()); GetSize(), GetFormat());
RefPtr<gfx::DataSourceSurface> surf = CreateDataSourceSurfaceByCloning(grallocTempSurf); RefPtr<gfx::DataSourceSurface> surf = CreateDataSourceSurfaceByCloning(grallocTempSurf);
mGraphicBuffer->unlock(); graphicBuffer->unlock();
return surf.forget(); return surf.forget();
} }
GLuint
GrallocTextureSourceOGL::GetGLTexture()
{
return mTexture;
}
void
GrallocTextureSourceOGL::BindEGLImage()
{
gl()->fEGLImageTargetTexture2D(GetTextureTarget(), mEGLImage);
}
TextureSource* TextureSource*
GrallocTextureHostOGL::GetTextureSources() GrallocTextureHostOGL::GetTextureSources()
{ {
// This is now only used with tiled layers, and will eventually be removed. return nullptr;
// Other layer types use BindTextureSource instead.
MOZ_ASSERT(!mGLTextureSource);
if (!mTilingTextureSource) {
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
MOZ_ASSERT(graphicBuffer);
if (!graphicBuffer) {
return nullptr;
}
mTilingTextureSource = new GrallocTextureSourceOGL(mCompositor, this,
graphicBuffer, mFormat);
}
mTilingTextureSource->Lock();
return mTilingTextureSource;
} }
void void
@ -529,8 +318,6 @@ GrallocTextureHostOGL::PrepareTextureSource(CompositableTextureSourceRef& aTextu
// because otherwise we would be modifying the content of every layer that uses // because otherwise we would be modifying the content of every layer that uses
// the TextureSource in question, even thoug they don't use this TextureHost. // the TextureSource in question, even thoug they don't use this TextureHost.
MOZ_ASSERT(!mTilingTextureSource);
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get(); android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
MOZ_ASSERT(graphicBuffer); MOZ_ASSERT(graphicBuffer);

Просмотреть файл

@ -15,74 +15,6 @@
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
class GrallocTextureHostOGL;
// Progressively getting replaced by GLTextureSource
class GrallocTextureSourceOGL : public TextureSource
, public TextureSourceOGL
{
public:
friend class GrallocTextureHostOGL;
GrallocTextureSourceOGL(CompositorOGL* aCompositor,
GrallocTextureHostOGL* aTextureHost,
android::GraphicBuffer* aGraphicBuffer,
gfx::SurfaceFormat aFormat);
virtual ~GrallocTextureSourceOGL();
virtual bool IsValid() const MOZ_OVERRIDE;
virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
virtual GLenum GetTextureTarget() const MOZ_OVERRIDE;
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
virtual GLenum GetWrapMode() const MOZ_OVERRIDE
{
return LOCAL_GL_CLAMP_TO_EDGE;
}
void DeallocateDeviceData();
gl::GLContext* gl() const;
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
void ForgetBuffer()
{
mGraphicBuffer = nullptr;
mTextureHost = nullptr;
}
TemporaryRef<gfx::DataSourceSurface> GetAsSurface();
GLuint GetGLTexture();
void BindEGLImage();
EGLImage GetEGLImage()
{
return mEGLImage;
}
bool Lock();
protected:
RefPtr<CompositorOGL> mCompositor;
GrallocTextureHostOGL* mTextureHost;
android::sp<android::GraphicBuffer> mGraphicBuffer;
EGLImage mEGLImage;
GLuint mTexture;
gfx::SurfaceFormat mFormat;
bool mNeedsReset;
};
class GrallocTextureHostOGL : public TextureHost class GrallocTextureHostOGL : public TextureHost
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
, public TextureHostOGL , public TextureHostOGL
@ -144,8 +76,6 @@ private:
NewSurfaceDescriptorGralloc mGrallocHandle; NewSurfaceDescriptorGralloc mGrallocHandle;
RefPtr<GLTextureSource> mGLTextureSource; RefPtr<GLTextureSource> mGLTextureSource;
RefPtr<CompositorOGL> mCompositor; RefPtr<CompositorOGL> mCompositor;
// only used for tiling, will be removed.
RefPtr<GrallocTextureSourceOGL> mTilingTextureSource;
// Size reported by the GraphicBuffer // Size reported by the GraphicBuffer
gfx::IntSize mSize; gfx::IntSize mSize;
// Size reported by TextureClient, can be different in some cases (video?), // Size reported by TextureClient, can be different in some cases (video?),

Просмотреть файл

@ -27,11 +27,7 @@
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <time.h> #include <time.h>
#if ANDROID_VERSION >= 21 #include <unistd.h>
#include <limits.h>
#else
#include <asm/page.h>
#endif
#include "mozilla/DebugOnly.h" #include "mozilla/DebugOnly.h"
@ -1321,6 +1317,8 @@ EnsureKernelLowMemKillerParamsSet()
int32_t lowerBoundOfNextKillUnderKB = 0; int32_t lowerBoundOfNextKillUnderKB = 0;
int32_t countOfLowmemorykillerParametersSets = 0; int32_t countOfLowmemorykillerParametersSets = 0;
long page_size = sysconf(_SC_PAGESIZE);
for (int i = NUM_PROCESS_PRIORITY - 1; i >= 0; i--) { for (int i = NUM_PROCESS_PRIORITY - 1; i >= 0; i--) {
// The system doesn't function correctly if we're missing these prefs, so // The system doesn't function correctly if we're missing these prefs, so
// crash loudly. // crash loudly.
@ -1358,7 +1356,7 @@ EnsureKernelLowMemKillerParamsSet()
adjParams.AppendPrintf("%d,", OomAdjOfOomScoreAdj(oomScoreAdj)); adjParams.AppendPrintf("%d,", OomAdjOfOomScoreAdj(oomScoreAdj));
// minfree is in pages. // minfree is in pages.
minfreeParams.AppendPrintf("%d,", killUnderKB * 1024 / PAGE_SIZE); minfreeParams.AppendPrintf("%ld,", killUnderKB * 1024 / page_size);
lowerBoundOfNextOomScoreAdj = oomScoreAdj; lowerBoundOfNextOomScoreAdj = oomScoreAdj;
lowerBoundOfNextKillUnderKB = killUnderKB; lowerBoundOfNextKillUnderKB = killUnderKB;
@ -1381,7 +1379,7 @@ EnsureKernelLowMemKillerParamsSet()
// notify_trigger is in pages. // notify_trigger is in pages.
WriteToFile("/sys/module/lowmemorykiller/parameters/notify_trigger", WriteToFile("/sys/module/lowmemorykiller/parameters/notify_trigger",
nsPrintfCString("%d", lowMemNotifyThresholdKB * 1024 / PAGE_SIZE).get()); nsPrintfCString("%ld", lowMemNotifyThresholdKB * 1024 / page_size).get());
} }
// Ensure OOM events appear in logcat // Ensure OOM events appear in logcat

Просмотреть файл

@ -2242,7 +2242,7 @@ LIRGenerator::visitLoadSlot(MLoadSlot *ins)
MOZ_CRASH("typed load must have a payload"); MOZ_CRASH("typed load must have a payload");
default: default:
define(new(alloc()) LLoadSlotT(useRegisterAtStart(ins->slots())), ins); define(new(alloc()) LLoadSlotT(useRegisterForTypedLoad(ins->slots(), ins->type())), ins);
break; break;
} }
} }
@ -3088,13 +3088,16 @@ LIRGenerator::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins)
void void
LIRGenerator::visitLoadFixedSlot(MLoadFixedSlot *ins) LIRGenerator::visitLoadFixedSlot(MLoadFixedSlot *ins)
{ {
MOZ_ASSERT(ins->object()->type() == MIRType_Object); MDefinition *obj = ins->object();
MOZ_ASSERT(obj->type() == MIRType_Object);
if (ins->type() == MIRType_Value) { MIRType type = ins->type();
LLoadFixedSlotV *lir = new(alloc()) LLoadFixedSlotV(useRegisterAtStart(ins->object()));
if (type == MIRType_Value) {
LLoadFixedSlotV *lir = new(alloc()) LLoadFixedSlotV(useRegisterAtStart(obj));
defineBox(lir, ins); defineBox(lir, ins);
} else { } else {
LLoadFixedSlotT *lir = new(alloc()) LLoadFixedSlotT(useRegisterAtStart(ins->object())); LLoadFixedSlotT *lir = new(alloc()) LLoadFixedSlotT(useRegisterForTypedLoad(obj, type));
define(lir, ins); define(lir, ins);
} }
} }

Просмотреть файл

@ -482,6 +482,23 @@ LIRGeneratorShared::fillBoxUses(LInstruction *lir, size_t n, MDefinition *mir)
} }
#endif #endif
LUse
LIRGeneratorShared::useRegisterForTypedLoad(MDefinition *mir, MIRType type)
{
MOZ_ASSERT(type != MIRType_Value && type != MIRType_None);
MOZ_ASSERT(mir->type() == MIRType_Object || mir->type() == MIRType_Slots);
#ifdef JS_PUNBOX64
// On x64, masm.loadUnboxedValue emits slightly less efficient code when
// the input and output use the same register and we're not loading an
// int32/bool/double, so we just call useRegister in this case.
if (type != MIRType_Int32 && type != MIRType_Boolean && type != MIRType_Double)
return useRegister(mir);
#endif
return useRegisterAtStart(mir);
}
} // namespace jit } // namespace jit
} // namespace js } // namespace js

Просмотреть файл

@ -111,6 +111,8 @@ class LIRGeneratorShared : public MDefinitionVisitor
inline LAllocation useRegisterOrNonNegativeConstantAtStart(MDefinition *mir); inline LAllocation useRegisterOrNonNegativeConstantAtStart(MDefinition *mir);
inline LAllocation useRegisterOrNonDoubleConstant(MDefinition *mir); inline LAllocation useRegisterOrNonDoubleConstant(MDefinition *mir);
inline LUse useRegisterForTypedLoad(MDefinition *mir, MIRType type);
#ifdef JS_NUNBOX32 #ifdef JS_NUNBOX32
inline LUse useType(MDefinition *mir, LUse::Policy policy); inline LUse useType(MDefinition *mir, LUse::Policy policy);
inline LUse usePayload(MDefinition *mir, LUse::Policy policy); inline LUse usePayload(MDefinition *mir, LUse::Policy policy);

Просмотреть файл

@ -1,11 +0,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/.
include $(topsrcdir)/config/rules.mk
componentdir = js/xpconnect/tests/components
libs:: $(DEPTH)/config/makefiles/xpidl/xpt/$(XPT_NAME)
$(INSTALL) $^ $(testxpcobjdir)/$(componentdir)/native
$(INSTALL) $^ $(testxpcobjdir)/$(componentdir)/js

Просмотреть файл

@ -14,3 +14,11 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'xpctest' XPIDL_MODULE = 'xpctest'
# XXX: This relies on xpctest.xpt being created in dist/bin/components/ during
# the export tier AND TEST_HARNESS_FILES being processed after that.
TEST_HARNESS_FILES.xpcshell.js.xpconnect.tests.components.native += [
'!/dist/bin/components/xpctest.xpt',
]
TEST_HARNESS_FILES.xpcshell.js.xpconnect.tests.components.js += [
'!/dist/bin/components/xpctest.xpt',
]

Просмотреть файл

@ -146,7 +146,7 @@ Abs<long double>(const long double aLongDouble)
} // namespace mozilla } // namespace mozilla
#if defined(_WIN32) && \ #if defined(_MSC_VER) && \
(defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
# define MOZ_BITSCAN_WINDOWS # define MOZ_BITSCAN_WINDOWS

Просмотреть файл

@ -408,6 +408,8 @@
@BINPATH@/components/Webapps.manifest @BINPATH@/components/Webapps.manifest
@BINPATH@/components/AppsService.js @BINPATH@/components/AppsService.js
@BINPATH@/components/AppsService.manifest @BINPATH@/components/AppsService.manifest
@BINPATH@/components/htmlMenuBuilder.js
@BINPATH@/components/htmlMenuBuilder.manifest
@BINPATH@/components/Activities.manifest @BINPATH@/components/Activities.manifest
@BINPATH@/components/ActivitiesGlue.js @BINPATH@/components/ActivitiesGlue.js

Просмотреть файл

@ -9233,7 +9233,7 @@ githubusercontent.com
ro.com ro.com
// Google, Inc. // Google, Inc.
// Submitted by Eduardo Vela <evn@google.com> 2012-10-24 // Submitted by Eduardo Vela <evn@google.com> 2014-12-19
appspot.com appspot.com
blogspot.ae blogspot.ae
blogspot.be blogspot.be
@ -9281,6 +9281,7 @@ blogspot.tw
codespot.com codespot.com
googleapis.com googleapis.com
googlecode.com googlecode.com
pagespeedmobilizer.com
withgoogle.com withgoogle.com
// Heroku : https://www.heroku.com/ // Heroku : https://www.heroku.com/

Просмотреть файл

@ -2377,13 +2377,15 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param)
LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param)); LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param));
nsresult closeCode = static_cast<nsresult>(reason); nsresult closeCode = static_cast<nsresult>(reason);
nsHttpTransaction *trans = (nsHttpTransaction *) param; nsRefPtr<nsHttpTransaction> trans =
dont_AddRef(static_cast<nsHttpTransaction *>(param));
// //
// if the transaction owns a connection and the transaction is not done, // if the transaction owns a connection and the transaction is not done,
// then ask the connection to close the transaction. otherwise, close the // then ask the connection to close the transaction. otherwise, close the
// transaction directly (removing it from the pending queue first). // transaction directly (removing it from the pending queue first).
// //
nsAHttpConnection *conn = trans->Connection(); nsRefPtr<nsAHttpConnection> conn(trans->Connection());
if (conn && !trans->IsDone()) { if (conn && !trans->IsDone()) {
conn->CloseTransaction(trans, closeCode); conn->CloseTransaction(trans, closeCode);
} else { } else {
@ -2394,7 +2396,7 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param)
int32_t index = ent->mPendingQ.IndexOf(trans); int32_t index = ent->mPendingQ.IndexOf(trans);
if (index >= 0) { if (index >= 0) {
LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]" LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]"
" found in pending queue\n", trans)); " found in pending queue\n", trans.get()));
ent->mPendingQ.RemoveElementAt(index); ent->mPendingQ.RemoveElementAt(index);
nsHttpTransaction *temp = trans; nsHttpTransaction *temp = trans;
NS_RELEASE(temp); // b/c NS_RELEASE nulls its argument! NS_RELEASE(temp); // b/c NS_RELEASE nulls its argument!
@ -2429,12 +2431,11 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param)
if (liveTransaction && liveTransaction->IsNullTransaction()) { if (liveTransaction && liveTransaction->IsNullTransaction()) {
LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p] " LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p] "
"also canceling Null Transaction %p on conn %p\n", "also canceling Null Transaction %p on conn %p\n",
trans, liveTransaction, activeConn)); trans.get(), liveTransaction, activeConn));
activeConn->CloseTransaction(liveTransaction, closeCode); activeConn->CloseTransaction(liveTransaction, closeCode);
} }
} }
} }
NS_RELEASE(trans);
} }
void void

Просмотреть файл

@ -39,7 +39,7 @@ class XPIDLManager(object):
self.idls = {} self.idls = {}
self.modules = {} self.modules = {}
def register_idl(self, source, module, allow_existing=False): def register_idl(self, source, module, install_target, allow_existing=False):
"""Registers an IDL file with this instance. """Registers an IDL file with this instance.
The IDL file will be built, installed, etc. The IDL file will be built, installed, etc.
@ -58,7 +58,8 @@ class XPIDLManager(object):
raise Exception('IDL already registered: %' % entry['basename']) raise Exception('IDL already registered: %' % entry['basename'])
self.idls[entry['basename']] = entry self.idls[entry['basename']] = entry
self.modules.setdefault(entry['module'], set()).add(entry['root']) t = self.modules.setdefault(entry['module'], (install_target, set()))
t[1].add(entry['root'])
class WebIDLCollection(object): class WebIDLCollection(object):
@ -181,7 +182,8 @@ class CommonBackend(BuildBackend):
topsrcdir=obj.topsrcdir) topsrcdir=obj.topsrcdir)
elif isinstance(obj, XPIDLFile): elif isinstance(obj, XPIDLFile):
self._idl_manager.register_idl(obj.source_path, obj.module) self._idl_manager.register_idl(obj.source_path, obj.module,
obj.install_target)
elif isinstance(obj, ConfigFileSubstitution): elif isinstance(obj, ConfigFileSubstitution):
# Do not handle ConfigFileSubstitution for Makefiles. Leave that # Do not handle ConfigFileSubstitution for Makefiles. Leave that

Просмотреть файл

@ -4,6 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import errno
import itertools import itertools
import json import json
import logging import logging
@ -15,11 +16,11 @@ from collections import (
defaultdict, defaultdict,
namedtuple, namedtuple,
) )
from StringIO import StringIO
import mozwebidlcodegen import mozwebidlcodegen
from reftest import ReftestManifest from reftest import ReftestManifest
import mozbuild.makeutil as mozmakeutil
from mozpack.copier import FilePurger from mozpack.copier import FilePurger
from mozpack.manifests import ( from mozpack.manifests import (
InstallManifest, InstallManifest,
@ -751,7 +752,7 @@ class RecursiveMakeBackend(CommonBackend):
# Write out a master list of all IPDL source files. # Write out a master list of all IPDL source files.
ipdl_dir = mozpath.join(self.environment.topobjdir, 'ipc', 'ipdl') ipdl_dir = mozpath.join(self.environment.topobjdir, 'ipc', 'ipdl')
mk = mozmakeutil.Makefile() mk = Makefile()
sorted_ipdl_sources = list(sorted(self._ipdl_sources)) sorted_ipdl_sources = list(sorted(self._ipdl_sources))
mk.add_statement('ALL_IPDLSRCS := %s' % ' '.join(sorted_ipdl_sources)) mk.add_statement('ALL_IPDLSRCS := %s' % ' '.join(sorted_ipdl_sources))
@ -983,8 +984,7 @@ INSTALL_TARGETS += %(prefix)s
def _handle_idl_manager(self, manager): def _handle_idl_manager(self, manager):
build_files = self._install_manifests['xpidl'] build_files = self._install_manifests['xpidl']
for p in ('Makefile', 'backend.mk', '.deps/.mkdir.done', for p in ('Makefile', 'backend.mk', '.deps/.mkdir.done'):
'xpt/.mkdir.done'):
build_files.add_optional_exists(p) build_files.add_optional_exists(p)
for idl in manager.idls.values(): for idl in manager.idls.values():
@ -994,34 +994,44 @@ INSTALL_TARGETS += %(prefix)s
% idl['root']) % idl['root'])
for module in manager.modules: for module in manager.modules:
build_files.add_optional_exists(mozpath.join('xpt',
'%s.xpt' % module))
build_files.add_optional_exists(mozpath.join('.deps', build_files.add_optional_exists(mozpath.join('.deps',
'%s.pp' % module)) '%s.pp' % module))
modules = manager.modules modules = manager.modules
xpt_modules = sorted(modules.keys()) xpt_modules = sorted(modules.keys())
rules = [] xpt_files = set()
mk = Makefile()
for module in xpt_modules: for module in xpt_modules:
deps = sorted(modules[module]) install_target, sources = modules[module]
idl_deps = ['$(dist_idl_dir)/%s.idl' % dep for dep in deps] deps = sorted(sources)
rules.extend([
# It may seem strange to have the .idl files listed as # It may seem strange to have the .idl files listed as
# prerequisites both here and in the auto-generated .pp files. # prerequisites both here and in the auto-generated .pp files.
# It is necessary to list them here to handle the case where a # It is necessary to list them here to handle the case where a
# new .idl is added to an xpt. If we add a new .idl and nothing # new .idl is added to an xpt. If we add a new .idl and nothing
# else has changed, the new .idl won't be referenced anywhere # else has changed, the new .idl won't be referenced anywhere
# except in the command invocation. Therefore, the .xpt won't # except in the command invocation. Therefore, the .xpt won't
# be rebuilt because the dependencies say it is up to date. By # be rebuilt because the dependencies say it is up to date. By
# listing the .idls here, we ensure the make file has a # listing the .idls here, we ensure the make file has a
# reference to the new .idl. Since the new .idl presumably has # reference to the new .idl. Since the new .idl presumably has
# an mtime newer than the .xpt, it will trigger xpt generation. # an mtime newer than the .xpt, it will trigger xpt generation.
'$(idl_xpt_dir)/%s.xpt: %s' % (module, ' '.join(idl_deps)), xpt_path = '$(DEPTH)/%s/components/%s.xpt' % (install_target, module)
'\t@echo "$(notdir $@)"', xpt_files.add(xpt_path)
'\t$(idlprocess) $(basename $(notdir $@)) %s' % ' '.join(deps), rule = mk.create_rule([xpt_path])
'', rule.add_dependencies(['$(call mkdir_deps,%s)' % mozpath.dirname(xpt_path)])
]) rule.add_dependencies(manager.idls['%s.idl' % dep]['source'] for dep in deps)
if install_target.startswith('dist/'):
path = mozpath.relpath(xpt_path, '$(DEPTH)/dist')
prefix, subpath = path.split('/', 1)
key = 'dist_%s' % prefix
self._install_manifests[key].add_optional_exists(subpath)
rules = StringIO()
mk.dump(rules, removal_guard=False)
# Create dependency for output header so we force regeneration if the # Create dependency for output header so we force regeneration if the
# header was deleted. This ideally should not be necessary. However, # header was deleted. This ideally should not be necessary. However,
@ -1037,8 +1047,9 @@ INSTALL_TARGETS += %(prefix)s
obj.topobjdir = self.environment.topobjdir obj.topobjdir = self.environment.topobjdir
obj.config = self.environment obj.config = self.environment
self._create_makefile(obj, extra=dict( self._create_makefile(obj, extra=dict(
xpidl_rules='\n'.join(rules), xpidl_rules=rules.getvalue(),
xpidl_modules=' '.join(xpt_modules), xpidl_modules=' '.join(xpt_modules),
xpt_files=' '.join(sorted(xpt_files)),
)) ))
def _process_program(self, program, backend_file): def _process_program(self, program, backend_file):

Просмотреть файл

@ -1161,7 +1161,7 @@ VARIABLES = {
Files from topsrcdir and the objdir can also be installed by prefixing Files from topsrcdir and the objdir can also be installed by prefixing
the path(s) with a '/' character and a '!' character, respectively:: the path(s) with a '/' character and a '!' character, respectively::
TEST_HARNESS_FILES.path += ['/build/bar.py', '!quux.py'] TEST_HARNESS_FILES.path += ['/build/bar.py', '!quux.py']
""", None), """, 'libs'),
} }
# Sanity check: we don't want any variable above to have a list as storage type. # Sanity check: we don't want any variable above to have a list as storage type.

Просмотреть файл

@ -157,6 +157,7 @@ class XPIDLFile(ContextDerived):
__slots__ = ( __slots__ = (
'basename', 'basename',
'install_target',
'source_path', 'source_path',
) )
@ -167,6 +168,8 @@ class XPIDLFile(ContextDerived):
self.basename = mozpath.basename(source) self.basename = mozpath.basename(source)
self.module = module self.module = module
self.install_target = context['FINAL_TARGET']
class Defines(ContextDerived): class Defines(ContextDerived):
"""Context derived container object for DEFINES, which is an OrderedDict. """Context derived container object for DEFINES, which is an OrderedDict.
""" """

Просмотреть файл

@ -345,6 +345,14 @@ class TreeMetadataEmitter(LoggingMixin):
This is a generator of mozbuild.frontend.data.ContextDerived instances. This is a generator of mozbuild.frontend.data.ContextDerived instances.
""" """
# We only want to emit an InstallationTarget if one of the consulted
# variables is defined. Later on, we look up FINAL_TARGET, which has
# the side-effect of populating it. So, we need to do this lookup
# early.
if any(k in context for k in ('FINAL_TARGET', 'XPI_NAME', 'DIST_SUBDIR')):
yield InstallationTarget(context)
# We always emit a directory traversal descriptor. This is needed by # We always emit a directory traversal descriptor. This is needed by
# the recursive make backend. # the recursive make backend.
for o in self._emit_directory_traversal_from_context(context): yield o for o in self._emit_directory_traversal_from_context(context): yield o
@ -523,9 +531,9 @@ class TreeMetadataEmitter(LoggingMixin):
for s in strings: for s in strings:
if context.is_objdir_path(s): if context.is_objdir_path(s):
if s.startswith('!/'): if s.startswith('!/'):
raise SandboxValidationError( objdir_files[path].append('$(DEPTH)/%s' % s[2:])
'Topobjdir-relative file not allowed in TEST_HARNESS_FILES: %s' % s, context) else:
objdir_files[path].append(s[1:]) objdir_files[path].append(s[1:])
else: else:
resolved = context.resolve_path(s) resolved = context.resolve_path(s)
if '*' in s: if '*' in s:
@ -616,10 +624,6 @@ class TreeMetadataEmitter(LoggingMixin):
'does not exist: %s (resolved to %s)' % (local_include, actual_include), context) 'does not exist: %s (resolved to %s)' % (local_include, actual_include), context)
yield LocalInclude(context, local_include) yield LocalInclude(context, local_include)
if context.get('FINAL_TARGET') or context.get('XPI_NAME') or \
context.get('DIST_SUBDIR'):
yield InstallationTarget(context)
final_target_files = context.get('FINAL_TARGET_FILES') final_target_files = context.get('FINAL_TARGET_FILES')
if final_target_files: if final_target_files:
yield FinalTargetFiles(context, final_target_files, context['FINAL_TARGET']) yield FinalTargetFiles(context, final_target_files, context['FINAL_TARGET'])

Просмотреть файл

@ -443,7 +443,9 @@ class TestRecursiveMakeBackend(BackendTester):
m = InstallManifest(path=mozpath.join(install_dir, 'xpidl')) m = InstallManifest(path=mozpath.join(install_dir, 'xpidl'))
self.assertIn('.deps/my_module.pp', m) self.assertIn('.deps/my_module.pp', m)
self.assertIn('xpt/my_module.xpt', m)
m = InstallManifest(path=os.path.join(install_dir, 'dist_bin'))
self.assertIn('components/my_module.xpt', m)
m = InstallManifest(path=mozpath.join(install_dir, 'dist_include')) m = InstallManifest(path=mozpath.join(install_dir, 'dist_include'))
self.assertIn('foo.h', m) self.assertIn('foo.h', m)

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
this.EXPORTED_SYMBOLS = ["PageMenu"]; this.EXPORTED_SYMBOLS = ["PageMenuParent", "PageMenuChild"];
this.PageMenu = function PageMenu() { this.PageMenu = function PageMenu() {
} }
@ -11,46 +11,71 @@ PageMenu.prototype = {
PAGEMENU_ATTR: "pagemenu", PAGEMENU_ATTR: "pagemenu",
GENERATEDITEMID_ATTR: "generateditemid", GENERATEDITEMID_ATTR: "generateditemid",
popup: null, _popup: null,
builder: null,
maybeBuildAndAttachMenu: function(aTarget, aPopup) { // Only one of builder or browser will end up getting set.
var pageMenu = null; _builder: null,
var target = aTarget; _browser: null,
// Given a target node, get the context menu for it or its ancestor.
getContextMenu: function(aTarget) {
let pageMenu = null;
let target = aTarget;
while (target) { while (target) {
var contextMenu = target.contextMenu; let contextMenu = target.contextMenu;
if (contextMenu) { if (contextMenu) {
pageMenu = contextMenu; return contextMenu;
break;
} }
target = target.parentNode; target = target.parentNode;
} }
if (!pageMenu) { return null;
return false; },
}
var insertionPoint = this.getInsertionPoint(aPopup); // Given a target node, generate a JSON object for any context menu
if (!insertionPoint) { // associated with it, or null if there is no context menu.
return false; maybeBuild: function(aTarget) {
let pageMenu = this.getContextMenu(aTarget);
if (!pageMenu) {
return null;
} }
pageMenu.QueryInterface(Components.interfaces.nsIHTMLMenu); pageMenu.QueryInterface(Components.interfaces.nsIHTMLMenu);
pageMenu.sendShowEvent(); pageMenu.sendShowEvent();
// the show event is not cancelable, so no need to check a result here // the show event is not cancelable, so no need to check a result here
var fragment = aPopup.ownerDocument.createDocumentFragment(); this._builder = pageMenu.createBuilder();
if (!this._builder) {
return null;
}
var builder = pageMenu.createBuilder(); pageMenu.build(this._builder);
if (!builder) {
// This serializes then parses again, however this could be avoided in
// the single-process case with further improvement.
let menuString = this._builder.toJSONString();
if (!menuString) {
return null;
}
return JSON.parse(menuString);
},
// Given a JSON menu object and popup, add the context menu to the popup.
buildAndAttachMenuWithObject: function(aMenu, aBrowser, aPopup) {
if (!aMenu) {
return false; return false;
} }
builder.QueryInterface(Components.interfaces.nsIXULContextMenuBuilder);
builder.init(fragment, this.GENERATEDITEMID_ATTR);
pageMenu.build(builder); let insertionPoint = this.getInsertionPoint(aPopup);
if (!insertionPoint) {
return false;
}
var pos = insertionPoint.getAttribute(this.PAGEMENU_ATTR); let fragment = aPopup.ownerDocument.createDocumentFragment();
this.buildXULMenu(aMenu, fragment);
let pos = insertionPoint.getAttribute(this.PAGEMENU_ATTR);
if (pos == "start") { if (pos == "start") {
insertionPoint.insertBefore(fragment, insertionPoint.insertBefore(fragment,
insertionPoint.firstChild); insertionPoint.firstChild);
@ -60,33 +85,101 @@ PageMenu.prototype = {
insertionPoint.appendChild(fragment); insertionPoint.appendChild(fragment);
} }
this.builder = builder; this._browser = aBrowser;
this.popup = aPopup; this._popup = aPopup;
this.popup.addEventListener("command", this); this._popup.addEventListener("command", this);
this.popup.addEventListener("popuphidden", this); this._popup.addEventListener("popuphidden", this);
return true; return true;
}, },
handleEvent: function(event) { // Construct the XUL menu structure for a given JSON object.
var type = event.type; buildXULMenu: function(aNode, aElementForAppending) {
var target = event.target; let document = aElementForAppending.ownerDocument;
if (type == "command" && target.hasAttribute(this.GENERATEDITEMID_ATTR)) {
this.builder.click(target.getAttribute(this.GENERATEDITEMID_ATTR));
} else if (type == "popuphidden" && this.popup == target) {
this.removeGeneratedContent(this.popup);
this.popup.removeEventListener("popuphidden", this); let children = aNode.children;
this.popup.removeEventListener("command", this); for (let child of children) {
let menuitem;
switch (child.type) {
case "menuitem":
if (!child.id) {
continue; // Ignore children without ids
}
this.popup = null; menuitem = document.createElement("menuitem");
this.builder = null; if (child.checkbox) {
menuitem.setAttribute("type", "checkbox");
if (child.checked) {
menuitem.setAttribute("checked", "true");
}
}
if (child.label) {
menuitem.setAttribute("label", child.label);
}
if (child.icon) {
menuitem.setAttribute("image", child.icon);
menuitem.className = "menuitem-iconic";
}
if (child.disabled) {
menuitem.setAttribute("disabled", true);
}
break;
case "separator":
menuitem = document.createElement("menuseparator");
break;
case "menu":
menuitem = document.createElement("menu");
if (child.label) {
menuitem.setAttribute("label", child.label);
}
let menupopup = document.createElement("menupopup");
menuitem.appendChild(menupopup);
this.buildXULMenu(child, menupopup);
break;
}
menuitem.setAttribute(this.GENERATEDITEMID_ATTR, child.id ? child.id : 0);
aElementForAppending.appendChild(menuitem);
} }
}, },
// Called when the generated menuitem is executed.
handleEvent: function(event) {
let type = event.type;
let target = event.target;
if (type == "command" && target.hasAttribute(this.GENERATEDITEMID_ATTR)) {
// If a builder is assigned, call click on it directly. Otherwise, this is
// likely a menu with data from another process, so send a message to the
// browser to execute the menuitem.
if (this._builder) {
this._builder.click(target.getAttribute(this.GENERATEDITEMID_ATTR));
}
else if (this._browser) {
this._browser.messageManager.sendAsyncMessage("ContextMenu:DoCustomCommand",
target.getAttribute(this.GENERATEDITEMID_ATTR));
}
} else if (type == "popuphidden" && this._popup == target) {
this.removeGeneratedContent(this._popup);
this._popup.removeEventListener("popuphidden", this);
this._popup.removeEventListener("command", this);
this._popup = null;
this._builder = null;
this._browser = null;
}
},
// Get the first child of the given element with the given tag name.
getImmediateChild: function(element, tag) { getImmediateChild: function(element, tag) {
var child = element.firstChild; let child = element.firstChild;
while (child) { while (child) {
if (child.localName == tag) { if (child.localName == tag) {
return child; return child;
@ -96,16 +189,19 @@ PageMenu.prototype = {
return null; return null;
}, },
// Return the location where the generated items should be inserted into the
// given popup. They should be inserted as the next sibling of the returned
// element.
getInsertionPoint: function(aPopup) { getInsertionPoint: function(aPopup) {
if (aPopup.hasAttribute(this.PAGEMENU_ATTR)) if (aPopup.hasAttribute(this.PAGEMENU_ATTR))
return aPopup; return aPopup;
var element = aPopup.firstChild; let element = aPopup.firstChild;
while (element) { while (element) {
if (element.localName == "menu") { if (element.localName == "menu") {
var popup = this.getImmediateChild(element, "menupopup"); let popup = this.getImmediateChild(element, "menupopup");
if (popup) { if (popup) {
var result = this.getInsertionPoint(popup); let result = this.getInsertionPoint(popup);
if (result) { if (result) {
return result; return result;
} }
@ -117,19 +213,20 @@ PageMenu.prototype = {
return null; return null;
}, },
// Remove the generated content from the given popup.
removeGeneratedContent: function(aPopup) { removeGeneratedContent: function(aPopup) {
var ungenerated = []; let ungenerated = [];
ungenerated.push(aPopup); ungenerated.push(aPopup);
var count; let count;
while (0 != (count = ungenerated.length)) { while (0 != (count = ungenerated.length)) {
var last = count - 1; let last = count - 1;
var element = ungenerated[last]; let element = ungenerated[last];
ungenerated.splice(last, 1); ungenerated.splice(last, 1);
var i = element.childNodes.length; let i = element.childNodes.length;
while (i-- > 0) { while (i-- > 0) {
var child = element.childNodes[i]; let child = element.childNodes[i];
if (!child.hasAttribute(this.GENERATEDITEMID_ATTR)) { if (!child.hasAttribute(this.GENERATEDITEMID_ATTR)) {
ungenerated.push(child); ungenerated.push(child);
continue; continue;
@ -139,3 +236,78 @@ PageMenu.prototype = {
} }
} }
} }
// This object is expected to be used from a parent process.
this.PageMenuParent = function PageMenuParent() {
}
PageMenuParent.prototype = {
__proto__ : PageMenu.prototype,
/*
* Given a target node and popup, add the context menu to the popup. This is
* intended to be called when a single process is used. This is equivalent to
* calling PageMenuChild.build and PageMenuParent.addToPopup in sequence.
*
* Returns true if custom menu items were present.
*/
buildAndAddToPopup: function(aTarget, aPopup) {
let menuObject = this.maybeBuild(aTarget);
if (!menuObject) {
return false;
}
return this.buildAndAttachMenuWithObject(menuObject, null, aPopup);
},
/*
* Given a JSON menu object and popup, add the context menu to the popup. This
* is intended to be called when the child page is in a different process.
* aBrowser should be the browser containing the page the context menu is
* displayed for, which may be null.
*
* Returns true if custom menu items were present.
*/
addToPopup: function(aMenu, aBrowser, aPopup) {
return this.buildAndAttachMenuWithObject(aMenu, aBrowser, aPopup);
}
}
// This object is expected to be used from a child process.
this.PageMenuChild = function PageMenuChild() {
}
PageMenuChild.prototype = {
__proto__ : PageMenu.prototype,
/*
* Given a target node, return a JSON object for the custom menu commands. The
* object will consist of a hierarchical structure of menus, menuitems or
* separators. Supported properties of each are:
* Menu: children, label, type="menu"
* Menuitems: checkbox, checked, disabled, icon, label, type="menuitem"
* Separators: type="separator"
*
* In addition, the id of each item will be used to identify the item
* when it is executed. The type will either be 'menu', 'menuitem' or
* 'separator'. The toplevel node will be a menu with a children property. The
* children property of a menu is an array of zero or more other items.
*
* If there is no menu associated with aTarget, null will be returned.
*/
build: function(aTarget) {
return this.maybeBuild(aTarget);
},
/*
* Given the id of a menu, execute the command associated with that menu. It
* is assumed that only one command will be executed so the builder is
* cleared afterwards.
*/
executeMenu: function(aId) {
if (this._builder) {
this._builder.click(aId);
this._builder = null;
}
}
}