UNPKG

occaecatidicta

Version:
473 lines (416 loc) 15.6 kB
/* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor * @extends {WebInspector.Object} */ 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); }, _loadSettings: function() { var savedSnippets = this._snippetsSetting.get(); for (var i = 0; i < savedSnippets.length; ++i) this._snippetAdded(WebInspector.Snippet.fromObject(savedSnippets[i])); }, /** * @param {WebInspector.Snippet} snippet */ deleteSnippet: function(snippet) { delete this._snippets[snippet.id]; this._saveSettings(); this.dispatchEventToListeners(WebInspector.SnippetsModel.EventTypes.SnippetRemoved, snippet); }, /** * @return {WebInspector.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; }, /** * @param {WebInspector.Snippet} snippet */ _snippetAdded: function(snippet) { this._snippets[snippet.id] = snippet; this.dispatchEventToListeners(WebInspector.SnippetsModel.EventTypes.SnippetAdded, snippet); }, /** * @param {string} snippetId */ _snippetContentUpdated: function(snippetId) { this._saveSettings(); }, /** * @param {WebInspector.Snippet} snippet */ _snippetRenamed: function(snippet) { this._saveSettings(); this.dispatchEventToListeners(WebInspector.SnippetsModel.EventTypes.SnippetRenamed, snippet); }, /** * @param {WebInspector.Snippet} 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); }, /** * @param {WebInspector.Snippet} snippet * @param {string} evaluationIndex * @return {string} */ _sourceURLForSnippet: function(snippet, evaluationIndex) { var snippetsPrefix = WebInspector.SnippetsModel.snippetsSourceURLPrefix; var evaluationSuffix = evaluationIndex ? "_" + evaluationIndex : ""; return snippetsPrefix + snippet.id + evaluationSuffix; }, /** * @param {string} sourceURL * @return {string|null} */ snippetIdForSourceURL: function(sourceURL) { var snippetsPrefix = WebInspector.SnippetsModel.snippetsSourceURLPrefix; if (sourceURL.indexOf(snippetsPrefix) !== 0) return null; var splittedURL = sourceURL.substring(snippetsPrefix.length).split("_"); var snippetId = splittedURL[0]; return snippetId; }, /** * @param {string} sourceURL * @return {WebInspector.Snippet|null} */ 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; /** * @constructor * @extends {WebInspector.Object} * @param {WebInspector.SnippetsModel} model * @param {string} id * @param {string=} name * @param {string=} content */ 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; /** * @param {Object} serializedSnippet * @return {WebInspector.Snippet} */ WebInspector.Snippet.fromObject = function(serializedSnippet) { return new WebInspector.Snippet(this, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content); } WebInspector.Snippet.prototype = { /** * @type {number} */ get id() { return this._id; }, /** * @type {string} */ get name() { return this._name; }, set name(name) { if (this._name === name) return; this._name = name; this._model._snippetRenamed(this); }, /** * @type {string} */ 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); }, /** * @return {Object} */ 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; /** * @constructor * @extends {WebInspector.ScriptMapping} */ WebInspector.SnippetsScriptMapping = function() { this._snippetForScriptId = {}; this._uiSourceCodeForScriptId = {}; this._scriptForUISourceCode = new Map(); this._uiSourceCodeForSnippet = new Map(); WebInspector.snippetsModel.addEventListener(WebInspector.SnippetsModel.EventTypes.SnippetAdded, this._snippetAdded.bind(this)); WebInspector.snippetsModel.addEventListener(WebInspector.SnippetsModel.EventTypes.SnippetWillBeEvaluated, this._snippetWillBeEvaluated.bind(this)); WebInspector.snippetsModel.addEventListener(WebInspector.SnippetsModel.EventTypes.SnippetRemoved, this._snippetRemoved.bind(this)); } WebInspector.SnippetsScriptMapping.prototype = { /** * @param {DebuggerAgent.Location} rawLocation * @return {WebInspector.UILocation} */ 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); }, /** * @param {WebInspector.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber * @return {DebuggerAgent.Location} */ 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); }, /** * @return {Array.<WebInspector.UISourceCode>} */ uiSourceCodeList: function() { var result = []; for (var uiSourceCode in this._uiSourceCodeForSnippet.values()) result.push(uiSourceCode); result = result.concat(this._releasedUISourceCodes()); return result; }, /** * @return {Array.<WebInspector.UISourceCode>} */ _releasedUISourceCodes: function() { var result = []; for (var scriptId in this._uiSourceCodeForScriptId) { var uiSourceCode = this._uiSourceCodeForScriptId[scriptId]; if (uiSourceCode.isSnippet) continue; result.push(uiSourceCode); } return result; }, /** * @param {WebInspector.Script} script */ 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); var data = { scriptId: script.scriptId, uiSourceCodes: [uiSourceCode] }; this.dispatchEventToListeners(WebInspector.ScriptMapping.Events.ScriptBound, data); }, /** * @param {WebInspector.Event} event */ _snippetAdded: function(event) { var snippet = /** @type {WebInspector.Snippet} */ event.data; var uiSourceCodeId = ""; // FIXME: to be implemented. var uiSourceCodeURL = ""; // FIXME: to be implemented. var uiSourceCode = new WebInspector.UISourceCodeImpl(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); }, /** * @param {WebInspector.Event} event */ _snippetWillBeEvaluated: function(event) { var snippet = /** @type {WebInspector.Snippet} */ event.data; this._releaseSnippetScript(snippet); }, /** * @param {WebInspector.Script} script */ _createUISourceCodeForScript: function(script) { var uiSourceCode = new WebInspector.UISourceCodeImpl(script.sourceURL, script.sourceURL, new WebInspector.ScriptContentProvider(script)); uiSourceCode.isSnippetEvaluation = true; var oldUISourceCode = this._uiSourceCodeForScriptId[script.scriptId]; this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode; this._scriptForUISourceCode.put(uiSourceCode, script); var data = { scriptId: script.scriptId, uiSourceCodes: [oldUISourceCode] }; this.dispatchEventToListeners(WebInspector.ScriptMapping.Events.ScriptUnbound, data); var data = { removedItems: [], addedItems: [uiSourceCode] }; this.dispatchEventToListeners(WebInspector.ScriptMapping.Events.UISourceCodeListChanged, data); var data = { scriptId: script.scriptId, uiSourceCodes: [uiSourceCode] }; this.dispatchEventToListeners(WebInspector.ScriptMapping.Events.ScriptBound, data); }, /** * @param {WebInspector.Snippet} snippet */ _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); }, /** * @param {WebInspector.Event} event */ _snippetRemoved: function(event) { var snippet = /** @type {WebInspector.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; /** * @constructor * @extends {WebInspector.StaticContentProvider} * @param {WebInspector.Snippet} snippet */ WebInspector.SnippetContentProvider = function(snippet) { WebInspector.StaticContentProvider.call(this, "text/javascript", snippet.content); } WebInspector.SnippetContentProvider.prototype.__proto__ = WebInspector.StaticContentProvider.prototype; /** * @type {?WebInspector.SnippetsModel} */ WebInspector.snippetsModel = null;