--- a/browser/base/content/test/forms/browser_selectpopup.js
+++ b/browser/base/content/test/forms/browser_selectpopup.js
@@ -140,36 +140,36 @@ async function doSelectTests(contentType
is(menulist.selectedIndex, 1, "Initial selection");
is(selectPopup.firstChild.localName, "menucaption", "optgroup is caption");
is(selectPopup.firstChild.getAttribute("label"), "First Group", "optgroup label");
is(selectPopup.childNodes[1].localName, "menuitem", "option is menuitem");
is(selectPopup.childNodes[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");
for (let i = 0; i < 10; i++) {
is(menulist.getItemAtIndex(i).disabled, i >= 4 && i <= 7, "item " + i + " disabled");
}
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");
is((await getChangeEvents()), 0, "Before closed - number of change events");
is((await getClickEvents()), 0, "Before closed - number of click events");
EventUtils.synthesizeKey("a", { accelKey: true });
await ContentTask.spawn(gBrowser.selectedBrowser, { isWindows }, function(args) {
--- a/browser/base/content/test/general/browser_bug647886.js
+++ b/browser/base/content/test/general/browser_bug647886.js
@@ -3,18 +3,20 @@
add_task(async function() {
await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
await ContentTask.spawn(gBrowser.selectedBrowser, {}, 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");
let popupShownPromise = BrowserTestUtils.waitForEvent(backButton, "popupshown");
EventUtils.synthesizeMouseAtCenter(backButton, {type: "mousedown"});
EventUtils.synthesizeMouse(backButton, rect.width / 2, rect.height, {type: "mouseup"});
let event = await popupShownPromise;
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -251,17 +251,16 @@
#include "mozilla/ServoStyleSet.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/dom/SVGDocument.h"
#include "mozilla/dom/SVGSVGElement.h"
#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 "nsIDocShellTreeOwner.h"
#endif
#include "nsIPresShellInlines.h"
#include "mozilla/DocLoadingTimelineMarker.h"
@@ -6393,19 +6392,17 @@ nsIDocument::GetBoxObjectFor(Element* aE
boxObject = entry.Data();
return boxObject.forget();
}
int32_t namespaceID;
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();
}
} else
#endif // MOZ_XUL
{
boxObject = new BoxObject();
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -44,16 +44,17 @@
#include "mozilla/dom/ElementBinding.h"
#include "mozilla/dom/HTMLObjectElement.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLEmbedElement.h"
#include "mozilla/dom/HTMLElementBinding.h"
#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"
#include "mozilla/dom/WebIDLGlobalNameHash.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/dom/WorkerScope.h"
#include "mozilla/dom/XrayExpandoClass.h"
#include "mozilla/dom/XULScrollElementBinding.h"
@@ -3859,16 +3860,19 @@ HTMLConstructor(JSContext* aCx, unsigned
definition->mLocalName == nsGkAtoms::popup ||
definition->mLocalName == nsGkAtoms::panel ||
definition->mLocalName == nsGkAtoms::tooltip) {
cb = XULPopupElement_Binding::GetConstructorObject;
} else if (definition->mLocalName == nsGkAtoms::iframe ||
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 {
cb = XULElement_Binding::GetConstructorObject;
}
}
if (!cb) {
rename from dom/webidl/MenuBoxObject.webidl
rename to dom/chrome-webidl/XULMenuElement.webidl
--- a/dom/webidl/MenuBoxObject.webidl
+++ b/dom/chrome-webidl/XULMenuElement.webidl
@@ -1,19 +1,17 @@
/* -*- 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/.
*/
-[Func="IsChromeOrXBL"]
-interface MenuBoxObject : BoxObject {
-
- void openMenu(boolean openFlag);
+[HTMLConstructor, Func="IsChromeOrXBL"]
+interface XULMenuElement : XULElement {
attribute Element? activeChild;
boolean handleKeyPress(KeyboardEvent keyEvent);
- readonly attribute boolean openedWithKey;
+ readonly attribute boolean openWithKey;
};
--- a/dom/chrome-webidl/moz.build
+++ b/dom/chrome-webidl/moz.build
@@ -42,16 +42,17 @@ WEBIDL_FILES = [
'MozStorageStatementParams.webidl',
'MozStorageStatementRow.webidl',
'PrecompiledScript.webidl',
'PromiseDebugging.webidl',
'StructuredCloneHolder.webidl',
'WebExtensionContentScript.webidl',
'WebExtensionPolicy.webidl',
'XULFrameElement.webidl',
+ 'XULMenuElement.webidl',
'XULScrollElement.webidl'
]
if CONFIG['MOZ_PLACES']:
WEBIDL_FILES += [
'PlacesEvent.webidl',
'PlacesObservers.webidl',
]
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -655,18 +655,16 @@ var interfaceNamesInGlobalScope =
{name: "MediaStreamAudioSourceNode", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MediaStreamEvent", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{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!
{name: "MessageEvent", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MessagePort", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MIDIAccess", disabled: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
@@ -1249,16 +1247,18 @@ var interfaceNamesInGlobalScope =
{name: "XULCommandEvent", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "XULDocument", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{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!
{name: "XULScrollElement", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
];
// IMPORTANT: Do not change the list above without review from a DOM peer!
function createInterfaceMap(isXBLScope) {
--- a/dom/webidl/XULElement.webidl
+++ b/dom/webidl/XULElement.webidl
@@ -3,16 +3,18 @@
* 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/.
*/
interface XULControllers;
[HTMLConstructor, Func="IsChromeOrXBL"]
interface XULElement : Element {
+
+ void openMenu(boolean openFlag);
// Layout properties
[SetterThrows]
attribute DOMString align;
[SetterThrows]
attribute DOMString dir;
[SetterThrows]
attribute DOMString flex;
[SetterThrows]
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -655,17 +655,16 @@ WEBIDL_FILES = [
'MediaStream.webidl',
'MediaStreamAudioDestinationNode.webidl',
'MediaStreamAudioSourceNode.webidl',
'MediaStreamError.webidl',
'MediaStreamTrack.webidl',
'MediaTrackConstraintSet.webidl',
'MediaTrackSettings.webidl',
'MediaTrackSupportedConstraints.webidl',
- 'MenuBoxObject.webidl',
'MessageChannel.webidl',
'MessageEvent.webidl',
'MessagePort.webidl',
'MIDIAccess.webidl',
'MIDIInput.webidl',
'MIDIInputMap.webidl',
'MIDIMessageEvent.webidl',
'MIDIOptions.webidl',
rename from layout/xul/MenuBoxObject.cpp
rename to dom/xul/XULMenuElement.cpp
--- a/layout/xul/MenuBoxObject.cpp
+++ b/dom/xul/XULMenuElement.cpp
@@ -1,100 +1,71 @@
/* -*- 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/. */
-#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"
#include "nsIFrame.h"
#include "nsMenuBarFrame.h"
#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()
-{
-}
-
-MenuBoxObject::~MenuBoxObject()
-{
-}
-
-JSObject* MenuBoxObject::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return MenuBoxObject_Binding::Wrap(aCx, this, aGivenProto);
-}
-
-void MenuBoxObject::OpenMenu(bool aOpenFlag)
+JSObject*
+XULMenuElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
- 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 XULMenuElement_Binding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<Element>
-MenuBoxObject::GetActiveChild()
+XULMenuElement::GetActiveChild()
{
- nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
+ nsMenuFrame* menu = do_QueryFrame(GetPrimaryFrame());
if (menu) {
RefPtr<Element> el;
menu->GetActiveChild(getter_AddRefs(el));
return el.forget();
}
return nullptr;
}
-void MenuBoxObject::SetActiveChild(Element* arg)
+void XULMenuElement::SetActiveChild(Element* arg)
{
- nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
+ nsMenuFrame* menu = do_QueryFrame(GetPrimaryFrame());
if (menu) {
menu->SetActiveChild(arg);
}
}
-bool MenuBoxObject::HandleKeyPress(KeyboardEvent& keyEvent)
+bool XULMenuElement::HandleKeyPress(KeyboardEvent& keyEvent)
{
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (!pm) {
return false;
}
// if event has already been handled, bail
if (keyEvent.DefaultPrevented()) {
return false;
}
if (nsMenuBarListener::IsAccessKeyPressed(&keyEvent))
return false;
- nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
+ nsMenuFrame* menu = do_QueryFrame(GetPrimaryFrame());
if (!menu) {
return false;
}
nsMenuPopupFrame* popupFrame = menu->GetPopup();
if (!popupFrame) {
return false;
}
@@ -110,19 +81,19 @@ bool MenuBoxObject::HandleKeyPress(Keybo
theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode);
return pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection);
}
default:
return pm->HandleShortcutNavigation(&keyEvent, popupFrame);
}
}
-bool MenuBoxObject::OpenedWithKey()
+bool XULMenuElement::OpenWithKey()
{
- nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false));
+ nsMenuFrame* menuframe = do_QueryFrame(GetPrimaryFrame());
if (!menuframe) {
return false;
}
nsIFrame* frame = menuframe->GetParent();
while (frame) {
nsMenuBarFrame* menubar = do_QueryFrame(frame);
if (menubar) {
@@ -130,19 +101,8 @@ bool MenuBoxObject::OpenedWithKey()
}
frame = frame->GetParent();
}
return false;
}
} // namespace dom
} // namespace mozilla
-
-// Creation Routine ///////////////////////////////////////////////////////////////////////
-
-using namespace mozilla::dom;
-
-nsresult
-NS_NewMenuBoxObject(nsIBoxObject** aResult)
-{
- NS_ADDREF(*aResult = new MenuBoxObject());
- return NS_OK;
-}
rename from layout/xul/MenuBoxObject.h
rename to dom/xul/XULMenuElement.h
--- a/layout/xul/MenuBoxObject.h
+++ b/dom/xul/XULMenuElement.h
@@ -1,38 +1,39 @@
/* -*- 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
+#ifndef mozilla_dom_XULMenuElement_h
+#define mozilla_dom_XULMenuElement_h
-#include "mozilla/dom/BoxObject.h"
+#include "nsXULElement.h"
namespace mozilla {
namespace dom {
class KeyboardEvent;
-class MenuBoxObject final : public BoxObject
+class XULMenuElement final : public nsXULElement
{
public:
- MenuBoxObject();
+ explicit XULMenuElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo): nsXULElement(aNodeInfo)
+ {
+ }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- void OpenMenu(bool aOpenFlag);
+ // void OpenMenu(bool aOpenFlag);
already_AddRefed<Element> GetActiveChild();
void SetActiveChild(Element* arg);
bool HandleKeyPress(KeyboardEvent& keyEvent);
- bool OpenedWithKey();
+ bool OpenWithKey();
private:
- ~MenuBoxObject();
+ virtual ~XULMenuElement() {}
+ JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) final;
};
} // namespace dom
} // namespace mozilla
-#endif // mozilla_dom_MenuBoxObject_h
+#endif // XULMenuElement_h
--- a/dom/xul/moz.build
+++ b/dom/xul/moz.build
@@ -16,31 +16,33 @@ MOCHITEST_CHROME_MANIFESTS += ['test/chr
if CONFIG['MOZ_XUL']:
EXPORTS += [
'nsXULElement.h',
]
EXPORTS.mozilla.dom += [
'XULFrameElement.h',
+ 'XULMenuElement.h',
'XULPopupElement.h',
'XULScrollElement.h',
]
UNIFIED_SOURCES += [
'nsXULCommandDispatcher.cpp',
'nsXULContentSink.cpp',
'nsXULContentUtils.cpp',
'nsXULElement.cpp',
'nsXULPopupListener.cpp',
'nsXULPrototypeCache.cpp',
'nsXULPrototypeDocument.cpp',
'nsXULSortService.cpp',
'XULDocument.cpp',
'XULFrameElement.cpp',
+ 'XULMenuElement.cpp',
'XULPopupElement.cpp',
'XULScrollElement.cpp',
]
XPIDL_SOURCES += [
'nsIController.idl',
'nsIControllers.idl',
'nsIXULSortService.idl',
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -68,16 +68,17 @@
#include "nsXBLBinding.h"
#include "nsXULTooltipListener.h"
#include "mozilla/EventDispatcher.h"
#include "mozAutoDocUpdate.h"
#include "nsCCUncollectableMarker.h"
#include "nsICSSDeclaration.h"
#include "nsLayoutUtils.h"
#include "XULFrameElement.h"
+#include "XULMenuElement.h"
#include "XULPopupElement.h"
#include "XULScrollElement.h"
#include "mozilla/dom/XULElementBinding.h"
#include "mozilla/dom/BoxObject.h"
#include "mozilla/dom/MouseEventBinding.h"
#include "mozilla/dom/MutationEventBinding.h"
#include "mozilla/dom/XULCommandEvent.h"
@@ -152,16 +153,22 @@ nsXULElement* nsXULElement::Construct(al
if (nodeInfo->Equals(nsGkAtoms::iframe) ||
nodeInfo->Equals(nsGkAtoms::browser) ||
nodeInfo->Equals(nsGkAtoms::editor)) {
already_AddRefed<mozilla::dom::NodeInfo> frameni = nodeInfo.forget();
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);
}
return NS_NewBasicXULElement(nodeInfo.forget());
}
@@ -492,16 +499,39 @@ nsXULElement::IsFocusableInternal(int32_
} else {
shouldFocus = *aTabIndex >= 0;
}
}
return shouldFocus;
}
+void
+nsXULElement::OpenMenu(bool aOpenFlag)
+{
+ nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+ if (pm) {
+ nsIFrame* frame = GetPrimaryFrame();
+ if (frame) {
+ if (aOpenFlag) {
+ // nsCOMPtr<nsIContent> content = mContent;
+ pm->ShowMenu(this, false, false);
+ }
+ else {
+ nsMenuFrame* menu = do_QueryFrame(frame);
+ if (menu) {
+ nsMenuPopupFrame* popupFrame = menu->GetPopup();
+ if (popupFrame)
+ pm->HidePopup(popupFrame->GetContent(), false, true, false, false);
+ }
+ }
+ }
+ }
+}
+
bool
nsXULElement::PerformAccesskey(bool aKeyCausesActivation,
bool aIsTrustedEvent)
{
RefPtr<Element> content(this);
if (IsXULElement(nsGkAtoms::label)) {
nsAutoString control;
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -370,16 +370,18 @@ public:
#ifdef DEBUG
virtual void List(FILE* out, int32_t aIndent) const override;
virtual void DumpContent(FILE* out, int32_t aIndent,bool aDumpAll) const override
{
}
#endif
+ void OpenMenu(bool aOpenFlag);
+
virtual bool PerformAccesskey(bool aKeyCausesActivation,
bool aIsTrustedEvent) override;
void ClickWithInputSource(uint16_t aInputSource, bool aIsTrustedEvent);
nsIContent* GetBindingParent() const final
{
return mBindingParent;
}
--- a/layout/build/nsLayoutCID.h
+++ b/layout/build/nsLayoutCID.h
@@ -14,20 +14,16 @@
/* a6cf90f9-15b3-11d2-932e-00805f8add32 */
#define NS_LAYOUT_DEBUGGER_CID \
{ 0xa6cf90f9, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
// {D750A964-2D14-484c-B3AA-8ED7823B5C7B}
#define NS_BOXOBJECT_CID \
{ 0xd750a964, 0x2d14, 0x484c, { 0xb3, 0xaa, 0x8e, 0xd7, 0x82, 0x3b, 0x5c, 0x7b } }
-// {AA40253B-4C42-4056-8132-37BCD07862FD}
-#define NS_MENUBOXOBJECT_CID \
-{ 0xaa40253b, 0x4c42, 0x4056, { 0x81, 0x32, 0x37, 0xbc, 0xd0, 0x78, 0x62, 0xfd } }
-
// {3B581FD4-3497-426c-8F61-3658B971CB80}
#define NS_TREEBOXOBJECT_CID \
{ 0x3b581fd4, 0x3497, 0x426c, { 0x8f, 0x61, 0x36, 0x58, 0xb9, 0x71, 0xcb, 0x80 } }
// {2fe88332-31c6-4829-b247-a07d8a73e80f}
#define NS_CANVASRENDERINGCONTEXTWEBGL_CID \
{ 0x2fe88332, 0x31c6, 0x4829, { 0xb2, 0x47, 0xa0, 0x7d, 0x8a, 0x7e, 0xe8, 0x0fe } }
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -295,17 +295,16 @@ Shutdown()
#ifdef DEBUG
nsresult NS_NewLayoutDebugger(nsILayoutDebugger** aResult);
#endif
nsresult NS_NewBoxObject(nsIBoxObject** aResult);
#ifdef MOZ_XUL
-nsresult NS_NewMenuBoxObject(nsIBoxObject** aResult);
nsresult NS_NewTreeBoxObject(nsIBoxObject** aResult);
#endif
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
already_AddRefed<nsIContentViewer> NS_NewContentViewer();
nsresult NS_NewContentDocumentLoaderFactory(nsIDocumentLoaderFactory** aResult);
nsresult NS_NewHTMLCopyTextEncoder(nsIDocumentEncoder** aResult);
@@ -355,17 +354,16 @@ ctor_(nsISupports* aOuter, REFNSIID aIID
#ifdef DEBUG
MAKE_CTOR(CreateNewLayoutDebugger, nsILayoutDebugger, NS_NewLayoutDebugger)
#endif
MAKE_CTOR(CreateNewFrameTraversal, nsIFrameTraversal, NS_CreateFrameTraversal)
MAKE_CTOR(CreateNewBoxObject, nsIBoxObject, NS_NewBoxObject)
#ifdef MOZ_XUL
-MAKE_CTOR(CreateNewMenuBoxObject, nsIBoxObject, NS_NewMenuBoxObject)
MAKE_CTOR(CreateNewTreeBoxObject, nsIBoxObject, NS_NewTreeBoxObject)
#endif // MOZ_XUL
NS_GENERIC_FACTORY_CONSTRUCTOR(inDeepTreeWalker)
MAKE_CTOR2(CreateContentViewer, nsIContentViewer, NS_NewContentViewer)
MAKE_CTOR(CreateHTMLDocument, nsIDocument, NS_NewHTMLDocument)
MAKE_CTOR(CreateXMLDocument, nsIDocument, NS_NewXMLDocument)
@@ -496,17 +494,16 @@ Construct_nsIScriptSecurityManager(nsISu
}
#ifdef DEBUG
NS_DEFINE_NAMED_CID(NS_LAYOUT_DEBUGGER_CID);
#endif
NS_DEFINE_NAMED_CID(NS_FRAMETRAVERSAL_CID);
NS_DEFINE_NAMED_CID(NS_BOXOBJECT_CID);
#ifdef MOZ_XUL
-NS_DEFINE_NAMED_CID(NS_MENUBOXOBJECT_CID);
NS_DEFINE_NAMED_CID(NS_TREEBOXOBJECT_CID);
#endif // MOZ_XUL
NS_DEFINE_NAMED_CID(IN_DEEPTREEWALKER_CID);
NS_DEFINE_NAMED_CID(NS_CONTENT_VIEWER_CID);
NS_DEFINE_NAMED_CID(NS_HTMLDOCUMENT_CID);
NS_DEFINE_NAMED_CID(NS_XMLDOCUMENT_CID);
NS_DEFINE_NAMED_CID(NS_SVGDOCUMENT_CID);
NS_DEFINE_NAMED_CID(NS_IMAGEDOCUMENT_CID);
@@ -736,17 +733,16 @@ nsEditingCommandTableConstructor(nsISupp
static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
XPCONNECT_CIDENTRIES
#ifdef DEBUG
{ &kNS_LAYOUT_DEBUGGER_CID, false, nullptr, CreateNewLayoutDebugger },
#endif
{ &kNS_FRAMETRAVERSAL_CID, false, nullptr, CreateNewFrameTraversal },
{ &kNS_BOXOBJECT_CID, false, nullptr, CreateNewBoxObject },
#ifdef MOZ_XUL
- { &kNS_MENUBOXOBJECT_CID, false, nullptr, CreateNewMenuBoxObject },
{ &kNS_TREEBOXOBJECT_CID, false, nullptr, CreateNewTreeBoxObject },
#endif // MOZ_XUL
{ &kIN_DEEPTREEWALKER_CID, false, nullptr, inDeepTreeWalkerConstructor },
{ &kNS_CONTENT_VIEWER_CID, false, nullptr, CreateContentViewer },
{ &kNS_HTMLDOCUMENT_CID, false, nullptr, CreateHTMLDocument },
{ &kNS_XMLDOCUMENT_CID, false, nullptr, CreateXMLDocument },
{ &kNS_SVGDOCUMENT_CID, false, nullptr, CreateSVGDocument },
{ &kNS_IMAGEDOCUMENT_CID, false, nullptr, CreateImageDocument },
@@ -842,17 +838,16 @@ static const mozilla::Module::CIDEntry k
{ &kNS_SCRIPTERROR_CID, false, nullptr, nsScriptErrorConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
XPCONNECT_CONTRACTS
{ "@mozilla.org/layout/xul-boxobject;1", &kNS_BOXOBJECT_CID },
#ifdef MOZ_XUL
- { "@mozilla.org/layout/xul-boxobject-menu;1", &kNS_MENUBOXOBJECT_CID },
{ "@mozilla.org/layout/xul-boxobject-tree;1", &kNS_TREEBOXOBJECT_CID },
#endif // MOZ_XUL
{ "@mozilla.org/inspector/deep-tree-walker;1", &kIN_DEEPTREEWALKER_CID },
{ "@mozilla.org/xml/xml-document;1", &kNS_XMLDOCUMENT_CID },
{ "@mozilla.org/svg/svg-document;1", &kNS_SVGDOCUMENT_CID },
{ "@mozilla.org/content/post-content-iterator;1", &kNS_CONTENTITERATOR_CID },
{ "@mozilla.org/content/pre-content-iterator;1", &kNS_PRECONTENTITERATOR_CID },
{ "@mozilla.org/content/subtree-content-iterator;1", &kNS_SUBTREEITERATOR_CID },
--- a/layout/xul/moz.build
+++ b/layout/xul/moz.build
@@ -26,17 +26,16 @@ EXPORTS += [
'nsIScrollbarMediator.h',
'nsPIBoxObject.h',
'nsXULPopupManager.h',
'nsXULTooltipListener.h',
]
EXPORTS.mozilla.dom += [
'BoxObject.h',
- 'MenuBoxObject.h',
]
UNIFIED_SOURCES += [
'BoxObject.cpp',
'nsBox.cpp',
'nsBoxFrame.cpp',
'nsBoxLayout.cpp',
'nsBoxLayoutState.cpp',
@@ -49,17 +48,16 @@ UNIFIED_SOURCES += [
'nsSprocketLayout.cpp',
'nsStackFrame.cpp',
'nsStackLayout.cpp',
'nsXULTooltipListener.cpp',
]
if CONFIG['MOZ_XUL']:
UNIFIED_SOURCES += [
- 'MenuBoxObject.cpp',
'nsDeckFrame.cpp',
'nsDocElementBoxFrame.cpp',
'nsGroupBoxFrame.cpp',
'nsImageBoxFrame.cpp',
'nsLeafBoxFrame.cpp',
'nsMenuBarFrame.cpp',
'nsMenuBarListener.cpp',
'nsMenuFrame.cpp',
--- a/layout/xul/nsDeckFrame.cpp
+++ b/layout/xul/nsDeckFrame.cpp
@@ -22,16 +22,17 @@
#include "nsIPresShell.h"
#include "nsCSSRendering.h"
#include "nsViewManager.h"
#include "nsBoxLayoutState.h"
#include "nsStackLayout.h"
#include "nsDisplayList.h"
#include "nsContainerFrame.h"
#include "nsContentUtils.h"
+#include "nsXULPopupManager.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
#endif
nsIFrame*
NS_NewDeckFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle)
{
--- a/layout/xul/nsProgressMeterFrame.cpp
+++ b/layout/xul/nsProgressMeterFrame.cpp
@@ -59,17 +59,17 @@ nsReflowFrameRunnable::Run()
}
//
// NS_NewToolbarFrame
//
// 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);
}
NS_IMPL_FRAMEARENA_HELPERS(nsProgressMeterFrame)
//
// nsProgressMeterFrame dstr
--- a/toolkit/content/tests/chrome/popup_trigger.js
+++ b/toolkit/content/tests/chrome/popup_trigger.js
@@ -24,17 +24,17 @@ function cacheEvent(modifiers) {
function runTests() {
if (screen.height < 768) {
ok(false, "popup tests are likely to fail for screen heights less than 768 pixels");
}
gMenuPopup = document.getElementById("thepopup");
gTrigger = document.getElementById("trigger");
- gIsMenu = gTrigger.boxObject instanceof MenuBoxObject;
+ gIsMenu = gTrigger instanceof XULElement;
// a hacky way to get the screen position of the document. Cache the event
// so that we can use it in calls to openPopup.
gCachedEvent = cacheEvent({ shiftKey: true });
gScreenX = gCachedEvent.screenX;
gScreenY = gCachedEvent.screenY;
gCachedEvent2 = cacheEvent({ altKey: true, ctrlKey: true, shiftKey: true, metaKey: true });
--- a/toolkit/content/tests/chrome/test_menulist.xul
+++ b/toolkit/content/tests/chrome/test_menulist.xul
@@ -269,17 +269,17 @@ function test_menulist_open(element, scr
*/
// bug 543065, hovering the mouse over an item should highlight it, not
// scroll the parent, and not change the selected index.
var item = element.menupopup.childNodes[1];
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);
element.open = false;
}
function checkScrollAndFinish()
{
--- a/toolkit/content/tests/chrome/test_menulist_keynav.xul
+++ b/toolkit/content/tests/chrome/test_menulist_keynav.xul
@@ -55,21 +55,21 @@ function runTests()
keyCheck(list, "KEY_ArrowDown", 3, 1, "cursor down skip disabled");
keyCheck(list, "KEY_ArrowUp", 2, 1, "cursor up skip disabled");
keyCheck(list, "KEY_ArrowUp", 1, 1, "cursor up");
// On Windows, wrapping doesn't occur.
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
synthesizeKey("KEY_ArrowDown", {altKey: !ismac});
is(list.selectedItem, $("i1"), "open menulist down selectedItem");
synthesizeKey("KEY_ArrowUp", {altKey: !ismac});
is(list.selectedItem, $("i1"), "open menulist up selectedItem");
@@ -166,17 +166,17 @@ function tabAndScroll()
list.open = true;
var rowdiff = list.getItemAtIndex(1).getBoundingClientRect().top -
list.getItemAtIndex(0).getBoundingClientRect().top;
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);
originalPosition = item.getBoundingClientRect().top;
synthesizeKey("KEY_ArrowDown");
is(item.getBoundingClientRect().top, originalPosition - rowdiff, "position of item 10");
@@ -252,30 +252,30 @@ function checkCursorNavigation()
is(list.menupopup.state, "open", "cursor down popup state");
synthesizeKey("KEY_PageDown");
is(list.selectedIndex, iswin ? 3 : 1, "selectedIndex after page down");
is(commandEventsCount, iswin ? 2 : 0, "selectedIndex after page down command event");
is(list.menupopup.state, "open", "page down popup state");
// 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;
}
SimpleTest.finish();
}
SimpleTest.waitForFocus(runTests);
--- a/toolkit/content/tests/chrome/test_menulist_paging.xul
+++ b/toolkit/content/tests/chrome/test_menulist_paging.xul
@@ -119,36 +119,36 @@ function runTest()
test = tests.shift();
document.getElementById(test.list).open = true;
}
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);
// Skip menulist3 as it has a label that scrolling doesn't need normally deal with.
if (test.scroll >= 0) {
is(menulist.menupopup.childNodes[test.scroll].getBoundingClientRect().top,
menulist.menupopup.getBoundingClientRect().top + bpTop,
"Popup scroll at correct position");
}
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;
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
--- a/toolkit/content/tests/widgets/popup_shared.js
+++ b/toolkit/content/tests/widgets/popup_shared.js
@@ -247,33 +247,29 @@ function goNextStepSync() {
} else {
finish();
}
}
function openMenu(menu) {
if ("open" in menu) {
menu.open = true;
+ } else if (menu instanceof XULElement) {
+ menu.openMenu(true);
} else {
- var bo = menu.boxObject;
- if (bo instanceof MenuBoxObject)
- bo.openMenu(true);
- else
synthesizeMouse(menu, 4, 4, { });
}
}
function closeMenu(menu, popup) {
if ("open" in menu) {
menu.open = false;
+ } else if (menu instanceof XULElement) {
+ menu.openMenu(false);
} else {
- var bo = menu.boxObject;
- if (bo instanceof MenuBoxObject)
- bo.openMenu(false);
- else
popup.hidePopup();
}
}
function checkActive(popup, id, testname) {
var activeok = true;
var children = popup.childNodes;
for (var c = 0; c < children.length; c++) {
@@ -286,25 +282,25 @@ function checkActive(popup, id, testname
}
ok(activeok, testname + " item " + (id ? id : "none") + " active");
}
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 instanceof XULElement)
ok(menu.getAttribute("open") == "true", testname + " " + menuid + " menu is open");
}
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 instanceof XULElement)
ok(!menu.hasAttribute("open"), testname + " " + menuid + " menu is closed");
}
function convertPosition(anchor, align) {
if (anchor == "topleft" && align == "topleft") return "overlap";
if (anchor == "topleft" && align == "topright") return "start_before";
if (anchor == "topleft" && align == "bottomleft") return "before_start";
if (anchor == "topright" && align == "topleft") return "end_before";
--- a/toolkit/content/widgets/button.xml
+++ b/toolkit/content/widgets/button.xml
@@ -18,30 +18,16 @@
<property name="dlgType"
onget="return this.getAttribute('dlgtype');"
onset="this.setAttribute('dlgtype', val); return val;"/>
<property name="group"
onget="return this.getAttribute('group');"
onset="this.setAttribute('group', val); return val;"/>
- <property name="open" onget="return this.hasAttribute('open');">
- <setter><![CDATA[
- if (this.boxObject instanceof MenuBoxObject) {
- this.boxObject.openMenu(val);
- } else if (val) {
- // Fall back to just setting the attribute
- this.setAttribute("open", "true");
- } else {
- this.removeAttribute("open");
- }
- return val;
- ]]></setter>
- </property>
-
<property name="checked" onget="return this.hasAttribute('checked');">
<setter><![CDATA[
if (this.type == "radio" && val) {
var sibs = this.parentNode.getElementsByAttribute("group", this.group);
for (var i = 0; i < sibs.length; ++i)
sibs[i].removeAttribute("checked");
}
@@ -123,17 +109,17 @@
this._handleClick();
// Prevent page from scrolling on the space key.
event.preventDefault();
]]>
</handler>
<handler event="keypress">
<![CDATA[
- if (this.boxObject instanceof MenuBoxObject) {
+ if (this instanceof XULElement) {
if (this.open)
return;
} else {
if (event.keyCode == KeyEvent.DOM_VK_UP ||
(event.keyCode == KeyEvent.DOM_VK_LEFT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "ltr") ||
(event.keyCode == KeyEvent.DOM_VK_RIGHT &&
--- a/toolkit/content/widgets/menu.xml
+++ b/toolkit/content/widgets/menu.xml
@@ -43,27 +43,21 @@
</binding>
<binding id="menu-base"
extends="chrome://global/content/bindings/menu.xml#menuitem-base">
<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"/>
<parameter name="aValue"/>
<body>
const XUL_NS =
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
--- a/toolkit/content/widgets/menulist.xml
+++ b/toolkit/content/widgets/menulist.xml
@@ -24,339 +24,46 @@
<handlers>
<handler event="command" phase="capturing"
action="if (event.target.parentNode.parentNode == this) this.selectedItem = event.target;"/>
<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>
<handler event="keypress" modifiers="shift any" group="system">
<![CDATA[
if (!event.defaultPrevented &&
(event.keyCode == KeyEvent.DOM_VK_UP ||
event.keyCode == KeyEvent.DOM_VK_DOWN ||
event.keyCode == KeyEvent.DOM_VK_PAGE_UP ||
event.keyCode == KeyEvent.DOM_VK_PAGE_DOWN ||
event.keyCode == KeyEvent.DOM_VK_HOME ||
event.keyCode == KeyEvent.DOM_VK_END ||
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();
}
}
]]>
</handler>
</handlers>
-
- <implementation implements="nsIDOMXULMenuListElement">
- <constructor>
- this.mInputField = null;
- this.mSelectedInternal = null;
- this.mAttributeObserver = null;
- this.menuBoxObject = this.boxObject;
- this.setInitialSelection();
- </constructor>
-
- <method name="setInitialSelection">
- <body>
- <![CDATA[
- var popup = this.menupopup;
- if (popup) {
- var arr = popup.getElementsByAttribute("selected", "true");
-
- var editable = this.editable;
- var value = this.value;
- if (!arr.item(0) && value)
- arr = popup.getElementsByAttribute(editable ? "label" : "value", value);
-
- if (arr.item(0))
- this.selectedItem = arr[0];
- else if (!editable)
- this.selectedIndex = 0;
- }
- ]]>
- </body>
- </method>
-
- <property name="value" onget="return this.getAttribute('value');">
- <setter>
- <![CDATA[
- // if the new value is null, we still need to remove the old value
- if (val == null)
- return this.selectedItem = val;
-
- var arr = null;
- var popup = this.menupopup;
- if (popup)
- arr = popup.getElementsByAttribute("value", val);
-
- if (arr && arr.item(0))
- this.selectedItem = arr[0];
- else {
- this.selectedItem = null;
- this.setAttribute("value", val);
- }
-
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="inputField" readonly="true" onget="return null;"/>
-
- <property name="crop" onset="this.setAttribute('crop',val); return val;"
- onget="return this.getAttribute('crop');"/>
- <property name="image" onset="this.setAttribute('image',val); return val;"
- onget="return this.getAttribute('image');"/>
- <property name="label" readonly="true" onget="return this.getAttribute('label');"/>
- <property name="description" onset="this.setAttribute('description',val); return val;"
- onget="return this.getAttribute('description');"/>
-
- <property name="editable" onget="return this.getAttribute('editable') == 'true';">
- <setter>
- <![CDATA[
- if (!val && this.editable) {
- // If we were focused and transition from editable to not editable,
- // focus the parent menulist so that the focus does not get stuck.
- if (this.inputField == document.activeElement)
- window.setTimeout(() => this.focus(), 0);
- }
-
- this.setAttribute("editable", val);
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="open" onset="this.menuBoxObject.openMenu(val);
- return val;"
- onget="return this.hasAttribute('open');"/>
-
- <property name="itemCount" readonly="true"
- onget="return this.menupopup ? this.menupopup.childNodes.length : 0"/>
-
- <property name="menupopup" readonly="true">
- <getter>
- <![CDATA[
- var popup = this.firstChild;
- while (popup && popup.localName != "menupopup")
- popup = popup.nextSibling;
- return popup;
- ]]>
- </getter>
- </property>
-
- <method name="contains">
- <parameter name="item"/>
- <body>
- <![CDATA[
- if (!item)
- return false;
-
- var parent = item.parentNode;
- return (parent && parent.parentNode == this);
- ]]>
- </body>
- </method>
-
- <property name="selectedIndex">
- <getter>
- <![CDATA[
- // Quick and dirty. We won't deal with hierarchical menulists yet.
- if (!this.selectedItem ||
- !this.mSelectedInternal.parentNode ||
- this.mSelectedInternal.parentNode.parentNode != this)
- return -1;
-
- var children = this.mSelectedInternal.parentNode.childNodes;
- var i = children.length;
- while (i--)
- if (children[i] == this.mSelectedInternal)
- break;
-
- return i;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- var popup = this.menupopup;
- if (popup && 0 <= val) {
- if (val < popup.childNodes.length)
- this.selectedItem = popup.childNodes[val];
- } else
- this.selectedItem = null;
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedItem">
- <getter>
- <![CDATA[
- return this.mSelectedInternal;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- var oldval = this.mSelectedInternal;
- if (oldval == val)
- return val;
-
- if (val && !this.contains(val))
- return val;
-
- if (oldval) {
- oldval.removeAttribute("selected");
- this.mAttributeObserver.disconnect();
- }
-
- this.mSelectedInternal = val;
- let attributeFilter = ["value", "label", "image", "description"];
- if (val) {
- val.setAttribute("selected", "true");
- for (let attr of attributeFilter) {
- if (val.hasAttribute(attr)) {
- this.setAttribute(attr, val.getAttribute(attr));
- } else {
- this.removeAttribute(attr);
- }
- }
-
- this.mAttributeObserver = new MutationObserver(this.handleMutation.bind(this));
- this.mAttributeObserver.observe(val, { attributeFilter });
- } else {
- for (let attr of attributeFilter) {
- this.removeAttribute(attr);
- }
- }
-
- var event = document.createEvent("Events");
- event.initEvent("select", true, true);
- this.dispatchEvent(event);
-
- event = document.createEvent("Events");
- event.initEvent("ValueChange", true, true);
- this.dispatchEvent(event);
-
- return val;
- ]]>
- </setter>
- </property>
-
- <method name="handleMutation">
- <parameter name="aRecords"/>
- <body>
- <![CDATA[
- for (let record of aRecords) {
- let t = record.target;
- if (t == this.mSelectedInternal) {
- let attrName = record.attributeName;
- switch (attrName) {
- case "value":
- case "label":
- case "image":
- case "description":
- if (t.hasAttribute(attrName)) {
- this.setAttribute(attrName, t.getAttribute(attrName));
- } else {
- this.removeAttribute(attrName);
- }
- }
- }
- }
- ]]>
- </body>
- </method>
-
- <method name="getIndexOfItem">
- <parameter name="item"/>
- <body>
- <![CDATA[
- var popup = this.menupopup;
- if (popup) {
- var children = popup.childNodes;
- var i = children.length;
- while (i--)
- if (children[i] == item)
- return i;
- }
- return -1;
- ]]>
- </body>
- </method>
-
- <method name="getItemAtIndex">
- <parameter name="index"/>
- <body>
- <![CDATA[
- var popup = this.menupopup;
- if (popup) {
- var children = popup.childNodes;
- if (index >= 0 && index < children.length)
- return children[index];
- }
- return null;
- ]]>
- </body>
- </method>
-
- <method name="appendItem">
- <parameter name="label"/>
- <parameter name="value"/>
- <parameter name="description"/>
- <body>
- <![CDATA[
- const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var popup = this.menupopup ||
- this.appendChild(document.createElementNS(XULNS, "menupopup"));
- var item = document.createElementNS(XULNS, "menuitem");
- item.setAttribute("label", label);
- item.setAttribute("value", value);
- if (description)
- item.setAttribute("description", description);
-
- popup.appendChild(item);
- return item;
- ]]>
- </body>
- </method>
-
- <method name="removeAllItems">
- <body>
- <![CDATA[
- this.selectedItem = null;
- var popup = this.menupopup;
- if (popup)
- this.removeChild(popup);
- ]]>
- </body>
- </method>
-
- <destructor>
- <![CDATA[
- if (this.mAttributeObserver) {
- this.mAttributeObserver.disconnect();
- }
- ]]>
- </destructor>
- </implementation>
</binding>
<binding id="menulist-editable" extends="chrome://global/content/bindings/menulist.xml#menulist">
<content sizetopopup="pref">
<xul:hbox class="menulist-editable-box textbox-input-box" xbl:inherits="context,disabled,readonly,focused" flex="1">
<html:input class="menulist-editable-input" anonid="input" allowevents="true"
xbl:inherits="value=label,value,disabled,tabindex,readonly,placeholder"/>
</xul:hbox>
@@ -516,21 +223,21 @@
<handler event="popupshowing">
<![CDATA[
// editable menulists elements aren't in the focus order,
// so when the popup opens we need to force the focus to the inputField
if (event.target.parentNode == this) {
if (document.commandDispatcher.focusedElement != this.inputField)
this.inputField.focus();
- 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>
<handler event="keypress">
<![CDATA[
// open popup if key is up arrow, down arrow, or F4
if (!event.ctrlKey && !event.shiftKey) {
--- a/toolkit/modules/SelectParentHelper.jsm
+++ b/toolkit/modules/SelectParentHelper.jsm
@@ -427,17 +427,17 @@ function populateChildren(menulist, opti
// _moz-menuactive attribute on the selected <xul:menuitem>.
menulist.selectedItem = item;
// It's hack time. In the event that we've re-populated the menulist due
// to a mutation in the <select> in content, that means that the -moz_activemenu
// 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);
if (parentElement) {
item.classList.add("contentSelectDropdown-ingroup");
}
}
@@ -466,25 +466,25 @@ function populateChildren(menulist, opti
searchbox.parentElement.hidePopup();
break;
case "ArrowDown":
case "Enter":
case "Tab":
searchbox.blur();
if (searchbox.nextSibling.localName == "menuitem" &&
!searchbox.nextSibling.hidden) {
- menulist.menuBoxObject.activeChild = searchbox.nextSibling;
+ menulist.activeChild = searchbox.nextSibling;
} else {
var currentOption = searchbox.nextSibling;
while (currentOption && (currentOption.localName != "menuitem" ||
currentOption.hidden)) {
currentOption = currentOption.nextSibling;
}
if (currentOption) {
- menulist.menuBoxObject.activeChild = currentOption;
+ menulist.activeChild = currentOption;
} else {
searchbox.focus();
}
}
break;
default:
return;
}
@@ -551,17 +551,17 @@ 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", {});
}
function onSearchBlur() {
let searchObj = this;
let menupopup = searchObj.parentElement;
menupopup.setAttribute("ignorekeys", "false");