diff options
Diffstat (limited to 'WebCore/inspector/front-end/InjectedScript.js')
-rw-r--r-- | WebCore/inspector/front-end/InjectedScript.js | 280 |
1 files changed, 7 insertions, 273 deletions
diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js index e3be6a3..e62a916 100644 --- a/WebCore/inspector/front-end/InjectedScript.js +++ b/WebCore/inspector/front-end/InjectedScript.js @@ -83,8 +83,6 @@ InjectedScript.releaseWrapperObjectGroup = function(objectGroupName) { // Called from within InspectorController on the 'inspected page' side. InjectedScript.reset = function() { - InjectedScript._searchResults = []; - InjectedScript._includedInSearchResultsPropertyName = "__includedInInspectorSearchResults"; } InjectedScript.reset(); @@ -211,7 +209,7 @@ InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression return true; } catch(e) { try { - var result = inspectedWindow.eval("\"" + InjectedScript._escapeCharacters(expression, "\"") + "\""); + var result = inspectedWindow.eval("\"" + expression.replace(/"/g, "\\\"") + "\""); object[propertyName] = result; return true; } catch(e) { @@ -355,247 +353,6 @@ InjectedScript.getNodeId = function(node) return InjectedScriptHost.pushNodePathToFrontend(node, false, false); } -InjectedScript.performSearch = function(whitespaceTrimmedQuery, runSynchronously) -{ - // FIXME: Few things are missing here: - // 1) Search works with node granularity - number of matches within node is not calculated. - // 2) Search does not work outside main documents' domain - we need to use specific InjectedScript instances - // for other domains. - // 3) There is no need to push all search results to the front-end at a time, pushing next / previous result - // is sufficient. - 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 = InjectedScript._escapeCharacters(whitespaceTrimmedQuery, "'"); - const escapedTagNameQuery = (tagNameQuery ? InjectedScript._escapeCharacters(tagNameQuery, "'") : null); - const escapedWhitespaceTrimmedQuery = InjectedScript._escapeCharacters(whitespaceTrimmedQuery, "'"); - 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 = InjectedScriptHost.pushNodePathToFrontend(node, false, false); - nodeIds.push(nodeId); - } - InjectedScriptHost.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 = inspectedWindow.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 subdocumentResult = mainFrameDocument.querySelectorAll("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 false; - } - - searchDocument = searchDocuments[documentIndex]; - } - - try { - searchFunction.call(panel, searchDocument); - } catch(err) { - // ignore any exceptions. the query might be malformed, but we allow that. - } - return true; - } - - if (runSynchronously) - while (processChunk()) {} - else { - 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.openInInspectedWindow = function(url) { // Don't call window.open on wrapper - popup blocker mutes it. @@ -1017,38 +774,15 @@ InjectedScript._className = function(obj) // Both of the methods below result in "Object" names on the foreign engine bindings. // I gave up and am using a check below to distinguish between the egine bingings. - if (typeof Document === "object") { - // JSC + if (jsEngine == "JSC") { var str = inspectedWindow.Object ? inspectedWindow.Object.prototype.toString.call(obj) : InjectedScript._toString(obj); return str.replace(/^\[object (.*)\]$/i, "$1"); + } else { + // V8 + if (typeof obj !== "object") + return "null"; + return obj.constructor.name || "Object"; } - // V8 - if (typeof obj !== "object") - return "null"; - return obj.constructor.name; -} - -InjectedScript._escapeCharacters = function(str, chars) -{ - var foundChar = false; - for (var i = 0; i < chars.length; ++i) { - if (str.indexOf(chars.charAt(i)) !== -1) { - foundChar = true; - break; - } - } - - if (!foundChar) - return str; - - var result = ""; - for (var i = 0; i < str.length; ++i) { - if (chars.indexOf(str.charAt(i)) !== -1) - result += "\\"; - result += str.charAt(i); - } - - return result; } return InjectedScript; |