mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 16:58:38 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
1522
devtools/client/inspector/computed/computed.js
Normal file
1522
devtools/client/inspector/computed/computed.js
Normal file
File diff suppressed because it is too large
Load diff
11
devtools/client/inspector/computed/moz.build
Normal file
11
devtools/client/inspector/computed/moz.build
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'computed.js',
|
||||
)
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
6
devtools/client/inspector/computed/test/.eslintrc.js
Normal file
6
devtools/client/inspector/computed/test/.eslintrc.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the shared list of defined globals for mochitests.
|
||||
"extends": "../../../../.eslintrc.mochitests.js"
|
||||
};
|
||||
41
devtools/client/inspector/computed/test/browser.ini
Normal file
41
devtools/client/inspector/computed/test/browser.ini
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
doc_matched_selectors.html
|
||||
doc_media_queries.html
|
||||
doc_pseudoelement.html
|
||||
doc_sourcemaps.css
|
||||
doc_sourcemaps.css.map
|
||||
doc_sourcemaps.html
|
||||
doc_sourcemaps.scss
|
||||
head.js
|
||||
!/devtools/client/commandline/test/helpers.js
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
!/devtools/client/inspector/test/head.js
|
||||
!/devtools/client/inspector/test/shared-head.js
|
||||
!/devtools/client/shared/test/test-actor.js
|
||||
!/devtools/client/shared/test/test-actor-registry.js
|
||||
|
||||
[browser_computed_browser-styles.js]
|
||||
[browser_computed_cycle_color.js]
|
||||
[browser_computed_getNodeInfo.js]
|
||||
[browser_computed_keybindings_01.js]
|
||||
[browser_computed_keybindings_02.js]
|
||||
[browser_computed_matched-selectors-toggle.js]
|
||||
[browser_computed_matched-selectors_01.js]
|
||||
[browser_computed_matched-selectors_02.js]
|
||||
[browser_computed_media-queries.js]
|
||||
[browser_computed_no-results-placeholder.js]
|
||||
[browser_computed_original-source-link.js]
|
||||
[browser_computed_pseudo-element_01.js]
|
||||
[browser_computed_refresh-on-style-change_01.js]
|
||||
[browser_computed_search-filter.js]
|
||||
[browser_computed_search-filter_clear.js]
|
||||
[browser_computed_search-filter_context-menu.js]
|
||||
subsuite = clipboard
|
||||
[browser_computed_search-filter_escape-keypress.js]
|
||||
[browser_computed_search-filter_noproperties.js]
|
||||
[browser_computed_select-and-copy-styles.js]
|
||||
subsuite = clipboard
|
||||
[browser_computed_style-editor-link.js]
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* 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 that the checkbox to include browser styles works properly.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
.matches {
|
||||
color: #F00;
|
||||
}
|
||||
</style>
|
||||
<span id="matches" class="matches">Some styled text</span>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("#matches", inspector);
|
||||
|
||||
info("Checking the default styles");
|
||||
is(isPropertyVisible("color", view), true,
|
||||
"span #matches color property is visible");
|
||||
is(isPropertyVisible("background-color", view), false,
|
||||
"span #matches background-color property is hidden");
|
||||
|
||||
info("Toggling the browser styles");
|
||||
let doc = view.styleDocument;
|
||||
let checkbox = doc.querySelector(".includebrowserstyles");
|
||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
||||
checkbox.click();
|
||||
yield onRefreshed;
|
||||
|
||||
info("Checking the browser styles");
|
||||
is(isPropertyVisible("color", view), true,
|
||||
"span color property is visible");
|
||||
is(isPropertyVisible("background-color", view), true,
|
||||
"span background-color property is visible");
|
||||
});
|
||||
|
||||
function isPropertyVisible(name, view) {
|
||||
info("Checking property visibility for " + name);
|
||||
let propertyViews = view.propertyViews;
|
||||
for (let propView of propertyViews) {
|
||||
if (propView.name == name) {
|
||||
return propView.visible;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +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";
|
||||
|
||||
// Computed view color cycling test.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
.matches {
|
||||
color: #f00;
|
||||
}
|
||||
</style>
|
||||
<span id="matches" class="matches">Some styled text</span>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("#matches", inspector);
|
||||
|
||||
info("Checking the property itself");
|
||||
let container = getComputedViewPropertyView(view, "color").valueNode;
|
||||
checkColorCycling(container, view);
|
||||
|
||||
info("Checking matched selectors");
|
||||
container = yield getComputedViewMatchedRules(view, "color");
|
||||
yield checkColorCycling(container, view);
|
||||
});
|
||||
|
||||
function* checkColorCycling(container, view) {
|
||||
let valueNode = container.querySelector(".computedview-color");
|
||||
let win = view.styleWindow;
|
||||
|
||||
// "Authored" (default; currently the computed value)
|
||||
is(valueNode.textContent, "rgb(255, 0, 0)",
|
||||
"Color displayed as an RGB value.");
|
||||
|
||||
let tests = [{
|
||||
value: "red",
|
||||
comment: "Color displayed as a color name."
|
||||
}, {
|
||||
value: "#f00",
|
||||
comment: "Color displayed as an authored value."
|
||||
}, {
|
||||
value: "hsl(0, 100%, 50%)",
|
||||
comment: "Color displayed as an HSL value again."
|
||||
}, {
|
||||
value: "rgb(255, 0, 0)",
|
||||
comment: "Color displayed as an RGB value again."
|
||||
}];
|
||||
|
||||
for (let test of tests) {
|
||||
yield checkSwatchShiftClick(container, win, test.value, test.comment);
|
||||
}
|
||||
}
|
||||
|
||||
function* checkSwatchShiftClick(container, win, expectedValue, comment) {
|
||||
let swatch = container.querySelector(".computedview-colorswatch");
|
||||
let valueNode = container.querySelector(".computedview-color");
|
||||
swatch.scrollIntoView();
|
||||
|
||||
let onUnitChange = swatch.once("unit-change");
|
||||
EventUtils.synthesizeMouseAtCenter(swatch, {
|
||||
type: "mousedown",
|
||||
shiftKey: true
|
||||
}, win);
|
||||
yield onUnitChange;
|
||||
is(valueNode.textContent, expectedValue, comment);
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/* 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 various output of the computed-view's getNodeInfo method.
|
||||
// This method is used by the HighlightersOverlay and TooltipsOverlay on mouseover to
|
||||
// decide which highlighter or tooltip to show when hovering over a value/name/selector
|
||||
// if any.
|
||||
//
|
||||
// For instance, browser_ruleview_selector-highlighter_01.js and
|
||||
// browser_ruleview_selector-highlighter_02.js test that the selector
|
||||
// highlighter appear when hovering over a selector in the rule-view.
|
||||
// Since the code to make this work for the computed-view is 90% the same,
|
||||
// there is no need for testing it again here.
|
||||
// This test however serves as a unit test for getNodeInfo.
|
||||
|
||||
const {
|
||||
VIEW_NODE_SELECTOR_TYPE,
|
||||
VIEW_NODE_PROPERTY_TYPE,
|
||||
VIEW_NODE_VALUE_TYPE,
|
||||
VIEW_NODE_IMAGE_URL_TYPE
|
||||
} = require("devtools/client/inspector/shared/node-types");
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: red;
|
||||
color: white;
|
||||
}
|
||||
div {
|
||||
background: green;
|
||||
}
|
||||
div div {
|
||||
background-color: yellow;
|
||||
background-image: url(chrome://global/skin/icons/warning-64.png);
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<div><div id="testElement">Test element</div></div>
|
||||
`;
|
||||
|
||||
// Each item in this array must have the following properties:
|
||||
// - desc {String} will be logged for information
|
||||
// - getHoveredNode {Generator Function} received the computed-view instance as
|
||||
// argument and must return the node to be tested
|
||||
// - assertNodeInfo {Function} should check the validity of the nodeInfo
|
||||
// argument it receives
|
||||
const TEST_DATA = [
|
||||
{
|
||||
desc: "Testing a null node",
|
||||
getHoveredNode: function* () {
|
||||
return null;
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo, null);
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing a useless node",
|
||||
getHoveredNode: function* (view) {
|
||||
return view.element;
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo, null);
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing a property name",
|
||||
getHoveredNode: function* (view) {
|
||||
return getComputedViewProperty(view, "color").nameSpan;
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo.type, VIEW_NODE_PROPERTY_TYPE);
|
||||
ok("property" in nodeInfo.value);
|
||||
ok("value" in nodeInfo.value);
|
||||
is(nodeInfo.value.property, "color");
|
||||
is(nodeInfo.value.value, "rgb(255, 0, 0)");
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing a property value",
|
||||
getHoveredNode: function* (view) {
|
||||
return getComputedViewProperty(view, "color").valueSpan;
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo.type, VIEW_NODE_VALUE_TYPE);
|
||||
ok("property" in nodeInfo.value);
|
||||
ok("value" in nodeInfo.value);
|
||||
is(nodeInfo.value.property, "color");
|
||||
is(nodeInfo.value.value, "rgb(255, 0, 0)");
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing an image url",
|
||||
getHoveredNode: function* (view) {
|
||||
let {valueSpan} = getComputedViewProperty(view, "background-image");
|
||||
return valueSpan.querySelector(".theme-link");
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo.type, VIEW_NODE_IMAGE_URL_TYPE);
|
||||
ok("property" in nodeInfo.value);
|
||||
ok("value" in nodeInfo.value);
|
||||
is(nodeInfo.value.property, "background-image");
|
||||
is(nodeInfo.value.value,
|
||||
"url(\"chrome://global/skin/icons/warning-64.png\")");
|
||||
is(nodeInfo.value.url, "chrome://global/skin/icons/warning-64.png");
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing a matched rule selector (bestmatch)",
|
||||
getHoveredNode: function* (view) {
|
||||
let el = yield getComputedViewMatchedRules(view, "background-color");
|
||||
return el.querySelector(".bestmatch");
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo.type, VIEW_NODE_SELECTOR_TYPE);
|
||||
is(nodeInfo.value, "div div");
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing a matched rule selector (matched)",
|
||||
getHoveredNode: function* (view) {
|
||||
let el = yield getComputedViewMatchedRules(view, "background-color");
|
||||
return el.querySelector(".matched");
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo.type, VIEW_NODE_SELECTOR_TYPE);
|
||||
is(nodeInfo.value, "div");
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing a matched rule selector (parentmatch)",
|
||||
getHoveredNode: function* (view) {
|
||||
let el = yield getComputedViewMatchedRules(view, "color");
|
||||
return el.querySelector(".parentmatch");
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo.type, VIEW_NODE_SELECTOR_TYPE);
|
||||
is(nodeInfo.value, "body");
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing a matched rule value",
|
||||
getHoveredNode: function* (view) {
|
||||
let el = yield getComputedViewMatchedRules(view, "color");
|
||||
return el.querySelector(".other-property-value");
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo.type, VIEW_NODE_VALUE_TYPE);
|
||||
is(nodeInfo.value.property, "color");
|
||||
is(nodeInfo.value.value, "red");
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Testing a matched rule stylesheet link",
|
||||
getHoveredNode: function* (view) {
|
||||
let el = yield getComputedViewMatchedRules(view, "color");
|
||||
return el.querySelector(".rule-link .theme-link");
|
||||
},
|
||||
assertNodeInfo: function (nodeInfo) {
|
||||
is(nodeInfo, null);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("#testElement", inspector);
|
||||
|
||||
for (let {desc, getHoveredNode, assertNodeInfo} of TEST_DATA) {
|
||||
info(desc);
|
||||
let nodeInfo = view.getNodeInfo(yield getHoveredNode(view));
|
||||
assertNodeInfo(nodeInfo);
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/* 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 computed view key bindings.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
.matches {
|
||||
color: #F00;
|
||||
}
|
||||
</style>
|
||||
<span class="matches">Some styled text</span>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode(".matches", inspector);
|
||||
|
||||
let propView = getFirstVisiblePropertyView(view);
|
||||
let rulesTable = propView.matchedSelectorsContainer;
|
||||
let matchedExpander = propView.element;
|
||||
|
||||
info("Focusing the property");
|
||||
matchedExpander.scrollIntoView();
|
||||
let onMatchedExpanderFocus = once(matchedExpander, "focus", true);
|
||||
EventUtils.synthesizeMouseAtCenter(matchedExpander, {}, view.styleWindow);
|
||||
yield onMatchedExpanderFocus;
|
||||
|
||||
yield checkToggleKeyBinding(view.styleWindow, "VK_SPACE", rulesTable,
|
||||
inspector);
|
||||
yield checkToggleKeyBinding(view.styleWindow, "VK_RETURN", rulesTable,
|
||||
inspector);
|
||||
yield checkHelpLinkKeybinding(view);
|
||||
});
|
||||
|
||||
function getFirstVisiblePropertyView(view) {
|
||||
let propView = null;
|
||||
view.propertyViews.some(p => {
|
||||
if (p.visible) {
|
||||
propView = p;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return propView;
|
||||
}
|
||||
|
||||
function* checkToggleKeyBinding(win, key, rulesTable, inspector) {
|
||||
info("Pressing " + key + " key a couple of times to check that the " +
|
||||
"property gets expanded/collapsed");
|
||||
|
||||
let onExpand = inspector.once("computed-view-property-expanded");
|
||||
let onCollapse = inspector.once("computed-view-property-collapsed");
|
||||
|
||||
info("Expanding the property");
|
||||
EventUtils.synthesizeKey(key, {}, win);
|
||||
yield onExpand;
|
||||
isnot(rulesTable.innerHTML, "", "The property has been expanded");
|
||||
|
||||
info("Collapsing the property");
|
||||
EventUtils.synthesizeKey(key, {}, win);
|
||||
yield onCollapse;
|
||||
is(rulesTable.innerHTML, "", "The property has been collapsed");
|
||||
}
|
||||
|
||||
function checkHelpLinkKeybinding(view) {
|
||||
info("Check that MDN link is opened on \"F1\"");
|
||||
let def = defer();
|
||||
|
||||
let propView = getFirstVisiblePropertyView(view);
|
||||
propView.mdnLinkClick = function (event) {
|
||||
ok(true, "Pressing F1 opened the MDN link");
|
||||
def.resolve();
|
||||
};
|
||||
|
||||
EventUtils.synthesizeKey("VK_F1", {}, view.styleWindow);
|
||||
return def.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* 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 computed-view keyboard navigation.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
span {
|
||||
font-variant: small-caps;
|
||||
color: #000000;
|
||||
}
|
||||
.nomatches {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
<div id="first" style="margin: 10em;
|
||||
font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">
|
||||
<h1>Some header text</h1>
|
||||
<p id="salutation" style="font-size: 12pt">hi.</p>
|
||||
<p id="body" style="font-size: 12pt">I am a test-case. This text exists
|
||||
solely to provide some things to <span style="color: yellow">
|
||||
highlight</span> and <span style="font-weight: bold">count</span>
|
||||
style list-items in the box at right. If you are reading this,
|
||||
you should go do something else instead. Maybe read a book. Or better
|
||||
yet, write some test-cases for another bit of code.
|
||||
<span style="font-style: italic">some text</span></p>
|
||||
<p id="closing">more text</p>
|
||||
<p>even more text</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("span", inspector);
|
||||
|
||||
info("Selecting the first computed style in the list");
|
||||
let firstStyle = view.styleDocument.querySelector(".property-view");
|
||||
ok(firstStyle, "First computed style found in panel");
|
||||
firstStyle.focus();
|
||||
|
||||
info("Tab to select the 2nd style and press return");
|
||||
let onExpanded = inspector.once("computed-view-property-expanded");
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
yield onExpanded;
|
||||
|
||||
info("Verify the 2nd style has been expanded");
|
||||
let secondStyleSelectors = view.styleDocument.querySelectorAll(
|
||||
".property-content .matchedselectors")[1];
|
||||
ok(secondStyleSelectors.childNodes.length > 0, "Matched selectors expanded");
|
||||
|
||||
info("Tab back up and test the same thing, with space");
|
||||
onExpanded = inspector.once("computed-view-property-expanded");
|
||||
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
|
||||
EventUtils.synthesizeKey("VK_SPACE", {});
|
||||
yield onExpanded;
|
||||
|
||||
info("Verify the 1st style has been expanded too");
|
||||
let firstStyleSelectors = view.styleDocument.querySelectorAll(
|
||||
".property-content .matchedselectors")[0];
|
||||
ok(firstStyleSelectors.childNodes.length > 0, "Matched selectors expanded");
|
||||
});
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/* 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 that the computed view properties can be expanded and collapsed with
|
||||
// either the twisty or by dbl-clicking on the container.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css"> ,
|
||||
html { color: #000000; font-size: 15pt; }
|
||||
h1 { color: red; }
|
||||
</style>
|
||||
<h1>Some header text</h1>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("h1", inspector);
|
||||
|
||||
yield testExpandOnTwistyClick(view, inspector);
|
||||
yield testCollapseOnTwistyClick(view, inspector);
|
||||
yield testExpandOnDblClick(view, inspector);
|
||||
yield testCollapseOnDblClick(view, inspector);
|
||||
});
|
||||
|
||||
function* testExpandOnTwistyClick({styleDocument, styleWindow}, inspector) {
|
||||
info("Testing that a property expands on twisty click");
|
||||
|
||||
info("Getting twisty element");
|
||||
let twisty = styleDocument.querySelector("#propertyContainer .expandable");
|
||||
ok(twisty, "Twisty found");
|
||||
|
||||
let onExpand = inspector.once("computed-view-property-expanded");
|
||||
info("Clicking on the twisty element");
|
||||
twisty.click();
|
||||
|
||||
yield onExpand;
|
||||
|
||||
// Expanded means the matchedselectors div is not empty
|
||||
let div = styleDocument.querySelector(".property-content .matchedselectors");
|
||||
ok(div.childNodes.length > 0,
|
||||
"Matched selectors are expanded on twisty click");
|
||||
}
|
||||
|
||||
function* testCollapseOnTwistyClick({styleDocument, styleWindow}, inspector) {
|
||||
info("Testing that a property collapses on twisty click");
|
||||
|
||||
info("Getting twisty element");
|
||||
let twisty = styleDocument.querySelector("#propertyContainer .expandable");
|
||||
ok(twisty, "Twisty found");
|
||||
|
||||
let onCollapse = inspector.once("computed-view-property-collapsed");
|
||||
info("Clicking on the twisty element");
|
||||
twisty.click();
|
||||
|
||||
yield onCollapse;
|
||||
|
||||
// Collapsed means the matchedselectors div is empty
|
||||
let div = styleDocument.querySelector(".property-content .matchedselectors");
|
||||
ok(div.childNodes.length === 0,
|
||||
"Matched selectors are collapsed on twisty click");
|
||||
}
|
||||
|
||||
function* testExpandOnDblClick({styleDocument, styleWindow}, inspector) {
|
||||
info("Testing that a property expands on container dbl-click");
|
||||
|
||||
info("Getting computed property container");
|
||||
let container = styleDocument.querySelector(".property-view");
|
||||
ok(container, "Container found");
|
||||
|
||||
container.scrollIntoView();
|
||||
|
||||
let onExpand = inspector.once("computed-view-property-expanded");
|
||||
info("Dbl-clicking on the container");
|
||||
EventUtils.synthesizeMouseAtCenter(container, {clickCount: 2}, styleWindow);
|
||||
|
||||
yield onExpand;
|
||||
|
||||
// Expanded means the matchedselectors div is not empty
|
||||
let div = styleDocument.querySelector(".property-content .matchedselectors");
|
||||
ok(div.childNodes.length > 0, "Matched selectors are expanded on dblclick");
|
||||
}
|
||||
|
||||
function* testCollapseOnDblClick({styleDocument, styleWindow}, inspector) {
|
||||
info("Testing that a property collapses on container dbl-click");
|
||||
|
||||
info("Getting computed property container");
|
||||
let container = styleDocument.querySelector(".property-view");
|
||||
ok(container, "Container found");
|
||||
|
||||
let onCollapse = inspector.once("computed-view-property-collapsed");
|
||||
info("Dbl-clicking on the container");
|
||||
EventUtils.synthesizeMouseAtCenter(container, {clickCount: 2}, styleWindow);
|
||||
|
||||
yield onCollapse;
|
||||
|
||||
// Collapsed means the matchedselectors div is empty
|
||||
let div = styleDocument.querySelector(".property-content .matchedselectors");
|
||||
ok(div.childNodes.length === 0,
|
||||
"Matched selectors are collapsed on dblclick");
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* 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";
|
||||
|
||||
// Checking selector counts, matched rules and titles in the computed-view.
|
||||
|
||||
const {PropertyView} =
|
||||
require("devtools/client/inspector/computed/computed");
|
||||
const TEST_URI = URL_ROOT + "doc_matched_selectors.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab(TEST_URI);
|
||||
let {inspector, view} = yield openComputedView();
|
||||
|
||||
yield selectNode("#test", inspector);
|
||||
yield testMatchedSelectors(view, inspector);
|
||||
});
|
||||
|
||||
function* testMatchedSelectors(view, inspector) {
|
||||
info("checking selector counts, matched rules and titles");
|
||||
|
||||
let nodeFront = yield getNodeFront("#test", inspector);
|
||||
is(nodeFront, view._viewedElement,
|
||||
"style inspector node matches the selected node");
|
||||
|
||||
let propertyView = new PropertyView(view, "color");
|
||||
propertyView.buildMain();
|
||||
propertyView.buildSelectorContainer();
|
||||
propertyView.matchedExpanded = true;
|
||||
|
||||
yield propertyView.refreshMatchedSelectors();
|
||||
|
||||
let numMatchedSelectors = propertyView.matchedSelectors.length;
|
||||
is(numMatchedSelectors, 6,
|
||||
"CssLogic returns the correct number of matched selectors for div");
|
||||
is(propertyView.hasMatchedSelectors, true,
|
||||
"hasMatchedSelectors returns true");
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/* 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 for matched selector texts in the computed view.
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8,<div style='color:blue;'></div>");
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
info("Checking the color property view");
|
||||
let propertyView = getPropertyView(view, "color");
|
||||
ok(propertyView, "found PropertyView for color");
|
||||
is(propertyView.hasMatchedSelectors, true, "hasMatchedSelectors is true");
|
||||
|
||||
info("Expanding the matched selectors");
|
||||
propertyView.matchedExpanded = true;
|
||||
yield propertyView.refreshMatchedSelectors();
|
||||
|
||||
let span = propertyView.matchedSelectorsContainer
|
||||
.querySelector("span.rule-text");
|
||||
ok(span, "Found the first table row");
|
||||
|
||||
let selector = propertyView.matchedSelectorViews[0];
|
||||
ok(selector, "Found the first matched selector view");
|
||||
});
|
||||
|
||||
function getPropertyView(computedView, name) {
|
||||
let propertyView = null;
|
||||
computedView.propertyViews.some(function (view) {
|
||||
if (view.name == name) {
|
||||
propertyView = view;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return propertyView;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/* 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 that we correctly display appropriate media query titles in the
|
||||
// property view.
|
||||
|
||||
const TEST_URI = URL_ROOT + "doc_media_queries.html";
|
||||
|
||||
var {PropertyView} = require("devtools/client/inspector/computed/computed");
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab(TEST_URI);
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("div", inspector);
|
||||
yield checkPropertyView(view);
|
||||
});
|
||||
|
||||
function checkPropertyView(view) {
|
||||
let propertyView = new PropertyView(view, "width");
|
||||
propertyView.buildMain();
|
||||
propertyView.buildSelectorContainer();
|
||||
propertyView.matchedExpanded = true;
|
||||
|
||||
return propertyView.refreshMatchedSelectors().then(() => {
|
||||
let numMatchedSelectors = propertyView.matchedSelectors.length;
|
||||
|
||||
is(numMatchedSelectors, 2,
|
||||
"Property view has the correct number of matched selectors for div");
|
||||
|
||||
is(propertyView.hasMatchedSelectors, true,
|
||||
"hasMatchedSelectors returns true");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* 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 that the no results placeholder works properly.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
.matches {
|
||||
color: #F00;
|
||||
}
|
||||
</style>
|
||||
<span id="matches" class="matches">Some styled text</span>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("#matches", inspector);
|
||||
|
||||
yield enterInvalidFilter(inspector, view);
|
||||
checkNoResultsPlaceholderShown(view);
|
||||
|
||||
yield clearFilterText(inspector, view);
|
||||
checkNoResultsPlaceholderHidden(view);
|
||||
});
|
||||
|
||||
function* enterInvalidFilter(inspector, computedView) {
|
||||
let searchbar = computedView.searchField;
|
||||
let searchTerm = "xxxxx";
|
||||
|
||||
info("setting filter text to \"" + searchTerm + "\"");
|
||||
|
||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
||||
searchbar.focus();
|
||||
synthesizeKeys(searchTerm, computedView.styleWindow);
|
||||
yield onRefreshed;
|
||||
}
|
||||
|
||||
function checkNoResultsPlaceholderShown(computedView) {
|
||||
info("Checking that the no results placeholder is shown");
|
||||
|
||||
let placeholder = computedView.noResults;
|
||||
let win = computedView.styleWindow;
|
||||
let display = win.getComputedStyle(placeholder).display;
|
||||
is(display, "block", "placeholder is visible");
|
||||
}
|
||||
|
||||
function* clearFilterText(inspector, computedView) {
|
||||
info("Clearing the filter text");
|
||||
|
||||
let searchbar = computedView.searchField;
|
||||
|
||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
||||
searchbar.focus();
|
||||
searchbar.value = "";
|
||||
EventUtils.synthesizeKey("c", {}, computedView.styleWindow);
|
||||
yield onRefreshed;
|
||||
}
|
||||
|
||||
function checkNoResultsPlaceholderHidden(computedView) {
|
||||
info("Checking that the no results placeholder is hidden");
|
||||
|
||||
let placeholder = computedView.noResults;
|
||||
let win = computedView.styleWindow;
|
||||
let display = win.getComputedStyle(placeholder).display;
|
||||
is(display, "none", "placeholder is hidden");
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/* 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 that the computed view shows the original source link when source maps
|
||||
// are enabled.
|
||||
|
||||
const TESTCASE_URI = URL_ROOT_SSL + "doc_sourcemaps.html";
|
||||
const PREF = "devtools.styleeditor.source-maps-enabled";
|
||||
const SCSS_LOC = "doc_sourcemaps.scss:4";
|
||||
const CSS_LOC = "doc_sourcemaps.css:1";
|
||||
|
||||
add_task(function* () {
|
||||
info("Turning the pref " + PREF + " on");
|
||||
Services.prefs.setBoolPref(PREF, true);
|
||||
|
||||
yield addTab(TESTCASE_URI);
|
||||
let {toolbox, inspector, view} = yield openComputedView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
info("Expanding the first property");
|
||||
yield expandComputedViewPropertyByIndex(view, 0);
|
||||
|
||||
info("Verifying the link text");
|
||||
// Forcing a call to updateSourceLink on the SelectorView here. The
|
||||
// computed-view already does it, but we have no way of waiting for it to be
|
||||
// done here, so just call it again and wait for the returned promise to
|
||||
// resolve.
|
||||
let propertyView = getComputedViewPropertyView(view, "color");
|
||||
yield propertyView.matchedSelectorViews[0].updateSourceLink();
|
||||
verifyLinkText(view, SCSS_LOC);
|
||||
|
||||
info("Toggling the pref");
|
||||
let onLinksUpdated = inspector.once("computed-view-sourcelinks-updated");
|
||||
Services.prefs.setBoolPref(PREF, false);
|
||||
yield onLinksUpdated;
|
||||
|
||||
info("Verifying that the link text has changed after the pref change");
|
||||
yield verifyLinkText(view, CSS_LOC);
|
||||
|
||||
info("Toggling the pref again");
|
||||
onLinksUpdated = inspector.once("computed-view-sourcelinks-updated");
|
||||
Services.prefs.setBoolPref(PREF, true);
|
||||
yield onLinksUpdated;
|
||||
|
||||
info("Testing that clicking on the link works");
|
||||
yield testClickingLink(toolbox, view);
|
||||
|
||||
info("Turning the pref " + PREF + " off");
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
});
|
||||
|
||||
function* testClickingLink(toolbox, view) {
|
||||
let onEditor = waitForStyleEditor(toolbox, "doc_sourcemaps.scss");
|
||||
|
||||
info("Clicking the computedview stylesheet link");
|
||||
let link = getComputedViewLinkByIndex(view, 0);
|
||||
link.scrollIntoView();
|
||||
link.click();
|
||||
|
||||
let editor = yield onEditor;
|
||||
|
||||
let {line} = editor.sourceEditor.getCursor();
|
||||
is(line, 3, "cursor is at correct line number in original source");
|
||||
}
|
||||
|
||||
function verifyLinkText(view, text) {
|
||||
let link = getComputedViewLinkByIndex(view, 0);
|
||||
is(link.textContent, text,
|
||||
"Linked text changed to display the correct location");
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* 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 that pseudoelements are displayed correctly in the rule view.
|
||||
|
||||
const TEST_URI = URL_ROOT + "doc_pseudoelement.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab(TEST_URI);
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield testTopLeft(inspector, view);
|
||||
});
|
||||
|
||||
function* testTopLeft(inspector, view) {
|
||||
let node = yield getNodeFront("#topleft", inspector.markup);
|
||||
yield selectNode(node, inspector);
|
||||
let float = getComputedViewPropertyValue(view, "float");
|
||||
is(float, "left", "The computed view shows the correct float");
|
||||
|
||||
let children = yield inspector.markup.walker.children(node);
|
||||
is(children.nodes.length, 3, "Element has correct number of children");
|
||||
|
||||
let beforeElement = children.nodes[0];
|
||||
yield selectNode(beforeElement, inspector);
|
||||
let top = getComputedViewPropertyValue(view, "top");
|
||||
is(top, "0px", "The computed view shows the correct top");
|
||||
let left = getComputedViewPropertyValue(view, "left");
|
||||
is(left, "0px", "The computed view shows the correct left");
|
||||
|
||||
let afterElement = children.nodes[children.nodes.length - 1];
|
||||
yield selectNode(afterElement, inspector);
|
||||
top = getComputedViewPropertyValue(view, "top");
|
||||
is(top, "50%", "The computed view shows the correct top");
|
||||
left = getComputedViewPropertyValue(view, "left");
|
||||
is(left, "50%", "The computed view shows the correct left");
|
||||
}
|
||||
|
|
@ -0,0 +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 that the computed view refreshes when the current node has its style
|
||||
// changed.
|
||||
|
||||
const TEST_URI = "<div id='testdiv' style='font-size:10px;'>Test div!</div>";
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view, testActor} = yield openComputedView();
|
||||
yield selectNode("#testdiv", inspector);
|
||||
|
||||
let fontSize = getComputedViewPropertyValue(view, "font-size");
|
||||
is(fontSize, "10px", "The computed view shows the right font-size");
|
||||
|
||||
info("Changing the node's style and waiting for the update");
|
||||
let onUpdated = inspector.once("computed-view-refreshed");
|
||||
yield testActor.setAttribute("#testdiv", "style",
|
||||
"font-size: 15px; color: red;");
|
||||
yield onUpdated;
|
||||
|
||||
fontSize = getComputedViewPropertyValue(view, "font-size");
|
||||
is(fontSize, "15px", "The computed view shows the updated font-size");
|
||||
let color = getComputedViewPropertyValue(view, "color");
|
||||
is(color, "rgb(255, 0, 0)", "The computed view also shows the color now");
|
||||
});
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* 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 that the search filter works properly.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
.matches {
|
||||
color: #F00;
|
||||
}
|
||||
</style>
|
||||
<span id="matches" class="matches">Some styled text</span>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("#matches", inspector);
|
||||
yield testToggleDefaultStyles(inspector, view);
|
||||
yield testAddTextInFilter(inspector, view);
|
||||
});
|
||||
|
||||
function* testToggleDefaultStyles(inspector, computedView) {
|
||||
info("checking \"Browser styles\" checkbox");
|
||||
let checkbox = computedView.includeBrowserStylesCheckbox;
|
||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
||||
checkbox.click();
|
||||
yield onRefreshed;
|
||||
}
|
||||
|
||||
function* testAddTextInFilter(inspector, computedView) {
|
||||
info("setting filter text to \"color\"");
|
||||
let doc = computedView.styleDocument;
|
||||
let boxModelWrapper = doc.querySelector("#boxmodel-wrapper");
|
||||
let searchField = computedView.searchField;
|
||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
||||
let win = computedView.styleWindow;
|
||||
|
||||
// First check to make sure that accel + F doesn't focus search if the
|
||||
// container isn't focused
|
||||
inspector.panelWin.focus();
|
||||
EventUtils.synthesizeKey("f", { accelKey: true });
|
||||
isnot(inspector.panelDoc.activeElement, searchField,
|
||||
"Search field isn't focused");
|
||||
|
||||
computedView.element.focus();
|
||||
EventUtils.synthesizeKey("f", { accelKey: true });
|
||||
is(inspector.panelDoc.activeElement, searchField, "Search field is focused");
|
||||
|
||||
synthesizeKeys("color", win);
|
||||
yield onRefreshed;
|
||||
|
||||
ok(boxModelWrapper.hidden, "Box model is hidden");
|
||||
|
||||
info("check that the correct properties are visible");
|
||||
|
||||
let propertyViews = computedView.propertyViews;
|
||||
propertyViews.forEach(propView => {
|
||||
let name = propView.name;
|
||||
is(propView.visible, name.indexOf("color") > -1,
|
||||
"span " + name + " property visibility check");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +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";
|
||||
|
||||
// Tests that the search filter clear button works properly.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
.matches {
|
||||
color: #F00;
|
||||
background-color: #00F;
|
||||
border-color: #0F0;
|
||||
}
|
||||
</style>
|
||||
<span id="matches" class="matches">Some styled text</span>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("#matches", inspector);
|
||||
yield testAddTextInFilter(inspector, view);
|
||||
yield testClearSearchFilter(inspector, view);
|
||||
});
|
||||
|
||||
function* testAddTextInFilter(inspector, computedView) {
|
||||
info("Setting filter text to \"background-color\"");
|
||||
|
||||
let win = computedView.styleWindow;
|
||||
let propertyViews = computedView.propertyViews;
|
||||
let searchField = computedView.searchField;
|
||||
|
||||
searchField.focus();
|
||||
synthesizeKeys("background-color", win);
|
||||
yield inspector.once("computed-view-refreshed");
|
||||
|
||||
info("Check that the correct properties are visible");
|
||||
|
||||
propertyViews.forEach((propView) => {
|
||||
let name = propView.name;
|
||||
is(propView.visible, name.indexOf("background-color") > -1,
|
||||
"span " + name + " property visibility check");
|
||||
});
|
||||
}
|
||||
|
||||
function* testClearSearchFilter(inspector, computedView) {
|
||||
info("Clearing the search filter");
|
||||
|
||||
let win = computedView.styleWindow;
|
||||
let doc = computedView.styleDocument;
|
||||
let boxModelWrapper = doc.querySelector("#boxmodel-wrapper");
|
||||
let propertyViews = computedView.propertyViews;
|
||||
let searchField = computedView.searchField;
|
||||
let searchClearButton = computedView.searchClearButton;
|
||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(searchClearButton, {}, win);
|
||||
yield onRefreshed;
|
||||
|
||||
ok(!boxModelWrapper.hidden, "Box model is displayed");
|
||||
|
||||
info("Check that the correct properties are visible");
|
||||
|
||||
ok(!searchField.value, "Search filter is cleared");
|
||||
propertyViews.forEach((propView) => {
|
||||
is(propView.visible, propView.hasMatchedSelectors,
|
||||
"span " + propView.name + " property visibility check");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/* 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 computed view search filter context menu works properly.
|
||||
|
||||
const TEST_INPUT = "h1";
|
||||
|
||||
const TEST_URI = "<h1>test filter context menu</h1>";
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {toolbox, inspector, view} = yield openComputedView();
|
||||
yield selectNode("h1", inspector);
|
||||
|
||||
let win = view.styleWindow;
|
||||
let searchField = view.searchField;
|
||||
let searchContextMenu = toolbox.textBoxContextMenuPopup;
|
||||
ok(searchContextMenu,
|
||||
"The search filter context menu is loaded in the computed view");
|
||||
|
||||
let cmdUndo = searchContextMenu.querySelector("[command=cmd_undo]");
|
||||
let cmdDelete = searchContextMenu.querySelector("[command=cmd_delete]");
|
||||
let cmdSelectAll = searchContextMenu.querySelector("[command=cmd_selectAll]");
|
||||
let cmdCut = searchContextMenu.querySelector("[command=cmd_cut]");
|
||||
let cmdCopy = searchContextMenu.querySelector("[command=cmd_copy]");
|
||||
let cmdPaste = searchContextMenu.querySelector("[command=cmd_paste]");
|
||||
|
||||
info("Opening context menu");
|
||||
|
||||
emptyClipboard();
|
||||
|
||||
let onFocus = once(searchField, "focus");
|
||||
searchField.focus();
|
||||
yield onFocus;
|
||||
|
||||
let onContextMenuPopup = once(searchContextMenu, "popupshowing");
|
||||
EventUtils.synthesizeMouse(searchField, 2, 2,
|
||||
{type: "contextmenu", button: 2}, win);
|
||||
yield onContextMenuPopup;
|
||||
|
||||
is(cmdUndo.getAttribute("disabled"), "true", "cmdUndo is disabled");
|
||||
is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
|
||||
is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
|
||||
|
||||
// Cut/Copy items are enabled in context menu even if there
|
||||
// is no selection. See also Bug 1303033
|
||||
is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
|
||||
is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
|
||||
|
||||
if (isWindows()) {
|
||||
// emptyClipboard only works on Windows (666254), assert paste only for this OS.
|
||||
is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
|
||||
}
|
||||
|
||||
info("Closing context menu");
|
||||
let onContextMenuHidden = once(searchContextMenu, "popuphidden");
|
||||
searchContextMenu.hidePopup();
|
||||
yield onContextMenuHidden;
|
||||
|
||||
info("Copy text in search field using the context menu");
|
||||
searchField.value = TEST_INPUT;
|
||||
searchField.select();
|
||||
EventUtils.synthesizeMouse(searchField, 2, 2,
|
||||
{type: "contextmenu", button: 2}, win);
|
||||
yield onContextMenuPopup;
|
||||
yield waitForClipboardPromise(() => cmdCopy.click(), TEST_INPUT);
|
||||
searchContextMenu.hidePopup();
|
||||
yield onContextMenuHidden;
|
||||
|
||||
info("Reopen context menu and check command properties");
|
||||
EventUtils.synthesizeMouse(searchField, 2, 2,
|
||||
{type: "contextmenu", button: 2}, win);
|
||||
yield onContextMenuPopup;
|
||||
|
||||
is(cmdUndo.getAttribute("disabled"), "", "cmdUndo is enabled");
|
||||
is(cmdDelete.getAttribute("disabled"), "", "cmdDelete is enabled");
|
||||
is(cmdSelectAll.getAttribute("disabled"), "", "cmdSelectAll is enabled");
|
||||
is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
|
||||
is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
|
||||
is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
|
||||
});
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* 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";
|
||||
|
||||
// Avoid test timeouts on Linux debug builds where the test takes just a bit too long to
|
||||
// run (see bug 1258081).
|
||||
requestLongerTimeout(2);
|
||||
|
||||
// Tests that search filter escape keypress will clear the search field.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
.matches {
|
||||
color: #F00;
|
||||
}
|
||||
</style>
|
||||
<span id="matches" class="matches">Some styled text</span>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("#matches", inspector);
|
||||
yield testAddTextInFilter(inspector, view);
|
||||
yield testEscapeKeypress(inspector, view);
|
||||
});
|
||||
|
||||
function* testAddTextInFilter(inspector, computedView) {
|
||||
info("Setting filter text to \"background-color\"");
|
||||
|
||||
let win = computedView.styleWindow;
|
||||
let propertyViews = computedView.propertyViews;
|
||||
let searchField = computedView.searchField;
|
||||
let checkbox = computedView.includeBrowserStylesCheckbox;
|
||||
|
||||
info("Include browser styles");
|
||||
checkbox.click();
|
||||
yield inspector.once("computed-view-refreshed");
|
||||
|
||||
searchField.focus();
|
||||
synthesizeKeys("background-color", win);
|
||||
yield inspector.once("computed-view-refreshed");
|
||||
|
||||
info("Check that the correct properties are visible");
|
||||
|
||||
propertyViews.forEach((propView) => {
|
||||
let name = propView.name;
|
||||
is(propView.visible, name.indexOf("background-color") > -1,
|
||||
"span " + name + " property visibility check");
|
||||
});
|
||||
}
|
||||
|
||||
function* testEscapeKeypress(inspector, computedView) {
|
||||
info("Pressing the escape key on search filter");
|
||||
|
||||
let win = computedView.styleWindow;
|
||||
let propertyViews = computedView.propertyViews;
|
||||
let searchField = computedView.searchField;
|
||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
||||
|
||||
searchField.focus();
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, win);
|
||||
yield onRefreshed;
|
||||
|
||||
info("Check that the correct properties are visible");
|
||||
|
||||
ok(!searchField.value, "Search filter is cleared");
|
||||
propertyViews.forEach((propView) => {
|
||||
let name = propView.name;
|
||||
is(propView.visible, true,
|
||||
"span " + name + " property is visible");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* 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 that the "no-results" message is displayed when selecting an invalid element or
|
||||
// when all properties have been filtered out.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
.matches {
|
||||
color: #F00;
|
||||
background-color: #00F;
|
||||
border-color: #0F0;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<!-- comment node -->
|
||||
<span id="matches" class="matches">Some styled text</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
let propertyViews = view.propertyViews;
|
||||
|
||||
info("Select the #matches node");
|
||||
let matchesNode = yield getNodeFront("#matches", inspector);
|
||||
let onRefresh = inspector.once("computed-view-refreshed");
|
||||
yield selectNode(matchesNode, inspector);
|
||||
yield onRefresh;
|
||||
|
||||
ok(propertyViews.filter(p => p.visible).length > 0, "CSS properties are displayed");
|
||||
ok(view.noResults.hasAttribute("hidden"), "no-results message is hidden");
|
||||
|
||||
info("Select a comment node");
|
||||
let commentNode = yield inspector.walker.previousSibling(matchesNode);
|
||||
yield selectNode(commentNode, inspector);
|
||||
|
||||
is(propertyViews.filter(p => p.visible).length, 0, "No properties displayed");
|
||||
ok(!view.noResults.hasAttribute("hidden"), "no-results message is displayed");
|
||||
|
||||
info("Select the #matches node again");
|
||||
onRefresh = inspector.once("computed-view-refreshed");
|
||||
yield selectNode(matchesNode, inspector);
|
||||
yield onRefresh;
|
||||
|
||||
ok(propertyViews.filter(p => p.visible).length > 0, "CSS properties are displayed");
|
||||
ok(view.noResults.hasAttribute("hidden"), "no-results message is hidden");
|
||||
|
||||
info("Filter by 'will-not-match' and check the no-results message is displayed");
|
||||
let searchField = view.searchField;
|
||||
searchField.focus();
|
||||
synthesizeKeys("will-not-match", view.styleWindow);
|
||||
yield inspector.once("computed-view-refreshed");
|
||||
|
||||
is(propertyViews.filter(p => p.visible).length, 0, "No properties displayed");
|
||||
ok(!view.noResults.hasAttribute("hidden"), "no-results message is displayed");
|
||||
});
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/* 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 that properties can be selected and copied from the computed view.
|
||||
|
||||
const osString = Services.appinfo.OS;
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
span {
|
||||
font-variant-caps: small-caps;
|
||||
color: #000000;
|
||||
}
|
||||
.nomatches {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
<div id="first" style="margin: 10em;
|
||||
font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">
|
||||
<h1>Some header text</h1>
|
||||
<p id="salutation" style="font-size: 12pt">hi.</p>
|
||||
<p id="body" style="font-size: 12pt">I am a test-case. This text exists
|
||||
solely to provide some things to <span style="color: yellow">
|
||||
highlight</span> and <span style="font-weight: bold">count</span>
|
||||
style list-items in the box at right. If you are reading this,
|
||||
you should go do something else instead. Maybe read a book. Or better
|
||||
yet, write some test-cases for another bit of code.
|
||||
<span style="font-style: italic">some text</span></p>
|
||||
<p id="closing">more text</p>
|
||||
<p>even more text</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("span", inspector);
|
||||
yield checkCopySelection(view);
|
||||
yield checkSelectAll(view);
|
||||
});
|
||||
|
||||
function* checkCopySelection(view) {
|
||||
info("Testing selection copy");
|
||||
|
||||
let contentDocument = view.styleDocument;
|
||||
let props = contentDocument.querySelectorAll(".property-view");
|
||||
ok(props, "captain, we have the property-view nodes");
|
||||
|
||||
let range = contentDocument.createRange();
|
||||
range.setStart(props[1], 0);
|
||||
range.setEnd(props[3], 2);
|
||||
contentDocument.defaultView.getSelection().addRange(range);
|
||||
|
||||
info("Checking that cssHtmlTree.siBoundCopy() returns the correct " +
|
||||
"clipboard value");
|
||||
|
||||
let expectedPattern = "font-family: helvetica,sans-serif;[\\r\\n]+" +
|
||||
"font-size: 16px;[\\r\\n]+" +
|
||||
"font-variant-caps: small-caps;[\\r\\n]*";
|
||||
|
||||
try {
|
||||
yield waitForClipboardPromise(() => fireCopyEvent(props[0]),
|
||||
() => checkClipboardData(expectedPattern));
|
||||
} catch (e) {
|
||||
failedClipboard(expectedPattern);
|
||||
}
|
||||
}
|
||||
|
||||
function* checkSelectAll(view) {
|
||||
info("Testing select-all copy");
|
||||
|
||||
let contentDoc = view.styleDocument;
|
||||
let prop = contentDoc.querySelector(".property-view");
|
||||
|
||||
info("Checking that _onSelectAll() then copy returns the correct " +
|
||||
"clipboard value");
|
||||
view._contextmenu._onSelectAll();
|
||||
let expectedPattern = "color: rgb\\(255, 255, 0\\);[\\r\\n]+" +
|
||||
"font-family: helvetica,sans-serif;[\\r\\n]+" +
|
||||
"font-size: 16px;[\\r\\n]+" +
|
||||
"font-variant-caps: small-caps;[\\r\\n]*";
|
||||
|
||||
try {
|
||||
yield waitForClipboardPromise(() => fireCopyEvent(prop),
|
||||
() => checkClipboardData(expectedPattern));
|
||||
} catch (e) {
|
||||
failedClipboard(expectedPattern);
|
||||
}
|
||||
}
|
||||
|
||||
function checkClipboardData(expectedPattern) {
|
||||
let actual = SpecialPowers.getClipboardData("text/unicode");
|
||||
let expectedRegExp = new RegExp(expectedPattern, "g");
|
||||
return expectedRegExp.test(actual);
|
||||
}
|
||||
|
||||
function failedClipboard(expectedPattern) {
|
||||
// Format expected text for comparison
|
||||
let terminator = osString == "WINNT" ? "\r\n" : "\n";
|
||||
expectedPattern = expectedPattern.replace(/\[\\r\\n\][+*]/g, terminator);
|
||||
expectedPattern = expectedPattern.replace(/\\\(/g, "(");
|
||||
expectedPattern = expectedPattern.replace(/\\\)/g, ")");
|
||||
|
||||
let actual = SpecialPowers.getClipboardData("text/unicode");
|
||||
|
||||
// Trim the right hand side of our strings. This is because expectedPattern
|
||||
// accounts for windows sometimes adding a newline to our copied data.
|
||||
expectedPattern = expectedPattern.trimRight();
|
||||
actual = actual.trimRight();
|
||||
|
||||
dump("TEST-UNEXPECTED-FAIL | Clipboard text does not match expected ... " +
|
||||
"results (escaped for accurate comparison):\n");
|
||||
info("Actual: " + escape(actual));
|
||||
info("Expected: " + escape(expectedPattern));
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/* 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";
|
||||
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Unknown sheet source");
|
||||
|
||||
// Tests the links from the computed view to the style editor.
|
||||
|
||||
const STYLESHEET_URL = "data:text/css," + encodeURIComponent(
|
||||
".highlight {color: blue}");
|
||||
|
||||
const DOCUMENT_URL = "data:text/html;charset=utf-8," + encodeURIComponent(
|
||||
`<html>
|
||||
<head>
|
||||
<title>Computed view style editor link test</title>
|
||||
<style type="text/css">
|
||||
html { color: #000000; }
|
||||
span { font-variant: small-caps; color: #000000; }
|
||||
.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em;
|
||||
font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">
|
||||
</style>
|
||||
<style>
|
||||
div { color: #f06; }
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="${STYLESHEET_URL}">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Some header text</h1>
|
||||
<p id="salutation" style="font-size: 12pt">hi.</p>
|
||||
<p id="body" style="font-size: 12pt">I am a test-case. This text exists
|
||||
solely to provide some things to
|
||||
<span style="color: yellow" class="highlight">
|
||||
highlight</span> and <span style="font-weight: bold">count</span>
|
||||
style list-items in the box at right. If you are reading this,
|
||||
you should go do something else instead. Maybe read a book. Or better
|
||||
yet, write some test-cases for another bit of code.
|
||||
<span style="font-style: italic">some text</span></p>
|
||||
<p id="closing">more text</p>
|
||||
<p>even more text</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>`);
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab(DOCUMENT_URL);
|
||||
let {toolbox, inspector, view, testActor} = yield openComputedView();
|
||||
yield selectNode("span", inspector);
|
||||
|
||||
yield testInlineStyle(view);
|
||||
yield testFirstInlineStyleSheet(view, toolbox, testActor);
|
||||
yield testSecondInlineStyleSheet(view, toolbox, testActor);
|
||||
yield testExternalStyleSheet(view, toolbox, testActor);
|
||||
});
|
||||
|
||||
function* testInlineStyle(view) {
|
||||
info("Testing inline style");
|
||||
|
||||
yield expandComputedViewPropertyByIndex(view, 0);
|
||||
|
||||
let onTab = waitForTab();
|
||||
info("Clicking on the first rule-link in the computed-view");
|
||||
clickLinkByIndex(view, 0);
|
||||
|
||||
let tab = yield onTab;
|
||||
|
||||
let tabURI = tab.linkedBrowser.documentURI.spec;
|
||||
ok(tabURI.startsWith("view-source:"), "View source tab is open");
|
||||
info("Closing tab");
|
||||
gBrowser.removeTab(tab);
|
||||
}
|
||||
|
||||
function* testFirstInlineStyleSheet(view, toolbox, testActor) {
|
||||
info("Testing inline stylesheet");
|
||||
|
||||
info("Listening for toolbox switch to the styleeditor");
|
||||
let onSwitch = waitForStyleEditor(toolbox);
|
||||
|
||||
info("Clicking an inline stylesheet");
|
||||
clickLinkByIndex(view, 2);
|
||||
let editor = yield onSwitch;
|
||||
|
||||
ok(true, "Switched to the style-editor panel in the toolbox");
|
||||
|
||||
yield validateStyleEditorSheet(editor, 0, testActor);
|
||||
}
|
||||
|
||||
function* testSecondInlineStyleSheet(view, toolbox, testActor) {
|
||||
info("Testing second inline stylesheet");
|
||||
|
||||
info("Waiting for the stylesheet editor to be selected");
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
let onSelected = panel.UI.once("editor-selected");
|
||||
|
||||
info("Switching back to the inspector panel in the toolbox");
|
||||
yield toolbox.selectTool("inspector");
|
||||
|
||||
info("Clicking on second inline stylesheet link");
|
||||
clickLinkByIndex(view, 4);
|
||||
let editor = yield onSelected;
|
||||
|
||||
is(toolbox.currentToolId, "styleeditor",
|
||||
"The style editor is selected again");
|
||||
yield validateStyleEditorSheet(editor, 1, testActor);
|
||||
}
|
||||
|
||||
function* testExternalStyleSheet(view, toolbox, testActor) {
|
||||
info("Testing external stylesheet");
|
||||
|
||||
info("Waiting for the stylesheet editor to be selected");
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
let onSelected = panel.UI.once("editor-selected");
|
||||
|
||||
info("Switching back to the inspector panel in the toolbox");
|
||||
yield toolbox.selectTool("inspector");
|
||||
|
||||
info("Clicking on an external stylesheet link");
|
||||
clickLinkByIndex(view, 1);
|
||||
let editor = yield onSelected;
|
||||
|
||||
is(toolbox.currentToolId, "styleeditor",
|
||||
"The style editor is selected again");
|
||||
yield validateStyleEditorSheet(editor, 2, testActor);
|
||||
}
|
||||
|
||||
function* validateStyleEditorSheet(editor, expectedSheetIndex, testActor) {
|
||||
info("Validating style editor stylesheet");
|
||||
let expectedHref = yield testActor.eval(`
|
||||
document.styleSheets[${expectedSheetIndex}].href;
|
||||
`);
|
||||
is(editor.styleSheet.href, expectedHref,
|
||||
"loaded stylesheet matches document stylesheet");
|
||||
}
|
||||
|
||||
function clickLinkByIndex(view, index) {
|
||||
let link = getComputedViewLinkByIndex(view, index);
|
||||
link.scrollIntoView();
|
||||
link.click();
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.matched1, .matched2, .matched3, .matched4, .matched5 {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
div {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 20px;
|
||||
border: 1px solid #000;
|
||||
color: #111;
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
inspectstyle($("test"));
|
||||
<div id="test" class="matched1 matched2 matched3 matched4 matched5">Test div</div>
|
||||
<div id="dummy">
|
||||
<div></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>test</title>
|
||||
<style>
|
||||
div {
|
||||
width: 1000px;
|
||||
height: 100px;
|
||||
background-color: #f00;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1px) {
|
||||
div {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
||||
131
devtools/client/inspector/computed/test/doc_pseudoelement.html
Normal file
131
devtools/client/inspector/computed/test/doc_pseudoelement.html
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.box {
|
||||
float:left;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
background: #ddd;
|
||||
padding: 32px;
|
||||
margin: 32px;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.box:first-line {
|
||||
color: orange;
|
||||
background: red;
|
||||
}
|
||||
|
||||
.box:first-letter {
|
||||
color: green;
|
||||
}
|
||||
|
||||
* {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
nothing {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
p::-moz-selection {
|
||||
color: white;
|
||||
background: black;
|
||||
}
|
||||
p::selection {
|
||||
color: white;
|
||||
background: black;
|
||||
}
|
||||
|
||||
p:first-line {
|
||||
background: blue;
|
||||
}
|
||||
p:first-letter {
|
||||
color: red;
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
.box:before {
|
||||
background: green;
|
||||
content: " ";
|
||||
position: absolute;
|
||||
height:32px;
|
||||
width:32px;
|
||||
}
|
||||
|
||||
.box:after {
|
||||
background: red;
|
||||
content: " ";
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
height:32px;
|
||||
width:32px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -16px;
|
||||
margin-left: -16px;
|
||||
}
|
||||
|
||||
.topleft:before {
|
||||
top:0;
|
||||
left:0;
|
||||
}
|
||||
|
||||
.topleft:first-line {
|
||||
color: orange;
|
||||
}
|
||||
.topleft::selection {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.topright:before {
|
||||
top:0;
|
||||
right:0;
|
||||
}
|
||||
|
||||
.bottomright:before {
|
||||
bottom:10px;
|
||||
right:10px;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.bottomright:before {
|
||||
bottom:0;
|
||||
right:0;
|
||||
}
|
||||
|
||||
.bottomleft:before {
|
||||
bottom:0;
|
||||
left:0;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ruleview pseudoelement($("test"));</h1>
|
||||
|
||||
<div id="topleft" class="box topleft">
|
||||
<p>Top Left<br />Position</p>
|
||||
</div>
|
||||
|
||||
<div id="topright" class="box topright">
|
||||
<p>Top Right<br />Position</p>
|
||||
</div>
|
||||
|
||||
<div id="bottomright" class="box bottomright">
|
||||
<p>Bottom Right<br />Position</p>
|
||||
</div>
|
||||
|
||||
<div id="bottomleft" class="box bottomleft">
|
||||
<p>Bottom Left<br />Position</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
div {
|
||||
color: #ff0066; }
|
||||
|
||||
span {
|
||||
background-color: #EEE; }
|
||||
|
||||
/*# sourceMappingURL=doc_sourcemaps.css.map */
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"version": 3,
|
||||
"mappings": "AAGA,GAAI;EACF,KAAK,EAHU,OAAI;;AAMrB,IAAK;EACH,gBAAgB,EAAE,IAAI",
|
||||
"sources": ["doc_sourcemaps.scss"],
|
||||
"names": [],
|
||||
"file": "doc_sourcemaps.css"
|
||||
}
|
||||
11
devtools/client/inspector/computed/test/doc_sourcemaps.html
Normal file
11
devtools/client/inspector/computed/test/doc_sourcemaps.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>testcase for testing CSS source maps</title>
|
||||
<link rel="stylesheet" type="text/css" href="simple.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="doc_sourcemaps.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div>source maps <span>testcase</span></div>
|
||||
</body>
|
||||
</html>
|
||||
10
devtools/client/inspector/computed/test/doc_sourcemaps.scss
Normal file
10
devtools/client/inspector/computed/test/doc_sourcemaps.scss
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
$paulrougetpink: #f06;
|
||||
|
||||
div {
|
||||
color: $paulrougetpink;
|
||||
}
|
||||
|
||||
span {
|
||||
background-color: #EEE;
|
||||
}
|
||||
157
devtools/client/inspector/computed/test/head.js
Normal file
157
devtools/client/inspector/computed/test/head.js
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/* 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/ */
|
||||
/* eslint no-unused-vars: [2, {"vars": "local"}] */
|
||||
/* import-globals-from ../../test/head.js */
|
||||
"use strict";
|
||||
|
||||
// Import the inspector's head.js first (which itself imports shared-head.js).
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
|
||||
this);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.defaultColorUnit");
|
||||
});
|
||||
|
||||
/**
|
||||
* Dispatch the copy event on the given element
|
||||
*/
|
||||
function fireCopyEvent(element) {
|
||||
let evt = element.ownerDocument.createEvent("Event");
|
||||
evt.initEvent("copy", true, true);
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get references to the name and value span nodes corresponding to a given
|
||||
* property name in the computed-view
|
||||
*
|
||||
* @param {CssComputedView} view
|
||||
* The instance of the computed view panel
|
||||
* @param {String} name
|
||||
* The name of the property to retrieve
|
||||
* @return an object {nameSpan, valueSpan}
|
||||
*/
|
||||
function getComputedViewProperty(view, name) {
|
||||
let prop;
|
||||
for (let property of view.styleDocument.querySelectorAll(".property-view")) {
|
||||
let nameSpan = property.querySelector(".property-name");
|
||||
let valueSpan = property.querySelector(".property-value");
|
||||
|
||||
if (nameSpan.textContent === name) {
|
||||
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||
break;
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of PropertyView from the computed-view.
|
||||
*
|
||||
* @param {CssComputedView} view
|
||||
* The instance of the computed view panel
|
||||
* @param {String} name
|
||||
* The name of the property to retrieve
|
||||
* @return {PropertyView}
|
||||
*/
|
||||
function getComputedViewPropertyView(view, name) {
|
||||
let propView;
|
||||
for (let propertyView of view.propertyViews) {
|
||||
if (propertyView._propertyInfo.name === name) {
|
||||
propView = propertyView;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return propView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the property-content element for a given property name in
|
||||
* the computed-view.
|
||||
* A property-content element always follows (nextSibling) the property itself
|
||||
* and is only shown when the twisty icon is expanded on the property.
|
||||
* A property-content element contains matched rules, with selectors,
|
||||
* properties, values and stylesheet links
|
||||
*
|
||||
* @param {CssComputedView} view
|
||||
* The instance of the computed view panel
|
||||
* @param {String} name
|
||||
* The name of the property to retrieve
|
||||
* @return {Promise} A promise that resolves to the property matched rules
|
||||
* container
|
||||
*/
|
||||
var getComputedViewMatchedRules = Task.async(function* (view, name) {
|
||||
let expander;
|
||||
let propertyContent;
|
||||
for (let property of view.styleDocument.querySelectorAll(".property-view")) {
|
||||
let nameSpan = property.querySelector(".property-name");
|
||||
if (nameSpan.textContent === name) {
|
||||
expander = property.querySelector(".expandable");
|
||||
propertyContent = property.nextSibling;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!expander.hasAttribute("open")) {
|
||||
// Need to expand the property
|
||||
let onExpand = view.inspector.once("computed-view-property-expanded");
|
||||
expander.click();
|
||||
yield onExpand;
|
||||
}
|
||||
|
||||
return propertyContent;
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the text value of the property corresponding to a given name in the
|
||||
* computed-view
|
||||
*
|
||||
* @param {CssComputedView} view
|
||||
* The instance of the computed view panel
|
||||
* @param {String} name
|
||||
* The name of the property to retrieve
|
||||
* @return {String} The property value
|
||||
*/
|
||||
function getComputedViewPropertyValue(view, name, propertyName) {
|
||||
return getComputedViewProperty(view, name, propertyName)
|
||||
.valueSpan.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand a given property, given its index in the current property list of
|
||||
* the computed view
|
||||
*
|
||||
* @param {CssComputedView} view
|
||||
* The instance of the computed view panel
|
||||
* @param {Number} index
|
||||
* The index of the property to be expanded
|
||||
* @return a promise that resolves when the property has been expanded, or
|
||||
* rejects if the property was not found
|
||||
*/
|
||||
function expandComputedViewPropertyByIndex(view, index) {
|
||||
info("Expanding property " + index + " in the computed view");
|
||||
let expandos = view.styleDocument.querySelectorAll("#propertyContainer .expandable");
|
||||
if (!expandos.length || !expandos[index]) {
|
||||
return promise.reject();
|
||||
}
|
||||
|
||||
let onExpand = view.inspector.once("computed-view-property-expanded");
|
||||
expandos[index].click();
|
||||
return onExpand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a rule-link from the computed-view given its index
|
||||
*
|
||||
* @param {CssComputedView} view
|
||||
* The instance of the computed view panel
|
||||
* @param {Number} index
|
||||
* The index of the link to be retrieved
|
||||
* @return {DOMNode} The link at the given index, if one exists, null otherwise
|
||||
*/
|
||||
function getComputedViewLinkByIndex(view, index) {
|
||||
let links = view.styleDocument.querySelectorAll(".rule-link .link");
|
||||
return links[index];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue