summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js')
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js779
1 files changed, 779 insertions, 0 deletions
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js
new file mode 100644
index 00000000000..4670b5e9e04
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js
@@ -0,0 +1,779 @@
+/*
+ * 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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
+ * @param {string} parentPath
+ * @param {string} name
+ * @param {string} originURL
+ * @param {string} url
+ * @param {!WebInspector.ResourceType} contentType
+ */
+WebInspector.FileDescriptor = function(parentPath, name, originURL, url, contentType)
+{
+ this.parentPath = parentPath;
+ this.name = name;
+ this.originURL = originURL;
+ this.url = url;
+ this.contentType = contentType;
+}
+
+/**
+ * @interface
+ */
+WebInspector.ProjectDelegate = function() { }
+
+WebInspector.ProjectDelegate.prototype = {
+ /**
+ * @return {string}
+ */
+ type: function() { },
+
+ /**
+ * @return {string}
+ */
+ displayName: function() { },
+
+ /**
+ * @param {string} path
+ * @param {function(?Date, ?number)} callback
+ */
+ requestMetadata: function(path, callback) { },
+
+ /**
+ * @param {string} path
+ * @param {function(?string)} callback
+ */
+ requestFileContent: function(path, callback) { },
+
+ /**
+ * @return {boolean}
+ */
+ canSetFileContent: function() { },
+
+ /**
+ * @param {string} path
+ * @param {string} newContent
+ * @param {function(?string)} callback
+ */
+ setFileContent: function(path, newContent, callback) { },
+
+ /**
+ * @return {boolean}
+ */
+ canRename: function() { },
+
+ /**
+ * @param {string} path
+ * @param {string} newName
+ * @param {function(boolean, string=, string=, string=, !WebInspector.ResourceType=)} callback
+ */
+ rename: function(path, newName, callback) { },
+
+ /**
+ * @param {string} path
+ */
+ refresh: function(path) { },
+
+ /**
+ * @param {string} path
+ */
+ excludeFolder: function(path) { },
+
+ /**
+ * @param {string} path
+ * @param {?string} name
+ * @param {string} content
+ * @param {function(?string)} callback
+ */
+ createFile: function(path, name, content, callback) { },
+
+ /**
+ * @param {string} path
+ */
+ deleteFile: function(path) { },
+
+ remove: function() { },
+
+ /**
+ * @param {string} path
+ * @param {string} query
+ * @param {boolean} caseSensitive
+ * @param {boolean} isRegex
+ * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
+ */
+ searchInFileContent: function(path, query, caseSensitive, isRegex, callback) { },
+
+ /**
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
+ * @param {!WebInspector.Progress} progress
+ * @param {function(!Array.<string>)} callback
+ */
+ findFilesMatchingSearchRequest: function(searchConfig, progress, callback) { },
+
+ /**
+ * @param {!WebInspector.Progress} progress
+ */
+ indexContent: function(progress) { }
+}
+
+/**
+ * @interface
+ */
+WebInspector.ProjectSearchConfig = function() {}
+
+WebInspector.ProjectSearchConfig.prototype = {
+ /**
+ * @return {string}
+ */
+ query: function() { },
+
+ /**
+ * @return {boolean}
+ */
+ ignoreCase: function() { },
+
+ /**
+ * @return {boolean}
+ */
+ isRegex: function() { },
+
+ /**
+ * @return {!Array.<string>}
+ */
+ queries: function() { },
+
+ /**
+ * @param {string} filePath
+ * @return {boolean}
+ */
+ filePathMatchesFileQuery: function(filePath) { }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.Project} project
+ */
+WebInspector.ProjectStore = function(project)
+{
+ this._project = project;
+}
+
+WebInspector.ProjectStore.prototype = {
+ /**
+ * @param {!WebInspector.FileDescriptor} fileDescriptor
+ */
+ addFile: function(fileDescriptor)
+ {
+ this._project._addFile(fileDescriptor);
+ },
+
+ /**
+ * @param {string} path
+ */
+ removeFile: function(path)
+ {
+ this._project._removeFile(path);
+ },
+
+ /**
+ * @return {!WebInspector.Project}
+ */
+ project: function()
+ {
+ return this._project;
+ }
+}
+
+/**
+ * @param {!WebInspector.Workspace} workspace
+ * @param {string} projectId
+ * @param {!WebInspector.ProjectDelegate} projectDelegate
+ * @constructor
+ */
+WebInspector.Project = function(workspace, projectId, projectDelegate)
+{
+ /** @type {!Object.<string, !{uiSourceCode: !WebInspector.UISourceCode, index: number}>} */
+ this._uiSourceCodesMap = {};
+ /** @type {!Array.<!WebInspector.UISourceCode>} */
+ this._uiSourceCodesList = [];
+ this._workspace = workspace;
+ this._projectId = projectId;
+ this._projectDelegate = projectDelegate;
+ this._displayName = this._projectDelegate.displayName();
+}
+
+WebInspector.Project.prototype = {
+ /**
+ * @return {string}
+ */
+ id: function()
+ {
+ return this._projectId;
+ },
+
+ /**
+ * @return {string}
+ */
+ type: function()
+ {
+ return this._projectDelegate.type();
+ },
+
+ /**
+ * @return {string}
+ */
+ displayName: function()
+ {
+ return this._displayName;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isServiceProject: function()
+ {
+ return this._projectDelegate.type() === WebInspector.projectTypes.Debugger || this._projectDelegate.type() === WebInspector.projectTypes.Formatter || this._projectDelegate.type() === WebInspector.projectTypes.LiveEdit;
+ },
+
+ /**
+ * @param {!WebInspector.FileDescriptor} fileDescriptor
+ */
+ _addFile: function(fileDescriptor)
+ {
+ var path = fileDescriptor.parentPath ? fileDescriptor.parentPath + "/" + fileDescriptor.name : fileDescriptor.name;
+ var uiSourceCode = this.uiSourceCode(path);
+ if (uiSourceCode)
+ return;
+
+ uiSourceCode = new WebInspector.UISourceCode(this, fileDescriptor.parentPath, fileDescriptor.name, fileDescriptor.originURL, fileDescriptor.url, fileDescriptor.contentType);
+
+ this._uiSourceCodesMap[path] = {uiSourceCode: uiSourceCode, index: this._uiSourceCodesList.length};
+ this._uiSourceCodesList.push(uiSourceCode);
+ this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeAdded, uiSourceCode);
+ },
+
+ /**
+ * @param {string} path
+ */
+ _removeFile: function(path)
+ {
+ var uiSourceCode = this.uiSourceCode(path);
+ if (!uiSourceCode)
+ return;
+
+ var entry = this._uiSourceCodesMap[path];
+ var movedUISourceCode = this._uiSourceCodesList[this._uiSourceCodesList.length - 1];
+ this._uiSourceCodesList[entry.index] = movedUISourceCode;
+ var movedEntry = this._uiSourceCodesMap[movedUISourceCode.path()];
+ movedEntry.index = entry.index;
+ this._uiSourceCodesList.splice(this._uiSourceCodesList.length - 1, 1);
+ delete this._uiSourceCodesMap[path];
+ this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeRemoved, entry.uiSourceCode);
+ },
+
+ _remove: function()
+ {
+ this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectRemoved, this);
+ this._uiSourceCodesMap = {};
+ this._uiSourceCodesList = [];
+ },
+
+ /**
+ * @return {!WebInspector.Workspace}
+ */
+ workspace: function()
+ {
+ return this._workspace;
+ },
+
+ /**
+ * @param {string} path
+ * @return {?WebInspector.UISourceCode}
+ */
+ uiSourceCode: function(path)
+ {
+ var entry = this._uiSourceCodesMap[path];
+ return entry ? entry.uiSourceCode : null;
+ },
+
+ /**
+ * @param {string} originURL
+ * @return {?WebInspector.UISourceCode}
+ */
+ uiSourceCodeForOriginURL: function(originURL)
+ {
+ for (var i = 0; i < this._uiSourceCodesList.length; ++i) {
+ var uiSourceCode = this._uiSourceCodesList[i];
+ if (uiSourceCode.originURL() === originURL)
+ return uiSourceCode;
+ }
+ return null;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.UISourceCode>}
+ */
+ uiSourceCodes: function()
+ {
+ return this._uiSourceCodesList;
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {function(?Date, ?number)} callback
+ */
+ requestMetadata: function(uiSourceCode, callback)
+ {
+ this._projectDelegate.requestMetadata(uiSourceCode.path(), callback);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {function(?string)} callback
+ */
+ requestFileContent: function(uiSourceCode, callback)
+ {
+ this._projectDelegate.requestFileContent(uiSourceCode.path(), callback);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ canSetFileContent: function()
+ {
+ return this._projectDelegate.canSetFileContent();
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {string} newContent
+ * @param {function(?string)} callback
+ */
+ setFileContent: function(uiSourceCode, newContent, callback)
+ {
+ this._projectDelegate.setFileContent(uiSourceCode.path(), newContent, onSetContent.bind(this));
+
+ /**
+ * @param {?string} content
+ * @this {WebInspector.Project}
+ */
+ function onSetContent(content)
+ {
+ this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeContentCommitted, { uiSourceCode: uiSourceCode, content: newContent });
+ callback(content);
+ }
+ },
+
+ /**
+ * @return {boolean}
+ */
+ canRename: function()
+ {
+ return this._projectDelegate.canRename();
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {string} newName
+ * @param {function(boolean, string=, string=, string=, !WebInspector.ResourceType=)} callback
+ */
+ rename: function(uiSourceCode, newName, callback)
+ {
+ if (newName === uiSourceCode.name()) {
+ callback(true, uiSourceCode.name(), uiSourceCode.url, uiSourceCode.originURL(), uiSourceCode.contentType());
+ return;
+ }
+
+ this._projectDelegate.rename(uiSourceCode.path(), newName, innerCallback.bind(this));
+
+ /**
+ * @param {boolean} success
+ * @param {string=} newName
+ * @param {string=} newURL
+ * @param {string=} newOriginURL
+ * @param {!WebInspector.ResourceType=} newContentType
+ * @this {WebInspector.Project}
+ */
+ function innerCallback(success, newName, newURL, newOriginURL, newContentType)
+ {
+ if (!success || !newName) {
+ callback(false);
+ return;
+ }
+ var oldPath = uiSourceCode.path();
+ var newPath = uiSourceCode.parentPath() ? uiSourceCode.parentPath() + "/" + newName : newName;
+ this._uiSourceCodesMap[newPath] = this._uiSourceCodesMap[oldPath];
+ delete this._uiSourceCodesMap[oldPath];
+ callback(true, newName, newURL, newOriginURL, newContentType);
+ }
+ },
+
+ /**
+ * @param {string} path
+ */
+ refresh: function(path)
+ {
+ this._projectDelegate.refresh(path);
+ },
+
+ /**
+ * @param {string} path
+ */
+ excludeFolder: function(path)
+ {
+ this._projectDelegate.excludeFolder(path);
+ var uiSourceCodes = this._uiSourceCodesList.slice();
+ for (var i = 0; i < uiSourceCodes.length; ++i) {
+ var uiSourceCode = uiSourceCodes[i];
+ if (uiSourceCode.path().startsWith(path.substr(1)))
+ this._removeFile(uiSourceCode.path());
+ }
+ },
+
+ /**
+ * @param {string} path
+ * @param {?string} name
+ * @param {string} content
+ * @param {function(?string)} callback
+ */
+ createFile: function(path, name, content, callback)
+ {
+ this._projectDelegate.createFile(path, name, content, innerCallback);
+
+ function innerCallback(filePath)
+ {
+ callback(filePath);
+ }
+ },
+
+ /**
+ * @param {string} path
+ */
+ deleteFile: function(path)
+ {
+ this._projectDelegate.deleteFile(path);
+ },
+
+ remove: function()
+ {
+ this._projectDelegate.remove();
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {string} query
+ * @param {boolean} caseSensitive
+ * @param {boolean} isRegex
+ * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
+ */
+ searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback)
+ {
+ this._projectDelegate.searchInFileContent(uiSourceCode.path(), query, caseSensitive, isRegex, callback);
+ },
+
+ /**
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
+ * @param {!WebInspector.Progress} progress
+ * @param {function(!Array.<string>)} callback
+ */
+ findFilesMatchingSearchRequest: function(searchConfig, progress, callback)
+ {
+ this._projectDelegate.findFilesMatchingSearchRequest(searchConfig, progress, callback);
+ },
+
+ /**
+ * @param {!WebInspector.Progress} progress
+ */
+ indexContent: function(progress)
+ {
+ this._projectDelegate.indexContent(progress);
+ }
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.projectTypes = {
+ Debugger: "debugger",
+ Formatter: "formatter",
+ LiveEdit: "liveedit",
+ Network: "network",
+ Snippets: "snippets",
+ FileSystem: "filesystem",
+ ContentScripts: "contentscripts"
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {!WebInspector.FileSystemMapping} fileSystemMapping
+ */
+WebInspector.Workspace = function(fileSystemMapping)
+{
+ this._fileSystemMapping = fileSystemMapping;
+ /** @type {!Object.<string, !WebInspector.Project>} */
+ this._projects = {};
+ this._hasResourceContentTrackingExtensions = false;
+}
+
+WebInspector.Workspace.Events = {
+ UISourceCodeAdded: "UISourceCodeAdded",
+ UISourceCodeRemoved: "UISourceCodeRemoved",
+ UISourceCodeContentCommitted: "UISourceCodeContentCommitted",
+ ProjectRemoved: "ProjectRemoved"
+}
+
+WebInspector.Workspace.prototype = {
+ /**
+ * @return {!Array.<!WebInspector.UISourceCode>}
+ */
+ unsavedSourceCodes: function()
+ {
+ function filterUnsaved(sourceCode)
+ {
+ return sourceCode.isDirty();
+ }
+ return this.uiSourceCodes().filter(filterUnsaved);
+ },
+
+ /**
+ * @param {string} projectId
+ * @param {string} path
+ * @return {?WebInspector.UISourceCode}
+ */
+ uiSourceCode: function(projectId, path)
+ {
+ var project = this._projects[projectId];
+ return project ? project.uiSourceCode(path) : null;
+ },
+
+ /**
+ * @param {string} originURL
+ * @return {?WebInspector.UISourceCode}
+ */
+ uiSourceCodeForOriginURL: function(originURL)
+ {
+ var projects = this.projectsForType(WebInspector.projectTypes.Network);
+ projects = projects.concat(this.projectsForType(WebInspector.projectTypes.ContentScripts));
+ for (var i = 0; i < projects.length; ++i) {
+ var project = projects[i];
+ var uiSourceCode = project.uiSourceCodeForOriginURL(originURL);
+ if (uiSourceCode)
+ return uiSourceCode;
+ }
+ return null;
+ },
+
+ /**
+ * @param {string} type
+ * @return {!Array.<!WebInspector.UISourceCode>}
+ */
+ uiSourceCodesForProjectType: function(type)
+ {
+ var result = [];
+ for (var projectName in this._projects) {
+ var project = this._projects[projectName];
+ if (project.type() === type)
+ result = result.concat(project.uiSourceCodes());
+ }
+ return result;
+ },
+
+ /**
+ * @param {string} projectId
+ * @param {!WebInspector.ProjectDelegate} projectDelegate
+ * @return {!WebInspector.ProjectStore}
+ */
+ addProject: function(projectId, projectDelegate)
+ {
+ var project = new WebInspector.Project(this, projectId, projectDelegate);
+ this._projects[projectId] = project;
+ var projectStore = new WebInspector.ProjectStore(project);
+ return projectStore;
+ },
+
+ /**
+ * @param {string} projectId
+ */
+ removeProject: function(projectId)
+ {
+ var project = this._projects[projectId];
+ if (!project)
+ return;
+ delete this._projects[projectId];
+ project._remove();
+ },
+
+ /**
+ * @param {string} projectId
+ * @return {!WebInspector.Project}
+ */
+ project: function(projectId)
+ {
+ return this._projects[projectId];
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.Project>}
+ */
+ projects: function()
+ {
+ return Object.values(this._projects);
+ },
+
+ /**
+ * @param {string} type
+ * @return {!Array.<!WebInspector.Project>}
+ */
+ projectsForType: function(type)
+ {
+ function filterByType(project)
+ {
+ return project.type() === type;
+ }
+ return this.projects().filter(filterByType);
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.UISourceCode>}
+ */
+ uiSourceCodes: function()
+ {
+ var result = [];
+ for (var projectId in this._projects) {
+ var project = this._projects[projectId];
+ result = result.concat(project.uiSourceCodes());
+ }
+ return result;
+ },
+
+ /**
+ * @param {string} url
+ * @return {boolean}
+ */
+ hasMappingForURL: function(url)
+ {
+ return this._fileSystemMapping.hasMappingForURL(url);
+ },
+
+ /**
+ * @param {string} url
+ * @return {?WebInspector.UISourceCode}
+ */
+ _networkUISourceCodeForURL: function(url)
+ {
+ var splitURL = WebInspector.ParsedURL.splitURL(url);
+ var projectId = splitURL[0];
+ var project = this.project(projectId);
+ return project ? project.uiSourceCode(splitURL.slice(1).join("/")) : null;
+ },
+
+ /**
+ * @param {string} url
+ * @return {?WebInspector.UISourceCode}
+ */
+ _contentScriptUISourceCodeForURL: function(url)
+ {
+ var splitURL = WebInspector.ParsedURL.splitURL(url);
+ var projectId = "contentscripts:" + splitURL[0];
+ var project = this.project(projectId);
+ return project ? project.uiSourceCode(splitURL.slice(1).join("/")) : null;
+ },
+
+ /**
+ * @param {string} url
+ * @return {?WebInspector.UISourceCode}
+ */
+ uiSourceCodeForURL: function(url)
+ {
+ var file = this._fileSystemMapping.fileForURL(url);
+ if (!file)
+ return this._networkUISourceCodeForURL(url) || this._contentScriptUISourceCodeForURL(url);
+
+ var projectId = WebInspector.FileSystemWorkspaceBinding.projectId(file.fileSystemPath);
+ var project = this.project(projectId);
+ return project ? project.uiSourceCode(file.filePath) : null;
+ },
+
+ /**
+ * @param {string} fileSystemPath
+ * @param {string} filePath
+ * @return {string}
+ */
+ urlForPath: function(fileSystemPath, filePath)
+ {
+ return this._fileSystemMapping.urlForPath(fileSystemPath, filePath);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} networkUISourceCode
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {!WebInspector.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding
+ */
+ addMapping: function(networkUISourceCode, uiSourceCode, fileSystemWorkspaceBinding)
+ {
+ var url = networkUISourceCode.url;
+ var path = uiSourceCode.path();
+ var fileSystemPath = fileSystemWorkspaceBinding.fileSystemPath(uiSourceCode.project().id());
+ this._fileSystemMapping.addMappingForResource(url, fileSystemPath, path);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ removeMapping: function(uiSourceCode)
+ {
+ this._fileSystemMapping.removeMappingForURL(uiSourceCode.url);
+ },
+
+ /**
+ * @param {boolean} hasExtensions
+ */
+ setHasResourceContentTrackingExtensions: function(hasExtensions)
+ {
+ this._hasResourceContentTrackingExtensions = hasExtensions;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasResourceContentTrackingExtensions: function()
+ {
+ return this._hasResourceContentTrackingExtensions;
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @type {!WebInspector.Workspace}
+ */
+WebInspector.workspace;