зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1327675 - Correctly hightlight nodes for inherited rules. r=pbro
--HG-- extra : rebase_source : 1df369d9b5e07beaf9d66d017122f1f76afd9faf
This commit is contained in:
Родитель
89c63a086b
Коммит
ae30e668fa
|
@ -212,6 +212,7 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
|
|||
[browser_rules_selector-highlighter_02.js]
|
||||
[browser_rules_selector-highlighter_03.js]
|
||||
[browser_rules_selector-highlighter_04.js]
|
||||
[browser_rules_selector-highlighter_05.js]
|
||||
[browser_rules_selector_highlight.js]
|
||||
[browser_rules_strict-search-filter-computed-list_01.js]
|
||||
[browser_rules_strict-search-filter_01.js]
|
||||
|
|
|
@ -22,6 +22,7 @@ add_task(function* () {
|
|||
|
||||
let testActor = yield getTestActorWithoutToolbox(tab);
|
||||
let inspector = yield clickOnInspectMenuItem(testActor, "span");
|
||||
yield getRuleViewSelectorHighlighterIcon(inspector.ruleview.view, "element", 3);
|
||||
|
||||
checkRuleViewContent(inspector.ruleview.view);
|
||||
});
|
||||
|
|
|
@ -33,7 +33,7 @@ function* testSelectorHighlight(view, name) {
|
|||
info("Test creating selector highlighter");
|
||||
|
||||
info("Clicking on a selector icon");
|
||||
let icon = getRuleViewSelectorHighlighterIcon(view, name);
|
||||
let icon = yield getRuleViewSelectorHighlighterIcon(view, name);
|
||||
|
||||
let onToggled = view.once("ruleview-selectorhighlighter-toggled");
|
||||
EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
|
||||
|
|
|
@ -18,6 +18,7 @@ add_task(function* () {
|
|||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openRuleView();
|
||||
yield selectNode("#test1", inspector);
|
||||
yield getRuleViewSelectorHighlighterIcon(view, "element", 1);
|
||||
yield elementStyleInherit(inspector, view);
|
||||
});
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ add_task(function* () {
|
|||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openRuleView();
|
||||
yield selectNode("a", inspector);
|
||||
yield getRuleViewSelectorHighlighterIcon(view, "element", 2);
|
||||
yield elementStyleInherit(inspector, view);
|
||||
});
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ add_task(function* () {
|
|||
let highlighters = view.highlighters;
|
||||
|
||||
info("Clicking on a selector icon");
|
||||
let icon = getRuleViewSelectorHighlighterIcon(view, "body, p, td");
|
||||
let icon = yield getRuleViewSelectorHighlighterIcon(view, "body, p, td");
|
||||
|
||||
let onToggled = view.once("ruleview-selectorhighlighter-toggled");
|
||||
EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
|
||||
|
|
|
@ -24,7 +24,7 @@ add_task(function* () {
|
|||
"No selectorhighlighter exist in the rule-view");
|
||||
|
||||
info("Clicking on a selector icon");
|
||||
let icon = getRuleViewSelectorHighlighterIcon(view, "body, p, td");
|
||||
let icon = yield getRuleViewSelectorHighlighterIcon(view, "body, p, td");
|
||||
|
||||
let onToggled = view.once("ruleview-selectorhighlighter-toggled");
|
||||
EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
|
||||
|
|
|
@ -46,7 +46,7 @@ add_task(function* () {
|
|||
// Inject the mock highlighter in the rule-view
|
||||
view.selectorHighlighter = HighlighterFront;
|
||||
|
||||
let icon = getRuleViewSelectorHighlighterIcon(view, "body");
|
||||
let icon = yield getRuleViewSelectorHighlighterIcon(view, "body");
|
||||
|
||||
info("Checking that the HighlighterFront's show/hide methods are called");
|
||||
|
||||
|
@ -60,7 +60,7 @@ add_task(function* () {
|
|||
|
||||
info("Checking that the right NodeFront reference and options are passed");
|
||||
yield selectNode("p", inspector);
|
||||
icon = getRuleViewSelectorHighlighterIcon(view, "p");
|
||||
icon = yield getRuleViewSelectorHighlighterIcon(view, "p");
|
||||
|
||||
yield clickSelectorIcon(icon, view);
|
||||
is(HighlighterFront.nodeFront.tagName, "P",
|
||||
|
@ -69,7 +69,7 @@ add_task(function* () {
|
|||
"The right selector option is passed to the highlighter (1)");
|
||||
|
||||
yield selectNode("body", inspector);
|
||||
icon = getRuleViewSelectorHighlighterIcon(view, "body");
|
||||
icon = yield getRuleViewSelectorHighlighterIcon(view, "body");
|
||||
yield clickSelectorIcon(icon, view);
|
||||
is(HighlighterFront.nodeFront.tagName, "BODY",
|
||||
"The right NodeFront is passed to the highlighter (2)");
|
||||
|
|
|
@ -39,7 +39,7 @@ add_task(function* () {
|
|||
|
||||
info("Select .node-1 and click on the .node-1 selector icon");
|
||||
yield selectNode(".node-1", inspector);
|
||||
let icon = getRuleViewSelectorHighlighterIcon(view, ".node-1");
|
||||
let icon = yield getRuleViewSelectorHighlighterIcon(view, ".node-1");
|
||||
yield clickSelectorIcon(icon, view);
|
||||
ok(HighlighterFront.isShown, "The highlighter is shown");
|
||||
|
||||
|
@ -48,12 +48,12 @@ add_task(function* () {
|
|||
ok(!HighlighterFront.isShown, "The highlighter is now hidden");
|
||||
|
||||
info("With .node-1 still selected, click on the div selector icon");
|
||||
icon = getRuleViewSelectorHighlighterIcon(view, "div");
|
||||
icon = yield getRuleViewSelectorHighlighterIcon(view, "div");
|
||||
yield clickSelectorIcon(icon, view);
|
||||
ok(HighlighterFront.isShown, "The highlighter is shown again");
|
||||
|
||||
info("With .node-1 still selected, click again on the .node-1 selector icon");
|
||||
icon = getRuleViewSelectorHighlighterIcon(view, ".node-1");
|
||||
icon = yield getRuleViewSelectorHighlighterIcon(view, ".node-1");
|
||||
yield clickSelectorIcon(icon, view);
|
||||
ok(HighlighterFront.isShown,
|
||||
"The highlighter is shown again since the clicked selector was different");
|
||||
|
@ -64,14 +64,14 @@ add_task(function* () {
|
|||
"The highlighter is still shown after selection");
|
||||
|
||||
info("With .node-2 selected, click on the div selector icon");
|
||||
icon = getRuleViewSelectorHighlighterIcon(view, "div");
|
||||
icon = yield getRuleViewSelectorHighlighterIcon(view, "div");
|
||||
yield clickSelectorIcon(icon, view);
|
||||
ok(HighlighterFront.isShown,
|
||||
"The highlighter is shown still since the selected was different");
|
||||
|
||||
info("Switching back to .node-1 and clicking on the div selector");
|
||||
yield selectNode(".node-1", inspector);
|
||||
icon = getRuleViewSelectorHighlighterIcon(view, "div");
|
||||
icon = yield getRuleViewSelectorHighlighterIcon(view, "div");
|
||||
yield clickSelectorIcon(icon, view);
|
||||
ok(!HighlighterFront.isShown,
|
||||
"The highlighter is hidden now that the same selector was clicked");
|
||||
|
|
|
@ -39,7 +39,7 @@ add_task(function* () {
|
|||
|
||||
info("Checking that the right NodeFront reference and options are passed");
|
||||
yield selectNode("p", inspector);
|
||||
let icon = getRuleViewSelectorHighlighterIcon(view, "element");
|
||||
let icon = yield getRuleViewSelectorHighlighterIcon(view, "element");
|
||||
|
||||
yield clickSelectorIcon(icon, view);
|
||||
is(HighlighterFront.nodeFront.tagName, "P",
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* 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 selector highlighter is correctly shown when clicking on a
|
||||
// inherited element
|
||||
|
||||
// Note that in this test, we mock the highlighter front, merely testing the
|
||||
// behavior of the style-inspector UI for now
|
||||
|
||||
const TEST_URI = `
|
||||
<div style="cursor:pointer">
|
||||
A
|
||||
<div style="cursor:pointer">
|
||||
B<a>Cursor</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openRuleView();
|
||||
|
||||
// Mock the highlighter front to get the reference of the NodeFront
|
||||
let HighlighterFront = {
|
||||
isShown: false,
|
||||
nodeFront: null,
|
||||
options: null,
|
||||
show: function (nodeFront, options) {
|
||||
this.nodeFront = nodeFront;
|
||||
this.options = options;
|
||||
this.isShown = true;
|
||||
},
|
||||
hide: function () {
|
||||
this.nodeFront = null;
|
||||
this.options = null;
|
||||
this.isShown = false;
|
||||
}
|
||||
};
|
||||
// Inject the mock highlighter in the rule-view
|
||||
view.selectorHighlighter = HighlighterFront;
|
||||
|
||||
info("Checking that the right NodeFront reference and options are passed");
|
||||
yield selectNode("a", inspector);
|
||||
|
||||
let icon = yield getRuleViewSelectorHighlighterIcon(view, "element");
|
||||
yield clickSelectorIcon(icon, view);
|
||||
is(HighlighterFront.options.selector,
|
||||
"body > div:nth-child(1) > div:nth-child(1) > a:nth-child(1)",
|
||||
"The right selector option is passed to the highlighter (1)");
|
||||
|
||||
icon = yield getRuleViewSelectorHighlighterIcon(view, "element", 1);
|
||||
yield clickSelectorIcon(icon, view);
|
||||
is(HighlighterFront.options.selector, "body > div:nth-child(1) > div:nth-child(1)",
|
||||
"The right selector option is passed to the highlighter (1)");
|
||||
|
||||
icon = yield getRuleViewSelectorHighlighterIcon(view, "element", 2);
|
||||
yield clickSelectorIcon(icon, view);
|
||||
is(HighlighterFront.options.selector, "body > div:nth-child(1)",
|
||||
"The right selector option is passed to the highlighter (1)");
|
||||
});
|
|
@ -44,76 +44,6 @@ addTab = function (url) {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Wait for a content -> chrome message on the message manager (the window
|
||||
* messagemanager is used).
|
||||
*
|
||||
* @param {String} name
|
||||
* The message name
|
||||
* @return {Promise} A promise that resolves to the response data when the
|
||||
* message has been received
|
||||
*/
|
||||
function waitForContentMessage(name) {
|
||||
info("Expecting message " + name + " from content");
|
||||
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
let def = defer();
|
||||
mm.addMessageListener(name, function onMessage(msg) {
|
||||
mm.removeMessageListener(name, onMessage);
|
||||
def.resolve(msg.data);
|
||||
});
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script (chrome -> content) and wait for a
|
||||
* response message with the same name (content -> chrome).
|
||||
*
|
||||
* @param {String} name
|
||||
* The message name. Should be one of the messages defined
|
||||
* in doc_frame_script.js
|
||||
* @param {Object} data
|
||||
* Optional data to send along
|
||||
* @param {Object} objects
|
||||
* Optional CPOW objects to send along
|
||||
* @param {Boolean} expectResponse
|
||||
* If set to false, don't wait for a response with the same name
|
||||
* from the content script. Defaults to true.
|
||||
* @return {Promise} Resolves to the response data if a response is expected,
|
||||
* immediately resolves otherwise
|
||||
*/
|
||||
function executeInContent(name, data = {}, objects = {},
|
||||
expectResponse = true) {
|
||||
info("Sending message " + name + " to content");
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
mm.sendAsyncMessage(name, data, objects);
|
||||
if (expectResponse) {
|
||||
return waitForContentMessage(name);
|
||||
}
|
||||
|
||||
return promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script and get back the requested
|
||||
* computed style property.
|
||||
*
|
||||
* @param {String} selector
|
||||
* The selector used to obtain the element.
|
||||
* @param {String} pseudo
|
||||
* pseudo id to query, or null.
|
||||
* @param {String} name
|
||||
* name of the property.
|
||||
*/
|
||||
function* getComputedStyleProperty(selector, pseudo, propName) {
|
||||
return yield executeInContent("Test:GetComputedStylePropertyValue",
|
||||
{selector,
|
||||
pseudo,
|
||||
name: propName});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an element's inline style property value.
|
||||
* @param {TestActor} testActor
|
||||
|
@ -129,49 +59,6 @@ function getStyle(testActor, selector, propName) {
|
|||
`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script and wait until the requested
|
||||
* computed style property has the expected value.
|
||||
*
|
||||
* @param {String} selector
|
||||
* The selector used to obtain the element.
|
||||
* @param {String} pseudo
|
||||
* pseudo id to query, or null.
|
||||
* @param {String} prop
|
||||
* name of the property.
|
||||
* @param {String} expected
|
||||
* expected value of property
|
||||
* @param {String} name
|
||||
* the name used in test message
|
||||
*/
|
||||
function* waitForComputedStyleProperty(selector, pseudo, name, expected) {
|
||||
return yield executeInContent("Test:WaitForComputedStylePropertyValue",
|
||||
{selector,
|
||||
pseudo,
|
||||
expected,
|
||||
name});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an inplace editable element, click to switch it to edit mode, wait for
|
||||
* focus
|
||||
*
|
||||
* @return a promise that resolves to the inplace-editor element when ready
|
||||
*/
|
||||
var focusEditableField = Task.async(function* (ruleView, editable, xOffset = 1,
|
||||
yOffset = 1, options = {}) {
|
||||
let onFocus = once(editable.parentNode, "focus", true);
|
||||
info("Clicking on editable field to turn to edit mode");
|
||||
EventUtils.synthesizeMouse(editable, xOffset, yOffset, options,
|
||||
editable.ownerDocument.defaultView);
|
||||
yield onFocus;
|
||||
|
||||
info("Editable field gained focus, returning the input field now");
|
||||
let onEdit = inplaceEditor(editable.ownerDocument.activeElement);
|
||||
|
||||
return onEdit;
|
||||
});
|
||||
|
||||
/**
|
||||
* When a tooltip is closed, this ends up "commiting" the value changed within
|
||||
* the tooltip (e.g. the color in case of a colorpicker) which, in turn, ends up
|
||||
|
@ -219,109 +106,6 @@ var waitForSuccess = Task.async(function* (validatorFn, desc = "untitled") {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the DOMNode for a css rule in the rule-view that corresponds to the given
|
||||
* selector
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view for which the rule
|
||||
* object is wanted
|
||||
* @return {DOMNode}
|
||||
*/
|
||||
function getRuleViewRule(view, selectorText) {
|
||||
let rule;
|
||||
for (let r of view.styleDocument.querySelectorAll(".ruleview-rule")) {
|
||||
let selector = r.querySelector(".ruleview-selectorcontainer, " +
|
||||
".ruleview-selector-matched");
|
||||
if (selector && selector.textContent === selectorText) {
|
||||
rule = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get references to the name and value span nodes corresponding to a given
|
||||
* selector and property name in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for the property in
|
||||
* @param {String} propertyName
|
||||
* The name of the property
|
||||
* @return {Object} An object like {nameSpan: DOMNode, valueSpan: DOMNode}
|
||||
*/
|
||||
function getRuleViewProperty(view, selectorText, propertyName) {
|
||||
let prop;
|
||||
|
||||
let rule = getRuleViewRule(view, selectorText);
|
||||
if (rule) {
|
||||
// Look for the propertyName in that rule element
|
||||
for (let p of rule.querySelectorAll(".ruleview-property")) {
|
||||
let nameSpan = p.querySelector(".ruleview-propertyname");
|
||||
let valueSpan = p.querySelector(".ruleview-propertyvalue");
|
||||
|
||||
if (nameSpan.textContent === propertyName) {
|
||||
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value of the property corresponding to a given selector and name
|
||||
* in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for the property in
|
||||
* @param {String} propertyName
|
||||
* The name of the property
|
||||
* @return {String} The property value
|
||||
*/
|
||||
function getRuleViewPropertyValue(view, selectorText, propertyName) {
|
||||
return getRuleViewProperty(view, selectorText, propertyName)
|
||||
.valueSpan.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the selector DOM element corresponding to a given selector
|
||||
* in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for
|
||||
* @return {DOMNode} The selector DOM element
|
||||
*/
|
||||
function getRuleViewSelector(view, selectorText) {
|
||||
let rule = getRuleViewRule(view, selectorText);
|
||||
return rule.querySelector(".ruleview-selector, .ruleview-selector-matched");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the selectorhighlighter icon DOM element corresponding to
|
||||
* a given selector in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for
|
||||
* @return {DOMNode} The selectorhighlighter icon DOM element
|
||||
*/
|
||||
function getRuleViewSelectorHighlighterIcon(view, selectorText) {
|
||||
let rule = getRuleViewRule(view, selectorText);
|
||||
return rule.querySelector(".ruleview-selectorhighlighter");
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate a color change in a given color picker tooltip, and optionally wait
|
||||
* for a given element in the page to have its style changed as a result.
|
||||
|
@ -452,34 +236,6 @@ var openCubicBezierAndChangeCoords = Task.async(function* (view, ruleIndex,
|
|||
return {propEditor, swatch, bezierTooltip};
|
||||
});
|
||||
|
||||
/**
|
||||
* Get a rule-link from the rule-view given its index
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {Number} index
|
||||
* The index of the link to get
|
||||
* @return {DOMNode} The link if any at this index
|
||||
*/
|
||||
function getRuleViewLinkByIndex(view, index) {
|
||||
let links = view.styleDocument.querySelectorAll(".ruleview-rule-source");
|
||||
return links[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rule-link text from the rule-view given its index
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {Number} index
|
||||
* The index of the link to get
|
||||
* @return {String} The string at this index
|
||||
*/
|
||||
function getRuleViewLinkTextByIndex(view, index) {
|
||||
let link = getRuleViewLinkByIndex(view, index);
|
||||
return link.querySelector(".ruleview-rule-source-label").textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate adding a new property in an existing rule in the rule-view.
|
||||
*
|
||||
|
@ -625,74 +381,6 @@ var togglePropStatus = Task.async(function* (view, textProp) {
|
|||
yield onRuleViewRefreshed;
|
||||
});
|
||||
|
||||
/**
|
||||
* Click on a rule-view's close brace to focus a new property name editor
|
||||
*
|
||||
* @param {RuleEditor} ruleEditor
|
||||
* An instance of RuleEditor that will receive the new property
|
||||
* @return a promise that resolves to the newly created editor when ready and
|
||||
* focused
|
||||
*/
|
||||
var focusNewRuleViewProperty = Task.async(function* (ruleEditor) {
|
||||
info("Clicking on a close ruleEditor brace to start editing a new property");
|
||||
|
||||
// Use bottom alignment to avoid scrolling out of the parent element area.
|
||||
ruleEditor.closeBrace.scrollIntoView(false);
|
||||
let editor = yield focusEditableField(ruleEditor.ruleView,
|
||||
ruleEditor.closeBrace);
|
||||
|
||||
is(inplaceEditor(ruleEditor.newPropSpan), editor,
|
||||
"Focused editor is the new property editor.");
|
||||
|
||||
return editor;
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a new property name in the rule-view, focusing a new property editor
|
||||
* by clicking on the close brace, and then entering the given text.
|
||||
* Keep in mind that the rule-view knows how to handle strings with multiple
|
||||
* properties, so the input text may be like: "p1:v1;p2:v2;p3:v3".
|
||||
*
|
||||
* @param {RuleEditor} ruleEditor
|
||||
* The instance of RuleEditor that will receive the new property(ies)
|
||||
* @param {String} inputValue
|
||||
* The text to be entered in the new property name field
|
||||
* @return a promise that resolves when the new property name has been entered
|
||||
* and once the value field is focused
|
||||
*/
|
||||
var createNewRuleViewProperty = Task.async(function* (ruleEditor, inputValue) {
|
||||
info("Creating a new property editor");
|
||||
let editor = yield focusNewRuleViewProperty(ruleEditor);
|
||||
|
||||
info("Entering the value " + inputValue);
|
||||
editor.input.value = inputValue;
|
||||
|
||||
info("Submitting the new value and waiting for value field focus");
|
||||
let onFocus = once(ruleEditor.element, "focus", true);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {},
|
||||
ruleEditor.element.ownerDocument.defaultView);
|
||||
yield onFocus;
|
||||
});
|
||||
|
||||
/**
|
||||
* Set the search value for the rule-view filter styles search box.
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} searchValue
|
||||
* The filter search value
|
||||
* @return a promise that resolves when the rule-view is filtered for the
|
||||
* search term
|
||||
*/
|
||||
var setSearchFilter = Task.async(function* (view, searchValue) {
|
||||
info("Setting filter text to \"" + searchValue + "\"");
|
||||
let win = view.styleWindow;
|
||||
let searchField = view.searchField;
|
||||
searchField.focus();
|
||||
synthesizeKeys(searchValue, win);
|
||||
yield view.inspector.once("ruleview-filtered");
|
||||
});
|
||||
|
||||
/**
|
||||
* Reload the current page and wait for the inspector to be initialized after
|
||||
* the navigation
|
||||
|
@ -778,26 +466,6 @@ function* sendKeysAndWaitForFocus(view, element, keys) {
|
|||
yield onFocus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the style editor context menu and return all of it's items in a flat array
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @return An array of MenuItems
|
||||
*/
|
||||
function openStyleContextMenuAndGetAllItems(view, target) {
|
||||
let menu = view._contextmenu._openMenu({target: target});
|
||||
|
||||
// Flatten all menu items into a single array to make searching through it easier
|
||||
let allItems = [].concat.apply([], menu.items.map(function addItem(item) {
|
||||
if (item.submenu) {
|
||||
return addItem(item.submenu.items);
|
||||
}
|
||||
return item;
|
||||
}));
|
||||
|
||||
return allItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for a markupmutation event on the inspector that is for a style modification.
|
||||
* @param {InspectorPanel} inspector
|
||||
|
|
|
@ -149,9 +149,20 @@ RuleEditor.prototype = {
|
|||
}
|
||||
|
||||
if (this.rule.domRule.type !== CSSRule.KEYFRAME_RULE) {
|
||||
let selector = this.rule.domRule.selectors
|
||||
? this.rule.domRule.selectors.join(", ")
|
||||
: this.ruleView.inspector.selectionCssSelector;
|
||||
Task.spawn(function* () {
|
||||
let selector;
|
||||
|
||||
if (this.rule.domRule.selectors) {
|
||||
// This is a "normal" rule with a selector.
|
||||
selector = this.rule.domRule.selectors.join(", ");
|
||||
} else if (this.rule.inherited) {
|
||||
// This is an inline style from an inherited rule. Need to resolve the unique
|
||||
// selector from the node which rule this is inherited from.
|
||||
selector = yield this.rule.inherited.getUniqueSelector();
|
||||
} else {
|
||||
// This is an inline style from the current node.
|
||||
selector = this.ruleView.inspector.selectionCssSelector;
|
||||
}
|
||||
|
||||
let selectorHighlighter = createChild(header, "span", {
|
||||
class: "ruleview-selectorhighlighter" +
|
||||
|
@ -162,6 +173,10 @@ RuleEditor.prototype = {
|
|||
selectorHighlighter.addEventListener("click", () => {
|
||||
this.ruleView.toggleSelectorHighlighter(selectorHighlighter, selector);
|
||||
});
|
||||
|
||||
this.uniqueSelector = selector;
|
||||
this.emit("selector-icon-created");
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
this.openBrace = createChild(header, "span", {
|
||||
|
|
|
@ -88,123 +88,6 @@ addTab = function (url) {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Wait for a content -> chrome message on the message manager (the window
|
||||
* messagemanager is used).
|
||||
*
|
||||
* @param {String} name
|
||||
* The message name
|
||||
* @return {Promise} A promise that resolves to the response data when the
|
||||
* message has been received
|
||||
*/
|
||||
function waitForContentMessage(name) {
|
||||
info("Expecting message " + name + " from content");
|
||||
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
let def = defer();
|
||||
mm.addMessageListener(name, function onMessage(msg) {
|
||||
mm.removeMessageListener(name, onMessage);
|
||||
def.resolve(msg.data);
|
||||
});
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script (chrome -> content) and wait for a
|
||||
* response message with the same name (content -> chrome).
|
||||
*
|
||||
* @param {String} name
|
||||
* The message name. Should be one of the messages defined
|
||||
* in doc_frame_script.js
|
||||
* @param {Object} data
|
||||
* Optional data to send along
|
||||
* @param {Object} objects
|
||||
* Optional CPOW objects to send along
|
||||
* @param {Boolean} expectResponse
|
||||
* If set to false, don't wait for a response with the same name
|
||||
* from the content script. Defaults to true.
|
||||
* @return {Promise} Resolves to the response data if a response is expected,
|
||||
* immediately resolves otherwise
|
||||
*/
|
||||
function executeInContent(name, data = {}, objects = {},
|
||||
expectResponse = true) {
|
||||
info("Sending message " + name + " to content");
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
mm.sendAsyncMessage(name, data, objects);
|
||||
if (expectResponse) {
|
||||
return waitForContentMessage(name);
|
||||
}
|
||||
|
||||
return promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script and get back the requested
|
||||
* computed style property.
|
||||
*
|
||||
* @param {String} selector
|
||||
* The selector used to obtain the element.
|
||||
* @param {String} pseudo
|
||||
* pseudo id to query, or null.
|
||||
* @param {String} name
|
||||
* name of the property.
|
||||
*/
|
||||
function* getComputedStyleProperty(selector, pseudo, propName) {
|
||||
let data = {
|
||||
selector,
|
||||
pseudo,
|
||||
name: propName
|
||||
};
|
||||
return yield executeInContent("Test:GetComputedStylePropertyValue", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script and wait until the requested
|
||||
* computed style property has the expected value.
|
||||
*
|
||||
* @param {String} selector
|
||||
* The selector used to obtain the element.
|
||||
* @param {String} pseudo
|
||||
* pseudo id to query, or null.
|
||||
* @param {String} prop
|
||||
* name of the property.
|
||||
* @param {String} expected
|
||||
* expected value of property
|
||||
* @param {String} name
|
||||
* the name used in test message
|
||||
*/
|
||||
function* waitForComputedStyleProperty(selector, pseudo, name, expected) {
|
||||
let data = {
|
||||
selector,
|
||||
pseudo,
|
||||
expected,
|
||||
name
|
||||
};
|
||||
return yield executeInContent("Test:WaitForComputedStylePropertyValue", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an inplace editable element, click to switch it to edit mode, wait for
|
||||
* focus
|
||||
*
|
||||
* @return a promise that resolves to the inplace-editor element when ready
|
||||
*/
|
||||
var focusEditableField = Task.async(function* (ruleView, editable, xOffset = 1,
|
||||
yOffset = 1, options = {}) {
|
||||
let onFocus = once(editable.parentNode, "focus", true);
|
||||
info("Clicking on editable field to turn to edit mode");
|
||||
EventUtils.synthesizeMouse(editable, xOffset, yOffset, options,
|
||||
editable.ownerDocument.defaultView);
|
||||
yield onFocus;
|
||||
|
||||
info("Editable field gained focus, returning the input field now");
|
||||
let onEdit = inplaceEditor(editable.ownerDocument.activeElement);
|
||||
|
||||
return onEdit;
|
||||
});
|
||||
|
||||
/**
|
||||
* Polls a given function waiting for it to return true.
|
||||
*
|
||||
|
@ -258,109 +141,6 @@ var getFontFamilyDataURL = Task.async(function* (font, nodeFront) {
|
|||
* This object contains functions to get rules, get properties, ...
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the DOMNode for a css rule in the rule-view that corresponds to the given
|
||||
* selector
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view for which the rule
|
||||
* object is wanted
|
||||
* @return {DOMNode}
|
||||
*/
|
||||
function getRuleViewRule(view, selectorText) {
|
||||
let rule;
|
||||
for (let r of view.styleDocument.querySelectorAll(".ruleview-rule")) {
|
||||
let selector = r.querySelector(".ruleview-selectorcontainer, " +
|
||||
".ruleview-selector-matched");
|
||||
if (selector && selector.textContent === selectorText) {
|
||||
rule = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get references to the name and value span nodes corresponding to a given
|
||||
* selector and property name in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for the property in
|
||||
* @param {String} propertyName
|
||||
* The name of the property
|
||||
* @return {Object} An object like {nameSpan: DOMNode, valueSpan: DOMNode}
|
||||
*/
|
||||
function getRuleViewProperty(view, selectorText, propertyName) {
|
||||
let prop;
|
||||
|
||||
let rule = getRuleViewRule(view, selectorText);
|
||||
if (rule) {
|
||||
// Look for the propertyName in that rule element
|
||||
for (let p of rule.querySelectorAll(".ruleview-property")) {
|
||||
let nameSpan = p.querySelector(".ruleview-propertyname");
|
||||
let valueSpan = p.querySelector(".ruleview-propertyvalue");
|
||||
|
||||
if (nameSpan.textContent === propertyName) {
|
||||
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value of the property corresponding to a given selector and name
|
||||
* in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for the property in
|
||||
* @param {String} propertyName
|
||||
* The name of the property
|
||||
* @return {String} The property value
|
||||
*/
|
||||
function getRuleViewPropertyValue(view, selectorText, propertyName) {
|
||||
return getRuleViewProperty(view, selectorText, propertyName)
|
||||
.valueSpan.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the selector DOM element corresponding to a given selector
|
||||
* in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for
|
||||
* @return {DOMNode} The selector DOM element
|
||||
*/
|
||||
function getRuleViewSelector(view, selectorText) {
|
||||
let rule = getRuleViewRule(view, selectorText);
|
||||
return rule.querySelector(".ruleview-selector, .ruleview-selector-matched");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the selectorhighlighter icon DOM element corresponding to
|
||||
* a given selector in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for
|
||||
* @return {DOMNode} The selectorhighlighter icon DOM element
|
||||
*/
|
||||
function getRuleViewSelectorHighlighterIcon(view, selectorText) {
|
||||
let rule = getRuleViewRule(view, selectorText);
|
||||
return rule.querySelector(".ruleview-selectorhighlighter");
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate a color change in a given color picker tooltip, and optionally wait
|
||||
* for a given element in the page to have its style changed as a result
|
||||
|
@ -400,100 +180,6 @@ var simulateColorPickerChange = Task.async(function* (ruleView, colorPicker,
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get a rule-link from the rule-view given its index
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {Number} index
|
||||
* The index of the link to get
|
||||
* @return {DOMNode} The link if any at this index
|
||||
*/
|
||||
function getRuleViewLinkByIndex(view, index) {
|
||||
let links = view.styleDocument.querySelectorAll(".ruleview-rule-source");
|
||||
return links[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rule-link text from the rule-view given its index
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {Number} index
|
||||
* The index of the link to get
|
||||
* @return {String} The string at this index
|
||||
*/
|
||||
function getRuleViewLinkTextByIndex(view, index) {
|
||||
let link = getRuleViewLinkByIndex(view, index);
|
||||
return link.querySelector(".ruleview-rule-source-label").textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Click on a rule-view's close brace to focus a new property name editor
|
||||
*
|
||||
* @param {RuleEditor} ruleEditor
|
||||
* An instance of RuleEditor that will receive the new property
|
||||
* @return a promise that resolves to the newly created editor when ready and
|
||||
* focused
|
||||
*/
|
||||
var focusNewRuleViewProperty = Task.async(function* (ruleEditor) {
|
||||
info("Clicking on a close ruleEditor brace to start editing a new property");
|
||||
ruleEditor.closeBrace.scrollIntoView();
|
||||
let editor = yield focusEditableField(ruleEditor.ruleView,
|
||||
ruleEditor.closeBrace);
|
||||
|
||||
is(inplaceEditor(ruleEditor.newPropSpan), editor,
|
||||
"Focused editor is the new property editor.");
|
||||
|
||||
return editor;
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a new property name in the rule-view, focusing a new property editor
|
||||
* by clicking on the close brace, and then entering the given text.
|
||||
* Keep in mind that the rule-view knows how to handle strings with multiple
|
||||
* properties, so the input text may be like: "p1:v1;p2:v2;p3:v3".
|
||||
*
|
||||
* @param {RuleEditor} ruleEditor
|
||||
* The instance of RuleEditor that will receive the new property(ies)
|
||||
* @param {String} inputValue
|
||||
* The text to be entered in the new property name field
|
||||
* @return a promise that resolves when the new property name has been entered
|
||||
* and once the value field is focused
|
||||
*/
|
||||
var createNewRuleViewProperty = Task.async(function* (ruleEditor, inputValue) {
|
||||
info("Creating a new property editor");
|
||||
let editor = yield focusNewRuleViewProperty(ruleEditor);
|
||||
|
||||
info("Entering the value " + inputValue);
|
||||
editor.input.value = inputValue;
|
||||
|
||||
info("Submitting the new value and waiting for value field focus");
|
||||
let onFocus = once(ruleEditor.element, "focus", true);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {},
|
||||
ruleEditor.element.ownerDocument.defaultView);
|
||||
yield onFocus;
|
||||
});
|
||||
|
||||
/**
|
||||
* Set the search value for the rule-view filter styles search box.
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} searchValue
|
||||
* The filter search value
|
||||
* @return a promise that resolves when the rule-view is filtered for the
|
||||
* search term
|
||||
*/
|
||||
var setSearchFilter = Task.async(function* (view, searchValue) {
|
||||
info("Setting filter text to \"" + searchValue + "\"");
|
||||
let win = view.styleWindow;
|
||||
let searchField = view.searchField;
|
||||
searchField.focus();
|
||||
synthesizeKeys(searchValue, win);
|
||||
yield view.inspector.once("ruleview-filtered");
|
||||
});
|
||||
|
||||
/* *********************************************
|
||||
* COMPUTED-VIEW
|
||||
* *********************************************
|
||||
|
@ -539,23 +225,3 @@ function getComputedViewPropertyValue(view, name, propertyName) {
|
|||
return getComputedViewProperty(view, name, propertyName)
|
||||
.valueSpan.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the style editor context menu and return all of it's items in a flat array
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @return An array of MenuItems
|
||||
*/
|
||||
function openStyleContextMenuAndGetAllItems(view, target) {
|
||||
let menu = view._contextmenu._openMenu({target: target});
|
||||
|
||||
// Flatten all menu items into a single array to make searching through it easier
|
||||
let allItems = [].concat.apply([], menu.items.map(function addItem(item) {
|
||||
if (item.submenu) {
|
||||
return addItem(item.submenu.items);
|
||||
}
|
||||
return item;
|
||||
}));
|
||||
|
||||
return allItems;
|
||||
}
|
||||
|
|
|
@ -184,3 +184,352 @@ function manualThrottle() {
|
|||
|
||||
return throttle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for a content -> chrome message on the message manager (the window
|
||||
* messagemanager is used).
|
||||
*
|
||||
* @param {String} name
|
||||
* The message name
|
||||
* @return {Promise} A promise that resolves to the response data when the
|
||||
* message has been received
|
||||
*/
|
||||
function waitForContentMessage(name) {
|
||||
info("Expecting message " + name + " from content");
|
||||
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
let def = defer();
|
||||
mm.addMessageListener(name, function onMessage(msg) {
|
||||
mm.removeMessageListener(name, onMessage);
|
||||
def.resolve(msg.data);
|
||||
});
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script (chrome -> content) and wait for a
|
||||
* response message with the same name (content -> chrome).
|
||||
*
|
||||
* @param {String} name
|
||||
* The message name. Should be one of the messages defined
|
||||
* in doc_frame_script.js
|
||||
* @param {Object} data
|
||||
* Optional data to send along
|
||||
* @param {Object} objects
|
||||
* Optional CPOW objects to send along
|
||||
* @param {Boolean} expectResponse
|
||||
* If set to false, don't wait for a response with the same name
|
||||
* from the content script. Defaults to true.
|
||||
* @return {Promise} Resolves to the response data if a response is expected,
|
||||
* immediately resolves otherwise
|
||||
*/
|
||||
function executeInContent(name, data = {}, objects = {},
|
||||
expectResponse = true) {
|
||||
info("Sending message " + name + " to content");
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
mm.sendAsyncMessage(name, data, objects);
|
||||
if (expectResponse) {
|
||||
return waitForContentMessage(name);
|
||||
}
|
||||
|
||||
return promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script and get back the requested
|
||||
* computed style property.
|
||||
*
|
||||
* @param {String} selector
|
||||
* The selector used to obtain the element.
|
||||
* @param {String} pseudo
|
||||
* pseudo id to query, or null.
|
||||
* @param {String} name
|
||||
* name of the property.
|
||||
*/
|
||||
function* getComputedStyleProperty(selector, pseudo, propName) {
|
||||
return yield executeInContent("Test:GetComputedStylePropertyValue",
|
||||
{selector,
|
||||
pseudo,
|
||||
name: propName});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an async message to the frame script and wait until the requested
|
||||
* computed style property has the expected value.
|
||||
*
|
||||
* @param {String} selector
|
||||
* The selector used to obtain the element.
|
||||
* @param {String} pseudo
|
||||
* pseudo id to query, or null.
|
||||
* @param {String} prop
|
||||
* name of the property.
|
||||
* @param {String} expected
|
||||
* expected value of property
|
||||
* @param {String} name
|
||||
* the name used in test message
|
||||
*/
|
||||
function* waitForComputedStyleProperty(selector, pseudo, name, expected) {
|
||||
return yield executeInContent("Test:WaitForComputedStylePropertyValue",
|
||||
{selector,
|
||||
pseudo,
|
||||
expected,
|
||||
name});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an inplace editable element, click to switch it to edit mode, wait for
|
||||
* focus
|
||||
*
|
||||
* @return a promise that resolves to the inplace-editor element when ready
|
||||
*/
|
||||
var focusEditableField = Task.async(function* (ruleView, editable, xOffset = 1,
|
||||
yOffset = 1, options = {}) {
|
||||
let onFocus = once(editable.parentNode, "focus", true);
|
||||
info("Clicking on editable field to turn to edit mode");
|
||||
EventUtils.synthesizeMouse(editable, xOffset, yOffset, options,
|
||||
editable.ownerDocument.defaultView);
|
||||
yield onFocus;
|
||||
|
||||
info("Editable field gained focus, returning the input field now");
|
||||
let onEdit = inplaceEditor(editable.ownerDocument.activeElement);
|
||||
|
||||
return onEdit;
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the DOMNode for a css rule in the rule-view that corresponds to the given
|
||||
* selector.
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view for which the rule
|
||||
* object is wanted
|
||||
* @param {Number} index
|
||||
* If there are more than 1 rule with the same selector, you may pass a
|
||||
* index to determine which of the rules you want.
|
||||
* @return {DOMNode}
|
||||
*/
|
||||
function getRuleViewRule(view, selectorText, index = 0) {
|
||||
let rule;
|
||||
let pos = 0;
|
||||
for (let r of view.styleDocument.querySelectorAll(".ruleview-rule")) {
|
||||
let selector = r.querySelector(".ruleview-selectorcontainer, " +
|
||||
".ruleview-selector-matched");
|
||||
if (selector && selector.textContent === selectorText) {
|
||||
if (index == pos) {
|
||||
rule = r;
|
||||
break;
|
||||
}
|
||||
pos ++;
|
||||
}
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get references to the name and value span nodes corresponding to a given
|
||||
* selector and property name in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for the property in
|
||||
* @param {String} propertyName
|
||||
* The name of the property
|
||||
* @return {Object} An object like {nameSpan: DOMNode, valueSpan: DOMNode}
|
||||
*/
|
||||
function getRuleViewProperty(view, selectorText, propertyName) {
|
||||
let prop;
|
||||
|
||||
let rule = getRuleViewRule(view, selectorText);
|
||||
if (rule) {
|
||||
// Look for the propertyName in that rule element
|
||||
for (let p of rule.querySelectorAll(".ruleview-property")) {
|
||||
let nameSpan = p.querySelector(".ruleview-propertyname");
|
||||
let valueSpan = p.querySelector(".ruleview-propertyvalue");
|
||||
|
||||
if (nameSpan.textContent === propertyName) {
|
||||
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value of the property corresponding to a given selector and name
|
||||
* in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for the property in
|
||||
* @param {String} propertyName
|
||||
* The name of the property
|
||||
* @return {String} The property value
|
||||
*/
|
||||
function getRuleViewPropertyValue(view, selectorText, propertyName) {
|
||||
return getRuleViewProperty(view, selectorText, propertyName)
|
||||
.valueSpan.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the selector DOM element corresponding to a given selector
|
||||
* in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for
|
||||
* @return {DOMNode} The selector DOM element
|
||||
*/
|
||||
function getRuleViewSelector(view, selectorText) {
|
||||
let rule = getRuleViewRule(view, selectorText);
|
||||
return rule.querySelector(".ruleview-selector, .ruleview-selector-matched");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the selectorhighlighter icon DOM element corresponding to
|
||||
* a given selector in the rule-view
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} selectorText
|
||||
* The selector in the rule-view to look for
|
||||
* @param {Number} index
|
||||
* If there are more than 1 rule with the same selector, use this index
|
||||
* to determine which one should be retrieved. Defaults to 0
|
||||
* @return {DOMNode} The selectorhighlighter icon DOM element
|
||||
*/
|
||||
var getRuleViewSelectorHighlighterIcon = Task.async(function* (view,
|
||||
selectorText, index = 0) {
|
||||
let rule = getRuleViewRule(view, selectorText, index);
|
||||
|
||||
let editor = rule._ruleEditor;
|
||||
if (!editor.uniqueSelector) {
|
||||
yield once(editor, "selector-icon-created");
|
||||
}
|
||||
|
||||
return rule.querySelector(".ruleview-selectorhighlighter");
|
||||
});
|
||||
|
||||
/**
|
||||
* Get a rule-link from the rule-view given its index
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {Number} index
|
||||
* The index of the link to get
|
||||
* @return {DOMNode} The link if any at this index
|
||||
*/
|
||||
function getRuleViewLinkByIndex(view, index) {
|
||||
let links = view.styleDocument.querySelectorAll(".ruleview-rule-source");
|
||||
return links[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rule-link text from the rule-view given its index
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {Number} index
|
||||
* The index of the link to get
|
||||
* @return {String} The string at this index
|
||||
*/
|
||||
function getRuleViewLinkTextByIndex(view, index) {
|
||||
let link = getRuleViewLinkByIndex(view, index);
|
||||
return link.querySelector(".ruleview-rule-source-label").textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Click on a rule-view's close brace to focus a new property name editor
|
||||
*
|
||||
* @param {RuleEditor} ruleEditor
|
||||
* An instance of RuleEditor that will receive the new property
|
||||
* @return a promise that resolves to the newly created editor when ready and
|
||||
* focused
|
||||
*/
|
||||
var focusNewRuleViewProperty = Task.async(function* (ruleEditor) {
|
||||
info("Clicking on a close ruleEditor brace to start editing a new property");
|
||||
|
||||
// Use bottom alignment to avoid scrolling out of the parent element area.
|
||||
ruleEditor.closeBrace.scrollIntoView(false);
|
||||
let editor = yield focusEditableField(ruleEditor.ruleView,
|
||||
ruleEditor.closeBrace);
|
||||
|
||||
is(inplaceEditor(ruleEditor.newPropSpan), editor,
|
||||
"Focused editor is the new property editor.");
|
||||
|
||||
return editor;
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a new property name in the rule-view, focusing a new property editor
|
||||
* by clicking on the close brace, and then entering the given text.
|
||||
* Keep in mind that the rule-view knows how to handle strings with multiple
|
||||
* properties, so the input text may be like: "p1:v1;p2:v2;p3:v3".
|
||||
*
|
||||
* @param {RuleEditor} ruleEditor
|
||||
* The instance of RuleEditor that will receive the new property(ies)
|
||||
* @param {String} inputValue
|
||||
* The text to be entered in the new property name field
|
||||
* @return a promise that resolves when the new property name has been entered
|
||||
* and once the value field is focused
|
||||
*/
|
||||
var createNewRuleViewProperty = Task.async(function* (ruleEditor, inputValue) {
|
||||
info("Creating a new property editor");
|
||||
let editor = yield focusNewRuleViewProperty(ruleEditor);
|
||||
|
||||
info("Entering the value " + inputValue);
|
||||
editor.input.value = inputValue;
|
||||
|
||||
info("Submitting the new value and waiting for value field focus");
|
||||
let onFocus = once(ruleEditor.element, "focus", true);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {},
|
||||
ruleEditor.element.ownerDocument.defaultView);
|
||||
yield onFocus;
|
||||
});
|
||||
|
||||
/**
|
||||
* Set the search value for the rule-view filter styles search box.
|
||||
*
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @param {String} searchValue
|
||||
* The filter search value
|
||||
* @return a promise that resolves when the rule-view is filtered for the
|
||||
* search term
|
||||
*/
|
||||
var setSearchFilter = Task.async(function* (view, searchValue) {
|
||||
info("Setting filter text to \"" + searchValue + "\"");
|
||||
let win = view.styleWindow;
|
||||
let searchField = view.searchField;
|
||||
searchField.focus();
|
||||
synthesizeKeys(searchValue, win);
|
||||
yield view.inspector.once("ruleview-filtered");
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the style editor context menu and return all of it's items in a flat array
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @return An array of MenuItems
|
||||
*/
|
||||
function openStyleContextMenuAndGetAllItems(view, target) {
|
||||
let menu = view._contextmenu._openMenu({target: target});
|
||||
|
||||
// Flatten all menu items into a single array to make searching through it easier
|
||||
let allItems = [].concat.apply([], menu.items.map(function addItem(item) {
|
||||
if (item.submenu) {
|
||||
return addItem(item.submenu.items);
|
||||
}
|
||||
return item;
|
||||
}));
|
||||
|
||||
return allItems;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче