GotoAgent constructs and responds to the in-browser goto dialog.
Get the file component of the given url
function _fileFromURL(url) {
var comp = url.split("/");
return comp[comp.length - 1];
}
Make the given css rule a target for goto
function _makeCSSTarget(targets, rule) {
if (rule.sourceURL) {
var url = rule.sourceURL;
url += ":" + rule.style.range.start;
var name = rule.selectorList.text;
var file = _fileFromURL(url);
targets.push({"type": "css", "url": url, "name": name, "file": file});
}
}
Make the given node a target for goto
function _makeHTMLTarget(targets, node) {
if (node.location) {
var url = DOMAgent.url;
var location = node.location;
if (node.canHaveChildren()) {
location += node.length;
}
url += ":" + location;
var name = "<" + node.name + ">";
var file = _fileFromURL(url);
targets.push({"type": "html", "url": url, "name": name, "file": file});
}
}
Make the given javascript callFrame the target for goto
function _makeJSTarget(targets, callFrame) {
var script = ScriptAgent.scriptWithId(callFrame.location.scriptId);
if (script && script.url) {
var url = script.url;
url += ":" + callFrame.location.lineNumber + "," + callFrame.location.columnNumber;
var name = callFrame.functionName;
if (name === "") {
name = "anonymous function";
}
var file = _fileFromURL(url);
targets.push({"type": "js", "url": url, "name": name, "file": file});
}
}
Go to the given source node
function _onRemoteGoto(event, res) {
// res = {nodeId, name, value}
var location, url = res.value;
var matches = /^(.*):([^:]+)$/.exec(url);
if (matches) {
url = matches[1];
location = matches[2].split(",");
if (location.length === 1) {
location = parseInt(location[0], 10);
} else {
location = { line: parseInt(location[0], 10), ch: parseInt(location[1], 10) };
}
}
open(url, location);
}
Gather options where to go to from the given source node
function _onRemoteShowGoto(event, res) {
// res = {nodeId, name, value}
var node = DOMAgent.nodeWithId(res.nodeId);
// get all css rules that apply to the given node
Inspector.CSS.getMatchedStylesForNode(node.nodeId, function onMatchedStyles(res) {
var i, targets = [];
_makeHTMLTarget(targets, node);
for (i in node.trace) {
_makeJSTarget(targets, node.trace[i]);
}
for (i in node.events) {
var trace = node.events[i];
_makeJSTarget(targets, trace.callFrames[0]);
}
for (i in res.matchedCSSRules.reverse()) {
_makeCSSTarget(targets, res.matchedCSSRules[i].rule);
}
RemoteAgent.call("showGoto", targets);
});
}
Return the URL without the query string
function _urlWithoutQueryString(url) {
var index = url.search(/[#\?]/);
if (index >= 0) {
url = url.substr(0, index);
}
return url;
}
Initialize the agent
function load() {
RemoteAgent
.on("showgoto.GotoAgent", _onRemoteShowGoto)
.on("goto.GotoAgent", _onRemoteGoto);
}
Open the editor at the given url and editor location
function open(url, location, noFlash) {
console.assert(url.substr(0, 7) === "file://", "Cannot open non-file URLs");
var result = new $.Deferred();
url = _urlWithoutQueryString(url);
// Extract the path, also strip the third slash when on Windows
var path = url.slice(brackets.platform === "win" ? 8 : 7);
// URL-decode the path ('%20' => ' ')
path = decodeURI(path);
var promise = CommandManager.execute(Commands.FILE_OPEN, {fullPath: path});
promise.done(function onDone(doc) {
if (location) {
openLocation(location, noFlash);
}
result.resolve();
});
promise.fail(function onErr(err) {
console.error(err);
result.reject(err);
});
return result.promise();
}
Point the master editor to the given location
function openLocation(location, noFlash) {
var editor = EditorManager.getCurrentFullEditor();
var codeMirror = editor._codeMirror;
if (typeof location === "number") {
location = codeMirror.posFromIndex(location);
}
codeMirror.setCursor(location);
editor.focus();
if (!noFlash) {
codeMirror.addLineClass(location.line, "wrap", "flash");
window.setTimeout(function () {
codeMirror.removeLineClass(location.line, "wrap", "flash");
}, 1000);
}
}