Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
04b015e
use styleSheetAdded and styleSheetRemoved to replace deleted getAllSt…
jasonsanjose Feb 26, 2014
e2ef6eb
fix related doc ref count errors
jasonsanjose Feb 26, 2014
0905ca4
fallback to getAllStyleSheets if available
jasonsanjose Feb 26, 2014
02e2b10
add error handling when getAllStyleSheets is not found in inspector p…
jasonsanjose Feb 26, 2014
ab40ce0
do not change live dev status for inspector errors
jasonsanjose Feb 26, 2014
d2a8a82
account for styleSheetId changes after a CSSDocument reloads
jasonsanjose Feb 27, 2014
87bb739
remove styleSheetRemoved handler. handle weird chrome behavior where …
jasonsanjose Feb 27, 2014
24d3cf2
fix jslint error. Fix getSourceFromBrowser response. Remove debounce …
jasonsanjose Feb 28, 2014
8af9aee
fix failing unit tests. restore CSSDocument initial call to _updateBr…
jasonsanjose Feb 28, 2014
24a3969
Merge remote-tracking branch 'origin/master' into jasonsanjose/issue-…
jasonsanjose Feb 28, 2014
cbe4b09
remove extraneous reject for _openDeferred
jasonsanjose Feb 28, 2014
190f437
Ignore LiveDevelopment.close() if not active
jasonsanjose Feb 28, 2014
d2b33f5
Merge remote-tracking branch 'origin/master' into jasonsanjose/issue-…
redmunds Feb 28, 2014
4ac3e07
Merge branch 'jasonsanjose/issue-6830' of https://github.com/adobe/br…
redmunds Feb 28, 2014
00dde93
code review comments
jasonsanjose Mar 4, 2014
85b5d8c
Merge branch 'jasonsanjose/issue-6830' of https://github.com/adobe/br…
jasonsanjose Mar 4, 2014
d1a6752
Merge remote-tracking branch 'origin/master' into jasonsanjose/issue-…
jasonsanjose Mar 4, 2014
3cee9fe
fix async call to getLiveDocForPath
jasonsanjose Mar 4, 2014
ac80eca
update unit test spy for API change
jasonsanjose Mar 5, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 106 additions & 25 deletions src/LiveDevelopment/Agents/CSSAgent.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,25 @@
/**
* CSSAgent keeps track of loaded style sheets and allows reloading them
* from a {Document}.
*
* CSSAgent dispatches styleSheetAdded and styleSheetRemoved events, passing
* the URL for the added/removed style sheet.
*/

