Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Narcis Beleuzu 2018-09-19 19:44:24 +03:00
Родитель dea8a7e3af 49ae56e475
Коммит 04ab391b65
42 изменённых файлов: 338 добавлений и 198 удалений

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

@ -70,6 +70,11 @@ function isHTMLElement(aNode) {
aNode.namespaceURI == "http://www.w3.org/1999/xhtml";
}
function isXULElement(aNode) {
return aNode.nodeType == aNode.ELEMENT_NODE &&
aNode.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
}
/**
* Executes the function when requested event is handled.
*
@ -1092,18 +1097,19 @@ function synthClick(aNodeOrID, aCheckerOrEventSeq, aArgs) {
// Scroll the node into view, otherwise synth click may fail.
if (isHTMLElement(targetNode)) {
targetNode.scrollIntoView(true);
} else if (ChromeUtils.getClassName(targetNode) == "XULElement") {
} else if (isXULElement(targetNode)) {
var targetAcc = getAccessible(targetNode);
targetAcc.scrollTo(SCROLL_TYPE_ANYWHERE);
}
var x = 1, y = 1;
if (aArgs && ("where" in aArgs) && aArgs.where == "right") {
if (isHTMLElement(targetNode))
if (isHTMLElement(targetNode)) {
x = targetNode.offsetWidth - 1;
else if (ChromeUtils.getClassName(targetNode) == "XULElement")
} else if (isXULElement(targetNode)) {
x = targetNode.boxObject.width - 1;
}
}
synthesizeMouse(targetNode, x, y, aArgs ? aArgs : {});
};

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

@ -59,7 +59,6 @@
PlacesCommandHook.updateBookmarkAllTabsCommand() -->
<command id="Browser:BookmarkAllTabs"
oncommand="PlacesCommandHook.bookmarkPages(PlacesCommandHook.uniqueCurrentPages);"/>
<command id="Browser:Home" oncommand="BrowserHome();"/>
<command id="Browser:Back" oncommand="BrowserBack();" disabled="true"/>
<command id="Browser:BackOrBackDuplicate" oncommand="BrowserBack(event);" disabled="true">
<observes element="Browser:Back" attribute="disabled"/>
@ -202,7 +201,7 @@
<key id="goBackKb2" key="&goBackCmd.commandKey;" command="Browser:Back" modifiers="accel"/>
<key id="goForwardKb2" key="&goForwardCmd.commandKey;" command="Browser:Forward" modifiers="accel"/>
#endif
<key id="goHome" keycode="VK_HOME" command="Browser:Home" modifiers="alt"/>
<key id="goHome" keycode="VK_HOME" oncommand="BrowserHome();" modifiers="alt"/>
<key keycode="VK_F5" command="Browser:Reload"/>
#ifndef XP_MACOSX
<key id="showAllHistoryKb" key="&showAllHistoryCmd.commandkey;" command="Browser:ShowAllHistory" modifiers="accel,shift"/>

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

@ -145,17 +145,17 @@ async function doSelectTests(contentType, content) {
is(selectPopup.children[1].getAttribute("label"), "One", "option label");
EventUtils.synthesizeKey("KEY_ArrowDown");
is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(2), "Select item 2");
is(menulist.activeChild, menulist.getItemAtIndex(2), "Select item 2");
is(menulist.selectedIndex, isWindows ? 2 : 1, "Select item 2 selectedIndex");
EventUtils.synthesizeKey("KEY_ArrowDown");
is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(3), "Select item 3");
is(menulist.activeChild, menulist.getItemAtIndex(3), "Select item 3");
is(menulist.selectedIndex, isWindows ? 3 : 1, "Select item 3 selectedIndex");
EventUtils.synthesizeKey("KEY_ArrowDown");
// On Windows, one can navigate on disabled menuitems
is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(9),
is(menulist.activeChild, menulist.getItemAtIndex(9),
"Skip optgroup header and disabled items select item 7");
is(menulist.selectedIndex, isWindows ? 9 : 1, "Select or skip disabled item selectedIndex");
@ -164,7 +164,7 @@ async function doSelectTests(contentType, content) {
}
EventUtils.synthesizeKey("KEY_ArrowUp");
is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(3), "Select item 3 again");
is(menulist.activeChild, menulist.getItemAtIndex(3), "Select item 3 again");
is(menulist.selectedIndex, isWindows ? 3 : 1, "Select item 3 selectedIndex");
is((await getInputEvents()), 0, "Before closed - number of input events");

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

@ -8,8 +8,10 @@ add_task(async function() {
content.history.pushState({}, "2", "2.html");
});
var backButton = document.getElementById("back-button");
var rect = backButton.getBoundingClientRect();
await new Promise(resolve => SessionStore.getSessionHistory(gBrowser.selectedTab, resolve));
let backButton = document.getElementById("back-button");
let rect = backButton.getBoundingClientRect();
info("waiting for the history menu to open");

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

@ -1246,14 +1246,14 @@ var UITour = {
showMenu(aWindow, aMenuName, aOpenCallback = null) {
log.debug("showMenu:", aMenuName);
function openMenuButton(aMenuBtn) {
if (!aMenuBtn || !aMenuBtn.boxObject || aMenuBtn.open) {
if (!aMenuBtn || !aMenuBtn.hasMenu() || aMenuBtn.open) {
if (aOpenCallback)
aOpenCallback();
return;
}
if (aOpenCallback)
aMenuBtn.addEventListener("popupshown", aOpenCallback, { once: true });
aMenuBtn.boxObject.openMenu(true);
aMenuBtn.openMenu(true);
}
if (aMenuName == "appMenu" || aMenuName == "pageActionPanel") {
@ -1342,8 +1342,9 @@ var UITour = {
hideMenu(aWindow, aMenuName) {
log.debug("hideMenu:", aMenuName);
function closeMenuButton(aMenuBtn) {
if (aMenuBtn && aMenuBtn.boxObject)
aMenuBtn.boxObject.openMenu(false);
if (aMenuBtn && aMenuBtn.hasMenu()) {
aMenuBtn.openMenu(false);
}
}
if (aMenuName == "appMenu") {

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

@ -1299,31 +1299,20 @@ CustomElementRegistry::CallGetCustomInterface(Element* aElement,
func->Call(aElement, iid, &customInterface);
JS::Rooted<JSObject*> funcGlobal(RootingCx(), func->CallbackGlobalOrNull());
if (customInterface && funcGlobal) {
RefPtr<nsXPCWrappedJS> wrappedJS;
AutoJSAPI jsapi;
if (jsapi.Init(funcGlobal)) {
nsIXPConnect *xpConnect = nsContentUtils::XPConnect();
JSContext* cx = jsapi.cx();
nsresult rv =
nsXPCWrappedJS::GetNewOrUsed(cx, customInterface,
NS_GET_IID(nsISupports),
getter_AddRefs(wrappedJS));
if (NS_SUCCEEDED(rv) && wrappedJS) {
// Check if the returned object implements the desired interface.
nsCOMPtr<nsISupports> retval;
if (NS_SUCCEEDED(wrappedJS->QueryInterface(aIID,
getter_AddRefs(retval)))) {
return retval.forget();
}
}
}
}
}
}
// Otherwise, check if the element supports the interface directly, and just use that.
nsCOMPtr<nsISupports> supports;
if (NS_SUCCEEDED(aElement->QueryInterface(aIID, getter_AddRefs(supports)))) {
return supports.forget();
nsCOMPtr<nsISupports> wrapper;
nsresult rv = xpConnect->WrapJSAggregatedToNative(aElement, cx, customInterface,
aIID, getter_AddRefs(wrapper));
if (NS_SUCCEEDED(rv)) {
return wrapper.forget();
}
}
}
}
}
return nullptr;

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

@ -441,10 +441,7 @@ public:
* To allow native code to call methods of chrome-implemented custom elements,
* a helper method may be defined in the custom element called
* 'getCustomInterfaceCallback'. This method takes an IID and returns an
* object which implements an XPCOM interface. If there is no
* getCustomInterfaceCallback or the callback doesn't return an object,
* QueryInterface is called on aElement to see if this interface is
* implemented directly.
* object which implements an XPCOM interface.
*
* This returns null if aElement is not from a chrome document.
*/

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

