From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- devtools/server/actors/styleeditor.js | 528 ++++++++++++++++++++++++++++++++++ 1 file changed, 528 insertions(+) create mode 100644 devtools/server/actors/styleeditor.js (limited to 'devtools/server/actors/styleeditor.js') diff --git a/devtools/server/actors/styleeditor.js b/devtools/server/actors/styleeditor.js new file mode 100644 index 000000000..5793a2baf --- /dev/null +++ b/devtools/server/actors/styleeditor.js @@ -0,0 +1,528 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {Cc, Ci} = require("chrome"); +const Services = require("Services"); +const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm"); +const promise = require("promise"); +const events = require("sdk/event/core"); +const protocol = require("devtools/shared/protocol"); +const {Arg, method, RetVal} = protocol; +const {fetch} = require("devtools/shared/DevToolsUtils"); +const {oldStyleSheetSpec, styleEditorSpec} = require("devtools/shared/specs/styleeditor"); + +loader.lazyGetter(this, "CssLogic", () => require("devtools/shared/inspector/css-logic")); + +var TRANSITION_CLASS = "moz-styleeditor-transitioning"; +var TRANSITION_DURATION_MS = 500; +var TRANSITION_RULE = "\ +:root.moz-styleeditor-transitioning, :root.moz-styleeditor-transitioning * {\ +transition-duration: " + TRANSITION_DURATION_MS + "ms !important; \ +transition-delay: 0ms !important;\ +transition-timing-function: ease-out !important;\ +transition-property: all !important;\ +}"; + +var LOAD_ERROR = "error-load"; + +var OldStyleSheetActor = protocol.ActorClassWithSpec(oldStyleSheetSpec, { + toString: function() { + return "[OldStyleSheetActor " + this.actorID + "]"; + }, + + /** + * Window of target + */ + get window() { + return this._window || this.parentActor.window; + }, + + /** + * Document of target. + */ + get document() { + return this.window.document; + }, + + /** + * URL of underlying stylesheet. + */ + get href() { + return this.rawSheet.href; + }, + + /** + * Retrieve the index (order) of stylesheet in the document. + * + * @return number + */ + get styleSheetIndex() + { + if (this._styleSheetIndex == -1) { + for (let i = 0; i < this.document.styleSheets.length; i++) { + if (this.document.styleSheets[i] == this.rawSheet) { + this._styleSheetIndex = i; + break; + } + } + } + return this._styleSheetIndex; + }, + + initialize: function (aStyleSheet, aParentActor, aWindow) { + protocol.Actor.prototype.initialize.call(this, null); + + this.rawSheet = aStyleSheet; + this.parentActor = aParentActor; + this.conn = this.parentActor.conn; + + this._window = aWindow; + + // text and index are unknown until source load + this.text = null; + this._styleSheetIndex = -1; + + this._transitionRefCount = 0; + + // if this sheet has an @import, then it's rules are loaded async + let ownerNode = this.rawSheet.ownerNode; + if (ownerNode) { + let onSheetLoaded = (event) => { + ownerNode.removeEventListener("load", onSheetLoaded, false); + this._notifyPropertyChanged("ruleCount"); + }; + + ownerNode.addEventListener("load", onSheetLoaded, false); + } + }, + + /** + * Get the current state of the actor + * + * @return {object} + * With properties of the underlying stylesheet, plus 'text', + * 'styleSheetIndex' and 'parentActor' if it's @imported + */ + form: function (detail) { + if (detail === "actorid") { + return this.actorID; + } + + let docHref; + if (this.rawSheet.ownerNode) { + if (this.rawSheet.ownerNode instanceof Ci.nsIDOMHTMLDocument) { + docHref = this.rawSheet.ownerNode.location.href; + } + if (this.rawSheet.ownerNode.ownerDocument) { + docHref = this.rawSheet.ownerNode.ownerDocument.location.href; + } + } + + let form = { + actor: this.actorID, // actorID is set when this actor is added to a pool + href: this.href, + nodeHref: docHref, + disabled: this.rawSheet.disabled, + title: this.rawSheet.title, + system: !CssLogic.isContentStylesheet(this.rawSheet), + styleSheetIndex: this.styleSheetIndex + }; + + try { + form.ruleCount = this.rawSheet.cssRules.length; + } + catch (e) { + // stylesheet had an @import rule that wasn't loaded yet + } + return form; + }, + + /** + * Toggle the disabled property of the style sheet + * + * @return {object} + * 'disabled' - the disabled state after toggling. + */ + toggleDisabled: function () { + this.rawSheet.disabled = !this.rawSheet.disabled; + this._notifyPropertyChanged("disabled"); + + return this.rawSheet.disabled; + }, + + /** + * Send an event notifying that a property of the stylesheet + * has changed. + * + * @param {string} property + * Name of the changed property + */ + _notifyPropertyChanged: function (property) { + events.emit(this, "property-change", property, this.form()[property]); + }, + + /** + * Fetch the source of the style sheet from its URL. Send a "sourceLoad" + * event when it's been fetched. + */ + fetchSource: function () { + this._getText().then((content) => { + events.emit(this, "source-load", this.text); + }); + }, + + /** + * Fetch the text for this stylesheet from the cache or network. Return + * cached text if it's already been fetched. + * + * @return {Promise} + * Promise that resolves with a string text of the stylesheet. + */ + _getText: function () { + if (this.text) { + return promise.resolve(this.text); + } + + if (!this.href) { + // this is an inline