Changeset 87294 in webkit
- Timestamp:
- May 25, 2011 7:02:10 AM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r87293 r87294 1 2011-05-23 Alexander Pavlov <apavlov@chromium.org> 2 3 Reviewed by Yury Semikhatsky. 4 5 Web Inspector: extreme lagging when searching for "img[src*=" 6 https://bugs.webkit.org/show_bug.cgi?id=61282 7 8 No new tests, as this is a refactoring: ElementsTreeElement DOM is manipulated directly 9 when built and search-highlighted, rather than through innerHTML. 10 11 * inspector/front-end/DOMSyntaxHighlighter.js: 12 (WebInspector.DOMSyntaxHighlighter): 13 (WebInspector.DOMSyntaxHighlighter.prototype.createSpan): 14 * inspector/front-end/ElementsPanel.js: 15 (WebInspector.ElementsPanel.prototype._hideSearchHighlights): 16 * inspector/front-end/ElementsTreeOutline.js: 17 (WebInspector.ElementsTreeElement.prototype.highlightSearchResults): 18 (WebInspector.ElementsTreeElement.prototype.hideSearchHighlights): 19 (WebInspector.ElementsTreeElement.prototype._updateSearchHighlight.updateEntryShow): 20 (WebInspector.ElementsTreeElement.prototype._updateSearchHighlight.updateEntryHide): 21 (WebInspector.ElementsTreeElement.prototype._updateSearchHighlight): 22 (WebInspector.ElementsTreeElement.prototype._addNewAttribute): 23 (WebInspector.ElementsTreeElement.prototype.updateTitle): 24 (WebInspector.ElementsTreeElement.prototype._buildAttributeDOM): 25 (): 26 * inspector/front-end/utilities.js: 27 (): 28 1 29 2011-05-25 Leandro Gracia Gil <leandrogracia@chromium.org> 2 30 -
trunk/Source/WebCore/inspector/front-end/DOMSyntaxHighlighter.js
r86430 r87294 29 29 */ 30 30 31 WebInspector.DOMSyntaxHighlighter = function(mimeType )31 WebInspector.DOMSyntaxHighlighter = function(mimeType, stripExtraWhitespace) 32 32 { 33 33 this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType); 34 this._stripExtraWhitespace = stripExtraWhitespace; 34 35 } 35 36 … … 39 40 var span = document.createElement("span"); 40 41 span.className = "webkit-" + className; 42 if (this._stripExtraWhitespace) 43 content = content.replace(/^[\n\r]*/, "").replace(/\s*$/, ""); 41 44 span.appendChild(document.createTextNode(content)); 42 45 return span; -
trunk/Source/WebCore/inspector/front-end/ElementsPanel.js
r86674 r87294 394 394 var treeElement = this.treeOutline.findTreeElement(node); 395 395 if (treeElement) 396 treeElement.hi ghlightSearchResults(null);396 treeElement.hideSearchHighlights(); 397 397 } 398 398 }, -
trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
r86948 r87294 330 330 highlightSearchResults: function(searchQuery) 331 331 { 332 if (this._searchQuery === searchQuery) 333 return; 334 335 if (searchQuery) 336 delete this._searchHighlightedHTML; // A new search query (not clear-the-current-highlighting). 332 if (this._searchQuery !== searchQuery) { 333 this._updateSearchHighlight(false); 334 delete this._highlightResult; // A new search query. 335 } 337 336 338 337 this._searchQuery = searchQuery; 338 this._searchHighlightsVisible = true; 339 339 this.updateTitle(true); 340 }, 341 342 hideSearchHighlights: function() 343 { 344 delete this._searchHighlightsVisible; 345 this._updateSearchHighlight(false); 346 }, 347 348 _updateSearchHighlight: function(show) 349 { 350 if (!this._highlightResult) 351 return; 352 353 function updateEntryShow(entry) 354 { 355 switch (entry.type) { 356 case "added": 357 entry.parent.insertBefore(entry.node, entry.nextSibling); 358 break; 359 case "changed": 360 entry.node.textContent = entry.newText; 361 break; 362 } 363 } 364 365 function updateEntryHide(entry) 366 { 367 switch (entry.type) { 368 case "added": 369 if (entry.node.parentElement) 370 entry.node.parentElement.removeChild(entry.node); 371 break; 372 case "changed": 373 entry.node.textContent = entry.oldText; 374 break; 375 } 376 } 377 378 var updater = show ? updateEntryShow : updateEntryHide; 379 380 for (var i = 0, size = this._highlightResult.length; i < size; ++i) 381 updater(this._highlightResult[i]); 340 382 }, 341 383 … … 839 881 // a parent node. Use a temporary span container for the HTML. 840 882 var container = document.createElement("span"); 841 container.innerHTML = this._attributeHTML(" ", "");883 this._buildAttributeDOM(container, " ", ""); 842 884 var attr = container.firstChild; 843 885 attr.style.marginLeft = "2px"; // overrides the .editing margin rule … … 1180 1222 return; 1181 1223 1182 if (onlySearchQueryChanged && this._normalHTML) 1183 this.titleHTML = this._normalHTML; 1184 else { 1185 delete this._normalHTML; 1186 this.titleHTML = "<span class=\"highlight\">" + this._nodeTitleInfo(WebInspector.linkifyURL).titleHTML + "</span>"; 1224 if (onlySearchQueryChanged) { 1225 if (this._highlightResult) 1226 this._updateSearchHighlight(false); 1227 } else { 1228 var highlightElement = document.createElement("span"); 1229 highlightElement.className = "highlight"; 1230 highlightElement.appendChild(this._nodeTitleInfo(WebInspector.linkifyURLAsNode).titleDOM); 1231 this.title = highlightElement; 1232 delete this._highlightResult; 1187 1233 } 1188 1234 … … 1193 1239 }, 1194 1240 1195 _ attributeHTML: function(name, value, node, linkify)1241 _buildAttributeDOM: function(parentElement, name, value, node, linkify) 1196 1242 { 1197 1243 var hasText = (value.length > 0); 1198 var html = "<span class=\"webkit-html-attribute\"><span class=\"webkit-html-attribute-name\">" + name.escapeHTML() + "</span>"; 1244 var attrSpanElement = parentElement.createChild("span", "webkit-html-attribute"); 1245 var attrNameElement = attrSpanElement.createChild("span", "webkit-html-attribute-name"); 1246 attrNameElement.textContent = name.escapeHTML(); 1199 1247 1200 1248 if (hasText) 1201 html += "=​\"";1249 attrSpanElement.appendChild(document.createTextNode("=\u200B\"")); 1202 1250 1203 1251 if (linkify && (name === "src" || name === "href")) { 1204 1252 var rewrittenHref = WebInspector.resourceURLForRelatedNode(node, value); 1205 1253 value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B"); 1206 html += linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a");1254 attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a")); 1207 1255 } else { 1208 value = value.escapeHTML().replace(/([\/;:\)\]\}])/g, "$1​"); 1209 html += "<span class=\"webkit-html-attribute-value\">" + value + "</span>"; 1256 value = value.escapeHTML().replace(/([\/;:\)\]\}])/g, "$1\u200B"); 1257 var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value"); 1258 attrValueElement.textContent = value; 1210 1259 } 1211 1260 1212 1261 if (hasText) 1213 html += "\""; 1214 1215 html += "</span>"; 1216 return html; 1217 }, 1218 1219 _tagHTML: function(tagName, isClosingTag, isDistinctTreeElement, linkify, isShadow) 1262 attrSpanElement.appendChild(document.createTextNode("\"")); 1263 }, 1264 1265 _buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeElement, linkify, isShadow) 1220 1266 { 1221 1267 var node = this.representedObject; … … 1225 1271 if (isShadow) 1226 1272 classes.push("shadow"); 1227 var result = "<span class=\"" + classes.join(" ") + "\"><"; 1228 result += "<span " + (isClosingTag ? "" : "class=\"webkit-html-tag-name\"") + ">" + (isClosingTag ? "/" : "") + tagName + "</span>"; 1273 var tagElement = parentElement.createChild("span", classes.join(" ")); 1274 tagElement.appendChild(document.createTextNode("<")); 1275 var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name"); 1276 tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName; 1277 1229 1278 if (!isClosingTag && node.hasAttributes()) { 1230 1279 var attributes = node.attributes(); 1231 1280 for (var i = 0; i < attributes.length; ++i) { 1232 1281 var attr = attributes[i]; 1233 result += " " + this._attributeHTML(attr.name, attr.value, node, linkify);1234 }1235 }1236 result += "></span>​";1237 1238 return result;1282 tagElement.appendChild(document.createTextNode(" ")); 1283 this._buildAttributeDOM(tagElement, attr.name, attr.value, node, linkify); 1284 } 1285 } 1286 tagElement.appendChild(document.createTextNode(">")); 1287 parentElement.appendChild(document.createTextNode("\u200B")); 1239 1288 }, 1240 1289 … … 1242 1291 { 1243 1292 var node = this.representedObject; 1244 var info = {title HTML: "", hasChildren: this.hasChildren};1293 var info = {titleDOM: document.createDocumentFragment(), hasChildren: this.hasChildren}; 1245 1294 1246 1295 switch (node.nodeType()) { 1247 1296 case Node.DOCUMENT_NODE: 1248 info.title HTML = "Document";1297 info.titleDOM.appendChild(document.createTextNode("Document")); 1249 1298 break; 1250 1299 1251 1300 case Node.DOCUMENT_FRAGMENT_NODE: 1252 info.title HTML = "Document Fragment";1301 info.titleDOM.appendChild(document.createTextNode("Document Fragment")); 1253 1302 break; 1254 1303 1255 1304 case Node.ATTRIBUTE_NODE: 1256 1305 var value = node.value || "\u200B"; // Zero width space to force showing an empty value. 1257 info.titleHTML = this._attributeHTML(node.name, value);1306 this._buildAttributeDOM(info.titleDOM, node.name, value); 1258 1307 break; 1259 1308 … … 1261 1310 var tagName = this.treeOutline.nodeNameToCorrectCase(node.nodeName()).escapeHTML(); 1262 1311 if (this._elementCloseTag) { 1263 info.titleHTML = this._tagHTML(tagName, true, true, false, node.inShadowTree());1312 this._buildTagDOM(info.titleDOM, tagName, true, true, false, node.inShadowTree()); 1264 1313 info.hasChildren = false; 1265 1314 break; 1266 1315 } 1267 1316 1268 var titleHTML = this._tagHTML(tagName, false, false, linkify, node.inShadowTree());1317 this._buildTagDOM(info.titleDOM, tagName, false, false, linkify, node.inShadowTree()); 1269 1318 1270 1319 var textChild = this._singleTextChild(node); … … 1272 1321 1273 1322 if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) { 1274 if (this.hasChildren) 1275 titleHTML += "<span class=\"webkit-html-text-node\">…</span>​"; 1276 titleHTML += this._tagHTML(tagName, true, false, false, node.inShadowTree()); 1323 if (this.hasChildren) { 1324 var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node"); 1325 textNodeElement.textContent = "\u2026"; 1326 info.titleDOM.appendChild(document.createTextNode("\u200B")); 1327 } 1328 this._buildTagDOM(info.titleDOM, tagName, true, false, false, node.inShadowTree()); 1277 1329 } 1278 1330 … … 1281 1333 // create a subtree for them 1282 1334 if (showInlineText) { 1283 titleHTML += "<span class=\"webkit-html-text-node\">" + textChild.nodeValue().escapeHTML() + "</span>​" + this._tagHTML(tagName, true, false, node.inShadowTree()); 1335 var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node"); 1336 textNodeElement.textContent = textChild.nodeValue().escapeHTML(); 1337 info.titleDOM.appendChild(document.createTextNode("\u200B")); 1338 this._buildTagDOM(info.titleDOM, tagName, true, false, node.inShadowTree()); 1284 1339 info.hasChildren = false; 1285 1340 } 1286 info.titleHTML = titleHTML;1287 1341 break; 1288 1342 1289 1343 case Node.TEXT_NODE: 1290 1344 if (isNodeWhitespace.call(node)) 1291 info.title HTML = "(whitespace)";1345 info.titleDOM.appendChild(document.createTextNode("(whitespace)")); 1292 1346 else { 1293 1347 if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") { 1294 var newNode = document.createElement("span");1348 var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-js-node"); 1295 1349 newNode.textContent = node.nodeValue(); 1296 1350 1297 var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript" );1351 var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript", true); 1298 1352 javascriptSyntaxHighlighter.syntaxHighlightNode(newNode); 1299 1300 info.titleHTML = "<span class=\"webkit-html-text-node webkit-html-js-node\">" + newNode.innerHTML.replace(/^[\n\r]*/, "").replace(/\s*$/, "") + "</span>";1301 1353 } else if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "style") { 1302 var newNode = document.createElement("span");1354 var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-css-node"); 1303 1355 newNode.textContent = node.nodeValue(); 1304 1356 1305 var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css" );1357 var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css", true); 1306 1358 cssSyntaxHighlighter.syntaxHighlightNode(newNode); 1307 1308 info.titleHTML = "<span class=\"webkit-html-text-node webkit-html-css-node\">" + newNode.innerHTML.replace(/^[\n\r]*/, "").replace(/\s*$/, "") + "</span>"; 1309 } else 1310 info.titleHTML = "\"<span class=\"webkit-html-text-node\">" + node.nodeValue().escapeHTML() + "</span>\""; 1359 } else { 1360 info.titleDOM.appendChild(document.createTextNode("\"")); 1361 var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node"); 1362 textNodeElement.textContent = node.nodeValue().escapeHTML(); 1363 info.titleDOM.appendChild(document.createTextNode("\"")); 1364 } 1311 1365 } 1312 1366 break; 1313 1367 1314 1368 case Node.COMMENT_NODE: 1315 info.titleHTML = "<span class=\"webkit-html-comment\"><!--" + node.nodeValue().escapeHTML() + "--></span>"; 1369 var commentElement = info.titleDOM.createChild("span", "webkit-html-comment"); 1370 commentElement.appendChild(document.createTextNode("<!--" + node.nodeValue().escapeHTML() + "-->")); 1316 1371 break; 1317 1372 1318 1373 case Node.DOCUMENT_TYPE_NODE: 1319 var titleHTML = "<span class=\"webkit-html-doctype\"><!DOCTYPE " + node.nodeName(); 1374 var docTypeElement = info.titleDOM.createChild("span", "webkit-html-doctype"); 1375 docTypeElement.appendChild(document.createTextNode("<!DOCTYPE " + node.nodeName())); 1320 1376 if (node.publicId) { 1321 titleHTML += " PUBLIC \"" + node.publicId + "\"";1377 docTypeElement.appendChild(document.createTextNode(" PUBLIC \"" + node.publicId + "\"")); 1322 1378 if (node.systemId) 1323 titleHTML += " \"" + node.systemId + "\"";1379 docTypeElement.appendChild(document.createTextNode(" \"" + node.systemId + "\"")); 1324 1380 } else if (node.systemId) 1325 titleHTML += " SYSTEM \"" + node.systemId + "\""; 1381 docTypeElement.appendChild(document.createTextNode(" SYSTEM \"" + node.systemId + "\"")); 1382 1326 1383 if (node.internalSubset) 1327 titleHTML += " [" + node.internalSubset + "]";1328 titleHTML += "></span>"; 1329 info.titleHTML = titleHTML;1384 docTypeElement.appendChild(document.createTextNode(" [" + node.internalSubset + "]")); 1385 1386 docTypeElement.appendChild(document.createTextNode(">")); 1330 1387 break; 1331 1388 1332 1389 case Node.CDATA_SECTION_NODE: 1333 info.titleHTML = "<span class=\"webkit-html-text-node\"><![CDATA[" + node.nodeValue().escapeHTML() + "]]></span>"; 1390 var cdataElement = info.titleDOM.createChild("span", "webkit-html-text-node"); 1391 cdataElement.appendChild(document.createTextNode("<![CDATA[" + node.nodeValue().escapeHTML() + "]]>")); 1334 1392 break; 1335 1393 1336 1394 case Node.SHADOW_ROOT_NODE: 1337 info.titleHTML = "<span class=\"dom-shadow-root\">(shadow)</span>"; 1395 var cdataElement = info.titleDOM.createChild("span", "dom-shadow-root"); 1396 cdataElement.appendChild(document.createTextNode("(shadow)")); 1338 1397 break; 1339 1398 1340 1399 default: 1341 info.titleHTML = this.treeOutline.nodeNameToCorrectCase(node.nodeName()).collapseWhitespace().escapeHTML();1400 var defaultElement = info.titleDOM.appendChild(document.createTextNode(this.treeOutline.nodeNameToCorrectCase(node.nodeName()).collapseWhitespace().escapeHTML())); 1342 1401 } 1343 1402 … … 1424 1483 _highlightSearchResults: function() 1425 1484 { 1426 if (!this._searchQuery) 1427 return; 1428 if (this._searchHighlightedHTML) { 1429 this.listItemElement.innerHTML = this._searchHighlightedHTML; 1430 return; 1431 } 1432 1433 if (!this._normalHTML) 1434 this._normalHTML = this.titleHTML; 1485 if (!this._searchQuery || !this._searchHighlightsVisible) 1486 return; 1487 if (this._highlightResult) { 1488 this._updateSearchHighlight(true); 1489 return; 1490 } 1435 1491 1436 1492 var text = this.listItemElement.textContent; … … 1449 1505 matchRanges.push({ offset: 0, length: text.length }); 1450 1506 1451 highlightSearchResults(this.listItemElement, matchRanges);1452 this._searchHighlightedHTML = this.listItemElement.innerHTML;1507 this._highlightResult = []; 1508 highlightSearchResults(this.listItemElement, matchRanges, this._highlightResult); 1453 1509 } 1454 1510 } -
trunk/Source/WebCore/inspector/front-end/utilities.js
r86562 r87294 259 259 return element; 260 260 } 261 262 DocumentFragment.prototype.createChild = Element.prototype.createChild; 261 263 262 264 Element.prototype.__defineGetter__("totalOffsetLeft", function() … … 954 956 } 955 957 956 function highlightSearchResults(element, resultRanges) 957 { 958 function highlightSearchResults(element, resultRanges, changes) 959 { 960 changes = changes || []; 958 961 var highlightNodes = []; 959 962 var lineText = element.textContent; … … 998 1001 // Selection belongs to a single split mode. 999 1002 textNode.textContent = text.substring(textNodeOffset + resultLength); 1003 changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent }); 1004 1000 1005 textNode.parentElement.insertBefore(highlightNode, textNode); 1006 changes.push({ node: highlightNode, type: "added", nextSibling: textNode, parent: textNode.parentElement }); 1007 1001 1008 var prefixNode = document.createTextNode(text.substring(0, textNodeOffset)); 1002 1009 textNode.parentElement.insertBefore(prefixNode, highlightNode); 1003 1010 changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: textNode.parentElement }); 1004 1011 highlightNodes.push(highlightNode); 1005 1012 continue; … … 1011 1018 length -= text.length - textNodeOffset; 1012 1019 textNode.textContent = text.substring(0, textNodeOffset); 1020 changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent }); 1013 1021 1014 1022 while (currentSnapshotItem < snapshotLength) { … … 1018 1026 if (length < text.length) { 1019 1027 textNode.textContent = text.substring(length); 1028 changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent }); 1020 1029 break; 1021 1030 } … … 1023 1032 length -= text.length; 1024 1033 textNode.textContent = ""; 1034 changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent }); 1025 1035 } 1026 1036 1027 1037 parentElement.insertBefore(highlightNode, anchorElement); 1038 changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: parentElement }); 1028 1039 highlightNodes.push(highlightNode); 1029 1040 }
Note: See TracChangeset
for help on using the changeset viewer.