Bug 1310615 - eslint: force unix style linebreaks in devtools;r=jryans draft
authorJulian Descottes <jdescottes@mozilla.com>
Mon, 17 Oct 2016 11:47:03 +0200
changeset 426522 1267f5e399526a4090d8eff1b8fc9f27bbc19737
parent 426515 a84e0b5bc9939435ded1d3b90872d76d89687c66
child 534188 27fe4320c7ec16df715d436049917681350cd1de
push id32717
push userjdescottes@mozilla.com
push dateTue, 18 Oct 2016 15:26:54 +0000
reviewersjryans
bugs1310615
milestone52.0a1
Bug 1310615 - eslint: force unix style linebreaks in devtools;r=jryans MozReview-Commit-ID: BOmZ5vBJ3Fm
devtools/.eslintrc
devtools/client/animationinspector/test/browser_animation_animated_properties_displayed.js
devtools/client/animationinspector/test/browser_animation_click_selects_animation.js
devtools/client/animationinspector/test/browser_animation_controller_exposes_document_currentTime.js
devtools/client/animationinspector/test/browser_animation_keyframe_click_to_set_time.js
devtools/client/animationinspector/test/browser_animation_keyframe_markers.js
devtools/client/animationinspector/test/browser_animation_mutations_with_same_names.js
devtools/client/animationinspector/test/browser_animation_pseudo_elements.js
devtools/client/animationinspector/test/browser_animation_running_on_compositor.js
devtools/client/animationinspector/test/browser_animation_target_highlighter_lock.js
devtools/client/animationinspector/test/browser_animation_timeline_currentTime.js
devtools/client/animationinspector/test/browser_animation_timeline_iterationStart.js
devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js
devtools/client/animationinspector/test/browser_animation_timeline_rate_selector.js
devtools/client/animationinspector/test/browser_animation_timeline_rewind_button.js
devtools/client/animationinspector/test/browser_animation_timeline_scrubber_moves.js
devtools/client/animationinspector/test/browser_animation_timeline_shows_time_info.js
devtools/client/animationinspector/test/doc_negative_animation.html
devtools/client/animationinspector/test/unit/test_formatStopwatchTime.js
devtools/client/animationinspector/test/unit/test_getCssPropertyName.js
devtools/client/animationinspector/test/unit/test_timeScale_dimensions.js
devtools/client/inspector/markup/test/browser_markup_dragdrop_distance.js
devtools/client/inspector/markup/test/browser_markup_dragdrop_draggable.js
devtools/client/inspector/markup/test/browser_markup_keybindings_delete_attributes.js
devtools/client/inspector/markup/test/browser_markup_keybindings_scrolltonode.js
devtools/client/inspector/markup/test/browser_markup_whitespace.js
devtools/client/inspector/markup/test/doc_markup_image_and_canvas.html
devtools/client/inspector/markup/test/doc_markup_image_and_canvas_2.html
devtools/client/inspector/rules/test/browser_rules_add-rule-and-property.js
devtools/client/inspector/rules/test/browser_rules_add-rule-with-menu.js
devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js
devtools/client/inspector/rules/test/browser_rules_invalid-source-map.js
devtools/client/inspector/shared/dom-node-preview.js
devtools/client/inspector/shared/test/browser_styleinspector_context-menu-copy-urls.js
devtools/client/inspector/test/browser_inspector_addNode_01.js
devtools/client/inspector/test/browser_inspector_addNode_02.js
devtools/client/inspector/test/browser_inspector_addNode_03.js
devtools/client/inspector/test/browser_inspector_breadcrumbs_keybinding.js
devtools/client/inspector/test/browser_inspector_highlighter-embed.js
devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-clipboard.js
devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-csp.js
devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-events.js
devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-label.js
devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-show-hide.js
devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-xul.js
devtools/client/inspector/test/browser_inspector_highlighter-keybinding_01.js
devtools/client/inspector/test/browser_inspector_highlighter-keybinding_02.js
devtools/client/inspector/test/browser_inspector_highlighter-keybinding_03.js
devtools/client/inspector/test/browser_inspector_search-sidebar.js
devtools/client/inspector/test/browser_inspector_textbox-menu.js
devtools/client/shared/components/splitter/draggable.js
devtools/client/shared/components/splitter/split-box.js
--- a/devtools/.eslintrc
+++ b/devtools/.eslintrc
@@ -139,18 +139,18 @@
     // Deprecated, will be removed in 1.0.
     "global-strict": 0,
     // Only useful in a node environment.
     "handle-callback-err": 0,
     // Tab width.
     "indent": [2, 2, {"SwitchCase": 1}],
     // Enforces spacing between keys and values in object literal properties.
     "key-spacing": [2, {"beforeColon": false, "afterColon": true}],
-    // Allow mixed 'LF' and 'CRLF' as linebreaks.
-    "linebreak-style": 0,
+    // Enforces unix style line breaks.
+    "linebreak-style": [2, "unix"],
     // Don't enforce the maximum depth that blocks can be nested. The complexity
     // rule is a better rule to check this.
     "max-depth": 0,
     // Maximum length of a line.
     "max-len": [2, 90, 2, {"ignoreUrls": true, "ignorePattern": "data:image\/|\\s*require\\s*\\(|^\\s*loader\\.lazy|-\\*-"}],
     // Maximum depth callbacks can be nested.
     "max-nested-callbacks": [2, 3],
     // Don't limit the number of parameters that can be used in a function.
