mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 699978 - Tools should notify the highlighter when they've modified a node. r=robcee
This commit is contained in:
parent
bd3c81c7c9
commit
995c21565d
@ -577,6 +577,7 @@ TreePanel.prototype = {
|
||||
this.editingContext.attrObj.innerHTML = editorInput.value;
|
||||
|
||||
this.IUI.isDirty = true;
|
||||
this.IUI.nodeChanged(this.registrationObject);
|
||||
|
||||
// event notification
|
||||
Services.obs.notifyObservers(null, this.IUI.INSPECTOR_NOTIFICATIONS.EDITOR_SAVED,
|
||||
|
@ -1158,6 +1158,19 @@ InspectorUI.prototype = {
|
||||
this.toolsSelect(aScroll);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the highlighted node is changed by a tool.
|
||||
*
|
||||
* @param object aUpdater
|
||||
* The tool that triggered the update (if any), that tool's
|
||||
* onChanged will not be called.
|
||||
*/
|
||||
nodeChanged: function IUI_nodeChanged(aUpdater)
|
||||
{
|
||||
this.highlighter.highlight();
|
||||
this.toolsOnChanged(aUpdater);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// Event Handling
|
||||
|
||||
@ -1340,6 +1353,10 @@ InspectorUI.prototype = {
|
||||
iframe.removeEventListener("load", boundLoadListener, true);
|
||||
let doc = iframe.contentDocument;
|
||||
this.ruleView = new CssRuleView(doc);
|
||||
this.boundRuleViewChanged = this.ruleViewChanged.bind(this);
|
||||
this.ruleView.element.addEventListener("CssRuleViewChanged",
|
||||
this.boundRuleViewChanged);
|
||||
|
||||
doc.documentElement.appendChild(this.ruleView.element);
|
||||
this.ruleView.highlight(this.selection);
|
||||
Services.obs.notifyObservers(null,
|
||||
@ -1370,6 +1387,12 @@ InspectorUI.prototype = {
|
||||
this.ruleView.highlight(aNode);
|
||||
},
|
||||
|
||||
ruleViewChanged: function IUI_ruleViewChanged()
|
||||
{
|
||||
this.isDirty = true;
|
||||
this.nodeChanged(this.ruleViewObject);
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the rule view.
|
||||
*/
|
||||
@ -1379,6 +1402,9 @@ InspectorUI.prototype = {
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
|
||||
if (this.ruleView) {
|
||||
this.ruleView.element.removeEventListener("CssRuleViewChanged",
|
||||
this.boundRuleViewChanged);
|
||||
delete boundRuleViewChanged;
|
||||
this.ruleView.clear();
|
||||
delete this.ruleView;
|
||||
}
|
||||
@ -1685,8 +1711,6 @@ InspectorUI.prototype = {
|
||||
*/
|
||||
toolShow: function IUI_toolShow(aTool)
|
||||
{
|
||||
aTool.show.call(aTool.context, this.selection);
|
||||
|
||||
let btn = this.chromeDoc.getElementById(this.getToolbarButtonId(aTool.id));
|
||||
btn.setAttribute("checked", "true");
|
||||
if (aTool.sidebar) {
|
||||
@ -1697,6 +1721,8 @@ InspectorUI.prototype = {
|
||||
this.getToolbarButtonId(other.id)).removeAttribute("checked");
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
aTool.show.call(aTool.context, this.selection);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1848,13 +1874,29 @@ InspectorUI.prototype = {
|
||||
*/
|
||||
toolsDim: function IUI_toolsDim(aState)
|
||||
{
|
||||
this.toolsDo(function IUI_toolsOnSelect(aTool) {
|
||||
this.toolsDo(function IUI_toolsDim(aTool) {
|
||||
if (aTool.isOpen && "dim" in aTool) {
|
||||
aTool.dim.call(aTool.context, aState);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify registered tools of changes to the highlighted element.
|
||||
*
|
||||
* @param object aUpdater
|
||||
* The tool that triggered the update (if any), that tool's
|
||||
* onChanged will not be called.
|
||||
*/
|
||||
toolsOnChanged: function IUI_toolsChanged(aUpdater)
|
||||
{
|
||||
this.toolsDo(function IUI_toolsOnChanged(aTool) {
|
||||
if (aTool.isOpen && ("onChanged" in aTool) && aTool != aUpdater) {
|
||||
aTool.onChanged.call(aTool.context);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Loop through all registered tools and pass each into the provided function
|
||||
* @param aFunction The function to which each tool is to be passed
|
||||
|
@ -66,6 +66,7 @@ _BROWSER_FILES = \
|
||||
browser_inspector_breadcrumbs.html \
|
||||
browser_inspector_breadcrumbs.js \
|
||||
browser_inspector_bug_699308_iframe_navigation.js \
|
||||
browser_inspector_changes.js \
|
||||
$(NULL)
|
||||
|
||||
# Disabled due to constant failures
|
||||
|
158
browser/devtools/highlighter/test/browser_inspector_changes.js
Normal file
158
browser/devtools/highlighter/test/browser_inspector_changes.js
Normal file
@ -0,0 +1,158 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Inspect Tests.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
* Rob Campbell <rcampbell@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
let doc;
|
||||
let testDiv;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<div id="testdiv">Test div!</div>';
|
||||
doc.title = "Inspector Change Test";
|
||||
startInspectorTests();
|
||||
}
|
||||
|
||||
|
||||
function getInspectorProp(aName)
|
||||
{
|
||||
for each (let view in InspectorUI.stylePanel.cssHtmlTree.propertyViews) {
|
||||
if (view.name == aName) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function startInspectorTests()
|
||||
{
|
||||
ok(InspectorUI, "InspectorUI variable exists");
|
||||
Services.obs.addObserver(runInspectorTests,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
InspectorUI.toggleInspectorUI();
|
||||
}
|
||||
|
||||
function runInspectorTests()
|
||||
{
|
||||
Services.obs.removeObserver(runInspectorTests, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
|
||||
testDiv = doc.getElementById("testdiv");
|
||||
|
||||
testDiv.style.fontSize = "10px";
|
||||
|
||||
InspectorUI.inspectNode(testDiv);
|
||||
InspectorUI.stopInspecting();
|
||||
|
||||
// Start up the style inspector panel...
|
||||
Services.obs.addObserver(stylePanelTests, "StyleInspector-populated", false);
|
||||
|
||||
executeSoon(function() {
|
||||
InspectorUI.showSidebar();
|
||||
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click();
|
||||
});
|
||||
}
|
||||
|
||||
function stylePanelTests()
|
||||
{
|
||||
Services.obs.removeObserver(stylePanelTests, "StyleInspector-populated");
|
||||
|
||||
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open");
|
||||
ok(InspectorUI.stylePanel.cssHtmlTree, "Style Panel has a cssHtmlTree");
|
||||
|
||||
let propView = getInspectorProp("font-size");
|
||||
is(propView.value, "10px", "Style inspector should be showing the correct font size.");
|
||||
|
||||
Services.obs.addObserver(stylePanelAfterChange, "StyleInspector-populated", false);
|
||||
|
||||
testDiv.style.fontSize = "15px";
|
||||
InspectorUI.nodeChanged();
|
||||
}
|
||||
|
||||
function stylePanelAfterChange()
|
||||
{
|
||||
Services.obs.removeObserver(stylePanelAfterChange, "StyleInspector-populated");
|
||||
|
||||
let propView = getInspectorProp("font-size");
|
||||
is(propView.value, "15px", "Style inspector should be showing the new font size.");
|
||||
|
||||
stylePanelNotActive();
|
||||
}
|
||||
|
||||
function stylePanelNotActive()
|
||||
{
|
||||
// Tests changes made while the style panel is not active.
|
||||
InspectorUI.ruleButton.click();
|
||||
executeSoon(function() {
|
||||
testDiv.style.fontSize = "20px";
|
||||
Services.obs.addObserver(stylePanelAfterSwitch, "StyleInspector-populated", false);
|
||||
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click();
|
||||
});
|
||||
}
|
||||
|
||||
function stylePanelAfterSwitch()
|
||||
{
|
||||
Services.obs.removeObserver(stylePanelAfterSwitch, "StyleInspector-populated");
|
||||
|
||||
let propView = getInspectorProp("font-size");
|
||||
is(propView.value, "20px", "Style inspector should be showing the newest font size.");
|
||||
|
||||
Services.obs.addObserver(finishTest, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
|
||||
executeSoon(function() {
|
||||
InspectorUI.closeInspectorUI(true);
|
||||
});
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
Services.obs.removeObserver(finishTest,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,basic tests for inspector";
|
||||
}
|
||||
|
@ -172,10 +172,6 @@ CssHtmlTree.prototype = {
|
||||
*/
|
||||
highlight: function CssHtmlTree_highlight(aElement)
|
||||
{
|
||||
if (this.viewedElement == aElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewedElement = aElement;
|
||||
this._unmatchedProperties = null;
|
||||
this._matchedProperties = null;
|
||||
@ -529,7 +525,7 @@ PropertyView.prototype = {
|
||||
*/
|
||||
get hasMatchedSelectors()
|
||||
{
|
||||
return this.tree.matchedProperties[this.name];
|
||||
return this.name in this.tree.matchedProperties;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -537,7 +533,7 @@ PropertyView.prototype = {
|
||||
*/
|
||||
get hasUnmatchedSelectors()
|
||||
{
|
||||
return this.tree.hasUnmatchedSelectors(this.name);
|
||||
return this.name in this.tree.hasUnmatchedSelectors;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -117,6 +117,17 @@ ElementStyle.prototype = {
|
||||
|
||||
domUtils: Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils),
|
||||
|
||||
/**
|
||||
* Called by the Rule object when it has been changed through the
|
||||
* setProperty* methods.
|
||||
*/
|
||||
_changed: function ElementStyle_changed()
|
||||
{
|
||||
if (this.onChanged) {
|
||||
this.onChanged();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh the list of rules to be displayed for the active element.
|
||||
* Upon completion, this.rules[] will hold a list of Rule objects.
|
||||
@ -388,6 +399,7 @@ Rule.prototype = {
|
||||
prop.priority = this.style.getPropertyPriority(prop.name);
|
||||
prop.updateComputed();
|
||||
}
|
||||
this.elementStyle._changed();
|
||||
|
||||
this.elementStyle.markOverridden();
|
||||
},
|
||||
@ -627,7 +639,15 @@ CssRuleView.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._elementStyle) {
|
||||
delete this._elementStyle.onChanged;
|
||||
}
|
||||
|
||||
this._elementStyle = new ElementStyle(aElement);
|
||||
this._elementStyle.onChanged = function() {
|
||||
this._changed();
|
||||
}.bind(this);
|
||||
|
||||
this._createEditors();
|
||||
},
|
||||
|
||||
@ -643,6 +663,17 @@ CssRuleView.prototype = {
|
||||
this._elementStyle = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the user has made changes to the ElementStyle.
|
||||
* Emits an event that clients can listen to.
|
||||
*/
|
||||
_changed: function CssRuleView_changed()
|
||||
{
|
||||
var evt = this.doc.createEvent("Events");
|
||||
evt.initEvent("CssRuleViewChanged", true, false);
|
||||
this.element.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates editor UI for each of the rules in _elementStyle.
|
||||
*/
|
||||
@ -1003,10 +1034,12 @@ TextPropertyEditor.prototype = {
|
||||
*/
|
||||
_parseValue: function TextPropertyEditor_parseValue(aValue)
|
||||
{
|
||||
let [value, priority] = aValue.split("!", 2);
|
||||
let pieces = aValue.split("!", 2);
|
||||
let value = pieces[0];
|
||||
let priority = pieces.length > 1 ? pieces[1] : "";
|
||||
return {
|
||||
value: value.trim(),
|
||||
priority: (priority ? priority.trim() : "")
|
||||
value: pieces[0].trim(),
|
||||
priority: (pieces.length > 1 ? pieces[1].trim() : "")
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -87,6 +87,7 @@ StyleInspector.prototype = {
|
||||
context: this,
|
||||
get isOpen() isOpen(),
|
||||
onSelect: this.selectNode,
|
||||
onChanged: this.updateNode,
|
||||
show: this.open,
|
||||
hide: this.close,
|
||||
dim: this.dimTool,
|
||||
@ -247,6 +248,17 @@ StyleInspector.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the display for the currently-selected node.
|
||||
*/
|
||||
updateNode: function SI_updateNode()
|
||||
{
|
||||
if (this.isOpen() && !this.dimmed) {
|
||||
this.cssLogic.highlight(this.selectedNode);
|
||||
this.cssHtmlTree.refreshPanel();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dim or undim a panel by setting or removing a dimmed attribute.
|
||||
* @param aState
|
||||
|
@ -32,6 +32,18 @@ function waitForEditorBlur(aEditor, aCallback)
|
||||
}, false);
|
||||
}
|
||||
|
||||
var gRuleViewChanged = false;
|
||||
function ruleViewChanged()
|
||||
{
|
||||
gRuleViewChanged = true;
|
||||
}
|
||||
|
||||
function expectChange()
|
||||
{
|
||||
ok(gRuleViewChanged, "Rule view should have fired a change event.");
|
||||
gRuleViewChanged = false;
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
let style = '' +
|
||||
@ -54,6 +66,7 @@ function startTest()
|
||||
let doc = ruleDialog.document;
|
||||
ruleView = new CssRuleView(doc);
|
||||
doc.documentElement.appendChild(ruleView.element);
|
||||
ruleView.element.addEventListener("CssRuleViewChanged", ruleViewChanged, false);
|
||||
ruleView.highlight(testElement);
|
||||
waitForFocus(testCancelNew, ruleDialog);
|
||||
}, true);
|
||||
@ -69,6 +82,7 @@ function testCancelNew()
|
||||
is(elementRuleEditor.newPropSpan.inplaceEditor, aEditor, "Next focused editor should be the new property editor.");
|
||||
let input = aEditor.input;
|
||||
waitForEditorBlur(aEditor, function () {
|
||||
ok(!gRuleViewChanged, "Shouldn't get a change event after a cancel.");
|
||||
is(elementRuleEditor.rule.textProps.length, 0, "Should have canceled creating a new text property.");
|
||||
ok(!elementRuleEditor.propertyList.hasChildNodes(), "Should not have any properties.");
|
||||
testCreateNew();
|
||||
@ -91,6 +105,7 @@ function testCreateNew()
|
||||
input.value = "background-color";
|
||||
|
||||
waitForEditorFocus(elementRuleEditor.element, function onNewValue(aEditor) {
|
||||
expectChange();
|
||||
is(elementRuleEditor.rule.textProps.length, 1, "Should have created a new text property.");
|
||||
is(elementRuleEditor.propertyList.children.length, 1, "Should have created a property editor.");
|
||||
let textProp = elementRuleEditor.rule.textProps[0];
|
||||
@ -98,6 +113,7 @@ function testCreateNew()
|
||||
|
||||
aEditor.input.value = "purple";
|
||||
waitForEditorBlur(aEditor, function() {
|
||||
expectChange();
|
||||
is(textProp.value, "purple", "Text prop should have been changed.");
|
||||
testEditProperty();
|
||||
});
|
||||
@ -120,10 +136,12 @@ function testEditProperty()
|
||||
is(propEditor.nameSpan.inplaceEditor, aEditor, "Next focused editor should be the name editor.");
|
||||
let input = aEditor.input;
|
||||
waitForEditorFocus(propEditor.element, function onNewName(aEditor) {
|
||||
expectChange();
|
||||
input = aEditor.input;
|
||||
is(propEditor.valueSpan.inplaceEditor, aEditor, "Focus should have moved to the value.");
|
||||
|
||||
waitForEditorBlur(aEditor, function() {
|
||||
expectChange();
|
||||
is(idRuleEditor.rule.style.getPropertyValue("border-color"), "red",
|
||||
"border-color should have been set.");
|
||||
testDisableProperty();
|
||||
@ -150,14 +168,20 @@ function testDisableProperty()
|
||||
|
||||
propEditor.enable.click();
|
||||
is(idRuleEditor.rule.style.getPropertyValue("border-color"), "", "Border-color should have been unset.");
|
||||
expectChange();
|
||||
|
||||
propEditor.enable.click();
|
||||
is(idRuleEditor.rule.style.getPropertyValue("border-color"), "red",
|
||||
"Border-color should have been reset.");
|
||||
expectChange();
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
ruleView.element.removeEventListener("CssRuleViewChanged", ruleViewChanged, false);
|
||||
ruleView.clear();
|
||||
ruleDialog.close();
|
||||
ruleDialog = ruleView = null;
|
||||
doc = null;
|
||||
|
Loading…
Reference in New Issue
Block a user