@ -259,7 +259,6 @@
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/TabGroup.h"
#ifdef MOZ_XUL
#include "mozilla/dom/MenuBoxObject.h"
#include "mozilla/dom/TreeBoxObject.h"
#include "nsIXULWindow.h"
#include "nsXULCommandDispatcher.h"
@ -6549,9 +6548,7 @@ nsIDocument::GetBoxObjectFor(Element* aElement, ErrorResult& aRv)
RefPtr<nsAtom> tag = BindingManager()->ResolveTag(aElement, &namespaceID);
#ifdef MOZ_XUL
if (namespaceID == kNameSpaceID_XUL) {
if (tag == nsGkAtoms::menu) {
boxObject = new MenuBoxObject();
} else if (tag == nsGkAtoms::tree) {
if (tag == nsGkAtoms::tree) {
boxObject = new TreeBoxObject();
} else {
boxObject = new BoxObject();

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

@ -52,6 +52,7 @@
#include "mozilla/dom/HTMLEmbedElementBinding.h"
#include "mozilla/dom/XULElementBinding.h"
#include "mozilla/dom/XULFrameElementBinding.h"
#include "mozilla/dom/XULMenuElementBinding.h"
#include "mozilla/dom/XULPopupElementBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ResolveSystemBinding.h"
@ -3861,6 +3862,9 @@ HTMLConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp,
definition->mLocalName == nsGkAtoms::browser ||
definition->mLocalName == nsGkAtoms::editor) {
cb = XULFrameElement_Binding::GetConstructorObject;
} else if (definition->mLocalName == nsGkAtoms::menu ||
definition->mLocalName == nsGkAtoms::menulist) {
cb = XULMenuElement_Binding::GetConstructorObject;
} else if (definition->mLocalName == nsGkAtoms::scrollbox) {
cb = XULScrollElement_Binding::GetConstructorObject;
} else {

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

@ -5,10 +5,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Func="IsChromeOrXBL"]
interface MenuBoxObject : BoxObject {
void openMenu(boolean openFlag);
[HTMLConstructor, Func="IsChromeOrXBL"]
interface XULMenuElement : XULElement {
attribute Element? activeChild;

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

@ -50,6 +50,7 @@ WEBIDL_FILES = [
'WebExtensionContentScript.webidl',
'WebExtensionPolicy.webidl',
'XULFrameElement.webidl',
'XULMenuElement.webidl',
'XULScrollElement.webidl'
]

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

@ -665,8 +665,6 @@ var interfaceNamesInGlobalScope =
{name: "MediaStreamTrackEvent", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MediaStreamTrack", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MenuBoxObject", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MessageChannel", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
@ -1261,6 +1259,8 @@ var interfaceNamesInGlobalScope =
{name: "XULElement", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "XULFrameElement", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "XULMenuElement", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "XULPopupElement", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!

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

@ -85,6 +85,14 @@ interface XULElement : Element {
[Constant]
readonly attribute CSSStyleDeclaration style;
// Returns true if this is a menu-type element that has a menu
// frame associated with it.
boolean hasMenu();
// If this is a menu-type element, opens or closes the menu
// depending on the argument passed.
void openMenu(boolean open);
};
XULElement implements GlobalEventHandlers;

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

@ -665,7 +665,6 @@ WEBIDL_FILES = [
'MediaTrackConstraintSet.webidl',
'MediaTrackSettings.webidl',
'MediaTrackSupportedConstraints.webidl',
'MenuBoxObject.webidl',
'MerchantValidationEvent.webidl',
'MessageChannel.webidl',
'MessageEvent.webidl',

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

@ -4,9 +4,6 @@
* 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 "mozilla/dom/MenuBoxObject.h"
#include "mozilla/dom/MenuBoxObjectBinding.h"
#include "mozilla/dom/KeyboardEvent.h"
#include "mozilla/dom/KeyboardEventBinding.h"
#include "mozilla/dom/Element.h"
@ -15,49 +12,36 @@
#include "nsMenuBarListener.h"
#include "nsMenuFrame.h"
#include "nsMenuPopupFrame.h"
#include "mozilla/dom/XULMenuElement.h"
#include "mozilla/dom/XULMenuElementBinding.h"
#include "nsXULPopupManager.h"
namespace mozilla {
namespace dom {
MenuBoxObject::MenuBoxObject()
JSObject*
XULMenuElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return XULMenuElement_Binding::Wrap(aCx, this, aGivenProto);
}
MenuBoxObject::~MenuBoxObject()
nsIFrame*
XULMenuElement::GetFrame()
{
nsCOMPtr<nsIContent> kungFuDeathGrip = this; // keep a reference
nsCOMPtr<nsIDocument> doc = GetUncomposedDoc();
if (doc) {
doc->FlushPendingNotifications(FlushType::Frames);
}
JSObject* MenuBoxObject::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return MenuBoxObject_Binding::Wrap(aCx, this, aGivenProto);
}
void MenuBoxObject::OpenMenu(bool aOpenFlag)
{
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (pm) {
nsIFrame* frame = GetFrame(false);
if (frame) {
if (aOpenFlag) {
nsCOMPtr<nsIContent> content = mContent;
pm->ShowMenu(content, false, false);
}
else {
nsMenuFrame* menu = do_QueryFrame(frame);
if (menu) {
nsMenuPopupFrame* popupFrame = menu->GetPopup();
if (popupFrame)
pm->HidePopup(popupFrame->GetContent(), false, true, false, false);
}
}
}
}
return GetPrimaryFrame();
}
already_AddRefed<Element>
MenuBoxObject::GetActiveChild()
XULMenuElement::GetActiveChild()
{
nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
nsMenuFrame* menu = do_QueryFrame(GetFrame());
if (menu) {
RefPtr<Element> el;
menu->GetActiveChild(getter_AddRefs(el));
@ -66,15 +50,17 @@ MenuBoxObject::GetActiveChild()
return nullptr;
}
void MenuBoxObject::SetActiveChild(Element* arg)
void
XULMenuElement::SetActiveChild(Element* arg)
{
nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
nsMenuFrame* menu = do_QueryFrame(GetFrame());
if (menu) {
menu->SetActiveChild(arg);
}
}
bool MenuBoxObject::HandleKeyPress(KeyboardEvent& keyEvent)
bool
XULMenuElement::HandleKeyPress(KeyboardEvent& keyEvent)
{
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (!pm) {
@ -89,7 +75,7 @@ bool MenuBoxObject::HandleKeyPress(KeyboardEvent& keyEvent)
if (nsMenuBarListener::IsAccessKeyPressed(&keyEvent))
return false;
nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
nsMenuFrame* menu = do_QueryFrame(GetFrame());
if (!menu) {
return false;
}
@ -115,9 +101,10 @@ bool MenuBoxObject::HandleKeyPress(KeyboardEvent& keyEvent)
}
}
bool MenuBoxObject::OpenedWithKey()
bool
XULMenuElement::OpenedWithKey()
{
nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false));
nsMenuFrame* menuframe = do_QueryFrame(GetFrame());
if (!menuframe) {
return false;
}

41
dom/xul/XULMenuElement.h Normal file
Просмотреть файл

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_XULMenuElement_h
#define mozilla_dom_XULMenuElement_h
#include "nsXULElement.h"
namespace mozilla {
namespace dom {
class KeyboardEvent;
class XULMenuElement final : public nsXULElement
{
public:
explicit XULMenuElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsXULElement(aNodeInfo)
{
}
MOZ_CAN_RUN_SCRIPT already_AddRefed<Element> GetActiveChild();
MOZ_CAN_RUN_SCRIPT void SetActiveChild(Element* arg);
MOZ_CAN_RUN_SCRIPT bool HandleKeyPress(KeyboardEvent& keyEvent);
MOZ_CAN_RUN_SCRIPT bool OpenedWithKey();
private:
virtual ~XULMenuElement() {}
JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) final;
nsIFrame* GetFrame();
};
} // namespace dom
} // namespace mozilla
#endif // XULMenuElement_h

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

@ -23,6 +23,7 @@ if CONFIG['MOZ_XUL']:
EXPORTS.mozilla.dom += [
'XULFrameElement.h',
'XULMenuElement.h',
'XULPopupElement.h',
'XULScrollElement.h',
]
@ -38,6 +39,7 @@ if CONFIG['MOZ_XUL']:
'nsXULSortService.cpp',
'XULDocument.cpp',
'XULFrameElement.cpp',
'XULMenuElement.cpp',
'XULPopupElement.cpp',
'XULScrollElement.cpp',
]

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

@ -75,6 +75,7 @@
#include "nsICSSDeclaration.h"
#include "nsLayoutUtils.h"
#include "XULFrameElement.h"
#include "XULMenuElement.h"
#include "XULPopupElement.h"
#include "XULScrollElement.h"
@ -159,6 +160,12 @@ nsXULElement* nsXULElement::Construct(already_AddRefed<mozilla::dom::NodeInfo>&&
return new XULFrameElement(frameni);
}
if (nodeInfo->Equals(nsGkAtoms::menu) ||
nodeInfo->Equals(nsGkAtoms::menulist)) {
already_AddRefed<mozilla::dom::NodeInfo> menuni = nodeInfo.forget();
return new XULMenuElement(menuni);
}
if (nodeInfo->Equals(nsGkAtoms::scrollbox)) {
already_AddRefed<mozilla::dom::NodeInfo> scrollni = nodeInfo.forget();
return new XULScrollElement(scrollni);
@ -304,7 +311,17 @@ NS_IMPL_RELEASE_INHERITED(nsXULElement, nsStyledElement)
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsXULElement)
NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
NS_INTERFACE_MAP_END_INHERITING(nsStyledElement)
nsCOMPtr<nsISupports> iface =
CustomElementRegistry::CallGetCustomInterface(this, aIID);
if (iface) {
iface->QueryInterface(aIID, aInstancePtr);
if (*aInstancePtr) {
return NS_OK;
}
}
NS_INTERFACE_MAP_END_INHERITING(Element)
//----------------------------------------------------------------------
// nsINode interface
@ -496,6 +513,39 @@ nsXULElement::IsFocusableInternal(int32_t *aTabIndex, bool aWithMouse)
return shouldFocus;
}
bool
nsXULElement::HasMenu()
{
nsMenuFrame* menu = do_QueryFrame(GetPrimaryFrame());
return menu != nullptr;
}
void
nsXULElement::OpenMenu(bool aOpenFlag)
{
nsCOMPtr<nsIDocument> doc = GetUncomposedDoc();
if (doc) {
doc->FlushPendingNotifications(FlushType::Frames);
}
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (pm) {
if (aOpenFlag) {
// Nothing will happen if this element isn't a menu.
pm->ShowMenu(this, false, false);
}
else {
nsMenuFrame* menu = do_QueryFrame(GetPrimaryFrame());
if (menu) {
nsMenuPopupFrame* popupFrame = menu->GetPopup();
if (popupFrame) {
pm->HidePopup(popupFrame->GetContent(), false, true, false, false);
}
}
}
}
}
bool
nsXULElement::PerformAccesskey(bool aKeyCausesActivation,
bool aIsTrustedEvent)

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

@ -375,6 +375,9 @@ public:
}
#endif
bool HasMenu();
MOZ_CAN_RUN_SCRIPT void OpenMenu(bool aOpenFlag);
virtual bool PerformAccesskey(bool aKeyCausesActivation,
bool aIsTrustedEvent) override;
void ClickWithInputSource(uint16_t aInputSource, bool aIsTrustedEvent);

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

@ -334,9 +334,11 @@ MacOSFontEntry::GetVariationAxes(nsTArray<gfxFontVariationAxis>& aVariationAxes)
kCTFontVariationAxisNameKey);
if (name) {
CFIndex len = CFStringGetLength(name);
axis.mName.SetLength(len);
nsAutoString nameStr;
nameStr.SetLength(len);
CFStringGetCharacters(name, CFRangeMake(0, len),
(UniChar*)axis.mName.BeginWriting());
(UniChar*)nameStr.BeginWriting());
AppendUTF16toUTF8(nameStr, axis.mName);
}
axis.mTag = (uint32_t)tag;
axis.mMinValue = minValue;

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

@ -351,17 +351,29 @@ template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::checkPositionalParameterIndices(Handle<GCVector<JSAtom*>> positionalParams,
ListNode* params)
{
MOZ_ASSERT(positionalParams.get().length() == params->count());
#ifdef DEBUG
// positionalParams should have the same length as non-rest parameters.
size_t paramsCount = params->count();
if (paramsCount > 0) {
if (params->last()->isKind(ParseNodeKind::Spread)) {
paramsCount--;
}
}
MOZ_ASSERT(positionalParams.get().length() == paramsCount);
#endif
uint32_t i = 0;
for (ParseNode* param : params->contents()) {
if (param->isKind(ParseNodeKind::Assign)) {
param = param->as<AssignmentNode>().left();
}
if (param->isKind(ParseNodeKind::Spread)) {
continue;
}
MOZ_ASSERT(param->isKind(ParseNodeKind::Name) ||
param->isKind(ParseNodeKind::Object) ||
param->isKind(ParseNodeKind::Array) ||
param->isKind(ParseNodeKind::Spread));
param->isKind(ParseNodeKind::Array));
if (JSAtom* name = positionalParams.get()[i]) {
// Simple or default parameter.

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

@ -0,0 +1,5 @@
var g = newGlobal();
var w1 = g.Math;
var w2 = g.evaluate("new Array");
recomputeWrappers(this, g);
recomputeWrappers();

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

@ -6137,6 +6137,46 @@ NukeAllCCWs(JSContext* cx, unsigned argc, Value* vp)
return true;
}
static bool
RecomputeWrappers(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() > 2) {
JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS,
"recomputeWrappers");
return false;
}
JS::Compartment* sourceComp = nullptr;
if (args.get(0).isObject()) {
sourceComp = GetObjectCompartment(UncheckedUnwrap(&args[0].toObject()));
}
JS::Compartment* targetComp = nullptr;
if (args.get(1).isObject()) {
targetComp = GetObjectCompartment(UncheckedUnwrap(&args[1].toObject()));
}
struct SingleOrAllCompartments final : public CompartmentFilter {
JS::Compartment* comp;
explicit SingleOrAllCompartments(JS::Compartment* c) : comp(c) {}
virtual bool match(JS::Compartment* c) const override {
return !comp || comp == c;
}
};
if (!js::RecomputeWrappers(cx,
SingleOrAllCompartments(sourceComp),
SingleOrAllCompartments(targetComp)))
{
return false;
}
args.rval().setUndefined();
return true;
}
static bool
GetMaxArgs(JSContext* cx, unsigned argc, Value* vp)
{
@ -8196,6 +8236,12 @@ JS_FN_HELP("parseBin", BinParse, 1, 0,
"nukeAllCCWs()",
" Like nukeCCW, but for all CrossCompartmentWrappers targeting the current compartment."),
JS_FN_HELP("recomputeWrappers", RecomputeWrappers, 2, 0,
"recomputeWrappers([src, [target]])",
" Recompute all cross-compartment wrappers. src and target are both optional\n"
" and can be used to filter source or target compartments: the unwrapped\n"
" object's compartment is used as CompartmentFilter.\n"),
JS_FN_HELP("wrapWithProto", WrapWithProto, 2, 0,
"wrapWithProto(obj)",
" Wrap an object into a noop wrapper with prototype semantics."),

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

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_MenuBoxObject_h
#define mozilla_dom_MenuBoxObject_h
#include "mozilla/dom/BoxObject.h"
namespace mozilla {
namespace dom {
class KeyboardEvent;
class MenuBoxObject final : public BoxObject
{
public:
MenuBoxObject();
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void OpenMenu(bool aOpenFlag);
already_AddRefed<Element> GetActiveChild();
void SetActiveChild(Element* arg);
bool HandleKeyPress(KeyboardEvent& keyEvent);
bool OpenedWithKey();
private:
~MenuBoxObject();
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_MenuBoxObject_h

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

@ -31,7 +31,6 @@ EXPORTS += [
EXPORTS.mozilla.dom += [
'BoxObject.h',
'MenuBoxObject.h',
]
UNIFIED_SOURCES += [
@ -54,7 +53,6 @@ UNIFIED_SOURCES += [
if CONFIG['MOZ_XUL']:
UNIFIED_SOURCES += [
'MenuBoxObject.cpp',
'nsDeckFrame.cpp',
'nsDocElementBoxFrame.cpp',
'nsGroupBoxFrame.cpp',

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

@ -27,6 +27,7 @@
#include "nsDisplayList.h"
#include "nsContainerFrame.h"
#include "nsContentUtils.h"
#include "nsXULPopupManager.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"

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

@ -64,7 +64,7 @@ nsReflowFrameRunnable::Run()
// Creates a new Toolbar frame and returns it
//
nsIFrame*
NS_NewProgressMeterFrame (nsIPresShell* aPresShell, ComputedStyle* aStyle)
NS_NewProgressMeterFrame (nsIPresShell* aPresShell, mozilla::ComputedStyle* aStyle)
{
return new (aPresShell) nsProgressMeterFrame(aStyle);
}

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

@ -3,7 +3,7 @@ job-defaults:
require-build: true
worker-type:
by-platform:
linux64.*: releng-hardware/gecko-t-linux-talos
linux64.*: releng-hardware/gecko-t-linux-talos-tw
worker:
by-platform:
linux64.*:

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

@ -1008,7 +1008,7 @@ def set_worker_type(config, tests):
elif test_platform.startswith('linux') or test_platform.startswith('android'):
if test.get('suite', '') in ['talos', 'raptor'] and \
not test['build-platform'].startswith('linux64-ccov'):
test['worker-type'] = 'releng-hardware/gecko-t-linux-talos'
test['worker-type'] = 'releng-hardware/gecko-t-linux-talos-tw'
else:
test['worker-type'] = LINUX_WORKER_TYPES[test['instance-size']]
else:

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

@ -36,7 +36,7 @@ WORKER_TYPES = {
'aws-provisioner-v1/taskcluster-generic': ('docker-worker', 'linux'),
'invalid/invalid': ('invalid', None),
'invalid/always-optimized': ('always-optimized', None),
'releng-hardware/gecko-t-linux-talos': ('native-engine', 'linux'),
'releng-hardware/gecko-t-linux-talos-tw': ('native-engine', 'linux'),
'scriptworker-prov-v1/balrog-dev': ('balrog', None),
'scriptworker-prov-v1/balrogworker-v1': ('balrog', None),
'scriptworker-prov-v1/beetmoverworker-v1': ('beetmover', None),

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

@ -110,9 +110,8 @@ class MozXULElement extends XULElement {
}
/**
* Indicate that a class defining an element implements one or more
* XPCOM interfaces. The custom element getCustomInterface is added
* as well as an implementation of QueryInterface.
* Indicate that a class defining a XUL element implements one or more
* XPCOM interfaces by adding a getCustomInterface implementation to it.
*
* The supplied class should implement the properties and methods of
* all of the interfaces that are specified.
@ -120,10 +119,9 @@ class MozXULElement extends XULElement {
* @param cls
* The class that implements the interface.
* @param names
* Array of interface names
* Array of interface names.
*/
static implementCustomInterface(cls, ifaces) {
cls.prototype.QueryInterface = ChromeUtils.generateQI(ifaces);
cls.prototype.getCustomInterfaceCallback = function getCustomInterfaceCallback(iface) {
if (ifaces.includes(Ci[Components.interfacesByID[iface.number]])) {
return getInterfaceProxy(this);

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

@ -29,7 +29,7 @@ function runTests() {
gMenuPopup = document.getElementById("thepopup");
gTrigger = document.getElementById("trigger");
gIsMenu = gTrigger.boxObject instanceof MenuBoxObject;
gIsMenu = gTrigger.hasMenu();
// a hacky way to get the screen position of the document. Cache the event
// so that we can use it in calls to openPopup.

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

@ -106,7 +106,7 @@ function menuTests()
is(gContextMenuFired, true, "context menu fired when menu open");
gSelectionStep = 1;
$("menu").boxObject.activeChild = $("menu2");
$("menu").activeChild = $("menu2");
synthesizeMouse(element, 0, 0, { type : "contextmenu", button: 0 });
$("menu").open = false;

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

@ -12,7 +12,10 @@
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
<simpleelement id="simple"/>
<button id="one"/>
<simpleelement id="two" style="-moz-user-focus: normal;"/>
<simpleelement id="three" disabled="true" style="-moz-user-focus: normal;"/>
<button id="four"/>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
@ -22,7 +25,7 @@
async function runTests() {
ok(MozXULElement, "MozXULElement defined on the window");
testParseXULToFragment();
testCustomInterface();
await testCustomInterface();
let htmlWin = await new Promise(resolve => {
let htmlIframe = document.createElement("iframe");
@ -51,29 +54,37 @@
deck.remove();
}
function testCustomInterface() {
async function testCustomInterface() {
class SimpleElement extends MozXULElement {
get disabled() {
return false;
return this.getAttribute("disabled") == "true";
}
set disabled(val) {
if (val) this.setAttribute("disabled", "true");
else this.removeAttribute("disabled");
return val;
}
get tabIndex() {
return 0;
return parseInt(this.getAttribute("tabIndex")) || 0;
}
set tabIndex(val) {
if (val) this.setAttribute("tabIndex", val);
else this.removeAttribute("tabIndex");
return val;
}
}
customElements.define("simpleelement", SimpleElement);
MozXULElement.implementCustomInterface(SimpleElement, [Ci.nsIDOMXULControlElement]);
customElements.define("simpleelement", SimpleElement);
let twoElement = document.getElementById("two");
is(document.documentElement.getCustomInterfaceCallback, undefined,
"No getCustomInterfaceCallback on non-custom element");
is(typeof document.getElementById("simple").getCustomInterfaceCallback, "function",
is(typeof twoElement.getCustomInterfaceCallback, "function",
"getCustomInterfaceCallback available on custom element when set");
try {
document.documentElement.QueryInterface(Ci.nsIDOMXULControlElement)
@ -81,8 +92,41 @@
} catch (ex) {
ok(true, "Non-custom element implements custom interface");
}
ok(document.getElementById("simple").QueryInterface(Ci.nsIDOMXULControlElement),
"Implements custom interface");
// Try various ways to get the custom interface.
let asControl = twoElement.getCustomInterfaceCallback(Ci.nsIDOMXULControlElement);
ok(asControl, twoElement, "getCustomInterface returns interface implementation ");
asControl = twoElement.QueryInterface(Ci.nsIDOMXULControlElement);
ok(asControl, "QueryInterface to nsIDOMXULControlElement");
ok(asControl instanceof Node, "Control is a Node");
// Now make sure that the custom element handles focus/tabIndex as needed by shitfing
// focus around and enabling/disabling the simple elements.
// Enable Full Keyboard Access emulation on Mac
await SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
ok(!twoElement.disabled, "two is enabled");
ok(document.getElementById("three").disabled, "three is disabled");
await SimpleTest.promiseFocus();
ok(document.hasFocus(), "has focus");
// This should skip the disabled simpleelement.
synthesizeKey("VK_TAB");
is(document.activeElement.id, "one", "Tab 1");
synthesizeKey("VK_TAB");
is(document.activeElement.id, "two", "Tab 2");
synthesizeKey("VK_TAB");
is(document.activeElement.id, "four", "Tab 3");
twoElement.disabled = true;
is(twoElement.getAttribute("disabled"), "true", "two disabled after change");
synthesizeKey("VK_TAB", { shiftKey: true });
is(document.activeElement.id, "one", "Tab 1");
}
]]>
</script>

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

@ -218,7 +218,7 @@ function test_menulist_open(element, scroller)
synthesizeMouse(element.menupopup.childNodes[1], 2, 2, { type: "mousemove" });
synthesizeMouse(element.menupopup.childNodes[1], 6, 6, { type: "mousemove" });
is(element.menuBoxObject.activeChild, item, "activeChild after menu highlight " + element.id);
is(element.activeChild, item, "activeChild after menu highlight " + element.id);
is(element.selectedIndex, 0, "selectedIndex after menu highlight " + element.id);
is(scroller.scrollTop, 0, "scroll position after menu highlight " + element.id);

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

@ -60,11 +60,11 @@ function runTests()
keyCheck(list, "KEY_ArrowUp", iswin ? 1 : 4, 1, "cursor up wrap");
list.selectedIndex = 4;
list.menuBoxObject.activeChild = list.selectedItem;
list.activeChild = list.selectedItem;
keyCheck(list, "KEY_ArrowDown", iswin ? 4 : 1, 4, "cursor down wrap");
list.selectedIndex = 0;
list.menuBoxObject.activeChild = list.selectedItem;
list.activeChild = list.selectedItem;
}
// check that attempting to open the menulist does not change the selection
@ -171,7 +171,7 @@ function tabAndScroll()
var item = list.getItemAtIndex(10);
var originalPosition = item.getBoundingClientRect().top;
list.menuBoxObject.activeChild = item;
list.activeChild = item;
ok(item.getBoundingClientRect().top < originalPosition,
"position of item 1: " + item.getBoundingClientRect().top + " -> " + originalPosition);
@ -257,15 +257,15 @@ function checkCursorNavigation()
// Check whether cursor up and down wraps.
list.selectedIndex = 0;
list.menuBoxObject.activeChild = list.selectedItem;
list.activeChild = list.selectedItem;
synthesizeKey("KEY_ArrowUp");
is(list.menuBoxObject.activeChild,
is(list.activeChild,
document.getElementById(iswin || ismac ? "b1" : "b4"), "cursor up wrap while open");
list.selectedIndex = 3;
list.menuBoxObject.activeChild = list.selectedItem;
list.activeChild = list.selectedItem;
synthesizeKey("KEY_ArrowDown");
is(list.menuBoxObject.activeChild,
is(list.activeChild,
document.getElementById(iswin || ismac ? "b4" : "b1"), "cursor down wrap while open");
synthesizeKey("KEY_ArrowUp", {altKey: true});

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

@ -124,7 +124,7 @@ function runTest()
function menulistShown()
{
let menulist = document.getElementById(test.list);
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.initial).label, test.list + " initial selection");
is(menulist.activeChild.label, menulist.getItemAtIndex(test.initial).label, test.list + " initial selection");
let cs = window.getComputedStyle(menulist.menupopup);
let bpTop = parseFloat(cs.paddingTop) + parseFloat(cs.borderTopWidth);
@ -138,12 +138,12 @@ function menulistShown()
for (let i = 0; i < test.downs.length; i++) {
sendKey("PAGE_DOWN");
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.downs[i]).label, test.list + " page down " + i);
is(menulist.activeChild.label, menulist.getItemAtIndex(test.downs[i]).label, test.list + " page down " + i);
}
for (let i = 0; i < test.ups.length; i++) {
sendKey("PAGE_UP");
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.ups[i]).label, test.list + " page up " + i);
is(menulist.activeChild.label, menulist.getItemAtIndex(test.ups[i]).label, test.list + " page up " + i);
}
menulist.open = false;

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

@ -252,11 +252,9 @@ function goNextStepSync() {
function openMenu(menu) {
if ("open" in menu) {
menu.open = true;
} else if (menu.hasMenu()) {
menu.openMenu(true);
} else {
var bo = menu.boxObject;
if (bo instanceof MenuBoxObject)
bo.openMenu(true);
else
synthesizeMouse(menu, 4, 4, { });
}
}
@ -264,11 +262,9 @@ function openMenu(menu) {
function closeMenu(menu, popup) {
if ("open" in menu) {
menu.open = false;
} else if (menu.hasMenu()) {
menu.openMenu(false);
} else {
var bo = menu.boxObject;
if (bo instanceof MenuBoxObject)
bo.openMenu(false);
else
popup.hidePopup();
}
}
@ -291,7 +287,7 @@ function checkOpen(menuid, testname) {
var menu = document.getElementById(menuid);
if ("open" in menu)
ok(menu.open, testname + " " + menuid + " menu is open");
else if (menu.boxObject instanceof MenuBoxObject)
else if (menu.hasMenu())
ok(menu.getAttribute("open") == "true", testname + " " + menuid + " menu is open");
}
@ -299,7 +295,7 @@ function checkClosed(menuid, testname) {
var menu = document.getElementById(menuid);
if ("open" in menu)
ok(!menu.open, testname + " " + menuid + " menu is open");
else if (menu.boxObject instanceof MenuBoxObject)
else if (menu.hasMenu())
ok(!menu.hasAttribute("open"), testname + " " + menuid + " menu is closed");
}

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

@ -25,8 +25,8 @@
<property name="open" onget="return this.hasAttribute('open');">
<setter><![CDATA[
if (this.boxObject instanceof MenuBoxObject) {
this.boxObject.openMenu(val);
if (this.hasMenu()) {
this.openMenu(val);
} else if (val) {
// Fall back to just setting the attribute
this.setAttribute("open", "true");
@ -128,7 +128,7 @@
<handler event="keypress">
<![CDATA[
if (this.boxObject instanceof MenuBoxObject) {
if (this.hasMenu()) {
if (this.open)
return;
} else {

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

@ -48,17 +48,11 @@
<implementation implements="nsIDOMXULContainerElement">
<property name="open" onget="return this.hasAttribute('open');">
<setter><![CDATA[
this.boxObject.openMenu(val);
this.openMenu(val);
return val;
]]></setter>
</property>
<property name="openedWithKey" readonly="true">
<getter><![CDATA[
return this.boxObject.openedWithKey;
]]></getter>
</property>
<!-- nsIDOMXULContainerElement interface -->
<method name="appendItem">
<parameter name="aLabel"/>

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

@ -29,11 +29,11 @@
<handler event="popupshowing">
<![CDATA[
if (event.target.parentNode == this) {
this.menuBoxObject.activeChild = null;
this.activeChild = null;
if (this.selectedItem)
// Not ready for auto-setting the active child in hierarchies yet.
// For now, only do this when the outermost menupopup opens.
this.menuBoxObject.activeChild = this.mSelectedInternal;
this.activeChild = this.mSelectedInternal;
}
]]>
</handler>
@ -50,9 +50,9 @@
event.keyCode == KeyEvent.DOM_VK_BACK_SPACE ||
event.charCode > 0)) {
// Moving relative to an item: start from the currently selected item
this.menuBoxObject.activeChild = this.mSelectedInternal;
if (this.menuBoxObject.handleKeyPress(event)) {
this.menuBoxObject.activeChild.doCommand();
this.activeChild = this.mSelectedInternal;
if (this.handleKeyPress(event)) {
this.activeChild.doCommand();
event.preventDefault();
}
}
@ -64,7 +64,6 @@
<constructor>
this.mSelectedInternal = null;
this.mAttributeObserver = null;
this.menuBoxObject = this.boxObject;
this.setInitialSelection();
</constructor>
@ -121,8 +120,7 @@
<property name="description" onset="this.setAttribute('description',val); return val;"
onget="return this.getAttribute('description');"/>
<property name="open" onset="this.menuBoxObject.openMenu(val);
return val;"
<property name="open" onset="this.openMenu(val); return val;"
onget="return this.hasAttribute('open');"/>
<property name="itemCount" readonly="true"

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

@ -432,7 +432,7 @@ function populateChildren(menulist, options, selectedIndex, zoom,
// may have been removed from the selected item. Since that's normally only
// set for the initially selected on popupshowing for the menulist, and we
// don't want to close and re-open the popup, we manually set it here.
menulist.menuBoxObject.activeChild = item;
menulist.activeChild = item;
}
item.setAttribute("value", option.index);
@ -471,7 +471,7 @@ function populateChildren(menulist, options, selectedIndex, zoom,
searchbox.blur();
if (searchbox.nextElementSibling.localName == "menuitem" &&
!searchbox.nextElementSibling.hidden) {
menulist.menuBoxObject.activeChild = searchbox.nextElementSibling;
menulist.activeChild = searchbox.nextElementSibling;
} else {
var currentOption = searchbox.nextElementSibling;
while (currentOption && (currentOption.localName != "menuitem" ||
@ -479,7 +479,7 @@ function populateChildren(menulist, options, selectedIndex, zoom,
currentOption = currentOption.nextElementSibling;
}
if (currentOption) {
menulist.menuBoxObject.activeChild = currentOption;
menulist.activeChild = currentOption;
} else {
searchbox.focus();
}
@ -556,7 +556,7 @@ function onSearchInput() {
function onSearchFocus() {
let searchObj = this;
let menupopup = searchObj.parentElement;
menupopup.parentElement.menuBoxObject.activeChild = null;
menupopup.parentElement.activeChild = null;
menupopup.setAttribute("ignorekeys", "true");
currentBrowser.messageManager.sendAsyncMessage("Forms:SearchFocused", {});
}