зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1179820 - Remove source map handling from stylesheets actor; r=gl
MozReview-Commit-ID: 88Sw3TSx5yL --HG-- extra : rebase_source : 802c54aece7174c5449d29b2c3a8fbef9826f15e
This commit is contained in:
Родитель
c43bfd93a0
Коммит
aec735d6be
|
@ -12,9 +12,8 @@ const {Task} = require("devtools/shared/task");
|
|||
const protocol = require("devtools/shared/protocol");
|
||||
const {LongStringActor} = require("devtools/server/actors/string");
|
||||
const {fetch} = require("devtools/shared/DevToolsUtils");
|
||||
const {originalSourceSpec, mediaRuleSpec, styleSheetSpec,
|
||||
const {mediaRuleSpec, styleSheetSpec,
|
||||
styleSheetsSpec} = require("devtools/shared/specs/stylesheets");
|
||||
const {SourceMapConsumer} = require("source-map");
|
||||
const {
|
||||
addPseudoClassLock, removePseudoClassLock } = require("devtools/server/actors/highlighters/utils/markup");
|
||||
|
||||
|
@ -58,64 +57,6 @@ exports.UPDATE_GENERAL = UPDATE_GENERAL;
|
|||
// edited text to be collected.
|
||||
let modifiedStyleSheets = new WeakMap();
|
||||
|
||||
/**
|
||||
* Actor representing an original source of a style sheet that was specified
|
||||
* in a source map.
|
||||
*/
|
||||
var OriginalSourceActor = protocol.ActorClassWithSpec(originalSourceSpec, {
|
||||
initialize: function (url, sourceMap, parentActor) {
|
||||
protocol.Actor.prototype.initialize.call(this, null);
|
||||
|
||||
this.url = url;
|
||||
this.sourceMap = sourceMap;
|
||||
this.parentActor = parentActor;
|
||||
this.conn = this.parentActor.conn;
|
||||
|
||||
this.text = null;
|
||||
},
|
||||
|
||||
form: function () {
|
||||
return {
|
||||
actor: this.actorID, // actorID is set when it's added to a pool
|
||||
url: this.url,
|
||||
relatedStyleSheet: this.parentActor.form()
|
||||
};
|
||||
},
|
||||
|
||||
_getText: function () {
|
||||
if (this.text) {
|
||||
return promise.resolve(this.text);
|
||||
}
|
||||
let content = this.sourceMap.sourceContentFor(this.url);
|
||||
if (content) {
|
||||
this.text = content;
|
||||
return promise.resolve(content);
|
||||
}
|
||||
let options = {
|
||||
// Make sure to use TYPE_OTHER - we are not fetching necessarily
|
||||
// even fetching a style sheet, and anyway we're not planning to
|
||||
// use it as a style sheet per se but rather just for its text;
|
||||
// and this avoids problems with X-Content-Type-Options:
|
||||
// nosniff. See bug 1330383.
|
||||
policy: Ci.nsIContentPolicy.TYPE_OTHER,
|
||||
window: this.window
|
||||
};
|
||||
return fetch(this.url, options).then(({content: text}) => {
|
||||
this.text = text;
|
||||
return text;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Protocol method to get the text of this source.
|
||||
*/
|
||||
getText: function () {
|
||||
return this._getText().then((text) => {
|
||||
return new LongStringActor(this.conn, text || "");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A MediaRuleActor lives on the server and provides access to properties
|
||||
* of a DOM @media rule and emits events when it changes.
|
||||
|
@ -191,9 +132,6 @@ var MediaRuleActor = protocol.ActorClassWithSpec(mediaRuleSpec, {
|
|||
* A StyleSheetActor represents a stylesheet on the server.
|
||||
*/
|
||||
var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, {
|
||||
/* List of original sources that generated this stylesheet */
|
||||
_originalSources: null,
|
||||
|
||||
toString: function () {
|
||||
return "[StyleSheetActor " + this.actorID + "]";
|
||||
},
|
||||
|
@ -499,145 +437,6 @@ var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, {
|
|||
return result;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Protocol method to get the original source (actors) for this
|
||||
* stylesheet if it has uses source maps.
|
||||
*/
|
||||
getOriginalSources: function () {
|
||||
if (this._originalSources) {
|
||||
return promise.resolve(this._originalSources);
|
||||
}
|
||||
return this._fetchOriginalSources();
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the original sources (actors) for this style sheet using its
|
||||
* source map. If they've already been fetched, returns cached array.
|
||||
*
|
||||
* @return {Promise}
|
||||
* Promise that resolves with an array of OriginalSourceActors
|
||||
*/
|
||||
_fetchOriginalSources: function () {
|
||||
this._clearOriginalSources();
|
||||
this._originalSources = [];
|
||||
|
||||
return this.getSourceMap().then((sourceMap) => {
|
||||
if (!sourceMap) {
|
||||
return null;
|
||||
}
|
||||
for (let url of sourceMap.sources) {
|
||||
let actor = new OriginalSourceActor(url, sourceMap, this);
|
||||
|
||||
this.manage(actor);
|
||||
this._originalSources.push(actor);
|
||||
}
|
||||
return this._originalSources;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the SourceMapConsumer for this stylesheet's source map, if
|
||||
* it exists. Saves the consumer for later queries.
|
||||
*
|
||||
* @return {Promise}
|
||||
* A promise that resolves with a SourceMapConsumer, or null.
|
||||
*/
|
||||
getSourceMap: function () {
|
||||
if (this._sourceMap) {
|
||||
return this._sourceMap;
|
||||
}
|
||||
return this._fetchSourceMap();
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the source map for this stylesheet.
|
||||
*
|
||||
* @return {Promise}
|
||||
* A promise that resolves with a SourceMapConsumer, or null.
|
||||
*/
|
||||
_fetchSourceMap: function () {
|
||||
let deferred = defer();
|
||||
|
||||
let url = this.rawSheet.sourceMapURL;
|
||||
if (!url) {
|
||||
// no source map for this stylesheet
|
||||
deferred.resolve(null);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
url = normalize(url, this.safeHref);
|
||||
let options = {
|
||||
loadFromCache: false,
|
||||
policy: Ci.nsIContentPolicy.TYPE_INTERNAL_STYLESHEET,
|
||||
window: this.window
|
||||
};
|
||||
|
||||
let map = fetch(url, options).then(({content}) => {
|
||||
// Fetching the source map might have failed with a 404 or other. When
|
||||
// this happens, SourceMapConsumer may fail with a JSON.parse error.
|
||||
let consumer;
|
||||
try {
|
||||
consumer = new SourceMapConsumer(content,
|
||||
this._getSourceMapRoot(url, this.safeHref));
|
||||
} catch (e) {
|
||||
deferred.reject(new Error(
|
||||
`Source map at ${url} not found or invalid`));
|
||||
return null;
|
||||
}
|
||||
this._sourceMap = promise.resolve(consumer);
|
||||
|
||||
deferred.resolve(consumer);
|
||||
return consumer;
|
||||
}, deferred.reject);
|
||||
|
||||
this._sourceMap = map;
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear and unmanage the original source actors for this stylesheet.
|
||||
*/
|
||||
_clearOriginalSources: function () {
|
||||
for (let actor in this._originalSources) {
|
||||
this.unmanage(actor);
|
||||
}
|
||||
this._originalSources = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Compute the URL to pass to the SourceMapConsumer constructor as
|
||||
* the "source map's URL".
|
||||
*/
|
||||
_getSourceMapRoot: function (absSourceMapURL, scriptURL) {
|
||||
// Pass in the source map URL; except if it is a data: or blob:
|
||||
// URL, fall back to using the source's URL, if possible.
|
||||
if (scriptURL && (absSourceMapURL.startsWith("data:") ||
|
||||
absSourceMapURL.startsWith("blob:"))) {
|
||||
return scriptURL;
|
||||
}
|
||||
return absSourceMapURL;
|
||||
},
|
||||
|
||||
/**
|
||||
* Protocol method that gets the location in the original source of a
|
||||
* line, column pair in this stylesheet, if its source mapped, otherwise
|
||||
* a promise of the same location.
|
||||
*/
|
||||
getOriginalLocation: function (line, column) {
|
||||
return this.getSourceMap().then((sourceMap) => {
|
||||
if (sourceMap) {
|
||||
return sourceMap.originalPositionFor({ line: line, column: column });
|
||||
}
|
||||
return {
|
||||
fromSourceMap: false,
|
||||
source: this.href,
|
||||
line: line,
|
||||
column: column
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Protocol method to get the media rules for the stylesheet.
|
||||
*/
|
||||
|
@ -1043,15 +842,3 @@ var StyleSheetsActor = protocol.ActorClassWithSpec(styleSheetsSpec, {
|
|||
});
|
||||
|
||||
exports.StyleSheetsActor = StyleSheetsActor;
|
||||
|
||||
/**
|
||||
* Normalize multiple relative paths towards the base paths on the right.
|
||||
*/
|
||||
function normalize(...urls) {
|
||||
let base = Services.io.newURI(urls.pop());
|
||||
let url;
|
||||
while ((url = urls.pop())) {
|
||||
base = Services.io.newURI(url, null, base);
|
||||
}
|
||||
return base.spec;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
const { Front, FrontClassWithSpec } = require("devtools/shared/protocol");
|
||||
const {
|
||||
originalSourceSpec,
|
||||
mediaRuleSpec,
|
||||
styleSheetSpec,
|
||||
styleSheetsSpec
|
||||
|
@ -18,35 +17,6 @@ loader.lazyRequireGetter(this, "getIndentationFromPrefs",
|
|||
loader.lazyRequireGetter(this, "getIndentationFromString",
|
||||
"devtools/shared/indentation", true);
|
||||
|
||||
/**
|
||||
* The client-side counterpart for an OriginalSourceActor.
|
||||
*/
|
||||
const OriginalSourceFront = FrontClassWithSpec(originalSourceSpec, {
|
||||
initialize: function (client, form) {
|
||||
Front.prototype.initialize.call(this, client, form);
|
||||
|
||||
this.isOriginalSource = true;
|
||||
},
|
||||
|
||||
form: function (form, detail) {
|
||||
if (detail === "actorid") {
|
||||
this.actorID = form;
|
||||
return;
|
||||
}
|
||||
this.actorID = form.actor;
|
||||
this._form = form;
|
||||
},
|
||||
|
||||
get href() {
|
||||
return this._form.url;
|
||||
},
|
||||
get url() {
|
||||
return this._form.url;
|
||||
}
|
||||
});
|
||||
|
||||
exports.OriginalSourceFront = OriginalSourceFront;
|
||||
|
||||
/**
|
||||
* Corresponding client-side front for a MediaRuleActor.
|
||||
*/
|
||||
|
|
|
@ -190,7 +190,7 @@ const Types = exports.__TypesForTests = [
|
|||
front: "devtools/shared/fronts/styles",
|
||||
},
|
||||
{
|
||||
types: ["originalsource", "mediarule", "stylesheet", "stylesheets"],
|
||||
types: ["mediarule", "stylesheet", "stylesheets"],
|
||||
spec: "devtools/shared/specs/stylesheets",
|
||||
front: "devtools/shared/fronts/stylesheets",
|
||||
},
|
||||
|
|
|
@ -10,20 +10,6 @@ const {
|
|||
types
|
||||
} = require("devtools/shared/protocol");
|
||||
|
||||
const originalSourceSpec = generateActorSpec({
|
||||
typeName: "originalsource",
|
||||
|
||||
methods: {
|
||||
getText: {
|
||||
response: {
|
||||
text: RetVal("longstring")
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
exports.originalSourceSpec = originalSourceSpec;
|
||||
|
||||
const mediaRuleSpec = generateActorSpec({
|
||||
typeName: "mediarule",
|
||||
|
||||
|
@ -68,23 +54,6 @@ const styleSheetSpec = generateActorSpec({
|
|||
text: RetVal("longstring")
|
||||
}
|
||||
},
|
||||
getOriginalSources: {
|
||||
request: {},
|
||||
response: {
|
||||
originalSources: RetVal("nullable:array:originalsource")
|
||||
}
|
||||
},
|
||||
getOriginalLocation: {
|
||||
request: {
|
||||
line: Arg(0, "number"),
|
||||
column: Arg(1, "number")
|
||||
},
|
||||
response: RetVal(types.addDictType("originallocationresponse", {
|
||||
source: "string",
|
||||
line: "number",
|
||||
column: "number"
|
||||
}))
|
||||
},
|
||||
getMediaRules: {
|
||||
request: {},
|
||||
response: {
|
||||
|
|
Загрузка…
Ссылка в новой задаче