Bug 1448732 - Part 2: Open detail pane by clicking on summary graph instead of selecting the node. r=pbro draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Tue, 03 Apr 2018 12:26:36 +0900
changeset 776442 98a9bb6339d34872009ce6e57fc81f36b415fa7e
parent 776441 78f80b588fa9ff47af4f9b608c7ad6b817a93dfc
child 776443 b136930a83fd165552ef8c62f529f8d639484f83
push id104883
push userbmo:dakatsuka@mozilla.com
push dateTue, 03 Apr 2018 03:27:41 +0000
reviewerspbro
bugs1448732
milestone61.0a1
Bug 1448732 - Part 2: Open detail pane by clicking on summary graph instead of selecting the node. r=pbro MozReview-Commit-ID: CeMj2VJwRR5
devtools/client/inspector/animation/test/browser_animation_animated-property-list.js
devtools/client/inspector/animation/test/browser_animation_animation-detail_title.js
devtools/client/inspector/animation/test/browser_animation_keyframes-graph_computed-value-path.js
devtools/client/inspector/animation/test/browser_animation_keyframes-graph_computed-value-path_easing-hint.js
devtools/client/inspector/animation/test/browser_animation_keyframes-graph_keyframe-marker.js
devtools/client/inspector/animation/test/browser_animation_summary-graph_animation-name.js
devtools/client/inspector/animation/test/browser_animation_summary-graph_computed-timing-path.js
devtools/client/inspector/animation/test/browser_animation_summary-graph_delay-sign.js
devtools/client/inspector/animation/test/browser_animation_summary-graph_effect-timing-path.js
devtools/client/inspector/animation/test/browser_animation_summary-graph_end-delay-sign.js
devtools/client/inspector/animation/test/browser_animation_summary-graph_negative-delay-path.js
devtools/client/inspector/animation/test/browser_animation_summary-graph_negative-end-delay-path.js
devtools/client/inspector/animation/test/browser_animation_summary-graph_tooltip.js
devtools/client/inspector/animation/test/head.js
--- a/devtools/client/inspector/animation/test/browser_animation_animated-property-list.js
+++ b/devtools/client/inspector/animation/test/browser_animation_animated-property-list.js
@@ -16,25 +16,26 @@ const TEST_DATA = [
     targetClass: "compositor-notall",
     expectedNumber: 3,
   },
 ];
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_simple_animation.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
-  const { inspector, panel } = await openAnimationInspector();
+  const { animationInspector, panel } = await openAnimationInspector();
 
   info("Checking animated property list and items existence at initial");
   ok(!panel.querySelector(".animated-property-list"),
      "The animated-property-list should not be in the DOM at initial");
 
   for (const { targetClass, expectedNumber } of TEST_DATA) {
     info(`Checking animated-property-list and items existence at ${ targetClass }`);
-    await selectNodeAndWaitForAnimations(`.${ targetClass }`, inspector);
+    await clickOnAnimationByTargetSelector(animationInspector,
+                                           panel, `.${ targetClass }`);
     ok(panel.querySelector(".animated-property-list"),
       `The animated-property-list should be in the DOM at ${ targetClass }`);
     const itemEls =
       panel.querySelectorAll(".animated-property-list .animated-property-item");
     is(itemEls.length, expectedNumber,
        `The number of animated-property-list should be ${ expectedNumber } ` +
        `at ${ targetClass }`);
 
--- a/devtools/client/inspector/animation/test/browser_animation_animation-detail_title.js
+++ b/devtools/client/inspector/animation/test/browser_animation_animation-detail_title.js
@@ -18,20 +18,21 @@ const TEST_DATA = [
     targetClass: "easing-step",
     expectedTitle: "Script Animation",
   },
 ];
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_timings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
-  const { inspector, panel } = await openAnimationInspector();
+  const { animationInspector, panel } = await openAnimationInspector();
 
   info("Checking title in each header of animation detail");
 
   for (const { targetClass, expectedTitle } of TEST_DATA) {
     info(`Checking title at ${ targetClass }`);
-    await selectNodeAndWaitForAnimations(`.${ targetClass }`, inspector);
+    await clickOnAnimationByTargetSelector(animationInspector,
+                                           panel, `.${ targetClass }`);
     const titleEl = panel.querySelector(".animation-detail-title");
     is(titleEl.textContent, expectedTitle,
       `Title of "${ targetClass }" should be "${ expectedTitle }"`);
   }
 });
