WebInspector.SnippetsModel = function()
{
this._snippets = {};
this._lastSnippetIdentifierSetting = WebInspector.settings.createSetting("lastSnippetIdentifier", 0);
this._snippetsSetting = WebInspector.settings.createSetting("snippets", []);
this._lastSnippetEvaluationIndexSetting = WebInspector.settings.createSetting("lastSnippetEvaluationIndex", 0);
this._loadSettings();
}
WebInspector.SnippetsModel.snippetsSourceURLPrefix = "snippets://";
WebInspector.SnippetsModel.EventTypes = {
SnippetAdded: "SnippetAdded",
SnippetWillBeEvaluated: "SnippetWillBeEvaluated",
SnippetRenamed: "SnippetRenamed",
SnippetRemoved: "SnippetRemoved",
}
WebInspector.SnippetsModel.prototype = {
_saveSettings: function()
{
var savedSnippets = [];
for (var id in this._snippets)
savedSnippets.push(this._snippets[id].serializeToObject());
this._snippetsSetting.set(savedSnippets);
},
get snippets()
{
var result = [];
for (var id in this._snippets)
result.push(this._snippets[id]);
return result;
},
_loadSettings: function()
{
var savedSnippets = this._snippetsSetting.get();
for (var i = 0; i < savedSnippets.length; ++i)
this._snippetAdded(WebInspector.Snippet.fromObject(savedSnippets[i]));
},
deleteSnippet: function(snippet)
{
delete this._snippets[snippet.id];
this._saveSettings();
this.dispatchEventToListeners(WebInspector.SnippetsModel.EventTypes.SnippetRemoved, snippet);
},
createSnippet: function()
{
var nextId = this._lastSnippetIdentifierSetting.get() + 1;
var snippetId = String(nextId);
this._lastSnippetIdentifierSetting.set(nextId);
var snippet = new WebInspector.Snippet(this, snippetId);
this._snippetAdded(snippet);
this._saveSettings();
return snippet;
},
_snippetAdded: function(snippet)
{
this._snippets[snippet.id] = snippet;
this.dispatchEventToListeners(WebInspector.SnippetsModel.EventTypes.SnippetAdded, snippet);
},
_snippetContentUpdated: function(snippetId)
{
this._saveSettings();
},
_snippetRenamed: function(snippet)
{
this._saveSettings();
this.dispatchEventToListeners(WebInspector.SnippetsModel.EventTypes.SnippetRenamed, snippet);
},
_evaluateSnippet: function(snippet)
{
this.dispatchEventToListeners(WebInspector.SnippetsModel.EventTypes.SnippetWillBeEvaluated, snippet);
var evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
var sourceURL = this._sourceURLForSnippet(snippet, evaluationIndex);
snippet._lastEvaluationSourceURL = sourceURL;
var expression = "\n//@ sourceURL=" + sourceURL + "\n" + snippet.content;
WebInspector.evaluateInConsole(expression, true);
},
_sourceURLForSnippet: function(snippet, evaluationIndex)
{
var snippetsPrefix = WebInspector.SnippetsModel.snippetsSourceURLPrefix;
var evaluationSuffix = evaluationIndex ? "_" + evaluationIndex : "";
return snippetsPrefix + snippet.id + evaluationSuffix;
},
snippetIdForSourceURL: function(sourceURL)
{
var snippetsPrefix = WebInspector.SnippetsModel.snippetsSourceURLPrefix;
if (!sourceURL.startsWith(snippetsPrefix))
return null;
var splittedURL = sourceURL.substring(snippetsPrefix.length).split("_");
var snippetId = splittedURL[0];
return snippetId;
},
snippetForSourceURL: function(sourceURL)
{
var snippetId = this.snippetIdForSourceURL(sourceURL);
if (!snippetId)
return null;
var snippet = this._snippets[snippetId];
if (!snippet || snippet._lastEvaluationSourceURL !== sourceURL)
return null;
return snippet;
}
}
WebInspector.SnippetsModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.Snippet = function(model, id, name, content)
{
this._model = model;
this._id = id;
this._name = name || "Snippet #" + id;
this._content = content || "";
}
WebInspector.Snippet.evaluatedSnippetExtraLinesCount = 2;
WebInspector.Snippet.fromObject = function(serializedSnippet)
{
return new WebInspector.Snippet(this, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content);
}
WebInspector.Snippet.prototype = {
get id()
{
return this._id;
},
get name()
{
return this._name;
},
set name(name)
{
if (this._name === name)
return;
this._name = name;
this._model._snippetRenamed(this);
},
get content()
{
return this._content;
},
set content(content)
{
if (this._content === content)
return;
this._content = content;
this._model._snippetContentUpdated(this._id);
},
evaluate: function()
{
this._model._evaluateSnippet(this);
},
serializeToObject: function()
{
var serializedSnippet = {};
serializedSnippet.id = this.id;
serializedSnippet.name = this.name;
serializedSnippet.content = this.content;
return serializedSnippet;
}
}
WebInspector.Snippet.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.SnippetsScriptMapping = function()
{
this._snippetForScriptId = {};
this._uiSourceCodeForScriptId = {};
this._scriptForUISourceCode = new Map();
this._uiSourceCodeForSnippet = new Map();
WebInspector.snippetsModel.addEventListener(WebInspector.SnippetsModel.EventTypes.SnippetAdded, this._handleSnippetAdded.bind(this));
WebInspector.snippetsModel.addEventListener(WebInspector.SnippetsModel.EventTypes.SnippetWillBeEvaluated, this._snippetWillBeEvaluated.bind(this));
WebInspector.snippetsModel.addEventListener(WebInspector.SnippetsModel.EventTypes.SnippetRemoved, this._snippetRemoved.bind(this));
for (var i = 0; i < WebInspector.snippetsModel.snippets.length; ++i)
this._snippetAdded(WebInspector.snippetsModel.snippets[i]);
}
WebInspector.SnippetsScriptMapping.prototype = {
rawLocationToUILocation: function(rawLocation)
{
var uiSourceCode = this._uiSourceCodeForScriptId[rawLocation.scriptId];
var snippet = this._snippetForScriptId[rawLocation.scriptId];
if (snippet) {
var uiLineNumber = rawLocation.lineNumber - WebInspector.Snippet.evaluatedSnippetExtraLinesCount;
return new WebInspector.UILocation(uiSourceCode, uiLineNumber, rawLocation.columnNumber || 0);
}
return new WebInspector.UILocation(uiSourceCode, rawLocation.lineNumber, rawLocation.columnNumber || 0);
},
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return null;
if (uiSourceCode.isSnippet) {
var rawLineNumber = lineNumber + WebInspector.Snippet.evaluatedSnippetExtraLinesCount;
return WebInspector.debuggerModel.createRawLocation(script, rawLineNumber, columnNumber);
}
return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},
uiSourceCodeList: function()
{
var result = this._uiSourceCodeForSnippet.values();
result = result.concat(this._releasedUISourceCodes());
return result;
},
_releasedUISourceCodes: function()
{
var result = [];
for (var scriptId in this._uiSourceCodeForScriptId) {
var uiSourceCode = this._uiSourceCodeForScriptId[scriptId];
if (uiSourceCode.isSnippet)
continue;
result.push(uiSourceCode);
}
return result;
},
addScript: function(script)
{
var snippet = WebInspector.snippetsModel.snippetForSourceURL(script.sourceURL);
if (!snippet) {
this._createUISourceCodeForScript(script);
return;
}
var uiSourceCode = this._uiSourceCodeForSnippet.get(snippet);
console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
this._snippetForScriptId[script.scriptId] = snippet;
this._scriptForUISourceCode.put(uiSourceCode, script);
script.setSourceMapping(this);
},
_handleSnippetAdded: function(event)
{
var snippet = event.data;
this._snippetAdded(snippet);
},
_snippetAdded: function(snippet)
{
var uiSourceCodeId = ""; var uiSourceCodeURL = ""; var uiSourceCode = new WebInspector.JavaScriptSource(uiSourceCodeId, uiSourceCodeURL, new WebInspector.SnippetContentProvider(snippet));
uiSourceCode.isSnippet = true;
uiSourceCode.isEditable = true;
this._uiSourceCodeForSnippet.put(snippet, uiSourceCode);
uiSourceCode.snippet = snippet;
var data = { removedItems: [], addedItems: [uiSourceCode] };
this.dispatchEventToListeners(WebInspector.ScriptMapping.Events.UISourceCodeListChanged, data);
},
_snippetWillBeEvaluated: function(event)
{
var snippet = event.data;
this._releaseSnippetScript(snippet);
},
_createUISourceCodeForScript: function(script)
{
var uiSourceCode = new WebInspector.JavaScriptSource(script.sourceURL, script.sourceURL, script);
uiSourceCode.isSnippetEvaluation = true;
var oldUISourceCode = this._uiSourceCodeForScriptId[script.scriptId];
this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
this._scriptForUISourceCode.put(uiSourceCode, script);
var data = { removedItems: [], addedItems: [uiSourceCode] };
this.dispatchEventToListeners(WebInspector.ScriptMapping.Events.UISourceCodeListChanged, data);
script.setSourceMapping(this);
},
_releaseSnippetScript: function(snippet)
{
var uiSourceCode = this._uiSourceCodeForSnippet.get(snippet);
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return;
delete this._uiSourceCodeForScriptId[script.scriptId];
delete this._snippetForScriptId[script.scriptId];
this._scriptForUISourceCode.remove(uiSourceCode);
this._createUISourceCodeForScript(script);
},
_snippetRemoved: function(event)
{
var snippet = event.data;
var uiSourceCode = this._uiSourceCodeForSnippet.get(snippet);
this._releaseSnippetScript(snippet);
this._uiSourceCodeForSnippet.remove(snippet);
var data = { removedItems: [uiSourceCode], addedItems: [] };
this.dispatchEventToListeners(WebInspector.ScriptMapping.Events.UISourceCodeListChanged, data);
},
reset: function()
{
var removedUISourceCodes = this._releasedUISourceCodes();
this._snippetForScriptId = {};
this._uiSourceCodeForScriptId = {};
this._scriptForUISourceCode = new Map();
var data = { removedItems: removedUISourceCodes, addedItems: [] };
this.dispatchEventToListeners(WebInspector.ScriptMapping.Events.UISourceCodeListChanged, data);
}
}
WebInspector.SnippetsScriptMapping.prototype.__proto__ = WebInspector.ScriptMapping.prototype;
WebInspector.SnippetContentProvider = function(snippet)
{
WebInspector.StaticContentProvider.call(this, "text/javascript", snippet.content);
}
WebInspector.SnippetContentProvider.prototype.__proto__ = WebInspector.StaticContentProvider.prototype;
WebInspector.snippetsModel = null;