define(function CSSAgent(require, exports, module) {
"use strict";

require("thirdparty/path-utils/path-utils.min");

var Inspector = require("LiveDevelopment/Inspector/Inspector");

var _load; // {$.Deferred} load promise
var _urlToStyle; // {url -> loaded} style definition
/** @type {Object.<string, CSS.CSSStyleSheetHeader>} */
var _urlToStyle;

/** @type {Object.<string, string>} */
var _styleSheetIdToUrl;

/** @type {boolean} */
var _getAllStyleSheetsNotFound = false;

/**
* Create a canonicalized version of the given URL, stripping off query strings and hashes.
Expand All @@ -49,34 +57,29 @@ define(function CSSAgent(require, exports, module) {
return PathUtils.parseUrl(url).hrefNoSearch;
}

// WebInspector Event: Page.loadEventFired
function _onLoadEventFired(event, res) {
// res = {timestamp}
/**
* @private
* WebInspector Event: Page.frameNavigated
* @param {jQuery.Event} event
* @param {frame: Frame} res
*/
function _onFrameNavigated(event, res) {
// Clear maps when navigating to a new page
_urlToStyle = {};
Inspector.CSS.enable().done(function () {
Inspector.CSS.getAllStyleSheets(function onGetAllStyleSheets(res) {
var i, header;
for (i in res.headers) {
header = res.headers[i];
_urlToStyle[_canonicalize(header.sourceURL)] = header;
}
_load.resolve();
});
});
_styleSheetIdToUrl = {};
}

/** Get a style sheet for a url
* @param {string} url
*/
function styleForURL(url) {
if (_urlToStyle) {
return _urlToStyle[_canonicalize(url)];
}

return null;
return _urlToStyle[_canonicalize(url)];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since code no longer checks if (_urlToStyle) then _urlToStyle should be initialized to _urlToStyle = {} on line 43 to be safe. Same for _styleSheetIdToUrl.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}

/** Get a list of all loaded stylesheet files by URL */
/**
* @deprecated Use styleSheetAdded and styleSheetRemoved events
* Get a list of all loaded stylesheet files by URL
*/
function getStylesheetURLs() {
var urls = [], url;
for (url in _urlToStyle) {
Expand Down Expand Up @@ -104,20 +107,98 @@ define(function CSSAgent(require, exports, module) {
console.assert(style, "Style Sheet for document not loaded: " + doc.url);
Inspector.CSS.setStyleSheetText(style.styleSheetId, "");
}

/**
* @private
* @param {jQuery.Event} event
* @param {header: CSSStyleSheetHeader}
*/
function _styleSheetAdded(event, res) {
if (!_urlToStyle) {
return;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the initialization: _urlToStyle = {} is done as mentioned in this comment, then no need to check if (!_urlToStyle) here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


var url = _canonicalize(res.header.sourceURL),
existing = _urlToStyle[url];

// detect duplicates
if (existing && existing.styleSheetId === res.header.styleSheetId) {
return;
}

_urlToStyle[url] = res.header;
_styleSheetIdToUrl[res.header.styleSheetId] = url;

$(exports).triggerHandler("styleSheetAdded", [url]);
}

/**
* @private
* @param {jQuery.Event} event
* @param {styleSheetId: StyleSheetId}
*/
function _styleSheetRemoved(event, res) {
if (!_urlToStyle) {
return;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer necessary to check for existence of _urlToStyle object.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


var url = _styleSheetIdToUrl[res.styleSheetId];

if (url) {
delete _urlToStyle[url];
}

delete _styleSheetIdToUrl[res.styleSheetId];

$(exports).triggerHandler("styleSheetRemoved", [url]);
}

/**
* @private
* Attempt to use deleted API CSS.getAllStyleSheets
* @param {jQuery.Event} event
* @param {frameId: Network.FrameId}
*/
function _onFrameStoppedLoading(event, res) {
// Manually fire getAllStyleSheets since it will be removed from
// Inspector.json in a future update
Inspector.send("CSS", "getAllStyleSheets").done(function (res) {
res.headers.forEach(function (header) {
// _styleSheetAdded will ignore duplicates
_styleSheetAdded(null, { header: header });
});
}).fail(function (err) {
// Disable getAllStyleSheets if the first call fails
_getAllStyleSheetsNotFound = (err.code === -32601);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe write to console.log if it's some other error code?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do this already in the _onError handling in LiveDevelopment.

$(Inspector.Page).off("frameStoppedLoading.CSSAgent", _onFrameStoppedLoading);
});
}

/** Enable the domain */
function enable() {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allow enable during LiveDevelopment _onInterstitialPageLoad(). The old behavior would wait all the way until loadEventFired to enable the CSS domain. This also allows loadAgents() to complete faster since we no longer wait for the sequence of (1) loadEventFired, (2) enable and (3) getAllStylesheets.

return Inspector.CSS.enable();
}

/** Initialize the agent */
function load() {
_load = new $.Deferred();
$(Inspector.Page).on("loadEventFired.CSSAgent", _onLoadEventFired);
return _load.promise();
$(Inspector.Page).on("frameNavigated.CSSAgent", _onFrameNavigated);
$(Inspector.CSS).on("styleSheetAdded.CSSAgent", _styleSheetAdded);
$(Inspector.CSS).on("styleSheetRemoved.CSSAgent", _styleSheetRemoved);

// getAllStyleSheets was deleted beginning with Chrome 34
if (!_getAllStyleSheetsNotFound) {
$(Inspector.Page).on("frameStoppedLoading.CSSAgent", _onFrameStoppedLoading);
}
}

/** Clean up */
function unload() {
$(Inspector.Page).off(".CSSAgent");
$(Inspector.CSS).off(".CSSAgent");
}

// Export public functions
exports.enable = enable;
exports.styleForURL = styleForURL;
exports.getStylesheetURLs = getStylesheetURLs;
exports.reloadCSSForDocument = reloadCSSForDocument;
Expand Down
58 changes: 42 additions & 16 deletions src/LiveDevelopment/Inspector/Inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,12 @@ define(function Inspector(require, exports, module) {
} else {
var deferred = new $.Deferred();
promise = deferred.promise();
callback = function (result) {
deferred.resolve(result);
callback = function (result, error) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently we never had error callback handling from the inspector protocol.

if (error) {
deferred.reject(error);
} else {
deferred.resolve(result);
}
};
}

Expand All @@ -144,16 +148,30 @@ define(function Inspector(require, exports, module) {

// verify the parameters against the method signature
// this also constructs the params object of type {name -> value}
for (i in signature) {
if (_verifySignature(args[i], signature[i])) {
params[signature[i].name] = args[i];
if (signature) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signature is omitted for direct calls to the new send method.

for (i in signature) {
if (_verifySignature(args[i], signature[i])) {
params[signature[i].name] = args[i];
}
}
}

_socket.send(JSON.stringify({ method: method, id: id, params: params }));

return promise;
}

/**
* Manually send a message to the remote debugger
* All passed arguments after the command are passed on as parameters.
* If the last argument is a function, it is used as the callback function.
* @param {string} domain
* @param {string} command
*/
function send(domain, command, varargs) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New public API for arbitrary API calls to the inspector protocol. This allows APIs not defined currently in our copy of Inspector.json to be called.

return _send(domain + "." + command, null, varargs);
}

/** WebSocket did close */
function _onDisconnect() {
_socket = undefined;
Expand Down Expand Up @@ -186,20 +204,27 @@ define(function Inspector(require, exports, module) {
* @param {object} message
*/
function _onMessage(message) {
var response = JSON.parse(message.data);
var response = JSON.parse(message.data),
callback = _messageCallbacks[response.id];

if (callback) {
// Messages with an ID are a response to a command, fire callback
callback(response.result, response.error);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old behavior would only fire an error event from Inspector. This new behavior will respond back to the caller (via callback or promise) passing in an error argument. We still fire an error event for backwards compatibility.

The new error callback is used when testing availability of CSS.getAllStyleSheets.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add comment to the code about "We still fire an error event for backwards compatibility" to help us clean it up some day.

delete _messageCallbacks[response.id];
} else if (response.method) {
// Messages with a method are an event, trigger event handlers
var domainAndMethod = response.method.split("."),
domain = domainAndMethod[0],
method = domainAndMethod[1];

$(exports[domain]).triggerHandler(method, response.params);
}

// Always fire event handlers for all messages/errors
$exports.triggerHandler("message", [response]);

if (response.error) {
$exports.triggerHandler("error", [response.error]);
} else if (response.result) {
if (_messageCallbacks[response.id]) {
_messageCallbacks[response.id](response.result);
delete _messageCallbacks[response.id];
}
} else {
var domainAndMethod = response.method.split(".");
var domain = domainAndMethod[0];
var method = domainAndMethod[1];
$(exports[domain]).triggerHandler(method, response.params);
}
}

Expand Down Expand Up @@ -363,5 +388,6 @@ define(function Inspector(require, exports, module) {
exports.connect = connect;
exports.connectToURL = connectToURL;
exports.connected = connected;
exports.send = send;
exports.init = init;
});
Loading