--- a/devtools/client/animationinspector/test/browser_animation_animated_properties_displayed.js
+++ b/devtools/client/animationinspector/test/browser_animation_animated_properties_displayed.js
@@ -1,86 +1,86 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const LAYOUT_ERRORS_L10N =
-  new LocalizationHelper("global/locale/layout_errors.properties");
-
-// Test that when an animation is selected, its list of animated properties is
-// displayed below it.
-
-const EXPECTED_PROPERTIES = [
-  "background-color",
-  "background-position-x",
-  "background-position-y",
-  "background-size",
-  "border-bottom-left-radius",
-  "border-bottom-right-radius",
-  "border-top-left-radius",
-  "border-top-right-radius",
-  "filter",
-  "height",
-  "transform",
-  "width"
-].sort();
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_keyframes.html");
-  let {panel} = yield openAnimationInspector();
-  let timeline = panel.animationsTimelineComponent;
-  let propertiesList = timeline.rootWrapperEl
-                               .querySelector(".animated-properties");
-
-  ok(!isNodeVisible(propertiesList),
-     "The list of properties panel is hidden by default");
-
-  info("Click to select the animation");
-  yield clickOnAnimation(panel, 0);
-
-  ok(isNodeVisible(propertiesList),
-     "The list of properties panel is shown");
-  ok(propertiesList.querySelectorAll(".property").length,
-     "The list of properties panel actually contains properties");
-  ok(hasExpectedProperties(propertiesList),
-     "The list of properties panel contains the right properties");
-
-  ok(hasExpectedWarnings(propertiesList),
-     "The list of properties panel contains the right warnings");
-
-  info("Click to unselect the animation");
-  yield clickOnAnimation(panel, 0, true);
-
-  ok(!isNodeVisible(propertiesList),
-     "The list of properties panel is hidden again");
-});
-
-function hasExpectedProperties(containerEl) {
-  let names = [...containerEl.querySelectorAll(".property .name")]
-              .map(n => n.textContent)
-              .sort();
-
-  if (names.length !== EXPECTED_PROPERTIES.length) {
-    return false;
-  }
-
-  for (let i = 0; i < names.length; i++) {
-    if (names[i] !== EXPECTED_PROPERTIES[i]) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-function hasExpectedWarnings(containerEl) {
-  let warnings = [...containerEl.querySelectorAll(".warning")];
-  for (let warning of warnings) {
-    let warningID =
-      "CompositorAnimationWarningTransformWithGeometricProperties";
-    if (warning.getAttribute("title") == LAYOUT_ERRORS_L10N.getStr(warningID)) {
-      return true;
-    }
-  }
-  return false;
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const LAYOUT_ERRORS_L10N =
+  new LocalizationHelper("global/locale/layout_errors.properties");
+
+// Test that when an animation is selected, its list of animated properties is
+// displayed below it.
+
+const EXPECTED_PROPERTIES = [
+  "background-color",
+  "background-position-x",
+  "background-position-y",
+  "background-size",
+  "border-bottom-left-radius",
+  "border-bottom-right-radius",
+  "border-top-left-radius",
+  "border-top-right-radius",
+  "filter",
+  "height",
+  "transform",
+  "width"
+].sort();
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_keyframes.html");
+  let {panel} = yield openAnimationInspector();
+  let timeline = panel.animationsTimelineComponent;
+  let propertiesList = timeline.rootWrapperEl
+                               .querySelector(".animated-properties");
+
+  ok(!isNodeVisible(propertiesList),
+     "The list of properties panel is hidden by default");
+
+  info("Click to select the animation");
+  yield clickOnAnimation(panel, 0);
+
+  ok(isNodeVisible(propertiesList),
+     "The list of properties panel is shown");
+  ok(propertiesList.querySelectorAll(".property").length,
+     "The list of properties panel actually contains properties");
+  ok(hasExpectedProperties(propertiesList),
+     "The list of properties panel contains the right properties");
+
+  ok(hasExpectedWarnings(propertiesList),
+     "The list of properties panel contains the right warnings");
+
+  info("Click to unselect the animation");
+  yield clickOnAnimation(panel, 0, true);
+
+  ok(!isNodeVisible(propertiesList),
+     "The list of properties panel is hidden again");
+});
+
+function hasExpectedProperties(containerEl) {
+  let names = [...containerEl.querySelectorAll(".property .name")]
+              .map(n => n.textContent)
+              .sort();
+
+  if (names.length !== EXPECTED_PROPERTIES.length) {
+    return false;
+  }
+
+  for (let i = 0; i < names.length; i++) {
+    if (names[i] !== EXPECTED_PROPERTIES[i]) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+function hasExpectedWarnings(containerEl) {
+  let warnings = [...containerEl.querySelectorAll(".warning")];
+  for (let warning of warnings) {
+    let warningID =
+      "CompositorAnimationWarningTransformWithGeometricProperties";
+    if (warning.getAttribute("title") == LAYOUT_ERRORS_L10N.getStr(warningID)) {
+      return true;
+    }
+  }
+  return false;
+}
--- a/devtools/client/animationinspector/test/browser_animation_click_selects_animation.js
+++ b/devtools/client/animationinspector/test/browser_animation_click_selects_animation.js
@@ -1,44 +1,44 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Check that animations displayed in the timeline can be selected by clicking
-// them, and that this emits the right events and adds the right classes.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-  let {panel} = yield openAnimationInspector();
-  let timeline = panel.animationsTimelineComponent;
-
-  let selected = timeline.rootWrapperEl.querySelectorAll(".animation.selected");
-  ok(!selected.length, "There are no animations selected by default");
-
-  info("Click on the first animation, expect the right event and right class");
-  let animation0 = yield clickOnAnimation(panel, 0);
-  is(animation0, timeline.animations[0],
-     "The selected event was emitted with the right animation");
-  ok(isTimeBlockSelected(timeline, 0),
-     "The time block has the right selected class");
-
-  info("Click on the second animation, expect it to be selected too");
-  let animation1 = yield clickOnAnimation(panel, 1);
-  is(animation1, timeline.animations[1],
-     "The selected event was emitted with the right animation");
-  ok(isTimeBlockSelected(timeline, 1),
-     "The second time block has the right selected class");
-
-  info("Click again on the first animation and check if it unselects");
-  yield clickOnAnimation(panel, 0, true);
-  ok(!isTimeBlockSelected(timeline, 0),
-     "The first time block has been unselected");
-});
-
-function isTimeBlockSelected(timeline, index) {
-  let animation = timeline.rootWrapperEl.querySelectorAll(".animation")[index];
-  let animatedProperties = timeline.rootWrapperEl.querySelectorAll(
-    ".animated-properties")[index];
-  return animation.classList.contains("selected") &&
-         animatedProperties.classList.contains("selected");
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Check that animations displayed in the timeline can be selected by clicking
+// them, and that this emits the right events and adds the right classes.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+  let {panel} = yield openAnimationInspector();
+  let timeline = panel.animationsTimelineComponent;
+
+  let selected = timeline.rootWrapperEl.querySelectorAll(".animation.selected");
+  ok(!selected.length, "There are no animations selected by default");
+
+  info("Click on the first animation, expect the right event and right class");
+  let animation0 = yield clickOnAnimation(panel, 0);
+  is(animation0, timeline.animations[0],
+     "The selected event was emitted with the right animation");
+  ok(isTimeBlockSelected(timeline, 0),
+     "The time block has the right selected class");
+
+  info("Click on the second animation, expect it to be selected too");
+  let animation1 = yield clickOnAnimation(panel, 1);
+  is(animation1, timeline.animations[1],
+     "The selected event was emitted with the right animation");
+  ok(isTimeBlockSelected(timeline, 1),
+     "The second time block has the right selected class");
+
+  info("Click again on the first animation and check if it unselects");
+  yield clickOnAnimation(panel, 0, true);
+  ok(!isTimeBlockSelected(timeline, 0),
+     "The first time block has been unselected");
+});
+
+function isTimeBlockSelected(timeline, index) {
+  let animation = timeline.rootWrapperEl.querySelectorAll(".animation")[index];
+  let animatedProperties = timeline.rootWrapperEl.querySelectorAll(
+    ".animated-properties")[index];
+  return animation.classList.contains("selected") &&
+         animatedProperties.classList.contains("selected");
+}
--- a/devtools/client/animationinspector/test/browser_animation_controller_exposes_document_currentTime.js
+++ b/devtools/client/animationinspector/test/browser_animation_controller_exposes_document_currentTime.js
@@ -1,43 +1,43 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that the controller provides the document.timeline currentTime (at least
-// the last known version since new animations were added).
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-  let {panel, controller} = yield openAnimationInspector();
-
-  ok(controller.documentCurrentTime, "The documentCurrentTime getter exists");
-  checkDocumentTimeIsCorrect(controller);
-  let time1 = controller.documentCurrentTime;
-
-  yield startNewAnimation(controller, panel);
-  checkDocumentTimeIsCorrect(controller);
-  let time2 = controller.documentCurrentTime;
-  ok(time2 > time1, "The new documentCurrentTime is higher than the old one");
-});
-
-function checkDocumentTimeIsCorrect(controller) {
-  let time = 0;
-  for (let {state} of controller.animationPlayers) {
-    time = Math.max(time, state.documentCurrentTime);
-  }
-  is(controller.documentCurrentTime, time,
-     "The documentCurrentTime is correct");
-}
-
-function* startNewAnimation(controller, panel) {
-  info("Add a new animation to the page and check the time again");
-  let onPlayerAdded = controller.once(controller.PLAYERS_UPDATED_EVENT);
-  yield executeInContent("devtools:test:setAttribute", {
-    selector: ".still",
-    attributeName: "class",
-    attributeValue: "ball still short"
-  });
-  yield onPlayerAdded;
-  yield waitForAllAnimationTargets(panel);
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that the controller provides the document.timeline currentTime (at least
+// the last known version since new animations were added).
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+  let {panel, controller} = yield openAnimationInspector();
+
+  ok(controller.documentCurrentTime, "The documentCurrentTime getter exists");
+  checkDocumentTimeIsCorrect(controller);
+  let time1 = controller.documentCurrentTime;
+
+  yield startNewAnimation(controller, panel);
+  checkDocumentTimeIsCorrect(controller);
+  let time2 = controller.documentCurrentTime;
+  ok(time2 > time1, "The new documentCurrentTime is higher than the old one");
+});
+
+function checkDocumentTimeIsCorrect(controller) {
+  let time = 0;
+  for (let {state} of controller.animationPlayers) {
+    time = Math.max(time, state.documentCurrentTime);
+  }
+  is(controller.documentCurrentTime, time,
+     "The documentCurrentTime is correct");
+}
+
+function* startNewAnimation(controller, panel) {
+  info("Add a new animation to the page and check the time again");
+  let onPlayerAdded = controller.once(controller.PLAYERS_UPDATED_EVENT);
+  yield executeInContent("devtools:test:setAttribute", {
+    selector: ".still",
+    attributeName: "class",
+    attributeValue: "ball still short"
+  });
+  yield onPlayerAdded;
+  yield waitForAllAnimationTargets(panel);
+}
--- a/devtools/client/animationinspector/test/browser_animation_keyframe_click_to_set_time.js
+++ b/devtools/client/animationinspector/test/browser_animation_keyframe_click_to_set_time.js
@@ -1,52 +1,52 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that animated properties' keyframes can be clicked, and that doing so
-// sets the current time in the timeline.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_keyframes.html");
-  let {panel} = yield openAnimationInspector();
-  let timeline = panel.animationsTimelineComponent;
-  let {scrubberEl} = timeline;
-
-  // XXX: The scrollbar is placed in the timeline in such a way that it causes
-  // the animations to be slightly offset with the header when it appears.
-  // So for now, let's hide the scrollbar. Bug 1229340 should fix this.
-  timeline.animationsEl.style.overflow = "hidden";
-
-  info("Expand the animation");
-  yield clickOnAnimation(panel, 0);
-
-  info("Click on the first keyframe of the first animated property");
-  yield clickKeyframe(panel, 0, "background-color", 0);
-
-  info("Make sure the scrubber stopped moving and is at the right position");
-  yield assertScrubberMoving(panel, false);
-  checkScrubberPos(scrubberEl, 0);
-
-  info("Click on a keyframe in the middle");
-  yield clickKeyframe(panel, 0, "transform", 2);
-
-  info("Make sure the scrubber is at the right position");
-  checkScrubberPos(scrubberEl, 50);
-});
-
-function* clickKeyframe(panel, animIndex, property, index) {
-  let keyframeComponent = getKeyframeComponent(panel, animIndex, property);
-  let keyframeEl = getKeyframeEl(panel, animIndex, property, index);
-
-  let onSelect = keyframeComponent.once("frame-selected");
-  EventUtils.sendMouseEvent({type: "click"}, keyframeEl,
-                            keyframeEl.ownerDocument.defaultView);
-  yield onSelect;
-}
-
-function checkScrubberPos(scrubberEl, pos) {
-  let newPos = Math.round(parseFloat(scrubberEl.style.left));
-  let expectedPos = Math.round(pos);
-  is(newPos, expectedPos, `The scrubber is at ${pos}%`);
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that animated properties' keyframes can be clicked, and that doing so
+// sets the current time in the timeline.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_keyframes.html");
+  let {panel} = yield openAnimationInspector();
+  let timeline = panel.animationsTimelineComponent;
+  let {scrubberEl} = timeline;
+
+  // XXX: The scrollbar is placed in the timeline in such a way that it causes
+  // the animations to be slightly offset with the header when it appears.
+  // So for now, let's hide the scrollbar. Bug 1229340 should fix this.
+  timeline.animationsEl.style.overflow = "hidden";
+
+  info("Expand the animation");
+  yield clickOnAnimation(panel, 0);
+
+  info("Click on the first keyframe of the first animated property");
+  yield clickKeyframe(panel, 0, "background-color", 0);
+
+  info("Make sure the scrubber stopped moving and is at the right position");
+  yield assertScrubberMoving(panel, false);
+  checkScrubberPos(scrubberEl, 0);
+
+  info("Click on a keyframe in the middle");
+  yield clickKeyframe(panel, 0, "transform", 2);
+
+  info("Make sure the scrubber is at the right position");
+  checkScrubberPos(scrubberEl, 50);
+});
+
+function* clickKeyframe(panel, animIndex, property, index) {
+  let keyframeComponent = getKeyframeComponent(panel, animIndex, property);
+  let keyframeEl = getKeyframeEl(panel, animIndex, property, index);
+
+  let onSelect = keyframeComponent.once("frame-selected");
+  EventUtils.sendMouseEvent({type: "click"}, keyframeEl,
+                            keyframeEl.ownerDocument.defaultView);
+  yield onSelect;
+}
+
+function checkScrubberPos(scrubberEl, pos) {
+  let newPos = Math.round(parseFloat(scrubberEl.style.left));
+  let expectedPos = Math.round(pos);
+  is(newPos, expectedPos, `The scrubber is at ${pos}%`);
+}
--- a/devtools/client/animationinspector/test/browser_animation_keyframe_markers.js
+++ b/devtools/client/animationinspector/test/browser_animation_keyframe_markers.js
@@ -1,74 +1,74 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that when an animation is selected and its list of properties is shown,
-// there are keyframes markers next to each property being animated.
-
-const EXPECTED_PROPERTIES = [
-  "backgroundColor",
-  "backgroundPosition",
-  "backgroundSize",
-  "borderBottomLeftRadius",
-  "borderBottomRightRadius",
-  "borderTopLeftRadius",
-  "borderTopRightRadius",
-  "filter",
-  "height",
-  "transform",
-  "width"
-];
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_keyframes.html");
-  let {panel} = yield openAnimationInspector();
-  let timeline = panel.animationsTimelineComponent;
-
-  info("Expand the animation");
-  yield clickOnAnimation(panel, 0);
-
-  ok(timeline.rootWrapperEl.querySelectorAll(".frames .keyframes").length,
-     "There are container elements for displaying keyframes");
-
-  let data = yield getExpectedKeyframesData(timeline.animations[0]);
-  for (let propertyName in data) {
-    info("Check the keyframe markers for " + propertyName);
-    let widthMarkerSelector = ".frame[data-property=" + propertyName + "]";
-    let markers = timeline.rootWrapperEl.querySelectorAll(widthMarkerSelector);
-
-    is(markers.length, data[propertyName].length,
-       "The right number of keyframes was found for " + propertyName);
-
-    let offsets = [...markers].map(m => parseFloat(m.dataset.offset));
-    let values = [...markers].map(m => m.dataset.value);
-    for (let i = 0; i < markers.length; i++) {
-      is(markers[i].dataset.offset, offsets[i],
-         "Marker " + i + " for " + propertyName + " has the right offset");
-      is(markers[i].dataset.value, values[i],
-         "Marker " + i + " for " + propertyName + " has the right value");
-    }
-  }
-});
-
-function* getExpectedKeyframesData(animation) {
-  // We're testing the UI state here, so it's fine to get the list of expected
-  // properties from the animation actor.
-  let properties = yield animation.getProperties();
-  let data = {};
-
-  for (let expectedProperty of EXPECTED_PROPERTIES) {
-    data[expectedProperty] = [];
-    for (let {name, values} of properties) {
-      if (name !== expectedProperty) {
-        continue;
-      }
-      for (let {offset, value} of values) {
-        data[expectedProperty].push({offset, value});
-      }
-    }
-  }
-
-  return data;
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that when an animation is selected and its list of properties is shown,
+// there are keyframes markers next to each property being animated.
+
+const EXPECTED_PROPERTIES = [
+  "backgroundColor",
+  "backgroundPosition",
+  "backgroundSize",
+  "borderBottomLeftRadius",
+  "borderBottomRightRadius",
+  "borderTopLeftRadius",
+  "borderTopRightRadius",
+  "filter",
+  "height",
+  "transform",
+  "width"
+];
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_keyframes.html");
+  let {panel} = yield openAnimationInspector();
+  let timeline = panel.animationsTimelineComponent;
+
+  info("Expand the animation");
+  yield clickOnAnimation(panel, 0);
+
+  ok(timeline.rootWrapperEl.querySelectorAll(".frames .keyframes").length,
+     "There are container elements for displaying keyframes");
+
+  let data = yield getExpectedKeyframesData(timeline.animations[0]);
+  for (let propertyName in data) {
+    info("Check the keyframe markers for " + propertyName);
+    let widthMarkerSelector = ".frame[data-property=" + propertyName + "]";
+    let markers = timeline.rootWrapperEl.querySelectorAll(widthMarkerSelector);
+
+    is(markers.length, data[propertyName].length,
+       "The right number of keyframes was found for " + propertyName);
+
+    let offsets = [...markers].map(m => parseFloat(m.dataset.offset));
+    let values = [...markers].map(m => m.dataset.value);
+    for (let i = 0; i < markers.length; i++) {
+      is(markers[i].dataset.offset, offsets[i],
+         "Marker " + i + " for " + propertyName + " has the right offset");
+      is(markers[i].dataset.value, values[i],
+         "Marker " + i + " for " + propertyName + " has the right value");
+    }
+  }
+});
+
+function* getExpectedKeyframesData(animation) {
+  // We're testing the UI state here, so it's fine to get the list of expected
+  // properties from the animation actor.
+  let properties = yield animation.getProperties();
+  let data = {};
+
+  for (let expectedProperty of EXPECTED_PROPERTIES) {
+    data[expectedProperty] = [];
+    for (let {name, values} of properties) {
+      if (name !== expectedProperty) {
+        continue;
+      }
+      for (let {offset, value} of values) {
+        data[expectedProperty].push({offset, value});
+      }
+    }
+  }
+
+  return data;
+}
--- a/devtools/client/animationinspector/test/browser_animation_mutations_with_same_names.js
+++ b/devtools/client/animationinspector/test/browser_animation_mutations_with_same_names.js
@@ -1,31 +1,31 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Check that when animations are added later (through animation mutations) and
-// if these animations have the same names, then all of them are still being
-// displayed (which should be true as long as these animations apply to
-// different nodes).
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_negative_animation.html");
-  let {controller, panel} = yield openAnimationInspector();
-
-  info("Wait until all animations have been added " +
-       "(they're added with setTimeout)");
-  while (controller.animationPlayers.length < 3) {
-    yield controller.once(controller.PLAYERS_UPDATED_EVENT);
-  }
-  yield waitForAllAnimationTargets(panel);
-
-  is(panel.animationsTimelineComponent.animations.length, 3,
-     "The timeline shows 3 animations too");
-
-  // Reduce the known nodeFronts to a set to make them unique.
-  let nodeFronts = new Set(panel.animationsTimelineComponent
-                                .targetNodes.map(n => n.previewer.nodeFront));
-  is(nodeFronts.size, 3,
-     "The animations are applied to 3 different node fronts");
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Check that when animations are added later (through animation mutations) and
+// if these animations have the same names, then all of them are still being
+// displayed (which should be true as long as these animations apply to
+// different nodes).
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_negative_animation.html");
+  let {controller, panel} = yield openAnimationInspector();
+
+  info("Wait until all animations have been added " +
+       "(they're added with setTimeout)");
+  while (controller.animationPlayers.length < 3) {
+    yield controller.once(controller.PLAYERS_UPDATED_EVENT);
+  }
+  yield waitForAllAnimationTargets(panel);
+
+  is(panel.animationsTimelineComponent.animations.length, 3,
+     "The timeline shows 3 animations too");
+
+  // Reduce the known nodeFronts to a set to make them unique.
+  let nodeFronts = new Set(panel.animationsTimelineComponent
+                                .targetNodes.map(n => n.previewer.nodeFront));
+  is(nodeFronts.size, 3,
+     "The animations are applied to 3 different node fronts");
+});
--- a/devtools/client/animationinspector/test/browser_animation_pseudo_elements.js
+++ b/devtools/client/animationinspector/test/browser_animation_pseudo_elements.js
@@ -1,49 +1,49 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that animated pseudo-elements do show in the timeline.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_pseudo_elements.html");
-  let {inspector, panel} = yield openAnimationInspector();
-  let timeline = panel.animationsTimelineComponent;
-
-  info("With <body> selected by default check the content of the timeline");
-  is(timeline.timeBlocks.length, 3, "There are 3 animations in the timeline");
-
-  let getTargetNodeText = index => {
-    let el = timeline.targetNodes[index].previewer.previewEl;
-    return [...el.childNodes]
-           .map(n => n.style.display === "none" ? "" : n.textContent)
-           .join("");
-  };
-
-  is(getTargetNodeText(0), "body", "The first animated node is <body>");
-  is(getTargetNodeText(1), "::before", "The second animated node is ::before");
-  is(getTargetNodeText(2), "::after", "The third animated node is ::after");
-
-  info("Getting the before and after nodeFronts");
-  let bodyContainer = yield getContainerForSelector("body", inspector);
-  let getBodyChildNodeFront = index => {
-    return bodyContainer.elt.children[1].childNodes[index].container.node;
-  };
-  let beforeNode = getBodyChildNodeFront(0);
-  let afterNode = getBodyChildNodeFront(1);
-
-  info("Select the ::before pseudo-element in the inspector");
-  yield selectNode(beforeNode, inspector);
-  is(timeline.timeBlocks.length, 1, "There is 1 animation in the timeline");
-  is(timeline.targetNodes[0].previewer.nodeFront,
-     inspector.selection.nodeFront,
-     "The right node front is displayed in the timeline");
-
-  info("Select the ::after pseudo-element in the inspector");
-  yield selectNode(afterNode, inspector);
-  is(timeline.timeBlocks.length, 1, "There is 1 animation in the timeline");
-  is(timeline.targetNodes[0].previewer.nodeFront,
-     inspector.selection.nodeFront,
-     "The right node front is displayed in the timeline");
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that animated pseudo-elements do show in the timeline.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_pseudo_elements.html");
+  let {inspector, panel} = yield openAnimationInspector();
+  let timeline = panel.animationsTimelineComponent;
+
+  info("With <body> selected by default check the content of the timeline");
+  is(timeline.timeBlocks.length, 3, "There are 3 animations in the timeline");
+
+  let getTargetNodeText = index => {
+    let el = timeline.targetNodes[index].previewer.previewEl;
+    return [...el.childNodes]
+           .map(n => n.style.display === "none" ? "" : n.textContent)
+           .join("");
+  };
+
+  is(getTargetNodeText(0), "body", "The first animated node is <body>");
+  is(getTargetNodeText(1), "::before", "The second animated node is ::before");
+  is(getTargetNodeText(2), "::after", "The third animated node is ::after");
+
+  info("Getting the before and after nodeFronts");
+  let bodyContainer = yield getContainerForSelector("body", inspector);
+  let getBodyChildNodeFront = index => {
+    return bodyContainer.elt.children[1].childNodes[index].container.node;
+  };
+  let beforeNode = getBodyChildNodeFront(0);
+  let afterNode = getBodyChildNodeFront(1);
+
+  info("Select the ::before pseudo-element in the inspector");
+  yield selectNode(beforeNode, inspector);
+  is(timeline.timeBlocks.length, 1, "There is 1 animation in the timeline");
+  is(timeline.targetNodes[0].previewer.nodeFront,
+     inspector.selection.nodeFront,
+     "The right node front is displayed in the timeline");
+
+  info("Select the ::after pseudo-element in the inspector");
+  yield selectNode(afterNode, inspector);
+  is(timeline.timeBlocks.length, 1, "There is 1 animation in the timeline");
+  is(timeline.targetNodes[0].previewer.nodeFront,
+     inspector.selection.nodeFront,
+     "The right node front is displayed in the timeline");
+});
--- a/devtools/client/animationinspector/test/browser_animation_running_on_compositor.js
+++ b/devtools/client/animationinspector/test/browser_animation_running_on_compositor.js
@@ -1,57 +1,57 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Test that when animations displayed in the timeline are running on the
-// compositor, they get a special icon and information in the tooltip.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-  let {inspector, panel} = yield openAnimationInspector();
-  let timeline = panel.animationsTimelineComponent;
-
-  info("Select a test node we know has an animation running on the compositor");
-  yield selectNodeAndWaitForAnimations(".animated", inspector);
-
-  let animationEl = timeline.animationsEl.querySelector(".animation");
-  ok(animationEl.classList.contains("fast-track"),
-     "The animation element has the fast-track css class");
-  ok(hasTooltip(animationEl,
-                ANIMATION_L10N.getStr("player.allPropertiesOnCompositorTooltip")),
-     "The animation element has the right tooltip content");
-
-  info("Select a node we know doesn't have an animation on the compositor");
-  yield selectNodeAndWaitForAnimations(".no-compositor", inspector);
-
-  animationEl = timeline.animationsEl.querySelector(".animation");
-  ok(!animationEl.classList.contains("fast-track"),
-     "The animation element does not have the fast-track css class");
-  ok(!hasTooltip(animationEl,
-                 ANIMATION_L10N.getStr("player.allPropertiesOnCompositorTooltip")),
-     "The animation element does not have oncompositor tooltip content");
-  ok(!hasTooltip(animationEl,
-                 ANIMATION_L10N.getStr("player.somePropertiesOnCompositorTooltip")),
-     "The animation element does not have oncompositor tooltip content");
-
-  info("Select a node we know has animation on the compositor and not on the" +
-       " compositor");
-  yield selectNodeAndWaitForAnimations(".compositor-notall", inspector);
-
-  animationEl = timeline.animationsEl.querySelector(".animation");
-  ok(animationEl.classList.contains("fast-track"),
-     "The animation element has the fast-track css class");
-  ok(hasTooltip(animationEl,
-                ANIMATION_L10N.getStr("player.somePropertiesOnCompositorTooltip")),
-     "The animation element has the right tooltip content");
-});
-
-function hasTooltip(animationEl, expected) {
-  let el = animationEl.querySelector(".name");
-  let tooltip = el.getAttribute("title");
-
-  return tooltip.indexOf(expected) !== -1;
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+// Test that when animations displayed in the timeline are running on the
+// compositor, they get a special icon and information in the tooltip.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+  let {inspector, panel} = yield openAnimationInspector();
+  let timeline = panel.animationsTimelineComponent;
+
+  info("Select a test node we know has an animation running on the compositor");
+  yield selectNodeAndWaitForAnimations(".animated", inspector);
+
+  let animationEl = timeline.animationsEl.querySelector(".animation");
+  ok(animationEl.classList.contains("fast-track"),
+     "The animation element has the fast-track css class");
+  ok(hasTooltip(animationEl,
+                ANIMATION_L10N.getStr("player.allPropertiesOnCompositorTooltip")),
+     "The animation element has the right tooltip content");
+
+  info("Select a node we know doesn't have an animation on the compositor");
+  yield selectNodeAndWaitForAnimations(".no-compositor", inspector);
+
+  animationEl = timeline.animationsEl.querySelector(".animation");
+  ok(!animationEl.classList.contains("fast-track"),
+     "The animation element does not have the fast-track css class");
+  ok(!hasTooltip(animationEl,
+                 ANIMATION_L10N.getStr("player.allPropertiesOnCompositorTooltip")),
+     "The animation element does not have oncompositor tooltip content");
+  ok(!hasTooltip(animationEl,
+                 ANIMATION_L10N.getStr("player.somePropertiesOnCompositorTooltip")),
+     "The animation element does not have oncompositor tooltip content");
+
+  info("Select a node we know has animation on the compositor and not on the" +
+       " compositor");
+  yield selectNodeAndWaitForAnimations(".compositor-notall", inspector);
+
+  animationEl = timeline.animationsEl.querySelector(".animation");
+  ok(animationEl.classList.contains("fast-track"),
+     "The animation element has the fast-track css class");
+  ok(hasTooltip(animationEl,
+                ANIMATION_L10N.getStr("player.somePropertiesOnCompositorTooltip")),
+     "The animation element has the right tooltip content");
+});
+
+function hasTooltip(animationEl, expected) {
+  let el = animationEl.querySelector(".name");
+  let tooltip = el.getAttribute("title");
+
+  return tooltip.indexOf(expected) !== -1;
+}
--- a/devtools/client/animationinspector/test/browser_animation_target_highlighter_lock.js
+++ b/devtools/client/animationinspector/test/browser_animation_target_highlighter_lock.js
@@ -1,54 +1,54 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Test that the DOM element targets displayed in animation player widgets can
-// be used to highlight elements in the DOM and select them in the inspector.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-  let {panel} = yield openAnimationInspector();
-
-  let targets = panel.animationsTimelineComponent.targetNodes;
-
-  info("Click on the highlighter icon for the first animated node");
-  let domNodePreview1 = targets[0].previewer;
-  yield lockHighlighterOn(domNodePreview1);
-  ok(domNodePreview1.highlightNodeEl.classList.contains("selected"),
-     "The highlighter icon is selected");
-
-  info("Click on the highlighter icon for the second animated node");
-  let domNodePreview2 = targets[1].previewer;
-  yield lockHighlighterOn(domNodePreview2);
-  ok(domNodePreview2.highlightNodeEl.classList.contains("selected"),
-     "The highlighter icon is selected");
-  ok(!domNodePreview1.highlightNodeEl.classList.contains("selected"),
-     "The highlighter icon for the first node is unselected");
-
-  info("Click again to unhighlight");
-  yield unlockHighlighterOn(domNodePreview2);
-  ok(!domNodePreview2.highlightNodeEl.classList.contains("selected"),
-     "The highlighter icon for the second node is unselected");
-});
-
-function* lockHighlighterOn(domNodePreview) {
-  let onLocked = domNodePreview.once("target-highlighter-locked");
-  clickOnHighlighterIcon(domNodePreview);
-  yield onLocked;
-}
-
-function* unlockHighlighterOn(domNodePreview) {
-  let onUnlocked = domNodePreview.once("target-highlighter-unlocked");
-  clickOnHighlighterIcon(domNodePreview);
-  yield onUnlocked;
-}
-
-function clickOnHighlighterIcon(domNodePreview) {
-  let lockEl = domNodePreview.highlightNodeEl;
-  EventUtils.sendMouseEvent({type: "click"}, lockEl,
-                            lockEl.ownerDocument.defaultView);
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+// Test that the DOM element targets displayed in animation player widgets can
+// be used to highlight elements in the DOM and select them in the inspector.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+  let {panel} = yield openAnimationInspector();
+
+  let targets = panel.animationsTimelineComponent.targetNodes;
+
+  info("Click on the highlighter icon for the first animated node");
+  let domNodePreview1 = targets[0].previewer;
+  yield lockHighlighterOn(domNodePreview1);
+  ok(domNodePreview1.highlightNodeEl.classList.contains("selected"),
+     "The highlighter icon is selected");
+
+  info("Click on the highlighter icon for the second animated node");
+  let domNodePreview2 = targets[1].previewer;
+  yield lockHighlighterOn(domNodePreview2);
+  ok(domNodePreview2.highlightNodeEl.classList.contains("selected"),
+     "The highlighter icon is selected");
+  ok(!domNodePreview1.highlightNodeEl.classList.contains("selected"),
+     "The highlighter icon for the first node is unselected");
+
+  info("Click again to unhighlight");
+  yield unlockHighlighterOn(domNodePreview2);
+  ok(!domNodePreview2.highlightNodeEl.classList.contains("selected"),
+     "The highlighter icon for the second node is unselected");
+});
+
+function* lockHighlighterOn(domNodePreview) {
+  let onLocked = domNodePreview.once("target-highlighter-locked");
+  clickOnHighlighterIcon(domNodePreview);
+  yield onLocked;
+}
+
+function* unlockHighlighterOn(domNodePreview) {
+  let onUnlocked = domNodePreview.once("target-highlighter-unlocked");
+  clickOnHighlighterIcon(domNodePreview);
+  yield onUnlocked;
+}
+
+function clickOnHighlighterIcon(domNodePreview) {
+  let lockEl = domNodePreview.highlightNodeEl;
+  EventUtils.sendMouseEvent({type: "click"}, lockEl,
+                            lockEl.ownerDocument.defaultView);
+}
--- a/devtools/client/animationinspector/test/browser_animation_timeline_currentTime.js
+++ b/devtools/client/animationinspector/test/browser_animation_timeline_currentTime.js
@@ -1,48 +1,48 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Check that the timeline toolbar displays the current time, and that it
-// changes when animations are playing, gets back to 0 when animations are
-// rewound, and stops when animations are paused.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-
-  let {panel} = yield openAnimationInspector();
-  let label = panel.timelineCurrentTimeEl;
-  ok(label, "The current time label exists");
-
-  // On page load animations are playing so the time shoud change, although we
-  // don't want to test the exact value of the time displayed, just that it
-  // actually changes.
-  info("Make sure the time displayed actually changes");
-  yield isCurrentTimeLabelChanging(panel, true);
-
-  info("Pause the animations and check that the time stops changing");
-  yield clickTimelinePlayPauseButton(panel);
-  yield isCurrentTimeLabelChanging(panel, false);
-
-  info("Rewind the animations and check that the time stops changing");
-  yield clickTimelineRewindButton(panel);
-  yield isCurrentTimeLabelChanging(panel, false);
-  is(label.textContent, "00:00.000");
-});
-
-function* isCurrentTimeLabelChanging(panel, isChanging) {
-  let label = panel.timelineCurrentTimeEl;
-
-  let time1 = label.textContent;
-  yield new Promise(r => setTimeout(r, 200));
-  let time2 = label.textContent;
-
-  if (isChanging) {
-    ok(time1 !== time2, "The text displayed in the label changes with time");
-  } else {
-    is(time1, time2, "The text displayed in the label doesn't change");
-  }
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+// Check that the timeline toolbar displays the current time, and that it
+// changes when animations are playing, gets back to 0 when animations are
+// rewound, and stops when animations are paused.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+
+  let {panel} = yield openAnimationInspector();
+  let label = panel.timelineCurrentTimeEl;
+  ok(label, "The current time label exists");
+
+  // On page load animations are playing so the time shoud change, although we
+  // don't want to test the exact value of the time displayed, just that it
+  // actually changes.
+  info("Make sure the time displayed actually changes");
+  yield isCurrentTimeLabelChanging(panel, true);
+
+  info("Pause the animations and check that the time stops changing");
+  yield clickTimelinePlayPauseButton(panel);
+  yield isCurrentTimeLabelChanging(panel, false);
+
+  info("Rewind the animations and check that the time stops changing");
+  yield clickTimelineRewindButton(panel);
+  yield isCurrentTimeLabelChanging(panel, false);
+  is(label.textContent, "00:00.000");
+});
+
+function* isCurrentTimeLabelChanging(panel, isChanging) {
+  let label = panel.timelineCurrentTimeEl;
+
+  let time1 = label.textContent;
+  yield new Promise(r => setTimeout(r, 200));
+  let time2 = label.textContent;
+
+  if (isChanging) {
+    ok(time1 !== time2, "The text displayed in the label changes with time");
+  } else {
+    is(time1, time2, "The text displayed in the label doesn't change");
+  }
+}
--- a/devtools/client/animationinspector/test/browser_animation_timeline_iterationStart.js
+++ b/devtools/client/animationinspector/test/browser_animation_timeline_iterationStart.js
@@ -1,84 +1,84 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Check that the iteration start is displayed correctly in time blocks.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_script_animation.html");
-  let {panel} = yield openAnimationInspector();
-  let timelineComponent = panel.animationsTimelineComponent;
-  let timeBlockComponents = timelineComponent.timeBlocks;
-  let detailsComponents = timelineComponent.details;
-
-  for (let i = 0; i < timeBlockComponents.length; i++) {
-    info(`Expand time block ${i} so its keyframes are visible`);
-    yield clickOnAnimation(panel, i);
-
-    info(`Check the state of time block ${i}`);
-    let {containerEl, animation: {state}} = timeBlockComponents[i];
-
-    checkAnimationTooltip(containerEl, state);
-    checkIterationBackground(containerEl, state);
-
-    // Get the first set of keyframes (there's only one animated property
-    // anyway), and the first frame element from there, we're only interested in
-    // its offset.
-    let keyframeComponent = detailsComponents[i].keyframeComponents[0];
-    let frameEl = keyframeComponent.keyframesEl.querySelector(".frame");
-    checkKeyframeOffset(containerEl, frameEl, state);
-  }
-});
-
-function checkAnimationTooltip(el, {iterationStart, duration}) {
-  info("Check an animation's iterationStart data in its tooltip");
-  let title = el.querySelector(".name").getAttribute("title");
-
-  let iterationStartTime = iterationStart * duration / 1000;
-  let iterationStartTimeString = iterationStartTime.toLocaleString(undefined, {
-    maximumFractionDigits: 2,
-    minimumFractionDigits: 2
-  }).replace(".", "\\.");
-  let iterationStartString = iterationStart.toString().replace(".", "\\.");
-
-  let regex = new RegExp("Iteration start: " + iterationStartString +
-                         " \\(" + iterationStartTimeString + "s\\)");
-  ok(title.match(regex), "The tooltip shows the expected iteration start");
-}
-
-function checkIterationBackground(el, {iterationCount, iterationStart}) {
-  info("Check the background-image used to display iterations is offset " +
-       "correctly to represent the iterationStart");
-
-  let iterationsEl = el.querySelector(".iterations");
-  let start = getIterationStartFromBackground(iterationsEl, iterationCount);
-  is(start, iterationStart % 1,
-     "The right background-position for iteration start");
-}
-
-function getIterationStartFromBackground(el, iterationCount) {
-  if (iterationCount == 1) {
-    let size = parseFloat(/([.\d]+)%/.exec(el.style.backgroundSize)[1]);
-    return 1 - size / 100;
-  }
-
-  let size = parseFloat(/([.\d]+)%/.exec(el.style.backgroundSize)[1]);
-  let position = parseFloat(/([-\d]+)%/.exec(el.style.backgroundPosition)[1]);
-  let iterationStartW = -position / size * (100 - size);
-  let rounded = Math.round(iterationStartW * 100);
-  return rounded / 10000;
-}
-
-function checkKeyframeOffset(timeBlockEl, frameEl, {iterationStart}) {
-  info("Check that the first keyframe is offset correctly");
-
-  let start = getIterationStartFromLeft(frameEl);
-  is(start, iterationStart % 1, "The frame offset for iteration start");
-}
-
-function getIterationStartFromLeft(el) {
-  let left = 100 - parseFloat(/(\d+)%/.exec(el.style.left)[1]);
-  return left / 100;
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Check that the iteration start is displayed correctly in time blocks.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_script_animation.html");
+  let {panel} = yield openAnimationInspector();
+  let timelineComponent = panel.animationsTimelineComponent;
+  let timeBlockComponents = timelineComponent.timeBlocks;
+  let detailsComponents = timelineComponent.details;
+
+  for (let i = 0; i < timeBlockComponents.length; i++) {
+    info(`Expand time block ${i} so its keyframes are visible`);
+    yield clickOnAnimation(panel, i);
+
+    info(`Check the state of time block ${i}`);
+    let {containerEl, animation: {state}} = timeBlockComponents[i];
+
+    checkAnimationTooltip(containerEl, state);
+    checkIterationBackground(containerEl, state);
+
+    // Get the first set of keyframes (there's only one animated property
+    // anyway), and the first frame element from there, we're only interested in
+    // its offset.
+    let keyframeComponent = detailsComponents[i].keyframeComponents[0];
+    let frameEl = keyframeComponent.keyframesEl.querySelector(".frame");
+    checkKeyframeOffset(containerEl, frameEl, state);
+  }
+});
+
+function checkAnimationTooltip(el, {iterationStart, duration}) {
+  info("Check an animation's iterationStart data in its tooltip");
+  let title = el.querySelector(".name").getAttribute("title");
+
+  let iterationStartTime = iterationStart * duration / 1000;
+  let iterationStartTimeString = iterationStartTime.toLocaleString(undefined, {
+    maximumFractionDigits: 2,
+    minimumFractionDigits: 2
+  }).replace(".", "\\.");
+  let iterationStartString = iterationStart.toString().replace(".", "\\.");
+
+  let regex = new RegExp("Iteration start: " + iterationStartString +
+                         " \\(" + iterationStartTimeString + "s\\)");
+  ok(title.match(regex), "The tooltip shows the expected iteration start");
+}
+
+function checkIterationBackground(el, {iterationCount, iterationStart}) {
+  info("Check the background-image used to display iterations is offset " +
+       "correctly to represent the iterationStart");
+
+  let iterationsEl = el.querySelector(".iterations");
+  let start = getIterationStartFromBackground(iterationsEl, iterationCount);
+  is(start, iterationStart % 1,
+     "The right background-position for iteration start");
+}
+
+function getIterationStartFromBackground(el, iterationCount) {
+  if (iterationCount == 1) {
+    let size = parseFloat(/([.\d]+)%/.exec(el.style.backgroundSize)[1]);
+    return 1 - size / 100;
+  }
+
+  let size = parseFloat(/([.\d]+)%/.exec(el.style.backgroundSize)[1]);
+  let position = parseFloat(/([-\d]+)%/.exec(el.style.backgroundPosition)[1]);
+  let iterationStartW = -position / size * (100 - size);
+  let rounded = Math.round(iterationStartW * 100);
+  return rounded / 10000;
+}
+
+function checkKeyframeOffset(timeBlockEl, frameEl, {iterationStart}) {
+  info("Check that the first keyframe is offset correctly");
+
+  let start = getIterationStartFromLeft(frameEl);
+  is(start, iterationStart % 1, "The frame offset for iteration start");
+}
+
+function getIterationStartFromLeft(el) {
+  let left = 100 - parseFloat(/(\d+)%/.exec(el.style.left)[1]);
+  return left / 100;
+}
--- a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js
+++ b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js
@@ -1,110 +1,110 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Check that the timeline toolbar contains a pause button and that this pause
-// button can be clicked. Check that when it is, the current animations
-// displayed in the timeline get their playstates changed accordingly, and check
-// that the scrubber resumes/stops moving.
-// Also checks that the button goes to the right state when the scrubber has
-// reached the end of the timeline: continues to be in playing mode for infinite
-// animations, goes to paused mode otherwise.
-// And test that clicking the button once the scrubber has reached the end of
-// the timeline does the right thing.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-
-  let {panel, inspector} = yield openAnimationInspector();
-  let timeline = panel.animationsTimelineComponent;
-  let btn = panel.playTimelineButtonEl;
-
-  ok(btn, "The play/pause button exists");
-  ok(!btn.classList.contains("paused"),
-     "The play/pause button is in its playing state");
-
-  info("Click on the button to pause all timeline animations");
-  yield clickTimelinePlayPauseButton(panel);
-
-  ok(btn.classList.contains("paused"),
-     "The play/pause button is in its paused state");
-  yield assertScrubberMoving(panel, false);
-
-  info("Click again on the button to play all timeline animations");
-  yield clickTimelinePlayPauseButton(panel);
-
-  ok(!btn.classList.contains("paused"),
-     "The play/pause button is in its playing state again");
-  yield assertScrubberMoving(panel, true);
-
-  // Some animations on the test page are infinite, so the scrubber won't stop
-  // at the end of the timeline, and the button should remain in play mode.
-  info("Select an infinite animation, reload the page and wait for the " +
-       "animation to complete");
-  yield selectNodeAndWaitForAnimations(".multi", inspector);
-  yield reloadTab(inspector);
-  yield waitForOutOfBoundScrubber(timeline);
-
-  ok(!btn.classList.contains("paused"),
-     "The button is in its playing state still, animations are infinite.");
-  yield assertScrubberMoving(panel, true);
-
-  info("Click on the button after the scrubber has moved out of bounds");
-  yield clickTimelinePlayPauseButton(panel);
-
-  ok(btn.classList.contains("paused"),
-     "The button can be paused after the scrubber has moved out of bounds");
-  yield assertScrubberMoving(panel, false);
-
-  // For a finite animation though, once the scrubber reaches the end of the
-  // timeline, it should go back to paused mode.
-  info("Select a finite animation, reload the page and wait for the " +
-       "animation to complete");
-  yield selectNodeAndWaitForAnimations(".negative-delay", inspector);
-
-  let onScrubberStopped = waitForScrubberStopped(timeline);
-  yield reloadTab(inspector);
-  yield onScrubberStopped;
-
-  ok(btn.classList.contains("paused"),
-     "The button is in paused state once finite animations are done");
-  yield assertScrubberMoving(panel, false);
-
-  info("Click again on the button to play the animation from the start again");
-  yield clickTimelinePlayPauseButton(panel);
-
-  ok(!btn.classList.contains("paused"),
-     "Clicking the button once finite animations are done should restart them");
-  yield assertScrubberMoving(panel, true);
-});
-
-function waitForOutOfBoundScrubber({win, scrubberEl}) {
-  return new Promise(resolve => {
-    function check() {
-      let pos = scrubberEl.getBoxQuads()[0].bounds.right;
-      let width = win.document.documentElement.offsetWidth;
-      if (pos >= width) {
-        setTimeout(resolve, 50);
-      } else {
-        setTimeout(check, 50);
-      }
-    }
-    check();
-  });
-}
-
-function waitForScrubberStopped(timeline) {
-  return new Promise(resolve => {
-    timeline.on("timeline-data-changed",
-      function onTimelineData(e, {isMoving}) {
-        if (!isMoving) {
-          timeline.off("timeline-data-changed", onTimelineData);
-          resolve();
-        }
-      });
-  });
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+// Check that the timeline toolbar contains a pause button and that this pause
+// button can be clicked. Check that when it is, the current animations
+// displayed in the timeline get their playstates changed accordingly, and check
+// that the scrubber resumes/stops moving.
+// Also checks that the button goes to the right state when the scrubber has
+// reached the end of the timeline: continues to be in playing mode for infinite
+// animations, goes to paused mode otherwise.
+// And test that clicking the button once the scrubber has reached the end of
+// the timeline does the right thing.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+
+  let {panel, inspector} = yield openAnimationInspector();
+  let timeline = panel.animationsTimelineComponent;
+  let btn = panel.playTimelineButtonEl;
+
+  ok(btn, "The play/pause button exists");
+  ok(!btn.classList.contains("paused"),
+     "The play/pause button is in its playing state");
+
+  info("Click on the button to pause all timeline animations");
+  yield clickTimelinePlayPauseButton(panel);
+
+  ok(btn.classList.contains("paused"),
+     "The play/pause button is in its paused state");
+  yield assertScrubberMoving(panel, false);
+
+  info("Click again on the button to play all timeline animations");
+  yield clickTimelinePlayPauseButton(panel);
+
+  ok(!btn.classList.contains("paused"),
+     "The play/pause button is in its playing state again");
+  yield assertScrubberMoving(panel, true);
+
+  // Some animations on the test page are infinite, so the scrubber won't stop
+  // at the end of the timeline, and the button should remain in play mode.
+  info("Select an infinite animation, reload the page and wait for the " +
+       "animation to complete");
+  yield selectNodeAndWaitForAnimations(".multi", inspector);
+  yield reloadTab(inspector);
+  yield waitForOutOfBoundScrubber(timeline);
+
+  ok(!btn.classList.contains("paused"),
+     "The button is in its playing state still, animations are infinite.");
+  yield assertScrubberMoving(panel, true);
+
+  info("Click on the button after the scrubber has moved out of bounds");
+  yield clickTimelinePlayPauseButton(panel);
+
+  ok(btn.classList.contains("paused"),
+     "The button can be paused after the scrubber has moved out of bounds");
+  yield assertScrubberMoving(panel, false);
+
+  // For a finite animation though, once the scrubber reaches the end of the
+  // timeline, it should go back to paused mode.
+  info("Select a finite animation, reload the page and wait for the " +
+       "animation to complete");
+  yield selectNodeAndWaitForAnimations(".negative-delay", inspector);
+
+  let onScrubberStopped = waitForScrubberStopped(timeline);
+  yield reloadTab(inspector);
+  yield onScrubberStopped;
+
+  ok(btn.classList.contains("paused"),
+     "The button is in paused state once finite animations are done");
+  yield assertScrubberMoving(panel, false);
+
+  info("Click again on the button to play the animation from the start again");
+  yield clickTimelinePlayPauseButton(panel);
+
+  ok(!btn.classList.contains("paused"),
+     "Clicking the button once finite animations are done should restart them");
+  yield assertScrubberMoving(panel, true);
+});
+
+function waitForOutOfBoundScrubber({win, scrubberEl}) {
+  return new Promise(resolve => {
+    function check() {
+      let pos = scrubberEl.getBoxQuads()[0].bounds.right;
+      let width = win.document.documentElement.offsetWidth;
+      if (pos >= width) {
+        setTimeout(resolve, 50);
+      } else {
+        setTimeout(check, 50);
+      }
+    }
+    check();
+  });
+}
+
+function waitForScrubberStopped(timeline) {
+  return new Promise(resolve => {
+    timeline.on("timeline-data-changed",
+      function onTimelineData(e, {isMoving}) {
+        if (!isMoving) {
+          timeline.off("timeline-data-changed", onTimelineData);
+          resolve();
+        }
+      });
+  });
+}
--- a/devtools/client/animationinspector/test/browser_animation_timeline_rate_selector.js
+++ b/devtools/client/animationinspector/test/browser_animation_timeline_rate_selector.js
@@ -1,56 +1,56 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Check that the timeline toolbar contains a playback rate selector UI and that
-// it can be used to change the playback rate of animations in the timeline.
-// Also check that it displays the rate of the current animations in case they
-// all have the same rate, or that it displays the empty value in case they
-// have mixed rates.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-
-  let {panel, controller, inspector, toolbox} = yield openAnimationInspector();
-
-  // In this test, we disable the highlighter on purpose because of the way
-  // events are simulated to select an option in the playbackRate <select>.
-  // Indeed, this may cause mousemove events to be triggered on the nodes that
-  // are underneath the <select>, and these are AnimationTargetNode instances.
-  // Simulating mouse events on them will cause the highlighter to emit requests
-  // and this might cause the test to fail if they happen after it has ended.
-  disableHighlighter(toolbox);
-
-  let select = panel.rateSelectorEl.firstChild;
-
-  ok(select, "The rate selector exists");
-
-  info("Change all of the current animations' rates to 0.5");
-  yield changeTimelinePlaybackRate(panel, .5);
-  checkAllAnimationsRatesChanged(controller, select, .5);
-
-  info("Select just one animated node and change its rate only");
-  yield selectNodeAndWaitForAnimations(".animated", inspector);
-
-  yield changeTimelinePlaybackRate(panel, 2);
-  checkAllAnimationsRatesChanged(controller, select, 2);
-
-  info("Select the <body> again, it should now have mixed-rates animations");
-  yield selectNodeAndWaitForAnimations("body", inspector);
-
-  is(select.value, "", "The selected rate is empty");
-
-  info("Change the rate for these mixed-rate animations");
-  yield changeTimelinePlaybackRate(panel, 1);
-  checkAllAnimationsRatesChanged(controller, select, 1);
-});
-
-function checkAllAnimationsRatesChanged({animationPlayers}, select, rate) {
-  ok(animationPlayers.every(({state}) => state.playbackRate === rate),
-     "All animations' rates have been set to " + rate);
-  is(select.value, rate, "The right value is displayed in the select");
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+// Check that the timeline toolbar contains a playback rate selector UI and that
+// it can be used to change the playback rate of animations in the timeline.
+// Also check that it displays the rate of the current animations in case they
+// all have the same rate, or that it displays the empty value in case they
+// have mixed rates.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+
+  let {panel, controller, inspector, toolbox} = yield openAnimationInspector();
+
+  // In this test, we disable the highlighter on purpose because of the way
+  // events are simulated to select an option in the playbackRate <select>.
+  // Indeed, this may cause mousemove events to be triggered on the nodes that
+  // are underneath the <select>, and these are AnimationTargetNode instances.
+  // Simulating mouse events on them will cause the highlighter to emit requests
+  // and this might cause the test to fail if they happen after it has ended.
+  disableHighlighter(toolbox);
+
+  let select = panel.rateSelectorEl.firstChild;
+
+  ok(select, "The rate selector exists");
+
+  info("Change all of the current animations' rates to 0.5");
+  yield changeTimelinePlaybackRate(panel, .5);
+  checkAllAnimationsRatesChanged(controller, select, .5);
+
+  info("Select just one animated node and change its rate only");
+  yield selectNodeAndWaitForAnimations(".animated", inspector);
+
+  yield changeTimelinePlaybackRate(panel, 2);
+  checkAllAnimationsRatesChanged(controller, select, 2);
+
+  info("Select the <body> again, it should now have mixed-rates animations");
+  yield selectNodeAndWaitForAnimations("body", inspector);
+
+  is(select.value, "", "The selected rate is empty");
+
+  info("Change the rate for these mixed-rate animations");
+  yield changeTimelinePlaybackRate(panel, 1);
+  checkAllAnimationsRatesChanged(controller, select, 1);
+});
+
+function checkAllAnimationsRatesChanged({animationPlayers}, select, rate) {
+  ok(animationPlayers.every(({state}) => state.playbackRate === rate),
+     "All animations' rates have been set to " + rate);
+  is(select.value, rate, "The right value is displayed in the select");
+}
--- a/devtools/client/animationinspector/test/browser_animation_timeline_rewind_button.js
+++ b/devtools/client/animationinspector/test/browser_animation_timeline_rewind_button.js
@@ -1,51 +1,51 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Check that the timeline toolbar contains a rewind button and that it can be
-// clicked. Check that when it is, the current animations displayed in the
-// timeline get their playstates changed to paused, and their currentTimes
-// reset to 0, and that the scrubber stops moving and is positioned to the
-// start.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-
-  let {panel, controller} = yield openAnimationInspector();
-  let players = controller.animationPlayers;
-  let btn = panel.rewindTimelineButtonEl;
-
-  ok(btn, "The rewind button exists");
-
-  info("Click on the button to rewind all timeline animations");
-  yield clickTimelineRewindButton(panel);
-
-  info("Check that the scrubber has stopped moving");
-  yield assertScrubberMoving(panel, false);
-
-  ok(players.every(({state}) => state.currentTime === 0),
-     "All animations' currentTimes have been set to 0");
-  ok(players.every(({state}) => state.playState === "paused"),
-     "All animations have been paused");
-
-  info("Play the animations again");
-  yield clickTimelinePlayPauseButton(panel);
-
-  info("And pause them after a short while");
-  yield new Promise(r => setTimeout(r, 200));
-
-  info("Check that rewinding when animations are paused works too");
-  yield clickTimelineRewindButton(panel);
-
-  info("Check that the scrubber has stopped moving");
-  yield assertScrubberMoving(panel, false);
-
-  ok(players.every(({state}) => state.currentTime === 0),
-     "All animations' currentTimes have been set to 0");
-  ok(players.every(({state}) => state.playState === "paused"),
-     "All animations have been paused");
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+// Check that the timeline toolbar contains a rewind button and that it can be
+// clicked. Check that when it is, the current animations displayed in the
+// timeline get their playstates changed to paused, and their currentTimes
+// reset to 0, and that the scrubber stops moving and is positioned to the
+// start.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+
+  let {panel, controller} = yield openAnimationInspector();
+  let players = controller.animationPlayers;
+  let btn = panel.rewindTimelineButtonEl;
+
+  ok(btn, "The rewind button exists");
+
+  info("Click on the button to rewind all timeline animations");
+  yield clickTimelineRewindButton(panel);
+
+  info("Check that the scrubber has stopped moving");
+  yield assertScrubberMoving(panel, false);
+
+  ok(players.every(({state}) => state.currentTime === 0),
+     "All animations' currentTimes have been set to 0");
+  ok(players.every(({state}) => state.playState === "paused"),
+     "All animations have been paused");
+
+  info("Play the animations again");
+  yield clickTimelinePlayPauseButton(panel);
+
+  info("And pause them after a short while");
+  yield new Promise(r => setTimeout(r, 200));
+
+  info("Check that rewinding when animations are paused works too");
+  yield clickTimelineRewindButton(panel);
+
+  info("Check that the scrubber has stopped moving");
+  yield assertScrubberMoving(panel, false);
+
+  ok(players.every(({state}) => state.currentTime === 0),
+     "All animations' currentTimes have been set to 0");
+  ok(players.every(({state}) => state.playState === "paused"),
+     "All animations have been paused");
+});
--- a/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_moves.js
+++ b/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_moves.js
@@ -1,28 +1,28 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Check that the scrubber in the timeline moves when animations are playing.
-// The animations in the test page last for a very long time, so the test just
-// measures the position of the scrubber once, then waits for some time to pass
-// and measures its position again.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-  let {panel} = yield openAnimationInspector();
-
-  let timeline = panel.animationsTimelineComponent;
-  let scrubberEl = timeline.scrubberEl;
-  let startPos = scrubberEl.getBoundingClientRect().left;
-
-  info("Wait for some time to check that the scrubber moves");
-  yield new Promise(r => setTimeout(r, 2000));
-
-  let endPos = scrubberEl.getBoundingClientRect().left;
-
-  ok(endPos > startPos, "The scrubber has moved");
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+// Check that the scrubber in the timeline moves when animations are playing.
+// The animations in the test page last for a very long time, so the test just
+// measures the position of the scrubber once, then waits for some time to pass
+// and measures its position again.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+  let {panel} = yield openAnimationInspector();
+
+  let timeline = panel.animationsTimelineComponent;
+  let scrubberEl = timeline.scrubberEl;
+  let startPos = scrubberEl.getBoundingClientRect().left;
+
+  info("Wait for some time to check that the scrubber moves");
+  yield new Promise(r => setTimeout(r, 2000));
+
+  let endPos = scrubberEl.getBoundingClientRect().left;
+
+  ok(endPos > startPos, "The scrubber has moved");
+});
--- a/devtools/client/animationinspector/test/browser_animation_timeline_shows_time_info.js
+++ b/devtools/client/animationinspector/test/browser_animation_timeline_shows_time_info.js
@@ -1,41 +1,41 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Check that the timeline displays animations' duration, delay iteration
-// counts and iteration start in tooltips.
-
-add_task(function* () {
-  yield addTab(URL_ROOT + "doc_simple_animation.html");
-  let {panel, controller} = yield openAnimationInspector();
-
-  info("Getting the animation element from the panel");
-  let timelineEl = panel.animationsTimelineComponent.rootWrapperEl;
-  let timeBlockNameEls = timelineEl.querySelectorAll(".time-block .name");
-
-  // Verify that each time-block's name element has a tooltip that looks sort of
-  // ok. We don't need to test the actual content.
-  [...timeBlockNameEls].forEach((el, i) => {
-    ok(el.hasAttribute("title"), "The tooltip is defined for animation " + i);
-
-    let title = el.getAttribute("title");
-    if (controller.animationPlayers[i].state.delay) {
-      ok(title.match(/Delay: [\d.-]+s/), "The tooltip shows the delay");
-    }
-    ok(title.match(/Duration: [\d.]+s/), "The tooltip shows the duration");
-    if (controller.animationPlayers[i].state.endDelay) {
-      ok(title.match(/End delay: [\d.-]+s/), "The tooltip shows the endDelay");
-    }
-    if (controller.animationPlayers[i].state.iterationCount !== 1) {
-      ok(title.match(/Repeats: /), "The tooltip shows the iterations");
-    } else {
-      ok(!title.match(/Repeats: /), "The tooltip doesn't show the iterations");
-    }
-    ok(!title.match(/Iteration start:/),
-      "The tooltip doesn't show the iteration start");
-  });
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+// Check that the timeline displays animations' duration, delay iteration
+// counts and iteration start in tooltips.
+
+add_task(function* () {
+  yield addTab(URL_ROOT + "doc_simple_animation.html");
+  let {panel, controller} = yield openAnimationInspector();
+
+  info("Getting the animation element from the panel");
+  let timelineEl = panel.animationsTimelineComponent.rootWrapperEl;
+  let timeBlockNameEls = timelineEl.querySelectorAll(".time-block .name");
+
+  // Verify that each time-block's name element has a tooltip that looks sort of
+  // ok. We don't need to test the actual content.
+  [...timeBlockNameEls].forEach((el, i) => {
+    ok(el.hasAttribute("title"), "The tooltip is defined for animation " + i);
+
+    let title = el.getAttribute("title");
+    if (controller.animationPlayers[i].state.delay) {
+      ok(title.match(/Delay: [\d.-]+s/), "The tooltip shows the delay");
+    }
+    ok(title.match(/Duration: [\d.]+s/), "The tooltip shows the duration");
+    if (controller.animationPlayers[i].state.endDelay) {
+      ok(title.match(/End delay: [\d.-]+s/), "The tooltip shows the endDelay");
+    }
+    if (controller.animationPlayers[i].state.iterationCount !== 1) {
+      ok(title.match(/Repeats: /), "The tooltip shows the iterations");
+    } else {
+      ok(!title.match(/Repeats: /), "The tooltip doesn't show the iterations");
+    }
+    ok(!title.match(/Iteration start:/),
+      "The tooltip doesn't show the iteration start");
+  });
+});
--- a/devtools/client/animationinspector/test/doc_negative_animation.html
+++ b/devtools/client/animationinspector/test/doc_negative_animation.html
@@ -1,66 +1,66 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <style>
-  html, body {
-    margin: 0;
-    height: 100%;
-    overflow: hidden;
-  }
-
-  div {
-    position: absolute;
-    top: 0;
-    left: -500px;
-    height: 20px;
-    width: 500px;
-    color: red;
-    background: linear-gradient(to left, currentColor, currentColor 2px, transparent);
-  }
-
-  .zero {
-    color: blue;
-    top: 20px;
-  }
-
-  .positive {
-    color: green;
-    top: 40px;
-  }
-
-  .negative.move { animation: 5s -1s move linear forwards; }
-  .zero.move { animation: 5s 0s move linear forwards; }
-  .positive.move { animation: 5s 1s move linear forwards; }
-
-  @keyframes move {
-    to {
-      transform: translateX(500px);
-    }
-  }
-  </style>
-</head>
-<body>
-  <div class="negative"></div>
-  <div class="zero"></div>
-  <div class="positive"></div>
-  <script>
-    "use strict";
-
-    var negative = document.querySelector(".negative");
-    var zero = document.querySelector(".zero");
-    var positive = document.querySelector(".positive");
-
-    // The non-delayed animation starts now.
-    zero.classList.add("move");
-    // The negative-delayed animation starts in 1 second.
-    setTimeout(function () {
-      negative.classList.add("move");
-    }, 1000);
-    // The positive-delayed animation starts in 200 ms.
-    setTimeout(function () {
-      positive.classList.add("move");
-    }, 200);
-  </script>
-</body>
-</html>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <style>
+  html, body {
+    margin: 0;
+    height: 100%;
+    overflow: hidden;
+  }
+
+  div {
+    position: absolute;
+    top: 0;
+    left: -500px;
+    height: 20px;
+    width: 500px;
+    color: red;
+    background: linear-gradient(to left, currentColor, currentColor 2px, transparent);
+  }
+
+  .zero {
+    color: blue;
+    top: 20px;
+  }
+
+  .positive {
+    color: green;
+    top: 40px;
+  }
+
+  .negative.move { animation: 5s -1s move linear forwards; }
+  .zero.move { animation: 5s 0s move linear forwards; }
+  .positive.move { animation: 5s 1s move linear forwards; }
+
+  @keyframes move {
+    to {
+      transform: translateX(500px);
+    }
+  }
+  </style>
+</head>
+<body>
+  <div class="negative"></div>
+  <div class="zero"></div>
+  <div class="positive"></div>
+  <script>
+    "use strict";
+
+    var negative = document.querySelector(".negative");
+    var zero = document.querySelector(".zero");
+    var positive = document.querySelector(".positive");
+
+    // The non-delayed animation starts now.
+    zero.classList.add("move");
+    // The negative-delayed animation starts in 1 second.
+    setTimeout(function () {
+      negative.classList.add("move");
+    }, 1000);
+    // The positive-delayed animation starts in 200 ms.
+    setTimeout(function () {
+      positive.classList.add("move");
+    }, 200);
+  </script>
+</body>
+</html>
--- a/devtools/client/animationinspector/test/unit/test_formatStopwatchTime.js
+++ b/devtools/client/animationinspector/test/unit/test_formatStopwatchTime.js
@@ -1,62 +1,62 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var Cu = Components.utils;
-const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
-const {formatStopwatchTime} = require("devtools/client/animationinspector/utils");
-
-const TEST_DATA = [{
-  desc: "Formatting 0",
-  time: 0,
-  expected: "00:00.000"
-}, {
-  desc: "Formatting null",
-  time: null,
-  expected: "00:00.000"
-}, {
-  desc: "Formatting undefined",
-  time: undefined,
-  expected: "00:00.000"
-}, {
-  desc: "Formatting a small number of ms",
-  time: 13,
-  expected: "00:00.013"
-}, {
-  desc: "Formatting a slightly larger number of ms",
-  time: 500,
-  expected: "00:00.500"
-}, {
-  desc: "Formatting 1 second",
-  time: 1000,
-  expected: "00:01.000"
-}, {
-  desc: "Formatting a number of seconds",
-  time: 1532,
-  expected: "00:01.532"
-}, {
-  desc: "Formatting a big number of seconds",
-  time: 58450,
-  expected: "00:58.450"
-}, {
-  desc: "Formatting 1 minute",
-  time: 60000,
-  expected: "01:00.000"
-}, {
-  desc: "Formatting a number of minutes",
-  time: 263567,
-  expected: "04:23.567"
-}, {
-  desc: "Formatting a large number of minutes",
-  time: 1000 * 60 * 60 * 3,
-  expected: "180:00.000"
-}];
-
-function run_test() {
-  for (let {desc, time, expected} of TEST_DATA) {
-    equal(formatStopwatchTime(time), expected, desc);
-  }
-}
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+var Cu = Components.utils;
+const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
+const {formatStopwatchTime} = require("devtools/client/animationinspector/utils");
+
+const TEST_DATA = [{
+  desc: "Formatting 0",
+  time: 0,
+  expected: "00:00.000"
+}, {
+  desc: "Formatting null",
+  time: null,
+  expected: "00:00.000"
+}, {
+  desc: "Formatting undefined",
+  time: undefined,
+  expected: "00:00.000"
+}, {
+  desc: "Formatting a small number of ms",
+  time: 13,
+  expected: "00:00.013"
+}, {
+  desc: "Formatting a slightly larger number of ms",
+  time: 500,
+  expected: "00:00.500"
+}, {
+  desc: "Formatting 1 second",
+  time: 1000,
+  expected: "00:01.000"
+}, {
+  desc: "Formatting a number of seconds",
+  time: 1532,
+  expected: "00:01.532"
+}, {
+  desc: "Formatting a big number of seconds",
+  time: 58450,
+  expected: "00:58.450"
+}, {
+  desc: "Formatting 1 minute",
+  time: 60000,
+  expected: "01:00.000"
+}, {
+  desc: "Formatting a number of minutes",
+  time: 263567,
+  expected: "04:23.567"
+}, {
+  desc: "Formatting a large number of minutes",
+  time: 1000 * 60 * 60 * 3,
+  expected: "180:00.000"
+}];
+
+function run_test() {
+  for (let {desc, time, expected} of TEST_DATA) {
+    equal(formatStopwatchTime(time), expected, desc);
+  }
+}
--- a/devtools/client/animationinspector/test/unit/test_getCssPropertyName.js
+++ b/devtools/client/animationinspector/test/unit/test_getCssPropertyName.js
@@ -1,27 +1,27 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var Cu = Components.utils;
-const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
-const {getCssPropertyName} = require("devtools/client/animationinspector/components/animation-details");
-
-const TEST_DATA = [{
-  jsName: "alllowercase",
-  cssName: "alllowercase"
-}, {
-  jsName: "borderWidth",
-  cssName: "border-width"
-}, {
-  jsName: "borderTopRightRadius",
-  cssName: "border-top-right-radius"
-}];
-
-function run_test() {
-  for (let {jsName, cssName} of TEST_DATA) {
-    equal(getCssPropertyName(jsName), cssName);
-  }
-}
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+var Cu = Components.utils;
+const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
+const {getCssPropertyName} = require("devtools/client/animationinspector/components/animation-details");
+
+const TEST_DATA = [{
+  jsName: "alllowercase",
+  cssName: "alllowercase"
+}, {
+  jsName: "borderWidth",
+  cssName: "border-width"
+}, {
+  jsName: "borderTopRightRadius",
+  cssName: "border-top-right-radius"
+}];
+
+function run_test() {
+  for (let {jsName, cssName} of TEST_DATA) {
+    equal(getCssPropertyName(jsName), cssName);
+  }
+}
--- a/devtools/client/animationinspector/test/unit/test_timeScale_dimensions.js
+++ b/devtools/client/animationinspector/test/unit/test_timeScale_dimensions.js
@@ -1,54 +1,54 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
-   https://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const Cu = Components.utils;
-const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
-const {TimeScale} = require("devtools/client/animationinspector/utils");
-
-const TEST_ENDDELAY_X = [{
-  desc: "Testing positive-endDelay animations",
-  animations: [{
-    previousStartTime: 0,
-    duration: 500,
-    playbackRate: 1,
-    iterationCount: 3,
-    delay: 500,
-    endDelay: 500
-  }],
-  expectedEndDelayX: 80
-}, {
-  desc: "Testing negative-endDelay animations",
-  animations: [{
-    previousStartTime: 0,
-    duration: 500,
-    playbackRate: 1,
-    iterationCount: 9,
-    delay: 500,
-    endDelay: -500
-  }],
-  expectedEndDelayX: 90
-}];
-
-function run_test() {
-  do_print("Test calculating endDelayX");
-
-  // Be independent of possible prior tests
-  TimeScale.reset();
-
-  for (let {desc, animations, expectedEndDelayX} of TEST_ENDDELAY_X) {
-    do_print(`Adding animations: ${desc}`);
-
-    for (let state of animations) {
-      TimeScale.addAnimation(state);
-
-      let {endDelayX} = TimeScale.getAnimationDimensions({state});
-      equal(endDelayX, expectedEndDelayX);
-
-      TimeScale.reset();
-    }
-  }
-}
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   https://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const Cu = Components.utils;
+const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
+const {TimeScale} = require("devtools/client/animationinspector/utils");
+
+const TEST_ENDDELAY_X = [{
+  desc: "Testing positive-endDelay animations",
+  animations: [{
+    previousStartTime: 0,
+    duration: 500,
+    playbackRate: 1,
+    iterationCount: 3,
+    delay: 500,
+    endDelay: 500
+  }],
+  expectedEndDelayX: 80
+}, {
+  desc: "Testing negative-endDelay animations",
+  animations: [{
+    previousStartTime: 0,
+    duration: 500,
+    playbackRate: 1,
+    iterationCount: 9,
+    delay: 500,
+    endDelay: -500
+  }],
+  expectedEndDelayX: 90
+}];
+
+function run_test() {
+  do_print("Test calculating endDelayX");
+
+  // Be independent of possible prior tests
+  TimeScale.reset();
+
+  for (let {desc, animations, expectedEndDelayX} of TEST_ENDDELAY_X) {
+    do_print(`Adding animations: ${desc}`);
+
+    for (let state of animations) {
+      TimeScale.addAnimation(state);
+
+      let {endDelayX} = TimeScale.getAnimationDimensions({state});
+      equal(endDelayX, expectedEndDelayX);
+
+      TimeScale.reset();
+    }
+  }
+}
--- a/devtools/client/inspector/markup/test/browser_markup_dragdrop_distance.js
+++ b/devtools/client/inspector/markup/test/browser_markup_dragdrop_distance.js
@@ -1,49 +1,49 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that nodes don't start dragging before the mouse has moved by at least
-// the minimum vertical distance defined in markup-view.js by
-// DRAG_DROP_MIN_INITIAL_DISTANCE.
-
-const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
-const TEST_NODE = "#test";
-
-// Keep this in sync with DRAG_DROP_MIN_INITIAL_DISTANCE in markup-view.js
-const MIN_DISTANCE = 10;
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
-
-  info("Drag the test node by half of the minimum distance");
-  yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE / 2);
-  yield checkIsDragging(inspector, TEST_NODE, false);
-
-  info("Drag the test node by exactly the minimum distance");
-  yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE);
-  yield checkIsDragging(inspector, TEST_NODE, true);
-  inspector.markup.cancelDragging();
-
-  info("Drag the test node by more than the minimum distance");
-  yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE * 2);
-  yield checkIsDragging(inspector, TEST_NODE, true);
-  inspector.markup.cancelDragging();
-
-  info("Drag the test node by minus the minimum distance");
-  yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE * -1);
-  yield checkIsDragging(inspector, TEST_NODE, true);
-  inspector.markup.cancelDragging();
-});
-
-function* checkIsDragging(inspector, selector, isDragging) {
-  let container = yield getContainerForSelector(selector, inspector);
-  if (isDragging) {
-    ok(container.isDragging, "The container is being dragged");
-    ok(inspector.markup.isDragging, "And the markup-view knows it");
-  } else {
-    ok(!container.isDragging, "The container hasn't been marked as dragging");
-    ok(!inspector.markup.isDragging, "And the markup-view either");
-  }
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that nodes don't start dragging before the mouse has moved by at least
+// the minimum vertical distance defined in markup-view.js by
+// DRAG_DROP_MIN_INITIAL_DISTANCE.
+
+const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
+const TEST_NODE = "#test";
+
+// Keep this in sync with DRAG_DROP_MIN_INITIAL_DISTANCE in markup-view.js
+const MIN_DISTANCE = 10;
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URL);
+
+  info("Drag the test node by half of the minimum distance");
+  yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE / 2);
+  yield checkIsDragging(inspector, TEST_NODE, false);
+
+  info("Drag the test node by exactly the minimum distance");
+  yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE);
+  yield checkIsDragging(inspector, TEST_NODE, true);
+  inspector.markup.cancelDragging();
+
+  info("Drag the test node by more than the minimum distance");
+  yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE * 2);
+  yield checkIsDragging(inspector, TEST_NODE, true);
+  inspector.markup.cancelDragging();
+
+  info("Drag the test node by minus the minimum distance");
+  yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE * -1);
+  yield checkIsDragging(inspector, TEST_NODE, true);
+  inspector.markup.cancelDragging();
+});
+
+function* checkIsDragging(inspector, selector, isDragging) {
+  let container = yield getContainerForSelector(selector, inspector);
+  if (isDragging) {
+    ok(container.isDragging, "The container is being dragged");
+    ok(inspector.markup.isDragging, "And the markup-view knows it");
+  } else {
+    ok(!container.isDragging, "The container hasn't been marked as dragging");
+    ok(!inspector.markup.isDragging, "And the markup-view either");
+  }
+}
--- a/devtools/client/inspector/markup/test/browser_markup_dragdrop_draggable.js
+++ b/devtools/client/inspector/markup/test/browser_markup_dragdrop_draggable.js
@@ -1,63 +1,63 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test which nodes are consider draggable by the markup-view.
-
-const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
-
-// Test cases should be objects with the following properties:
-// - node {String|Function} A CSS selector that uniquely identifies the node to
-//   be tested. Or a generator function called in a Task that should return the
-//   corresponding MarkupContainer object to be tested.
-// - draggable {Boolean} Whether or not the node should be draggable.
-const TEST_DATA = [
-  { node: "head", draggable: false },
-  { node: "body", draggable: false },
-  { node: "html", draggable: false },
-  { node: "style", draggable: true },
-  { node: "a", draggable: true },
-  { node: "p", draggable: true },
-  { node: "input", draggable: true },
-  { node: "div", draggable: true },
-  {
-    node: function* (inspector) {
-      let parentFront = yield getNodeFront("#before", inspector);
-      let {nodes} = yield inspector.walker.children(parentFront);
-      // Getting the comment node.
-      return getContainerForNodeFront(nodes[1], inspector);
-    },
-    draggable: true
-  },
-  {
-    node: function* (inspector) {
-      let parentFront = yield getNodeFront("#test", inspector);
-      let {nodes} = yield inspector.walker.children(parentFront);
-      // Getting the ::before pseudo element.
-      return getContainerForNodeFront(nodes[0], inspector);
-    },
-    draggable: false
-  }
-];
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
-  yield inspector.markup.expandAll();
-
-  for (let {node, draggable} of TEST_DATA) {
-    let container;
-    let name;
-    if (typeof node === "string") {
-      container = yield getContainerForSelector(node, inspector);
-      name = node;
-    } else {
-      container = yield node(inspector);
-      name = container.toString();
-    }
-
-    let status = draggable ? "draggable" : "not draggable";
-    info(`Testing ${name}, expecting it to be ${status}`);
-    is(container.isDraggable(), draggable, `The node is ${status}`);
-  }
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+// Test which nodes are consider draggable by the markup-view.
+
+const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
+
+// Test cases should be objects with the following properties:
+// - node {String|Function} A CSS selector that uniquely identifies the node to
+//   be tested. Or a generator function called in a Task that should return the
+//   corresponding MarkupContainer object to be tested.
+// - draggable {Boolean} Whether or not the node should be draggable.
+const TEST_DATA = [
+  { node: "head", draggable: false },
+  { node: "body", draggable: false },
+  { node: "html", draggable: false },
+  { node: "style", draggable: true },
+  { node: "a", draggable: true },
+  { node: "p", draggable: true },
+  { node: "input", draggable: true },
+  { node: "div", draggable: true },
+  {
+    node: function* (inspector) {
+      let parentFront = yield getNodeFront("#before", inspector);
+      let {nodes} = yield inspector.walker.children(parentFront);
+      // Getting the comment node.
+      return getContainerForNodeFront(nodes[1], inspector);
+    },
+    draggable: true
+  },
+  {
+    node: function* (inspector) {
+      let parentFront = yield getNodeFront("#test", inspector);
+      let {nodes} = yield inspector.walker.children(parentFront);
+      // Getting the ::before pseudo element.
+      return getContainerForNodeFront(nodes[0], inspector);
+    },
+    draggable: false
+  }
+];
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URL);
+  yield inspector.markup.expandAll();
+
+  for (let {node, draggable} of TEST_DATA) {
+    let container;
+    let name;
+    if (typeof node === "string") {
+      container = yield getContainerForSelector(node, inspector);
+      name = node;
+    } else {
+      container = yield node(inspector);
+      name = container.toString();
+    }
+
+    let status = draggable ? "draggable" : "not draggable";
+    info(`Testing ${name}, expecting it to be ${status}`);
+    is(container.isDraggable(), draggable, `The node is ${status}`);
+  }
+});
--- a/devtools/client/inspector/markup/test/browser_markup_keybindings_delete_attributes.js
+++ b/devtools/client/inspector/markup/test/browser_markup_keybindings_delete_attributes.js
@@ -1,63 +1,63 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests that attributes can be deleted from the markup-view with the delete key
-// when they are focused.
-
-const HTML = '<div id="id" class="class" data-id="id"></div>';
-const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
-
-// List of all the test cases. Each item is an object with the following props:
-// - selector: the css selector of the node that should be selected
-// - attribute: the name of the attribute that should be focused. Do not
-//   specify an attribute that would make it impossible to find the node using
-//   selector.
-// Note that after each test case, undo is called.
-const TEST_DATA = [{
-  selector: "#id",
-  attribute: "class"
-}, {
-  selector: "#id",
-  attribute: "data-id"
-}];
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
-  let {walker} = inspector;
-
-  for (let {selector, attribute} of TEST_DATA) {
-    info("Get the container for node " + selector);
-    let {editor} = yield getContainerForSelector(selector, inspector);
-
-    info("Focus attribute " + attribute);
-    let attr = editor.attrElements.get(attribute).querySelector(".editable");
-    attr.focus();
-
-    info("Delete the attribute by pressing delete");
-    let mutated = inspector.once("markupmutation");
-    EventUtils.sendKey("delete", inspector.panelWin);
-    yield mutated;
-
-    info("Check that the node is still here");
-    let node = yield walker.querySelector(walker.rootNode, selector);
-    ok(node, "The node hasn't been deleted");
-
-    info("Check that the attribute has been deleted");
-    node = yield walker.querySelector(walker.rootNode,
-                                      selector + "[" + attribute + "]");
-    ok(!node, "The attribute does not exist anymore in the DOM");
-    ok(!editor.attrElements.get(attribute),
-       "The attribute has been removed from the container");
-
-    info("Undo the change");
-    yield undoChange(inspector);
-    node = yield walker.querySelector(walker.rootNode,
-                                      selector + "[" + attribute + "]");
-    ok(node, "The attribute is back in the DOM");
-    ok(editor.attrElements.get(attribute),
-       "The attribute is back on the container");
-  }
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests that attributes can be deleted from the markup-view with the delete key
+// when they are focused.
+
+const HTML = '<div id="id" class="class" data-id="id"></div>';
+const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
+
+// List of all the test cases. Each item is an object with the following props:
+// - selector: the css selector of the node that should be selected
+// - attribute: the name of the attribute that should be focused. Do not
+//   specify an attribute that would make it impossible to find the node using
+//   selector.
+// Note that after each test case, undo is called.
+const TEST_DATA = [{
+  selector: "#id",
+  attribute: "class"
+}, {
+  selector: "#id",
+  attribute: "data-id"
+}];
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URL);
+  let {walker} = inspector;
+
+  for (let {selector, attribute} of TEST_DATA) {
+    info("Get the container for node " + selector);
+    let {editor} = yield getContainerForSelector(selector, inspector);
+
+    info("Focus attribute " + attribute);
+    let attr = editor.attrElements.get(attribute).querySelector(".editable");
+    attr.focus();
+
+    info("Delete the attribute by pressing delete");
+    let mutated = inspector.once("markupmutation");
+    EventUtils.sendKey("delete", inspector.panelWin);
+    yield mutated;
+
+    info("Check that the node is still here");
+    let node = yield walker.querySelector(walker.rootNode, selector);
+    ok(node, "The node hasn't been deleted");
+
+    info("Check that the attribute has been deleted");
+    node = yield walker.querySelector(walker.rootNode,
+                                      selector + "[" + attribute + "]");
+    ok(!node, "The attribute does not exist anymore in the DOM");
+    ok(!editor.attrElements.get(attribute),
+       "The attribute has been removed from the container");
+
+    info("Undo the change");
+    yield undoChange(inspector);
+    node = yield walker.querySelector(walker.rootNode,
+                                      selector + "[" + attribute + "]");
+    ok(node, "The attribute is back in the DOM");
+    ok(editor.attrElements.get(attribute),
+       "The attribute is back on the container");
+  }
+});
--- a/devtools/client/inspector/markup/test/browser_markup_keybindings_scrolltonode.js
+++ b/devtools/client/inspector/markup/test/browser_markup_keybindings_scrolltonode.js
@@ -1,87 +1,87 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test the keyboard shortcut "S" used to scroll to the selected node.
-
-const HTML =
-  `<div style="width: 300px; height: 3000px; position:relative;">
-    <div id="scroll-top"
-      style="height: 50px; top: 0; position:absolute;">
-      TOP</div>
-    <div id="scroll-bottom"
-      style="height: 50px; bottom: 0; position:absolute;">
-      BOTTOM</div>
-  </div>`;
-const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
-
-add_task(function* () {
-  let { inspector, testActor } = yield openInspectorForURL(TEST_URL);
-
-  info("Make sure the markup frame has the focus");
-  inspector.markup._frame.focus();
-
-  info("Before test starts, #scroll-top is visible, #scroll-bottom is hidden");
-  yield checkElementIsInViewport("#scroll-top", true, testActor);
-  yield checkElementIsInViewport("#scroll-bottom", false, testActor);
-
-  info("Select the #scroll-bottom node");
-  yield selectNode("#scroll-bottom", inspector);
-  info("Press S to scroll to the bottom node");
-  let waitForScroll = testActor.waitForEventOnNode("scroll");
-  yield EventUtils.synthesizeKey("S", {}, inspector.panelWin);
-  yield waitForScroll;
-  ok(true, "Scroll event received");
-
-  info("#scroll-top should be scrolled out, #scroll-bottom should be visible");
-  yield checkElementIsInViewport("#scroll-top", false, testActor);
-  yield checkElementIsInViewport("#scroll-bottom", true, testActor);
-
-  info("Select the #scroll-top node");
-  yield selectNode("#scroll-top", inspector);
-  info("Press S to scroll to the top node");
-  waitForScroll = testActor.waitForEventOnNode("scroll");
-  yield EventUtils.synthesizeKey("S", {}, inspector.panelWin);
-  yield waitForScroll;
-  ok(true, "Scroll event received");
-
-  info("#scroll-top should be visible, #scroll-bottom should be scrolled out");
-  yield checkElementIsInViewport("#scroll-top", true, testActor);
-  yield checkElementIsInViewport("#scroll-bottom", false, testActor);
-
-  info("Select #scroll-bottom node");
-  yield selectNode("#scroll-bottom", inspector);
-  info("Press shift + S, nothing should happen due to the modifier");
-  yield EventUtils.synthesizeKey("S", {shiftKey: true}, inspector.panelWin);
-
-  info("Same state, #scroll-top is visible, #scroll-bottom is scrolled out");
-  yield checkElementIsInViewport("#scroll-top", true, testActor);
-  yield checkElementIsInViewport("#scroll-bottom", false, testActor);
-});
-
-/**
- * Verify that the element matching the provided selector is either in or out
- * of the viewport, depending on the provided "expected" argument.
- * Returns a promise that will resolve when the test has been performed.
- *
- * @param {String} selector
- *        css selector for the element to test
- * @param {Boolean} expected
- *        true if the element is expected to be in the viewport, false otherwise
- * @param {TestActor} testActor
- *        current test actor
- * @return {Promise} promise
- */
-function* checkElementIsInViewport(selector, expected, testActor) {
-  let isInViewport = yield testActor.eval(`
-    let node = content.document.querySelector("${selector}");
-    let rect = node.getBoundingClientRect();
-    rect.bottom >= 0 && rect.right >= 0 &&
-      rect.top <= content.innerHeight && rect.left <= content.innerWidth;
-  `);
-
-  is(isInViewport, expected,
-    selector + " in the viewport: expected to be " + expected);
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test the keyboard shortcut "S" used to scroll to the selected node.
+
+const HTML =
+  `<div style="width: 300px; height: 3000px; position:relative;">
+    <div id="scroll-top"
+      style="height: 50px; top: 0; position:absolute;">
+      TOP</div>
+    <div id="scroll-bottom"
+      style="height: 50px; bottom: 0; position:absolute;">
+      BOTTOM</div>
+  </div>`;
+const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
+
+add_task(function* () {
+  let { inspector, testActor } = yield openInspectorForURL(TEST_URL);
+
+  info("Make sure the markup frame has the focus");
+  inspector.markup._frame.focus();
+
+  info("Before test starts, #scroll-top is visible, #scroll-bottom is hidden");
+  yield checkElementIsInViewport("#scroll-top", true, testActor);
+  yield checkElementIsInViewport("#scroll-bottom", false, testActor);
+
+  info("Select the #scroll-bottom node");
+  yield selectNode("#scroll-bottom", inspector);
+  info("Press S to scroll to the bottom node");
+  let waitForScroll = testActor.waitForEventOnNode("scroll");
+  yield EventUtils.synthesizeKey("S", {}, inspector.panelWin);
+  yield waitForScroll;
+  ok(true, "Scroll event received");
+
+  info("#scroll-top should be scrolled out, #scroll-bottom should be visible");
+  yield checkElementIsInViewport("#scroll-top", false, testActor);
+  yield checkElementIsInViewport("#scroll-bottom", true, testActor);
+
+  info("Select the #scroll-top node");
+  yield selectNode("#scroll-top", inspector);
+  info("Press S to scroll to the top node");
+  waitForScroll = testActor.waitForEventOnNode("scroll");
+  yield EventUtils.synthesizeKey("S", {}, inspector.panelWin);
+  yield waitForScroll;
+  ok(true, "Scroll event received");
+
+  info("#scroll-top should be visible, #scroll-bottom should be scrolled out");
+  yield checkElementIsInViewport("#scroll-top", true, testActor);
+  yield checkElementIsInViewport("#scroll-bottom", false, testActor);
+
+  info("Select #scroll-bottom node");
+  yield selectNode("#scroll-bottom", inspector);
+  info("Press shift + S, nothing should happen due to the modifier");
+  yield EventUtils.synthesizeKey("S", {shiftKey: true}, inspector.panelWin);
+
+  info("Same state, #scroll-top is visible, #scroll-bottom is scrolled out");
+  yield checkElementIsInViewport("#scroll-top", true, testActor);
+  yield checkElementIsInViewport("#scroll-bottom", false, testActor);
+});
+
+/**
+ * Verify that the element matching the provided selector is either in or out
+ * of the viewport, depending on the provided "expected" argument.
+ * Returns a promise that will resolve when the test has been performed.
+ *
+ * @param {String} selector
+ *        css selector for the element to test
+ * @param {Boolean} expected
+ *        true if the element is expected to be in the viewport, false otherwise
+ * @param {TestActor} testActor
+ *        current test actor
+ * @return {Promise} promise
+ */
+function* checkElementIsInViewport(selector, expected, testActor) {
+  let isInViewport = yield testActor.eval(`
+    let node = content.document.querySelector("${selector}");
+    let rect = node.getBoundingClientRect();
+    rect.bottom >= 0 && rect.right >= 0 &&
+      rect.top <= content.innerHeight && rect.left <= content.innerWidth;
+  `);
+
+  is(isInViewport, expected,
+    selector + " in the viewport: expected to be " + expected);
+}
--- a/devtools/client/inspector/markup/test/browser_markup_whitespace.js
+++ b/devtools/client/inspector/markup/test/browser_markup_whitespace.js
@@ -1,66 +1,66 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that whitespace text nodes do show up in the markup-view when needed.
-
-const TEST_URL = URL_ROOT + "doc_markup_whitespace.html";
-
-add_task(function* () {
-  let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
-  let {markup} = inspector;
-
-  yield markup.expandAll();
-
-  info("Verify the number of child nodes and child elements in body");
-
-  // Body has 5 element children, but there are 6 text nodes in there too, they come from
-  // the HTML file formatting (spaces and carriage returns).
-  let {numNodes, numChildren} = yield testActor.getNodeInfo("body");
-  is(numNodes, 11, "The body node has 11 child nodes (includes text nodes)");
-  is(numChildren, 5, "The body node has 5 child elements (only element nodes)");
-
-  // In body, there are only block-level elements, so whitespace text nodes do not have
-  // layout, so they should be skipped in the markup-view.
-  info("Check that the body's whitespace text node children aren't shown");
-  let bodyContainer = markup.getContainer(inspector.selection.nodeFront);
-  let childContainers = bodyContainer.getChildContainers();
-  is(childContainers.length, 5,
-     "Only the element nodes are shown in the markup view");
-
-  // div#inline has 3 element children, but there are 4 text nodes in there too, like in
-  // body, they come from spaces and carriage returns in the HTML file.
-  info("Verify the number of child nodes and child elements in div#inline");
-  ({numNodes, numChildren} = yield testActor.getNodeInfo("#inline"));
-  is(numNodes, 7, "The div#inline node has 7 child nodes (includes text nodes)");
-  is(numChildren, 3, "The div#inline node has 3 child elements (only element nodes)");
-
-  // Within the inline formatting context in div#inline, the whitespace text nodes between
-  // the images have layout, so they should appear in the markup-view.
-  info("Check that the div#inline's whitespace text node children are shown");
-  yield selectNode("#inline", inspector);
-  let divContainer = markup.getContainer(inspector.selection.nodeFront);
-  childContainers = divContainer.getChildContainers();
-  is(childContainers.length, 5,
-     "Both the element nodes and some text nodes are shown in the markup view");
-
-  // div#pre has 2 element children, but there are 3 text nodes in there too, like in
-  // div#inline, they come from spaces and carriage returns in the HTML file.
-  info("Verify the number of child nodes and child elements in div#pre");
-  ({numNodes, numChildren} = yield testActor.getNodeInfo("#pre"));
-  is(numNodes, 5, "The div#pre node has 5 child nodes (includes text nodes)");
-  is(numChildren, 2, "The div#pre node has 2 child elements (only element nodes)");
-
-  // Within the inline formatting context in div#pre, the whitespace text nodes between
-  // the images have layout, so they should appear in the markup-view, but since
-  // white-space is set to pre, then the whitespace text nodes before and after the first
-  // and last image should also appear.
-  info("Check that the div#pre's whitespace text node children are shown");
-  yield selectNode("#pre", inspector);
-  divContainer = markup.getContainer(inspector.selection.nodeFront);
-  childContainers = divContainer.getChildContainers();
-  is(childContainers.length, 5,
-     "Both the element nodes and all text nodes are shown in the markup view");
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that whitespace text nodes do show up in the markup-view when needed.
+
+const TEST_URL = URL_ROOT + "doc_markup_whitespace.html";
+
+add_task(function* () {
+  let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
+  let {markup} = inspector;
+
+  yield markup.expandAll();
+
+  info("Verify the number of child nodes and child elements in body");
+
+  // Body has 5 element children, but there are 6 text nodes in there too, they come from
+  // the HTML file formatting (spaces and carriage returns).
+  let {numNodes, numChildren} = yield testActor.getNodeInfo("body");
+  is(numNodes, 11, "The body node has 11 child nodes (includes text nodes)");
+  is(numChildren, 5, "The body node has 5 child elements (only element nodes)");
+
+  // In body, there are only block-level elements, so whitespace text nodes do not have
+  // layout, so they should be skipped in the markup-view.
+  info("Check that the body's whitespace text node children aren't shown");
+  let bodyContainer = markup.getContainer(inspector.selection.nodeFront);
+  let childContainers = bodyContainer.getChildContainers();
+  is(childContainers.length, 5,
+     "Only the element nodes are shown in the markup view");
+
+  // div#inline has 3 element children, but there are 4 text nodes in there too, like in
+  // body, they come from spaces and carriage returns in the HTML file.
+  info("Verify the number of child nodes and child elements in div#inline");
+  ({numNodes, numChildren} = yield testActor.getNodeInfo("#inline"));
+  is(numNodes, 7, "The div#inline node has 7 child nodes (includes text nodes)");
+  is(numChildren, 3, "The div#inline node has 3 child elements (only element nodes)");
+
+  // Within the inline formatting context in div#inline, the whitespace text nodes between
+  // the images have layout, so they should appear in the markup-view.
+  info("Check that the div#inline's whitespace text node children are shown");
+  yield selectNode("#inline", inspector);
+  let divContainer = markup.getContainer(inspector.selection.nodeFront);
+  childContainers = divContainer.getChildContainers();
+  is(childContainers.length, 5,
+     "Both the element nodes and some text nodes are shown in the markup view");
+
+  // div#pre has 2 element children, but there are 3 text nodes in there too, like in
+  // div#inline, they come from spaces and carriage returns in the HTML file.
+  info("Verify the number of child nodes and child elements in div#pre");
+  ({numNodes, numChildren} = yield testActor.getNodeInfo("#pre"));
+  is(numNodes, 5, "The div#pre node has 5 child nodes (includes text nodes)");
+  is(numChildren, 2, "The div#pre node has 2 child elements (only element nodes)");
+
+  // Within the inline formatting context in div#pre, the whitespace text nodes between
+  // the images have layout, so they should appear in the markup-view, but since
+  // white-space is set to pre, then the whitespace text nodes before and after the first
+  // and last image should also appear.
+  info("Check that the div#pre's whitespace text node children are shown");
+  yield selectNode("#pre", inspector);
+  divContainer = markup.getContainer(inspector.selection.nodeFront);
+  childContainers = divContainer.getChildContainers();
+  is(childContainers.length, 5,
+     "Both the element nodes and all text nodes are shown in the markup view");
+});
--- a/devtools/client/inspector/markup/test/doc_markup_image_and_canvas.html
+++ b/devtools/client/inspector/markup/test/doc_markup_image_and_canvas.html
@@ -1,24 +1,24 @@
-<!DOCTYPE html>
-<html class="html">
-  <head class="head">
-    <meta charset=utf-8 />
-    <title>Image and Canvas markup-view test</title>
-  </head>
-  <body>
-    <div></div>
-    <img src="data:image/png;base64,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" />
-    <canvas class="canvas" width="600" height="600"></canvas>
-    <script type="text/javascript">
-      "use strict";
-
-      let context = document.querySelector(".canvas").getContext("2d");
-      context.beginPath();
-      context.moveTo(300, 0);
-      context.lineTo(600, 600);
-      context.lineTo(0, 600);
-      context.closePath();
-      context.fillStyle = "#ffc821";
-      context.fill();
-    </script>
-  </body>
-</html>
+<!DOCTYPE html>
+<html class="html">
+  <head class="head">
+    <meta charset=utf-8 />
+    <title>Image and Canvas markup-view test</title>
+  </head>
+  <body>
+    <div></div>
+    <img src="data:image/png;base64,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" />
+    <canvas class="canvas" width="600" height="600"></canvas>
+    <script type="text/javascript">
+      "use strict";
+
+      let context = document.querySelector(".canvas").getContext("2d");
+      context.beginPath();
+      context.moveTo(300, 0);
+      context.lineTo(600, 600);
+      context.lineTo(0, 600);
+      context.closePath();
+      context.fillStyle = "#ffc821";
+      context.fill();
+    </script>
+  </body>
+</html>
--- a/devtools/client/inspector/markup/test/doc_markup_image_and_canvas_2.html
+++ b/devtools/client/inspector/markup/test/doc_markup_image_and_canvas_2.html
@@ -1,25 +1,25 @@
-<!DOCTYPE html>
-<html class="html">
-  <head class="head">
-    <meta charset=utf-8 />
-    <title>Image and Canvas markup-view test</title>
-  </head>
-  <body>
-    <img class="local" src="chrome://branding/content/about-logo.png" />
-    <img class="data" src="data:image/png;base64,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" />
-    <img class="remote" src="http://example.com/browser/devtools/client/inspector/markup/test/doc_markup_tooltip.png" />
-    <canvas class="canvas" width="600" height="600"></canvas>
-    <script type="text/javascript">
-      "use strict";
-
-      let context = document.querySelector(".canvas").getContext("2d");
-      context.beginPath();
-      context.moveTo(300, 0);
-      context.lineTo(600, 600);
-      context.lineTo(0, 600);
-      context.closePath();
-      context.fillStyle = "#ffc821";
-      context.fill();
-    </script>
-  </body>
-</html>
+<!DOCTYPE html>
+<html class="html">
+  <head class="head">
+    <meta charset=utf-8 />
+    <title>Image and Canvas markup-view test</title>
+  </head>
+  <body>
+    <img class="local" src="chrome://branding/content/about-logo.png" />
+    <img class="data" src="data:image/png;base64,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" />
+    <img class="remote" src="http://example.com/browser/devtools/client/inspector/markup/test/doc_markup_tooltip.png" />
+    <canvas class="canvas" width="600" height="600"></canvas>
+    <script type="text/javascript">
+      "use strict";
+
+      let context = document.querySelector(".canvas").getContext("2d");
+      context.beginPath();
+      context.moveTo(300, 0);
+      context.lineTo(600, 600);
+      context.lineTo(0, 600);
+      context.closePath();
+      context.fillStyle = "#ffc821";
+      context.fill();
+    </script>
+  </body>
+</html>
--- a/devtools/client/inspector/rules/test/browser_rules_add-rule-and-property.js
+++ b/devtools/client/inspector/rules/test/browser_rules_add-rule-and-property.js
@@ -1,30 +1,30 @@
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests adding a new rule and a new property in this rule.
-
-add_task(function* () {
-  yield addTab("data:text/html;charset=utf-8,<div id='testid'>Styled Node</div>");
-  let {inspector, view} = yield openRuleView();
-
-  info("Selecting the test node");
-  yield selectNode("#testid", inspector);
-
-  info("Adding a new rule for this node and blurring the new selector field");
-  yield addNewRuleAndDismissEditor(inspector, view, "#testid", 1);
-
-  info("Adding a new property for this rule");
-  let ruleEditor = getRuleViewRuleEditor(view, 1);
-
-  let onRuleViewChanged = view.once("ruleview-changed");
-  ruleEditor.addProperty("font-weight", "bold", "", true);
-  yield onRuleViewChanged;
-
-  let textProps = ruleEditor.rule.textProps;
-  let prop = textProps[textProps.length - 1];
-  is(prop.name, "font-weight", "The last property name is font-weight");
-  is(prop.value, "bold", "The last property value is bold");
-});
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests adding a new rule and a new property in this rule.
+
+add_task(function* () {
+  yield addTab("data:text/html;charset=utf-8,<div id='testid'>Styled Node</div>");
+  let {inspector, view} = yield openRuleView();
+
+  info("Selecting the test node");
+  yield selectNode("#testid", inspector);
+
+  info("Adding a new rule for this node and blurring the new selector field");
+  yield addNewRuleAndDismissEditor(inspector, view, "#testid", 1);
+
+  info("Adding a new property for this rule");
+  let ruleEditor = getRuleViewRuleEditor(view, 1);
+
+  let onRuleViewChanged = view.once("ruleview-changed");
+  ruleEditor.addProperty("font-weight", "bold", "", true);
+  yield onRuleViewChanged;
+
+  let textProps = ruleEditor.rule.textProps;
+  let prop = textProps[textProps.length - 1];
+  is(prop.name, "font-weight", "The last property name is font-weight");
+  is(prop.value, "bold", "The last property value is bold");
+});
--- a/devtools/client/inspector/rules/test/browser_rules_add-rule-with-menu.js
+++ b/devtools/client/inspector/rules/test/browser_rules_add-rule-with-menu.js
@@ -1,42 +1,42 @@
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests the a new CSS rule can be added using the context menu.
-
-const TEST_URI = '<div id="testid">Test Node</div>';
-
-add_task(function* () {
-  yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
-  let {inspector, view} = yield openRuleView();
-
-  yield selectNode("#testid", inspector);
-  yield addNewRuleFromContextMenu(inspector, view);
-  yield testNewRule(view);
-});
-
-function* addNewRuleFromContextMenu(inspector, view) {
-  info("Waiting for context menu to be shown");
-
-  let allMenuItems = openStyleContextMenuAndGetAllItems(view, view.element);
-  let menuitemAddRule = allMenuItems.find(item => item.label ===
-    STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.addNewRule"));
-
-  ok(menuitemAddRule.visible, "Add rule is visible");
-
-  info("Adding the new rule and expecting a ruleview-changed event");
-  let onRuleViewChanged = view.once("ruleview-changed");
-  menuitemAddRule.click();
-  yield onRuleViewChanged;
-}
-
-function* testNewRule(view) {
-  let ruleEditor = getRuleViewRuleEditor(view, 1);
-  let editor = ruleEditor.selectorText.ownerDocument.activeElement;
-  is(editor.value, "#testid", "Selector editor value is as expected");
-
-  info("Escaping from the selector field the change");
-  EventUtils.synthesizeKey("VK_ESCAPE", {});
-}
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests the a new CSS rule can be added using the context menu.
+
+const TEST_URI = '<div id="testid">Test Node</div>';
+
+add_task(function* () {
+  yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
+  let {inspector, view} = yield openRuleView();
+
+  yield selectNode("#testid", inspector);
+  yield addNewRuleFromContextMenu(inspector, view);
+  yield testNewRule(view);
+});
+
+function* addNewRuleFromContextMenu(inspector, view) {
+  info("Waiting for context menu to be shown");
+
+  let allMenuItems = openStyleContextMenuAndGetAllItems(view, view.element);
+  let menuitemAddRule = allMenuItems.find(item => item.label ===
+    STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.addNewRule"));
+
+  ok(menuitemAddRule.visible, "Add rule is visible");
+
+  info("Adding the new rule and expecting a ruleview-changed event");
+  let onRuleViewChanged = view.once("ruleview-changed");
+  menuitemAddRule.click();
+  yield onRuleViewChanged;
+}
+
+function* testNewRule(view) {
+  let ruleEditor = getRuleViewRuleEditor(view, 1);
+  let editor = ruleEditor.selectorText.ownerDocument.activeElement;
+  is(editor.value, "#testid", "Selector editor value is as expected");
+
+  info("Escaping from the selector field the change");
+  EventUtils.synthesizeKey("VK_ESCAPE", {});
+}
--- a/devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js
+++ b/devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js
@@ -1,277 +1,277 @@
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that increasing/decreasing values in rule view using
-// arrow keys works correctly.
-
-const TEST_URI = `
-  <style>
-    #test {
-      margin-top: 0px;
-      padding-top: 0px;
-      color: #000000;
-      background-color: #000000;
-      background: none;
-      transition: initial;
-      z-index: 0;
-    }
-  </style>
-  <div id="test"></div>
-`;
-
-add_task(function* () {
-  yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
-
-  let {inspector, view} = yield openRuleView();
-  yield selectNode("#test", inspector);
-
-  yield testMarginIncrements(view);
-  yield testVariousUnitIncrements(view);
-  yield testHexIncrements(view);
-  yield testAlphaHexIncrements(view);
-  yield testRgbIncrements(view);
-  yield testShorthandIncrements(view);
-  yield testOddCases(view);
-  yield testZeroValueIncrements(view);
-});
-
-function* testMarginIncrements(view) {
-  info("Testing keyboard increments on the margin property");
-
-  let idRuleEditor = getRuleViewRuleEditor(view, 1);
-  let marginPropEditor = idRuleEditor.rule.textProps[0].editor;
-
-  yield runIncrementTest(marginPropEditor, view, {
-    1: {alt: true, start: "0px", end: "0.1px", selectAll: true},
-    2: {start: "0px", end: "1px", selectAll: true},
-    3: {shift: true, start: "0px", end: "10px", selectAll: true},
-    4: {down: true, alt: true, start: "0.1px", end: "0px", selectAll: true},
-    5: {down: true, start: "0px", end: "-1px", selectAll: true},
-    6: {down: true, shift: true, start: "0px", end: "-10px", selectAll: true},
-    7: {pageUp: true, shift: true, start: "0px", end: "100px", selectAll: true},
-    8: {pageDown: true, shift: true, start: "0px", end: "-100px",
-        selectAll: true},
-    9: {start: "0", end: "1px", selectAll: true},
-    10: {down: true, start: "0", end: "-1px", selectAll: true},
-  });
-}
-
-function* testVariousUnitIncrements(view) {
-  info("Testing keyboard increments on values with various units");
-
-  let idRuleEditor = getRuleViewRuleEditor(view, 1);
-  let paddingPropEditor = idRuleEditor.rule.textProps[1].editor;
-
-  yield runIncrementTest(paddingPropEditor, view, {
-    1: {start: "0px", end: "1px", selectAll: true},
-    2: {start: "0pt", end: "1pt", selectAll: true},
-    3: {start: "0pc", end: "1pc", selectAll: true},
-    4: {start: "0em", end: "1em", selectAll: true},
-    5: {start: "0%", end: "1%", selectAll: true},
-    6: {start: "0in", end: "1in", selectAll: true},
-    7: {start: "0cm", end: "1cm", selectAll: true},
-    8: {start: "0mm", end: "1mm", selectAll: true},
-    9: {start: "0ex", end: "1ex", selectAll: true},
-    10: {start: "0", end: "1px", selectAll: true},
-    11: {down: true, start: "0", end: "-1px", selectAll: true},
-  });
-}
-
-function* testHexIncrements(view) {
-  info("Testing keyboard increments with hex colors");
-
-  let idRuleEditor = getRuleViewRuleEditor(view, 1);
-  let hexColorPropEditor = idRuleEditor.rule.textProps[2].editor;
-
-  yield runIncrementTest(hexColorPropEditor, view, {
-    1: {start: "#CCCCCC", end: "#CDCDCD", selectAll: true},
-    2: {shift: true, start: "#CCCCCC", end: "#DCDCDC", selectAll: true},
-    3: {start: "#CCCCCC", end: "#CDCCCC", selection: [1, 3]},
-    4: {shift: true, start: "#CCCCCC", end: "#DCCCCC", selection: [1, 3]},
-    5: {start: "#FFFFFF", end: "#FFFFFF", selectAll: true},
-    6: {down: true, shift: true, start: "#000000", end: "#000000",
-        selectAll: true}
-  });
-}
-
-function* testAlphaHexIncrements(view) {
-  info("Testing keyboard increments with alpha hex colors");
-
-  let idRuleEditor = getRuleViewRuleEditor(view, 1);
-  let hexColorPropEditor = idRuleEditor.rule.textProps[2].editor;
-
-  yield runIncrementTest(hexColorPropEditor, view, {
-    1: {start: "#CCCCCCAA", end: "#CDCDCDAB", selectAll: true},
-    2: {shift: true, start: "#CCCCCCAA", end: "#DCDCDCBA", selectAll: true},
-    3: {start: "#CCCCCCAA", end: "#CDCCCCAA", selection: [1, 3]},
-    4: {shift: true, start: "#CCCCCCAA", end: "#DCCCCCAA", selection: [1, 3]},
-    5: {start: "#FFFFFFFF", end: "#FFFFFFFF", selectAll: true},
-    6: {down: true, shift: true, start: "#00000000", end: "#00000000",
-        selectAll: true}
-  });
-}
-
-function* testRgbIncrements(view) {
-  info("Testing keyboard increments with rgb colors");
-
-  let idRuleEditor = getRuleViewRuleEditor(view, 1);
-  let rgbColorPropEditor = idRuleEditor.rule.textProps[3].editor;
-
-  yield runIncrementTest(rgbColorPropEditor, view, {
-    1: {start: "rgb(0,0,0)", end: "rgb(0,1,0)", selection: [6, 7]},
-    2: {shift: true, start: "rgb(0,0,0)", end: "rgb(0,10,0)",
-        selection: [6, 7]},
-    3: {start: "rgb(0,255,0)", end: "rgb(0,255,0)", selection: [6, 9]},
-    4: {shift: true, start: "rgb(0,250,0)", end: "rgb(0,255,0)",
-        selection: [6, 9]},
-    5: {down: true, start: "rgb(0,0,0)", end: "rgb(0,0,0)", selection: [6, 7]},
-    6: {down: true, shift: true, start: "rgb(0,5,0)", end: "rgb(0,0,0)",
-        selection: [6, 7]}
-  });
-}
-
-function* testShorthandIncrements(view) {
-  info("Testing keyboard increments within shorthand values");
-
-  let idRuleEditor = getRuleViewRuleEditor(view, 1);
-  let paddingPropEditor = idRuleEditor.rule.textProps[1].editor;
-
-  yield runIncrementTest(paddingPropEditor, view, {
-    1: {start: "0px 0px 0px 0px", end: "0px 1px 0px 0px", selection: [4, 7]},
-    2: {shift: true, start: "0px 0px 0px 0px", end: "0px 10px 0px 0px",
-        selection: [4, 7]},
-    3: {start: "0px 0px 0px 0px", end: "1px 0px 0px 0px", selectAll: true},
-    4: {shift: true, start: "0px 0px 0px 0px", end: "10px 0px 0px 0px",
-        selectAll: true},
-    5: {down: true, start: "0px 0px 0px 0px", end: "0px 0px -1px 0px",
-        selection: [8, 11]},
-    6: {down: true, shift: true, start: "0px 0px 0px 0px",
-        end: "-10px 0px 0px 0px", selectAll: true},
-    7: {up: true, start: "0.1em .1em 0em 0em", end: "0.1em 1.1em 0em 0em",
-        selection: [6, 9]},
-    8: {up: true, alt: true, start: "0.1em .9em 0em 0em",
-        end: "0.1em 1em 0em 0em", selection: [6, 9]},
-    9: {up: true, shift: true, start: "0.2em .2em 0em 0em",
-        end: "0.2em 10.2em 0em 0em", selection: [6, 9]}
-  });
-}
-
-function* testOddCases(view) {
-  info("Testing some more odd cases");
-
-  let idRuleEditor = getRuleViewRuleEditor(view, 1);
-  let marginPropEditor = idRuleEditor.rule.textProps[0].editor;
-
-  yield runIncrementTest(marginPropEditor, view, {
-    1: {start: "98.7%", end: "99.7%", selection: [3, 3]},
-    2: {alt: true, start: "98.7%", end: "98.8%", selection: [3, 3]},
-    3: {start: "0", end: "1px"},
-    4: {down: true, start: "0", end: "-1px"},
-    5: {start: "'a=-1'", end: "'a=0'", selection: [4, 4]},
-    6: {start: "0 -1px", end: "0 0px", selection: [2, 2]},
-    7: {start: "url(-1)", end: "url(-1)", selection: [4, 4]},
-    8: {start: "url('test1.1.png')", end: "url('test1.2.png')",
-        selection: [11, 11]},
-    9: {start: "url('test1.png')", end: "url('test2.png')", selection: [9, 9]},
-    10: {shift: true, start: "url('test1.1.png')", end: "url('test11.1.png')",
-         selection: [9, 9]},
-    11: {down: true, start: "url('test-1.png')", end: "url('test-2.png')",
-         selection: [9, 11]},
-    12: {start: "url('test1.1.png')", end: "url('test1.2.png')",
-         selection: [11, 12]},
-    13: {down: true, alt: true, start: "url('test-0.png')",
-         end: "url('test--0.1.png')", selection: [10, 11]},
-    14: {alt: true, start: "url('test--0.1.png')", end: "url('test-0.png')",
-         selection: [10, 14]}
-  });
-}
-
-function* testZeroValueIncrements(view) {
-  info("Testing a valid unit is added when incrementing from 0");
-
-  let idRuleEditor = getRuleViewRuleEditor(view, 1);
-  let backgroundPropEditor = idRuleEditor.rule.textProps[4].editor;
-  yield runIncrementTest(backgroundPropEditor, view, {
-    1: { start: "url(test-0.png) no-repeat 0 0",
-         end: "url(test-0.png) no-repeat 1px 0", selection: [26, 26] },
-    2: { start: "url(test-0.png) no-repeat 0 0",
-         end: "url(test-0.png) no-repeat 0 1px", selection: [28, 28] },
-    3: { start: "url(test-0.png) no-repeat center/0",
-         end: "url(test-0.png) no-repeat center/1px", selection: [34, 34] },
-    4: { start: "url(test-0.png) no-repeat 0 0",
-         end: "url(test-1.png) no-repeat 0 0", selection: [10, 10] },
-    5: { start: "linear-gradient(0, red 0, blue 0)",
-         end: "linear-gradient(1deg, red 0, blue 0)", selection: [17, 17] },
-    6: { start: "linear-gradient(1deg, red 0, blue 0)",
-         end: "linear-gradient(1deg, red 1px, blue 0)", selection: [27, 27] },
-    7: { start: "linear-gradient(1deg, red 0, blue 0)",
-         end: "linear-gradient(1deg, red 0, blue 1px)", selection: [35, 35] },
-  });
-
-  let transitionPropEditor = idRuleEditor.rule.textProps[5].editor;
-  yield runIncrementTest(transitionPropEditor, view, {
-    1: { start: "all 0 ease-out", end: "all 1s ease-out", selection: [5, 5] },
-    2: { start: "margin 4s, color 0",
-         end: "margin 4s, color 1s", selection: [18, 18] },
-  });
-
-  let zIndexPropEditor = idRuleEditor.rule.textProps[6].editor;
-  yield runIncrementTest(zIndexPropEditor, view, {
-    1: {start: "0", end: "1", selection: [1, 1]},
-  });
-}
-
-function* runIncrementTest(propertyEditor, view, tests) {
-  let editor = yield focusEditableField(view, propertyEditor.valueSpan);
-
-  for (let test in tests) {
-    yield testIncrement(editor, tests[test], view, propertyEditor);
-  }
-
-  // Blur the field to put back the UI in its initial state (and avoid pending
-  // requests when the test ends).
-  let onRuleViewChanged = view.once("ruleview-changed");
-  EventUtils.synthesizeKey("VK_ESCAPE", {}, view.styleWindow);
-  view.throttle.flush();
-  yield onRuleViewChanged;
-}
-
-function* testIncrement(editor, options, view) {
-  editor.input.value = options.start;
-  let input = editor.input;
-
-  if (options.selectAll) {
-    input.select();
-  } else if (options.selection) {
-    input.setSelectionRange(options.selection[0], options.selection[1]);
-  }
-
-  is(input.value, options.start, "Value initialized at " + options.start);
-
-  let onRuleViewChanged = view.once("ruleview-changed");
-  let onKeyUp = once(input, "keyup");
-
-  let key;
-  key = options.down ? "VK_DOWN" : "VK_UP";
-  if (options.pageDown) {
-    key = "VK_PAGE_DOWN";
-  } else if (options.pageUp) {
-    key = "VK_PAGE_UP";
-  }
-
-  EventUtils.synthesizeKey(key, {altKey: options.alt, shiftKey: options.shift},
-    view.styleWindow);
-
-  yield onKeyUp;
-
-  // Only expect a change if the value actually changed!
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that increasing/decreasing values in rule view using
+// arrow keys works correctly.
+
+const TEST_URI = `
+  <style>
+    #test {
+      margin-top: 0px;
+      padding-top: 0px;
+      color: #000000;
+      background-color: #000000;
+      background: none;
+      transition: initial;
+      z-index: 0;
+    }
+  </style>
+  <div id="test"></div>
+`;
+
+add_task(function* () {
+  yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
+
+  let {inspector, view} = yield openRuleView();
+  yield selectNode("#test", inspector);
+
+  yield testMarginIncrements(view);
+  yield testVariousUnitIncrements(view);
+  yield testHexIncrements(view);
+  yield testAlphaHexIncrements(view);
+  yield testRgbIncrements(view);
+  yield testShorthandIncrements(view);
+  yield testOddCases(view);
+  yield testZeroValueIncrements(view);
+});
+
+function* testMarginIncrements(view) {
+  info("Testing keyboard increments on the margin property");
+
+  let idRuleEditor = getRuleViewRuleEditor(view, 1);
+  let marginPropEditor = idRuleEditor.rule.textProps[0].editor;
+
+  yield runIncrementTest(marginPropEditor, view, {
+    1: {alt: true, start: "0px", end: "0.1px", selectAll: true},
+    2: {start: "0px", end: "1px", selectAll: true},
+    3: {shift: true, start: "0px", end: "10px", selectAll: true},
+    4: {down: true, alt: true, start: "0.1px", end: "0px", selectAll: true},
+    5: {down: true, start: "0px", end: "-1px", selectAll: true},
+    6: {down: true, shift: true, start: "0px", end: "-10px", selectAll: true},
+    7: {pageUp: true, shift: true, start: "0px", end: "100px", selectAll: true},
+    8: {pageDown: true, shift: true, start: "0px", end: "-100px",
+        selectAll: true},
+    9: {start: "0", end: "1px", selectAll: true},
+    10: {down: true, start: "0", end: "-1px", selectAll: true},
+  });
+}
+
+function* testVariousUnitIncrements(view) {
+  info("Testing keyboard increments on values with various units");
+
+  let idRuleEditor = getRuleViewRuleEditor(view, 1);
+  let paddingPropEditor = idRuleEditor.rule.textProps[1].editor;
+
+  yield runIncrementTest(paddingPropEditor, view, {
+    1: {start: "0px", end: "1px", selectAll: true},
+    2: {start: "0pt", end: "1pt", selectAll: true},
+    3: {start: "0pc", end: "1pc", selectAll: true},
+    4: {start: "0em", end: "1em", selectAll: true},
+    5: {start: "0%", end: "1%", selectAll: true},
+    6: {start: "0in", end: "1in", selectAll: true},
+    7: {start: "0cm", end: "1cm", selectAll: true},
+    8: {start: "0mm", end: "1mm", selectAll: true},
+    9: {start: "0ex", end: "1ex", selectAll: true},
+    10: {start: "0", end: "1px", selectAll: true},
+    11: {down: true, start: "0", end: "-1px", selectAll: true},
+  });
+}
+
+function* testHexIncrements(view) {
+  info("Testing keyboard increments with hex colors");
+
+  let idRuleEditor = getRuleViewRuleEditor(view, 1);
+  let hexColorPropEditor = idRuleEditor.rule.textProps[2].editor;
+
+  yield runIncrementTest(hexColorPropEditor, view, {
+    1: {start: "#CCCCCC", end: "#CDCDCD", selectAll: true},
+    2: {shift: true, start: "#CCCCCC", end: "#DCDCDC", selectAll: true},
+    3: {start: "#CCCCCC", end: "#CDCCCC", selection: [1, 3]},
+    4: {shift: true, start: "#CCCCCC", end: "#DCCCCC", selection: [1, 3]},
+    5: {start: "#FFFFFF", end: "#FFFFFF", selectAll: true},
+    6: {down: true, shift: true, start: "#000000", end: "#000000",
+        selectAll: true}
+  });
+}
+
+function* testAlphaHexIncrements(view) {
+  info("Testing keyboard increments with alpha hex colors");
+
+  let idRuleEditor = getRuleViewRuleEditor(view, 1);
+  let hexColorPropEditor = idRuleEditor.rule.textProps[2].editor;
+
+  yield runIncrementTest(hexColorPropEditor, view, {
+    1: {start: "#CCCCCCAA", end: "#CDCDCDAB", selectAll: true},
+    2: {shift: true, start: "#CCCCCCAA", end: "#DCDCDCBA", selectAll: true},
+    3: {start: "#CCCCCCAA", end: "#CDCCCCAA", selection: [1, 3]},
+    4: {shift: true, start: "#CCCCCCAA", end: "#DCCCCCAA", selection: [1, 3]},
+    5: {start: "#FFFFFFFF", end: "#FFFFFFFF", selectAll: true},
+    6: {down: true, shift: true, start: "#00000000", end: "#00000000",
+        selectAll: true}
+  });
+}
+
+function* testRgbIncrements(view) {
+  info("Testing keyboard increments with rgb colors");
+
+  let idRuleEditor = getRuleViewRuleEditor(view, 1);
+  let rgbColorPropEditor = idRuleEditor.rule.textProps[3].editor;
+
+  yield runIncrementTest(rgbColorPropEditor, view, {
+    1: {start: "rgb(0,0,0)", end: "rgb(0,1,0)", selection: [6, 7]},
+    2: {shift: true, start: "rgb(0,0,0)", end: "rgb(0,10,0)",
+        selection: [6, 7]},
+    3: {start: "rgb(0,255,0)", end: "rgb(0,255,0)", selection: [6, 9]},
+    4: {shift: true, start: "rgb(0,250,0)", end: "rgb(0,255,0)",
+        selection: [6, 9]},
+    5: {down: true, start: "rgb(0,0,0)", end: "rgb(0,0,0)", selection: [6, 7]},
+    6: {down: true, shift: true, start: "rgb(0,5,0)", end: "rgb(0,0,0)",
+        selection: [6, 7]}
+  });
+}
+
+function* testShorthandIncrements(view) {
+  info("Testing keyboard increments within shorthand values");
+
+  let idRuleEditor = getRuleViewRuleEditor(view, 1);
+  let paddingPropEditor = idRuleEditor.rule.textProps[1].editor;
+
+  yield runIncrementTest(paddingPropEditor, view, {
+    1: {start: "0px 0px 0px 0px", end: "0px 1px 0px 0px", selection: [4, 7]},
+    2: {shift: true, start: "0px 0px 0px 0px", end: "0px 10px 0px 0px",
+        selection: [4, 7]},
+    3: {start: "0px 0px 0px 0px", end: "1px 0px 0px 0px", selectAll: true},
+    4: {shift: true, start: "0px 0px 0px 0px", end: "10px 0px 0px 0px",
+        selectAll: true},
+    5: {down: true, start: "0px 0px 0px 0px", end: "0px 0px -1px 0px",
+        selection: [8, 11]},
+    6: {down: true, shift: true, start: "0px 0px 0px 0px",
+        end: "-10px 0px 0px 0px", selectAll: true},
+    7: {up: true, start: "0.1em .1em 0em 0em", end: "0.1em 1.1em 0em 0em",
+        selection: [6, 9]},
+    8: {up: true, alt: true, start: "0.1em .9em 0em 0em",
+        end: "0.1em 1em 0em 0em", selection: [6, 9]},
+    9: {up: true, shift: true, start: "0.2em .2em 0em 0em",
+        end: "0.2em 10.2em 0em 0em", selection: [6, 9]}
+  });
+}
+
+function* testOddCases(view) {
+  info("Testing some more odd cases");
+
+  let idRuleEditor = getRuleViewRuleEditor(view, 1);
+  let marginPropEditor = idRuleEditor.rule.textProps[0].editor;
+
+  yield runIncrementTest(marginPropEditor, view, {
+    1: {start: "98.7%", end: "99.7%", selection: [3, 3]},
+    2: {alt: true, start: "98.7%", end: "98.8%", selection: [3, 3]},
+    3: {start: "0", end: "1px"},
+    4: {down: true, start: "0", end: "-1px"},
+    5: {start: "'a=-1'", end: "'a=0'", selection: [4, 4]},
+    6: {start: "0 -1px", end: "0 0px", selection: [2, 2]},
+    7: {start: "url(-1)", end: "url(-1)", selection: [4, 4]},
+    8: {start: "url('test1.1.png')", end: "url('test1.2.png')",
+        selection: [11, 11]},
+    9: {start: "url('test1.png')", end: "url('test2.png')", selection: [9, 9]},
+    10: {shift: true, start: "url('test1.1.png')", end: "url('test11.1.png')",
+         selection: [9, 9]},
+    11: {down: true, start: "url('test-1.png')", end: "url('test-2.png')",
+         selection: [9, 11]},
+    12: {start: "url('test1.1.png')", end: "url('test1.2.png')",
+         selection: [11, 12]},
+    13: {down: true, alt: true, start: "url('test-0.png')",
+         end: "url('test--0.1.png')", selection: [10, 11]},
+    14: {alt: true, start: "url('test--0.1.png')", end: "url('test-0.png')",
+         selection: [10, 14]}
+  });
+}
+
+function* testZeroValueIncrements(view) {
+  info("Testing a valid unit is added when incrementing from 0");
+
+  let idRuleEditor = getRuleViewRuleEditor(view, 1);
+  let backgroundPropEditor = idRuleEditor.rule.textProps[4].editor;
+  yield runIncrementTest(backgroundPropEditor, view, {
+    1: { start: "url(test-0.png) no-repeat 0 0",
+         end: "url(test-0.png) no-repeat 1px 0", selection: [26, 26] },
+    2: { start: "url(test-0.png) no-repeat 0 0",
+         end: "url(test-0.png) no-repeat 0 1px", selection: [28, 28] },
+    3: { start: "url(test-0.png) no-repeat center/0",
+         end: "url(test-0.png) no-repeat center/1px", selection: [34, 34] },
+    4: { start: "url(test-0.png) no-repeat 0 0",
+         end: "url(test-1.png) no-repeat 0 0", selection: [10, 10] },
+    5: { start: "linear-gradient(0, red 0, blue 0)",
+         end: "linear-gradient(1deg, red 0, blue 0)", selection: [17, 17] },
+    6: { start: "linear-gradient(1deg, red 0, blue 0)",
+         end: "linear-gradient(1deg, red 1px, blue 0)", selection: [27, 27] },
+    7: { start: "linear-gradient(1deg, red 0, blue 0)",
+         end: "linear-gradient(1deg, red 0, blue 1px)", selection: [35, 35] },
+  });
+
+  let transitionPropEditor = idRuleEditor.rule.textProps[5].editor;
+  yield runIncrementTest(transitionPropEditor, view, {
+    1: { start: "all 0 ease-out", end: "all 1s ease-out", selection: [5, 5] },
+    2: { start: "margin 4s, color 0",
+         end: "margin 4s, color 1s", selection: [18, 18] },
+  });
+
+  let zIndexPropEditor = idRuleEditor.rule.textProps[6].editor;
+  yield runIncrementTest(zIndexPropEditor, view, {
+    1: {start: "0", end: "1", selection: [1, 1]},
+  });
+}
+
+function* runIncrementTest(propertyEditor, view, tests) {
+  let editor = yield focusEditableField(view, propertyEditor.valueSpan);
+
+  for (let test in tests) {
+    yield testIncrement(editor, tests[test], view, propertyEditor);
+  }
+
+  // Blur the field to put back the UI in its initial state (and avoid pending
+  // requests when the test ends).
+  let onRuleViewChanged = view.once("ruleview-changed");
+  EventUtils.synthesizeKey("VK_ESCAPE", {}, view.styleWindow);
+  view.throttle.flush();
+  yield onRuleViewChanged;
+}
+
+function* testIncrement(editor, options, view) {
+  editor.input.value = options.start;
+  let input = editor.input;
+
+  if (options.selectAll) {
+    input.select();
+  } else if (options.selection) {
+    input.setSelectionRange(options.selection[0], options.selection[1]);
+  }
+
+  is(input.value, options.start, "Value initialized at " + options.start);
+
+  let onRuleViewChanged = view.once("ruleview-changed");
+  let onKeyUp = once(input, "keyup");
+
+  let key;
+  key = options.down ? "VK_DOWN" : "VK_UP";
+  if (options.pageDown) {
+    key = "VK_PAGE_DOWN";
+  } else if (options.pageUp) {
+    key = "VK_PAGE_UP";
+  }
+
+  EventUtils.synthesizeKey(key, {altKey: options.alt, shiftKey: options.shift},
+    view.styleWindow);
+
+  yield onKeyUp;
+
+  // Only expect a change if the value actually changed!
   if (options.start !== options.end) {
-    view.throttle.flush();
-    yield onRuleViewChanged;
-  }
-
-  is(input.value, options.end, "Value changed to " + options.end);
-}
+    view.throttle.flush();
+    yield onRuleViewChanged;
+  }
+
+  is(input.value, options.end, "Value changed to " + options.end);
+}
--- a/devtools/client/inspector/rules/test/browser_rules_invalid-source-map.js
+++ b/devtools/client/inspector/rules/test/browser_rules_invalid-source-map.js
@@ -1,43 +1,43 @@
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that when a source map is missing/invalid, the rule view still loads
-// correctly.
-
-const TESTCASE_URI = URL_ROOT + "doc_invalid_sourcemap.html";
-const PREF = "devtools.styleeditor.source-maps-enabled";
-const CSS_LOC = "doc_invalid_sourcemap.css:1";
-
-add_task(function* () {
-  Services.prefs.setBoolPref(PREF, true);
-
-  yield addTab(TESTCASE_URI);
-  let {inspector, view} = yield openRuleView();
-
-  yield selectNode("div", inspector);
-
-  let ruleEl = getRuleViewRule(view, "div");
-  ok(ruleEl, "The 'div' rule exists in the rule-view");
-
-  let prop = getRuleViewProperty(view, "div", "color");
-  ok(prop, "The 'color' property exists in this rule");
-
-  let value = getRuleViewPropertyValue(view, "div", "color");
-  is(value, "gold", "The 'color' property has the right value");
-
-  yield verifyLinkText(view, CSS_LOC);
-
-  Services.prefs.clearUserPref(PREF);
-});
-
-function verifyLinkText(view, text) {
-  info("Verifying that the rule-view stylesheet link is " + text);
-  let label = getRuleViewLinkByIndex(view, 1).querySelector("label");
-  return waitForSuccess(
-    () => label.getAttribute("value") == text,
-    "Link text changed to display correct location: " + text
-  );
-}
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that when a source map is missing/invalid, the rule view still loads
+// correctly.
+
+const TESTCASE_URI = URL_ROOT + "doc_invalid_sourcemap.html";
+const PREF = "devtools.styleeditor.source-maps-enabled";
+const CSS_LOC = "doc_invalid_sourcemap.css:1";
+
+add_task(function* () {
+  Services.prefs.setBoolPref(PREF, true);
+
+  yield addTab(TESTCASE_URI);
+  let {inspector, view} = yield openRuleView();
+
+  yield selectNode("div", inspector);
+
+  let ruleEl = getRuleViewRule(view, "div");
+  ok(ruleEl, "The 'div' rule exists in the rule-view");
+
+  let prop = getRuleViewProperty(view, "div", "color");
+  ok(prop, "The 'color' property exists in this rule");
+
+  let value = getRuleViewPropertyValue(view, "div", "color");
+  is(value, "gold", "The 'color' property has the right value");
+
+  yield verifyLinkText(view, CSS_LOC);
+
+  Services.prefs.clearUserPref(PREF);
+});
+
+function verifyLinkText(view, text) {
+  info("Verifying that the rule-view stylesheet link is " + text);
+  let label = getRuleViewLinkByIndex(view, 1).querySelector("label");
+  return waitForSuccess(
+    () => label.getAttribute("value") == text,
+    "Link text changed to display correct location: " + text
+  );
+}
--- a/devtools/client/inspector/shared/dom-node-preview.js
+++ b/devtools/client/inspector/shared/dom-node-preview.js
@@ -1,352 +1,352 @@
-/* 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/. */
-"use strict";
-
-const {Task} = require("devtools/shared/task");
-const EventEmitter = require("devtools/shared/event-emitter");
-const {createNode} = require("devtools/client/animationinspector/utils");
-const { LocalizationHelper } = require("devtools/shared/l10n");
-
-const STRINGS_URI = "devtools/locale/inspector.properties";
-const L10N = new LocalizationHelper(STRINGS_URI);
-
-/**
- * UI component responsible for displaying a preview of a dom node.
- * @param {InspectorPanel} inspector Requires a reference to the inspector-panel
- * to highlight and select the node, as well as refresh it when there are
- * mutations.
- * @param {Object} options Supported properties are:
- * - compact {Boolean} Defaults to false.
- *   By default, nodes are previewed like <tag id="id" class="class">
- *   If true, nodes will be previewed like tag#id.class instead.
- */
-function DomNodePreview(inspector, options = {}) {
-  this.inspector = inspector;
-  this.options = options;
-
-  this.onPreviewMouseOver = this.onPreviewMouseOver.bind(this);
-  this.onPreviewMouseOut = this.onPreviewMouseOut.bind(this);
-  this.onSelectElClick = this.onSelectElClick.bind(this);
-  this.onMarkupMutations = this.onMarkupMutations.bind(this);
-  this.onHighlightElClick = this.onHighlightElClick.bind(this);
-  this.onHighlighterLocked = this.onHighlighterLocked.bind(this);
-
-  EventEmitter.decorate(this);
-}
-
-exports.DomNodePreview = DomNodePreview;
-
-DomNodePreview.prototype = {
-  init: function (containerEl) {
-    let document = containerEl.ownerDocument;
-
-    // Init the markup for displaying the target node.
-    this.el = createNode({
-      parent: containerEl,
-      attributes: {
-        "class": "animation-target"
-      }
-    });
-
-    // Icon to select the node in the inspector.
-    this.highlightNodeEl = createNode({
-      parent: this.el,
-      nodeType: "span",
-      attributes: {
-        "class": "node-highlighter",
-        "title": L10N.getStr("inspector.nodePreview.highlightNodeLabel")
-      }
-    });
-
-    // Wrapper used for mouseover/out event handling.
-    this.previewEl = createNode({
-      parent: this.el,
-      nodeType: "span",
-      attributes: {
-        "title": L10N.getStr("inspector.nodePreview.selectNodeLabel")
-      }
-    });
-
-    if (!this.options.compact) {
-      this.previewEl.appendChild(document.createTextNode("<"));
-    }
-
-    // Only used for ::before and ::after pseudo-elements.
-    this.pseudoEl = createNode({
-      parent: this.previewEl,
-      nodeType: "span",
-      attributes: {
-        "class": "pseudo-element theme-fg-color5"
-      }
-    });
-
-    // Tag name.
-    this.tagNameEl = createNode({
-      parent: this.previewEl,
-      nodeType: "span",
-      attributes: {
-        "class": "tag-name theme-fg-color3"
-      }
-    });
-
-    // Id attribute container.
-    this.idEl = createNode({
-      parent: this.previewEl,
-      nodeType: "span"
-    });
-
-    if (!this.options.compact) {
-      createNode({
-        parent: this.idEl,
-        nodeType: "span",
-        attributes: {
-          "class": "attribute-name theme-fg-color2"
-        },
-        textContent: "id"
-      });
-      this.idEl.appendChild(document.createTextNode("=\""));
-    } else {
-      createNode({
-        parent: this.idEl,
-        nodeType: "span",
-        attributes: {
-          "class": "theme-fg-color6"
-        },
-        textContent: "#"
-      });
-    }
-
-    createNode({
-      parent: this.idEl,
-      nodeType: "span",
-      attributes: {
-        "class": "attribute-value theme-fg-color6"
-      }
-    });
-
-    if (!this.options.compact) {
-      this.idEl.appendChild(document.createTextNode("\""));
-    }
-
-    // Class attribute container.
-    this.classEl = createNode({
-      parent: this.previewEl,
-      nodeType: "span"
-    });
-
-    if (!this.options.compact) {
-      createNode({
-        parent: this.classEl,
-        nodeType: "span",
-        attributes: {
-          "class": "attribute-name theme-fg-color2"
-        },
-        textContent: "class"
-      });
-      this.classEl.appendChild(document.createTextNode("=\""));
-    } else {
-      createNode({
-        parent: this.classEl,
-        nodeType: "span",
-        attributes: {
-          "class": "theme-fg-color6"
-        },
-        textContent: "."
-      });
-    }
-
-    createNode({
-      parent: this.classEl,
-      nodeType: "span",
-      attributes: {
-        "class": "attribute-value theme-fg-color6"
-      }
-    });
-
-    if (!this.options.compact) {
-      this.classEl.appendChild(document.createTextNode("\""));
-      this.previewEl.appendChild(document.createTextNode(">"));
-    }
-
-    this.startListeners();
-  },
-
-  startListeners: function () {
-    // Init events for highlighting and selecting the node.
-    this.previewEl.addEventListener("mouseover", this.onPreviewMouseOver);
-    this.previewEl.addEventListener("mouseout", this.onPreviewMouseOut);
-    this.previewEl.addEventListener("click", this.onSelectElClick);
-    this.highlightNodeEl.addEventListener("click", this.onHighlightElClick);
-
-    // Start to listen for markupmutation events.
-    this.inspector.on("markupmutation", this.onMarkupMutations);
-
-    // Listen to the target node highlighter.
-    HighlighterLock.on("highlighted", this.onHighlighterLocked);
-  },
-
-  stopListeners: function () {
-    HighlighterLock.off("highlighted", this.onHighlighterLocked);
-    this.inspector.off("markupmutation", this.onMarkupMutations);
-    this.previewEl.removeEventListener("mouseover", this.onPreviewMouseOver);
-    this.previewEl.removeEventListener("mouseout", this.onPreviewMouseOut);
-    this.previewEl.removeEventListener("click", this.onSelectElClick);
-    this.highlightNodeEl.removeEventListener("click", this.onHighlightElClick);
-  },
-
-  destroy: function () {
-    HighlighterLock.unhighlight().catch(e => console.error(e));
-
-    this.stopListeners();
-
-    this.el.remove();
-    this.el = this.tagNameEl = this.idEl = this.classEl = this.pseudoEl = null;
-    this.highlightNodeEl = this.previewEl = null;
-    this.nodeFront = this.inspector = null;
-  },
-
-  get highlighterUtils() {
-    if (this.inspector && this.inspector.toolbox) {
-      return this.inspector.toolbox.highlighterUtils;
-    }
-    return null;
-  },
-
-  onPreviewMouseOver: function () {
-    if (!this.nodeFront || !this.highlighterUtils) {
-      return;
-    }
-    this.highlighterUtils.highlightNodeFront(this.nodeFront)
-                         .catch(e => console.error(e));
-  },
-
-  onPreviewMouseOut: function () {
-    if (!this.nodeFront || !this.highlighterUtils) {
-      return;
-    }
-    this.highlighterUtils.unhighlight()
-                         .catch(e => console.error(e));
-  },
-
-  onSelectElClick: function () {
-    if (!this.nodeFront) {
-      return;
-    }
-    this.inspector.selection.setNodeFront(this.nodeFront, "dom-node-preview");
-  },
-
-  onHighlightElClick: function (e) {
-    e.stopPropagation();
-
-    let classList = this.highlightNodeEl.classList;
-    let isHighlighted = classList.contains("selected");
-
-    if (isHighlighted) {
-      classList.remove("selected");
-      HighlighterLock.unhighlight().then(() => {
-        this.emit("target-highlighter-unlocked");
-      }, error => console.error(error));
-    } else {
-      classList.add("selected");
-      HighlighterLock.highlight(this).then(() => {
-        this.emit("target-highlighter-locked");
-      }, error => console.error(error));
-    }
-  },
-
-  onHighlighterLocked: function (e, domNodePreview) {
-    if (domNodePreview !== this) {
-      this.highlightNodeEl.classList.remove("selected");
-    }
-  },
-
-  onMarkupMutations: function (e, mutations) {
-    if (!this.nodeFront) {
-      return;
-    }
-
-    for (let {target} of mutations) {
-      if (target === this.nodeFront) {
-        // Re-render with the same nodeFront to update the output.
-        this.render(this.nodeFront);
-        break;
-      }
-    }
-  },
-
-  render: function (nodeFront) {
-    this.nodeFront = nodeFront;
-    let {displayName, attributes} = nodeFront;
-
-    if (nodeFront.isPseudoElement) {
-      this.pseudoEl.textContent = nodeFront.isBeforePseudoElement
-                                   ? "::before"
-                                   : "::after";
-      this.pseudoEl.style.display = "inline";
-      this.tagNameEl.style.display = "none";
-    } else {
-      this.tagNameEl.textContent = displayName;
-      this.pseudoEl.style.display = "none";
-      this.tagNameEl.style.display = "inline";
-    }
-
-    let idIndex = attributes.findIndex(({name}) => name === "id");
-    if (idIndex > -1 && attributes[idIndex].value) {
-      this.idEl.querySelector(".attribute-value").textContent =
-        attributes[idIndex].value;
-      this.idEl.style.display = "inline";
-    } else {
-      this.idEl.style.display = "none";
-    }
-
-    let classIndex = attributes.findIndex(({name}) => name === "class");
-    if (classIndex > -1 && attributes[classIndex].value) {
-      let value = attributes[classIndex].value;
-      if (this.options.compact) {
-        value = value.split(" ").join(".");
-      }
-
-      this.classEl.querySelector(".attribute-value").textContent = value;
-      this.classEl.style.display = "inline";
-    } else {
-      this.classEl.style.display = "none";
-    }
-  }
-};
-
-/**
- * HighlighterLock is a helper used to lock the highlighter on DOM nodes in the
- * page.
- * It instantiates a new highlighter that is then shared amongst all instances
- * of DomNodePreview. This is useful because that means showing the highlighter
- * on one node will unhighlight the previously highlighted one, but will not
- * interfere with the default inspector highlighter.
- */
-var HighlighterLock = {
-  highlighter: null,
-  isShown: false,
-
-  highlight: Task.async(function* (animationTargetNode) {
-    if (!this.highlighter) {
-      let util = animationTargetNode.inspector.toolbox.highlighterUtils;
-      this.highlighter = yield util.getHighlighterByType("BoxModelHighlighter");
-    }
-
-    yield this.highlighter.show(animationTargetNode.nodeFront);
-    this.isShown = true;
-    this.emit("highlighted", animationTargetNode);
-  }),
-
-  unhighlight: Task.async(function* () {
-    if (!this.highlighter || !this.isShown) {
-      return;
-    }
-
-    yield this.highlighter.hide();
-    this.isShown = false;
-    this.emit("unhighlighted");
-  })
-};
-
-EventEmitter.decorate(HighlighterLock);
+/* 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/. */
+"use strict";
+
+const {Task} = require("devtools/shared/task");
+const EventEmitter = require("devtools/shared/event-emitter");
+const {createNode} = require("devtools/client/animationinspector/utils");
+const { LocalizationHelper } = require("devtools/shared/l10n");
+
+const STRINGS_URI = "devtools/locale/inspector.properties";
+const L10N = new LocalizationHelper(STRINGS_URI);
+
+/**
+ * UI component responsible for displaying a preview of a dom node.
+ * @param {InspectorPanel} inspector Requires a reference to the inspector-panel
+ * to highlight and select the node, as well as refresh it when there are
+ * mutations.
+ * @param {Object} options Supported properties are:
+ * - compact {Boolean} Defaults to false.
+ *   By default, nodes are previewed like <tag id="id" class="class">
+ *   If true, nodes will be previewed like tag#id.class instead.
+ */
+function DomNodePreview(inspector, options = {}) {
+  this.inspector = inspector;
+  this.options = options;
+
+  this.onPreviewMouseOver = this.onPreviewMouseOver.bind(this);
+  this.onPreviewMouseOut = this.onPreviewMouseOut.bind(this);
+  this.onSelectElClick = this.onSelectElClick.bind(this);
+  this.onMarkupMutations = this.onMarkupMutations.bind(this);
+  this.onHighlightElClick = this.onHighlightElClick.bind(this);
+  this.onHighlighterLocked = this.onHighlighterLocked.bind(this);
+
+  EventEmitter.decorate(this);
+}
+
+exports.DomNodePreview = DomNodePreview;
+
+DomNodePreview.prototype = {
+  init: function (containerEl) {
+    let document = containerEl.ownerDocument;
+
+    // Init the markup for displaying the target node.
+    this.el = createNode({
+      parent: containerEl,
+      attributes: {
+        "class": "animation-target"
+      }
+    });
+
+    // Icon to select the node in the inspector.
+    this.highlightNodeEl = createNode({
+      parent: this.el,
+      nodeType: "span",
+      attributes: {
+        "class": "node-highlighter",
+        "title": L10N.getStr("inspector.nodePreview.highlightNodeLabel")
+      }
+    });
+
+    // Wrapper used for mouseover/out event handling.
+    this.previewEl = createNode({
+      parent: this.el,
+      nodeType: "span",
+      attributes: {
+        "title": L10N.getStr("inspector.nodePreview.selectNodeLabel")
+      }
+    });
+
+    if (!this.options.compact) {
+      this.previewEl.appendChild(document.createTextNode("<"));
+    }
+
+    // Only used for ::before and ::after pseudo-elements.
+    this.pseudoEl = createNode({
+      parent: this.previewEl,
+      nodeType: "span",
+      attributes: {
+        "class": "pseudo-element theme-fg-color5"
+      }
+    });
+
+    // Tag name.
+    this.tagNameEl = createNode({
+      parent: this.previewEl,
+      nodeType: "span",
+      attributes: {
+        "class": "tag-name theme-fg-color3"
+      }
+    });
+
+    // Id attribute container.
+    this.idEl = createNode({
+      parent: this.previewEl,
+      nodeType: "span"
+    });
+
+    if (!this.options.compact) {
+      createNode({
+        parent: this.idEl,
+        nodeType: "span",
+        attributes: {
+          "class": "attribute-name theme-fg-color2"
+        },
+        textContent: "id"
+      });
+      this.idEl.appendChild(document.createTextNode("=\""));
+    } else {
+      createNode({
+        parent: this.idEl,
+        nodeType: "span",
+        attributes: {
+          "class": "theme-fg-color6"
+        },
+        textContent: "#"
+      });
+    }
+
+    createNode({
+      parent: this.idEl,
+      nodeType: "span",
+      attributes: {
+        "class": "attribute-value theme-fg-color6"
+      }
+    });
+
+    if (!this.options.compact) {
+      this.idEl.appendChild(document.createTextNode("\""));
+    }
+
+    // Class attribute container.
+    this.classEl = createNode({
+      parent: this.previewEl,
+      nodeType: "span"
+    });
+
+    if (!this.options.compact) {
+      createNode({
+        parent: this.classEl,
+        nodeType: "span",
+        attributes: {
+          "class": "attribute-name theme-fg-color2"
+        },
+        textContent: "class"
+      });
+      this.classEl.appendChild(document.createTextNode("=\""));
+    } else {
+      createNode({
+        parent: this.classEl,
+        nodeType: "span",
+        attributes: {
+          "class": "theme-fg-color6"
+        },
+        textContent: "."
+      });
+    }
+
+    createNode({
+      parent: this.classEl,
+      nodeType: "span",
+      attributes: {
+        "class": "attribute-value theme-fg-color6"
+      }
+    });
+
+    if (!this.options.compact) {
+      this.classEl.appendChild(document.createTextNode("\""));
+      this.previewEl.appendChild(document.createTextNode(">"));
+    }
+
+    this.startListeners();
+  },
+
+  startListeners: function () {
+    // Init events for highlighting and selecting the node.
+    this.previewEl.addEventListener("mouseover", this.onPreviewMouseOver);
+    this.previewEl.addEventListener("mouseout", this.onPreviewMouseOut);
+    this.previewEl.addEventListener("click", this.onSelectElClick);
+    this.highlightNodeEl.addEventListener("click", this.onHighlightElClick);
+
+    // Start to listen for markupmutation events.
+    this.inspector.on("markupmutation", this.onMarkupMutations);
+
+    // Listen to the target node highlighter.
+    HighlighterLock.on("highlighted", this.onHighlighterLocked);
+  },
+
+  stopListeners: function () {
+    HighlighterLock.off("highlighted", this.onHighlighterLocked);
+    this.inspector.off("markupmutation", this.onMarkupMutations);
+    this.previewEl.removeEventListener("mouseover", this.onPreviewMouseOver);
+    this.previewEl.removeEventListener("mouseout", this.onPreviewMouseOut);
+    this.previewEl.removeEventListener("click", this.onSelectElClick);
+    this.highlightNodeEl.removeEventListener("click", this.onHighlightElClick);
+  },
+
+  destroy: function () {
+    HighlighterLock.unhighlight().catch(e => console.error(e));
+
+    this.stopListeners();
+
+    this.el.remove();
+    this.el = this.tagNameEl = this.idEl = this.classEl = this.pseudoEl = null;
+    this.highlightNodeEl = this.previewEl = null;
+    this.nodeFront = this.inspector = null;
+  },
+
+  get highlighterUtils() {
+    if (this.inspector && this.inspector.toolbox) {
+      return this.inspector.toolbox.highlighterUtils;
+    }
+    return null;
+  },
+
+  onPreviewMouseOver: function () {
+    if (!this.nodeFront || !this.highlighterUtils) {
+      return;
+    }
+    this.highlighterUtils.highlightNodeFront(this.nodeFront)
+                         .catch(e => console.error(e));
+  },
+
+  onPreviewMouseOut: function () {
+    if (!this.nodeFront || !this.highlighterUtils) {
+      return;
+    }
+    this.highlighterUtils.unhighlight()
+                         .catch(e => console.error(e));
+  },
+
+  onSelectElClick: function () {
+    if (!this.nodeFront) {
+      return;
+    }
+    this.inspector.selection.setNodeFront(this.nodeFront, "dom-node-preview");
+  },
+
+  onHighlightElClick: function (e) {
+    e.stopPropagation();
+
+    let classList = this.highlightNodeEl.classList;
+    let isHighlighted = classList.contains("selected");
+
+    if (isHighlighted) {
+      classList.remove("selected");
+      HighlighterLock.unhighlight().then(() => {
+        this.emit("target-highlighter-unlocked");
+      }, error => console.error(error));
+    } else {
+      classList.add("selected");
+      HighlighterLock.highlight(this).then(() => {
+        this.emit("target-highlighter-locked");
+      }, error => console.error(error));
+    }
+  },
+
+  onHighlighterLocked: function (e, domNodePreview) {
+    if (domNodePreview !== this) {
+      this.highlightNodeEl.classList.remove("selected");
+    }
+  },
+
+  onMarkupMutations: function (e, mutations) {
+    if (!this.nodeFront) {
+      return;
+    }
+
+    for (let {target} of mutations) {
+      if (target === this.nodeFront) {
+        // Re-render with the same nodeFront to update the output.
+        this.render(this.nodeFront);
+        break;
+      }
+    }
+  },
+
+  render: function (nodeFront) {
+    this.nodeFront = nodeFront;
+    let {displayName, attributes} = nodeFront;
+
+    if (nodeFront.isPseudoElement) {
+      this.pseudoEl.textContent = nodeFront.isBeforePseudoElement
+                                   ? "::before"
+                                   : "::after";
+      this.pseudoEl.style.display = "inline";
+      this.tagNameEl.style.display = "none";
+    } else {
+      this.tagNameEl.textContent = displayName;
+      this.pseudoEl.style.display = "none";
+      this.tagNameEl.style.display = "inline";
+    }
+
+    let idIndex = attributes.findIndex(({name}) => name === "id");
+    if (idIndex > -1 && attributes[idIndex].value) {
+      this.idEl.querySelector(".attribute-value").textContent =
+        attributes[idIndex].value;
+      this.idEl.style.display = "inline";
+    } else {
+      this.idEl.style.display = "none";
+    }
+
+    let classIndex = attributes.findIndex(({name}) => name === "class");
+    if (classIndex > -1 && attributes[classIndex].value) {
+      let value = attributes[classIndex].value;
+      if (this.options.compact) {
+        value = value.split(" ").join(".");
+      }
+
+      this.classEl.querySelector(".attribute-value").textContent = value;
+      this.classEl.style.display = "inline";
+    } else {
+      this.classEl.style.display = "none";
+    }
+  }
+};
+
+/**
+ * HighlighterLock is a helper used to lock the highlighter on DOM nodes in the
+ * page.
+ * It instantiates a new highlighter that is then shared amongst all instances
+ * of DomNodePreview. This is useful because that means showing the highlighter
+ * on one node will unhighlight the previously highlighted one, but will not
+ * interfere with the default inspector highlighter.
+ */
+var HighlighterLock = {
+  highlighter: null,
+  isShown: false,
+
+  highlight: Task.async(function* (animationTargetNode) {
+    if (!this.highlighter) {
+      let util = animationTargetNode.inspector.toolbox.highlighterUtils;
+      this.highlighter = yield util.getHighlighterByType("BoxModelHighlighter");
+    }
+
+    yield this.highlighter.show(animationTargetNode.nodeFront);
+    this.isShown = true;
+    this.emit("highlighted", animationTargetNode);
+  }),
+
+  unhighlight: Task.async(function* () {
+    if (!this.highlighter || !this.isShown) {
+      return;
+    }
+
+    yield this.highlighter.hide();
+    this.isShown = false;
+    this.emit("unhighlighted");
+  })
+};
+
+EventEmitter.decorate(HighlighterLock);
--- a/devtools/client/inspector/shared/test/browser_styleinspector_context-menu-copy-urls.js
+++ b/devtools/client/inspector/shared/test/browser_styleinspector_context-menu-copy-urls.js
@@ -1,109 +1,109 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/* Tests both Copy URL and Copy Data URL context menu items */
-
-const TEST_DATA_URI = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=";
-
-// Invalid URL still needs to be reachable otherwise getImageDataUrl will
-// timeout.  DevTools chrome:// URLs aren't content accessible, so use some
-// random resource:// URL here.
-const INVALID_IMAGE_URI = "resource://devtools/client/definitions.js";
-const ERROR_MESSAGE = STYLE_INSPECTOR_L10N.getStr("styleinspector.copyImageDataUrlError");
-
-add_task(function* () {
-  const TEST_URI = `<style type="text/css">
-      .valid-background {
-        background-image: url(${TEST_DATA_URI});
-      }
-      .invalid-background {
-        background-image: url(${INVALID_IMAGE_URI});
-      }
-    </style>
-    <div class="valid-background">Valid background image</div>
-    <div class="invalid-background">Invalid background image</div>`;
-
-  yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_URI));
-
-  yield startTest();
-});
-
-function* startTest() {
-  info("Opening rule view");
-  let {inspector, view} = yield openRuleView();
-
-  info("Test valid background image URL in rule view");
-  yield testCopyUrlToClipboard({view, inspector}, "data-uri",
-    ".valid-background", TEST_DATA_URI);
-  yield testCopyUrlToClipboard({view, inspector}, "url",
-    ".valid-background", TEST_DATA_URI);
-
-  info("Test invalid background image URL in rue view");
-  yield testCopyUrlToClipboard({view, inspector}, "data-uri",
-    ".invalid-background", ERROR_MESSAGE);
-  yield testCopyUrlToClipboard({view, inspector}, "url",
-    ".invalid-background", INVALID_IMAGE_URI);
-
-  info("Opening computed view");
-  view = selectComputedView(inspector);
-
-  info("Test valid background image URL in computed view");
-  yield testCopyUrlToClipboard({view, inspector}, "data-uri",
-    ".valid-background", TEST_DATA_URI);
-  yield testCopyUrlToClipboard({view, inspector}, "url",
-    ".valid-background", TEST_DATA_URI);
-
-  info("Test invalid background image URL in computed view");
-  yield testCopyUrlToClipboard({view, inspector}, "data-uri",
-    ".invalid-background", ERROR_MESSAGE);
-  yield testCopyUrlToClipboard({view, inspector}, "url",
-    ".invalid-background", INVALID_IMAGE_URI);
-}
-
-function* testCopyUrlToClipboard({view, inspector}, type, selector, expected) {
-  info("Select node in inspector panel");
-  yield selectNode(selector, inspector);
-
-  info("Retrieve background-image link for selected node in current " +
-       "styleinspector view");
-  let property = getBackgroundImageProperty(view, selector);
-  let imageLink = property.valueSpan.querySelector(".theme-link");
-  ok(imageLink, "Background-image link element found");
-
-  info("Simulate right click on the background-image URL");
-  let allMenuItems = openStyleContextMenuAndGetAllItems(view, imageLink);
-  let menuitemCopyUrl = allMenuItems.find(item => item.label ===
-    STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyUrl"));
-  let menuitemCopyImageDataUrl = allMenuItems.find(item => item.label ===
-    STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyImageDataUrl"));
-
-  info("Context menu is displayed");
-  ok(menuitemCopyUrl.visible,
-     "\"Copy URL\" menu entry is displayed");
-  ok(menuitemCopyImageDataUrl.visible,
-     "\"Copy Image Data-URL\" menu entry is displayed");
-
-  if (type == "data-uri") {
-    info("Click Copy Data URI and wait for clipboard");
-    yield waitForClipboardPromise(() => {
-      return menuitemCopyImageDataUrl.click();
-    }, expected);
-  } else {
-    info("Click Copy URL and wait for clipboard");
-    yield waitForClipboardPromise(() => {
-      return menuitemCopyUrl.click();
-    }, expected);
-  }
-
-  info("Hide context menu");
-}
-
-function getBackgroundImageProperty(view, selector) {
-  let isRuleView = view instanceof CssRuleView;
-  if (isRuleView) {
-    return getRuleViewProperty(view, selector, "background-image");
-  }
-  return getComputedViewProperty(view, "background-image");
-}
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/* Tests both Copy URL and Copy Data URL context menu items */
+
+const TEST_DATA_URI = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=";
+
+// Invalid URL still needs to be reachable otherwise getImageDataUrl will
+// timeout.  DevTools chrome:// URLs aren't content accessible, so use some
+// random resource:// URL here.
+const INVALID_IMAGE_URI = "resource://devtools/client/definitions.js";
+const ERROR_MESSAGE = STYLE_INSPECTOR_L10N.getStr("styleinspector.copyImageDataUrlError");
+
+add_task(function* () {
+  const TEST_URI = `<style type="text/css">
+      .valid-background {
+        background-image: url(${TEST_DATA_URI});
+      }
+      .invalid-background {
+        background-image: url(${INVALID_IMAGE_URI});
+      }
+    </style>
+    <div class="valid-background">Valid background image</div>
+    <div class="invalid-background">Invalid background image</div>`;
+
+  yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_URI));
+
+  yield startTest();
+});
+
+function* startTest() {
+  info("Opening rule view");
+  let {inspector, view} = yield openRuleView();
+
+  info("Test valid background image URL in rule view");
+  yield testCopyUrlToClipboard({view, inspector}, "data-uri",
+    ".valid-background", TEST_DATA_URI);
+  yield testCopyUrlToClipboard({view, inspector}, "url",
+    ".valid-background", TEST_DATA_URI);
+
+  info("Test invalid background image URL in rue view");
+  yield testCopyUrlToClipboard({view, inspector}, "data-uri",
+    ".invalid-background", ERROR_MESSAGE);
+  yield testCopyUrlToClipboard({view, inspector}, "url",
+    ".invalid-background", INVALID_IMAGE_URI);
+
+  info("Opening computed view");
+  view = selectComputedView(inspector);
+
+  info("Test valid background image URL in computed view");
+  yield testCopyUrlToClipboard({view, inspector}, "data-uri",
+    ".valid-background", TEST_DATA_URI);
+  yield testCopyUrlToClipboard({view, inspector}, "url",
+    ".valid-background", TEST_DATA_URI);
+
+  info("Test invalid background image URL in computed view");
+  yield testCopyUrlToClipboard({view, inspector}, "data-uri",
+    ".invalid-background", ERROR_MESSAGE);
+  yield testCopyUrlToClipboard({view, inspector}, "url",
+    ".invalid-background", INVALID_IMAGE_URI);
+}
+
+function* testCopyUrlToClipboard({view, inspector}, type, selector, expected) {
+  info("Select node in inspector panel");
+  yield selectNode(selector, inspector);
+
+  info("Retrieve background-image link for selected node in current " +
+       "styleinspector view");
+  let property = getBackgroundImageProperty(view, selector);
+  let imageLink = property.valueSpan.querySelector(".theme-link");
+  ok(imageLink, "Background-image link element found");
+
+  info("Simulate right click on the background-image URL");
+  let allMenuItems = openStyleContextMenuAndGetAllItems(view, imageLink);
+  let menuitemCopyUrl = allMenuItems.find(item => item.label ===
+    STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyUrl"));
+  let menuitemCopyImageDataUrl = allMenuItems.find(item => item.label ===
+    STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyImageDataUrl"));
+
+  info("Context menu is displayed");
+  ok(menuitemCopyUrl.visible,
+     "\"Copy URL\" menu entry is displayed");
+  ok(menuitemCopyImageDataUrl.visible,
+     "\"Copy Image Data-URL\" menu entry is displayed");
+
+  if (type == "data-uri") {
+    info("Click Copy Data URI and wait for clipboard");
+    yield waitForClipboardPromise(() => {
+      return menuitemCopyImageDataUrl.click();
+    }, expected);
+  } else {
+    info("Click Copy URL and wait for clipboard");
+    yield waitForClipboardPromise(() => {
+      return menuitemCopyUrl.click();
+    }, expected);
+  }
+
+  info("Hide context menu");
+}
+
+function getBackgroundImageProperty(view, selector) {
+  let isRuleView = view instanceof CssRuleView;
+  if (isRuleView) {
+    return getRuleViewProperty(view, selector, "background-image");
+  }
+  return getComputedViewProperty(view, "background-image");
+}
--- a/devtools/client/inspector/test/browser_inspector_addNode_01.js
+++ b/devtools/client/inspector/test/browser_inspector_addNode_01.js
@@ -1,22 +1,22 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that the add node button and context menu items are present in the UI.
-
-const TEST_URL = "data:text/html;charset=utf-8,<h1>Add node</h1>";
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
-  let {panelDoc} = inspector;
-
-  let allMenuItems = openContextMenuAndGetAllItems(inspector);
-  let menuItem = allMenuItems.find(item => item.id === "node-menu-add");
-  ok(menuItem, "The item is in the menu");
-
-  let toolbarButton =
-    panelDoc.querySelector("#inspector-toolbar #inspector-element-add-button");
-  ok(toolbarButton, "The add button is in the toolbar");
-});
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that the add node button and context menu items are present in the UI.
+
+const TEST_URL = "data:text/html;charset=utf-8,<h1>Add node</h1>";
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URL);
+  let {panelDoc} = inspector;
+
+  let allMenuItems = openContextMenuAndGetAllItems(inspector);
+  let menuItem = allMenuItems.find(item => item.id === "node-menu-add");
+  ok(menuItem, "The item is in the menu");
+
+  let toolbarButton =
+    panelDoc.querySelector("#inspector-toolbar #inspector-element-add-button");
+  ok(toolbarButton, "The add button is in the toolbar");
+});
--- a/devtools/client/inspector/test/browser_inspector_addNode_02.js
+++ b/devtools/client/inspector/test/browser_inspector_addNode_02.js
@@ -1,63 +1,63 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that the add node button and context menu items have the right state
-// depending on the current selection.
-
-const TEST_URL = URL_ROOT + "doc_inspector_add_node.html";
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
-
-  info("Select the DOCTYPE element");
-  let {nodes} = yield inspector.walker.children(inspector.walker.rootNode);
-  yield selectNode(nodes[0], inspector);
-  assertState(false, inspector,
-    "The button and item are disabled on DOCTYPE");
-
-  info("Select the ::before pseudo-element");
-  let body = yield getNodeFront("body", inspector);
-  ({nodes} = yield inspector.walker.children(body));
-  yield selectNode(nodes[0], inspector);
-  assertState(false, inspector,
-    "The button and item are disabled on a pseudo-element");
-
-  info("Select the svg element");
-  yield selectNode("svg", inspector);
-  assertState(false, inspector,
-    "The button and item are disabled on a SVG element");
-
-  info("Select the div#foo element");
-  yield selectNode("#foo", inspector);
-  assertState(true, inspector,
-    "The button and item are enabled on a DIV element");
-
-  info("Select the documentElement element (html)");
-  yield selectNode("html", inspector);
-  assertState(false, inspector,
-    "The button and item are disabled on the documentElement");
-
-  info("Select the iframe element");
-  yield selectNode("iframe", inspector);
-  assertState(false, inspector,
-    "The button and item are disabled on an IFRAME element");
-});
-
-function assertState(isEnabled, inspector, desc) {
-  let doc = inspector.panelDoc;
-  let btn = doc.querySelector("#inspector-element-add-button");
-
-  // Force an update of the context menu to make sure menu items are updated
-  // according to the current selection. This normally happens when the menu is
-  // opened, but for the sake of this test's simplicity, we directly call the
-  // private update function instead.
-  let allMenuItems = openContextMenuAndGetAllItems(inspector);
-  let menuItem = allMenuItems.find(item => item.id === "node-menu-add");
-  ok(menuItem, "The item is in the menu");
-  is(!menuItem.disabled, isEnabled, desc);
-
-  is(!btn.hasAttribute("disabled"), isEnabled, desc);
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that the add node button and context menu items have the right state
+// depending on the current selection.
+
+const TEST_URL = URL_ROOT + "doc_inspector_add_node.html";
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URL);
+
+  info("Select the DOCTYPE element");
+  let {nodes} = yield inspector.walker.children(inspector.walker.rootNode);
+  yield selectNode(nodes[0], inspector);
+  assertState(false, inspector,
+    "The button and item are disabled on DOCTYPE");
+
+  info("Select the ::before pseudo-element");
+  let body = yield getNodeFront("body", inspector);
+  ({nodes} = yield inspector.walker.children(body));
+  yield selectNode(nodes[0], inspector);
+  assertState(false, inspector,
+    "The button and item are disabled on a pseudo-element");
+
+  info("Select the svg element");
+  yield selectNode("svg", inspector);
+  assertState(false, inspector,
+    "The button and item are disabled on a SVG element");
+
+  info("Select the div#foo element");
+  yield selectNode("#foo", inspector);
+  assertState(true, inspector,
+    "The button and item are enabled on a DIV element");
+
+  info("Select the documentElement element (html)");
+  yield selectNode("html", inspector);
+  assertState(false, inspector,
+    "The button and item are disabled on the documentElement");
+
+  info("Select the iframe element");
+  yield selectNode("iframe", inspector);
+  assertState(false, inspector,
+    "The button and item are disabled on an IFRAME element");
+});
+
+function assertState(isEnabled, inspector, desc) {
+  let doc = inspector.panelDoc;
+  let btn = doc.querySelector("#inspector-element-add-button");
+
+  // Force an update of the context menu to make sure menu items are updated
+  // according to the current selection. This normally happens when the menu is
+  // opened, but for the sake of this test's simplicity, we directly call the
+  // private update function instead.
+  let allMenuItems = openContextMenuAndGetAllItems(inspector);
+  let menuItem = allMenuItems.find(item => item.id === "node-menu-add");
+  ok(menuItem, "The item is in the menu");
+  is(!menuItem.disabled, isEnabled, desc);
+
+  is(!btn.hasAttribute("disabled"), isEnabled, desc);
+}
--- a/devtools/client/inspector/test/browser_inspector_addNode_03.js
+++ b/devtools/client/inspector/test/browser_inspector_addNode_03.js
@@ -1,84 +1,84 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that adding nodes does work as expected: the parent gets expanded, the
-// new node gets selected.
-
-const TEST_URL = URL_ROOT + "doc_inspector_add_node.html";
-const PARENT_TREE_LEVEL = 3;
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
-
-  info("Adding in element that has no children and is collapsed");
-  let parentNode = yield getNodeFront("#foo", inspector);
-  yield selectNode(parentNode, inspector);
-  yield testAddNode(parentNode, inspector);
-
-  info("Adding in element with children but that has not been expanded yet");
-  parentNode = yield getNodeFront("#bar", inspector);
-  yield selectNode(parentNode, inspector);
-  yield testAddNode(parentNode, inspector);
-
-  info("Adding in element with children that has been expanded then collapsed");
-  // Select again #bar and collapse it.
-  parentNode = yield getNodeFront("#bar", inspector);
-  yield selectNode(parentNode, inspector);
-  collapseNode(parentNode, inspector);
-  yield testAddNode(parentNode, inspector);
-
-  info("Adding in element with children that is expanded");
-  parentNode = yield getNodeFront("#bar", inspector);
-  yield selectNode(parentNode, inspector);
-  yield testAddNode(parentNode, inspector);
-});
-
-function* testAddNode(parentNode, inspector) {
-  let btn = inspector.panelDoc.querySelector("#inspector-element-add-button");
-  let markupWindow = inspector.markup.win;
-  let parentContainer = inspector.markup.getContainer(parentNode);
-
-  is(parentContainer.tagLine.getAttribute("aria-level"), PARENT_TREE_LEVEL,
-    "Parent level should be up to date.");
-
-  info("Clicking 'add node' and expecting a markup mutation and focus event");
-  let onMutation = inspector.once("markupmutation");
-  btn.click();
-  let mutations = yield onMutation;
-
-  info("Expecting an inspector-updated event right after the mutation event " +
-       "to wait for the new node selection");
-  yield inspector.once("inspector-updated");
-
-  is(mutations.length, 1, "There is one mutation only");
-  is(mutations[0].added.length, 1, "There is one new node only");
-
-  let newNode = mutations[0].added[0];
-
-  is(newNode, inspector.selection.nodeFront,
-     "The new node is selected");
-
-  ok(parentContainer.expanded, "The parent node is now expanded");
-
-  is(inspector.selection.nodeFront.parentNode(), parentNode,
-     "The new node is inside the right parent");
-
-  let focusedElement = markupWindow.document.activeElement;
-  let focusedContainer = focusedElement.container;
-  let selectedContainer = inspector.markup._selectedContainer;
-  is(selectedContainer.tagLine.getAttribute("aria-level"),
-    PARENT_TREE_LEVEL + 1, "Added container level should be up to date.");
-  is(selectedContainer.node, inspector.selection.nodeFront,
-     "The right container is selected in the markup-view");
-  ok(selectedContainer.selected, "Selected container is set to selected");
-  is(focusedContainer.toString(), "[root container]",
-    "Root container is focused");
-}
-
-function collapseNode(node, inspector) {
-  let container = inspector.markup.getContainer(node);
-  container.setExpanded(false);
-}
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that adding nodes does work as expected: the parent gets expanded, the
+// new node gets selected.
+
+const TEST_URL = URL_ROOT + "doc_inspector_add_node.html";
+const PARENT_TREE_LEVEL = 3;
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URL);
+
+  info("Adding in element that has no children and is collapsed");
+  let parentNode = yield getNodeFront("#foo", inspector);
+  yield selectNode(parentNode, inspector);
+  yield testAddNode(parentNode, inspector);
+
+  info("Adding in element with children but that has not been expanded yet");
+  parentNode = yield getNodeFront("#bar", inspector);
+  yield selectNode(parentNode, inspector);
+  yield testAddNode(parentNode, inspector);
+
+  info("Adding in element with children that has been expanded then collapsed");
+  // Select again #bar and collapse it.
+  parentNode = yield getNodeFront("#bar", inspector);
+  yield selectNode(parentNode, inspector);
+  collapseNode(parentNode, inspector);
+  yield testAddNode(parentNode, inspector);
+
+  info("Adding in element with children that is expanded");
+  parentNode = yield getNodeFront("#bar", inspector);
+  yield selectNode(parentNode, inspector);
+  yield testAddNode(parentNode, inspector);
+});
+
+function* testAddNode(parentNode, inspector) {
+  let btn = inspector.panelDoc.querySelector("#inspector-element-add-button");
+  let markupWindow = inspector.markup.win;
+  let parentContainer = inspector.markup.getContainer(parentNode);
+
+  is(parentContainer.tagLine.getAttribute("aria-level"), PARENT_TREE_LEVEL,
+    "Parent level should be up to date.");
+
+  info("Clicking 'add node' and expecting a markup mutation and focus event");
+  let onMutation = inspector.once("markupmutation");
+  btn.click();
+  let mutations = yield onMutation;
+
+  info("Expecting an inspector-updated event right after the mutation event " +
+       "to wait for the new node selection");
+  yield inspector.once("inspector-updated");
+
+  is(mutations.length, 1, "There is one mutation only");
+  is(mutations[0].added.length, 1, "There is one new node only");
+
+  let newNode = mutations[0].added[0];
+
+  is(newNode, inspector.selection.nodeFront,
+     "The new node is selected");
+
+  ok(parentContainer.expanded, "The parent node is now expanded");
+
+  is(inspector.selection.nodeFront.parentNode(), parentNode,
+     "The new node is inside the right parent");
+
+  let focusedElement = markupWindow.document.activeElement;
+  let focusedContainer = focusedElement.container;
+  let selectedContainer = inspector.markup._selectedContainer;
+  is(selectedContainer.tagLine.getAttribute("aria-level"),
+    PARENT_TREE_LEVEL + 1, "Added container level should be up to date.");
+  is(selectedContainer.node, inspector.selection.nodeFront,
+     "The right container is selected in the markup-view");
+  ok(selectedContainer.selected, "Selected container is set to selected");
+  is(focusedContainer.toString(), "[root container]",
+    "Root container is focused");
+}
+
+function collapseNode(node, inspector) {
+  let container = inspector.markup.getContainer(node);
+  container.setExpanded(false);
+}
--- a/devtools/client/inspector/test/browser_inspector_breadcrumbs_keybinding.js
+++ b/devtools/client/inspector/test/browser_inspector_breadcrumbs_keybinding.js
@@ -1,71 +1,71 @@
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test that the breadcrumbs keybindings work.
-
-const TEST_URI = URL_ROOT + "doc_inspector_breadcrumbs.html";
-const TEST_DATA = [{
-  desc: "Pressing left should select the parent <body>",
-  key: "VK_LEFT",
-  newSelection: "body"
-}, {
-  desc: "Pressing left again should select the parent <html>",
-  key: "VK_LEFT",
-  newSelection: "html"
-}, {
-  desc: "Pressing left again should stay on <html>, it's the first element",
-  key: "VK_LEFT",
-  newSelection: "html"
-}, {
-  desc: "Pressing right should go to <body>",
-  key: "VK_RIGHT",
-  newSelection: "body"
-}, {
-  desc: "Pressing right again should go to #i2",
-  key: "VK_RIGHT",
-  newSelection: "#i2"
-}, {
-  desc: "Pressing right again should stay on #i2, it's the last element",
-  key: "VK_RIGHT",
-  newSelection: "#i2"
-}];
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URI);
-
-  info("Selecting the test node");
-  yield selectNode("#i2", inspector);
-
-  info("Clicking on the corresponding breadcrumbs node to focus it");
-  let container = inspector.panelDoc.getElementById("inspector-breadcrumbs");
-
-  let button = container.querySelector("button[checked]");
-  button.click();
-
-  let currentSelection = "#id2";
-  for (let {desc, key, newSelection} of TEST_DATA) {
-    info(desc);
-
-    // If the selection will change, wait for the breadcrumb to update,
-    // otherwise continue.
-    let onUpdated = null;
-    if (newSelection !== currentSelection) {
-      info("Expecting a new node to be selected");
-      onUpdated = inspector.once("breadcrumbs-updated");
-    }
-
-    EventUtils.synthesizeKey(key, {});
-    yield onUpdated;
-
-    let newNodeFront = yield getNodeFront(newSelection, inspector);
-    is(newNodeFront, inspector.selection.nodeFront,
-       "The current selection is correct");
-    is(container.getAttribute("aria-activedescendant"),
-       container.querySelector("button[checked]").id,
-      "aria-activedescendant is set correctly");
-
-    currentSelection = newSelection;
-  }
-});
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+// Test that the breadcrumbs keybindings work.
+
+const TEST_URI = URL_ROOT + "doc_inspector_breadcrumbs.html";
+const TEST_DATA = [{
+  desc: "Pressing left should select the parent <body>",
+  key: "VK_LEFT",
+  newSelection: "body"
+}, {
+  desc: "Pressing left again should select the parent <html>",
+  key: "VK_LEFT",
+  newSelection: "html"
+}, {
+  desc: "Pressing left again should stay on <html>, it's the first element",
+  key: "VK_LEFT",
+  newSelection: "html"
+}, {
+  desc: "Pressing right should go to <body>",
+  key: "VK_RIGHT",
+  newSelection: "body"
+}, {
+  desc: "Pressing right again should go to #i2",
+  key: "VK_RIGHT",
+  newSelection: "#i2"
+}, {
+  desc: "Pressing right again should stay on #i2, it's the last element",
+  key: "VK_RIGHT",
+  newSelection: "#i2"
+}];
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URI);
+
+  info("Selecting the test node");
+  yield selectNode("#i2", inspector);
+
+  info("Clicking on the corresponding breadcrumbs node to focus it");
+  let container = inspector.panelDoc.getElementById("inspector-breadcrumbs");
+
+  let button = container.querySelector("button[checked]");
+  button.click();
+
+  let currentSelection = "#id2";
+  for (let {desc, key, newSelection} of TEST_DATA) {
+    info(desc);
+
+    // If the selection will change, wait for the breadcrumb to update,
+    // otherwise continue.
+    let onUpdated = null;
+    if (newSelection !== currentSelection) {
+      info("Expecting a new node to be selected");
+      onUpdated = inspector.once("breadcrumbs-updated");
+    }
+
+    EventUtils.synthesizeKey(key, {});
+    yield onUpdated;
+
+    let newNodeFront = yield getNodeFront(newSelection, inspector);
+    is(newNodeFront, inspector.selection.nodeFront,
+       "The current selection is correct");
+    is(container.getAttribute("aria-activedescendant"),
+       container.querySelector("button[checked]").id,
+      "aria-activedescendant is set correctly");
+
+    currentSelection = newSelection;
+  }
+});
--- a/devtools/client/inspector/test/browser_inspector_highlighter-embed.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-embed.js
@@ -1,30 +1,30 @@
-/* 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/. */
-
-"use strict";
-
-// Test that the highlighter can go inside <embed> elements
-
-const TEST_URL = URL_ROOT + "doc_inspector_embed.html";
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
-
-  info("Get a node inside the <embed> element and select/highlight it");
-  let body = yield getEmbeddedBody(inspector);
-  yield selectAndHighlightNode(body, inspector);
-
-  let selectedNode = inspector.selection.nodeFront;
-  is(selectedNode.tagName.toLowerCase(), "body", "The selected node is <body>");
-  ok(selectedNode.baseURI.endsWith("doc_inspector_menu.html"),
-     "The selected node is the <body> node inside the <embed> element");
-});
-
-function* getEmbeddedBody({walker}) {
-  let embed = yield walker.querySelector(walker.rootNode, "embed");
-  let {nodes} = yield walker.children(embed);
-  let contentDoc = nodes[0];
-  let body = yield walker.querySelector(contentDoc, "body");
-  return body;
-}
+/* 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/. */
+
+"use strict";
+
+// Test that the highlighter can go inside <embed> elements
+
+const TEST_URL = URL_ROOT + "doc_inspector_embed.html";
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URL);
+
+  info("Get a node inside the <embed> element and select/highlight it");
+  let body = yield getEmbeddedBody(inspector);
+  yield selectAndHighlightNode(body, inspector);
+
+  let selectedNode = inspector.selection.nodeFront;
+  is(selectedNode.tagName.toLowerCase(), "body", "The selected node is <body>");
+  ok(selectedNode.baseURI.endsWith("doc_inspector_menu.html"),
+     "The selected node is the <body> node inside the <embed> element");
+});
+
+function* getEmbeddedBody({walker}) {
+  let embed = yield walker.querySelector(walker.rootNode, "embed");
+  let {nodes} = yield walker.children(embed);
+  let contentDoc = nodes[0];
+  let body = yield walker.querySelector(contentDoc, "body");
+  return body;
+}
--- a/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-clipboard.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-clipboard.js
@@ -1,39 +1,39 @@
-/* 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/. */
-"use strict";
-
-// Test that the eyedropper can copy colors to the clipboard
-
-const HIGHLIGHTER_TYPE = "EyeDropper";
-const ID = "eye-dropper-";
-const TEST_URI = "data:text/html;charset=utf-8,<style>html{background:red}</style>";
-
-add_task(function* () {
-  let helper = yield openInspectorForURL(TEST_URI)
-               .then(getHighlighterHelperFor(HIGHLIGHTER_TYPE));
-  helper.prefix = ID;
-
-  let {show, finalize,
-       waitForElementAttributeSet, waitForElementAttributeRemoved} = helper;
-
-  info("Show the eyedropper with the copyOnSelect option");
-  yield show("html", {copyOnSelect: true});
-
-  info("Make sure to wait until the eyedropper is done taking a screenshot of the page");
-  yield waitForElementAttributeSet("root", "drawn", helper);
-
-  yield waitForClipboardPromise(() => {
-    info("Activate the eyedropper so the background color is copied");
-    EventUtils.synthesizeKey("VK_RETURN", {});
-  }, "#FF0000");
-
-  ok(true, "The clipboard contains the right value");
-
-  yield waitForElementAttributeRemoved("root", "drawn", helper);
-  yield waitForElementAttributeSet("root", "hidden", helper);
-  ok(true, "The eyedropper is now hidden");
-
-  finalize();
-});
-
+/* 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/. */
+"use strict";
+
+// Test that the eyedropper can copy colors to the clipboard
+
+const HIGHLIGHTER_TYPE = "EyeDropper";
+const ID = "eye-dropper-";
+const TEST_URI = "data:text/html;charset=utf-8,<style>html{background:red}</style>";
+
+add_task(function* () {
+  let helper = yield openInspectorForURL(TEST_URI)
+               .then(getHighlighterHelperFor(HIGHLIGHTER_TYPE));
+  helper.prefix = ID;
+
+  let {show, finalize,
+       waitForElementAttributeSet, waitForElementAttributeRemoved} = helper;
+
+  info("Show the eyedropper with the copyOnSelect option");
+  yield show("html", {copyOnSelect: true});
+
+  info("Make sure to wait until the eyedropper is done taking a screenshot of the page");
+  yield waitForElementAttributeSet("root", "drawn", helper);
+
+  yield waitForClipboardPromise(() => {
+    info("Activate the eyedropper so the background color is copied");
+    EventUtils.synthesizeKey("VK_RETURN", {});
+  }, "#FF0000");
+
+  ok(true, "The clipboard contains the right value");
+
+  yield waitForElementAttributeRemoved("root", "drawn", helper);
+  yield waitForElementAttributeSet("root", "hidden", helper);
+  ok(true, "The eyedropper is now hidden");
+
+  finalize();
+});
+
--- a/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-csp.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-csp.js
@@ -1,30 +1,30 @@
-/* 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/. */
-"use strict";
-
-// Test that the eyedropper opens correctly even when the page defines CSP headers.
-
-const HIGHLIGHTER_TYPE = "EyeDropper";
-const ID = "eye-dropper-";
-const TEST_URI = URL_ROOT + "doc_inspector_csp.html";
-
-add_task(function* () {
-  let helper = yield openInspectorForURL(TEST_URI)
-               .then(getHighlighterHelperFor(HIGHLIGHTER_TYPE));
-  helper.prefix = ID;
-  let {show, hide, finalize, isElementHidden, waitForElementAttributeSet} = helper;
-
-  info("Try to display the eyedropper");
-  yield show("html");
-
-  let hidden = yield isElementHidden("root");
-  ok(!hidden, "The eyedropper is now shown");
-
-  info("Wait until the eyedropper is done taking a screenshot of the page");
-  yield waitForElementAttributeSet("root", "drawn", helper);
-  ok(true, "The image data was retrieved successfully from the window");
-
-  yield hide();
-  finalize();
-});
+/* 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/. */
+"use strict";
+
+// Test that the eyedropper opens correctly even when the page defines CSP headers.
+
+const HIGHLIGHTER_TYPE = "EyeDropper";
+const ID = "eye-dropper-";
+const TEST_URI = URL_ROOT + "doc_inspector_csp.html";
+
+add_task(function* () {
+  let helper = yield openInspectorForURL(TEST_URI)
+               .then(getHighlighterHelperFor(HIGHLIGHTER_TYPE));
+  helper.prefix = ID;
+  let {show, hide, finalize, isElementHidden, waitForElementAttributeSet} = helper;
+
+  info("Try to display the eyedropper");
+  yield show("html");
+
+  let hidden = yield isElementHidden("root");
+  ok(!hidden, "The eyedropper is now shown");
+
+  info("Wait until the eyedropper is done taking a screenshot of the page");
+  yield waitForElementAttributeSet("root", "drawn", helper);
+  ok(true, "The image data was retrieved successfully from the window");
+
+  yield hide();
+  finalize();
+});
--- a/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-events.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-events.js
@@ -1,141 +1,141 @@
-/* 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/. */
-"use strict";
-
-// Test the eyedropper mouse and keyboard handling.
-
-const HIGHLIGHTER_TYPE = "EyeDropper";
-const ID = "eye-dropper-";
-const TEST_URI = `
-<style>
-  html{width:100%;height:100%;}
-</style>
-<body>eye-dropper test</body>`;
-
-const MOVE_EVENTS_DATA = [
-  {type: "mouse", x: 200, y: 100, expected: {x: 200, y: 100}},
-  {type: "mouse", x: 100, y: 200, expected: {x: 100, y: 200}},
-  {type: "keyboard", key: "VK_LEFT", expected: {x: 99, y: 200}},
-  {type: "keyboard", key: "VK_LEFT", shift: true, expected: {x: 89, y: 200}},
-  {type: "keyboard", key: "VK_RIGHT", expected: {x: 90, y: 200}},
-  {type: "keyboard", key: "VK_RIGHT", shift: true, expected: {x: 100, y: 200}},
-  {type: "keyboard", key: "VK_DOWN", expected: {x: 100, y: 201}},
-  {type: "keyboard", key: "VK_DOWN", shift: true, expected: {x: 100, y: 211}},
-  {type: "keyboard", key: "VK_UP", expected: {x: 100, y: 210}},
-  {type: "keyboard", key: "VK_UP", shift: true, expected: {x: 100, y: 200}},
-  // Mouse initialization for left and top snapping
-  {type: "mouse", x: 7, y: 7, expected: {x: 7, y: 7}},
-  // Left Snapping
-  {type: "keyboard", key: "VK_LEFT", shift: true, expected: {x: 0, y: 7},
-   desc: "Left Snapping to x=0"},
-  // Top Snapping
-  {type: "keyboard", key: "VK_UP", shift: true, expected: {x: 0, y: 0},
-   desc: "Top Snapping to y=0"},
-  // Mouse initialization for right snapping
-  {
-    type: "mouse",
-    x: (width, height) => width - 5,
-    y: 0,
-    expected: {
-      x: (width, height) => width - 5,
-      y: 0
-    }
-  },
-  // Right snapping
-  {
-    type: "keyboard",
-    key: "VK_RIGHT",
-    shift: true,
-    expected: {
-      x: (width, height) => width,
-      y: 0
-    },
-    desc: "Right snapping to x=max window width available"
-  },
-  // Mouse initialization for bottom snapping
-  {
-    type: "mouse",
-    x: 0,
-    y: (width, height) => height - 5,
-    expected: {
-      x: 0,
-      y: (width, height) => height - 5
-    }
-  },
-  // Bottom snapping
-  {
-    type: "keyboard",
-    key: "VK_DOWN",
-    shift: true,
-    expected: {
-      x: 0,
-      y: (width, height) => height
-    },
-    desc: "Bottom snapping to y=max window height available"
-  },
-];
-
-add_task(function* () {
-  let {inspector, testActor} = yield openInspectorForURL(
-    "data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
-  let helper = yield getHighlighterHelperFor(HIGHLIGHTER_TYPE)({inspector, testActor});
-
-  helper.prefix = ID;
-
-  yield helper.show("html");
-  yield respondsToMoveEvents(helper, testActor);
-  yield respondsToReturnAndEscape(helper);
-
-  helper.finalize();
-});
-
-function* respondsToMoveEvents(helper, testActor) {
-  info("Checking that the eyedropper responds to events from the mouse and keyboard");
-  let {mouse} = helper;
-  let {width, height} = yield testActor.getBoundingClientRect("html");
-
-  for (let {type, x, y, key, shift, expected, desc} of MOVE_EVENTS_DATA) {
-    x = typeof x === "function" ? x(width, height) : x;
-    y = typeof y === "function" ? y(width, height) : y;
-    expected.x = typeof expected.x === "function" ?
-      expected.x(width, height) : expected.x;
-    expected.y = typeof expected.y === "function" ?
-      expected.y(width, height) : expected.y;
-
-    if (typeof desc === "undefined") {
-      info(`Simulating a ${type} event to move to ${expected.x} ${expected.y}`);
-    } else {
-      info(`Simulating ${type} event: ${desc}`);
-    }
-
-    if (type === "mouse") {
-      yield mouse.move(x, y);
-    } else if (type === "keyboard") {
-      let options = shift ? {shiftKey: true} : {};
-      yield EventUtils.synthesizeKey(key, options);
-    }
-    yield checkPosition(expected, helper);
-  }
-}
-
-function* checkPosition({x, y}, {getElementAttribute}) {
-  let style = yield getElementAttribute("root", "style");
-  is(style, `top:${y}px;left:${x}px;`,
-     `The eyedropper is at the expected ${x} ${y} position`);
-}
-
-function* respondsToReturnAndEscape({isElementHidden, show}) {
-  info("Simulating return to select the color and hide the eyedropper");
-
-  yield EventUtils.synthesizeKey("VK_RETURN", {});
-  let hidden = yield isElementHidden("root");
-  ok(hidden, "The eyedropper has been hidden");
-
-  info("Showing the eyedropper again and simulating escape to hide it");
-
-  yield show("html");
-  yield EventUtils.synthesizeKey("VK_ESCAPE", {});
-  hidden = yield isElementHidden("root");
-  ok(hidden, "The eyedropper has been hidden again");
-}
+/* 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/. */
+"use strict";
+
+// Test the eyedropper mouse and keyboard handling.
+
+const HIGHLIGHTER_TYPE = "EyeDropper";
+const ID = "eye-dropper-";
+const TEST_URI = `
+<style>
+  html{width:100%;height:100%;}
+</style>
+<body>eye-dropper test</body>`;
+
+const MOVE_EVENTS_DATA = [
+  {type: "mouse", x: 200, y: 100, expected: {x: 200, y: 100}},
+  {type: "mouse", x: 100, y: 200, expected: {x: 100, y: 200}},
+  {type: "keyboard", key: "VK_LEFT", expected: {x: 99, y: 200}},
+  {type: "keyboard", key: "VK_LEFT", shift: true, expected: {x: 89, y: 200}},
+  {type: "keyboard", key: "VK_RIGHT", expected: {x: 90, y: 200}},
+  {type: "keyboard", key: "VK_RIGHT", shift: true, expected: {x: 100, y: 200}},
+  {type: "keyboard", key: "VK_DOWN", expected: {x: 100, y: 201}},
+  {type: "keyboard", key: "VK_DOWN", shift: true, expected: {x: 100, y: 211}},
+  {type: "keyboard", key: "VK_UP", expected: {x: 100, y: 210}},
+  {type: "keyboard", key: "VK_UP", shift: true, expected: {x: 100, y: 200}},
+  // Mouse initialization for left and top snapping
+  {type: "mouse", x: 7, y: 7, expected: {x: 7, y: 7}},
+  // Left Snapping
+  {type: "keyboard", key: "VK_LEFT", shift: true, expected: {x: 0, y: 7},
+   desc: "Left Snapping to x=0"},
+  // Top Snapping
+  {type: "keyboard", key: "VK_UP", shift: true, expected: {x: 0, y: 0},
+   desc: "Top Snapping to y=0"},
+  // Mouse initialization for right snapping
+  {
+    type: "mouse",
+    x: (width, height) => width - 5,
+    y: 0,
+    expected: {
+      x: (width, height) => width - 5,
+      y: 0
+    }
+  },
+  // Right snapping
+  {
+    type: "keyboard",
+    key: "VK_RIGHT",
+    shift: true,
+    expected: {
+      x: (width, height) => width,
+      y: 0
+    },
+    desc: "Right snapping to x=max window width available"
+  },
+  // Mouse initialization for bottom snapping
+  {
+    type: "mouse",
+    x: 0,
+    y: (width, height) => height - 5,
+    expected: {
+      x: 0,
+      y: (width, height) => height - 5
+    }
+  },
+  // Bottom snapping
+  {
+    type: "keyboard",
+    key: "VK_DOWN",
+    shift: true,
+    expected: {
+      x: 0,
+      y: (width, height) => height
+    },
+    desc: "Bottom snapping to y=max window height available"
+  },
+];
+
+add_task(function* () {
+  let {inspector, testActor} = yield openInspectorForURL(
+    "data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
+  let helper = yield getHighlighterHelperFor(HIGHLIGHTER_TYPE)({inspector, testActor});
+
+  helper.prefix = ID;
+
+  yield helper.show("html");
+  yield respondsToMoveEvents(helper, testActor);
+  yield respondsToReturnAndEscape(helper);
+
+  helper.finalize();
+});
+
+function* respondsToMoveEvents(helper, testActor) {
+  info("Checking that the eyedropper responds to events from the mouse and keyboard");
+  let {mouse} = helper;
+  let {width, height} = yield testActor.getBoundingClientRect("html");
+
+  for (let {type, x, y, key, shift, expected, desc} of MOVE_EVENTS_DATA) {
+    x = typeof x === "function" ? x(width, height) : x;
+    y = typeof y === "function" ? y(width, height) : y;
+    expected.x = typeof expected.x === "function" ?
+      expected.x(width, height) : expected.x;
+    expected.y = typeof expected.y === "function" ?
+      expected.y(width, height) : expected.y;
+
+    if (typeof desc === "undefined") {
+      info(`Simulating a ${type} event to move to ${expected.x} ${expected.y}`);
+    } else {
+      info(`Simulating ${type} event: ${desc}`);
+    }
+
+    if (type === "mouse") {
+      yield mouse.move(x, y);
+    } else if (type === "keyboard") {
+      let options = shift ? {shiftKey: true} : {};
+      yield EventUtils.synthesizeKey(key, options);
+    }
+    yield checkPosition(expected, helper);
+  }
+}
+
+function* checkPosition({x, y}, {getElementAttribute}) {
+  let style = yield getElementAttribute("root", "style");
+  is(style, `top:${y}px;left:${x}px;`,
+     `The eyedropper is at the expected ${x} ${y} position`);
+}
+
+function* respondsToReturnAndEscape({isElementHidden, show}) {
+  info("Simulating return to select the color and hide the eyedropper");
+
+  yield EventUtils.synthesizeKey("VK_RETURN", {});
+  let hidden = yield isElementHidden("root");
+  ok(hidden, "The eyedropper has been hidden");
+
+  info("Showing the eyedropper again and simulating escape to hide it");
+
+  yield show("html");
+  yield EventUtils.synthesizeKey("VK_ESCAPE", {});
+  hidden = yield isElementHidden("root");
+  ok(hidden, "The eyedropper has been hidden again");
+}
--- a/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-label.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-label.js
@@ -1,115 +1,115 @@
-/* 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/. */
-"use strict";
-
-// Test the position of the eyedropper label.
-// It should move around when the eyedropper is close to the edges of the viewport so as
-// to always stay visible.
-
-const HIGHLIGHTER_TYPE = "EyeDropper";
-const ID = "eye-dropper-";
-
-const HTML = `
-<style>
-html, body {height: 100%; margin: 0;}
-body {background: linear-gradient(red, gold); display: flex; justify-content: center;
-      align-items: center;}
-</style>
-Eyedropper label position test
-`;
-const TEST_PAGE = "data:text/html;charset=utf-8," + encodeURI(HTML);
-
-const TEST_DATA = [{
-  desc: "Move the mouse to the center of the screen",
-  getCoordinates: (width, height) => {
-    return {x: width / 2, y: height / 2};
-  },
-  expectedPositions: {top: false, right: false, left: false}
-}, {
-  desc: "Move the mouse to the center left",
-  getCoordinates: (width, height) => {
-    return {x: 0, y: height / 2};
-  },
-  expectedPositions: {top: false, right: true, left: false}
-}, {
-  desc: "Move the mouse to the center right",
-  getCoordinates: (width, height) => {
-    return {x: width, y: height / 2};
-  },
-  expectedPositions: {top: false, right: false, left: true}
-}, {
-  desc: "Move the mouse to the bottom center",
-  getCoordinates: (width, height) => {
-    return {x: width / 2, y: height};
-  },
-  expectedPositions: {top: true, right: false, left: false}
-}, {
-  desc: "Move the mouse to the bottom left",
-  getCoordinates: (width, height) => {
-    return {x: 0, y: height};
-  },
-  expectedPositions: {top: true, right: true, left: false}
-}, {
-  desc: "Move the mouse to the bottom right",
-  getCoordinates: (width, height) => {
-    return {x: width, y: height};
-  },
-  expectedPositions: {top: true, right: false, left: true}
-}, {
-  desc: "Move the mouse to the top left",
-  getCoordinates: (width, height) => {
-    return {x: 0, y: 0};
-  },
-  expectedPositions: {top: false, right: true, left: false}
-}, {
-  desc: "Move the mouse to the top right",
-  getCoordinates: (width, height) => {
-    return {x: width, y: 0};
-  },
-  expectedPositions: {top: false, right: false, left: true}
-}];
-
-add_task(function* () {
-  let {inspector, testActor} = yield openInspectorForURL(TEST_PAGE);
-  let helper = yield getHighlighterHelperFor(HIGHLIGHTER_TYPE)({inspector, testActor});
-  helper.prefix = ID;
-
-  let {mouse, show, hide, finalize} = helper;
-  let {width, height} = yield testActor.getBoundingClientRect("html");
-
-  // This test fails in non-e10s windows if we use width and height. For some reasons, the
-  // mouse events can't be dispatched/handled properly when we try to move the eyedropper
-  // to the far right and/or bottom of the screen. So just removing 10px from each side
-  // fixes it.
-  width -= 10;
-  height -= 10;
-
-  info("Show the eyedropper on the page");
-  yield show("html");
-
-  info("Move the eyedropper around and check that the label appears at the right place");
-  for (let {desc, getCoordinates, expectedPositions} of TEST_DATA) {
-    info(desc);
-    let {x, y} = getCoordinates(width, height);
-    info(`Moving the mouse to ${x} ${y}`);
-    yield mouse.move(x, y);
-    yield checkLabelPositionAttributes(helper, expectedPositions);
-  }
-
-  info("Hide the eyedropper");
-  yield hide();
-  finalize();
-});
-
-function* checkLabelPositionAttributes(helper, positions) {
-  for (let position in positions) {
-    is((yield hasAttribute(helper, position)), positions[position],
-       `The label was ${positions[position] ? "" : "not "}moved to the ${position}`);
-  }
-}
-
-function* hasAttribute({getElementAttribute}, name) {
-  let value = yield getElementAttribute("root", name);
-  return value !== null;
-}
+/* 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/. */
+"use strict";
+
+// Test the position of the eyedropper label.
+// It should move around when the eyedropper is close to the edges of the viewport so as
+// to always stay visible.
+
+const HIGHLIGHTER_TYPE = "EyeDropper";
+const ID = "eye-dropper-";
+
+const HTML = `
+<style>
+html, body {height: 100%; margin: 0;}
+body {background: linear-gradient(red, gold); display: flex; justify-content: center;
+      align-items: center;}
+</style>
+Eyedropper label position test
+`;
+const TEST_PAGE = "data:text/html;charset=utf-8," + encodeURI(HTML);
+
+const TEST_DATA = [{
+  desc: "Move the mouse to the center of the screen",
+  getCoordinates: (width, height) => {
+    return {x: width / 2, y: height / 2};
+  },
+  expectedPositions: {top: false, right: false, left: false}
+}, {
+  desc: "Move the mouse to the center left",
+  getCoordinates: (width, height) => {
+    return {x: 0, y: height / 2};
+  },
+  expectedPositions: {top: false, right: true, left: false}
+}, {
+  desc: "Move the mouse to the center right",
+  getCoordinates: (width, height) => {
+    return {x: width, y: height / 2};
+  },
+  expectedPositions: {top: false, right: false, left: true}
+}, {
+  desc: "Move the mouse to the bottom center",
+  getCoordinates: (width, height) => {
+    return {x: width / 2, y: height};
+  },
+  expectedPositions: {top: true, right: false, left: false}
+}, {
+  desc: "Move the mouse to the bottom left",
+  getCoordinates: (width, height) => {
+    return {x: 0, y: height};
+  },
+  expectedPositions: {top: true, right: true, left: false}
+}, {
+  desc: "Move the mouse to the bottom right",
+  getCoordinates: (width, height) => {
+    return {x: width, y: height};
+  },
+  expectedPositions: {top: true, right: false, left: true}
+}, {
+  desc: "Move the mouse to the top left",
+  getCoordinates: (width, height) => {
+    return {x: 0, y: 0};
+  },
+  expectedPositions: {top: false, right: true, left: false}
+}, {
+  desc: "Move the mouse to the top right",
+  getCoordinates: (width, height) => {
+    return {x: width, y: 0};
+  },
+  expectedPositions: {top: false, right: false, left: true}
+}];
+
+add_task(function* () {
+  let {inspector, testActor} = yield openInspectorForURL(TEST_PAGE);
+  let helper = yield getHighlighterHelperFor(HIGHLIGHTER_TYPE)({inspector, testActor});
+  helper.prefix = ID;
+
+  let {mouse, show, hide, finalize} = helper;
+  let {width, height} = yield testActor.getBoundingClientRect("html");
+
+  // This test fails in non-e10s windows if we use width and height. For some reasons, the
+  // mouse events can't be dispatched/handled properly when we try to move the eyedropper
+  // to the far right and/or bottom of the screen. So just removing 10px from each side
+  // fixes it.
+  width -= 10;
+  height -= 10;
+
+  info("Show the eyedropper on the page");
+  yield show("html");
+
+  info("Move the eyedropper around and check that the label appears at the right place");
+  for (let {desc, getCoordinates, expectedPositions} of TEST_DATA) {
+    info(desc);
+    let {x, y} = getCoordinates(width, height);
+    info(`Moving the mouse to ${x} ${y}`);
+    yield mouse.move(x, y);
+    yield checkLabelPositionAttributes(helper, expectedPositions);
+  }
+
+  info("Hide the eyedropper");
+  yield hide();
+  finalize();
+});
+
+function* checkLabelPositionAttributes(helper, positions) {
+  for (let position in positions) {
+    is((yield hasAttribute(helper, position)), positions[position],
+       `The label was ${positions[position] ? "" : "not "}moved to the ${position}`);
+  }
+}
+
+function* hasAttribute({getElementAttribute}, name) {
+  let value = yield getElementAttribute("root", name);
+  return value !== null;
+}
--- a/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-show-hide.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-show-hide.js
@@ -1,42 +1,42 @@
-/* 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/. */
-"use strict";
-
-// Test the basic structure of the eye-dropper highlighter.
-
-const HIGHLIGHTER_TYPE = "EyeDropper";
-const ID = "eye-dropper-";
-
-add_task(function* () {
-  let helper = yield openInspectorForURL("data:text/html;charset=utf-8,eye-dropper test")
-               .then(getHighlighterHelperFor(HIGHLIGHTER_TYPE));
-  helper.prefix = ID;
-
-  yield isInitiallyHidden(helper);
-  yield canBeShownAndHidden(helper);
-
-  helper.finalize();
-});
-
-function* isInitiallyHidden({isElementHidden}) {
-  info("Checking that the eyedropper is hidden by default");
-
-  let hidden = yield isElementHidden("root");
-  ok(hidden, "The eyedropper is hidden by default");
-}
-
-function* canBeShownAndHidden({show, hide, isElementHidden, getElementAttribute}) {
-  info("Asking to show and hide the highlighter actually works");
-
-  yield show("html");
-  let hidden = yield isElementHidden("root");
-  ok(!hidden, "The eyedropper is now shown");
-
-  let style = yield getElementAttribute("root", "style");
-  is(style, "top:100px;left:100px;", "The eyedropper is correctly positioned");
-
-  yield hide();
-  hidden = yield isElementHidden("root");
-  ok(hidden, "The eyedropper is now hidden again");
-}
+/* 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/. */
+"use strict";
+
+// Test the basic structure of the eye-dropper highlighter.
+
+const HIGHLIGHTER_TYPE = "EyeDropper";
+const ID = "eye-dropper-";
+
+add_task(function* () {
+  let helper = yield openInspectorForURL("data:text/html;charset=utf-8,eye-dropper test")
+               .then(getHighlighterHelperFor(HIGHLIGHTER_TYPE));
+  helper.prefix = ID;
+
+  yield isInitiallyHidden(helper);
+  yield canBeShownAndHidden(helper);
+
+  helper.finalize();
+});
+
+function* isInitiallyHidden({isElementHidden}) {
+  info("Checking that the eyedropper is hidden by default");
+
+  let hidden = yield isElementHidden("root");
+  ok(hidden, "The eyedropper is hidden by default");
+}
+
+function* canBeShownAndHidden({show, hide, isElementHidden, getElementAttribute}) {
+  info("Asking to show and hide the highlighter actually works");
+
+  yield show("html");
+  let hidden = yield isElementHidden("root");
+  ok(!hidden, "The eyedropper is now shown");
+
+  let style = yield getElementAttribute("root", "style");
+  is(style, "top:100px;left:100px;", "The eyedropper is correctly positioned");
+
+  yield hide();
+  hidden = yield isElementHidden("root");
+  ok(hidden, "The eyedropper is now hidden again");
+}
--- a/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-xul.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-xul.js
@@ -1,42 +1,42 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that the eyedropper icons in the toolbar and in the color picker aren't displayed
-// when the page isn't an HTML one.
-
-const TEST_URL = URL_ROOT + "doc_inspector_highlighter_xbl.xul";
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
-
-  info("Check the inspector toolbar");
-  let button = inspector.panelDoc.querySelector("#inspector-eyedropper-toggle");
-  ok(!isVisible(button), "The button is hidden in the toolbar");
-
-  info("Check the color picker");
-  yield selectNode("#scale", inspector);
-
-  // Find the color swatch in the rule-view.
-  let ruleView = inspector.ruleview.view;
-  let ruleViewDocument = ruleView.styleDocument;
-  let swatchEl = ruleViewDocument.querySelector(".ruleview-colorswatch");
-
-  info("Open the color picker");
-  let cPicker = ruleView.tooltips.colorPicker;
-  let onColorPickerReady = cPicker.once("ready");
-  swatchEl.click();
-  yield onColorPickerReady;
-
-  button = cPicker.tooltip.doc.querySelector("#eyedropper-button");
-  ok(isDisabled(button), "The button is disabled in the color picker");
-});
-
-function isVisible(button) {
-  return button.getBoxQuads().length !== 0;
-}
-
-function isDisabled(button) {
-  return button.disabled;
-}
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that the eyedropper icons in the toolbar and in the color picker aren't displayed
+// when the page isn't an HTML one.
+
+const TEST_URL = URL_ROOT + "doc_inspector_highlighter_xbl.xul";
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL(TEST_URL);
+
+  info("Check the inspector toolbar");
+  let button = inspector.panelDoc.querySelector("#inspector-eyedropper-toggle");
+  ok(!isVisible(button), "The button is hidden in the toolbar");
+
+  info("Check the color picker");
+  yield selectNode("#scale", inspector);
+
+  // Find the color swatch in the rule-view.
+  let ruleView = inspector.ruleview.view;
+  let ruleViewDocument = ruleView.styleDocument;
+  let swatchEl = ruleViewDocument.querySelector(".ruleview-colorswatch");
+
+  info("Open the color picker");
+  let cPicker = ruleView.tooltips.colorPicker;
+  let onColorPickerReady = cPicker.once("ready");
+  swatchEl.click();
+  yield onColorPickerReady;
+
+  button = cPicker.tooltip.doc.querySelector("#eyedropper-button");
+  ok(isDisabled(button), "The button is disabled in the color picker");
+});
+
+function isVisible(button) {
+  return button.getBoxQuads().length !== 0;
+}
+
+function isDisabled(button) {
+  return button.disabled;
+}
--- a/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_01.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_01.js
@@ -1,64 +1,64 @@
-/* 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/. */
-
-"use strict";
-
-// Test that the keybindings for Picker work alright
-
-const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
-
-add_task(function* () {
-  let {inspector, toolbox, testActor} = yield openInspectorForURL(TEST_URL);
-
-  yield startPicker(toolbox);
-
-  info("Selecting the simple-div1 DIV");
-  yield moveMouseOver("#simple-div1");
-
-  ok((yield testActor.assertHighlightedNode("#simple-div1")),
-     "The highlighter shows #simple-div1. OK.");
-
-  // First Child selection
-  info("Testing first-child selection.");
-
-  yield doKeyHover({key: "VK_RIGHT", options: {}});
-  ok((yield testActor.assertHighlightedNode("#useless-para")),
-     "The highlighter shows #useless-para. OK.");
-
-  info("Selecting the useful-para paragraph DIV");
-  yield moveMouseOver("#useful-para");
-  ok((yield testActor.assertHighlightedNode("#useful-para")),
-     "The highlighter shows #useful-para. OK.");
-
-  yield doKeyHover({key: "VK_RIGHT", options: {}});
-  ok((yield testActor.assertHighlightedNode("#bold")),
-     "The highlighter shows #bold. OK.");
-
-  info("Going back up to the simple-div1 DIV");
-  yield doKeyHover({key: "VK_LEFT", options: {}});
-  yield doKeyHover({key: "VK_LEFT", options: {}});
-  ok((yield testActor.assertHighlightedNode("#simple-div1")),
-     "The highlighter shows #simple-div1. OK.");
-
-  info("First child selection test Passed.");
-
-  info("Stopping the picker");
-  yield toolbox.highlighterUtils.stopPicker();
-
-  function doKeyHover(args) {
-    info("Key pressed. Waiting for element to be highlighted/hovered");
-    testActor.synthesizeKey(args);
-    return inspector.toolbox.once("picker-node-hovered");
-  }
-
-  function moveMouseOver(selector) {
-    info("Waiting for element " + selector + " to be highlighted");
-    testActor.synthesizeMouse({
-      options: {type: "mousemove"},
-      center: true,
-      selector: selector
-    });
-    return inspector.toolbox.once("picker-node-hovered");
-  }
-});
+/* 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/. */
+
+"use strict";
+
+// Test that the keybindings for Picker work alright
+
+const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
+
+add_task(function* () {
+  let {inspector, toolbox, testActor} = yield openInspectorForURL(TEST_URL);
+
+  yield startPicker(toolbox);
+
+  info("Selecting the simple-div1 DIV");
+  yield moveMouseOver("#simple-div1");
+
+  ok((yield testActor.assertHighlightedNode("#simple-div1")),
+     "The highlighter shows #simple-div1. OK.");
+
+  // First Child selection
+  info("Testing first-child selection.");
+
+  yield doKeyHover({key: "VK_RIGHT", options: {}});
+  ok((yield testActor.assertHighlightedNode("#useless-para")),
+     "The highlighter shows #useless-para. OK.");
+
+  info("Selecting the useful-para paragraph DIV");
+  yield moveMouseOver("#useful-para");
+  ok((yield testActor.assertHighlightedNode("#useful-para")),
+     "The highlighter shows #useful-para. OK.");
+
+  yield doKeyHover({key: "VK_RIGHT", options: {}});
+  ok((yield testActor.assertHighlightedNode("#bold")),
+     "The highlighter shows #bold. OK.");
+
+  info("Going back up to the simple-div1 DIV");
+  yield doKeyHover({key: "VK_LEFT", options: {}});
+  yield doKeyHover({key: "VK_LEFT", options: {}});
+  ok((yield testActor.assertHighlightedNode("#simple-div1")),
+     "The highlighter shows #simple-div1. OK.");
+
+  info("First child selection test Passed.");
+
+  info("Stopping the picker");
+  yield toolbox.highlighterUtils.stopPicker();
+
+  function doKeyHover(args) {
+    info("Key pressed. Waiting for element to be highlighted/hovered");
+    testActor.synthesizeKey(args);
+    return inspector.toolbox.once("picker-node-hovered");
+  }
+
+  function moveMouseOver(selector) {
+    info("Waiting for element " + selector + " to be highlighted");
+    testActor.synthesizeMouse({
+      options: {type: "mousemove"},
+      center: true,
+      selector: selector
+    });
+    return inspector.toolbox.once("picker-node-hovered");
+  }
+});
--- a/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_02.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_02.js
@@ -1,64 +1,64 @@
-/* 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/. */
-
-"use strict";
-
-// Test that the keybindings for Picker work alright
-
-const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
-
-add_task(function* () {
-  let {inspector, toolbox, testActor} = yield openInspectorForURL(TEST_URL);
-
-  yield startPicker(toolbox);
-
-  // Previously chosen child memory
-  info("Testing whether previously chosen child is remembered");
-
-  info("Selecting the ahoy paragraph DIV");
-  yield moveMouseOver("#ahoy");
-
-  yield doKeyHover({key: "VK_LEFT", options: {}});
-  ok((yield testActor.assertHighlightedNode("#simple-div2")),
-     "The highlighter shows #simple-div2. OK.");
-
-  yield doKeyHover({key: "VK_RIGHT", options: {}});
-  ok((yield testActor.assertHighlightedNode("#ahoy")),
-     "The highlighter shows #ahoy. OK.");
-
-  info("Going back up to the complex-div DIV");
-  yield doKeyHover({key: "VK_LEFT", options: {}});
-  yield doKeyHover({key: "VK_LEFT", options: {}});
-  ok((yield testActor.assertHighlightedNode("#complex-div")),
-     "The highlighter shows #complex-div. OK.");
-
-  yield doKeyHover({key: "VK_RIGHT", options: {}});
-  ok((yield testActor.assertHighlightedNode("#simple-div2")),
-     "The highlighter shows #simple-div2. OK.");
-
-  info("Previously chosen child is remembered. Passed.");
-
-  info("Stopping the picker");
-  yield toolbox.highlighterUtils.stopPicker();
-
-  function doKeyHover(args) {
-    info("Key pressed. Waiting for element to be highlighted/hovered");
-    let onHighlighterReady = toolbox.once("highlighter-ready");
-    let onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
-    testActor.synthesizeKey(args);
-    return promise.all([onHighlighterReady, onPickerNodeHovered]);
-  }
-
-  function moveMouseOver(selector) {
-    info("Waiting for element " + selector + " to be highlighted");
-    let onHighlighterReady = toolbox.once("highlighter-ready");
-    let onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
-    testActor.synthesizeMouse({
-      options: {type: "mousemove"},
-      center: true,
-      selector: selector
-    });
-    return promise.all([onHighlighterReady, onPickerNodeHovered]);
-  }
-});
+/* 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/. */
+
+"use strict";
+
+// Test that the keybindings for Picker work alright
+
+const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
+
+add_task(function* () {
+  let {inspector, toolbox, testActor} = yield openInspectorForURL(TEST_URL);
+
+  yield startPicker(toolbox);
+
+  // Previously chosen child memory
+  info("Testing whether previously chosen child is remembered");
+
+  info("Selecting the ahoy paragraph DIV");
+  yield moveMouseOver("#ahoy");
+
+  yield doKeyHover({key: "VK_LEFT", options: {}});
+  ok((yield testActor.assertHighlightedNode("#simple-div2")),
+     "The highlighter shows #simple-div2. OK.");
+
+  yield doKeyHover({key: "VK_RIGHT", options: {}});
+  ok((yield testActor.assertHighlightedNode("#ahoy")),
+     "The highlighter shows #ahoy. OK.");
+
+  info("Going back up to the complex-div DIV");
+  yield doKeyHover({key: "VK_LEFT", options: {}});
+  yield doKeyHover({key: "VK_LEFT", options: {}});
+  ok((yield testActor.assertHighlightedNode("#complex-div")),
+     "The highlighter shows #complex-div. OK.");
+
+  yield doKeyHover({key: "VK_RIGHT", options: {}});
+  ok((yield testActor.assertHighlightedNode("#simple-div2")),
+     "The highlighter shows #simple-div2. OK.");
+
+  info("Previously chosen child is remembered. Passed.");
+
+  info("Stopping the picker");
+  yield toolbox.highlighterUtils.stopPicker();
+
+  function doKeyHover(args) {
+    info("Key pressed. Waiting for element to be highlighted/hovered");
+    let onHighlighterReady = toolbox.once("highlighter-ready");
+    let onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
+    testActor.synthesizeKey(args);
+    return promise.all([onHighlighterReady, onPickerNodeHovered]);
+  }
+
+  function moveMouseOver(selector) {
+    info("Waiting for element " + selector + " to be highlighted");
+    let onHighlighterReady = toolbox.once("highlighter-ready");
+    let onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
+    testActor.synthesizeMouse({
+      options: {type: "mousemove"},
+      center: true,
+      selector: selector
+    });
+    return promise.all([onHighlighterReady, onPickerNodeHovered]);
+  }
+});
--- a/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_03.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_03.js
@@ -1,71 +1,71 @@
-/* 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/. */
-
-"use strict";
-
-// Test that the keybindings for Picker work alright
-
-const IS_OSX = Services.appinfo.OS === "Darwin";
-const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
-
-add_task(function* () {
-  let {inspector, toolbox, testActor} = yield openInspectorForURL(TEST_URL);
-
-  yield startPicker(toolbox);
-  yield moveMouseOver("#another");
-
-  info("Testing enter/return key as pick-node command");
-  yield doKeyPick({key: "VK_RETURN", options: {}});
-  is(inspector.selection.nodeFront.id, "another",
-     "The #another node was selected. Passed.");
-
-  info("Testing escape key as cancel-picker command");
-  yield startPicker(toolbox);
-  yield moveMouseOver("#ahoy");
-  yield doKeyStop({key: "VK_ESCAPE", options: {}});
-  is(inspector.selection.nodeFront.id, "another",
-     "The #another DIV is still selected. Passed.");
-
-  info("Testing Ctrl+Shift+C shortcut as cancel-picker command");
-  yield startPicker(toolbox);
-  yield moveMouseOver("#ahoy");
-  let shortcutOpts = {key: "VK_C", options: {}};
-  if (IS_OSX) {
-    shortcutOpts.options.metaKey = true;
-    shortcutOpts.options.altKey = true;
-  } else {
-    shortcutOpts.options.ctrlKey = true;
-    shortcutOpts.options.shiftKey = true;
-  }
-  yield doKeyStop(shortcutOpts);
-  is(inspector.selection.nodeFront.id, "another",
-     "The #another DIV is still selected. Passed.");
-
-  function doKeyPick(args) {
-    info("Key pressed. Waiting for element to be picked");
-    testActor.synthesizeKey(args);
-    return promise.all([
-      inspector.selection.once("new-node-front"),
-      inspector.once("inspector-updated")
-    ]);
-  }
-
-  function doKeyStop(args) {
-    info("Key pressed. Waiting for picker to be canceled");
-    testActor.synthesizeKey(args);
-    return inspector.toolbox.once("picker-stopped");
-  }
-
-  function moveMouseOver(selector) {
-    info("Waiting for element " + selector + " to be highlighted");
-    let onHighlighterReady = toolbox.once("highlighter-ready");
-    let onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
-    testActor.synthesizeMouse({
-      options: {type: "mousemove"},
-      center: true,
-      selector: selector
-    });
-    return promise.all([onHighlighterReady, onPickerNodeHovered]);
-  }
-});
+/* 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/. */
+
+"use strict";
+
+// Test that the keybindings for Picker work alright
+
+const IS_OSX = Services.appinfo.OS === "Darwin";
+const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
+
+add_task(function* () {
+  let {inspector, toolbox, testActor} = yield openInspectorForURL(TEST_URL);
+
+  yield startPicker(toolbox);
+  yield moveMouseOver("#another");
+
+  info("Testing enter/return key as pick-node command");
+  yield doKeyPick({key: "VK_RETURN", options: {}});
+  is(inspector.selection.nodeFront.id, "another",
+     "The #another node was selected. Passed.");
+
+  info("Testing escape key as cancel-picker command");
+  yield startPicker(toolbox);
+  yield moveMouseOver("#ahoy");
+  yield doKeyStop({key: "VK_ESCAPE", options: {}});
+  is(inspector.selection.nodeFront.id, "another",
+     "The #another DIV is still selected. Passed.");
+
+  info("Testing Ctrl+Shift+C shortcut as cancel-picker command");
+  yield startPicker(toolbox);
+  yield moveMouseOver("#ahoy");
+  let shortcutOpts = {key: "VK_C", options: {}};
+  if (IS_OSX) {
+    shortcutOpts.options.metaKey = true;
+    shortcutOpts.options.altKey = true;
+  } else {
+    shortcutOpts.options.ctrlKey = true;
+    shortcutOpts.options.shiftKey = true;
+  }
+  yield doKeyStop(shortcutOpts);
+  is(inspector.selection.nodeFront.id, "another",
+     "The #another DIV is still selected. Passed.");
+
+  function doKeyPick(args) {
+    info("Key pressed. Waiting for element to be picked");
+    testActor.synthesizeKey(args);
+    return promise.all([
+      inspector.selection.once("new-node-front"),
+      inspector.once("inspector-updated")
+    ]);
+  }
+
+  function doKeyStop(args) {
+    info("Key pressed. Waiting for picker to be canceled");
+    testActor.synthesizeKey(args);
+    return inspector.toolbox.once("picker-stopped");
+  }
+
+  function moveMouseOver(selector) {
+    info("Waiting for element " + selector + " to be highlighted");
+    let onHighlighterReady = toolbox.once("highlighter-ready");
+    let onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
+    testActor.synthesizeMouse({
+      options: {type: "mousemove"},
+      center: true,
+      selector: selector
+    });
+    return promise.all([onHighlighterReady, onPickerNodeHovered]);
+  }
+});
--- a/devtools/client/inspector/test/browser_inspector_search-sidebar.js
+++ b/devtools/client/inspector/test/browser_inspector_search-sidebar.js
@@ -1,74 +1,74 @@
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test that depending where the user last clicked in the inspector, the right search
-// field is focused when ctrl+F is pressed.
-
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL("data:text/html;charset=utf-8,Search!");
-
-  info("Check that by default, the inspector search field gets focused");
-  pressCtrlF();
-  isInInspectorSearchBox(inspector);
-
-  info("Click somewhere in the rule-view");
-  clickInRuleView(inspector);
-
-  info("Check that the rule-view search field gets focused");
-  pressCtrlF();
-  isInRuleViewSearchBox(inspector);
-
-  info("Click in the inspector again");
-  yield clickContainer("head", inspector);
-
-  info("Check that now we're back in the inspector, its search field gets focused");
-  pressCtrlF();
-  isInInspectorSearchBox(inspector);
-
-  info("Switch to the computed view, and click somewhere inside it");
-  selectComputedView(inspector);
-  clickInComputedView(inspector);
-
-  info("Check that the computed-view search field gets focused");
-  pressCtrlF();
-  isInComputedViewSearchBox(inspector);
-
-  info("Click in the inspector yet again");
-  yield clickContainer("body", inspector);
-
-  info("We're back in the inspector again, check the inspector search field focuses");
-  pressCtrlF();
-  isInInspectorSearchBox(inspector);
-});
-
-function pressCtrlF() {
-  EventUtils.synthesizeKey("f", {accelKey: true});
-}
-
-function clickInRuleView(inspector) {
-  let el = inspector.panelDoc.querySelector("#sidebar-panel-ruleview");
-  EventUtils.synthesizeMouseAtCenter(el, {}, inspector.panelDoc.defaultView);
-}
-
-function clickInComputedView(inspector) {
-  let el = inspector.panelDoc.querySelector("#sidebar-panel-computedview");
-  EventUtils.synthesizeMouseAtCenter(el, {}, inspector.panelDoc.defaultView);
-}
-
-function isInInspectorSearchBox(inspector) {
-  // Focus ends up in an anonymous child of the XUL textbox.
-  ok(inspector.panelDoc.activeElement.closest("#inspector-searchbox"),
-     "The inspector search field is focused when ctrl+F is pressed");
-}
-
-function isInRuleViewSearchBox(inspector) {
-  is(inspector.panelDoc.activeElement, inspector.ruleview.view.searchField,
-     "The rule-view search field is focused when ctrl+F is pressed");
-}
-
-function isInComputedViewSearchBox(inspector) {
-  is(inspector.panelDoc.activeElement, inspector.computedview.computedView.searchField,
-     "The computed-view search field is focused when ctrl+F is pressed");
-}
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+// Test that depending where the user last clicked in the inspector, the right search
+// field is focused when ctrl+F is pressed.
+
+add_task(function* () {
+  let {inspector} = yield openInspectorForURL("data:text/html;charset=utf-8,Search!");
+
+  info("Check that by default, the inspector search field gets focused");
+  pressCtrlF();
+  isInInspectorSearchBox(inspector);
+
+  info("Click somewhere in the rule-view");
+  clickInRuleView(inspector);
+
+  info("Check that the rule-view search field gets focused");
+  pressCtrlF();
+  isInRuleViewSearchBox(inspector);
+
+  info("Click in the inspector again");
+  yield clickContainer("head", inspector);
+
+  info("Check that now we're back in the inspector, its search field gets focused");
+  pressCtrlF();
+  isInInspectorSearchBox(inspector);
+
+  info("Switch to the computed view, and click somewhere inside it");
+  selectComputedView(inspector);
+  clickInComputedView(inspector);
+
+  info("Check that the computed-view search field gets focused");
+  pressCtrlF();
+  isInComputedViewSearchBox(inspector);
+
+  info("Click in the inspector yet again");
+  yield clickContainer("body", inspector);
+
+  info("We're back in the inspector again, check the inspector search field focuses");
+  pressCtrlF();
+  isInInspectorSearchBox(inspector);
+});
+
+function pressCtrlF() {
+  EventUtils.synthesizeKey("f", {accelKey: true});
+}
+
+function clickInRuleView(inspector) {
+  let el = inspector.panelDoc.querySelector("#sidebar-panel-ruleview");
+  EventUtils.synthesizeMouseAtCenter(el, {}, inspector.panelDoc.defaultView);
+}
+
+function clickInComputedView(inspector) {
+  let el = inspector.panelDoc.querySelector("#sidebar-panel-computedview");
+  EventUtils.synthesizeMouseAtCenter(el, {}, inspector.panelDoc.defaultView);
+}
+
+function isInInspectorSearchBox(inspector) {
+  // Focus ends up in an anonymous child of the XUL textbox.
+  ok(inspector.panelDoc.activeElement.closest("#inspector-searchbox"),
+     "The inspector search field is focused when ctrl+F is pressed");
+}
+
+function isInRuleViewSearchBox(inspector) {
+  is(inspector.panelDoc.activeElement, inspector.ruleview.view.searchField,
+     "The rule-view search field is focused when ctrl+F is pressed");
+}
+
+function isInComputedViewSearchBox(inspector) {
+  is(inspector.panelDoc.activeElement, inspector.computedview.computedView.searchField,
+     "The computed-view search field is focused when ctrl+F is pressed");
+}
--- a/devtools/client/inspector/test/browser_inspector_textbox-menu.js
+++ b/devtools/client/inspector/test/browser_inspector_textbox-menu.js
@@ -1,90 +1,90 @@
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test that when right-clicking on various text boxes throughout the inspector does use
-// the toolbox's context menu (copy/cut/paste/selectAll/Undo).
-
-add_task(function* () {
-  yield addTab(`data:text/html;charset=utf-8,
-                <style>h1 { color: red; }</style>
-                <h1 id="title">textbox context menu test</h1>`);
-  let {toolbox, inspector} = yield openInspector();
-  yield selectNode("h1", inspector);
-
-  info("Testing the markup-view tagname");
-  let container = yield focusNode("h1", inspector);
-  let tag = container.editor.tag;
-  tag.focus();
-  EventUtils.sendKey("return", inspector.panelWin);
-  yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
-
-  info("Testing the markup-view attribute");
-  EventUtils.sendKey("tab", inspector.panelWin);
-  yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
-
-  info("Testing the markup-view new attribute");
-  // It takes 2 tabs to focus the newAttr field, the first one just moves the cursor to
-  // the end of the field.
-  EventUtils.sendKey("tab", inspector.panelWin);
-  EventUtils.sendKey("tab", inspector.panelWin);
-  yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
-
-  info("Testing the markup-view textcontent");
-  EventUtils.sendKey("tab", inspector.panelWin);
-  yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
-  // Blur this last markup-view field, since we're moving on to the rule-view next.
-  EventUtils.sendKey("escape", inspector.panelWin);
-
-  info("Testing the rule-view selector");
-  let ruleView = inspector.ruleview.view;
-  let cssRuleEditor = getRuleViewRuleEditor(ruleView, 1);
-  EventUtils.synthesizeMouse(cssRuleEditor.selectorText, 0, 0, {}, inspector.panelWin);
-  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
-
-  info("Testing the rule-view property name");
-  EventUtils.sendKey("tab", inspector.panelWin);
-  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
-
-  info("Testing the rule-view property value");
-  EventUtils.sendKey("tab", inspector.panelWin);
-  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
-
-  info("Testing the rule-view new property");
-  // Tabbing out of the value field triggers a ruleview-changed event that we need to wait
-  // for.
-  let onRuleViewChanged = once(ruleView, "ruleview-changed");
-  EventUtils.sendKey("tab", inspector.panelWin);
-  yield onRuleViewChanged;
-  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
-
-  info("Switching to the computed-view");
-  let onComputedViewReady = inspector.once("boxmodel-view-updated");
-  selectComputedView(inspector);
-  yield onComputedViewReady;
-
-  info("Testing the box-model region");
-  let margin = inspector.panelDoc.querySelector(".boxmodel-margin.boxmodel-top > span");
-  EventUtils.synthesizeMouseAtCenter(margin, {}, inspector.panelWin);
-  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
-});
-
-function* checkTextBox(textBox, {textBoxContextMenuPopup}) {
-  is(textBoxContextMenuPopup.state, "closed", "The menu is closed");
-
-  info("Simulating context click on the textbox and expecting the menu to open");
-  let onContextMenu = once(textBoxContextMenuPopup, "popupshown");
-  EventUtils.synthesizeMouse(textBox, 2, 2, {type: "contextmenu", button: 2},
-                             textBox.ownerDocument.defaultView);
-  yield onContextMenu;
-
-  is(textBoxContextMenuPopup.state, "open", "The menu is now visible");
-
-  info("Closing the menu");
-  let onContextMenuHidden = once(textBoxContextMenuPopup, "popuphidden");
-  textBoxContextMenuPopup.hidePopup();
-  yield onContextMenuHidden;
-
-  is(textBoxContextMenuPopup.state, "closed", "The menu is closed again");
-}
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+// Test that when right-clicking on various text boxes throughout the inspector does use
+// the toolbox's context menu (copy/cut/paste/selectAll/Undo).
+
+add_task(function* () {
+  yield addTab(`data:text/html;charset=utf-8,
+                <style>h1 { color: red; }</style>
+                <h1 id="title">textbox context menu test</h1>`);
+  let {toolbox, inspector} = yield openInspector();
+  yield selectNode("h1", inspector);
+
+  info("Testing the markup-view tagname");
+  let container = yield focusNode("h1", inspector);
+  let tag = container.editor.tag;
+  tag.focus();
+  EventUtils.sendKey("return", inspector.panelWin);
+  yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
+
+  info("Testing the markup-view attribute");
+  EventUtils.sendKey("tab", inspector.panelWin);
+  yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
+
+  info("Testing the markup-view new attribute");
+  // It takes 2 tabs to focus the newAttr field, the first one just moves the cursor to
+  // the end of the field.
+  EventUtils.sendKey("tab", inspector.panelWin);
+  EventUtils.sendKey("tab", inspector.panelWin);
+  yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
+
+  info("Testing the markup-view textcontent");
+  EventUtils.sendKey("tab", inspector.panelWin);
+  yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
+  // Blur this last markup-view field, since we're moving on to the rule-view next.
+  EventUtils.sendKey("escape", inspector.panelWin);
+
+  info("Testing the rule-view selector");
+  let ruleView = inspector.ruleview.view;
+  let cssRuleEditor = getRuleViewRuleEditor(ruleView, 1);
+  EventUtils.synthesizeMouse(cssRuleEditor.selectorText, 0, 0, {}, inspector.panelWin);
+  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
+
+  info("Testing the rule-view property name");
+  EventUtils.sendKey("tab", inspector.panelWin);
+  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
+
+  info("Testing the rule-view property value");
+  EventUtils.sendKey("tab", inspector.panelWin);
+  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
+
+  info("Testing the rule-view new property");
+  // Tabbing out of the value field triggers a ruleview-changed event that we need to wait
+  // for.
+  let onRuleViewChanged = once(ruleView, "ruleview-changed");
+  EventUtils.sendKey("tab", inspector.panelWin);
+  yield onRuleViewChanged;
+  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
+
+  info("Switching to the computed-view");
+  let onComputedViewReady = inspector.once("boxmodel-view-updated");
+  selectComputedView(inspector);
+  yield onComputedViewReady;
+
+  info("Testing the box-model region");
+  let margin = inspector.panelDoc.querySelector(".boxmodel-margin.boxmodel-top > span");
+  EventUtils.synthesizeMouseAtCenter(margin, {}, inspector.panelWin);
+  yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
+});
+
+function* checkTextBox(textBox, {textBoxContextMenuPopup}) {
+  is(textBoxContextMenuPopup.state, "closed", "The menu is closed");
+
+  info("Simulating context click on the textbox and expecting the menu to open");
+  let onContextMenu = once(textBoxContextMenuPopup, "popupshown");
+  EventUtils.synthesizeMouse(textBox, 2, 2, {type: "contextmenu", button: 2},
+                             textBox.ownerDocument.defaultView);
+  yield onContextMenu;
+
+  is(textBoxContextMenuPopup.state, "open", "The menu is now visible");
+
+  info("Closing the menu");
+  let onContextMenuHidden = once(textBoxContextMenuPopup, "popuphidden");
+  textBoxContextMenuPopup.hidePopup();
+  yield onContextMenuHidden;
+
+  is(textBoxContextMenuPopup.state, "closed", "The menu is closed again");
+}
--- a/devtools/client/shared/components/splitter/draggable.js
+++ b/devtools/client/shared/components/splitter/draggable.js
@@ -1,54 +1,54 @@
-/* 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/. */
-
-"use strict";
-
-const React = require("devtools/client/shared/vendor/react");
-const ReactDOM = require("devtools/client/shared/vendor/react-dom");
-const { DOM: dom, PropTypes } = React;
-
-const Draggable = React.createClass({
-  displayName: "Draggable",
-
-  propTypes: {
-    onMove: PropTypes.func.isRequired,
-    onStart: PropTypes.func,
-    onStop: PropTypes.func,
-    style: PropTypes.object,
-    className: PropTypes.string
-  },
-
-  startDragging(ev) {
-    ev.preventDefault();
-    const doc = ReactDOM.findDOMNode(this).ownerDocument;
-    doc.addEventListener("mousemove", this.onMove);
-    doc.addEventListener("mouseup", this.onUp);
-    this.props.onStart && this.props.onStart();
-  },
-
-  onMove(ev) {
-    ev.preventDefault();
-    // Use screen coordinates so, moving mouse over iframes
-    // doesn't mangle (relative) coordinates.
-    this.props.onMove(ev.screenX, ev.screenY);
-  },
-
-  onUp(ev) {
-    ev.preventDefault();
-    const doc = ReactDOM.findDOMNode(this).ownerDocument;
-    doc.removeEventListener("mousemove", this.onMove);
-    doc.removeEventListener("mouseup", this.onUp);
-    this.props.onStop && this.props.onStop();
-  },
-
-  render() {
-    return dom.div({
-      style: this.props.style,
-      className: this.props.className,
-      onMouseDown: this.startDragging
-    });
-  }
-});
-
-module.exports = Draggable;
+/* 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/. */
+
+"use strict";
+
+const React = require("devtools/client/shared/vendor/react");
+const ReactDOM = require("devtools/client/shared/vendor/react-dom");
+const { DOM: dom, PropTypes } = React;
+
+const Draggable = React.createClass({
+  displayName: "Draggable",
+
+  propTypes: {
+    onMove: PropTypes.func.isRequired,
+    onStart: PropTypes.func,
+    onStop: PropTypes.func,
+    style: PropTypes.object,
+    className: PropTypes.string
+  },
+
+  startDragging(ev) {
+    ev.preventDefault();
+    const doc = ReactDOM.findDOMNode(this).ownerDocument;
+    doc.addEventListener("mousemove", this.onMove);
+    doc.addEventListener("mouseup", this.onUp);
+    this.props.onStart && this.props.onStart();
+  },
+
+  onMove(ev) {
+    ev.preventDefault();
+    // Use screen coordinates so, moving mouse over iframes
+    // doesn't mangle (relative) coordinates.
+    this.props.onMove(ev.screenX, ev.screenY);
+  },
+
+  onUp(ev) {
+    ev.preventDefault();
+    const doc = ReactDOM.findDOMNode(this).ownerDocument;
+    doc.removeEventListener("mousemove", this.onMove);
+    doc.removeEventListener("mouseup", this.onUp);
+    this.props.onStop && this.props.onStop();
+  },
+
+  render() {
+    return dom.div({
+      style: this.props.style,
+      className: this.props.className,
+      onMouseDown: this.startDragging
+    });
+  }
+});
+
+module.exports = Draggable;
--- a/devtools/client/shared/components/splitter/split-box.js
+++ b/devtools/client/shared/components/splitter/split-box.js
@@ -1,207 +1,207 @@
-/* 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/. */
-
-"use strict";
-
-const React = require("devtools/client/shared/vendor/react");
-const ReactDOM = require("devtools/client/shared/vendor/react-dom");
-const Draggable = React.createFactory(require("devtools/client/shared/components/splitter/draggable"));
-const { DOM: dom, PropTypes } = React;
-
-/**
- * This component represents a Splitter. The splitter supports vertical
- * as well as horizontal mode.
- */
-const SplitBox = React.createClass({
-  displayName: "SplitBox",
-
-  propTypes: {
-    // Custom class name. You can use more names separated by a space.
-    className: PropTypes.string,
-    // Initial size of controlled panel.
-    initialSize: PropTypes.number,
-    // Left/top panel
-    startPanel: PropTypes.any,
-    // Min panel size.
-    minSize: PropTypes.number,
-    // Max panel size.
-    maxSize: PropTypes.number,
-    // Right/bottom panel
-    endPanel: PropTypes.any,
-    // True if the right/bottom panel should be controlled.
-    endPanelControl: PropTypes.bool,
-    // Size of the splitter handle bar.
-    splitterSize: PropTypes.number,
-    // True if the splitter bar is vertical (default is vertical).
-    vert: PropTypes.bool
-  },
-
-  getDefaultProps() {
-    return {
-      splitterSize: 5,
-      vert: true,
-      endPanelControl: false
-    };
-  },
-
-  /**
-   * The state stores the current orientation (vertical or horizontal)
-   * and the current size (width/height). All these values can change
-   * during the component's life time.
-   */
-  getInitialState() {
-    return {
-      vert: this.props.vert,
-      width: this.props.initialWidth || this.props.initialSize,
-      height: this.props.initialHeight || this.props.initialSize
-    };
-  },
-
-  // Dragging Events
-
-  /**
-   * Set 'resizing' cursor on entire document during splitter dragging.
-   * This avoids cursor-flickering that happens when the mouse leaves
-   * the splitter bar area (happens frequently).
-   */
-  onStartMove() {
-    const splitBox = ReactDOM.findDOMNode(this);
-    const doc = splitBox.ownerDocument;
-    let defaultCursor = doc.documentElement.style.cursor;
-    doc.documentElement.style.cursor = (this.state.vert ? "ew-resize" : "ns-resize");
-
-    splitBox.classList.add("dragging");
-
-    this.setState({
-      defaultCursor: defaultCursor
-    });
-  },
-
-  onStopMove() {
-    const splitBox = ReactDOM.findDOMNode(this);
-    const doc = splitBox.ownerDocument;
-    doc.documentElement.style.cursor = this.state.defaultCursor;
-
-    splitBox.classList.remove("dragging");
-  },
-
-  /**
-   * Adjust size of the controlled panel. Depending on the current
-   * orientation we either remember the width or height of
-   * the splitter box.
-   */
-  onMove(x, y) {
-    const node = ReactDOM.findDOMNode(this);
-    const doc = node.ownerDocument;
-    const win = doc.defaultView;
-
-    let size;
-    let { endPanelControl } = this.props;
-
-    if (this.state.vert) {
-      // Switch the control flag in case of RTL. Note that RTL
-      // has impact on vertical splitter only.
-      let dir = win.getComputedStyle(doc.documentElement).direction;
-      if (dir == "rtl") {
-        endPanelControl = !endPanelControl;
-      }
-
-      let innerOffset = x - win.mozInnerScreenX;
-      size = endPanelControl ?
-        (node.offsetLeft + node.offsetWidth) - innerOffset :
-        innerOffset - node.offsetLeft;
-
-      this.setState({
-        width: size
-      });
-    } else {
-      let innerOffset = y - win.mozInnerScreenY;
-      size = endPanelControl ?
-        (node.offsetTop + node.offsetHeight) - innerOffset :
-        innerOffset - node.offsetTop;
-
-      this.setState({
-        height: size
-      });
-    }
-  },
-
-  // Rendering
-
-  render() {
-    const vert = this.state.vert;
-    const { startPanel, endPanel, endPanelControl, minSize,
-      maxSize, splitterSize } = this.props;
-
-    let style = Object.assign({}, this.props.style);
-
-    // Calculate class names list.
-    let classNames = ["split-box"];
-    classNames.push(vert ? "vert" : "horz");
-    if (this.props.className) {
-      classNames = classNames.concat(this.props.className.split(" "));
-    }
-
-    let leftPanelStyle;
-    let rightPanelStyle;
-
-    // Set proper size for panels depending on the current state.
-    if (vert) {
-      leftPanelStyle = {
-        maxWidth: endPanelControl ? null : maxSize,
-        minWidth: endPanelControl ? null : minSize,
-        width: endPanelControl ? null : this.state.width
-      };
-      rightPanelStyle = {
-        maxWidth: endPanelControl ? maxSize : null,
-        minWidth: endPanelControl ? minSize : null,
-        width: endPanelControl ? this.state.width : null
-      };
-    } else {
-      leftPanelStyle = {
-        maxHeight: endPanelControl ? null : maxSize,
-        minHeight: endPanelControl ? null : minSize,
-        height: endPanelControl ? null : this.state.height
-      };
-      rightPanelStyle = {
-        maxHeight: endPanelControl ? maxSize : null,
-        minHeight: endPanelControl ? minSize : null,
-        height: endPanelControl ? this.state.height : null
-      };
-    }
-
-    // Calculate splitter size
-    let splitterStyle = {
-      flex: "0 0 " + splitterSize + "px"
-    };
-
-    return (
-      dom.div({
-        className: classNames.join(" "),
-        style: style },
-        startPanel ?
-          dom.div({
-            className: endPanelControl ? "uncontrolled" : "controlled",
-            style: leftPanelStyle},
-            startPanel
-          ) : null,
-        Draggable({
-          className: "splitter",
-          style: splitterStyle,
-          onStart: this.onStartMove,
-          onStop: this.onStopMove,
-          onMove: this.onMove
-        }),
-        endPanel ?
-          dom.div({
-            className: endPanelControl ? "controlled" : "uncontrolled",
-            style: rightPanelStyle},
-            endPanel
-          ) : null
-      )
-    );
-  }
-});
-
-module.exports = SplitBox;
+/* 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/. */
+
+"use strict";
+
+const React = require("devtools/client/shared/vendor/react");
+const ReactDOM = require("devtools/client/shared/vendor/react-dom");
+const Draggable = React.createFactory(require("devtools/client/shared/components/splitter/draggable"));
+const { DOM: dom, PropTypes } = React;
+
+/**
+ * This component represents a Splitter. The splitter supports vertical
+ * as well as horizontal mode.
+ */
+const SplitBox = React.createClass({
+  displayName: "SplitBox",
+
+  propTypes: {
+    // Custom class name. You can use more names separated by a space.
+    className: PropTypes.string,
+    // Initial size of controlled panel.
+    initialSize: PropTypes.number,
+    // Left/top panel
+    startPanel: PropTypes.any,
+    // Min panel size.
+    minSize: PropTypes.number,
+    // Max panel size.
+    maxSize: PropTypes.number,
+    // Right/bottom panel
+    endPanel: PropTypes.any,
+    // True if the right/bottom panel should be controlled.
+    endPanelControl: PropTypes.bool,
+    // Size of the splitter handle bar.
+    splitterSize: PropTypes.number,
+    // True if the splitter bar is vertical (default is vertical).
+    vert: PropTypes.bool
+  },
+
+  getDefaultProps() {
+    return {
+      splitterSize: 5,
+      vert: true,
+      endPanelControl: false
+    };
+  },
+
+  /**
+   * The state stores the current orientation (vertical or horizontal)
+   * and the current size (width/height). All these values can change
+   * during the component's life time.
+   */
+  getInitialState() {
+    return {
+      vert: this.props.vert,
+      width: this.props.initialWidth || this.props.initialSize,
+      height: this.props.initialHeight || this.props.initialSize
+    };
+  },
+
+  // Dragging Events
+
+  /**
+   * Set 'resizing' cursor on entire document during splitter dragging.
+   * This avoids cursor-flickering that happens when the mouse leaves
+   * the splitter bar area (happens frequently).
+   */
+  onStartMove() {
+    const splitBox = ReactDOM.findDOMNode(this);
+    const doc = splitBox.ownerDocument;
+    let defaultCursor = doc.documentElement.style.cursor;
+    doc.documentElement.style.cursor = (this.state.vert ? "ew-resize" : "ns-resize");
+
+    splitBox.classList.add("dragging");
+
+    this.setState({
+      defaultCursor: defaultCursor
+    });
+  },
+
+  onStopMove() {
+    const splitBox = ReactDOM.findDOMNode(this);
+    const doc = splitBox.ownerDocument;
+    doc.documentElement.style.cursor = this.state.defaultCursor;
+
+    splitBox.classList.remove("dragging");
+  },
+
+  /**
+   * Adjust size of the controlled panel. Depending on the current
+   * orientation we either remember the width or height of
+   * the splitter box.
+   */
+  onMove(x, y) {
+    const node = ReactDOM.findDOMNode(this);
+    const doc = node.ownerDocument;
+    const win = doc.defaultView;
+
+    let size;
+    let { endPanelControl } = this.props;
+
+    if (this.state.vert) {
+      // Switch the control flag in case of RTL. Note that RTL
+      // has impact on vertical splitter only.
+      let dir = win.getComputedStyle(doc.documentElement).direction;
+      if (dir == "rtl") {
+        endPanelControl = !endPanelControl;
+      }
+
+      let innerOffset = x - win.mozInnerScreenX;
+      size = endPanelControl ?
+        (node.offsetLeft + node.offsetWidth) - innerOffset :
+        innerOffset - node.offsetLeft;
+
+      this.setState({
+        width: size
+      });
+    } else {
+      let innerOffset = y - win.mozInnerScreenY;
+      size = endPanelControl ?
+        (node.offsetTop + node.offsetHeight) - innerOffset :
+        innerOffset - node.offsetTop;
+
+      this.setState({
+        height: size
+      });
+    }
+  },
+
+  // Rendering
+
+  render() {
+    const vert = this.state.vert;
+    const { startPanel, endPanel, endPanelControl, minSize,
+      maxSize, splitterSize } = this.props;
+
+    let style = Object.assign({}, this.props.style);
+
+    // Calculate class names list.
+    let classNames = ["split-box"];
+    classNames.push(vert ? "vert" : "horz");
+    if (this.props.className) {
+      classNames = classNames.concat(this.props.className.split(" "));
+    }
+
+    let leftPanelStyle;
+    let rightPanelStyle;
+
+    // Set proper size for panels depending on the current state.
+    if (vert) {
+      leftPanelStyle = {
+        maxWidth: endPanelControl ? null : maxSize,
+        minWidth: endPanelControl ? null : minSize,
+        width: endPanelControl ? null : this.state.width
+      };
+      rightPanelStyle = {
+        maxWidth: endPanelControl ? maxSize : null,
+        minWidth: endPanelControl ? minSize : null,
+        width: endPanelControl ? this.state.width : null
+      };
+    } else {
+      leftPanelStyle = {
+        maxHeight: endPanelControl ? null : maxSize,
+        minHeight: endPanelControl ? null : minSize,
+        height: endPanelControl ? null : this.state.height
+      };
+      rightPanelStyle = {
+        maxHeight: endPanelControl ? maxSize : null,
+        minHeight: endPanelControl ? minSize : null,
+        height: endPanelControl ? this.state.height : null
+      };
+    }
+
+    // Calculate splitter size
+    let splitterStyle = {
+      flex: "0 0 " + splitterSize + "px"
+    };
+
+    return (
+      dom.div({
+        className: classNames.join(" "),
+        style: style },
+        startPanel ?
+          dom.div({
+            className: endPanelControl ? "uncontrolled" : "controlled",
+            style: leftPanelStyle},
+            startPanel
+          ) : null,
+        Draggable({
+          className: "splitter",
+          style: splitterStyle,
+          onStart: this.onStartMove,
+          onStop: this.onStopMove,
+          onMove: this.onMove
+        }),
+        endPanel ?
+          dom.div({
+            className: endPanelControl ? "controlled" : "uncontrolled",
+            style: rightPanelStyle},
+            endPanel
+          ) : null
+      )
+    );
+  }
+});
+
+module.exports = SplitBox;