OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | |
5 /** | 4 /** |
6 * @constructor | |
7 * @extends {WebInspector.Widget} | |
8 * @implements {WebInspector.Searchable} | 5 * @implements {WebInspector.Searchable} |
9 * @param {!Document} parsedXML | 6 * @unrestricted |
10 */ | 7 */ |
11 WebInspector.XMLView = function(parsedXML) | 8 WebInspector.XMLView = class extends WebInspector.Widget { |
12 { | 9 /** |
13 WebInspector.Widget.call(this, true); | 10 * @param {!Document} parsedXML |
14 this.registerRequiredCSS("network/xmlView.css"); | 11 */ |
15 this.contentElement.classList.add("shadow-xml-view", "source-code"); | 12 constructor(parsedXML) { |
| 13 super(true); |
| 14 this.registerRequiredCSS('network/xmlView.css'); |
| 15 this.contentElement.classList.add('shadow-xml-view', 'source-code'); |
16 this._treeOutline = new TreeOutlineInShadow(); | 16 this._treeOutline = new TreeOutlineInShadow(); |
17 this._treeOutline.registerRequiredCSS("network/xmlTree.css"); | 17 this._treeOutline.registerRequiredCSS('network/xmlTree.css'); |
18 this.contentElement.appendChild(this._treeOutline.element); | 18 this.contentElement.appendChild(this._treeOutline.element); |
19 | 19 |
20 /** @type {?WebInspector.SearchableView} */ | 20 /** @type {?WebInspector.SearchableView} */ |
21 this._searchableView; | 21 this._searchableView; |
22 /** @type {number} */ | 22 /** @type {number} */ |
23 this._currentSearchFocusIndex = 0; | 23 this._currentSearchFocusIndex = 0; |
24 /** @type {!Array.<!TreeElement>} */ | 24 /** @type {!Array.<!TreeElement>} */ |
25 this._currentSearchTreeElements = []; | 25 this._currentSearchTreeElements = []; |
26 /** @type {?WebInspector.SearchableView.SearchConfig} */ | 26 /** @type {?WebInspector.SearchableView.SearchConfig} */ |
27 this._searchConfig; | 27 this._searchConfig; |
28 | 28 |
29 WebInspector.XMLView.Node.populate(this._treeOutline, parsedXML, this); | 29 WebInspector.XMLView.Node.populate(this._treeOutline, parsedXML, this); |
30 }; | 30 } |
31 | 31 |
32 /** | 32 /** |
33 * @param {!Document} parsedXML | 33 * @param {!Document} parsedXML |
34 * @return {!WebInspector.SearchableView} | 34 * @return {!WebInspector.SearchableView} |
35 */ | 35 */ |
36 WebInspector.XMLView.createSearchableView = function(parsedXML) | 36 static createSearchableView(parsedXML) { |
37 { | |
38 var xmlView = new WebInspector.XMLView(parsedXML); | 37 var xmlView = new WebInspector.XMLView(parsedXML); |
39 var searchableView = new WebInspector.SearchableView(xmlView); | 38 var searchableView = new WebInspector.SearchableView(xmlView); |
40 searchableView.setPlaceholder(WebInspector.UIString("Find")); | 39 searchableView.setPlaceholder(WebInspector.UIString('Find')); |
41 xmlView._searchableView = searchableView; | 40 xmlView._searchableView = searchableView; |
42 xmlView.show(searchableView.element); | 41 xmlView.show(searchableView.element); |
43 xmlView.contentElement.setAttribute("tabIndex", 0); | 42 xmlView.contentElement.setAttribute('tabIndex', 0); |
44 return searchableView; | 43 return searchableView; |
45 }; | 44 } |
46 | 45 |
47 /** | 46 /** |
48 * @param {string} text | 47 * @param {string} text |
49 * @param {string} mimeType | 48 * @param {string} mimeType |
50 * @return {?Document} | 49 * @return {?Document} |
51 */ | 50 */ |
52 WebInspector.XMLView.parseXML = function(text, mimeType) | 51 static parseXML(text, mimeType) { |
53 { | |
54 var parsedXML; | 52 var parsedXML; |
55 try { | 53 try { |
56 parsedXML = (new DOMParser()).parseFromString(text, mimeType); | 54 parsedXML = (new DOMParser()).parseFromString(text, mimeType); |
57 } catch (e) { | 55 } catch (e) { |
58 return null; | 56 return null; |
59 } | 57 } |
60 if (parsedXML.body) | 58 if (parsedXML.body) |
61 return null; | 59 return null; |
62 return parsedXML; | 60 return parsedXML; |
| 61 } |
| 62 |
| 63 /** |
| 64 * @param {number} index |
| 65 * @param {boolean} shouldJump |
| 66 */ |
| 67 _jumpToMatch(index, shouldJump) { |
| 68 if (!this._searchConfig) |
| 69 return; |
| 70 var regex = this._searchConfig.toSearchRegex(true); |
| 71 var previousFocusElement = this._currentSearchTreeElements[this._currentSear
chFocusIndex]; |
| 72 if (previousFocusElement) |
| 73 previousFocusElement.setSearchRegex(regex); |
| 74 |
| 75 var newFocusElement = this._currentSearchTreeElements[index]; |
| 76 if (newFocusElement) { |
| 77 this._updateSearchIndex(index); |
| 78 if (shouldJump) |
| 79 newFocusElement.reveal(true); |
| 80 newFocusElement.setSearchRegex(regex, WebInspector.highlightedCurrentSearc
hResultClassName); |
| 81 } else { |
| 82 this._updateSearchIndex(0); |
| 83 } |
| 84 } |
| 85 |
| 86 /** |
| 87 * @param {number} count |
| 88 */ |
| 89 _updateSearchCount(count) { |
| 90 if (!this._searchableView) |
| 91 return; |
| 92 this._searchableView.updateSearchMatchesCount(count); |
| 93 } |
| 94 |
| 95 /** |
| 96 * @param {number} index |
| 97 */ |
| 98 _updateSearchIndex(index) { |
| 99 this._currentSearchFocusIndex = index; |
| 100 if (!this._searchableView) |
| 101 return; |
| 102 this._searchableView.updateCurrentMatchIndex(index); |
| 103 } |
| 104 |
| 105 /** |
| 106 * @param {boolean} shouldJump |
| 107 * @param {boolean=} jumpBackwards |
| 108 */ |
| 109 _innerPerformSearch(shouldJump, jumpBackwards) { |
| 110 if (!this._searchConfig) |
| 111 return; |
| 112 var newIndex = this._currentSearchFocusIndex; |
| 113 var previousSearchFocusElement = this._currentSearchTreeElements[newIndex]; |
| 114 this._innerSearchCanceled(); |
| 115 this._currentSearchTreeElements = []; |
| 116 var regex = this._searchConfig.toSearchRegex(true); |
| 117 |
| 118 for (var element = this._treeOutline.rootElement(); element; element = eleme
nt.traverseNextTreeElement(false)) { |
| 119 if (!(element instanceof WebInspector.XMLView.Node)) |
| 120 continue; |
| 121 var hasMatch = element.setSearchRegex(regex); |
| 122 if (hasMatch) |
| 123 this._currentSearchTreeElements.push(element); |
| 124 if (previousSearchFocusElement === element) { |
| 125 var currentIndex = this._currentSearchTreeElements.length - 1; |
| 126 if (hasMatch || jumpBackwards) |
| 127 newIndex = currentIndex; |
| 128 else |
| 129 newIndex = currentIndex + 1; |
| 130 } |
| 131 } |
| 132 this._updateSearchCount(this._currentSearchTreeElements.length); |
| 133 |
| 134 if (!this._currentSearchTreeElements.length) { |
| 135 this._updateSearchIndex(0); |
| 136 return; |
| 137 } |
| 138 newIndex = mod(newIndex, this._currentSearchTreeElements.length); |
| 139 |
| 140 this._jumpToMatch(newIndex, shouldJump); |
| 141 } |
| 142 |
| 143 _innerSearchCanceled() { |
| 144 for (var element = this._treeOutline.rootElement(); element; element = eleme
nt.traverseNextTreeElement(false)) { |
| 145 if (!(element instanceof WebInspector.XMLView.Node)) |
| 146 continue; |
| 147 element.revertHighlightChanges(); |
| 148 } |
| 149 this._updateSearchCount(0); |
| 150 this._updateSearchIndex(0); |
| 151 } |
| 152 |
| 153 /** |
| 154 * @override |
| 155 */ |
| 156 searchCanceled() { |
| 157 this._searchConfig = null; |
| 158 this._currentSearchTreeElements = []; |
| 159 this._innerSearchCanceled(); |
| 160 } |
| 161 |
| 162 /** |
| 163 * @override |
| 164 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
| 165 * @param {boolean} shouldJump |
| 166 * @param {boolean=} jumpBackwards |
| 167 */ |
| 168 performSearch(searchConfig, shouldJump, jumpBackwards) { |
| 169 this._searchConfig = searchConfig; |
| 170 this._innerPerformSearch(shouldJump, jumpBackwards); |
| 171 } |
| 172 |
| 173 /** |
| 174 * @override |
| 175 */ |
| 176 jumpToNextSearchResult() { |
| 177 if (!this._currentSearchTreeElements.length) |
| 178 return; |
| 179 |
| 180 var newIndex = mod(this._currentSearchFocusIndex + 1, this._currentSearchTre
eElements.length); |
| 181 this._jumpToMatch(newIndex, true); |
| 182 } |
| 183 |
| 184 /** |
| 185 * @override |
| 186 */ |
| 187 jumpToPreviousSearchResult() { |
| 188 if (!this._currentSearchTreeElements.length) |
| 189 return; |
| 190 |
| 191 var newIndex = mod(this._currentSearchFocusIndex - 1, this._currentSearchTre
eElements.length); |
| 192 this._jumpToMatch(newIndex, true); |
| 193 } |
| 194 |
| 195 /** |
| 196 * @override |
| 197 * @return {boolean} |
| 198 */ |
| 199 supportsCaseSensitiveSearch() { |
| 200 return true; |
| 201 } |
| 202 |
| 203 /** |
| 204 * @override |
| 205 * @return {boolean} |
| 206 */ |
| 207 supportsRegexSearch() { |
| 208 return true; |
| 209 } |
63 }; | 210 }; |
64 | 211 |
65 WebInspector.XMLView.prototype = { | |
66 /** | |
67 * @param {number} index | |
68 * @param {boolean} shouldJump | |
69 */ | |
70 _jumpToMatch: function(index, shouldJump) | |
71 { | |
72 if (!this._searchConfig) | |
73 return; | |
74 var regex = this._searchConfig.toSearchRegex(true); | |
75 var previousFocusElement = this._currentSearchTreeElements[this._current
SearchFocusIndex]; | |
76 if (previousFocusElement) | |
77 previousFocusElement.setSearchRegex(regex); | |
78 | |
79 var newFocusElement = this._currentSearchTreeElements[index]; | |
80 if (newFocusElement) { | |
81 this._updateSearchIndex(index); | |
82 if (shouldJump) | |
83 newFocusElement.reveal(true); | |
84 newFocusElement.setSearchRegex(regex, WebInspector.highlightedCurren
tSearchResultClassName); | |
85 } else { | |
86 this._updateSearchIndex(0); | |
87 } | |
88 }, | |
89 | |
90 /** | |
91 * @param {number} count | |
92 */ | |
93 _updateSearchCount: function(count) | |
94 { | |
95 if (!this._searchableView) | |
96 return; | |
97 this._searchableView.updateSearchMatchesCount(count); | |
98 }, | |
99 | |
100 /** | |
101 * @param {number} index | |
102 */ | |
103 _updateSearchIndex: function(index) | |
104 { | |
105 this._currentSearchFocusIndex = index; | |
106 if (!this._searchableView) | |
107 return; | |
108 this._searchableView.updateCurrentMatchIndex(index); | |
109 }, | |
110 | |
111 /** | |
112 * @param {boolean} shouldJump | |
113 * @param {boolean=} jumpBackwards | |
114 */ | |
115 _innerPerformSearch: function(shouldJump, jumpBackwards) | |
116 { | |
117 if (!this._searchConfig) | |
118 return; | |
119 var newIndex = this._currentSearchFocusIndex; | |
120 var previousSearchFocusElement = this._currentSearchTreeElements[newInde
x]; | |
121 this._innerSearchCanceled(); | |
122 this._currentSearchTreeElements = []; | |
123 var regex = this._searchConfig.toSearchRegex(true); | |
124 | |
125 for (var element = this._treeOutline.rootElement(); element; element = e
lement.traverseNextTreeElement(false)) { | |
126 if (!(element instanceof WebInspector.XMLView.Node)) | |
127 continue; | |
128 var hasMatch = element.setSearchRegex(regex); | |
129 if (hasMatch) | |
130 this._currentSearchTreeElements.push(element); | |
131 if (previousSearchFocusElement === element) { | |
132 var currentIndex = this._currentSearchTreeElements.length - 1; | |
133 if (hasMatch || jumpBackwards) | |
134 newIndex = currentIndex; | |
135 else | |
136 newIndex = currentIndex + 1; | |
137 } | |
138 } | |
139 this._updateSearchCount(this._currentSearchTreeElements.length); | |
140 | |
141 if (!this._currentSearchTreeElements.length) { | |
142 this._updateSearchIndex(0); | |
143 return; | |
144 } | |
145 newIndex = mod(newIndex, this._currentSearchTreeElements.length); | |
146 | |
147 this._jumpToMatch(newIndex, shouldJump); | |
148 }, | |
149 | |
150 _innerSearchCanceled: function() | |
151 { | |
152 for (var element = this._treeOutline.rootElement(); element; element = e
lement.traverseNextTreeElement(false)) { | |
153 if (!(element instanceof WebInspector.XMLView.Node)) | |
154 continue; | |
155 element.revertHighlightChanges(); | |
156 } | |
157 this._updateSearchCount(0); | |
158 this._updateSearchIndex(0); | |
159 }, | |
160 | |
161 /** | |
162 * @override | |
163 */ | |
164 searchCanceled: function() | |
165 { | |
166 this._searchConfig = null; | |
167 this._currentSearchTreeElements = []; | |
168 this._innerSearchCanceled(); | |
169 }, | |
170 | |
171 /** | |
172 * @override | |
173 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
174 * @param {boolean} shouldJump | |
175 * @param {boolean=} jumpBackwards | |
176 */ | |
177 performSearch: function(searchConfig, shouldJump, jumpBackwards) | |
178 { | |
179 this._searchConfig = searchConfig; | |
180 this._innerPerformSearch(shouldJump, jumpBackwards); | |
181 }, | |
182 | |
183 /** | |
184 * @override | |
185 */ | |
186 jumpToNextSearchResult: function() | |
187 { | |
188 if (!this._currentSearchTreeElements.length) | |
189 return; | |
190 | |
191 var newIndex = mod(this._currentSearchFocusIndex + 1, this._currentSearc
hTreeElements.length); | |
192 this._jumpToMatch(newIndex, true); | |
193 }, | |
194 | |
195 /** | |
196 * @override | |
197 */ | |
198 jumpToPreviousSearchResult: function() | |
199 { | |
200 if (!this._currentSearchTreeElements.length) | |
201 return; | |
202 | |
203 var newIndex = mod(this._currentSearchFocusIndex - 1, this._currentSearc
hTreeElements.length); | |
204 this._jumpToMatch(newIndex, true); | |
205 }, | |
206 | |
207 /** | |
208 * @override | |
209 * @return {boolean} | |
210 */ | |
211 supportsCaseSensitiveSearch: function() | |
212 { | |
213 return true; | |
214 }, | |
215 | |
216 /** | |
217 * @override | |
218 * @return {boolean} | |
219 */ | |
220 supportsRegexSearch: function() | |
221 { | |
222 return true; | |
223 }, | |
224 | |
225 __proto__: WebInspector.Widget.prototype | |
226 }; | |
227 | 212 |
228 /** | 213 /** |
229 * @constructor | 214 * @unrestricted |
230 * @extends {TreeElement} | |
231 * @param {!Node} node | |
232 * @param {boolean} closeTag | |
233 * @param {!WebInspector.XMLView} xmlView | |
234 */ | 215 */ |
235 WebInspector.XMLView.Node = function(node, closeTag, xmlView) | 216 WebInspector.XMLView.Node = class extends TreeElement { |
236 { | 217 /** |
237 TreeElement.call(this, "", !closeTag && !!node.childElementCount); | 218 * @param {!Node} node |
| 219 * @param {boolean} closeTag |
| 220 * @param {!WebInspector.XMLView} xmlView |
| 221 */ |
| 222 constructor(node, closeTag, xmlView) { |
| 223 super('', !closeTag && !!node.childElementCount); |
238 this._node = node; | 224 this._node = node; |
239 this._closeTag = closeTag; | 225 this._closeTag = closeTag; |
240 this.selectable = false; | 226 this.selectable = false; |
241 /** @type {!Array.<!Object>} */ | 227 /** @type {!Array.<!Object>} */ |
242 this._highlightChanges = []; | 228 this._highlightChanges = []; |
243 this._xmlView = xmlView; | 229 this._xmlView = xmlView; |
244 this._updateTitle(); | 230 this._updateTitle(); |
| 231 } |
| 232 |
| 233 /** |
| 234 * @param {!TreeOutline|!TreeElement} root |
| 235 * @param {!Node} xmlNode |
| 236 * @param {!WebInspector.XMLView} xmlView |
| 237 */ |
| 238 static populate(root, xmlNode, xmlView) { |
| 239 var node = xmlNode.firstChild; |
| 240 while (node) { |
| 241 var currentNode = node; |
| 242 node = node.nextSibling; |
| 243 var nodeType = currentNode.nodeType; |
| 244 // ignore empty TEXT |
| 245 if (nodeType === 3 && currentNode.nodeValue.match(/\s+/)) |
| 246 continue; |
| 247 // ignore ATTRIBUTE, ENTITY_REFERENCE, ENTITY, DOCUMENT, DOCUMENT_TYPE, DO
CUMENT_FRAGMENT, NOTATION |
| 248 if ((nodeType !== 1) && (nodeType !== 3) && (nodeType !== 4) && (nodeType
!== 7) && (nodeType !== 8)) |
| 249 continue; |
| 250 root.appendChild(new WebInspector.XMLView.Node(currentNode, false, xmlView
)); |
| 251 } |
| 252 } |
| 253 |
| 254 /** |
| 255 * @param {?RegExp} regex |
| 256 * @param {string=} additionalCssClassName |
| 257 * @return {boolean} |
| 258 */ |
| 259 setSearchRegex(regex, additionalCssClassName) { |
| 260 this.revertHighlightChanges(); |
| 261 if (!regex) |
| 262 return false; |
| 263 if (this._closeTag && this.parent && !this.parent.expanded) |
| 264 return false; |
| 265 regex.lastIndex = 0; |
| 266 var cssClasses = WebInspector.highlightedSearchResultClassName; |
| 267 if (additionalCssClassName) |
| 268 cssClasses += ' ' + additionalCssClassName; |
| 269 var content = this.listItemElement.textContent.replace(/\xA0/g, ' '); |
| 270 var match = regex.exec(content); |
| 271 var ranges = []; |
| 272 while (match) { |
| 273 ranges.push(new WebInspector.SourceRange(match.index, match[0].length)); |
| 274 match = regex.exec(content); |
| 275 } |
| 276 if (ranges.length) |
| 277 WebInspector.highlightRangesWithStyleClass(this.listItemElement, ranges, c
ssClasses, this._highlightChanges); |
| 278 return !!this._highlightChanges.length; |
| 279 } |
| 280 |
| 281 revertHighlightChanges() { |
| 282 WebInspector.revertDomChanges(this._highlightChanges); |
| 283 this._highlightChanges = []; |
| 284 } |
| 285 |
| 286 _updateTitle() { |
| 287 var node = this._node; |
| 288 switch (node.nodeType) { |
| 289 case 1: // ELEMENT |
| 290 var tag = node.tagName; |
| 291 if (this._closeTag) { |
| 292 this._setTitle(['</' + tag + '>', 'shadow-xml-view-tag']); |
| 293 return; |
| 294 } |
| 295 var titleItems = ['<' + tag, 'shadow-xml-view-tag']; |
| 296 var attributes = node.attributes; |
| 297 for (var i = 0; i < attributes.length; ++i) { |
| 298 var attributeNode = attributes.item(i); |
| 299 titleItems.push( |
| 300 '\u00a0', 'shadow-xml-view-tag', attributeNode.name, 'shadow-xml-v
iew-attribute-name', '="', |
| 301 'shadow-xml-view-tag', attributeNode.value, 'shadow-xml-view-attri
bute-value', '"', |
| 302 'shadow-xml-view-tag'); |
| 303 } |
| 304 if (!this.expanded) { |
| 305 if (node.childElementCount) { |
| 306 titleItems.push( |
| 307 '>', 'shadow-xml-view-tag', '\u2026', 'shadow-xml-view-comment',
'</' + tag, 'shadow-xml-view-tag'); |
| 308 } else if (this._node.textContent) { |
| 309 titleItems.push( |
| 310 '>', 'shadow-xml-view-tag', node.textContent, 'shadow-xml-view-t
ext', '</' + tag, |
| 311 'shadow-xml-view-tag'); |
| 312 } else { |
| 313 titleItems.push(' /', 'shadow-xml-view-tag'); |
| 314 } |
| 315 } |
| 316 titleItems.push('>', 'shadow-xml-view-tag'); |
| 317 this._setTitle(titleItems); |
| 318 return; |
| 319 case 3: // TEXT |
| 320 this._setTitle([node.nodeValue, 'shadow-xml-view-text']); |
| 321 return; |
| 322 case 4: // CDATA |
| 323 this._setTitle([ |
| 324 '<![CDATA[', 'shadow-xml-view-cdata', node.nodeValue, 'shadow-xml-view
-text', ']]>', 'shadow-xml-view-cdata' |
| 325 ]); |
| 326 return; |
| 327 case 7: // PROCESSING_INSTRUCTION |
| 328 this._setTitle(['<?' + node.nodeName + ' ' + node.nodeValue + '?>', 'sha
dow-xml-view-processing-instruction']); |
| 329 return; |
| 330 case 8: // COMMENT |
| 331 this._setTitle(['<!--' + node.nodeValue + '-->', 'shadow-xml-view-commen
t']); |
| 332 return; |
| 333 } |
| 334 } |
| 335 |
| 336 /** |
| 337 * @param {!Array.<string>} items |
| 338 */ |
| 339 _setTitle(items) { |
| 340 var titleFragment = createDocumentFragment(); |
| 341 for (var i = 0; i < items.length; i += 2) |
| 342 titleFragment.createChild('span', items[i + 1]).textContent = items[i]; |
| 343 this.title = titleFragment; |
| 344 this._xmlView._innerPerformSearch(false, false); |
| 345 } |
| 346 |
| 347 /** |
| 348 * @override |
| 349 */ |
| 350 onattach() { |
| 351 this.listItemElement.classList.toggle('shadow-xml-view-close-tag', this._clo
seTag); |
| 352 } |
| 353 |
| 354 /** |
| 355 * @override |
| 356 */ |
| 357 onexpand() { |
| 358 this._updateTitle(); |
| 359 } |
| 360 |
| 361 /** |
| 362 * @override |
| 363 */ |
| 364 oncollapse() { |
| 365 this._updateTitle(); |
| 366 } |
| 367 |
| 368 /** |
| 369 * @override |
| 370 */ |
| 371 onpopulate() { |
| 372 WebInspector.XMLView.Node.populate(this, this._node, this._xmlView); |
| 373 this.appendChild(new WebInspector.XMLView.Node(this._node, true, this._xmlVi
ew)); |
| 374 } |
245 }; | 375 }; |
246 | 376 |
247 /** | |
248 * @param {!TreeOutline|!TreeElement} root | |
249 * @param {!Node} xmlNode | |
250 * @param {!WebInspector.XMLView} xmlView | |
251 */ | |
252 WebInspector.XMLView.Node.populate = function(root, xmlNode, xmlView) | |
253 { | |
254 var node = xmlNode.firstChild; | |
255 while (node) { | |
256 var currentNode = node; | |
257 node = node.nextSibling; | |
258 var nodeType = currentNode.nodeType; | |
259 // ignore empty TEXT | |
260 if (nodeType === 3 && currentNode.nodeValue.match(/\s+/)) | |
261 continue; | |
262 // ignore ATTRIBUTE, ENTITY_REFERENCE, ENTITY, DOCUMENT, DOCUMENT_TYPE,
DOCUMENT_FRAGMENT, NOTATION | |
263 if ((nodeType !== 1) && (nodeType !== 3) && (nodeType !== 4) && (nodeTyp
e !== 7) && (nodeType !== 8)) | |
264 continue; | |
265 root.appendChild(new WebInspector.XMLView.Node(currentNode, false, xmlVi
ew)); | |
266 } | |
267 }; | |
268 | 377 |
269 WebInspector.XMLView.Node.prototype = { | |
270 /** | |
271 * @param {?RegExp} regex | |
272 * @param {string=} additionalCssClassName | |
273 * @return {boolean} | |
274 */ | |
275 setSearchRegex: function(regex, additionalCssClassName) | |
276 { | |
277 this.revertHighlightChanges(); | |
278 if (!regex) | |
279 return false; | |
280 if (this._closeTag && this.parent && !this.parent.expanded) | |
281 return false; | |
282 regex.lastIndex = 0; | |
283 var cssClasses = WebInspector.highlightedSearchResultClassName; | |
284 if (additionalCssClassName) | |
285 cssClasses += " " + additionalCssClassName; | |
286 var content = this.listItemElement.textContent.replace(/\xA0/g, " "); | |
287 var match = regex.exec(content); | |
288 var ranges = []; | |
289 while (match) { | |
290 ranges.push(new WebInspector.SourceRange(match.index, match[0].lengt
h)); | |
291 match = regex.exec(content); | |
292 } | |
293 if (ranges.length) | |
294 WebInspector.highlightRangesWithStyleClass(this.listItemElement, ran
ges, cssClasses, this._highlightChanges); | |
295 return !!this._highlightChanges.length; | |
296 }, | |
297 | |
298 revertHighlightChanges: function() | |
299 { | |
300 WebInspector.revertDomChanges(this._highlightChanges); | |
301 this._highlightChanges = []; | |
302 }, | |
303 | |
304 _updateTitle: function() | |
305 { | |
306 var node = this._node; | |
307 switch (node.nodeType) { | |
308 case 1: // ELEMENT | |
309 var tag = node.tagName; | |
310 if (this._closeTag) { | |
311 this._setTitle(["</" + tag + ">", "shadow-xml-view-tag"]); | |
312 return; | |
313 } | |
314 var titleItems = ["<" + tag, "shadow-xml-view-tag"]; | |
315 var attributes = node.attributes; | |
316 for (var i = 0; i < attributes.length; ++i) { | |
317 var attributeNode = attributes.item(i); | |
318 titleItems.push( | |
319 "\u00a0", "shadow-xml-view-tag", | |
320 attributeNode.name, "shadow-xml-view-attribute-name", | |
321 "=\"", "shadow-xml-view-tag", | |
322 attributeNode.value, "shadow-xml-view-attribute-value", | |
323 "\"", "shadow-xml-view-tag"); | |
324 } | |
325 if (!this.expanded) { | |
326 if (node.childElementCount) { | |
327 titleItems.push( | |
328 ">", "shadow-xml-view-tag", | |
329 "\u2026", "shadow-xml-view-comment", | |
330 "</" + tag, "shadow-xml-view-tag"); | |
331 } else if (this._node.textContent) { | |
332 titleItems.push( | |
333 ">", "shadow-xml-view-tag", | |
334 node.textContent, "shadow-xml-view-text", | |
335 "</" + tag, "shadow-xml-view-tag"); | |
336 } else { | |
337 titleItems.push(" /", "shadow-xml-view-tag"); | |
338 } | |
339 } | |
340 titleItems.push(">", "shadow-xml-view-tag"); | |
341 this._setTitle(titleItems); | |
342 return; | |
343 case 3: // TEXT | |
344 this._setTitle([node.nodeValue, "shadow-xml-view-text"]); | |
345 return; | |
346 case 4: // CDATA | |
347 this._setTitle([ | |
348 "<![CDATA[", "shadow-xml-view-cdata", | |
349 node.nodeValue, "shadow-xml-view-text", | |
350 "]]>", "shadow-xml-view-cdata"]); | |
351 return; | |
352 case 7: // PROCESSING_INSTRUCTION | |
353 this._setTitle(["<?" + node.nodeName + " " + node.nodeValue + "?>",
"shadow-xml-view-processing-instruction"]); | |
354 return; | |
355 case 8: // COMMENT | |
356 this._setTitle(["<!--" + node.nodeValue + "-->", "shadow-xml-view-co
mment"]); | |
357 return; | |
358 } | |
359 }, | |
360 | |
361 /** | |
362 * @param {!Array.<string>} items | |
363 */ | |
364 _setTitle: function(items) | |
365 { | |
366 var titleFragment = createDocumentFragment(); | |
367 for (var i = 0; i < items.length; i += 2) | |
368 titleFragment.createChild("span", items[i + 1]).textContent = items[
i]; | |
369 this.title = titleFragment; | |
370 this._xmlView._innerPerformSearch(false, false); | |
371 }, | |
372 | |
373 onattach: function() | |
374 { | |
375 this.listItemElement.classList.toggle("shadow-xml-view-close-tag", this.
_closeTag); | |
376 }, | |
377 | |
378 onexpand: function() | |
379 { | |
380 this._updateTitle(); | |
381 }, | |
382 | |
383 oncollapse: function() | |
384 { | |
385 this._updateTitle(); | |
386 }, | |
387 | |
388 onpopulate: function() | |
389 { | |
390 WebInspector.XMLView.Node.populate(this, this._node, this._xmlView); | |
391 this.appendChild(new WebInspector.XMLView.Node(this._node, true, this._x
mlView)); | |
392 }, | |
393 | |
394 __proto__: TreeElement.prototype | |
395 }; | |
OLD | NEW |