2014-06-25 05:12:07 +00:00
|
|
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
2011-08-30 12:12:02 +00:00
|
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* 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/. */
|
2011-08-30 12:12:02 +00:00
|
|
|
|
2015-08-10 22:17:04 +00:00
|
|
|
"use strict";
|
|
|
|
|
2013-04-11 20:59:08 +00:00
|
|
|
const {Cc, Cu, Ci} = require("chrome");
|
2015-08-26 13:05:13 +00:00
|
|
|
const promise = require("promise");
|
2015-09-21 17:04:18 +00:00
|
|
|
const {Tools} = require("devtools/client/main");
|
2011-08-30 12:12:02 +00:00
|
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
2015-09-21 17:04:18 +00:00
|
|
|
const {PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
|
2012-11-30 08:07:59 +00:00
|
|
|
|
2015-08-10 22:17:04 +00:00
|
|
|
loader.lazyGetter(this, "gDevTools", () =>
|
2015-09-21 17:04:18 +00:00
|
|
|
Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {}).gDevTools);
|
2015-08-10 22:17:04 +00:00
|
|
|
loader.lazyGetter(this, "RuleView",
|
2015-09-21 17:04:18 +00:00
|
|
|
() => require("devtools/client/styleinspector/rule-view"));
|
2015-08-10 22:17:04 +00:00
|
|
|
loader.lazyGetter(this, "ComputedView",
|
2015-09-21 17:04:18 +00:00
|
|
|
() => require("devtools/client/styleinspector/computed-view"));
|
2013-04-11 20:59:08 +00:00
|
|
|
loader.lazyGetter(this, "_strings", () => Services.strings
|
2013-11-19 14:15:46 +00:00
|
|
|
.createBundle("chrome://global/locale/devtools/styleinspector.properties"));
|
2011-08-30 12:12:02 +00:00
|
|
|
|
2012-04-19 18:04:46 +00:00
|
|
|
// This module doesn't currently export any symbols directly, it only
|
|
|
|
// registers inspector tools.
|
2011-10-21 17:40:22 +00:00
|
|
|
|
2015-08-10 22:17:04 +00:00
|
|
|
function RuleViewTool(inspector, window) {
|
2014-11-26 09:18:12 +00:00
|
|
|
this.inspector = inspector;
|
2015-07-12 22:52:16 +00:00
|
|
|
this.document = window.document;
|
2012-04-19 18:13:42 +00:00
|
|
|
|
2015-07-12 22:52:16 +00:00
|
|
|
this.view = new RuleView.CssRuleView(this.inspector, this.document);
|
2012-04-19 18:04:46 +00:00
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
this.onLinkClicked = this.onLinkClicked.bind(this);
|
|
|
|
this.onSelected = this.onSelected.bind(this);
|
|
|
|
this.refresh = this.refresh.bind(this);
|
|
|
|
this.clearUserProperties = this.clearUserProperties.bind(this);
|
|
|
|
this.onPropertyChanged = this.onPropertyChanged.bind(this);
|
|
|
|
this.onViewRefreshed = this.onViewRefreshed.bind(this);
|
2014-12-10 08:09:19 +00:00
|
|
|
this.onPanelSelected = this.onPanelSelected.bind(this);
|
2012-04-19 18:04:46 +00:00
|
|
|
|
2015-03-24 14:06:39 +00:00
|
|
|
this.view.on("ruleview-changed", this.onPropertyChanged);
|
|
|
|
this.view.on("ruleview-refreshed", this.onViewRefreshed);
|
|
|
|
this.view.on("ruleview-linked-clicked", this.onLinkClicked);
|
2012-04-19 18:04:46 +00:00
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
this.inspector.selection.on("detached", this.onSelected);
|
|
|
|
this.inspector.selection.on("new-node-front", this.onSelected);
|
|
|
|
this.inspector.on("layout-change", this.refresh);
|
|
|
|
this.inspector.selection.on("pseudoclass", this.refresh);
|
|
|
|
this.inspector.target.on("navigate", this.clearUserProperties);
|
2014-12-10 08:09:19 +00:00
|
|
|
this.inspector.sidebar.on("ruleview-selected", this.onPanelSelected);
|
2015-10-06 16:35:31 +00:00
|
|
|
this.inspector.pageStyle.on("stylesheet-updated", this.refresh);
|
2013-08-08 15:44:57 +00:00
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
this.onSelected();
|
|
|
|
}
|
2013-08-08 15:44:57 +00:00
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
RuleViewTool.prototype = {
|
2014-12-10 08:09:19 +00:00
|
|
|
isSidebarActive: function() {
|
2015-01-22 09:42:45 +00:00
|
|
|
if (!this.view) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-12-10 08:09:19 +00:00
|
|
|
return this.inspector.sidebar.getCurrentTabID() == "ruleview";
|
|
|
|
},
|
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
onSelected: function(event) {
|
2014-12-10 08:09:19 +00:00
|
|
|
// Ignore the event if the view has been destroyed, or if it's inactive.
|
|
|
|
// But only if the current selection isn't null. If it's been set to null,
|
2015-08-10 22:17:04 +00:00
|
|
|
// let the update go through as this is needed to empty the view on
|
|
|
|
// navigation.
|
2015-01-22 09:42:45 +00:00
|
|
|
if (!this.view) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-08-10 22:17:04 +00:00
|
|
|
let isInactive = !this.isSidebarActive() &&
|
|
|
|
this.inspector.selection.nodeFront;
|
2015-01-22 09:42:45 +00:00
|
|
|
if (isInactive) {
|
2014-11-26 09:18:12 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.view.setPageStyle(this.inspector.pageStyle);
|
|
|
|
|
|
|
|
if (!this.inspector.selection.isConnected() ||
|
|
|
|
!this.inspector.selection.isElementNode()) {
|
|
|
|
this.view.selectElement(null);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!event || event == "new-node-front") {
|
|
|
|
let done = this.inspector.updating("rule-view");
|
2015-08-10 22:17:04 +00:00
|
|
|
this.view.selectElement(this.inspector.selection.nodeFront)
|
|
|
|
.then(done, done);
|
2014-11-26 09:18:12 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
refresh: function() {
|
2014-12-10 08:09:19 +00:00
|
|
|
if (this.isSidebarActive()) {
|
|
|
|
this.view.refreshPanel();
|
|
|
|
}
|
2014-11-26 09:18:12 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
clearUserProperties: function() {
|
|
|
|
if (this.view && this.view.store && this.view.store.userProperties) {
|
|
|
|
this.view.store.userProperties.clear();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2014-12-10 08:09:19 +00:00
|
|
|
onPanelSelected: function() {
|
|
|
|
if (this.inspector.selection.nodeFront === this.view.viewedElement) {
|
|
|
|
this.refresh();
|
|
|
|
} else {
|
|
|
|
this.onSelected();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2015-03-24 14:06:39 +00:00
|
|
|
onLinkClicked: function(e, rule) {
|
2013-08-08 15:44:57 +00:00
|
|
|
let sheet = rule.parentStyleSheet;
|
2013-12-07 07:52:32 +00:00
|
|
|
|
|
|
|
// Chrome stylesheets are not listed in the style editor, so show
|
|
|
|
// these sheets in the view source window instead.
|
2013-12-16 19:49:17 +00:00
|
|
|
if (!sheet || sheet.isSystem) {
|
|
|
|
let href = rule.nodeHref || rule.href;
|
2015-04-24 21:16:34 +00:00
|
|
|
let toolbox = gDevTools.getToolbox(this.inspector.target);
|
|
|
|
toolbox.viewSource(href, rule.line);
|
2013-12-07 07:52:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let location = promise.resolve(rule.location);
|
|
|
|
if (Services.prefs.getBoolPref(PREF_ORIG_SOURCES)) {
|
|
|
|
location = rule.getOriginalLocation();
|
|
|
|
}
|
2014-08-22 19:30:00 +00:00
|
|
|
location.then(({ source, href, line, column }) => {
|
2012-11-30 08:07:59 +00:00
|
|
|
let target = this.inspector.target;
|
2014-11-26 09:18:12 +00:00
|
|
|
if (Tools.styleEditor.isTargetSupported(target)) {
|
2012-12-13 13:03:55 +00:00
|
|
|
gDevTools.showToolbox(target, "styleeditor").then(function(toolbox) {
|
2014-08-22 19:30:00 +00:00
|
|
|
let sheet = source || href;
|
|
|
|
toolbox.getCurrentPanel().selectStyleSheet(sheet, line, column);
|
2012-11-30 08:07:59 +00:00
|
|
|
});
|
|
|
|
}
|
2013-08-08 15:44:57 +00:00
|
|
|
return;
|
2015-08-10 22:17:04 +00:00
|
|
|
});
|
2012-11-30 08:07:59 +00:00
|
|
|
},
|
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
onPropertyChanged: function() {
|
|
|
|
this.inspector.markDirty();
|
2013-08-08 15:44:57 +00:00
|
|
|
},
|
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
onViewRefreshed: function() {
|
|
|
|
this.inspector.emit("rule-view-refreshed");
|
2014-08-11 13:17:52 +00:00
|
|
|
},
|
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
destroy: function() {
|
2012-11-30 08:07:59 +00:00
|
|
|
this.inspector.off("layout-change", this.refresh);
|
|
|
|
this.inspector.selection.off("pseudoclass", this.refresh);
|
2014-11-26 09:18:12 +00:00
|
|
|
this.inspector.selection.off("new-node-front", this.onSelected);
|
|
|
|
this.inspector.target.off("navigate", this.clearUserProperties);
|
2014-12-10 08:09:19 +00:00
|
|
|
this.inspector.sidebar.off("ruleview-selected", this.onPanelSelected);
|
2015-10-06 16:35:31 +00:00
|
|
|
if (this.inspector.pageStyle) {
|
|
|
|
this.inspector.pageStyle.off("stylesheet-updated", this.refresh);
|
|
|
|
}
|
2012-11-30 08:07:59 +00:00
|
|
|
|
2015-03-24 14:06:39 +00:00
|
|
|
this.view.off("ruleview-linked-clicked", this.onLinkClicked);
|
|
|
|
this.view.off("ruleview-changed", this.onPropertyChanged);
|
|
|
|
this.view.off("ruleview-refreshed", this.onViewRefreshed);
|
2013-08-08 15:44:57 +00:00
|
|
|
|
2012-04-19 18:04:46 +00:00
|
|
|
this.view.destroy();
|
|
|
|
|
2015-07-12 22:52:16 +00:00
|
|
|
this.view = this.document = this.inspector = null;
|
2012-04-19 18:04:46 +00:00
|
|
|
}
|
2014-03-09 17:03:00 +00:00
|
|
|
};
|
2012-04-19 18:04:46 +00:00
|
|
|
|
2015-08-10 22:17:04 +00:00
|
|
|
function ComputedViewTool(inspector, window) {
|
2014-11-26 09:18:12 +00:00
|
|
|
this.inspector = inspector;
|
2015-07-12 22:52:16 +00:00
|
|
|
this.document = window.document;
|
2014-11-26 09:18:12 +00:00
|
|
|
|
2015-08-10 22:17:04 +00:00
|
|
|
this.view = new ComputedView.CssComputedView(this.inspector, this.document,
|
|
|
|
this.inspector.pageStyle);
|
2014-11-26 09:18:12 +00:00
|
|
|
|
|
|
|
this.onSelected = this.onSelected.bind(this);
|
2012-11-30 08:07:59 +00:00
|
|
|
this.refresh = this.refresh.bind(this);
|
2014-12-10 08:09:19 +00:00
|
|
|
this.onPanelSelected = this.onPanelSelected.bind(this);
|
2014-11-26 09:18:12 +00:00
|
|
|
|
|
|
|
this.inspector.selection.on("detached", this.onSelected);
|
|
|
|
this.inspector.selection.on("new-node-front", this.onSelected);
|
2012-11-30 08:07:59 +00:00
|
|
|
this.inspector.on("layout-change", this.refresh);
|
|
|
|
this.inspector.selection.on("pseudoclass", this.refresh);
|
2014-12-10 08:09:19 +00:00
|
|
|
this.inspector.sidebar.on("computedview-selected", this.onPanelSelected);
|
2015-10-06 16:35:31 +00:00
|
|
|
this.inspector.pageStyle.on("stylesheet-updated", this.refresh);
|
2012-04-19 18:04:46 +00:00
|
|
|
|
2014-11-26 09:18:07 +00:00
|
|
|
this.view.selectElement(null);
|
2012-04-19 18:04:46 +00:00
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
this.onSelected();
|
2012-04-19 18:04:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ComputedViewTool.prototype = {
|
2014-12-10 08:09:19 +00:00
|
|
|
isSidebarActive: function() {
|
2015-01-22 09:42:45 +00:00
|
|
|
if (!this.view) {
|
2015-08-10 22:17:04 +00:00
|
|
|
return false;
|
2015-01-22 09:42:45 +00:00
|
|
|
}
|
2014-12-10 08:09:19 +00:00
|
|
|
return this.inspector.sidebar.getCurrentTabID() == "computedview";
|
|
|
|
},
|
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
onSelected: function(event) {
|
2014-12-10 08:09:19 +00:00
|
|
|
// Ignore the event if the view has been destroyed, or if it's inactive.
|
|
|
|
// But only if the current selection isn't null. If it's been set to null,
|
2015-08-10 22:17:04 +00:00
|
|
|
// let the update go through as this is needed to empty the view on
|
|
|
|
// navigation.
|
2015-01-22 09:42:45 +00:00
|
|
|
if (!this.view) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-08-10 22:17:04 +00:00
|
|
|
let isInactive = !this.isSidebarActive() &&
|
|
|
|
this.inspector.selection.nodeFront;
|
2015-01-22 09:42:45 +00:00
|
|
|
if (isInactive) {
|
2014-03-08 21:13:59 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-12-10 08:09:19 +00:00
|
|
|
|
2013-08-08 15:44:57 +00:00
|
|
|
this.view.setPageStyle(this.inspector.pageStyle);
|
|
|
|
|
2012-11-30 08:07:59 +00:00
|
|
|
if (!this.inspector.selection.isConnected() ||
|
|
|
|
!this.inspector.selection.isElementNode()) {
|
2014-11-26 09:18:07 +00:00
|
|
|
this.view.selectElement(null);
|
2012-11-30 08:07:59 +00:00
|
|
|
return;
|
2011-11-03 13:37:14 +00:00
|
|
|
}
|
2011-08-30 12:12:02 +00:00
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
if (!event || event == "new-node-front") {
|
2013-08-08 15:44:57 +00:00
|
|
|
let done = this.inspector.updating("computed-view");
|
2014-11-26 09:18:07 +00:00
|
|
|
this.view.selectElement(this.inspector.selection.nodeFront).then(() => {
|
2013-08-08 15:44:57 +00:00
|
|
|
done();
|
|
|
|
});
|
2011-08-30 12:12:02 +00:00
|
|
|
}
|
2012-11-30 08:07:59 +00:00
|
|
|
},
|
2012-04-19 18:04:46 +00:00
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
refresh: function() {
|
2014-12-10 08:09:19 +00:00
|
|
|
if (this.isSidebarActive()) {
|
|
|
|
this.view.refreshPanel();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onPanelSelected: function() {
|
|
|
|
if (this.inspector.selection.nodeFront === this.view.viewedElement) {
|
|
|
|
this.refresh();
|
|
|
|
} else {
|
|
|
|
this.onSelected();
|
|
|
|
}
|
2013-08-08 15:44:57 +00:00
|
|
|
},
|
|
|
|
|
2014-11-26 09:18:12 +00:00
|
|
|
destroy: function() {
|
2012-11-30 08:07:59 +00:00
|
|
|
this.inspector.off("layout-change", this.refresh);
|
|
|
|
this.inspector.sidebar.off("computedview-selected", this.refresh);
|
|
|
|
this.inspector.selection.off("pseudoclass", this.refresh);
|
2014-11-26 09:18:12 +00:00
|
|
|
this.inspector.selection.off("new-node-front", this.onSelected);
|
2014-12-10 08:09:19 +00:00
|
|
|
this.inspector.sidebar.off("computedview-selected", this.onPanelSelected);
|
2015-10-06 16:35:31 +00:00
|
|
|
if (this.inspector.pageStyle) {
|
|
|
|
this.inspector.pageStyle.off("stylesheet-updated", this.refresh);
|
|
|
|
}
|
2012-11-30 08:07:59 +00:00
|
|
|
|
2012-04-19 18:04:46 +00:00
|
|
|
this.view.destroy();
|
2014-11-26 09:18:12 +00:00
|
|
|
|
2015-07-12 22:52:16 +00:00
|
|
|
this.view = this.document = this.inspector = null;
|
2012-04-19 18:04:46 +00:00
|
|
|
}
|
2013-08-30 08:06:59 +00:00
|
|
|
};
|
2014-11-26 09:18:12 +00:00
|
|
|
|
|
|
|
exports.RuleViewTool = RuleViewTool;
|
|
|
|
exports.ComputedViewTool = ComputedViewTool;
|