mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 23:05:42 +00:00
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
commit
04ab391b65
@ -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,17 +1097,18 @@ 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,33 +1299,22 @@ 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();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> wrapper;
|
||||
nsresult rv = xpConnect->WrapJSAggregatedToNative(aElement, cx, customInterface,
|
||||
aIID, getter_AddRefs(wrapper));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return wrapper.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();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDocument> doc = GetUncomposedDoc();
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(FlushType::Frames);
|
||||
}
|
||||
|
||||
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
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.
|
||||
|
5
js/src/jit-test/tests/basic/recompute-wrappers.js
Normal file
5
js/src/jit-test/tests/basic/recompute-wrappers.js
Normal file
@ -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,20 +257,20 @@ 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});
|
||||
is(list.open, ismac, "alt+up closes popup");
|
||||
|
||||
|
||||
if (ismac) {
|
||||
list.open = false;
|
||||
}
|
||||
|
@ -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,24 +252,20 @@ 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, { });
|
||||
synthesizeMouse(menu, 4, 4, { });
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
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", {});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user