Merge m-c to m-i

This commit is contained in:
Phil Ringnalda 2014-03-16 08:38:30 -07:00
commit 85d6114084
16 changed files with 326 additions and 186 deletions

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>

View File

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/> <project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="485846b2a40d8ac7d6c1c5f8af6d15b0c10af19d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="485846b2a40d8ac7d6c1c5f8af6d15b0c10af19d"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="a9e08b91e9cd1f0930f16cfc49ec72f63575d5fe"> <project name="platform_build" path="build" remote="b2g" revision="a9e08b91e9cd1f0930f16cfc49ec72f63575d5fe">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/> <project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>

View File

@ -4,6 +4,6 @@
"branch": "", "branch": "",
"revision": "" "revision": ""
}, },
"revision": "1b537b86025c437cd428abbc2996f376f3b78799", "revision": "de57cd03d28aec6c8d25572741e49348277d283e",
"repo_path": "/integration/gaia-central" "repo_path": "/integration/gaia-central"
} }

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/> <project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="485846b2a40d8ac7d6c1c5f8af6d15b0c10af19d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="485846b2a40d8ac7d6c1c5f8af6d15b0c10af19d"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="70978988d048737b1379f5452a679429dadcd35f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8f802237927c7d5e024fb7dca054dd5efef6b2e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -23,15 +23,20 @@ function test() {
Task.spawn(function* () { Task.spawn(function* () {
try { try {
yield ensureSourceIs(gPanel, CODE_URL, true); // Refresh and hit the debugger statement before the location we want to
// set our breakpoints. We have to pause before the breakpoint locations
// so that GC doesn't get a chance to kick in and collect the IIFE's
// script, which would causes us to receive a 'noScript' error from the
// server when we try to set the breakpoints.
const [paused, ] = yield promise.all([
waitForThreadEvents(gPanel, "paused"),
reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN),
]);
// Pause and set our breakpoints. is(paused.why.type, "debuggerStatement");
yield doInterrupt();
// Set our breakpoints.
const [bp1, bp2, bp3] = yield promise.all([ const [bp1, bp2, bp3] = yield promise.all([
setBreakpoint({
url: CODE_URL,
line: 2
}),
setBreakpoint({ setBreakpoint({
url: CODE_URL, url: CODE_URL,
line: 3 line: 3
@ -39,23 +44,31 @@ function test() {
setBreakpoint({ setBreakpoint({
url: CODE_URL, url: CODE_URL,
line: 4 line: 4
}),
setBreakpoint({
url: CODE_URL,
line: 5
}) })
]); ]);
// Should hit the first breakpoint on reload. // Refresh and hit the debugger statement again.
yield promise.all([ yield promise.all([
reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN), reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN),
waitForCaretUpdated(gPanel, 2) waitForCaretAndScopes(gPanel, 1)
]); ]);
// And should hit the other breakpoints as we resume. // And we should hit the breakpoints as we resume.
yield promise.all([ yield promise.all([
doResume(), doResume(),
waitForCaretUpdated(gPanel, 3) waitForCaretAndScopes(gPanel, 3)
]); ]);
yield promise.all([ yield promise.all([
doResume(), doResume(),
waitForCaretUpdated(gPanel, 4) waitForCaretAndScopes(gPanel, 4)
]);
yield promise.all([
doResume(),
waitForCaretAndScopes(gPanel, 5)
]); ]);
// Clean up the breakpoints. // Clean up the breakpoints.

View File

@ -1,3 +1,4 @@
debugger;
var a = (function(){ var a = (function(){
var b = 9; var b = 9;
console.log("x", b); console.log("x", b);

View File

@ -811,9 +811,9 @@ this.UITour = {
let minDimension = Math.min(highlightHeight, highlightWidth); let minDimension = Math.min(highlightHeight, highlightWidth);
let maxDimension = Math.max(highlightHeight, highlightWidth); let maxDimension = Math.max(highlightHeight, highlightWidth);
// If the dimensions are within 110% of each other (to include the bookmarks button), // If the dimensions are within 200% of each other (to include the bookmarks button),
// make the highlight a circle with the largest dimension as the diameter. // make the highlight a circle with the largest dimension as the diameter.
if (maxDimension / minDimension <= 2.1) { if (maxDimension / minDimension <= 3.0) {
highlightHeight = highlightWidth = maxDimension; highlightHeight = highlightWidth = maxDimension;
highlighter.style.borderRadius = "100%"; highlighter.style.borderRadius = "100%";
} else { } else {

View File

@ -1918,8 +1918,7 @@ var NativeWindow = {
}, },
contextmenus: { contextmenus: {
items: {}, // a list of context menu items that we may show items: {}, // a list of context menu items that we may show
_nativeItemsSeparator: 0, // the index to insert native context menu items at DEFAULT_HTML5_ORDER: -1, // Sort order for HTML5 context menu items
_contextId: 0, // id to assign to new context menu items if they are added
init: function() { init: function() {
Services.obs.addObserver(this, "Gesture:LongPress", false); Services.obs.addObserver(this, "Gesture:LongPress", false);
@ -1929,27 +1928,26 @@ var NativeWindow = {
Services.obs.removeObserver(this, "Gesture:LongPress"); Services.obs.removeObserver(this, "Gesture:LongPress");
}, },
add: function(aName, aSelector, aCallback) { add: function() {
if (!aName) let args;
if (arguments.length == 1) {
args = arguments[0];
} else if (arguments.length == 3) {
args = {
label : arguments[0],
selector: arguments[1],
callback: arguments[2]
};
} else {
throw "Incorrect number of parameters";
}
if (!args.label)
throw "Menu items must have a name"; throw "Menu items must have a name";
let item = { let cmItem = new ContextMenuItem(args);
name: aName, this.items[cmItem.id] = cmItem;
context: aSelector, return cmItem.id;
callback: aCallback,
matches: function(aElt, aX, aY) {
return this.context.matches(aElt, aX, aY);
},
getValue: function(aElt) {
return {
label: (typeof this.name == "function") ? this.name(aElt) : this.name,
id: this.id
}
}
};
item.id = this._contextId++;
this.items[item.id] = item;
return item.id;
}, },
remove: function(aId) { remove: function(aId) {
@ -2114,123 +2112,87 @@ var NativeWindow = {
else this._targetRef = null; else this._targetRef = null;
}, },
_addHTMLContextMenuItems: function cm_addContextMenuItems(aMenu, aParent) { _addHTMLContextMenuItemsForElement: function(element) {
for (let i = 0; i < aMenu.childNodes.length; i++) { let htmlMenu = element.contextMenu;
let item = aMenu.childNodes[i]; if (!htmlMenu)
if (!item.label) return;
htmlMenu.QueryInterface(Components.interfaces.nsIHTMLMenu);
htmlMenu.sendShowEvent();
this._addHTMLContextMenuItemsForMenu(htmlMenu, element);
},
_addHTMLContextMenuItemsForMenu: function(menu, target) {
for (let i = 0; i < menu.childNodes.length; i++) {
let elt = menu.childNodes[i];
if (!elt.label)
continue; continue;
let id = this._contextId++; this.menuitems.push(new HTMLContextMenuItem(elt, target));
let menuitem = {
id: id,
isGroup: false,
callback: (function(aTarget, aX, aY) {
// If this is a menu item, show a new context menu with the submenu in it
if (item instanceof Ci.nsIDOMHTMLMenuElement) {
this.menuitems = [];
this._nativeItemsSeparator = 0;
this._addHTMLContextMenuItems(item, id);
this._innerShow(aTarget, aX, aY);
} else {
// oltherwise just click the item
item.click();
}
}).bind(this),
getValue: function(aElt) {
if (item.hasAttribute("hidden"))
return null;
return {
icon: item.icon,
label: item.label,
id: id,
disabled: item.disabled,
parent: item instanceof Ci.nsIDOMHTMLMenuElement
}
}
};
this.menuitems.splice(this._nativeItemsSeparator, 0, menuitem);
this._nativeItemsSeparator++;
} }
}, },
_getMenuItemForId: function(aId) { _containsItem: function(aId) {
if (!this.menuitems) if (!this.menuitems)
return null; return null;
for (let i = 0; i < this.menuitems.length; i++) { let menu = this.menuitems;
if (this.menuitems[i].id == aId) for (let i = 0; i < menu.length; i++) {
return this.menuitems[i]; if (menu[i].id == aId)
return menu[i];
} }
return null; return null;
}, },
shouldShow: function() {
return this.menuitems.length > 0;
},
_addNativeContextMenuItems: function(element, x, y) {
for (let itemId of Object.keys(this.items)) {
let item = this.items[itemId];
if (!this._containsItem(item.id) && item.matches(element, x, y)) {
this.menuitems.push(item);
}
}
},
// Checks if there are context menu items to show, and if it finds them // Checks if there are context menu items to show, and if it finds them
// sends a contextmenu event to content. We also send showing events to // sends a contextmenu event to content. We also send showing events to
// any html5 context menus we are about to show // any html5 context menus we are about to show
_sendToContent: function(aX, aY) { _sendToContent: function(x, y) {
// find and store the top most element this context menu is being shown for let target = BrowserEventHandler._highlightElement || ElementTouchHelper.elementFromPoint(x, y);
// use the highlighted element if possible, otherwise look for nearby clickable elements
// If we still don't find one we fall back to using anything
let target = BrowserEventHandler._highlightElement || ElementTouchHelper.elementFromPoint(aX, aY);
if (!target) if (!target)
target = ElementTouchHelper.anyElementFromPoint(aX, aY); target = ElementTouchHelper.anyElementFromPoint(x, y);
if (!target) if (!target)
return; return;
// store a weakref to the target to be used when the context menu event returns
this._target = target; this._target = target;
this.menuitems = [];
let menuitemsSet = false;
Services.obs.notifyObservers(null, "before-build-contextmenu", ""); Services.obs.notifyObservers(null, "before-build-contextmenu", "");
this._buildMenu(x, y);
// now walk up the tree and for each node look for any context menu items that apply
let element = target;
this._nativeItemsSeparator = 0;
while (element) {
// first check for any html5 context menus that might exist
let contextmenu = element.contextMenu;
if (contextmenu) {
// send this before we build the list to make sure the site can update the menu
contextmenu.QueryInterface(Components.interfaces.nsIHTMLMenu);
contextmenu.sendShowEvent();
this._addHTMLContextMenuItems(contextmenu, null);
}
// then check for any context menu items registered in the ui
for (let itemId of Object.keys(this.items)) {
let item = this.items[itemId];
if (!this._getMenuItemForId(item.id) && item.matches(element, aX, aY)) {
this.menuitems.push(item);
}
}
element = element.parentNode;
}
// only send the contextmenu event to content if we are planning to show a context menu (i.e. not on every long tap) // only send the contextmenu event to content if we are planning to show a context menu (i.e. not on every long tap)
if (this.menuitems.length > 0) { if (this.shouldShow()) {
let event = target.ownerDocument.createEvent("MouseEvent"); let event = target.ownerDocument.createEvent("MouseEvent");
event.initMouseEvent("contextmenu", true, true, content, event.initMouseEvent("contextmenu", true, true, target.defaultView,
0, aX, aY, aX, aY, false, false, false, false, 0, x, y, x, y, false, false, false, false,
0, null); 0, null);
target.ownerDocument.defaultView.addEventListener("contextmenu", this, false); target.ownerDocument.defaultView.addEventListener("contextmenu", this, false);
target.dispatchEvent(event); target.dispatchEvent(event);
} else { } else {
this._target = null; this.menuitems = null;
BrowserEventHandler._cancelTapHighlight(); Services.obs.notifyObservers({target: target, x: x, y: y}, "context-menu-not-shown", "");
if (SelectionHandler.canSelect(target)) { if (SelectionHandler.canSelect(target)) {
if (!SelectionHandler.startSelection(target, { if (!SelectionHandler.startSelection(target, {
mode: SelectionHandler.SELECT_AT_POINT, mode: SelectionHandler.SELECT_AT_POINT,
x: aX, x: x,
y: aY y: y
})) { })) {
SelectionHandler.attachCaret(target); SelectionHandler.attachCaret(target);
} }
@ -2238,6 +2200,41 @@ var NativeWindow = {
} }
}, },
_getTitle: function(node) {
if (node.hasAttribute && node.hasAttribute("title")) {
return node.getAttribute("title");
}
return this._getUrl(node);
},
_getUrl: function(node) {
if ((node instanceof Ci.nsIDOMHTMLAnchorElement && node.href) ||
(node instanceof Ci.nsIDOMHTMLAreaElement && node.href)) {
return this._getLinkURL(node);
} else if (node instanceof Ci.nsIImageLoadingContent && node.currentURI) {
return node.currentURI.spec;
} else if (node instanceof Ci.nsIDOMHTMLMediaElement) {
return (node.currentSrc || node.src);
}
return "";
},
_buildMenu: function(x, y) {
// now walk up the tree and for each node look for any context menu items that apply
let element = this._target;
this.menuitems = [];
while (element) {
// First check for any html5 context menus that might exist...
this._addHTMLContextMenuItemsForElement(element);
// then check for any context menu items registered in the ui.
this._addNativeContextMenuItems(element, x, y);
// walk up the tree and find more items to show
element = element.parentNode;
}
},
// Actually shows the native context menu by passing a list of context menu items to // Actually shows the native context menu by passing a list of context menu items to
// show to the Java. // show to the Java.
_show: function(aEvent) { _show: function(aEvent) {
@ -2249,69 +2246,83 @@ var NativeWindow = {
this._innerShow(popupNode, aEvent.clientX, aEvent.clientY); this._innerShow(popupNode, aEvent.clientX, aEvent.clientY);
}, },
_innerShow: function(aTarget, aX, aY) { _findTitle: function(node) {
let title = "";
while(node && !title) {
title = this._getTitle(node);
node = node.parentNode;
}
return title;
},
_getItems: function(target) {
return this._getItemsInList(target, this.menuitems);
},
_getItemsInList: function(target, list) {
let itemArray = [];
for (let i = 0; i < list.length; i++) {
let t = target;
while(t) {
if (list[i].matches(t)) {
let val = list[i].getValue(t);
// hidden menu items will return null from getValue
if (val) {
itemArray.push(val);
break;
}
}
t = t.parentNode;
}
}
return itemArray;
},
_innerShow: function(target, x, y) {
Haptic.performSimpleAction(Haptic.LongPress); Haptic.performSimpleAction(Haptic.LongPress);
// spin through the tree looking for a title for this context menu // spin through the tree looking for a title for this context menu
let node = aTarget; let title = this._findTitle(target);
let title ="";
while(node && !title) {
if (node.hasAttribute && node.hasAttribute("title")) {
title = node.getAttribute("title");
} else if ((node instanceof Ci.nsIDOMHTMLAnchorElement && node.href) ||
(node instanceof Ci.nsIDOMHTMLAreaElement && node.href)) {
title = this._getLinkURL(node);
} else if (node instanceof Ci.nsIImageLoadingContent && node.currentURI) {
title = node.currentURI.spec;
} else if (node instanceof Ci.nsIDOMHTMLMediaElement) {
title = (node.currentSrc || node.src);
}
node = node.parentNode;
}
// convert this.menuitems object to an array for sending to native code this.menuitems.sort((a,b) => {
let itemArray = []; if (a.order == b.order) return 0;
for (let i = 0; i < this.menuitems.length; i++) { return (a.order > b.order) ? 1 : -1;
let val = this.menuitems[i].getValue(aTarget); });
// hidden menu items will return null from getValue
if (val)
itemArray.push(val);
}
if (itemArray.length == 0)
return;
let prompt = new Prompt({ let prompt = new Prompt({
window: aTarget.ownerDocument.defaultView, window: target.ownerDocument.defaultView,
title: title title: title
}).setSingleChoiceItems(itemArray) });
.show((function(data) {
let items = this._getItems(target);
prompt.setSingleChoiceItems(items);
prompt.show(this._promptDone.bind(this, target, x, y, items));
},
_promptDone: function(target, x, y, items, data) {
if (data.button == -1) { if (data.button == -1) {
// prompt was cancelled // prompt was cancelled
return; return;
} }
let selectedId = itemArray[data.button].id; let selectedItemId = items[data.list[0]].id;
let selectedItem = this._getMenuItemForId(selectedId); let selectedItem = this._containsItem(selectedItemId);
this.menuitems = null; this.menuitems = null;
if (selectedItem && selectedItem.callback) {
if (selectedItem.matches) { if (!selectedItem || !selectedItem.matches || !selectedItem.callback) {
return;
}
// for menuitems added using the native UI, pass the dom element that matched that item to the callback // for menuitems added using the native UI, pass the dom element that matched that item to the callback
while (aTarget) { while (target) {
if (selectedItem.matches(aTarget, aX, aY)) { if (selectedItem.matches(target, x, y)) {
selectedItem.callback.call(selectedItem, aTarget, aX, aY); selectedItem.callback(target, x, y);
break; break;
} }
aTarget = aTarget.parentNode; target = target.parentNode;
} }
} else {
// if this was added using the html5 context menu api, just click on the context menu item
selectedItem.callback.call(selectedItem, aTarget, aX, aY);
}
}
}).bind(this));
}, },
handleEvent: function(aEvent) { handleEvent: function(aEvent) {
@ -2343,7 +2354,7 @@ var NativeWindow = {
aElement instanceof Ci.nsIDOMHTMLLinkElement || aElement instanceof Ci.nsIDOMHTMLLinkElement ||
aElement.getAttributeNS(kXLinkNamespace, "type") == "simple")) { aElement.getAttributeNS(kXLinkNamespace, "type") == "simple")) {
try { try {
let url = NativeWindow.contextmenus._getLinkURL(aElement); let url = this._getLinkURL(aElement);
return Services.io.newURI(url, null, null); return Services.io.newURI(url, null, null);
} catch (e) {} } catch (e) {}
} }
@ -8264,3 +8275,108 @@ var Tabs = {
} }
}, },
}; };
function ContextMenuItem(args) {
this.id = uuidgen.generateUUID().toString();
this.args = args;
}
ContextMenuItem.prototype = {
get order() {
return this.args.order || 0;
},
matches: function(elt, x, y) {
return this.args.selector.matches(elt, x, y);
},
callback: function(elt) {
this.args.callback(elt);
},
addVal: function(name, elt, defaultValue) {
if (!(name in this.args))
return defaultValue;
if (typeof this.args[name] == "function")
return this.args[name](elt);
return this.args[name];
},
getValue: function(elt) {
return {
id: this.id,
label: this.addVal("label", elt),
shareData: this.addVal("shareData", elt),
icon: this.addVal("icon", elt),
isGroup: this.addVal("isGroup", elt, false),
inGroup: this.addVal("inGroup", elt, false),
disabled: this.addVal("disabled", elt, false),
selected: this.addVal("selected", elt, false),
isParent: this.addVal("isParent", elt, false),
};
}
}
function HTMLContextMenuItem(elt, target) {
ContextMenuItem.call(this, { });
this.menuElementRef = Cu.getWeakReference(elt);
this.targetElementRef = Cu.getWeakReference(target);
}
HTMLContextMenuItem.prototype = Object.create(ContextMenuItem.prototype, {
order: {
value: NativeWindow.contextmenus.DEFAULT_HTML5_ORDER
},
matches: {
value: function(target) {
let t = this.targetElementRef.get();
return t === target;
},
},
callback: {
value: function(target) {
let elt = this.menuElementRef.get();
if (!elt) {
return;
}
// If this is a menu item, show a new context menu with the submenu in it
if (elt instanceof Ci.nsIDOMHTMLMenuElement) {
try {
NativeWindow.contextmenus.menuitems = [];
NativeWindow.contextmenus._addHTMLContextMenuItemsForMenu(elt, target);
NativeWindow.contextmenus._innerShow(target);
} catch(ex) {
Cu.reportError(ex);
}
} else {
// otherwise just click the menu item
elt.click();
}
},
},
getValue: {
value: function(target) {
let elt = this.menuElementRef.get();
if (!elt)
return null;
if (elt.hasAttribute("hidden"))
return null;
return {
id: this.id,
icon: elt.icon,
label: elt.label,
disabled: elt.disabled,
menu: elt instanceof Ci.nsIDOMHTMLMenuElement
};
}
},
});

View File

@ -1362,7 +1362,13 @@ ThreadActor.prototype = {
if (line == null || if (line == null ||
line < 0 || line < 0 ||
this.dbg.findScripts({ url: url }).length == 0) { this.dbg.findScripts({ url: url }).length == 0) {
return { error: "noScript" }; return {
error: "noScript",
message: "Requested setting a breakpoint on "
+ url + ":" + line
+ (column != null ? ":" + column : "")
+ " but there is no Debugger.Script at that location"
};
} }
let response = this._createAndStoreBreakpoint({ let response = this._createAndStoreBreakpoint({
@ -1450,6 +1456,10 @@ ThreadActor.prototype = {
if (scripts.length == 0) { if (scripts.length == 0) {
return { return {
error: "noScript", error: "noScript",
message: "Requested setting a breakpoint on "
+ aLocation.url + ":" + aLocation.line
+ (aLocation.column != null ? ":" + aLocation.column : "")
+ " but there is no Debugger.Script at that location",
actor: actor.actorID actor: actor.actorID
}; };
} }