Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: resources/inspector/utilities.js

Issue 853002: Updating the Chromium reference build for Windows. The continuous... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/reference_builds/chrome/
Patch Set: Added the symbol files back. Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « resources/inspector/treeoutline.js ('k') | servers/chrome_launcher.exe » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 Object.proxyType = function(objectProxy)
30 {
31 if (objectProxy === null)
32 return "null";
33
34 var type = typeof objectProxy;
35 if (type !== "object" && type !== "function")
36 return type;
37
38 return objectProxy.type;
39 }
40
41 Object.properties = function(obj)
42 {
43 var properties = [];
44 for (var prop in obj)
45 properties.push(prop);
46 return properties;
47 }
48
49 Object.sortedProperties = function(obj, sortFunc)
50 {
51 return Object.properties(obj).sort(sortFunc);
52 }
53
54 Function.prototype.bind = function(thisObject)
55 {
56 var func = this;
57 var args = Array.prototype.slice.call(arguments, 1);
58 return function() { return func.apply(thisObject, args.concat(Array.prototyp e.slice.call(arguments, 0))) };
59 }
60
61 Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, di rection)
62 {
63 var startNode;
64 var startOffset = 0;
65 var endNode;
66 var endOffset = 0;
67
68 if (!stayWithinNode)
69 stayWithinNode = this;
70
71 if (!direction || direction === "backward" || direction === "both") {
72 var node = this;
73 while (node) {
74 if (node === stayWithinNode) {
75 if (!startNode)
76 startNode = stayWithinNode;
77 break;
78 }
79
80 if (node.nodeType === Node.TEXT_NODE) {
81 var start = (node === this ? (offset - 1) : (node.nodeValue.leng th - 1));
82 for (var i = start; i >= 0; --i) {
83 if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
84 startNode = node;
85 startOffset = i + 1;
86 break;
87 }
88 }
89 }
90
91 if (startNode)
92 break;
93
94 node = node.traversePreviousNode(stayWithinNode);
95 }
96
97 if (!startNode) {
98 startNode = stayWithinNode;
99 startOffset = 0;
100 }
101 } else {
102 startNode = this;
103 startOffset = offset;
104 }
105
106 if (!direction || direction === "forward" || direction === "both") {
107 node = this;
108 while (node) {
109 if (node === stayWithinNode) {
110 if (!endNode)
111 endNode = stayWithinNode;
112 break;
113 }
114
115 if (node.nodeType === Node.TEXT_NODE) {
116 var start = (node === this ? offset : 0);
117 for (var i = start; i < node.nodeValue.length; ++i) {
118 if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
119 endNode = node;
120 endOffset = i;
121 break;
122 }
123 }
124 }
125
126 if (endNode)
127 break;
128
129 node = node.traverseNextNode(stayWithinNode);
130 }
131
132 if (!endNode) {
133 endNode = stayWithinNode;
134 endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinN ode.nodeValue.length : stayWithinNode.childNodes.length;
135 }
136 } else {
137 endNode = this;
138 endOffset = offset;
139 }
140
141 var result = this.ownerDocument.createRange();
142 result.setStart(startNode, startOffset);
143 result.setEnd(endNode, endOffset);
144
145 return result;
146 }
147
148 Element.prototype.removeStyleClass = function(className)
149 {
150 // Test for the simple case before using a RegExp.
151 if (this.className === className) {
152 this.className = "";
153 return;
154 }
155
156 this.removeMatchingStyleClasses(className.escapeForRegExp());
157 }
158
159 Element.prototype.removeMatchingStyleClasses = function(classNameRegex)
160 {
161 var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)");
162 if (regex.test(this.className))
163 this.className = this.className.replace(regex, " ");
164 }
165
166 Element.prototype.addStyleClass = function(className)
167 {
168 if (className && !this.hasStyleClass(className))
169 this.className += (this.className.length ? " " + className : className);
170 }
171
172 Element.prototype.hasStyleClass = function(className)
173 {
174 if (!className)
175 return false;
176 // Test for the simple case before using a RegExp.
177 if (this.className === className)
178 return true;
179 var regex = new RegExp("(^|\\s)" + className.escapeForRegExp() + "($|\\s)");
180 return regex.test(this.className);
181 }
182
183 Element.prototype.positionAt = function(x, y)
184 {
185 this.style.left = x + "px";
186 this.style.top = y + "px";
187 }
188
189 Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
190 {
191 for (var node = this; node && node !== this.ownerDocument; node = node.paren tNode)
192 for (var i = 0; i < nameArray.length; ++i)
193 if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
194 return node;
195 return null;
196 }
197
198 Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
199 {
200 return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
201 }
202
203 Node.prototype.enclosingNodeOrSelfWithClass = function(className)
204 {
205 for (var node = this; node && node !== this.ownerDocument; node = node.paren tNode)
206 if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className) )
207 return node;
208 return null;
209 }
210
211 Node.prototype.enclosingNodeWithClass = function(className)
212 {
213 if (!this.parentNode)
214 return null;
215 return this.parentNode.enclosingNodeOrSelfWithClass(className);
216 }
217
218 Element.prototype.query = function(query)
219 {
220 return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDE RED_NODE_TYPE, null).singleNodeValue;
221 }
222
223 Element.prototype.removeChildren = function()
224 {
225 while (this.firstChild)
226 this.removeChild(this.firstChild);
227 }
228
229 Element.prototype.isInsertionCaretInside = function()
230 {
231 var selection = window.getSelection();
232 if (!selection.rangeCount || !selection.isCollapsed)
233 return false;
234 var selectionRange = selection.getRangeAt(0);
235 return selectionRange.startContainer === this || selectionRange.startContain er.isDescendant(this);
236 }
237
238 Element.prototype.__defineGetter__("totalOffsetLeft", function()
239 {
240 var total = 0;
241 for (var element = this; element; element = element.offsetParent)
242 total += element.offsetLeft;
243 return total;
244 });
245
246 Element.prototype.__defineGetter__("totalOffsetTop", function()
247 {
248 var total = 0;
249 for (var element = this; element; element = element.offsetParent)
250 total += element.offsetTop;
251 return total;
252 });
253
254 Element.prototype.offsetRelativeToWindow = function(targetWindow)
255 {
256 var elementOffset = {x: 0, y: 0};
257 var curElement = this;
258 var curWindow = this.ownerDocument.defaultView;
259 while (curWindow && curElement) {
260 elementOffset.x += curElement.totalOffsetLeft;
261 elementOffset.y += curElement.totalOffsetTop;
262 if (curWindow === targetWindow)
263 break;
264
265 curElement = curWindow.frameElement;
266 curWindow = curWindow.parent;
267 }
268
269 return elementOffset;
270 }
271
272 Node.prototype.isWhitespace = isNodeWhitespace;
273 Node.prototype.displayName = nodeDisplayName;
274 Node.prototype.isAncestor = function(node)
275 {
276 return isAncestorNode(this, node);
277 };
278 Node.prototype.isDescendant = isDescendantNode;
279 Node.prototype.traverseNextNode = traverseNextNode;
280 Node.prototype.traversePreviousNode = traversePreviousNode;
281 Node.prototype.onlyTextChild = onlyTextChild;
282
283 String.prototype.hasSubstring = function(string, caseInsensitive)
284 {
285 if (!caseInsensitive)
286 return this.indexOf(string) !== -1;
287 return this.match(new RegExp(string.escapeForRegExp(), "i"));
288 }
289
290 String.prototype.escapeCharacters = function(chars)
291 {
292 var foundChar = false;
293 for (var i = 0; i < chars.length; ++i) {
294 if (this.indexOf(chars.charAt(i)) !== -1) {
295 foundChar = true;
296 break;
297 }
298 }
299
300 if (!foundChar)
301 return this;
302
303 var result = "";
304 for (var i = 0; i < this.length; ++i) {
305 if (chars.indexOf(this.charAt(i)) !== -1)
306 result += "\\";
307 result += this.charAt(i);
308 }
309
310 return result;
311 }
312
313 String.prototype.escapeForRegExp = function()
314 {
315 return this.escapeCharacters("^[]{}()\\.$*+?|");
316 }
317
318 String.prototype.escapeHTML = function()
319 {
320 return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt; ");
321 }
322
323 String.prototype.collapseWhitespace = function()
324 {
325 return this.replace(/[\s\xA0]+/g, " ");
326 }
327
328 String.prototype.trimLeadingWhitespace = function()
329 {
330 return this.replace(/^[\s\xA0]+/g, "");
331 }
332
333 String.prototype.trimTrailingWhitespace = function()
334 {
335 return this.replace(/[\s\xA0]+$/g, "");
336 }
337
338 String.prototype.trimWhitespace = function()
339 {
340 return this.replace(/^[\s\xA0]+|[\s\xA0]+$/g, "");
341 }
342
343 String.prototype.trimURL = function(baseURLDomain)
344 {
345 var result = this.replace(new RegExp("^http[s]?:\/\/", "i"), "");
346 if (baseURLDomain)
347 result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp() , "i"), "");
348 return result;
349 }
350
351 function isNodeWhitespace()
352 {
353 if (!this || this.nodeType !== Node.TEXT_NODE)
354 return false;
355 if (!this.nodeValue.length)
356 return true;
357 return this.nodeValue.match(/^[\s\xA0]+$/);
358 }
359
360 function nodeDisplayName()
361 {
362 if (!this)
363 return "";
364
365 switch (this.nodeType) {
366 case Node.DOCUMENT_NODE:
367 return "Document";
368
369 case Node.ELEMENT_NODE:
370 var name = "<" + this.nodeName.toLowerCase();
371
372 if (this.hasAttributes()) {
373 var value = this.getAttribute("id");
374 if (value)
375 name += " id=\"" + value + "\"";
376 value = this.getAttribute("class");
377 if (value)
378 name += " class=\"" + value + "\"";
379 if (this.nodeName.toLowerCase() === "a") {
380 value = this.getAttribute("name");
381 if (value)
382 name += " name=\"" + value + "\"";
383 value = this.getAttribute("href");
384 if (value)
385 name += " href=\"" + value + "\"";
386 } else if (this.nodeName.toLowerCase() === "img") {
387 value = this.getAttribute("src");
388 if (value)
389 name += " src=\"" + value + "\"";
390 } else if (this.nodeName.toLowerCase() === "iframe") {
391 value = this.getAttribute("src");
392 if (value)
393 name += " src=\"" + value + "\"";
394 } else if (this.nodeName.toLowerCase() === "input") {
395 value = this.getAttribute("name");
396 if (value)
397 name += " name=\"" + value + "\"";
398 value = this.getAttribute("type");
399 if (value)
400 name += " type=\"" + value + "\"";
401 } else if (this.nodeName.toLowerCase() === "form") {
402 value = this.getAttribute("action");
403 if (value)
404 name += " action=\"" + value + "\"";
405 }
406 }
407
408 return name + ">";
409
410 case Node.TEXT_NODE:
411 if (isNodeWhitespace.call(this))
412 return "(whitespace)";
413 return "\"" + this.nodeValue + "\"";
414
415 case Node.COMMENT_NODE:
416 return "<!--" + this.nodeValue + "-->";
417
418 case Node.DOCUMENT_TYPE_NODE:
419 var docType = "<!DOCTYPE " + this.nodeName;
420 if (this.publicId) {
421 docType += " PUBLIC \"" + this.publicId + "\"";
422 if (this.systemId)
423 docType += " \"" + this.systemId + "\"";
424 } else if (this.systemId)
425 docType += " SYSTEM \"" + this.systemId + "\"";
426 if (this.internalSubset)
427 docType += " [" + this.internalSubset + "]";
428 return docType + ">";
429 }
430
431 return this.nodeName.toLowerCase().collapseWhitespace();
432 }
433
434 function isAncestorNode(ancestor, node)
435 {
436 if (!node || !ancestor)
437 return false;
438
439 var currentNode = node.parentNode;
440 while (currentNode) {
441 if (ancestor === currentNode)
442 return true;
443 currentNode = currentNode.parentNode;
444 }
445 return false;
446 }
447
448 function isDescendantNode(descendant)
449 {
450 return isAncestorNode(descendant, this);
451 }
452
453 function traverseNextNode(stayWithin)
454 {
455 if (!this)
456 return;
457
458 var node = this.firstChild;
459 if (node)
460 return node;
461
462 if (stayWithin && this === stayWithin)
463 return null;
464
465 node = this.nextSibling;
466 if (node)
467 return node;
468
469 node = this;
470 while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node .parentNode !== stayWithin))
471 node = node.parentNode;
472 if (!node)
473 return null;
474
475 return node.nextSibling;
476 }
477
478 function traversePreviousNode(stayWithin)
479 {
480 if (!this)
481 return;
482 if (stayWithin && this === stayWithin)
483 return null;
484 var node = this.previousSibling;
485 while (node && node.lastChild)
486 node = node.lastChild;
487 if (node)
488 return node;
489 return this.parentNode;
490 }
491
492 function onlyTextChild()
493 {
494 if (!this)
495 return null;
496
497 var firstChild = this.firstChild;
498 if (!firstChild || firstChild.nodeType !== Node.TEXT_NODE)
499 return null;
500
501 var sibling = firstChild.nextSibling;
502 return sibling ? null : firstChild;
503 }
504
505 function appropriateSelectorForNode(node, justSelector)
506 {
507 if (!node)
508 return "";
509
510 var lowerCaseName = node.localName || node.nodeName.toLowerCase();
511
512 var id = node.getAttribute("id");
513 if (id) {
514 var selector = "#" + id;
515 return (justSelector ? selector : lowerCaseName + selector);
516 }
517
518 var className = node.getAttribute("class");
519 if (className) {
520 var selector = "." + className.replace(/\s+/, ".");
521 return (justSelector ? selector : lowerCaseName + selector);
522 }
523
524 if (lowerCaseName === "input" && node.getAttribute("type"))
525 return lowerCaseName + "[type=\"" + node.getAttribute("type") + "\"]";
526
527 return lowerCaseName;
528 }
529
530 function getDocumentForNode(node)
531 {
532 return node.nodeType == Node.DOCUMENT_NODE ? node : node.ownerDocument;
533 }
534
535 function parentNode(node)
536 {
537 return node.parentNode;
538 }
539
540 Number.secondsToString = function(seconds, formatterFunction, higherResolution)
541 {
542 if (!formatterFunction)
543 formatterFunction = String.sprintf;
544
545 var ms = seconds * 1000;
546 if (higherResolution && ms < 1000)
547 return formatterFunction("%.3fms", ms);
548 else if (ms < 1000)
549 return formatterFunction("%.0fms", ms);
550
551 if (seconds < 60)
552 return formatterFunction("%.2fs", seconds);
553
554 var minutes = seconds / 60;
555 if (minutes < 60)
556 return formatterFunction("%.1fmin", minutes);
557
558 var hours = minutes / 60;
559 if (hours < 24)
560 return formatterFunction("%.1fhrs", hours);
561
562 var days = hours / 24;
563 return formatterFunction("%.1f days", days);
564 }
565
566 Number.bytesToString = function(bytes, formatterFunction, higherResolution)
567 {
568 if (!formatterFunction)
569 formatterFunction = String.sprintf;
570 if (typeof higherResolution === "undefined")
571 higherResolution = true;
572
573 if (bytes < 1024)
574 return formatterFunction("%.0fB", bytes);
575
576 var kilobytes = bytes / 1024;
577 if (higherResolution && kilobytes < 1024)
578 return formatterFunction("%.2fKB", kilobytes);
579 else if (kilobytes < 1024)
580 return formatterFunction("%.0fKB", kilobytes);
581
582 var megabytes = kilobytes / 1024;
583 if (higherResolution)
584 return formatterFunction("%.3fMB", megabytes);
585 else
586 return formatterFunction("%.0fMB", megabytes);
587 }
588
589 Number.constrain = function(num, min, max)
590 {
591 if (num < min)
592 num = min;
593 else if (num > max)
594 num = max;
595 return num;
596 }
597
598 HTMLTextAreaElement.prototype.moveCursorToEnd = function()
599 {
600 var length = this.value.length;
601 this.setSelectionRange(length, length);
602 }
603
604 Array.prototype.remove = function(value, onlyFirst)
605 {
606 if (onlyFirst) {
607 var index = this.indexOf(value);
608 if (index !== -1)
609 this.splice(index, 1);
610 return;
611 }
612
613 var length = this.length;
614 for (var i = 0; i < length; ++i) {
615 if (this[i] === value)
616 this.splice(i, 1);
617 }
618 }
619
620 function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunctio n)
621 {
622 // indexOf returns (-lowerBound - 1). Taking (-result - 1) works out to lowe rBound.
623 return (-indexOfObjectInListSortedByFunction(anObject, aList, aFunction) - 1 );
624 }
625
626 function indexOfObjectInListSortedByFunction(anObject, aList, aFunction)
627 {
628 var first = 0;
629 var last = aList.length - 1;
630 var floor = Math.floor;
631 var mid, c;
632
633 while (first <= last) {
634 mid = floor((first + last) / 2);
635 c = aFunction(anObject, aList[mid]);
636
637 if (c > 0)
638 first = mid + 1;
639 else if (c < 0)
640 last = mid - 1;
641 else {
642 // Return the first occurance of an item in the list.
643 while (mid > 0 && aFunction(anObject, aList[mid - 1]) === 0)
644 mid--;
645 first = mid;
646 break;
647 }
648 }
649
650 // By returning 1 less than the negative lower search bound, we can reuse th is function
651 // for both indexOf and insertionIndexFor, with some simple arithmetic.
652 return (-first - 1);
653 }
654
655 String.sprintf = function(format)
656 {
657 return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
658 }
659
660 String.tokenizeFormatString = function(format)
661 {
662 var tokens = [];
663 var substitutionIndex = 0;
664
665 function addStringToken(str)
666 {
667 tokens.push({ type: "string", value: str });
668 }
669
670 function addSpecifierToken(specifier, precision, substitutionIndex)
671 {
672 tokens.push({ type: "specifier", specifier: specifier, precision: precis ion, substitutionIndex: substitutionIndex });
673 }
674
675 var index = 0;
676 for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; pre centIndex = format.indexOf("%", index)) {
677 addStringToken(format.substring(index, precentIndex));
678 index = precentIndex + 1;
679
680 if (format[index] === "%") {
681 addStringToken("%");
682 ++index;
683 continue;
684 }
685
686 if (!isNaN(format[index])) {
687 // The first character is a number, it might be a substitution index .
688 var number = parseInt(format.substring(index));
689 while (!isNaN(format[index]))
690 ++index;
691 // If the number is greater than zero and ends with a "$",
692 // then this is a substitution index.
693 if (number > 0 && format[index] === "$") {
694 substitutionIndex = (number - 1);
695 ++index;
696 }
697 }
698
699 var precision = -1;
700 if (format[index] === ".") {
701 // This is a precision specifier. If no digit follows the ".",
702 // then the precision should be zero.
703 ++index;
704 precision = parseInt(format.substring(index));
705 if (isNaN(precision))
706 precision = 0;
707 while (!isNaN(format[index]))
708 ++index;
709 }
710
711 addSpecifierToken(format[index], precision, substitutionIndex);
712
713 ++substitutionIndex;
714 ++index;
715 }
716
717 addStringToken(format.substring(index));
718
719 return tokens;
720 }
721
722 String.standardFormatters = {
723 d: function(substitution)
724 {
725 if (typeof substitution == "object" && Object.proxyType(substitution) == = "number")
726 substitution = substitution.description;
727 substitution = parseInt(substitution);
728 return !isNaN(substitution) ? substitution : 0;
729 },
730
731 f: function(substitution, token)
732 {
733 if (typeof substitution == "object" && Object.proxyType(substitution) == = "number")
734 substitution = substitution.description;
735 substitution = parseFloat(substitution);
736 if (substitution && token.precision > -1)
737 substitution = substitution.toFixed(token.precision);
738 return !isNaN(substitution) ? substitution : (token.precision > -1 ? Num ber(0).toFixed(token.precision) : 0);
739 },
740
741 s: function(substitution)
742 {
743 if (typeof substitution == "object" && Object.proxyType(substitution) != = "null")
744 substitution = substitution.description;
745 return substitution;
746 },
747 };
748
749 String.vsprintf = function(format, substitutions)
750 {
751 return String.format(format, substitutions, String.standardFormatters, "", f unction(a, b) { return a + b; }).formattedResult;
752 }
753
754 String.format = function(format, substitutions, formatters, initialValue, append )
755 {
756 if (!format || !substitutions || !substitutions.length)
757 return { formattedResult: append(initialValue, format), unusedSubstituti ons: substitutions };
758
759 function prettyFunctionName()
760 {
761 return "String.format(\"" + format + "\", \"" + substitutions.join("\", \"") + "\")";
762 }
763
764 function warn(msg)
765 {
766 console.warn(prettyFunctionName() + ": " + msg);
767 }
768
769 function error(msg)
770 {
771 console.error(prettyFunctionName() + ": " + msg);
772 }
773
774 var result = initialValue;
775 var tokens = String.tokenizeFormatString(format);
776 var usedSubstitutionIndexes = {};
777
778 for (var i = 0; i < tokens.length; ++i) {
779 var token = tokens[i];
780
781 if (token.type === "string") {
782 result = append(result, token.value);
783 continue;
784 }
785
786 if (token.type !== "specifier") {
787 error("Unknown token type \"" + token.type + "\" found.");
788 continue;
789 }
790
791 if (token.substitutionIndex >= substitutions.length) {
792 // If there are not enough substitutions for the current substitutio nIndex
793 // just output the format specifier literally and move on.
794 error("not enough substitution arguments. Had " + substitutions.leng th + " but needed " + (token.substitutionIndex + 1) + ", so substitution was ski pped.");
795 result = append(result, "%" + (token.precision > -1 ? token.precisio n : "") + token.specifier);
796 continue;
797 }
798
799 usedSubstitutionIndexes[token.substitutionIndex] = true;
800
801 if (!(token.specifier in formatters)) {
802 // Encountered an unsupported format character, treat as a string.
803 warn("unsupported format character \u201C" + token.specifier + "\u20 1D. Treating as a string.");
804 result = append(result, substitutions[token.substitutionIndex]);
805 continue;
806 }
807
808 result = append(result, formatters[token.specifier](substitutions[token. substitutionIndex], token));
809 }
810
811 var unusedSubstitutions = [];
812 for (var i = 0; i < substitutions.length; ++i) {
813 if (i in usedSubstitutionIndexes)
814 continue;
815 unusedSubstitutions.push(substitutions[i]);
816 }
817
818 return { formattedResult: result, unusedSubstitutions: unusedSubstitutions } ;
819 }
OLDNEW
« no previous file with comments | « resources/inspector/treeoutline.js ('k') | servers/chrome_launcher.exe » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698