--- a/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_computed-value-path.js
+++ b/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_computed-value-path.js
@@ -407,21 +407,22 @@ const TEST_DATA = [
         ],
       },
     ],
   },
 ];
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_keyframes.html");
-  const { inspector, panel } = await openAnimationInspector();
+  const { animationInspector, panel } = await openAnimationInspector();
 
   for (const { properties, targetClass } of TEST_DATA) {
     info(`Checking keyframes graph for ${ targetClass }`);
-    await selectNodeAndWaitForAnimations(`.${ targetClass }`, inspector);
+    await clickOnAnimationByTargetSelector(animationInspector,
+                                           panel, `.${ targetClass }`);
 
     for (const property of properties) {
       const {
         name,
         computedValuePathClass,
         expectedPathSegments,
         expectedStopColors,
       } = property;
--- a/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_computed-value-path_easing-hint.js
+++ b/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_computed-value-path_easing-hint.js
@@ -187,21 +187,22 @@ const TEST_DATA = [
       },
     ],
   },
 ];
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_easings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
-  const { inspector, panel } = await openAnimationInspector();
+  const { animationInspector, panel } = await openAnimationInspector();
 
   for (const { properties, targetClass } of TEST_DATA) {
     info(`Checking keyframes graph for ${ targetClass }`);
-    await selectNodeAndWaitForAnimations(`.${ targetClass }`, inspector);
+    await clickOnAnimationByTargetSelector(animationInspector,
+                                           panel, `.${ targetClass }`);
 
     for (const { name, expectedHints } of properties) {
       const testTarget = `${ name } in ${ targetClass }`;
       info(`Checking easing hint for ${ testTarget }`);
       info(`Checking easing hint existence for ${ testTarget }`);
       const hintEls = panel.querySelectorAll(`.${ name } .hint`);
       is(hintEls.length, expectedHints.length,
         `Count of easing hint elements of ${ testTarget } ` +
--- a/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_keyframe-marker.js
+++ b/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_keyframe-marker.js
@@ -131,21 +131,22 @@ const TEST_DATA = [
       },
     ],
   }
 ];
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_keyframes.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
-  const { inspector, panel } = await openAnimationInspector();
+  const { animationInspector, panel } = await openAnimationInspector();
 
   for (const { properties, targetClass } of TEST_DATA) {
     info(`Checking keyframe marker for ${ targetClass }`);
-    await selectNodeAndWaitForAnimations(`.${ targetClass }`, inspector);
+    await clickOnAnimationByTargetSelector(animationInspector,
+                                           panel, `.${ targetClass }`);
 
     for (const { name, expectedValues } of properties) {
       const testTarget = `${ name } in ${ targetClass }`;
       info(`Checking keyframe marker for ${ testTarget }`);
       info(`Checking keyframe marker existence for ${ testTarget }`);
       const markerEls = panel.querySelectorAll(`.${ name } .keyframe-marker-item`);
       is(markerEls.length, expectedValues.length,
         `Count of keyframe marker elements of ${ testTarget } ` +
--- a/devtools/client/inspector/animation/test/browser_animation_summary-graph_animation-name.js
+++ b/devtools/client/inspector/animation/test/browser_animation_summary-graph_animation-name.js
@@ -31,17 +31,17 @@ const TEST_DATA = [
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_timings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
   const { panel } = await openAnimationInspector();
 
   for (const { targetClass, expectedLabel } of TEST_DATA) {
     const animationItemEl =
-      findAnimationItemElementsByTargetClassName(panel, targetClass);
+      findAnimationItemElementsByTargetSelector(panel, `.${ targetClass }`);
 
     info(`Checking animation name element existance for ${ targetClass }`);
     const animationNameEl = animationItemEl.querySelector(".animation-name");
 
     if (expectedLabel) {
       ok(animationNameEl,
         "The animation name element should be in animation item element");
       is(animationNameEl.textContent, expectedLabel,
--- a/devtools/client/inspector/animation/test/browser_animation_summary-graph_computed-timing-path.js
+++ b/devtools/client/inspector/animation/test/browser_animation_summary-graph_computed-timing-path.js
@@ -399,17 +399,17 @@ add_task(async function() {
       expectedEndDelayPath,
       expectedForwardsPath,
       expectedIterationPathList,
       isInfinity,
       targetClass,
     } = testData;
 
     const animationItemEl =
-      findAnimationItemElementsByTargetClassName(panel, targetClass);
+      findAnimationItemElementsByTargetSelector(panel, `.${ targetClass }`);
 
     info(`Checking computed timing path existance for ${ targetClass }`);
     const computedTimingPathEl =
       animationItemEl.querySelector(".animation-computed-timing-path");
     ok(computedTimingPathEl,
        "The computed timing path element should be in each animation item element");
 
     info(`Checking delay path for ${ targetClass }`);
--- a/devtools/client/inspector/animation/test/browser_animation_summary-graph_delay-sign.js
+++ b/devtools/client/inspector/animation/test/browser_animation_summary-graph_delay-sign.js
@@ -51,17 +51,17 @@ const TEST_DATA = [
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_timings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
   const { panel } = await openAnimationInspector();
 
   for (const { targetClass, expectedResult } of TEST_DATA) {
     const animationItemEl =
-      findAnimationItemElementsByTargetClassName(panel, targetClass);
+      findAnimationItemElementsByTargetSelector(panel, `.${ targetClass }`);
 
     info(`Checking delay sign existance for ${ targetClass }`);
     const delaySignEl = animationItemEl.querySelector(".animation-delay-sign");
 
     if (expectedResult) {
       ok(delaySignEl, "The delay sign element should be in animation item element");
 
       is(delaySignEl.style.left, expectedResult.left,
--- a/devtools/client/inspector/animation/test/browser_animation_summary-graph_effect-timing-path.js
+++ b/devtools/client/inspector/animation/test/browser_animation_summary-graph_effect-timing-path.js
@@ -31,17 +31,17 @@ const TEST_DATA = [
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_timings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
   const { panel } = await openAnimationInspector();
 
   for (const { targetClass, expectedPath } of TEST_DATA) {
     const animationItemEl =
-      findAnimationItemElementsByTargetClassName(panel, targetClass);
+      findAnimationItemElementsByTargetSelector(panel, `.${ targetClass }`);
 
     info(`Checking effect timing path existance for ${ targetClass }`);
     const effectTimingPathEl =
       animationItemEl.querySelector(".animation-effect-timing-path");
 
     if (expectedPath) {
       ok(effectTimingPathEl,
         "The effect timing path element should be in animation item element");
--- a/devtools/client/inspector/animation/test/browser_animation_summary-graph_end-delay-sign.js
+++ b/devtools/client/inspector/animation/test/browser_animation_summary-graph_end-delay-sign.js
@@ -43,17 +43,17 @@ const TEST_DATA = [
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_timings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
   const { panel } = await openAnimationInspector();
 
   for (const { targetClass, expectedResult } of TEST_DATA) {
     const animationItemEl =
-      findAnimationItemElementsByTargetClassName(panel, targetClass);
+      findAnimationItemElementsByTargetSelector(panel, `.${ targetClass }`);
 
     info(`Checking endDelay sign existance for ${ targetClass }`);
     const endDelaySignEl = animationItemEl.querySelector(".animation-end-delay-sign");
 
     if (expectedResult) {
       ok(endDelaySignEl, "The endDelay sign element should be in animation item element");
 
       is(endDelaySignEl.style.left, expectedResult.left,
--- a/devtools/client/inspector/animation/test/browser_animation_summary-graph_negative-delay-path.js
+++ b/devtools/client/inspector/animation/test/browser_animation_summary-graph_negative-delay-path.js
@@ -24,17 +24,17 @@ const TEST_DATA = [
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_timings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
   const { panel } = await openAnimationInspector();
 
   for (const { targetClass, expectedPath } of TEST_DATA) {
     const animationItemEl =
-      findAnimationItemElementsByTargetClassName(panel, targetClass);
+      findAnimationItemElementsByTargetSelector(panel, `.${ targetClass }`);
 
     info(`Checking negative delay path existence for ${ targetClass }`);
     const negativeDelayPathEl =
       animationItemEl.querySelector(".animation-negative-delay-path");
 
     if (expectedPath) {
       ok(negativeDelayPathEl,
         "The negative delay path element should be in animation item element");
--- a/devtools/client/inspector/animation/test/browser_animation_summary-graph_negative-end-delay-path.js
+++ b/devtools/client/inspector/animation/test/browser_animation_summary-graph_negative-end-delay-path.js
@@ -25,17 +25,17 @@ const TEST_DATA = [
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_timings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
   const { panel } = await openAnimationInspector();
 
   for (const { targetClass, expectedPath } of TEST_DATA) {
     const animationItemEl =
-      findAnimationItemElementsByTargetClassName(panel, targetClass);
+      findAnimationItemElementsByTargetSelector(panel, `.${ targetClass }`);
 
     info(`Checking negative endDelay path existance for ${ targetClass }`);
     const negativeEndDelayPathEl =
       animationItemEl.querySelector(".animation-negative-end-delay-path");
 
     if (expectedPath) {
       ok(negativeEndDelayPathEl,
         "The negative endDelay path element should be in animation item element");
--- a/devtools/client/inspector/animation/test/browser_animation_summary-graph_tooltip.js
+++ b/devtools/client/inspector/animation/test/browser_animation_summary-graph_tooltip.js
@@ -176,17 +176,17 @@ const TEST_DATA = [
 
 add_task(async function() {
   await addTab(URL_ROOT + "doc_multi_timings.html");
   await removeAnimatedElementsExcept(TEST_DATA.map(t => `.${ t.targetClass }`));
   const { panel } = await openAnimationInspector();
 
   for (const { targetClass, expectedResult } of TEST_DATA) {
     const animationItemEl =
-      findAnimationItemElementsByTargetClassName(panel, targetClass);
+      findAnimationItemElementsByTargetSelector(panel, `.${ targetClass }`);
     const summaryGraphEl = animationItemEl.querySelector(".animation-summary-graph");
 
     info(`Checking tooltip for ${ targetClass }`);
     ok(summaryGraphEl.hasAttribute("title"),
       "Summary graph should have 'title' attribute");
 
     const tooltip = summaryGraphEl.getAttribute("title");
     const {
--- a/devtools/client/inspector/animation/test/head.js
+++ b/devtools/client/inspector/animation/test/head.js
@@ -101,24 +101,34 @@ const removeAnimatedElementsExcept = asy
  * @param {AnimationsPanel} panel
  *        The panel instance.
  * @param {Number} index
  *        The index of the animation to click on.
  */
 const clickOnAnimation = async function(animationInspector, panel, index) {
   info("Click on animation " + index + " in the timeline");
   const summaryGraphEl = panel.querySelectorAll(".animation-summary-graph")[index];
-  // Scroll to show the timeBlock since the element may be out of displayed area.
-  summaryGraphEl.scrollIntoView(false);
-  const bounds = summaryGraphEl.getBoundingClientRect();
-  const x = bounds.width / 2;
-  const y = bounds.height / 2;
-  EventUtils.synthesizeMouse(summaryGraphEl, x, y, {}, summaryGraphEl.ownerGlobal);
+  await clickOnSummaryGraph(animationInspector, panel, summaryGraphEl);
+};
 
-  await waitForAnimationDetail(animationInspector);
+/**
+ * Click on an animation by given selector of node which is target element of animation.
+ *
+ * @param {AnimationInspector} animationInspector.
+ * @param {AnimationsPanel} panel
+ *        The panel instance.
+ * @param {String} selector
+ *        Selector of node which is target element of animation.
+ */
+const clickOnAnimationByTargetSelector = async function(animationInspector,
+                                                        panel, selector) {
+  info(`Click on animation whose selector of target element is '${ selector }'`);
+  const animationItemEl = findAnimationItemElementsByTargetSelector(panel, selector);
+  const summaryGraphEl = animationItemEl.querySelector(".animation-summary-graph");
+  await clickOnSummaryGraph(animationInspector, panel, summaryGraphEl);
 };
 
 /**
  * Click on close button for animation detail pane.
  *
  * @param {AnimationsPanel} panel
  *        The panel instance.
  */
@@ -208,16 +218,35 @@ const clickOnPlaybackRateSelector = asyn
 
   const win = selectEl.ownerGlobal;
   EventUtils.synthesizeMouseAtCenter(selectEl, { type: "mousedown" }, win);
   EventUtils.synthesizeMouseAtCenter(optionEl, { type: "mouseup" }, win);
   await waitForSummaryAndDetail(animationInspector);
 };
 
 /**
+ * Click on given summary graph element.
+ *
+ * @param {AnimationInspector} animationInspector
+ * @param {AnimationsPanel} panel
+ * @param {Element} summaryGraphEl
+ */
+const clickOnSummaryGraph = async function(animationInspector, panel, summaryGraphEl) {
+  // Disable pointer-events of the scrubber in order to avoid to click accidently.
+  const scrubberEl = panel.querySelector(".current-time-scrubber");
+  scrubberEl.style.pointerEvents = "none";
+  // Scroll to show the timeBlock since the element may be out of displayed area.
+  summaryGraphEl.scrollIntoView(false);
+  EventUtils.synthesizeMouseAtCenter(summaryGraphEl, {}, summaryGraphEl.ownerGlobal);
+  await waitForAnimationDetail(animationInspector);
+  // Restore the scrubber style.
+  scrubberEl.style.pointerEvents = "unset";
+};
+
+/**
  * Drag on the scrubber to update the animation current time.
  *
  * @param {AnimationsPanel} panel
  * @param {Number} mouseDownPosition
  *        rate on scrubber controller pane.
  *        This method calculates
  *        `mouseDownPosition * offsetWidth + offsetLeft of scrubber controller pane`
  *        as the clientX of MouseEvent.
@@ -595,32 +624,31 @@ function isPassingThrough(pathSegList, x
       return true;
     }
     previousPathSeg = pathSeg;
   }
   return false;
 }
 
 /**
- * Return animation item element by target node class.
- * This function compares betweem animation-target textContent and given className.
- * Also, this function premises one class name.
+ * Return animation item element by target node selector.
+ * This function compares betweem animation-target textContent and given selector.
+ * Then returns matched first item.
  *
  * @param {Element} panel - root element of animation inspector.
- * @param {String} targetClassName - class name of tested element.
+ * @param {String} selector - selector of tested element.
  * @return {Element} animation item element.
  */
-function findAnimationItemElementsByTargetClassName(panel, targetClassName) {
-  const animationTargetEls = panel.querySelectorAll(".animation-target");
+function findAnimationItemElementsByTargetSelector(panel, selector) {
+  const attrNameEls = panel.querySelectorAll(".animation-target .attrName");
+  const regexp = new RegExp(`\\${ selector }(\\.|$)`, "gi");
 
-  for (const animationTargetEl of animationTargetEls) {
-    const className = animationTargetEl.textContent.split(".")[1];
-
-    if (className === targetClassName) {
-      return animationTargetEl.closest(".animation-item");
+  for (const attrNameEl of attrNameEls) {
+    if (regexp.exec(attrNameEl.textContent)) {
+      return attrNameEl.closest(".animation-item");
     }
   }
 
   return null;
 }
 
 /**
  * Find the <stop> element which has the given offset in the given linearGradientEl.