зеркало из https://github.com/mozilla/gecko-dev.git
313 строки
13 KiB
XML
313 строки
13 KiB
XML
<?xml version="1.0"?>
|
|
|
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
|
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
-
|
|
- The contents of this file are subject to the Mozilla Public License Version
|
|
- 1.1 (the "License"); you may not use this file except in compliance with
|
|
- the License. You may obtain a copy of the License at
|
|
- http://www.mozilla.org/MPL/
|
|
-
|
|
- Software distributed under the License is distributed on an "AS IS" basis,
|
|
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
- for the specific language governing rights and limitations under the
|
|
- License.
|
|
-
|
|
- The Original Code is Native Menus Test code
|
|
-
|
|
- The Initial Developer of the Original Code is
|
|
- Mozilla Corporation.
|
|
- Portions created by the Initial Developer are Copyright (C) 2008
|
|
- the Initial Developer. All Rights Reserved.
|
|
-
|
|
- Contributor(s):
|
|
- Josh Aas <josh@mozilla.com>
|
|
-
|
|
- Alternatively, the contents of this file may be used under the terms of
|
|
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
- in which case the provisions of the GPL or the LGPL are applicable instead
|
|
- of those above. If you wish to allow use of your version of this file only
|
|
- under the terms of either the GPL or the LGPL, and not to allow others to
|
|
- use your version of this file under the terms of the MPL, indicate your
|
|
- decision by deleting the provisions above and replace them with the notice
|
|
- and other provisions required by the GPL or the LGPL. If you do not delete
|
|
- the provisions above, a recipient may use your version of this file under
|
|
- the terms of any one of the MPL, the GPL or the LGPL.
|
|
-
|
|
- ***** END LICENSE BLOCK ***** -->
|
|
|
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
|
|
|
<window id="NativeMenuWindow"
|
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
width="300"
|
|
height="300"
|
|
onload="onLoad();"
|
|
title="Native Menu Test">
|
|
|
|
<command id="cmd_FooItem0" oncommand="executedCommandID = 'cmd_FooItem0';"/>
|
|
<command id="cmd_FooItem1" oncommand="executedCommandID = 'cmd_FooItem1';"/>
|
|
<command id="cmd_BarItem0" oncommand="executedCommandID = 'cmd_BarItem0';"/>
|
|
<command id="cmd_BarItem1" oncommand="executedCommandID = 'cmd_BarItem1';"/>
|
|
<command id="cmd_NewItem0" oncommand="executedCommandID = 'cmd_NewItem0';"/>
|
|
<command id="cmd_NewItem1" oncommand="executedCommandID = 'cmd_NewItem1';"/>
|
|
<command id="cmd_NewItem2" oncommand="executedCommandID = 'cmd_NewItem2';"/>
|
|
<command id="cmd_NewItem3" oncommand="executedCommandID = 'cmd_NewItem3';"/>
|
|
<command id="cmd_NewItem4" oncommand="executedCommandID = 'cmd_NewItem4';"/>
|
|
<command id="cmd_NewItem5" oncommand="executedCommandID = 'cmd_NewItem5';"/>
|
|
|
|
<!-- We do not modify any menus or menu items defined here in testing. These
|
|
serve as a baseline structure for us to test after other modifications.
|
|
We add children to the menubar defined here and test by modifying those
|
|
children. -->
|
|
<menubar id="nativemenubar">
|
|
<menu id="foo" label="Foo">
|
|
<menupopup>
|
|
<menuitem label="FooItem0" command="cmd_FooItem0"/>
|
|
<menuitem label="FooItem1" command="cmd_FooItem1"/>
|
|
<menuseparator/>
|
|
<menu label="Bar">
|
|
<menupopup>
|
|
<menuitem label="BarItem0" command="cmd_BarItem0"/>
|
|
<menuitem label="BarItem1" command="cmd_BarItem1"/>
|
|
</menupopup>
|
|
</menu>
|
|
</menupopup>
|
|
</menu>
|
|
</menubar>
|
|
|
|
<script type="application/javascript"><![CDATA[
|
|
|
|
function ok(condition, message) {
|
|
window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
|
|
}
|
|
|
|
function onTestsFinished() {
|
|
window.close();
|
|
window.opener.wrappedJSObject.SimpleTest.finish();
|
|
}
|
|
|
|
// Force a menu to update itself. All of the menus parents will be updated
|
|
// as well. An empty string will force a complete menu system reload.
|
|
function forceUpdateNativeMenuAt(location) {
|
|
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
|
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
|
try {
|
|
utils.forceUpdateNativeMenuAt(location);
|
|
}
|
|
catch (e) {
|
|
dump(e + "\n");
|
|
}
|
|
}
|
|
|
|
var executedCommandID = "";
|
|
|
|
function testItem(location, targetID) {
|
|
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
|
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
|
var correctCommandHandler = false;
|
|
try {
|
|
utils.activateNativeMenuItemAt(location);
|
|
correctCommandHandler = executedCommandID == targetID;
|
|
}
|
|
catch (e) {
|
|
dump(e + "\n");
|
|
}
|
|
finally {
|
|
executedCommandID = "";
|
|
return correctCommandHandler;
|
|
}
|
|
}
|
|
|
|
function createXULMenuPopup() {
|
|
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
var item = document.createElementNS(XUL_NS, "menupopup");
|
|
return item;
|
|
}
|
|
|
|
function createXULMenu(aLabel) {
|
|
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
var item = document.createElementNS(XUL_NS, "menu");
|
|
item.setAttribute("label", aLabel);
|
|
return item;
|
|
}
|
|
|
|
function createXULMenuItem(aLabel, aCommandId) {
|
|
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
var item = document.createElementNS(XUL_NS, "menuitem");
|
|
item.setAttribute("label", aLabel);
|
|
item.setAttribute("command", aCommandId);
|
|
return item;
|
|
}
|
|
|
|
function runBaseMenuTests() {
|
|
forceUpdateNativeMenuAt("0|3");
|
|
return testItem("0|0", "cmd_FooItem0") &&
|
|
testItem("0|1", "cmd_FooItem1") &&
|
|
testItem("0|3|0", "cmd_BarItem0") &&
|
|
testItem("0|3|1", "cmd_BarItem1");
|
|
}
|
|
|
|
function onLoad() {
|
|
var _delayedOnLoad = function() {
|
|
// First let's run the base menu tests.
|
|
ok(runBaseMenuTests());
|
|
|
|
// Set up some nodes that we'll use.
|
|
var menubarNode = document.getElementById("nativemenubar");
|
|
var newMenu0 = createXULMenu("NewMenu0");
|
|
var newMenu1 = createXULMenu("NewMenu1");
|
|
var newMenuPopup0 = createXULMenuPopup();
|
|
var newMenuPopup1 = createXULMenuPopup();
|
|
var newMenuItem0 = createXULMenuItem("NewMenuItem0", "cmd_NewItem0");
|
|
var newMenuItem1 = createXULMenuItem("NewMenuItem1", "cmd_NewItem1");
|
|
var newMenuItem2 = createXULMenuItem("NewMenuItem2", "cmd_NewItem2");
|
|
var newMenuItem3 = createXULMenuItem("NewMenuItem3", "cmd_NewItem3");
|
|
var newMenuItem4 = createXULMenuItem("NewMenuItem4", "cmd_NewItem4");
|
|
var newMenuItem5 = createXULMenuItem("NewMenuItem5", "cmd_NewItem5");
|
|
|
|
// Create another submenu with hierarchy via DOM manipulation.
|
|
// ******************
|
|
// * Foo * NewMenu0 * <- Menu bar
|
|
// ******************
|
|
// ****************
|
|
// * NewMenuItem0 * <- NewMenu0 submenu
|
|
// ****************
|
|
// * NewMenuItem1 *
|
|
// ****************
|
|
// * NewMenuItem2 *
|
|
// *******************************
|
|
// * NewMenu1 > * NewMenuItem3 * <- NewMenu1 submenu
|
|
// *******************************
|
|
// * NewMenuItem4 *
|
|
// ****************
|
|
// * NewMenuItem5 *
|
|
// ****************
|
|
newMenu0.appendChild(newMenuPopup0);
|
|
newMenuPopup0.appendChild(newMenuItem0);
|
|
newMenuPopup0.appendChild(newMenuItem1);
|
|
newMenuPopup0.appendChild(newMenuItem2);
|
|
newMenuPopup0.appendChild(newMenu1);
|
|
newMenu1.appendChild(newMenuPopup1);
|
|
newMenuPopup1.appendChild(newMenuItem3);
|
|
newMenuPopup1.appendChild(newMenuItem4);
|
|
newMenuPopup1.appendChild(newMenuItem5);
|
|
//XXX - we have to append the menu to the top-level of the menu bar
|
|
// only after constructing it. If we append before construction, it is
|
|
// invalid because it has no children and we don't validate it if we add
|
|
// children later.
|
|
menubarNode.appendChild(newMenu0);
|
|
forceUpdateNativeMenuAt("1|3");
|
|
// Run basic tests again.
|
|
ok(runBaseMenuTests());
|
|
|
|
// Error strings.
|
|
var sa = "Command handler(s) should have activated";
|
|
var sna = "Command handler(s) should not have activated";
|
|
|
|
// Test middle items.
|
|
ok(testItem("1|1", "cmd_NewItem1"), sa);
|
|
ok(testItem("1|3|1", "cmd_NewItem4"), sa);
|
|
|
|
// Hide newMenu0.
|
|
newMenu0.setAttribute("hidden", "true");
|
|
ok(runBaseMenuTests(), sa); // the base menu should still be unhidden
|
|
ok(!testItem("1|0", ""), sna);
|
|
ok(!testItem("1|1", ""), sna);
|
|
ok(!testItem("1|2", ""), sna);
|
|
ok(!testItem("1|3|0", ""), sna);
|
|
ok(!testItem("1|3|1", ""), sna);
|
|
ok(!testItem("1|3|2", ""), sna);
|
|
|
|
// Show newMenu0.
|
|
newMenu0.setAttribute("hidden", "false");
|
|
forceUpdateNativeMenuAt("1|3");
|
|
ok(runBaseMenuTests(), sa);
|
|
ok(testItem("1|0", "cmd_NewItem0"), sa);
|
|
ok(testItem("1|1", "cmd_NewItem1"), sa);
|
|
ok(testItem("1|2", "cmd_NewItem2"), sa);
|
|
ok(testItem("1|3|0", "cmd_NewItem3"), sa);
|
|
ok(testItem("1|3|1", "cmd_NewItem4"), sa);
|
|
ok(testItem("1|3|2", "cmd_NewItem5"), sa);
|
|
|
|
// Hide items.
|
|
newMenuItem1.setAttribute("hidden", "true");
|
|
newMenuItem4.setAttribute("hidden", "true");
|
|
forceUpdateNativeMenuAt("1|2");
|
|
ok(runBaseMenuTests(), sa);
|
|
ok(testItem("1|0", "cmd_NewItem0"), sa);
|
|
ok(testItem("1|1", "cmd_NewItem2"), sa);
|
|
ok(!testItem("1|2", ""), sna);
|
|
ok(testItem("1|2|0", "cmd_NewItem3"), sa);
|
|
ok(testItem("1|2|1", "cmd_NewItem5"), sa);
|
|
ok(!testItem("1|2|2", ""), sna);
|
|
|
|
// Show items.
|
|
newMenuItem1.setAttribute("hidden", "false");
|
|
newMenuItem4.setAttribute("hidden", "false");
|
|
forceUpdateNativeMenuAt("1|3");
|
|
ok(runBaseMenuTests(), sa);
|
|
ok(testItem("1|0", "cmd_NewItem0"), sa);
|
|
ok(testItem("1|1", "cmd_NewItem1"), sa);
|
|
ok(testItem("1|2", "cmd_NewItem2"), sa);
|
|
ok(testItem("1|3|0", "cmd_NewItem3"), sa);
|
|
ok(testItem("1|3|1", "cmd_NewItem4"), sa);
|
|
ok(testItem("1|3|2", "cmd_NewItem5"), sa);
|
|
|
|
// At this point in the tests the state of the menus has been returned
|
|
// to the originally diagramed state.
|
|
|
|
// Remove menu.
|
|
menubarNode.removeChild(newMenu0);
|
|
ok(runBaseMenuTests(), sa);
|
|
ok(!testItem("1|0", ""), sna);
|
|
ok(!testItem("1|1", ""), sna);
|
|
ok(!testItem("1|2", ""), sna);
|
|
ok(!testItem("1|3|0", ""), sna);
|
|
ok(!testItem("1|3|1", ""), sna);
|
|
ok(!testItem("1|3|2", ""), sna);
|
|
// return state to original diagramed state
|
|
menubarNode.appendChild(newMenu0);
|
|
|
|
// Test for bug 447042, make sure that adding a menu node with no children
|
|
// to the menu bar and then adding another menu node with children works.
|
|
// Menus with no children don't get their native menu items shown and that
|
|
// caused internal arrays to get out of sync and an append crashed.
|
|
var tmpMenu0 = createXULMenu("tmpMenu0");
|
|
menubarNode.removeChild(newMenu0);
|
|
menubarNode.appendChild(tmpMenu0);
|
|
menubarNode.appendChild(newMenu0);
|
|
forceUpdateNativeMenuAt("1|3");
|
|
ok(runBaseMenuTests());
|
|
ok(testItem("1|0", "cmd_NewItem0"), sa);
|
|
ok(testItem("1|1", "cmd_NewItem1"), sa);
|
|
ok(testItem("1|2", "cmd_NewItem2"), sa);
|
|
ok(testItem("1|3|0", "cmd_NewItem3"), sa);
|
|
ok(testItem("1|3|1", "cmd_NewItem4"), sa);
|
|
ok(testItem("1|3|2", "cmd_NewItem5"), sa);
|
|
// return state to original diagramed state
|
|
menubarNode.removeChild(tmpMenu0);
|
|
delete tmpMenu0;
|
|
|
|
// This test is basically a crash test for bug 433858.
|
|
newMenuItem1.setAttribute("hidden", "true");
|
|
newMenuItem2.setAttribute("hidden", "true");
|
|
newMenu1.setAttribute("hidden", "true");
|
|
forceUpdateNativeMenuAt("1");
|
|
newMenuItem1.setAttribute("hidden", "false");
|
|
newMenuItem2.setAttribute("hidden", "false");
|
|
newMenu1.setAttribute("hidden", "false");
|
|
forceUpdateNativeMenuAt("1");
|
|
|
|
onTestsFinished();
|
|
}
|
|
|
|
setTimeout(_delayedOnLoad, 1000);
|
|
}
|
|
|
|
]]></script>
|
|
</window>
|