summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector/front-end/InjectedScript.js
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/inspector/front-end/InjectedScript.js')
-rw-r--r--WebCore/inspector/front-end/InjectedScript.js464
1 files changed, 42 insertions, 422 deletions
diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js
index 4144826..4611b48 100644
--- a/WebCore/inspector/front-end/InjectedScript.js
+++ b/WebCore/inspector/front-end/InjectedScript.js
@@ -27,20 +27,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-var InjectedScript = {};
-
-// Called from within InspectorController on the 'inspected page' side.
-InjectedScript.reset = function()
-{
- InjectedScript._styles = {};
- InjectedScript._styleRules = {};
- InjectedScript._lastStyleId = 0;
- InjectedScript._lastStyleRuleId = 0;
- InjectedScript._searchResults = [];
- InjectedScript._includedInSearchResultsPropertyName = "__includedInInspectorSearchResults";
-}
-
-InjectedScript.reset();
+var InjectedScript = {
+ _styles: {},
+ _styleRules: {},
+ _lastStyleId: 0,
+ _lastStyleRuleId: 0
+};
InjectedScript.getStyles = function(nodeId, authorOnly)
{
@@ -182,14 +174,12 @@ InjectedScript.toggleStyleEnabled = function(styleId, propertyName, disabled)
return InjectedScript._serializeStyle(style, true);
}
-InjectedScript.applyStyleRuleText = function(ruleId, newContent, selectedNodeId)
+InjectedScript.applyStyleRuleText = function(ruleId, newContent, selectedNode)
{
var rule = InjectedScript._styleRules[ruleId];
if (!rule)
return false;
- var selectedNode = InjectedScript._nodeForId(selectedNodeId);
-
try {
var stylesheet = rule.parentStyleSheet;
stylesheet.addRule(newContent);
@@ -204,14 +194,20 @@ InjectedScript.applyStyleRuleText = function(ruleId, newContent, selectedNodeId)
}
}
- return [InjectedScript._serializeRule(newRule), InjectedScript._doesSelectorAffectNode(newContent, selectedNode)];
+ var nodes = selectedNode.ownerDocument.querySelectorAll(newContent);
+ for (var i = 0; i < nodes.length; ++i) {
+ if (nodes[i] === selectedNode) {
+ return [InjectedScript._serializeRule(newRule), true];
+ }
+ }
+ return [InjectedScript._serializeRule(newRule), false];
} catch(e) {
// Report invalid syntax.
return false;
}
}
-InjectedScript.addStyleSelector = function(newContent, selectedNodeId)
+InjectedScript.addStyleSelector = function(newContent)
{
var stylesheet = InjectedScript.stylesheet;
if (!stylesheet) {
@@ -231,28 +227,10 @@ InjectedScript.addStyleSelector = function(newContent, selectedNodeId)
return false;
}
- var selectedNode = InjectedScript._nodeForId(selectedNodeId);
- var rule = stylesheet.cssRules[stylesheet.cssRules.length - 1];
- rule.__isViaInspector = true;
-
- return [ InjectedScript._serializeRule(rule), InjectedScript._doesSelectorAffectNode(newContent, selectedNode) ];
-}
-
-InjectedScript._doesSelectorAffectNode = function(selectorText, node)
-{
- if (!node)
- return false;
- var nodes = node.ownerDocument.querySelectorAll(selectorText);
- for (var i = 0; i < nodes.length; ++i) {
- if (nodes[i] === node) {
- return true;
- }
- }
- return false;
+ return InjectedScript._serializeRule(stylesheet.cssRules[stylesheet.cssRules.length - 1]);
}
-InjectedScript.setStyleProperty = function(styleId, name, value)
-{
+InjectedScript.setStyleProperty = function(styleId, name, value) {
var style = InjectedScript._styles[styleId];
if (!style)
return false;
@@ -273,18 +251,17 @@ InjectedScript._serializeRule = function(rule)
}
ruleValue.isUserAgent = parentStyleSheet && !parentStyleSheet.ownerNode && !parentStyleSheet.href;
ruleValue.isUser = parentStyleSheet && parentStyleSheet.ownerNode && parentStyleSheet.ownerNode.nodeName == "#document";
- ruleValue.isViaInspector = !!rule.__isViaInspector;
// Bind editable scripts only.
var doBind = !ruleValue.isUserAgent && !ruleValue.isUser;
ruleValue.style = InjectedScript._serializeStyle(rule.style, doBind);
if (doBind) {
- if (!rule.id) {
- rule.id = InjectedScript._lastStyleRuleId++;
- InjectedScript._styleRules[rule.id] = rule;
+ if (!rule._id) {
+ rule._id = InjectedScript._lastStyleRuleId++;
+ InjectedScript._styleRules[rule._id] = rule;
}
- ruleValue.id = rule.id;
+ ruleValue.id = rule._id;
}
return ruleValue;
}
@@ -318,11 +295,11 @@ InjectedScript._serializeStyle = function(style, doBind)
result.uniqueStyleProperties = InjectedScript._getUniqueStyleProperties(style);
if (doBind) {
- if (!style.id) {
- style.id = InjectedScript._lastStyleId++;
- InjectedScript._styles[style.id] = style;
+ if (!style._id) {
+ style._id = InjectedScript._lastStyleId++;
+ InjectedScript._styles[style._id] = style;
}
- result.id = style.id;
+ result.id = style._id;
}
return result;
}
@@ -428,7 +405,6 @@ InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty)
return false;
var properties = [];
-
// Go over properties, prepare results.
for (var propertyName in object) {
if (!ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOwnProperty(propertyName))
@@ -439,31 +415,29 @@ InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty)
continue;
var property = {};
property.name = propertyName;
- property.parentObjectProxy = objectProxy;
var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName);
if (!property.isGetter) {
var childObject = object[propertyName];
- var childObjectProxy = {};
- childObjectProxy.objectId = objectProxy.objectId;
- childObjectProxy.path = objectProxy.path ? objectProxy.path.slice() : [];
- childObjectProxy.path.push(propertyName);
-
- childObjectProxy.protoDepth = objectProxy.protoDepth || 0;
- childObjectProxy.description = Object.describe(childObject, true);
- property.value = childObjectProxy;
-
- var type = typeof childObject;
- if (type === "object" || type === "function") {
+ property.type = typeof childObject;
+ property.textContent = Object.describe(childObject, true);
+ property.parentObjectProxy = objectProxy;
+ var parentPath = objectProxy.path.slice();
+ property.childObjectProxy = {
+ objectId : objectProxy.objectId,
+ path : parentPath.splice(parentPath.length, 0, propertyName),
+ protoDepth : objectProxy.protoDepth
+ };
+ if (childObject && (property.type === "object" || property.type === "function")) {
for (var subPropertyName in childObject) {
if (propertyName === "__treeElementIdentifier")
continue;
- childObjectProxy.hasChildren = true;
+ property.hasChildren = true;
break;
}
}
} else {
// FIXME: this should show something like "getter" (bug 16734).
- property.value = { description: "\u2014" }; // em dash
+ property.textContent = "\u2014"; // em dash
property.isGetter = true;
}
properties.push(property);
@@ -505,338 +479,6 @@ InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression
}
}
-InjectedScript.evaluate = function(expression)
-{
- InjectedScript._ensureCommandLineAPIInstalled();
- // Surround the expression in with statements to inject our command line API so that
- // the window object properties still take more precedent than our API functions.
- expression = "with (window._inspectorCommandLineAPI) { with (window) { " + expression + " } }";
-
- var result = {};
- try {
- var value = InjectedScript._window().eval(expression);
- var wrapper = InspectorController.wrapObject(value);
- if (typeof wrapper === "object" && wrapper.exception)
- result.exception = wrapper.exception;
- else
- result.value = wrapper;
- } catch (e) {
- result.exception = e.toString();
- }
- return result;
-}
-
-InjectedScript.addInspectedNode = function(nodeId)
-{
- var node = InjectedScript._nodeForId(nodeId);
- if (!node)
- return false;
-
- InjectedScript._ensureCommandLineAPIInstalled();
- var inspectedNodes = InjectedScript._window()._inspectorCommandLineAPI._inspectedNodes;
- inspectedNodes.unshift(node);
- if (inspectedNodes.length >= 5)
- inspectedNodes.pop();
- return true;
-}
-
-InjectedScript.performSearch = function(whitespaceTrimmedQuery, searchResultsProperty)
-{
- var tagNameQuery = whitespaceTrimmedQuery;
- var attributeNameQuery = whitespaceTrimmedQuery;
- var startTagFound = (tagNameQuery.indexOf("<") === 0);
- var endTagFound = (tagNameQuery.lastIndexOf(">") === (tagNameQuery.length - 1));
-
- if (startTagFound || endTagFound) {
- var tagNameQueryLength = tagNameQuery.length;
- tagNameQuery = tagNameQuery.substring((startTagFound ? 1 : 0), (endTagFound ? (tagNameQueryLength - 1) : tagNameQueryLength));
- }
-
- // Check the tagNameQuery is it is a possibly valid tag name.
- if (!/^[a-zA-Z0-9\-_:]+$/.test(tagNameQuery))
- tagNameQuery = null;
-
- // Check the attributeNameQuery is it is a possibly valid tag name.
- if (!/^[a-zA-Z0-9\-_:]+$/.test(attributeNameQuery))
- attributeNameQuery = null;
-
- const escapedQuery = whitespaceTrimmedQuery.escapeCharacters("'");
- const escapedTagNameQuery = (tagNameQuery ? tagNameQuery.escapeCharacters("'") : null);
- const escapedWhitespaceTrimmedQuery = whitespaceTrimmedQuery.escapeCharacters("'");
- const searchResultsProperty = InjectedScript._includedInSearchResultsPropertyName;
-
- function addNodesToResults(nodes, length, getItem)
- {
- if (!length)
- return;
-
- var nodeIds = [];
- for (var i = 0; i < length; ++i) {
- var node = getItem.call(nodes, i);
- // Skip this node if it already has the property.
- if (searchResultsProperty in node)
- continue;
-
- if (!InjectedScript._searchResults.length) {
- InjectedScript._currentSearchResultIndex = 0;
- }
-
- node[searchResultsProperty] = true;
- InjectedScript._searchResults.push(node);
- var nodeId = InspectorController.pushNodePathToFrontend(node, false);
- nodeIds.push(nodeId);
- }
- InspectorController.addNodesToSearchResult(nodeIds.join(","));
- }
-
- function matchExactItems(doc)
- {
- matchExactId.call(this, doc);
- matchExactClassNames.call(this, doc);
- matchExactTagNames.call(this, doc);
- matchExactAttributeNames.call(this, doc);
- }
-
- function matchExactId(doc)
- {
- const result = doc.__proto__.getElementById.call(doc, whitespaceTrimmedQuery);
- addNodesToResults.call(this, result, (result ? 1 : 0), function() { return this });
- }
-
- function matchExactClassNames(doc)
- {
- const result = doc.__proto__.getElementsByClassName.call(doc, whitespaceTrimmedQuery);
- addNodesToResults.call(this, result, result.length, result.item);
- }
-
- function matchExactTagNames(doc)
- {
- if (!tagNameQuery)
- return;
- const result = doc.__proto__.getElementsByTagName.call(doc, tagNameQuery);
- addNodesToResults.call(this, result, result.length, result.item);
- }
-
- function matchExactAttributeNames(doc)
- {
- if (!attributeNameQuery)
- return;
- const result = doc.__proto__.querySelectorAll.call(doc, "[" + attributeNameQuery + "]");
- addNodesToResults.call(this, result, result.length, result.item);
- }
-
- function matchPartialTagNames(doc)
- {
- if (!tagNameQuery)
- return;
- const result = doc.__proto__.evaluate.call(doc, "//*[contains(name(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchStartOfTagNames(doc)
- {
- if (!tagNameQuery)
- return;
- const result = doc.__proto__.evaluate.call(doc, "//*[starts-with(name(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchPartialTagNamesAndAttributeValues(doc)
- {
- if (!tagNameQuery) {
- matchPartialAttributeValues.call(this, doc);
- return;
- }
-
- const result = doc.__proto__.evaluate.call(doc, "//*[contains(name(), '" + escapedTagNameQuery + "') or contains(@*, '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchPartialAttributeValues(doc)
- {
- const result = doc.__proto__.evaluate.call(doc, "//*[contains(@*, '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchStyleSelector(doc)
- {
- const result = doc.__proto__.querySelectorAll.call(doc, whitespaceTrimmedQuery);
- addNodesToResults.call(this, result, result.length, result.item);
- }
-
- function matchPlainText(doc)
- {
- const result = doc.__proto__.evaluate.call(doc, "//text()[contains(., '" + escapedQuery + "')] | //comment()[contains(., '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchXPathQuery(doc)
- {
- const result = doc.__proto__.evaluate.call(doc, whitespaceTrimmedQuery, doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function finishedSearching()
- {
- // Remove the searchResultsProperty now that the search is finished.
- for (var i = 0; i < InjectedScript._searchResults.length; ++i)
- delete InjectedScript._searchResults[i][searchResultsProperty];
- }
-
- const mainFrameDocument = InjectedScript._window().document;
- const searchDocuments = [mainFrameDocument];
- var searchFunctions;
- if (tagNameQuery && startTagFound && endTagFound)
- searchFunctions = [matchExactTagNames, matchPlainText];
- else if (tagNameQuery && startTagFound)
- searchFunctions = [matchStartOfTagNames, matchPlainText];
- else if (tagNameQuery && endTagFound) {
- // FIXME: we should have a matchEndOfTagNames search function if endTagFound is true but not startTagFound.
- // This requires ends-with() support in XPath, WebKit only supports starts-with() and contains().
- searchFunctions = [matchPartialTagNames, matchPlainText];
- } else if (whitespaceTrimmedQuery === "//*" || whitespaceTrimmedQuery === "*") {
- // These queries will match every node. Matching everything isn't useful and can be slow for large pages,
- // so limit the search functions list to plain text and attribute matching.
- searchFunctions = [matchPartialAttributeValues, matchPlainText];
- } else
- searchFunctions = [matchExactItems, matchStyleSelector, matchPartialTagNamesAndAttributeValues, matchPlainText, matchXPathQuery];
-
- // Find all frames, iframes and object elements to search their documents.
- const querySelectorAllFunction = InjectedScript._window().Document.prototype.querySelectorAll;
- const subdocumentResult = querySelectorAllFunction.call(mainFrameDocument, "iframe, frame, object");
-
- for (var i = 0; i < subdocumentResult.length; ++i) {
- var element = subdocumentResult.item(i);
- if (element.contentDocument)
- searchDocuments.push(element.contentDocument);
- }
-
- const panel = InjectedScript;
- var documentIndex = 0;
- var searchFunctionIndex = 0;
- var chunkIntervalIdentifier = null;
-
- // Split up the work into chunks so we don't block the UI thread while processing.
-
- function processChunk()
- {
- var searchDocument = searchDocuments[documentIndex];
- var searchFunction = searchFunctions[searchFunctionIndex];
-
- if (++searchFunctionIndex > searchFunctions.length) {
- searchFunction = searchFunctions[0];
- searchFunctionIndex = 0;
-
- if (++documentIndex > searchDocuments.length) {
- if (panel._currentSearchChunkIntervalIdentifier === chunkIntervalIdentifier)
- delete panel._currentSearchChunkIntervalIdentifier;
- clearInterval(chunkIntervalIdentifier);
- finishedSearching.call(panel);
- return;
- }
-
- searchDocument = searchDocuments[documentIndex];
- }
-
- if (!searchDocument || !searchFunction)
- return;
-
- try {
- searchFunction.call(panel, searchDocument);
- } catch(err) {
- // ignore any exceptions. the query might be malformed, but we allow that.
- }
- }
-
- processChunk();
-
- chunkIntervalIdentifier = setInterval(processChunk, 25);
- InjectedScript._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier;
- return true;
-}
-
-InjectedScript.searchCanceled = function()
-{
- if (InjectedScript._searchResults) {
- const searchResultsProperty = InjectedScript._includedInSearchResultsPropertyName;
- for (var i = 0; i < this._searchResults.length; ++i) {
- var node = this._searchResults[i];
-
- // Remove the searchResultsProperty since there might be an unfinished search.
- delete node[searchResultsProperty];
- }
- }
-
- if (InjectedScript._currentSearchChunkIntervalIdentifier) {
- clearInterval(InjectedScript._currentSearchChunkIntervalIdentifier);
- delete InjectedScript._currentSearchChunkIntervalIdentifier;
- }
- InjectedScript._searchResults = [];
- return true;
-}
-
-InjectedScript.getCookies = function()
-{
- return InjectedScript._window().document.cookie;
-}
-
-InjectedScript._ensureCommandLineAPIInstalled = function(inspectedWindow)
-{
- var inspectedWindow = InjectedScript._window();
- if (inspectedWindow._inspectorCommandLineAPI)
- return;
-
- inspectedWindow.eval("window._inspectorCommandLineAPI = { \
- $: function() { return document.getElementById.apply(document, arguments) }, \
- $$: function() { return document.querySelectorAll.apply(document, arguments) }, \
- $x: function(xpath, context) { \
- var nodes = []; \
- try { \
- var doc = context || document; \
- var results = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null); \
- var node; \
- while (node = results.iterateNext()) nodes.push(node); \
- } catch (e) {} \
- return nodes; \
- }, \
- dir: function() { return console.dir.apply(console, arguments) }, \
- dirxml: function() { return console.dirxml.apply(console, arguments) }, \
- keys: function(o) { var a = []; for (var k in o) a.push(k); return a; }, \
- values: function(o) { var a = []; for (var k in o) a.push(o[k]); return a; }, \
- profile: function() { return console.profile.apply(console, arguments) }, \
- profileEnd: function() { return console.profileEnd.apply(console, arguments) }, \
- _inspectedNodes: [], \
- get $0() { return _inspectorCommandLineAPI._inspectedNodes[0] }, \
- get $1() { return _inspectorCommandLineAPI._inspectedNodes[1] }, \
- get $2() { return _inspectorCommandLineAPI._inspectedNodes[2] }, \
- get $3() { return _inspectorCommandLineAPI._inspectedNodes[3] }, \
- get $4() { return _inspectorCommandLineAPI._inspectedNodes[4] } \
- };");
-
- inspectedWindow._inspectorCommandLineAPI.clear = InspectorController.wrapCallback(InspectorController.clearMessages.bind(InspectorController, true));
- inspectedWindow._inspectorCommandLineAPI.inspect = InspectorController.wrapCallback(inspectObject.bind(this));
-
- function inspectObject(o)
- {
- if (arguments.length === 0)
- return;
-
- inspectedWindow.console.log(o);
- if (Object.type(o, inspectedWindow) === "node") {
- InspectorController.pushNodePathToFrontend(o, true);
- } else {
- switch (Object.describe(o)) {
- case "Database":
- InspectorController.selectDatabase(o);
- break;
- case "Storage":
- InspectorController.selectDOMStorage(o);
- break;
- }
- }
- }
-}
-
InjectedScript._resolveObject = function(objectProxy)
{
var object = InjectedScript._objectForId(objectProxy.objectId);
@@ -844,11 +486,11 @@ InjectedScript._resolveObject = function(objectProxy)
var protoDepth = objectProxy.protoDepth;
// Follow the property path.
- for (var i = 0; object && path && i < path.length; ++i)
+ for (var i = 0; object && i < path.length; ++i)
object = object[path[i]];
// Get to the necessary proto layer.
- for (var i = 0; object && protoDepth && i < protoDepth; ++i)
+ for (var i = 0; object && i < protoDepth; ++i)
object = object.__proto__;
return object;
@@ -863,34 +505,12 @@ InjectedScript._window = function()
InjectedScript._nodeForId = function(nodeId)
{
- if (!nodeId)
- return null;
- return InspectorController.nodeForId(nodeId);
+ // TODO: replace with node lookup in the InspectorDOMAgent once DOMAgent nodes are used.
+ return nodeId;
}
InjectedScript._objectForId = function(objectId)
{
- if (typeof objectId === "number")
- return InjectedScript._nodeForId(objectId);
- else if (typeof objectId === "string")
- return InspectorController.unwrapObject(objectId);
-
- // TODO: move scope chain objects to proxy-based schema.
+ // TODO: replace with node lookups for node ids and evaluation result lookups for the rest of ids.
return objectId;
}
-
-// Called from within InspectorController on the 'inspected page' side.
-InjectedScript.createProxyObject = function(object, objectId)
-{
- var result = {};
- result.objectId = objectId;
- result.type = Object.type(object, InjectedScript._window());
- if (result.type === "node")
- result.nodeId = InspectorController.pushNodePathToFrontend(object, false);
- try {
- result.description = Object.describe(object, true, InjectedScript._window());
- } catch (e) {
- result.exception = e.toString();
- }
- return result;
-}