diff --git a/devtools/client/inspector/markup/test/browser.ini b/devtools/client/inspector/markup/test/browser.ini index 9ca299ea2f7d..71dc305a4394 100644 --- a/devtools/client/inspector/markup/test/browser.ini +++ b/devtools/client/inspector/markup/test/browser.ini @@ -7,7 +7,9 @@ support-files = doc_markup_dragdrop.html doc_markup_dragdrop_autoscroll.html doc_markup_edit.html - doc_markup_events.html + doc_markup_events1.html + doc_markup_events2.html + doc_markup_events3.html doc_markup_events_form.html doc_markup_events_jquery.html doc_markup_events-overflow.html @@ -62,7 +64,9 @@ skip-if = e10s # scratchpad.xul is not loading in e10s window [browser_markup_dragdrop_invalidNodes.js] [browser_markup_dragdrop_reorder.js] [browser_markup_dragdrop_tooltip.js] -[browser_markup_events.js] +[browser_markup_events1.js] +[browser_markup_events2.js] +[browser_markup_events3.js] [browser_markup_events_form.js] [browser_markup_events_jquery_1.0.js] [browser_markup_events_jquery_1.1.js] diff --git a/devtools/client/inspector/markup/test/browser_markup_events.js b/devtools/client/inspector/markup/test/browser_markup_events1.js similarity index 72% rename from devtools/client/inspector/markup/test/browser_markup_events.js rename to devtools/client/inspector/markup/test/browser_markup_events1.js index 09420c94e15d..dbfd4a5c3e37 100644 --- a/devtools/client/inspector/markup/test/browser_markup_events.js +++ b/devtools/client/inspector/markup/test/browser_markup_events1.js @@ -8,7 +8,7 @@ // Test that markup view event bubbles show the correct event info for DOM // events. -const TEST_URL = URL_ROOT + "doc_markup_events.html"; +const TEST_URL = URL_ROOT + "doc_markup_events1.html"; loadHelperScript("helper_events_test_runner.js"); @@ -32,7 +32,7 @@ const TEST_DATA = [ // eslint-disable-line expected: [ { type: "mouseover", - filename: TEST_URL + ":62", + filename: TEST_URL + ":45", attributes: [ "Capturing", "DOM2" @@ -51,7 +51,7 @@ const TEST_DATA = [ // eslint-disable-line expected: [ { type: "click", - filename: TEST_URL + ":69", + filename: TEST_URL + ":52", attributes: [ "Bubbling", "DOM2" @@ -63,7 +63,7 @@ const TEST_DATA = [ // eslint-disable-line }, { type: "mouseup", - filename: TEST_URL + ":78", + filename: TEST_URL + ":57", attributes: [ "Bubbling", "DOM2" @@ -75,84 +75,6 @@ const TEST_DATA = [ // eslint-disable-line } ] }, - { - selector: "#DOM0", - expected: [ - { - type: "click", - filename: TEST_URL, - attributes: [ - "Bubbling", - "DOM0" - ], - handler: "alert('hi')" - } - ] - }, - { - selector: "#handleevent", - expected: [ - { - type: "click", - filename: TEST_URL + ":89", - attributes: [ - "Bubbling", - "DOM2" - ], - handler: "handleEvent: function(blah) {\n" + - " alert(\"handleEvent clicked\");\n" + - "}" - } - ] - }, - { - selector: "#fatarrow", - expected: [ - { - type: "click", - filename: TEST_URL + ":57", - attributes: [ - "Bubbling", - "DOM2" - ], - handler: "event => {\n" + - " alert(\"Yay for the fat arrow!\");\n" + - "}" - } - ] - }, - { - selector: "#boundhe", - expected: [ - { - type: "click", - filename: TEST_URL + ":101", - attributes: [ - "Bubbling", - "DOM2" - ], - handler: "handleEvent: function() {\n" + - " alert(\"boundHandleEvent clicked\");\n" + - "}" - } - ] - }, - { - selector: "#bound", - expected: [ - { - type: "click", - filename: TEST_URL + ":74", - attributes: [ - "Bubbling", - "DOM2" - ], - handler: "function boundClickHandler(event) {\n" + - " alert(\"Bound event clicked\");\n" + - "}" - } - ] - }, // #noevents tests check that dynamically added events are properly displayed // in the markupview { @@ -169,7 +91,7 @@ const TEST_DATA = [ // eslint-disable-line expected: [ { type: "click", - filename: TEST_URL + ":106", + filename: TEST_URL + ":72", attributes: [ "Bubbling", "DOM2" @@ -190,6 +112,36 @@ const TEST_DATA = [ // eslint-disable-line }, expected: [] }, + { + selector: "#DOM0", + expected: [ + { + type: "click", + filename: TEST_URL, + attributes: [ + "Bubbling", + "DOM0" + ], + handler: "alert('DOM0')" + } + ] + }, + { + selector: "#handleevent", + expected: [ + { + type: "click", + filename: TEST_URL + ":67", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "handleEvent: function(blah) {\n" + + " alert(\"handleEvent\");\n" + + "}" + } + ] + } ]; add_task(function* () { diff --git a/devtools/client/inspector/markup/test/browser_markup_events2.js b/devtools/client/inspector/markup/test/browser_markup_events2.js new file mode 100644 index 000000000000..3e741cf1fd65 --- /dev/null +++ b/devtools/client/inspector/markup/test/browser_markup_events2.js @@ -0,0 +1,163 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +/* import-globals-from helper_events_test_runner.js */ + +"use strict"; + +// Test that markup view event bubbles show the correct event info for DOM +// events. + +const TEST_URL = URL_ROOT + "doc_markup_events2.html"; + +loadHelperScript("helper_events_test_runner.js"); + +const TEST_DATA = [ // eslint-disable-line + { + selector: "#fatarrow", + expected: [ + { + type: "click", + filename: TEST_URL + ":39", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "() => {\n" + + " alert(\"Fat arrow without params!\");\n" + + "}" + }, + { + type: "click", + filename: TEST_URL + ":43", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "event => {\n" + + " alert(\"Fat arrow with 1 param!\");\n" + + "}" + }, + { + type: "click", + filename: TEST_URL + ":47", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "(event, foo, bar) => {\n" + + " alert(\"Fat arrow with 3 params!\");\n" + + "}" + }, + { + type: "click", + filename: TEST_URL + ":51", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "b => b" + } + ] + }, + { + selector: "#bound", + expected: [ + { + type: "click", + filename: TEST_URL + ":62", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "function boundClickHandler(event) {\n" + + " alert(\"Bound event\");\n" + + "}" + } + ] + }, + { + selector: "#boundhe", + expected: [ + { + type: "click", + filename: TEST_URL + ":85", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "handleEvent: function() {\n" + + " alert(\"boundHandleEvent\");\n" + + "}" + } + ] + }, + { + selector: "#comment-inline", + expected: [ + { + type: "click", + filename: TEST_URL + ":91", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "function functionProceededByInlineComment() {\n" + + " alert(\"comment-inline\");\n" + + "}" + } + ] + }, + { + selector: "#comment-streaming", + expected: [ + { + type: "click", + filename: TEST_URL + ":96", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "function functionProceededByStreamingComment() {\n" + + " alert(\"comment-streaming\");\n" + + "}" + } + ] + }, + { + selector: "#anon-object-method", + expected: [ + { + type: "click", + filename: TEST_URL + ":71", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "anonObjectMethod: function() {\n" + + " alert(\"obj.anonObjectMethod\");\n" + + "}" + } + ] + }, + { + selector: "#object-method", + expected: [ + { + type: "click", + filename: TEST_URL + ":75", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "objectMethod: function kay() {\n" + + " alert(\"obj.objectMethod\");\n" + + "}" + } + ] + } +]; + +add_task(function* () { + yield runEventPopupTests(TEST_URL, TEST_DATA); +}); diff --git a/devtools/client/inspector/markup/test/browser_markup_events3.js b/devtools/client/inspector/markup/test/browser_markup_events3.js new file mode 100644 index 000000000000..a9dc2a4995c4 --- /dev/null +++ b/devtools/client/inspector/markup/test/browser_markup_events3.js @@ -0,0 +1,161 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +/* import-globals-from helper_events_test_runner.js */ + +"use strict"; + +// Test that markup view event bubbles show the correct event info for DOM +// events. + +const TEST_URL = URL_ROOT + "doc_markup_events3.html"; + +loadHelperScript("helper_events_test_runner.js"); + +const TEST_DATA = [ // eslint-disable-line + { + selector: "#es6-method", + expected: [ + { + type: "click", + filename: TEST_URL + ":91", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "es6Method() {\n" + + " alert(\"obj.es6Method\");\n" + + "}" + } + ] + }, + { + selector: "#generator", + expected: [ + { + type: "click", + filename: TEST_URL + ":96", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "function* generator() {\n" + + " alert(\"generator\");\n" + + "}" + } + ] + }, + { + selector: "#anon-generator", + expected: [ + { + type: "click", + filename: TEST_URL + ":55", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "function*() {\n" + + " alert(\"anonGenerator\");\n" + + "}" + } + ] + }, + { + selector: "#named-function-expression", + expected: [ + { + type: "click", + filename: TEST_URL + ":23", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "let namedFunctionExpression =\n" + + " function foo() {\n" + + " alert(\"namedFunctionExpression\");\n" + + " }" + } + ] + }, + { + selector: "#anon-function-expression", + expected: [ + { + type: "click", + filename: TEST_URL + ":27", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "let anonFunctionExpression = function() {\n" + + " alert(\"anonFunctionExpression\");\n" + + "}" + } + ] + }, + { + selector: "#returned-function", + expected: [ + { + type: "click", + filename: TEST_URL + ":32", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "function bar() {\n" + + " alert(\"returnedFunction\");\n" + + "}" + } + ] + }, + { + selector: "#constructed-function", + expected: [ + { + type: "click", + filename: TEST_URL + ":1", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "" + } + ] + }, + { + selector: "#constructed-function-with-body-string", + expected: [ + { + type: "click", + filename: TEST_URL + ":1", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "alert(\"constructedFuncWithBodyString\");" + } + ] + }, + { + selector: "#multiple-assignment", + expected: [ + { + type: "click", + filename: TEST_URL + ":42", + attributes: [ + "Bubbling", + "DOM2" + ], + handler: "let multipleAssignment = foo = bar = function multi() {\n" + + " alert(\"multipleAssignment\");\n" + + "}" + } + ] + }, +]; + +add_task(function* () { + yield runEventPopupTests(TEST_URL, TEST_DATA); +}); diff --git a/devtools/client/inspector/markup/test/browser_markup_events_jquery_1.0.js b/devtools/client/inspector/markup/test/browser_markup_events_jquery_1.0.js index d9aa2aa10018..7413ea660dfc 100644 --- a/devtools/client/inspector/markup/test/browser_markup_events_jquery_1.0.js +++ b/devtools/client/inspector/markup/test/browser_markup_events_jquery_1.0.js @@ -23,8 +23,7 @@ const TEST_DATA = [ attributes: [ "jQuery" ], - handler: "// Handle when the DOM is ready\n" + - "ready: function() {\n" + + handler: "ready: function() {\n" + " // Make sure that the DOM is not already loaded\n" + " if (!jQuery.isReady) {\n" + " // Remember that the DOM is ready\n" + diff --git a/devtools/client/inspector/markup/test/browser_markup_events_jquery_1.1.js b/devtools/client/inspector/markup/test/browser_markup_events_jquery_1.1.js index a63a970b8f2f..e5e995a876f9 100644 --- a/devtools/client/inspector/markup/test/browser_markup_events_jquery_1.1.js +++ b/devtools/client/inspector/markup/test/browser_markup_events_jquery_1.1.js @@ -23,8 +23,7 @@ const TEST_DATA = [ attributes: [ "jQuery" ], - handler: "// Handle when the DOM is ready\n" + - "ready: function() {\n" + + handler: "ready: function() {\n" + " // Make sure that the DOM is not already loaded\n" + " if (!jQuery.isReady) {\n" + " // Remember that the DOM is ready\n" + diff --git a/devtools/client/inspector/markup/test/doc_markup_events.html b/devtools/client/inspector/markup/test/doc_markup_events1.html similarity index 64% rename from devtools/client/inspector/markup/test/doc_markup_events.html rename to devtools/client/inspector/markup/test/doc_markup_events1.html index 1a4f358971f9..0955289e2b46 100644 --- a/devtools/client/inspector/markup/test/doc_markup_events.html +++ b/devtools/client/inspector/markup/test/doc_markup_events1.html @@ -19,15 +19,6 @@ #noevents, #DOM0, #handleevent, - #fatarrow, - #bound, - #boundhe { - border: 1px solid #000; - width: 200px; - min-height: 1em; - cursor: pointer; - } - #output, #noevents { cursor: auto; @@ -41,22 +32,14 @@ function init() { let container = document.getElementById("container"); let multiple = document.getElementById("multiple"); - let fatarrow = document.getElementById("fatarrow"); container.addEventListener("mouseover", mouseoverHandler, true); multiple.addEventListener("click", clickHandler, false); multiple.addEventListener("mouseup", mouseupHandler, false); - new handleEventClick(); - new boundHandleEventClick(); - - let bound = document.getElementById("bound"); - boundClickHandler = boundClickHandler.bind(this); - bound.addEventListener("click", boundClickHandler); - - fatarrow.addEventListener("click", event => { - alert("Yay for the fat arrow!"); - }); + let he = new handleEventClick(); + let handleevent = document.getElementById("handleevent"); + handleevent.addEventListener("click", he); } function mouseoverHandler(event) { @@ -71,54 +54,38 @@ output.textContent = "click"; } - function boundClickHandler(event) { - alert("Bound event clicked"); - } - function mouseupHandler(event) { let output = document.getElementById("output"); output.textContent = "mouseup"; } function handleEventClick(hehe) { - let handleevent = document.getElementById("handleevent"); - handleevent.addEventListener("click", this); + } handleEventClick.prototype = { handleEvent: function(blah) { - alert("handleEvent clicked"); - } - }; - - function boundHandleEventClick() { - let boundhe = document.getElementById("boundhe"); - this.handleEvent = this.handleEvent.bind(this); - boundhe.addEventListener("click", this); - } - - boundHandleEventClick.prototype = { - handleEvent: function() { - alert("boundHandleEvent clicked"); + alert("handleEvent"); } }; function noeventsClickHandler(event) { alert("noevents has an event listener"); - }; + } function addNoeventsClickHandler() { let noevents = document.getElementById("noevents"); noevents.addEventListener("click", noeventsClickHandler); - }; + } function removeNoeventsClickHandler() { let noevents = document.getElementById("noevents"); noevents.removeEventListener("click", noeventsClickHandler); - }; + } +

Events test 1

1
2
@@ -139,11 +106,8 @@
multiple
-
No events here
-
DOM0 event here
-
handleEvent event here
-
Fat arrow event
-
Bound handleEvent
-
Bound event
+
noevents
+
DOM0 event here
+
handleEvent
diff --git a/devtools/client/inspector/markup/test/doc_markup_events2.html b/devtools/client/inspector/markup/test/doc_markup_events2.html new file mode 100644 index 000000000000..ddc17537d59f --- /dev/null +++ b/devtools/client/inspector/markup/test/doc_markup_events2.html @@ -0,0 +1,111 @@ + + + + + + + + +

Events test 2

+
Fat arrows
+
Bound handleEvent
+
Bound event
+
Event proceeded by an inline comment
+
Event proceeded by a streaming comment
+
Anonymous object method
+
Object method
+ + diff --git a/devtools/client/inspector/markup/test/doc_markup_events3.html b/devtools/client/inspector/markup/test/doc_markup_events3.html new file mode 100644 index 000000000000..af4decc40f33 --- /dev/null +++ b/devtools/client/inspector/markup/test/doc_markup_events3.html @@ -0,0 +1,115 @@ + + + + + + + + +

Events test 3

+
ES6 method
+
Generator
+
Anonymous Generator
+
Named Function Expression
+
Anonymous Function Expression
+
Returned Function
+
Constructed Function
+
+ Constructed Function with body string +
+
Multiple Assignment
+ + diff --git a/devtools/server/actors/inspector.js b/devtools/server/actors/inspector.js index 4d6ee5321596..d15897501f9d 100644 --- a/devtools/server/actors/inspector.js +++ b/devtools/server/actors/inspector.js @@ -87,8 +87,10 @@ const FONT_FAMILY_PREVIEW_TEXT_SIZE = 20; const PSEUDO_CLASSES = [":hover", ":active", ":focus"]; const HIDDEN_CLASS = "__fx-devtools-hide-shortcut__"; const XHTML_NS = "http://www.w3.org/1999/xhtml"; -const XUL_NS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; +const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const IMAGE_FETCHING_TIMEOUT = 500; +const RX_FUNC_NAME = /((var|const|let)\s+)?([\w$.]+\s*[:=]\s*)*(function)?\s*\*?\s*([\w$]+)?\s*$/; + // The possible completions to a ':' with added score to give certain values // some preference. const PSEUDO_SELECTORS = [ @@ -553,28 +555,22 @@ var NodeActor = exports.NodeActor = protocol.ActorClass({ /* The script returned is the whole script and scriptSource.substr(script.sourceStart, script.sourceLength) returns - something like: + something like this: () { doSomething(); } - So we need to work back to the preceeding \n, ; or } so we can get the - appropriate function info e.g.: - () => { doSomething(); } - function doit() { doSomething(); } - doit: function() { doSomething(); } + So we need to use some regex magic to get the appropriate function info + e.g.: + () => { ... } + function doit() { ... } + doit: function() { ... } + es6func() { ... } + var|let|const foo = function () { ... } + function generator*() { ... } */ let scriptBeforeFunc = scriptSource.substr(0, script.sourceStart); - let lastEnding = Math.max( - scriptBeforeFunc.lastIndexOf(";"), - scriptBeforeFunc.lastIndexOf("}"), - scriptBeforeFunc.lastIndexOf("{"), - scriptBeforeFunc.lastIndexOf("("), - scriptBeforeFunc.lastIndexOf(","), - scriptBeforeFunc.lastIndexOf("!") - ); - - if (lastEnding !== -1) { - let functionPrefix = scriptBeforeFunc.substr(lastEnding + 1); - functionSource = functionPrefix + functionSource; + let matches = scriptBeforeFunc.match(RX_FUNC_NAME); + if (matches && matches.length > 0) { + functionSource = matches[0].trim() + functionSource; } let dom0 = false;