Guest User

chrome.pak first part

a guest
Nov 27th, 2013
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 207.42 KB | None | 0 0
  1.  ³ ].A ^. _.ä4 `.kï a.È ! b.–K" c.º·" d.ZÌ" e.–Þ" f.J# g.z# h.0# i.*?# j.KL# k.·# l.öœ# m.â°# n.™Â# o.cÎ# p.9ð# q. $ r.Ó$ s.,$ t.ñ4$ u.©F$ v.õ$ w.¼†$ x.”‡$ y.™ˆ$ z.Ÿ‰$ {.E‹$ |.ãŒ$ }.5$ ~.¦Ž$ .3—$ €.èœ$ .ž$ ‚.çž$ ƒ._Ÿ$ „.\ $ ….R¡$ †.Š¢$ ‡.8£$ ˆ.#¤$ ‰.­¤$ Š.>¥$ ‹.¦$ Œ.“¦$ .™§$ Ž.9¨$ .â¨$ .i©$ ‘. ¬$ ’.€­$ “. °$ ”.¾±$ •.”²$ –.v´$ —.Ý´$ ˜.Dµ$ ™.½µ$ š.6¶$ ›.ȶ$ œ.h·$ . ¸$ ž.î¿$ Ÿ.Ä$  .ÖÇ$ ¡.óË$ ¢.Í$ £.Î$ ¤.ûÐ$ ¥.PÑ$ ¦.¥Ñ$ §.úÞ$ ¨.¼í$ ©.î$ ª.êò$ «.L÷$ ¬.nù$ ­.%% ®.ó% ¯.
  2. % °.:% ±.³% ².Ø´% ³.¸µ% ´.Ù¹% µ.¬½% ¶.J¾% ·.¥Á% ¸.Ã% ¹.¡Ã% º. Ê% ».œÏ% ¼.x& ½.9y& ¾.iz& ¿.q{& À.J|& Á.s}& Â. ~& Ã.@& Ä.Ñ& Å.& Æ.‘& Ç.¾…& È.RŒ& É.Ú˜& Ê.b¥& Ë.ê±& Ì.r¾& Í./¿& Î.¿& Ï.zÏ& Ð./ß& Ñ.Äø& Ò.œù& Ó.äú& Ô. ü& Õ.eü& Ö.Áü& ×.­þ& Ø.D' Ù.{' Ú.' Û.¯' Ü.ä
  3. ' Ý.
  4. ' Þ.S' ß._%' à.ª1' á.¹=' â.J' ã.AV' ä.rb' å.Fo' æ.<x' ç.Ù…' è.S“' é.ë ' ê.ƒ®' ë.¼' ì.µÉ' í.E×' î.ä' ï.‹ñ' ð.¡þ' ñ.º ( ò.á( ó.ï%( ô.ö2( õ.Õ«( ö.÷) ÷. ) ø. ) ù.H
  5. ) ú.î
  6. ) û.‚) ü.) ý.«) þ._) ÿ.) /¾) /`) /=) /N) /ž) /‚) /ª) /^0) /{@) /‹P)
  7. /r`) /ˆp) /)
  8. /¢‘) /{¢) /U´) Å) <!--
  9. Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
  10.  
  11. Redistribution and use in source and binary forms, with or without
  12. modification, are permitted provided that the following conditions
  13. are met:
  14.  
  15. 1. Redistributions of source code must retain the above copyright
  16. notice, this list of conditions and the following disclaimer.
  17. 2. Redistributions in binary form must reproduce the above copyright
  18. notice, this list of conditions and the following disclaimer in the
  19. documentation and/or other materials provided with the distribution.
  20. 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  21. its contributors may be used to endorse or promote products derived
  22. from this software without specific prior written permission.
  23.  
  24. THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  25. EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27. DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  28. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  29. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  31. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  33. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. -->
  35. <!DOCTYPE html>
  36. <html>
  37. <head>
  38. <meta http-equiv="content-type" content="text/html; charset=utf-8">
  39. <link rel="stylesheet" type="text/css" href="devTools.css">
  40. <script type="text/javascript" src="DevTools.js"></script>
  41. </head>
  42. <body class="detached" id="-webkit-web-inspector">
  43. <div id="toolbar">
  44. <div class="toolbar-item close-left"><button id="close-button-left"></button></div>
  45. <div id="toolbar-controls">
  46. <div class="toolbar-item"><button id="toolbar-dropdown-arrow" class="toolbar-label">&raquo;</button></div>
  47. <div class="toolbar-item hidden" id="search-results-matches"></div>
  48. <div class="toolbar-item toolbar-search-item"><input id="search" type="search" incremental results="0"><div id="search-toolbar-label" class="toolbar-label"></div></div>
  49. <div class="toolbar-item close-right"><button id="close-button-right"></button></div>
  50. </div>
  51. </div>
  52. <div id="main">
  53. <div id="main-status-bar" class="status-bar"><div id="anchored-status-bar-items"><div id="counters"><div id="error-warning-count" class="hidden"></div></div></div></div>
  54. </div>
  55. <div id="drawer"></div>
  56. </body>
  57. </html>
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64. Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
  65. {
  66. var startNode;
  67. var startOffset = 0;
  68. var endNode;
  69. var endOffset = 0;
  70.  
  71. if (!stayWithinNode)
  72. stayWithinNode = this;
  73.  
  74. if (!direction || direction === "backward" || direction === "both") {
  75. var node = this;
  76. while (node) {
  77. if (node === stayWithinNode) {
  78. if (!startNode)
  79. startNode = stayWithinNode;
  80. break;
  81. }
  82.  
  83. if (node.nodeType === Node.TEXT_NODE) {
  84. var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
  85. for (var i = start; i >= 0; --i) {
  86. if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
  87. startNode = node;
  88. startOffset = i + 1;
  89. break;
  90. }
  91. }
  92. }
  93.  
  94. if (startNode)
  95. break;
  96.  
  97. node = node.traversePreviousNode(stayWithinNode);
  98. }
  99.  
  100. if (!startNode) {
  101. startNode = stayWithinNode;
  102. startOffset = 0;
  103. }
  104. } else {
  105. startNode = this;
  106. startOffset = offset;
  107. }
  108.  
  109. if (!direction || direction === "forward" || direction === "both") {
  110. node = this;
  111. while (node) {
  112. if (node === stayWithinNode) {
  113. if (!endNode)
  114. endNode = stayWithinNode;
  115. break;
  116. }
  117.  
  118. if (node.nodeType === Node.TEXT_NODE) {
  119. var start = (node === this ? offset : 0);
  120. for (var i = start; i < node.nodeValue.length; ++i) {
  121. if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
  122. endNode = node;
  123. endOffset = i;
  124. break;
  125. }
  126. }
  127. }
  128.  
  129. if (endNode)
  130. break;
  131.  
  132. node = node.traverseNextNode(stayWithinNode);
  133. }
  134.  
  135. if (!endNode) {
  136. endNode = stayWithinNode;
  137. endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length;
  138. }
  139. } else {
  140. endNode = this;
  141. endOffset = offset;
  142. }
  143.  
  144. var result = this.ownerDocument.createRange();
  145. result.setStart(startNode, startOffset);
  146. result.setEnd(endNode, endOffset);
  147.  
  148. return result;
  149. }
  150.  
  151. Node.prototype.traverseNextTextNode = function(stayWithin)
  152. {
  153. var node = this.traverseNextNode(stayWithin);
  154. if (!node)
  155. return;
  156.  
  157. while (node && node.nodeType !== Node.TEXT_NODE)
  158. node = node.traverseNextNode(stayWithin);
  159.  
  160. return node;
  161. }
  162.  
  163. Node.prototype.rangeBoundaryForOffset = function(offset)
  164. {
  165. var node = this.traverseNextTextNode(this);
  166. while (node && offset > node.nodeValue.length) {
  167. offset -= node.nodeValue.length;
  168. node = node.traverseNextTextNode(this);
  169. }
  170. if (!node)
  171. return { container: this, offset: 0 };
  172. return { container: node, offset: offset };
  173. }
  174.  
  175. Element.prototype.removeStyleClass = function(className)
  176. {
  177. this.classList.remove(className);
  178. }
  179.  
  180. Element.prototype.removeMatchingStyleClasses = function(classNameRegex)
  181. {
  182. var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)");
  183. if (regex.test(this.className))
  184. this.className = this.className.replace(regex, " ");
  185. }
  186.  
  187. Element.prototype.addStyleClass = function(className)
  188. {
  189. this.classList.add(className);
  190. }
  191.  
  192. Element.prototype.hasStyleClass = function(className)
  193. {
  194. return this.classList.contains(className);
  195. }
  196.  
  197. Element.prototype.positionAt = function(x, y)
  198. {
  199. this.style.left = x + "px";
  200. this.style.top = y + "px";
  201. }
  202.  
  203. Element.prototype.pruneEmptyTextNodes = function()
  204. {
  205. var sibling = this.firstChild;
  206. while (sibling) {
  207. var nextSibling = sibling.nextSibling;
  208. if (sibling.nodeType === this.TEXT_NODE && sibling.nodeValue === "")
  209. this.removeChild(sibling);
  210. sibling = nextSibling;
  211. }
  212. }
  213.  
  214. Element.prototype.isScrolledToBottom = function()
  215. {
  216.  
  217. return this.scrollTop + this.clientHeight === this.scrollHeight;
  218. }
  219.  
  220. Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
  221. {
  222. for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
  223. for (var i = 0; i < nameArray.length; ++i)
  224. if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
  225. return node;
  226. return null;
  227. }
  228.  
  229. Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
  230. {
  231. return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
  232. }
  233.  
  234. Node.prototype.enclosingNodeOrSelfWithClass = function(className)
  235. {
  236. for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
  237. if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className))
  238. return node;
  239. return null;
  240. }
  241.  
  242. Node.prototype.enclosingNodeWithClass = function(className)
  243. {
  244. if (!this.parentNode)
  245. return null;
  246. return this.parentNode.enclosingNodeOrSelfWithClass(className);
  247. }
  248.  
  249. Element.prototype.query = function(query)
  250. {
  251. return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  252. }
  253.  
  254. Element.prototype.removeChildren = function()
  255. {
  256. if (this.firstChild)
  257. this.textContent = "";
  258. }
  259.  
  260. Element.prototype.isInsertionCaretInside = function()
  261. {
  262. var selection = window.getSelection();
  263. if (!selection.rangeCount || !selection.isCollapsed)
  264. return false;
  265. var selectionRange = selection.getRangeAt(0);
  266. return selectionRange.startContainer.isSelfOrDescendant(this);
  267. }
  268.  
  269.  
  270. Element.prototype.createChild = function(elementName, className)
  271. {
  272. var element = this.ownerDocument.createElement(elementName);
  273. if (className)
  274. element.className = className;
  275. this.appendChild(element);
  276. return element;
  277. }
  278.  
  279. DocumentFragment.prototype.createChild = Element.prototype.createChild;
  280.  
  281.  
  282. Element.prototype.totalOffsetLeft = function()
  283. {
  284. return this.totalOffset().left;
  285. }
  286.  
  287.  
  288. Element.prototype.totalOffsetTop = function()
  289. {
  290. return this.totalOffset().top;
  291.  
  292. }
  293.  
  294. Element.prototype.totalOffset = function()
  295. {
  296. var totalLeft = 0;
  297. var totalTop = 0;
  298.  
  299. for (var element = this; element; element = element.offsetParent) {
  300. totalLeft += element.offsetLeft;
  301. totalTop += element.offsetTop;
  302. if (this !== element) {
  303. totalLeft += element.clientLeft - element.scrollLeft;
  304. totalTop += element.clientTop - element.scrollTop;
  305. }
  306. }
  307.  
  308. return { left: totalLeft, top: totalTop };
  309. }
  310.  
  311. Element.prototype.scrollOffset = function()
  312. {
  313. var curLeft = 0;
  314. var curTop = 0;
  315. for (var element = this; element; element = element.scrollParent) {
  316. curLeft += element.scrollLeft;
  317. curTop += element.scrollTop;
  318. }
  319. return { left: curLeft, top: curTop };
  320. }
  321.  
  322.  
  323. function AnchorBox(x, y, width, height)
  324. {
  325. this.x = x || 0;
  326. this.y = y || 0;
  327. this.width = width || 0;
  328. this.height = height || 0;
  329. }
  330.  
  331.  
  332. Element.prototype.offsetRelativeToWindow = function(targetWindow)
  333. {
  334. var elementOffset = new AnchorBox();
  335. var curElement = this;
  336. var curWindow = this.ownerDocument.defaultView;
  337. while (curWindow && curElement) {
  338. elementOffset.x += curElement.totalOffsetLeft();
  339. elementOffset.y += curElement.totalOffsetTop();
  340. if (curWindow === targetWindow)
  341. break;
  342.  
  343. curElement = curWindow.frameElement;
  344. curWindow = curWindow.parent;
  345. }
  346.  
  347. return elementOffset;
  348. }
  349.  
  350.  
  351. Element.prototype.boxInWindow = function(targetWindow)
  352. {
  353. targetWindow = targetWindow || this.ownerDocument.defaultView;
  354.  
  355. var anchorBox = this.offsetRelativeToWindow(window);
  356. anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x);
  357. anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBox.y);
  358.  
  359. return anchorBox;
  360. }
  361.  
  362.  
  363. Element.prototype.setTextAndTitle = function(text)
  364. {
  365. this.textContent = text;
  366. this.title = text;
  367. }
  368.  
  369. KeyboardEvent.prototype.__defineGetter__("data", function()
  370. {
  371.  
  372.  
  373. switch (this.type) {
  374. case "keypress":
  375. if (!this.ctrlKey && !this.metaKey)
  376. return String.fromCharCode(this.charCode);
  377. else
  378. return "";
  379. case "keydown":
  380. case "keyup":
  381. if (!this.ctrlKey && !this.metaKey && !this.altKey)
  382. return String.fromCharCode(this.which);
  383. else
  384. return "";
  385. }
  386. });
  387.  
  388.  
  389. Event.prototype.consume = function(preventDefault)
  390. {
  391. this.stopImmediatePropagation();
  392. if (preventDefault)
  393. this.preventDefault();
  394. this.handled = true;
  395. }
  396.  
  397. Text.prototype.select = function(start, end)
  398. {
  399. start = start || 0;
  400. end = end || this.textContent.length;
  401.  
  402. if (start < 0)
  403. start = end + start;
  404.  
  405. var selection = this.ownerDocument.defaultView.getSelection();
  406. selection.removeAllRanges();
  407. var range = this.ownerDocument.createRange();
  408. range.setStart(this, start);
  409. range.setEnd(this, end);
  410. selection.addRange(range);
  411. return this;
  412. }
  413.  
  414. Element.prototype.selectionLeftOffset = function()
  415. {
  416.  
  417.  
  418. var selection = window.getSelection();
  419. if (!selection.containsNode(this, true))
  420. return null;
  421.  
  422. var leftOffset = selection.anchorOffset;
  423. var node = selection.anchorNode;
  424.  
  425. while (node !== this) {
  426. while (node.previousSibling) {
  427. node = node.previousSibling;
  428. leftOffset += node.textContent.length;
  429. }
  430. node = node.parentNode;
  431. }
  432.  
  433. return leftOffset;
  434. }
  435.  
  436. String.prototype.hasSubstring = function(string, caseInsensitive)
  437. {
  438. if (!caseInsensitive)
  439. return this.indexOf(string) !== -1;
  440. return this.match(new RegExp(string.escapeForRegExp(), "i"));
  441. }
  442.  
  443. String.prototype.findAll = function(string)
  444. {
  445. var matches = [];
  446. var i = this.indexOf(string);
  447. while (i !== -1) {
  448. matches.push(i);
  449. i = this.indexOf(string, i + string.length);
  450. }
  451. return matches;
  452. }
  453.  
  454. String.prototype.lineEndings = function()
  455. {
  456. if (!this._lineEndings) {
  457. this._lineEndings = this.findAll("\n");
  458. this._lineEndings.push(this.length);
  459. }
  460. return this._lineEndings;
  461. }
  462.  
  463. String.prototype.asParsedURL = function()
  464. {
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471. var match = this.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
  472. if (!match) {
  473. if (this == "about:blank") {
  474. return { scheme: "about",
  475. host: "blank",
  476. path: "/",
  477. lastPathComponent: ""};
  478. }
  479. return null;
  480. }
  481. var result = {};
  482. result.scheme = match[1].toLowerCase();
  483. result.host = match[2];
  484. result.port = match[3];
  485. result.path = match[4] || "/";
  486. result.fragment = match[5];
  487.  
  488. result.lastPathComponent = "";
  489. if (result.path) {
  490.  
  491. var path = result.path;
  492. var indexOfQuery = path.indexOf("?");
  493. if (indexOfQuery !== -1)
  494. path = path.substring(0, indexOfQuery);
  495.  
  496.  
  497. var lastSlashIndex = path.lastIndexOf("/");
  498. if (lastSlashIndex !== -1) {
  499. result.firstPathComponents = path.substring(0, lastSlashIndex + 1);
  500. result.lastPathComponent = path.substring(lastSlashIndex + 1);
  501. }
  502. }
  503. return result;
  504. }
  505.  
  506. String.prototype.escapeCharacters = function(chars)
  507. {
  508. var foundChar = false;
  509. for (var i = 0; i < chars.length; ++i) {
  510. if (this.indexOf(chars.charAt(i)) !== -1) {
  511. foundChar = true;
  512. break;
  513. }
  514. }
  515.  
  516. if (!foundChar)
  517. return this;
  518.  
  519. var result = "";
  520. for (var i = 0; i < this.length; ++i) {
  521. if (chars.indexOf(this.charAt(i)) !== -1)
  522. result += "\\";
  523. result += this.charAt(i);
  524. }
  525.  
  526. return result;
  527. }
  528.  
  529. String.prototype.escapeForRegExp = function()
  530. {
  531. return this.escapeCharacters("^[]{}()\\.$*+?|");
  532. }
  533.  
  534. String.prototype.escapeHTML = function()
  535. {
  536. return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
  537. }
  538.  
  539. String.prototype.collapseWhitespace = function()
  540. {
  541. return this.replace(/[\s\xA0]+/g, " ");
  542. }
  543.  
  544. String.prototype.trimMiddle = function(maxLength)
  545. {
  546. if (this.length <= maxLength)
  547. return this;
  548. var leftHalf = maxLength >> 1;
  549. var rightHalf = maxLength - leftHalf - 1;
  550. return this.substr(0, leftHalf) + "\u2026" + this.substr(this.length - rightHalf, rightHalf);
  551. }
  552.  
  553. String.prototype.trimEnd = function(maxLength)
  554. {
  555. if (this.length <= maxLength)
  556. return this;
  557. return this.substr(0, maxLength - 1) + "\u2026";
  558. }
  559.  
  560. String.prototype.trimURL = function(baseURLDomain)
  561. {
  562. var result = this.replace(/^(https|http|file):\/\//i, "");
  563. if (baseURLDomain)
  564. result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp(), "i"), "");
  565. return result;
  566. }
  567.  
  568. String.prototype.removeURLFragment = function()
  569. {
  570. var fragmentIndex = this.indexOf("#");
  571. if (fragmentIndex == -1)
  572. fragmentIndex = this.length;
  573. return this.substring(0, fragmentIndex);
  574. }
  575.  
  576. Node.prototype.isAncestor = function(node)
  577. {
  578. if (!node)
  579. return false;
  580.  
  581. var currentNode = node.parentNode;
  582. while (currentNode) {
  583. if (this === currentNode)
  584. return true;
  585. currentNode = currentNode.parentNode;
  586. }
  587. return false;
  588. }
  589.  
  590. Node.prototype.isDescendant = function(descendant)
  591. {
  592. return !!descendant && descendant.isAncestor(this);
  593. }
  594.  
  595. Node.prototype.isSelfOrAncestor = function(node)
  596. {
  597. return !!node && (node === this || this.isAncestor(node));
  598. }
  599.  
  600. Node.prototype.isSelfOrDescendant = function(node)
  601. {
  602. return !!node && (node === this || this.isDescendant(node));
  603. }
  604.  
  605. Node.prototype.traverseNextNode = function(stayWithin)
  606. {
  607. var node = this.firstChild;
  608. if (node)
  609. return node;
  610.  
  611. if (stayWithin && this === stayWithin)
  612. return null;
  613.  
  614. node = this.nextSibling;
  615. if (node)
  616. return node;
  617.  
  618. node = this;
  619. while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin))
  620. node = node.parentNode;
  621. if (!node)
  622. return null;
  623.  
  624. return node.nextSibling;
  625. }
  626.  
  627. Node.prototype.traversePreviousNode = function(stayWithin)
  628. {
  629. if (stayWithin && this === stayWithin)
  630. return null;
  631. var node = this.previousSibling;
  632. while (node && node.lastChild)
  633. node = node.lastChild;
  634. if (node)
  635. return node;
  636. return this.parentNode;
  637. }
  638.  
  639. Number.constrain = function(num, min, max)
  640. {
  641. if (num < min)
  642. num = min;
  643. else if (num > max)
  644. num = max;
  645. return num;
  646. }
  647.  
  648. Date.prototype.toISO8601Compact = function()
  649. {
  650. function leadZero(x)
  651. {
  652. return x > 9 ? '' + x : '0' + x
  653. }
  654. return this.getFullYear() +
  655. leadZero(this.getMonth() + 1) +
  656. leadZero(this.getDate()) + 'T' +
  657. leadZero(this.getHours()) +
  658. leadZero(this.getMinutes()) +
  659. leadZero(this.getSeconds());
  660. }
  661.  
  662. HTMLTextAreaElement.prototype.moveCursorToEnd = function()
  663. {
  664. var length = this.value.length;
  665. this.setSelectionRange(length, length);
  666. }
  667.  
  668. Object.defineProperty(Array.prototype, "remove",
  669. {
  670.  
  671. value: function(value, onlyFirst)
  672. {
  673. if (onlyFirst) {
  674. var index = this.indexOf(value);
  675. if (index !== -1)
  676. this.splice(index, 1);
  677. return;
  678. }
  679.  
  680. var length = this.length;
  681. for (var i = 0; i < length; ++i) {
  682. if (this[i] === value)
  683. this.splice(i, 1);
  684. }
  685. }
  686. });
  687.  
  688. Object.defineProperty(Array.prototype, "keySet",
  689. {
  690.  
  691. value: function()
  692. {
  693. var keys = {};
  694. for (var i = 0; i < this.length; ++i)
  695. keys[this[i]] = true;
  696. return keys;
  697. }
  698. });
  699.  
  700. Object.defineProperty(Array.prototype, "upperBound",
  701. {
  702.  
  703. value: function(value)
  704. {
  705. var first = 0;
  706. var count = this.length;
  707. while (count > 0) {
  708. var step = count >> 1;
  709. var middle = first + step;
  710. if (value >= this[middle]) {
  711. first = middle + 1;
  712. count -= step + 1;
  713. } else
  714. count = step;
  715. }
  716. return first;
  717. }
  718. });
  719.  
  720. Array.diff = function(left, right)
  721. {
  722. var o = left;
  723. var n = right;
  724.  
  725. var ns = {};
  726. var os = {};
  727.  
  728. for (var i = 0; i < n.length; i++) {
  729. if (ns[n[i]] == null)
  730. ns[n[i]] = { rows: [], o: null };
  731. ns[n[i]].rows.push(i);
  732. }
  733.  
  734. for (var i = 0; i < o.length; i++) {
  735. if (os[o[i]] == null)
  736. os[o[i]] = { rows: [], n: null };
  737. os[o[i]].rows.push(i);
  738. }
  739.  
  740. for (var i in ns) {
  741. if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
  742. n[ns[i].rows[0]] = { text: n[ns[i].rows[0]], row: os[i].rows[0] };
  743. o[os[i].rows[0]] = { text: o[os[i].rows[0]], row: ns[i].rows[0] };
  744. }
  745. }
  746.  
  747. for (var i = 0; i < n.length - 1; i++) {
  748. if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && n[i + 1] == o[n[i].row + 1]) {
  749. n[i + 1] = { text: n[i + 1], row: n[i].row + 1 };
  750. o[n[i].row + 1] = { text: o[n[i].row + 1], row: i + 1 };
  751. }
  752. }
  753.  
  754. for (var i = n.length - 1; i > 0; i--) {
  755. if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&
  756. n[i - 1] == o[n[i].row - 1]) {
  757. n[i - 1] = { text: n[i - 1], row: n[i].row - 1 };
  758. o[n[i].row - 1] = { text: o[n[i].row - 1], row: i - 1 };
  759. }
  760. }
  761.  
  762. return { left: o, right: n };
  763. }
  764.  
  765. Array.convert = function(list)
  766. {
  767.  
  768. return Array.prototype.slice.call(list);
  769. }
  770.  
  771.  
  772. String.sprintf = function(format, var_arg)
  773. {
  774. return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
  775. }
  776.  
  777. String.tokenizeFormatString = function(format, formatters)
  778. {
  779. var tokens = [];
  780. var substitutionIndex = 0;
  781.  
  782. function addStringToken(str)
  783. {
  784. tokens.push({ type: "string", value: str });
  785. }
  786.  
  787. function addSpecifierToken(specifier, precision, substitutionIndex)
  788. {
  789. tokens.push({ type: "specifier", specifier: specifier, precision: precision, substitutionIndex: substitutionIndex });
  790. }
  791.  
  792. function isDigit(c)
  793. {
  794. return !!/[0-9]/.exec(c);
  795. }
  796.  
  797. var index = 0;
  798. for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) {
  799. addStringToken(format.substring(index, precentIndex));
  800. index = precentIndex + 1;
  801.  
  802. if (isDigit(format[index])) {
  803.  
  804. var number = parseInt(format.substring(index), 10);
  805. while (isDigit(format[index]))
  806. ++index;
  807.  
  808.  
  809.  
  810. if (number > 0 && format[index] === "$") {
  811. substitutionIndex = (number - 1);
  812. ++index;
  813. }
  814. }
  815.  
  816. var precision = -1;
  817. if (format[index] === ".") {
  818.  
  819.  
  820. ++index;
  821. precision = parseInt(format.substring(index), 10);
  822. if (isNaN(precision))
  823. precision = 0;
  824.  
  825. while (isDigit(format[index]))
  826. ++index;
  827. }
  828.  
  829. if (!(format[index] in formatters)) {
  830. addStringToken(format.substring(precentIndex, index + 1));
  831. ++index;
  832. continue;
  833. }
  834.  
  835. addSpecifierToken(format[index], precision, substitutionIndex);
  836.  
  837. ++substitutionIndex;
  838. ++index;
  839. }
  840.  
  841. addStringToken(format.substring(index));
  842.  
  843. return tokens;
  844. }
  845.  
  846. String.standardFormatters = {
  847. d: function(substitution)
  848. {
  849. return !isNaN(substitution) ? substitution : 0;
  850. },
  851.  
  852. f: function(substitution, token)
  853. {
  854. if (substitution && token.precision > -1)
  855. substitution = substitution.toFixed(token.precision);
  856. return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
  857. },
  858.  
  859. s: function(substitution)
  860. {
  861. return substitution;
  862. }
  863. }
  864.  
  865. String.vsprintf = function(format, substitutions)
  866. {
  867. return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult;
  868. }
  869.  
  870. String.format = function(format, substitutions, formatters, initialValue, append)
  871. {
  872. if (!format || !substitutions || !substitutions.length)
  873. return { formattedResult: append(initialValue, format), unusedSubstitutions: substitutions };
  874.  
  875. function prettyFunctionName()
  876. {
  877. return "String.format(\"" + format + "\", \"" + substitutions.join("\", \"") + "\")";
  878. }
  879.  
  880. function warn(msg)
  881. {
  882. console.warn(prettyFunctionName() + ": " + msg);
  883. }
  884.  
  885. function error(msg)
  886. {
  887. console.error(prettyFunctionName() + ": " + msg);
  888. }
  889.  
  890. var result = initialValue;
  891. var tokens = String.tokenizeFormatString(format, formatters);
  892. var usedSubstitutionIndexes = {};
  893.  
  894. for (var i = 0; i < tokens.length; ++i) {
  895. var token = tokens[i];
  896.  
  897. if (token.type === "string") {
  898. result = append(result, token.value);
  899. continue;
  900. }
  901.  
  902. if (token.type !== "specifier") {
  903. error("Unknown token type \"" + token.type + "\" found.");
  904. continue;
  905. }
  906.  
  907. if (token.substitutionIndex >= substitutions.length) {
  908.  
  909.  
  910. error("not enough substitution arguments. Had " + substitutions.length + " but needed " + (token.substitutionIndex + 1) + ", so substitution was skipped.");
  911. result = append(result, "%" + (token.precision > -1 ? token.precision : "") + token.specifier);
  912. continue;
  913. }
  914.  
  915. usedSubstitutionIndexes[token.substitutionIndex] = true;
  916.  
  917. if (!(token.specifier in formatters)) {
  918.  
  919. warn("unsupported format character \u201C" + token.specifier + "\u201D. Treating as a string.");
  920. result = append(result, substitutions[token.substitutionIndex]);
  921. continue;
  922. }
  923.  
  924. result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token));
  925. }
  926.  
  927. var unusedSubstitutions = [];
  928. for (var i = 0; i < substitutions.length; ++i) {
  929. if (i in usedSubstitutionIndexes)
  930. continue;
  931. unusedSubstitutions.push(substitutions[i]);
  932. }
  933.  
  934. return { formattedResult: result, unusedSubstitutions: unusedSubstitutions };
  935. }
  936.  
  937. function isEnterKey(event) {
  938.  
  939. return event.keyCode !== 229 && event.keyIdentifier === "Enter";
  940. }
  941.  
  942. function consumeEvent(e)
  943. {
  944. e.consume();
  945. }
  946.  
  947.  
  948. function highlightSearchResult(element, offset, length, domChanges)
  949. {
  950. var result = highlightSearchResults(element, [{offset: offset, length: length }], domChanges);
  951. return result.length ? result[0] : null;
  952. }
  953.  
  954.  
  955. function highlightSearchResults(element, resultRanges, changes)
  956. {
  957. return highlightRangesWithStyleClass(element, resultRanges, "webkit-search-result", changes);
  958.  
  959. }
  960.  
  961.  
  962. function highlightRangesWithStyleClass(element, resultRanges, styleClass, changes)
  963. {
  964. changes = changes || [];
  965. var highlightNodes = [];
  966. var lineText = element.textContent;
  967. var ownerDocument = element.ownerDocument;
  968. var textNodeSnapshot = ownerDocument.evaluate(".//text()", element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  969.  
  970. var snapshotLength = textNodeSnapshot.snapshotLength;
  971. if (snapshotLength === 0)
  972. return highlightNodes;
  973.  
  974. var nodeRanges = [];
  975. var rangeEndOffset = 0;
  976. for (var i = 0; i < snapshotLength; ++i) {
  977. var range = {};
  978. range.offset = rangeEndOffset;
  979. range.length = textNodeSnapshot.snapshotItem(i).textContent.length;
  980. rangeEndOffset = range.offset + range.length;
  981. nodeRanges.push(range);
  982. }
  983.  
  984. var startIndex = 0;
  985. for (var i = 0; i < resultRanges.length; ++i) {
  986. var startOffset = resultRanges[i].offset;
  987. var endOffset = startOffset + resultRanges[i].length;
  988.  
  989. while (startIndex < snapshotLength && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
  990. startIndex++;
  991. var endIndex = startIndex;
  992. while (endIndex < snapshotLength && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
  993. endIndex++;
  994. if (endIndex === snapshotLength)
  995. break;
  996.  
  997. var highlightNode = ownerDocument.createElement("span");
  998. highlightNode.className = styleClass;
  999. highlightNode.textContent = lineText.substring(startOffset, endOffset);
  1000.  
  1001. var lastTextNode = textNodeSnapshot.snapshotItem(endIndex);
  1002. var lastText = lastTextNode.textContent;
  1003. lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
  1004. changes.push({ node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent });
  1005.  
  1006. if (startIndex === endIndex) {
  1007. lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
  1008. changes.push({ node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement });
  1009. highlightNodes.push(highlightNode);
  1010.  
  1011. var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
  1012. lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
  1013. changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement });
  1014. } else {
  1015. var firstTextNode = textNodeSnapshot.snapshotItem(startIndex);
  1016. var firstText = firstTextNode.textContent;
  1017. var anchorElement = firstTextNode.nextSibling;
  1018.  
  1019. firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
  1020. changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement });
  1021. highlightNodes.push(highlightNode);
  1022.  
  1023. firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
  1024. changes.push({ node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent });
  1025.  
  1026. for (var j = startIndex + 1; j < endIndex; j++) {
  1027. var textNode = textNodeSnapshot.snapshotItem(j);
  1028. var text = textNode.textContent;
  1029. textNode.textContent = "";
  1030. changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
  1031. }
  1032. }
  1033. startIndex = endIndex;
  1034. nodeRanges[startIndex].offset = endOffset;
  1035. nodeRanges[startIndex].length = lastTextNode.textContent.length;
  1036.  
  1037. }
  1038. return highlightNodes;
  1039. }
  1040.  
  1041. function applyDomChanges(domChanges)
  1042. {
  1043. for (var i = 0, size = domChanges.length; i < size; ++i) {
  1044. var entry = domChanges[i];
  1045. switch (entry.type) {
  1046. case "added":
  1047. entry.parent.insertBefore(entry.node, entry.nextSibling);
  1048. break;
  1049. case "changed":
  1050. entry.node.textContent = entry.newText;
  1051. break;
  1052. }
  1053. }
  1054. }
  1055.  
  1056. function revertDomChanges(domChanges)
  1057. {
  1058. for (var i = domChanges.length - 1; i >= 0; --i) {
  1059. var entry = domChanges[i];
  1060. switch (entry.type) {
  1061. case "added":
  1062. if (entry.node.parentElement)
  1063. entry.node.parentElement.removeChild(entry.node);
  1064. break;
  1065. case "changed":
  1066. entry.node.textContent = entry.oldText;
  1067. break;
  1068. }
  1069. }
  1070. }
  1071.  
  1072.  
  1073. function createSearchRegex(query, caseSensitive, isRegex)
  1074. {
  1075. var regexFlags = caseSensitive ? "g" : "gi";
  1076. var regexObject;
  1077.  
  1078. if (isRegex) {
  1079. try {
  1080. regexObject = new RegExp(query, regexFlags);
  1081. } catch (e) {
  1082.  
  1083. }
  1084. }
  1085.  
  1086. if (!regexObject)
  1087. regexObject = createPlainTextSearchRegex(query, regexFlags);
  1088.  
  1089. return regexObject;
  1090. }
  1091.  
  1092.  
  1093. function createPlainTextSearchRegex(query, flags)
  1094. {
  1095.  
  1096. var regexSpecialCharacters = "[](){}+-*.,?\\^$|";
  1097. var regex = "";
  1098. for (var i = 0; i < query.length; ++i) {
  1099. var c = query.charAt(i);
  1100. if (regexSpecialCharacters.indexOf(c) != -1)
  1101. regex += "\\";
  1102. regex += c;
  1103. }
  1104. return new RegExp(regex, flags || "");
  1105. }
  1106.  
  1107.  
  1108. function countRegexMatches(regex, content)
  1109. {
  1110. var text = content;
  1111. var result = 0;
  1112. var match;
  1113. while (text && (match = regex.exec(text))) {
  1114. if (match[0].length > 0)
  1115. ++result;
  1116. text = text.substring(match.index + 1);
  1117. }
  1118. return result;
  1119. }
  1120.  
  1121.  
  1122. function numberToStringWithSpacesPadding(value, symbolsCount)
  1123. {
  1124. var numberString = value.toString();
  1125. var paddingLength = Math.max(0, symbolsCount - numberString.length);
  1126. var paddingString = Array(paddingLength + 1).join("\u00a0");
  1127. return paddingString + numberString;
  1128. }
  1129.  
  1130.  
  1131. function TextDiff()
  1132. {
  1133. this.added = [];
  1134. this.removed = [];
  1135. this.changed = [];
  1136. }
  1137.  
  1138.  
  1139. TextDiff.compute = function(baseContent, newContent)
  1140. {
  1141. var oldLines = baseContent.split(/\r?\n/);
  1142. var newLines = newContent.split(/\r?\n/);
  1143.  
  1144. var diff = Array.diff(oldLines, newLines);
  1145.  
  1146. var diffData = new TextDiff();
  1147.  
  1148. var offset = 0;
  1149. var right = diff.right;
  1150. for (var i = 0; i < right.length; ++i) {
  1151. if (typeof right[i] === "string") {
  1152. if (right.length > i + 1 && right[i + 1].row === i + 1 - offset)
  1153. diffData.changed.push(i);
  1154. else {
  1155. diffData.added.push(i);
  1156. offset++;
  1157. }
  1158. } else
  1159. offset = i - right[i].row;
  1160. }
  1161. return diffData;
  1162. }
  1163.  
  1164.  
  1165. var Map = function()
  1166. {
  1167. this._map = {};
  1168. }
  1169.  
  1170. Map._lastObjectIdentifier = 0;
  1171.  
  1172. Map.prototype = {
  1173.  
  1174. put: function(key, value)
  1175. {
  1176. var objectIdentifier = key.__identifier;
  1177. if (!objectIdentifier) {
  1178. objectIdentifier = ++Map._lastObjectIdentifier;
  1179. key.__identifier = objectIdentifier;
  1180. }
  1181. this._map[objectIdentifier] = value;
  1182. },
  1183.  
  1184.  
  1185. remove: function(key)
  1186. {
  1187. delete this._map[key.__identifier];
  1188. },
  1189.  
  1190. values: function()
  1191. {
  1192. var result = [];
  1193. for (var objectIdentifier in this._map)
  1194. result.push(this._map[objectIdentifier]);
  1195. return result;
  1196. },
  1197.  
  1198.  
  1199. get: function(key)
  1200. {
  1201. return this._map[key.__identifier];
  1202. },
  1203.  
  1204. clear: function()
  1205. {
  1206. this._map = {};
  1207. }
  1208. }
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215. function binarySearch(object, array, comparator)
  1216. {
  1217. var first = 0;
  1218. var last = array.length - 1;
  1219.  
  1220. while (first <= last) {
  1221. var mid = (first + last) >> 1;
  1222. var c = comparator(object, array[mid]);
  1223. if (c > 0)
  1224. first = mid + 1;
  1225. else if (c < 0)
  1226. last = mid - 1;
  1227. else
  1228. return mid;
  1229. }
  1230.  
  1231.  
  1232. return -(first + 1);
  1233. }
  1234.  
  1235. Object.defineProperty(Array.prototype, "binaryIndexOf", { value: function(value, comparator)
  1236. {
  1237. var result = binarySearch(value, this, comparator);
  1238. return result >= 0 ? result : -1;
  1239. }});
  1240.  
  1241.  
  1242. function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
  1243. {
  1244. var index = binarySearch(anObject, aList, aFunction);
  1245. if (index < 0)
  1246.  
  1247. return -index - 1;
  1248. else {
  1249.  
  1250. while (index > 0 && aFunction(anObject, aList[index - 1]) === 0)
  1251. index--;
  1252. return index;
  1253. }
  1254. }
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261. function TreeOutline(listNode, nonFocusable)
  1262. {
  1263.  
  1264. this.children = [];
  1265. this.selectedTreeElement = null;
  1266. this._childrenListNode = listNode;
  1267. this.childrenListElement = this._childrenListNode;
  1268. this._childrenListNode.removeChildren();
  1269. this.expandTreeElementsWhenArrowing = false;
  1270. this.root = true;
  1271. this.hasChildren = false;
  1272. this.expanded = true;
  1273. this.selected = false;
  1274. this.treeOutline = this;
  1275. this.comparator = null;
  1276. this.searchable = false;
  1277. this.searchInputElement = null;
  1278.  
  1279. this.setFocusable(!nonFocusable);
  1280. this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true);
  1281. this._childrenListNode.addEventListener("keypress", this._treeKeyPress.bind(this), true);
  1282.  
  1283. this._treeElementsMap = new Map();
  1284. this._expandedStateMap = new Map();
  1285. }
  1286.  
  1287. TreeOutline.prototype.setFocusable = function(focusable)
  1288. {
  1289. if (focusable)
  1290. this._childrenListNode.setAttribute("tabIndex", 0);
  1291. else
  1292. this._childrenListNode.removeAttribute("tabIndex");
  1293. }
  1294.  
  1295. TreeOutline.prototype.appendChild = function(child)
  1296. {
  1297. var insertionIndex;
  1298. if (this.treeOutline.comparator)
  1299. insertionIndex = insertionIndexForObjectInListSortedByFunction(child, this.children, this.treeOutline.comparator);
  1300. else
  1301. insertionIndex = this.children.length;
  1302. this.insertChild(child, insertionIndex);
  1303. }
  1304.  
  1305. TreeOutline.prototype.insertChild = function(child, index)
  1306. {
  1307. if (!child)
  1308. throw("child can't be undefined or null");
  1309.  
  1310. var previousChild = (index > 0 ? this.children[index - 1] : null);
  1311. if (previousChild) {
  1312. previousChild.nextSibling = child;
  1313. child.previousSibling = previousChild;
  1314. } else {
  1315. child.previousSibling = null;
  1316. }
  1317.  
  1318. var nextChild = this.children[index];
  1319. if (nextChild) {
  1320. nextChild.previousSibling = child;
  1321. child.nextSibling = nextChild;
  1322. } else {
  1323. child.nextSibling = null;
  1324. }
  1325.  
  1326. this.children.splice(index, 0, child);
  1327. this.hasChildren = true;
  1328. child.parent = this;
  1329. child.treeOutline = this.treeOutline;
  1330. child.treeOutline._rememberTreeElement(child);
  1331.  
  1332. var current = child.children[0];
  1333. while (current) {
  1334. current.treeOutline = this.treeOutline;
  1335. current.treeOutline._rememberTreeElement(current);
  1336. current = current.traverseNextTreeElement(false, child, true);
  1337. }
  1338.  
  1339. if (child.hasChildren && typeof(child.treeOutline._expandedStateMap.get(child.representedObject)) !== "undefined")
  1340. child.expanded = child.treeOutline._expandedStateMap.get(child.representedObject);
  1341.  
  1342. if (!this._childrenListNode) {
  1343. this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
  1344. this._childrenListNode.parentTreeElement = this;
  1345. this._childrenListNode.classList.add("children");
  1346. if (this.hidden)
  1347. this._childrenListNode.classList.add("hidden");
  1348. }
  1349.  
  1350. child._attach();
  1351.  
  1352. if (this.treeOutline.onadd)
  1353. this.treeOutline.onadd(child);
  1354. }
  1355.  
  1356. TreeOutline.prototype.removeChildAtIndex = function(childIndex)
  1357. {
  1358. if (childIndex < 0 || childIndex >= this.children.length)
  1359. throw("childIndex out of range");
  1360.  
  1361. var child = this.children[childIndex];
  1362. this.children.splice(childIndex, 1);
  1363.  
  1364. var parent = child.parent;
  1365. if (child.deselect()) {
  1366. if (child.previousSibling)
  1367. child.previousSibling.select();
  1368. else if (child.nextSibling)
  1369. child.nextSibling.select();
  1370. else
  1371. parent.select();
  1372. }
  1373.  
  1374. if (child.previousSibling)
  1375. child.previousSibling.nextSibling = child.nextSibling;
  1376. if (child.nextSibling)
  1377. child.nextSibling.previousSibling = child.previousSibling;
  1378.  
  1379. if (child.treeOutline) {
  1380. child.treeOutline._forgetTreeElement(child);
  1381. child.treeOutline._forgetChildrenRecursive(child);
  1382. }
  1383.  
  1384. child._detach();
  1385. child.treeOutline = null;
  1386. child.parent = null;
  1387. child.nextSibling = null;
  1388. child.previousSibling = null;
  1389. }
  1390.  
  1391. TreeOutline.prototype.removeChild = function(child)
  1392. {
  1393. if (!child)
  1394. throw("child can't be undefined or null");
  1395.  
  1396. var childIndex = this.children.indexOf(child);
  1397. if (childIndex === -1)
  1398. throw("child not found in this node's children");
  1399.  
  1400. this.removeChildAtIndex.call(this, childIndex);
  1401. }
  1402.  
  1403. TreeOutline.prototype.removeChildren = function()
  1404. {
  1405. for (var i = 0; i < this.children.length; ++i) {
  1406. var child = this.children[i];
  1407. child.deselect();
  1408.  
  1409. if (child.treeOutline) {
  1410. child.treeOutline._forgetTreeElement(child);
  1411. child.treeOutline._forgetChildrenRecursive(child);
  1412. }
  1413.  
  1414. child._detach();
  1415. child.treeOutline = null;
  1416. child.parent = null;
  1417. child.nextSibling = null;
  1418. child.previousSibling = null;
  1419. }
  1420.  
  1421. this.children = [];
  1422. }
  1423.  
  1424. TreeOutline.prototype.removeChildrenRecursive = function()
  1425. {
  1426. var childrenToRemove = this.children;
  1427.  
  1428. var child = this.children[0];
  1429. while (child) {
  1430. if (child.children.length)
  1431. childrenToRemove = childrenToRemove.concat(child.children);
  1432. child = child.traverseNextTreeElement(false, this, true);
  1433. }
  1434.  
  1435. for (var i = 0; i < childrenToRemove.length; ++i) {
  1436. child = childrenToRemove[i];
  1437. child.deselect();
  1438. if (child.treeOutline)
  1439. child.treeOutline._forgetTreeElement(child);
  1440. child._detach();
  1441. child.children = [];
  1442. child.treeOutline = null;
  1443. child.parent = null;
  1444. child.nextSibling = null;
  1445. child.previousSibling = null;
  1446. }
  1447.  
  1448. this.children = [];
  1449. }
  1450.  
  1451. TreeOutline.prototype._rememberTreeElement = function(element)
  1452. {
  1453. if (!this._treeElementsMap.get(element.representedObject))
  1454. this._treeElementsMap.put(element.representedObject, []);
  1455.  
  1456.  
  1457. var elements = this._treeElementsMap.get(element.representedObject);
  1458. if (elements.indexOf(element) !== -1)
  1459. return;
  1460.  
  1461.  
  1462. elements.push(element);
  1463. }
  1464.  
  1465. TreeOutline.prototype._forgetTreeElement = function(element)
  1466. {
  1467. if (this._treeElementsMap.get(element.representedObject))
  1468. this._treeElementsMap.get(element.representedObject).remove(element, true);
  1469. }
  1470.  
  1471. TreeOutline.prototype._forgetChildrenRecursive = function(parentElement)
  1472. {
  1473. var child = parentElement.children[0];
  1474. while (child) {
  1475. this._forgetTreeElement(child);
  1476. child = child.traverseNextTreeElement(false, parentElement, true);
  1477. }
  1478. }
  1479.  
  1480. TreeOutline.prototype.getCachedTreeElement = function(representedObject)
  1481. {
  1482. if (!representedObject)
  1483. return null;
  1484.  
  1485. var elements = this._treeElementsMap.get(representedObject);
  1486. if (elements && elements.length)
  1487. return elements[0];
  1488. return null;
  1489. }
  1490.  
  1491. TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent)
  1492. {
  1493. if (!representedObject)
  1494. return null;
  1495.  
  1496. var cachedElement = this.getCachedTreeElement(representedObject);
  1497. if (cachedElement)
  1498. return cachedElement;
  1499.  
  1500.  
  1501.  
  1502. var item;
  1503. var found = false;
  1504. for (var i = 0; i < this.children.length; ++i) {
  1505. item = this.children[i];
  1506. if (item.representedObject === representedObject || isAncestor(item.representedObject, representedObject)) {
  1507. found = true;
  1508. break;
  1509. }
  1510. }
  1511.  
  1512. if (!found)
  1513. return null;
  1514.  
  1515.  
  1516.  
  1517. var ancestors = [];
  1518. var currentObject = representedObject;
  1519. while (currentObject) {
  1520. ancestors.unshift(currentObject);
  1521. if (currentObject === item.representedObject)
  1522. break;
  1523. currentObject = getParent(currentObject);
  1524. }
  1525.  
  1526.  
  1527. for (var i = 0; i < ancestors.length; ++i) {
  1528.  
  1529.  
  1530. if (ancestors[i] === representedObject)
  1531. continue;
  1532.  
  1533.  
  1534. item = this.findTreeElement(ancestors[i], isAncestor, getParent);
  1535. if (item)
  1536. item.onpopulate();
  1537. }
  1538.  
  1539. return this.getCachedTreeElement(representedObject);
  1540. }
  1541.  
  1542. TreeOutline.prototype._treeElementDidChange = function(treeElement)
  1543. {
  1544. if (treeElement.treeOutline !== this)
  1545. return;
  1546.  
  1547. if (this.onchange)
  1548. this.onchange(treeElement);
  1549. }
  1550.  
  1551. TreeOutline.prototype.treeElementFromPoint = function(x, y)
  1552. {
  1553. var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
  1554. if (!node)
  1555. return null;
  1556.  
  1557. var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
  1558. if (listNode)
  1559. return listNode.parentTreeElement || listNode.treeElement;
  1560. return null;
  1561. }
  1562.  
  1563. TreeOutline.prototype._treeKeyPress = function(event)
  1564. {
  1565. if (!this.searchable || WebInspector.isBeingEdited(this._childrenListNode))
  1566. return;
  1567.  
  1568. var searchText = String.fromCharCode(event.charCode);
  1569.  
  1570. if (searchText.trim() !== searchText)
  1571. return;
  1572.  
  1573. this._startSearch(searchText);
  1574. event.consume(true);
  1575. }
  1576.  
  1577. TreeOutline.prototype._treeKeyDown = function(event)
  1578. {
  1579. if (event.target !== this._childrenListNode)
  1580. return;
  1581.  
  1582. if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
  1583. return;
  1584.  
  1585. var handled = false;
  1586. var nextSelectedElement;
  1587. if (event.keyIdentifier === "Up" && !event.altKey) {
  1588. nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
  1589. while (nextSelectedElement && !nextSelectedElement.selectable)
  1590. nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
  1591. handled = nextSelectedElement ? true : false;
  1592. } else if (event.keyIdentifier === "Down" && !event.altKey) {
  1593. nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
  1594. while (nextSelectedElement && !nextSelectedElement.selectable)
  1595. nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
  1596. handled = nextSelectedElement ? true : false;
  1597. } else if (event.keyIdentifier === "Left") {
  1598. if (this.selectedTreeElement.expanded) {
  1599. if (event.altKey)
  1600. this.selectedTreeElement.collapseRecursively();
  1601. else
  1602. this.selectedTreeElement.collapse();
  1603. handled = true;
  1604. } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
  1605. handled = true;
  1606. if (this.selectedTreeElement.parent.selectable) {
  1607. nextSelectedElement = this.selectedTreeElement.parent;
  1608. while (nextSelectedElement && !nextSelectedElement.selectable)
  1609. nextSelectedElement = nextSelectedElement.parent;
  1610. handled = nextSelectedElement ? true : false;
  1611. } else if (this.selectedTreeElement.parent)
  1612. this.selectedTreeElement.parent.collapse();
  1613. }
  1614. } else if (event.keyIdentifier === "Right") {
  1615. if (!this.selectedTreeElement.revealed()) {
  1616. this.selectedTreeElement.reveal();
  1617. handled = true;
  1618. } else if (this.selectedTreeElement.hasChildren) {
  1619. handled = true;
  1620. if (this.selectedTreeElement.expanded) {
  1621. nextSelectedElement = this.selectedTreeElement.children[0];
  1622. while (nextSelectedElement && !nextSelectedElement.selectable)
  1623. nextSelectedElement = nextSelectedElement.nextSibling;
  1624. handled = nextSelectedElement ? true : false;
  1625. } else {
  1626. if (event.altKey)
  1627. this.selectedTreeElement.expandRecursively();
  1628. else
  1629. this.selectedTreeElement.expand();
  1630. }
  1631. }
  1632. } else if (event.keyCode === 8 || event.keyCode === 46 ) {
  1633. if (this.selectedTreeElement.ondelete)
  1634. handled = this.selectedTreeElement.ondelete();
  1635. } else if (isEnterKey(event)) {
  1636. if (this.selectedTreeElement.onenter)
  1637. handled = this.selectedTreeElement.onenter();
  1638. } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code) {
  1639. if (this.selectedTreeElement.onspace)
  1640. handled = this.selectedTreeElement.onspace();
  1641. }
  1642.  
  1643. if (nextSelectedElement) {
  1644. nextSelectedElement.reveal();
  1645. nextSelectedElement.select(false, true);
  1646. }
  1647.  
  1648. if (handled)
  1649. event.consume(true);
  1650. }
  1651.  
  1652. TreeOutline.prototype.expand = function()
  1653. {
  1654.  
  1655. }
  1656.  
  1657. TreeOutline.prototype.collapse = function()
  1658. {
  1659.  
  1660. }
  1661.  
  1662. TreeOutline.prototype.revealed = function()
  1663. {
  1664. return true;
  1665. }
  1666.  
  1667. TreeOutline.prototype.reveal = function()
  1668. {
  1669.  
  1670. }
  1671.  
  1672. TreeOutline.prototype.select = function()
  1673. {
  1674.  
  1675. }
  1676.  
  1677.  
  1678. TreeOutline.prototype.revealAndSelect = function(omitFocus)
  1679. {
  1680.  
  1681. }
  1682.  
  1683.  
  1684. TreeOutline.prototype._startSearch = function(searchText)
  1685. {
  1686. if (!this.searchInputElement || !this.searchable)
  1687. return;
  1688.  
  1689. this._searching = true;
  1690.  
  1691. if (this.searchStarted)
  1692. this.searchStarted();
  1693.  
  1694. this.searchInputElement.value = searchText;
  1695.  
  1696. function focusSearchInput()
  1697. {
  1698. this.searchInputElement.focus();
  1699. }
  1700. window.setTimeout(focusSearchInput.bind(this), 0);
  1701. this._searchTextChanged();
  1702. this._boundSearchTextChanged = this._searchTextChanged.bind(this);
  1703. this.searchInputElement.addEventListener("paste", this._boundSearchTextChanged);
  1704. this.searchInputElement.addEventListener("cut", this._boundSearchTextChanged);
  1705. this.searchInputElement.addEventListener("keypress", this._boundSearchTextChanged);
  1706. this._boundSearchInputKeyDown = this._searchInputKeyDown.bind(this);
  1707. this.searchInputElement.addEventListener("keydown", this._boundSearchInputKeyDown);
  1708. this._boundSearchInputBlur = this._searchInputBlur.bind(this);
  1709. this.searchInputElement.addEventListener("blur", this._boundSearchInputBlur);
  1710. }
  1711.  
  1712. TreeOutline.prototype._searchTextChanged = function()
  1713. {
  1714. function updateSearch()
  1715. {
  1716. var nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, false);
  1717. if (!nextSelectedElement)
  1718. nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.children[0], false);
  1719. this._showSearchMatchElement(nextSelectedElement);
  1720. }
  1721.  
  1722. window.setTimeout(updateSearch.bind(this), 0);
  1723. }
  1724.  
  1725. TreeOutline.prototype._showSearchMatchElement = function(treeElement)
  1726. {
  1727. this._currentSearchMatchElement = treeElement;
  1728. if (treeElement) {
  1729. this._childrenListNode.classList.add("search-match-found");
  1730. this._childrenListNode.classList.remove("search-match-not-found");
  1731. treeElement.revealAndSelect(true);
  1732. } else {
  1733. this._childrenListNode.classList.remove("search-match-found");
  1734. this._childrenListNode.classList.add("search-match-not-found");
  1735. }
  1736. }
  1737.  
  1738. TreeOutline.prototype._searchInputKeyDown = function(event)
  1739. {
  1740. if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey)
  1741. return;
  1742.  
  1743. var handled = false;
  1744. var nextSelectedElement;
  1745. if (event.keyIdentifier === "Down") {
  1746. nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, true);
  1747. handled = true;
  1748. } else if (event.keyIdentifier === "Up") {
  1749. nextSelectedElement = this._previousSearchMatch(this.searchInputElement.value, this.selectedTreeElement);
  1750. handled = true;
  1751. } else if (event.keyCode === 27 ) {
  1752. this._searchFinished();
  1753. handled = true;
  1754. } else if (isEnterKey(event)) {
  1755. var lastSearchMatchElement = this._currentSearchMatchElement;
  1756. this._searchFinished();
  1757. if (lastSearchMatchElement && lastSearchMatchElement.onenter)
  1758. lastSearchMatchElement.onenter();
  1759. handled = true;
  1760. }
  1761.  
  1762. if (nextSelectedElement)
  1763. this._showSearchMatchElement(nextSelectedElement);
  1764.  
  1765. if (handled)
  1766. event.consume(true);
  1767. else
  1768. window.setTimeout(this._boundSearchTextChanged, 0);
  1769. }
  1770.  
  1771.  
  1772. TreeOutline.prototype._nextSearchMatch = function(searchText, startTreeElement, skipStartTreeElement)
  1773. {
  1774. var currentTreeElement = startTreeElement;
  1775. var skipCurrentTreeElement = skipStartTreeElement;
  1776. while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) {
  1777. currentTreeElement = currentTreeElement.traverseNextTreeElement(true, null, true);
  1778. skipCurrentTreeElement = false;
  1779. }
  1780.  
  1781. return currentTreeElement;
  1782. }
  1783.  
  1784.  
  1785. TreeOutline.prototype._previousSearchMatch = function(searchText, startTreeElement)
  1786. {
  1787. var currentTreeElement = startTreeElement;
  1788. var skipCurrentTreeElement = true;
  1789. while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) {
  1790. currentTreeElement = currentTreeElement.traversePreviousTreeElement(true, true);
  1791. skipCurrentTreeElement = false;
  1792. }
  1793.  
  1794. return currentTreeElement;
  1795. }
  1796.  
  1797. TreeOutline.prototype._searchInputBlur = function(event)
  1798. {
  1799. this._searchFinished();
  1800. }
  1801.  
  1802. TreeOutline.prototype._searchFinished = function()
  1803. {
  1804. if (!this._searching)
  1805. return;
  1806.  
  1807. delete this._searching;
  1808. this._childrenListNode.classList.remove("search-match-found");
  1809. this._childrenListNode.classList.remove("search-match-not-found");
  1810. delete this._currentSearchMatchElement;
  1811.  
  1812. this.searchInputElement.value = "";
  1813. this.searchInputElement.removeEventListener("paste", this._boundSearchTextChanged);
  1814. this.searchInputElement.removeEventListener("cut", this._boundSearchTextChanged);
  1815. delete this._boundSearchTextChanged;
  1816.  
  1817. this.searchInputElement.removeEventListener("keydown", this._boundSearchInputKeyDown);
  1818. delete this._boundSearchInputKeyDown;
  1819.  
  1820. this.searchInputElement.removeEventListener("blur", this._boundSearchInputBlur);
  1821. delete this._boundSearchInputBlur;
  1822.  
  1823. if (this.searchFinished)
  1824. this.searchFinished();
  1825.  
  1826. this.treeOutline._childrenListNode.focus();
  1827. }
  1828.  
  1829. TreeOutline.prototype.stopSearch = function()
  1830. {
  1831. this._searchFinished();
  1832. }
  1833.  
  1834.  
  1835. function TreeElement(title, representedObject, hasChildren)
  1836. {
  1837. this._title = title;
  1838. this.representedObject = (representedObject || {});
  1839.  
  1840. this._hidden = false;
  1841. this._selectable = true;
  1842. this.expanded = false;
  1843. this.selected = false;
  1844. this.hasChildren = hasChildren;
  1845. this.children = [];
  1846. this.treeOutline = null;
  1847. this.parent = null;
  1848. this.previousSibling = null;
  1849. this.nextSibling = null;
  1850. this._listItemNode = null;
  1851. }
  1852.  
  1853. TreeElement.prototype = {
  1854. arrowToggleWidth: 10,
  1855.  
  1856. get selectable() {
  1857. if (this._hidden)
  1858. return false;
  1859. return this._selectable;
  1860. },
  1861.  
  1862. set selectable(x) {
  1863. this._selectable = x;
  1864. },
  1865.  
  1866. get listItemElement() {
  1867. return this._listItemNode;
  1868. },
  1869.  
  1870. get childrenListElement() {
  1871. return this._childrenListNode;
  1872. },
  1873.  
  1874. get title() {
  1875. return this._title;
  1876. },
  1877.  
  1878. set title(x) {
  1879. this._title = x;
  1880. this._setListItemNodeContent();
  1881. this.didChange();
  1882. },
  1883.  
  1884. get tooltip() {
  1885. return this._tooltip;
  1886. },
  1887.  
  1888. set tooltip(x) {
  1889. this._tooltip = x;
  1890. if (this._listItemNode)
  1891. this._listItemNode.title = x ? x : "";
  1892. this.didChange();
  1893. },
  1894.  
  1895. get hasChildren() {
  1896. return this._hasChildren;
  1897. },
  1898.  
  1899. set hasChildren(x) {
  1900. if (this._hasChildren === x)
  1901. return;
  1902.  
  1903. this._hasChildren = x;
  1904.  
  1905. if (!this._listItemNode)
  1906. return;
  1907.  
  1908. if (x)
  1909. this._listItemNode.classList.add("parent");
  1910. else {
  1911. this._listItemNode.classList.remove("parent");
  1912. this.collapse();
  1913. }
  1914.  
  1915. this.didChange();
  1916. },
  1917.  
  1918. get hidden() {
  1919. return this._hidden;
  1920. },
  1921.  
  1922. set hidden(x) {
  1923. if (this._hidden === x)
  1924. return;
  1925.  
  1926. this._hidden = x;
  1927.  
  1928. if (x) {
  1929. if (this._listItemNode)
  1930. this._listItemNode.classList.add("hidden");
  1931. if (this._childrenListNode)
  1932. this._childrenListNode.classList.add("hidden");
  1933. } else {
  1934. if (this._listItemNode)
  1935. this._listItemNode.classList.remove("hidden");
  1936. if (this._childrenListNode)
  1937. this._childrenListNode.classList.remove("hidden");
  1938. }
  1939. },
  1940.  
  1941. get shouldRefreshChildren() {
  1942. return this._shouldRefreshChildren;
  1943. },
  1944.  
  1945. set shouldRefreshChildren(x) {
  1946. this._shouldRefreshChildren = x;
  1947. if (x && this.expanded)
  1948. this.expand();
  1949. },
  1950.  
  1951. _fireDidChange: function()
  1952. {
  1953. delete this._didChangeTimeoutIdentifier;
  1954.  
  1955. if (this.treeOutline)
  1956. this.treeOutline._treeElementDidChange(this);
  1957. },
  1958.  
  1959. didChange: function()
  1960. {
  1961. if (!this.treeOutline)
  1962. return;
  1963.  
  1964.  
  1965. if (!this._didChangeTimeoutIdentifier)
  1966. this._didChangeTimeoutIdentifier = setTimeout(this._fireDidChange.bind(this), 0);
  1967. },
  1968.  
  1969. _setListItemNodeContent: function()
  1970. {
  1971. if (!this._listItemNode)
  1972. return;
  1973.  
  1974. if (typeof this._title === "string")
  1975. this._listItemNode.textContent = this._title;
  1976. else {
  1977. this._listItemNode.removeChildren();
  1978. if (this._title)
  1979. this._listItemNode.appendChild(this._title);
  1980. }
  1981. }
  1982. }
  1983.  
  1984. TreeElement.prototype.appendChild = TreeOutline.prototype.appendChild;
  1985. TreeElement.prototype.insertChild = TreeOutline.prototype.insertChild;
  1986. TreeElement.prototype.removeChild = TreeOutline.prototype.removeChild;
  1987. TreeElement.prototype.removeChildAtIndex = TreeOutline.prototype.removeChildAtIndex;
  1988. TreeElement.prototype.removeChildren = TreeOutline.prototype.removeChildren;
  1989. TreeElement.prototype.removeChildrenRecursive = TreeOutline.prototype.removeChildrenRecursive;
  1990.  
  1991. TreeElement.prototype._attach = function()
  1992. {
  1993. if (!this._listItemNode || this.parent._shouldRefreshChildren) {
  1994. if (this._listItemNode && this._listItemNode.parentNode)
  1995. this._listItemNode.parentNode.removeChild(this._listItemNode);
  1996.  
  1997. this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li");
  1998. this._listItemNode.treeElement = this;
  1999. this._setListItemNodeContent();
  2000. this._listItemNode.title = this._tooltip ? this._tooltip : "";
  2001.  
  2002. if (this.hidden)
  2003. this._listItemNode.classList.add("hidden");
  2004. if (this.hasChildren)
  2005. this._listItemNode.classList.add("parent");
  2006. if (this.expanded)
  2007. this._listItemNode.classList.add("expanded");
  2008. if (this.selected)
  2009. this._listItemNode.classList.add("selected");
  2010.  
  2011. this._listItemNode.addEventListener("mousedown", TreeElement.treeElementMouseDown, false);
  2012. this._listItemNode.addEventListener("click", TreeElement.treeElementToggled, false);
  2013. this._listItemNode.addEventListener("dblclick", TreeElement.treeElementDoubleClicked, false);
  2014.  
  2015. if (this.onattach)
  2016. this.onattach(this);
  2017. }
  2018.  
  2019. var nextSibling = null;
  2020. if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode)
  2021. nextSibling = this.nextSibling._listItemNode;
  2022. this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling);
  2023. if (this._childrenListNode)
  2024. this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
  2025. if (this.selected)
  2026. this.select();
  2027. if (this.expanded)
  2028. this.expand();
  2029. }
  2030.  
  2031. TreeElement.prototype._detach = function()
  2032. {
  2033. if (this._listItemNode && this._listItemNode.parentNode)
  2034. this._listItemNode.parentNode.removeChild(this._listItemNode);
  2035. if (this._childrenListNode && this._childrenListNode.parentNode)
  2036. this._childrenListNode.parentNode.removeChild(this._childrenListNode);
  2037. }
  2038.  
  2039. TreeElement.treeElementMouseDown = function(event)
  2040. {
  2041. var element = event.currentTarget;
  2042. if (!element || !element.treeElement || !element.treeElement.selectable)
  2043. return;
  2044.  
  2045. if (element.treeElement.isEventWithinDisclosureTriangle(event))
  2046. return;
  2047.  
  2048. element.treeElement.selectOnMouseDown(event);
  2049. }
  2050.  
  2051. TreeElement.treeElementToggled = function(event)
  2052. {
  2053. var element = event.currentTarget;
  2054. if (!element || !element.treeElement)
  2055. return;
  2056.  
  2057. var toggleOnClick = element.treeElement.toggleOnClick && !element.treeElement.selectable;
  2058. var isInTriangle = element.treeElement.isEventWithinDisclosureTriangle(event);
  2059. if (!toggleOnClick && !isInTriangle)
  2060. return;
  2061.  
  2062. if (element.treeElement.expanded) {
  2063. if (event.altKey)
  2064. element.treeElement.collapseRecursively();
  2065. else
  2066. element.treeElement.collapse();
  2067. } else {
  2068. if (event.altKey)
  2069. element.treeElement.expandRecursively();
  2070. else
  2071. element.treeElement.expand();
  2072. }
  2073. event.consume();
  2074. }
  2075.  
  2076. TreeElement.treeElementDoubleClicked = function(event)
  2077. {
  2078. var element = event.currentTarget;
  2079. if (!element || !element.treeElement)
  2080. return;
  2081.  
  2082. if (element.treeElement.ondblclick) {
  2083. var handled = element.treeElement.ondblclick.call(element.treeElement, event);
  2084. if (handled)
  2085. return;
  2086. } else if (element.treeElement.hasChildren && !element.treeElement.expanded)
  2087. element.treeElement.expand();
  2088. }
  2089.  
  2090. TreeElement.prototype.collapse = function()
  2091. {
  2092. if (this._listItemNode)
  2093. this._listItemNode.classList.remove("expanded");
  2094. if (this._childrenListNode)
  2095. this._childrenListNode.classList.remove("expanded");
  2096.  
  2097. this.expanded = false;
  2098.  
  2099. if (this.treeOutline)
  2100. this.treeOutline._expandedStateMap.put(this.representedObject, false);
  2101.  
  2102. if (this.oncollapse)
  2103. this.oncollapse(this);
  2104. }
  2105.  
  2106. TreeElement.prototype.collapseRecursively = function()
  2107. {
  2108. var item = this;
  2109. while (item) {
  2110. if (item.expanded)
  2111. item.collapse();
  2112. item = item.traverseNextTreeElement(false, this, true);
  2113. }
  2114. }
  2115.  
  2116. TreeElement.prototype.expand = function()
  2117. {
  2118. if (!this.hasChildren || (this.expanded && !this._shouldRefreshChildren && this._childrenListNode))
  2119. return;
  2120.  
  2121.  
  2122.  
  2123.  
  2124.  
  2125. this.expanded = true;
  2126. if (this.treeOutline)
  2127. this.treeOutline._expandedStateMap.put(this.representedObject, true);
  2128.  
  2129. if (this.treeOutline && (!this._childrenListNode || this._shouldRefreshChildren)) {
  2130. if (this._childrenListNode && this._childrenListNode.parentNode)
  2131. this._childrenListNode.parentNode.removeChild(this._childrenListNode);
  2132.  
  2133. this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
  2134. this._childrenListNode.parentTreeElement = this;
  2135. this._childrenListNode.classList.add("children");
  2136.  
  2137. if (this.hidden)
  2138. this._childrenListNode.classList.add("hidden");
  2139.  
  2140. this.onpopulate();
  2141.  
  2142. for (var i = 0; i < this.children.length; ++i)
  2143. this.children[i]._attach();
  2144.  
  2145. delete this._shouldRefreshChildren;
  2146. }
  2147.  
  2148. if (this._listItemNode) {
  2149. this._listItemNode.classList.add("expanded");
  2150. if (this._childrenListNode && this._childrenListNode.parentNode != this._listItemNode.parentNode)
  2151. this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
  2152. }
  2153.  
  2154. if (this._childrenListNode)
  2155. this._childrenListNode.classList.add("expanded");
  2156.  
  2157. if (this.onexpand)
  2158. this.onexpand(this);
  2159. }
  2160.  
  2161. TreeElement.prototype.expandRecursively = function(maxDepth)
  2162. {
  2163. var item = this;
  2164. var info = {};
  2165. var depth = 0;
  2166.  
  2167.  
  2168.  
  2169.  
  2170. if (typeof maxDepth === "undefined" || typeof maxDepth === "null")
  2171. maxDepth = 3;
  2172.  
  2173. while (item) {
  2174. if (depth < maxDepth)
  2175. item.expand();
  2176. item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
  2177. depth += info.depthChange;
  2178. }
  2179. }
  2180.  
  2181. TreeElement.prototype.hasAncestor = function(ancestor) {
  2182. if (!ancestor)
  2183. return false;
  2184.  
  2185. var currentNode = this.parent;
  2186. while (currentNode) {
  2187. if (ancestor === currentNode)
  2188. return true;
  2189. currentNode = currentNode.parent;
  2190. }
  2191.  
  2192. return false;
  2193. }
  2194.  
  2195. TreeElement.prototype.reveal = function()
  2196. {
  2197. var currentAncestor = this.parent;
  2198. while (currentAncestor && !currentAncestor.root) {
  2199. if (!currentAncestor.expanded)
  2200. currentAncestor.expand();
  2201. currentAncestor = currentAncestor.parent;
  2202. }
  2203.  
  2204. if (this.onreveal)
  2205. this.onreveal(this);
  2206. }
  2207.  
  2208. TreeElement.prototype.revealed = function()
  2209. {
  2210. var currentAncestor = this.parent;
  2211. while (currentAncestor && !currentAncestor.root) {
  2212. if (!currentAncestor.expanded)
  2213. return false;
  2214. currentAncestor = currentAncestor.parent;
  2215. }
  2216.  
  2217. return true;
  2218. }
  2219.  
  2220. TreeElement.prototype.selectOnMouseDown = function(event)
  2221. {
  2222. if (this.select(false, true))
  2223. event.consume(true);
  2224. }
  2225.  
  2226.  
  2227. TreeElement.prototype.select = function(omitFocus, selectedByUser)
  2228. {
  2229. if (!this.treeOutline || !this.selectable || this.selected)
  2230. return false;
  2231.  
  2232. if (this.treeOutline.selectedTreeElement)
  2233. this.treeOutline.selectedTreeElement.deselect();
  2234.  
  2235. this.selected = true;
  2236.  
  2237. if(!omitFocus)
  2238. this.treeOutline._childrenListNode.focus();
  2239.  
  2240.  
  2241. if (!this.treeOutline)
  2242. return false;
  2243. this.treeOutline.selectedTreeElement = this;
  2244. if (this._listItemNode)
  2245. this._listItemNode.classList.add("selected");
  2246.  
  2247. if (this.onselect)
  2248. return this.onselect(this, selectedByUser);
  2249. return false;
  2250. }
  2251.  
  2252.  
  2253. TreeElement.prototype.revealAndSelect = function(omitFocus)
  2254. {
  2255. this.reveal();
  2256. this.select(omitFocus);
  2257. }
  2258.  
  2259.  
  2260. TreeElement.prototype.deselect = function(supressOnDeselect)
  2261. {
  2262. if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
  2263. return false;
  2264.  
  2265. this.selected = false;
  2266. this.treeOutline.selectedTreeElement = null;
  2267. if (this._listItemNode)
  2268. this._listItemNode.classList.remove("selected");
  2269.  
  2270. if (this.ondeselect && !supressOnDeselect)
  2271. this.ondeselect(this);
  2272. return true;
  2273. }
  2274.  
  2275. TreeElement.prototype.onpopulate = function()
  2276. {
  2277.  
  2278. }
  2279.  
  2280.  
  2281. TreeElement.prototype.traverseNextTreeElement = function(skipUnrevealed, stayWithin, dontPopulate, info)
  2282. {
  2283. if (!dontPopulate && this.hasChildren)
  2284. this.onpopulate();
  2285.  
  2286. if (info)
  2287. info.depthChange = 0;
  2288.  
  2289. var element = skipUnrevealed ? (this.revealed() ? this.children[0] : null) : this.children[0];
  2290. if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) {
  2291. if (info)
  2292. info.depthChange = 1;
  2293. return element;
  2294. }
  2295.  
  2296. if (this === stayWithin)
  2297. return null;
  2298.  
  2299. element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
  2300. if (element)
  2301. return element;
  2302.  
  2303. element = this;
  2304. while (element && !element.root && !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) {
  2305. if (info)
  2306. info.depthChange -= 1;
  2307. element = element.parent;
  2308. }
  2309.  
  2310. if (!element)
  2311. return null;
  2312.  
  2313. return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
  2314. }
  2315.  
  2316.  
  2317. TreeElement.prototype.traversePreviousTreeElement = function(skipUnrevealed, dontPopulate)
  2318. {
  2319. var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
  2320. if (!dontPopulate && element && element.hasChildren)
  2321. element.onpopulate();
  2322.  
  2323. while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
  2324. if (!dontPopulate && element.hasChildren)
  2325. element.onpopulate();
  2326. element = (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]);
  2327. }
  2328.  
  2329. if (element)
  2330. return element;
  2331.  
  2332. if (!this.parent || this.parent.root)
  2333. return null;
  2334.  
  2335. return this.parent;
  2336. }
  2337.  
  2338. TreeElement.prototype.isEventWithinDisclosureTriangle = function(event)
  2339. {
  2340.  
  2341. var computedLeftPadding = window.getComputedStyle(this._listItemNode).getPropertyCSSValue("padding-left").getFloatValue(CSSPrimitiveValue.CSS_PX);
  2342. var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding;
  2343. return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
  2344. }
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350. var WebInspector = {
  2351. _createPanels: function()
  2352. {
  2353. this.panels = {};
  2354. WebInspector.inspectorView = new WebInspector.InspectorView();
  2355. var parentElement = document.getElementById("main");
  2356. WebInspector.inspectorView.show(parentElement);
  2357. WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, this._panelSelected, this);
  2358.  
  2359. if (WebInspector.WorkerManager.isWorkerFrontend()) {
  2360. this.panels.scripts = new WebInspector.ScriptsPanel(this.debuggerPresentationModel);
  2361. this.panels.timeline = new WebInspector.TimelinePanel();
  2362. this.panels.profiles = new WebInspector.ProfilesPanel();
  2363. this.panels.console = new WebInspector.ConsolePanel();
  2364. return;
  2365. }
  2366. var hiddenPanels = (InspectorFrontendHost.hiddenPanels() || "").split(',');
  2367. if (hiddenPanels.indexOf("elements") === -1)
  2368. this.panels.elements = new WebInspector.ElementsPanel();
  2369. if (hiddenPanels.indexOf("resources") === -1)
  2370. this.panels.resources = new WebInspector.ResourcesPanel();
  2371. if (hiddenPanels.indexOf("network") === -1)
  2372. this.panels.network = new WebInspector.NetworkPanel();
  2373. if (hiddenPanels.indexOf("scripts") === -1)
  2374. this.panels.scripts = new WebInspector.ScriptsPanel(this.debuggerPresentationModel);
  2375. if (hiddenPanels.indexOf("timeline") === -1)
  2376. this.panels.timeline = new WebInspector.TimelinePanel();
  2377. if (hiddenPanels.indexOf("profiles") === -1)
  2378. this.panels.profiles = new WebInspector.ProfilesPanel();
  2379. if (hiddenPanels.indexOf("audits") === -1)
  2380. this.panels.audits = new WebInspector.AuditsPanel();
  2381. if (hiddenPanels.indexOf("console") === -1)
  2382. this.panels.console = new WebInspector.ConsolePanel();
  2383. },
  2384.  
  2385. _panelSelected: function()
  2386. {
  2387. this._toggleConsoleButton.disabled = WebInspector.inspectorView.currentPanel() === WebInspector.panels.console;
  2388. },
  2389.  
  2390. _createGlobalStatusBarItems: function()
  2391. {
  2392. this._dockToggleButton = new WebInspector.StatusBarButton(this._dockButtonTitle(), "dock-status-bar-item");
  2393. this._dockToggleButton.addEventListener("click", this._toggleAttach.bind(this), false);
  2394. this._dockToggleButton.toggled = !this.attached;
  2395. WebInspector.updateDockToggleButton();
  2396.  
  2397. this._settingsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Settings"), "settings-status-bar-item");
  2398. this._settingsButton.addEventListener("click", this._toggleSettings.bind(this), false);
  2399.  
  2400. var anchoredStatusBar = document.getElementById("anchored-status-bar-items");
  2401. anchoredStatusBar.appendChild(this._dockToggleButton.element);
  2402.  
  2403. this._toggleConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show console."), "console-status-bar-item");
  2404. this._toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);
  2405. anchoredStatusBar.appendChild(this._toggleConsoleButton.element);
  2406.  
  2407. if (this.panels.elements)
  2408. anchoredStatusBar.appendChild(this.panels.elements.nodeSearchButton.element);
  2409. anchoredStatusBar.appendChild(this._settingsButton.element);
  2410. },
  2411.  
  2412. _dockButtonTitle: function()
  2413. {
  2414. return this.attached ? WebInspector.UIString("Undock into separate window.") : WebInspector.UIString("Dock to main window.");
  2415. },
  2416.  
  2417. _toggleAttach: function()
  2418. {
  2419. if (!this._attached) {
  2420. InspectorFrontendHost.requestAttachWindow();
  2421. WebInspector.userMetrics.WindowDocked.record();
  2422. } else {
  2423. InspectorFrontendHost.requestDetachWindow();
  2424. WebInspector.userMetrics.WindowUndocked.record();
  2425. }
  2426. },
  2427.  
  2428. _toggleConsoleButtonClicked: function()
  2429. {
  2430. if (this._toggleConsoleButton.disabled)
  2431. return;
  2432.  
  2433. this._toggleConsoleButton.toggled = !this._toggleConsoleButton.toggled;
  2434.  
  2435. var animationType = window.event && window.event.shiftKey ? WebInspector.Drawer.AnimationType.Slow : WebInspector.Drawer.AnimationType.Normal;
  2436. if (this._toggleConsoleButton.toggled) {
  2437. this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
  2438. this.drawer.show(this.consoleView, animationType);
  2439. this._consoleWasShown = true;
  2440. } else {
  2441. this._toggleConsoleButton.title = WebInspector.UIString("Show console.");
  2442. this.drawer.hide(animationType);
  2443. delete this._consoleWasShown;
  2444. }
  2445. },
  2446.  
  2447. closeDrawerView: function()
  2448. {
  2449.  
  2450. if (!this._consoleWasShown)
  2451. this.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
  2452. else
  2453. this._toggleConsoleButtonClicked();
  2454. },
  2455.  
  2456.  
  2457. showViewInDrawer: function(view)
  2458. {
  2459. this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
  2460. this._toggleConsoleButton.toggled = false;
  2461. this.drawer.show(view, WebInspector.Drawer.AnimationType.Immediately);
  2462. },
  2463.  
  2464. _toggleSettings: function()
  2465. {
  2466. this._settingsButton.toggled = !this._settingsButton.toggled;
  2467. if (this._settingsButton.toggled)
  2468. this._showSettingsScreen();
  2469. else
  2470. this._hideSettingsScreen();
  2471. },
  2472.  
  2473. _showSettingsScreen: function()
  2474. {
  2475. function onhide()
  2476. {
  2477. this._settingsButton.toggled = false;
  2478. delete this._settingsScreen;
  2479. }
  2480.  
  2481. if (!this._settingsScreen) {
  2482. this._settingsScreen = new WebInspector.SettingsScreen();
  2483. this._settingsScreen.show(onhide.bind(this));
  2484. }
  2485. },
  2486.  
  2487. _hideSettingsScreen: function()
  2488. {
  2489. if (this._settingsScreen)
  2490. this._settingsScreen.hide();
  2491. },
  2492.  
  2493. get attached()
  2494. {
  2495. return this._attached;
  2496. },
  2497.  
  2498. set attached(x)
  2499. {
  2500. if (this._attached === x)
  2501. return;
  2502.  
  2503. this._attached = x;
  2504.  
  2505. if (this._dockToggleButton) {
  2506. this._dockToggleButton.title = this._dockButtonTitle();
  2507. this._dockToggleButton.toggled = !x;
  2508. }
  2509.  
  2510. if (x)
  2511. document.body.removeStyleClass("detached");
  2512. else
  2513. document.body.addStyleClass("detached");
  2514.  
  2515. this._setCompactMode(x && !WebInspector.settings.dockToRight.get());
  2516. },
  2517.  
  2518. isCompactMode: function()
  2519. {
  2520. return this.attached && !WebInspector.settings.dockToRight.get();
  2521. },
  2522.  
  2523. _setCompactMode: function(x)
  2524. {
  2525. var body = document.body;
  2526. if (x)
  2527. body.addStyleClass("compact");
  2528. else
  2529. body.removeStyleClass("compact");
  2530.  
  2531.  
  2532.  
  2533. if (WebInspector.toolbar)
  2534. WebInspector.toolbar.compact = x;
  2535.  
  2536. if (WebInspector.searchController)
  2537. WebInspector.searchController.updateSearchLabel();
  2538.  
  2539. if (WebInspector.drawer)
  2540. WebInspector.drawer.resize();
  2541. },
  2542.  
  2543. _updateErrorAndWarningCounts: function()
  2544. {
  2545. var errorWarningElement = document.getElementById("error-warning-count");
  2546. if (!errorWarningElement)
  2547. return;
  2548.  
  2549. var errors = WebInspector.console.errors;
  2550. var warnings = WebInspector.console.warnings;
  2551. if (!errors && !warnings) {
  2552. errorWarningElement.addStyleClass("hidden");
  2553. return;
  2554. }
  2555.  
  2556. errorWarningElement.removeStyleClass("hidden");
  2557.  
  2558. errorWarningElement.removeChildren();
  2559.  
  2560. if (errors) {
  2561. var errorImageElement = document.createElement("img");
  2562. errorImageElement.id = "error-count-img";
  2563. errorWarningElement.appendChild(errorImageElement);
  2564. var errorElement = document.createElement("span");
  2565. errorElement.id = "error-count";
  2566. errorElement.textContent = errors;
  2567. errorWarningElement.appendChild(errorElement);
  2568. }
  2569.  
  2570. if (warnings) {
  2571. var warningsImageElement = document.createElement("img");
  2572. warningsImageElement.id = "warning-count-img";
  2573. errorWarningElement.appendChild(warningsImageElement);
  2574. var warningsElement = document.createElement("span");
  2575. warningsElement.id = "warning-count";
  2576. warningsElement.textContent = warnings;
  2577. errorWarningElement.appendChild(warningsElement);
  2578. }
  2579.  
  2580. if (errors) {
  2581. if (warnings) {
  2582. if (errors == 1) {
  2583. if (warnings == 1)
  2584. errorWarningElement.title = WebInspector.UIString("%d error, %d warning", errors, warnings);
  2585. else
  2586. errorWarningElement.title = WebInspector.UIString("%d error, %d warnings", errors, warnings);
  2587. } else if (warnings == 1)
  2588. errorWarningElement.title = WebInspector.UIString("%d errors, %d warning", errors, warnings);
  2589. else
  2590. errorWarningElement.title = WebInspector.UIString("%d errors, %d warnings", errors, warnings);
  2591. } else if (errors == 1)
  2592. errorWarningElement.title = WebInspector.UIString("%d error", errors);
  2593. else
  2594. errorWarningElement.title = WebInspector.UIString("%d errors", errors);
  2595. } else if (warnings == 1)
  2596. errorWarningElement.title = WebInspector.UIString("%d warning", warnings);
  2597. else if (warnings)
  2598. errorWarningElement.title = WebInspector.UIString("%d warnings", warnings);
  2599. else
  2600. errorWarningElement.title = null;
  2601. },
  2602.  
  2603. networkResourceById: function(id)
  2604. {
  2605. return this.panels.network.resourceById(id);
  2606. },
  2607.  
  2608. get inspectedPageDomain()
  2609. {
  2610. var parsedURL = WebInspector.inspectedPageURL && WebInspector.inspectedPageURL.asParsedURL();
  2611. return parsedURL ? parsedURL.host : "";
  2612. },
  2613.  
  2614. _initializeCapability: function(name, callback, error, result)
  2615. {
  2616. Capabilities[name] = result;
  2617. if (callback)
  2618. callback();
  2619. },
  2620.  
  2621. _zoomIn: function()
  2622. {
  2623. ++this._zoomLevel;
  2624. this._requestZoom();
  2625. },
  2626.  
  2627. _zoomOut: function()
  2628. {
  2629. --this._zoomLevel;
  2630. this._requestZoom();
  2631. },
  2632.  
  2633. _resetZoom: function()
  2634. {
  2635. this._zoomLevel = 0;
  2636. this._requestZoom();
  2637. },
  2638.  
  2639. _requestZoom: function()
  2640. {
  2641. WebInspector.settings.zoomLevel.set(this._zoomLevel);
  2642. InspectorFrontendHost.setZoomFactor(Math.pow(1.2, this._zoomLevel));
  2643. }
  2644. }
  2645.  
  2646. WebInspector.Events = {
  2647. InspectorClosing: "InspectorClosing"
  2648. }
  2649.  
  2650. {(function parseQueryParameters()
  2651. {
  2652. WebInspector.queryParamsObject = {};
  2653. var queryParams = window.location.search;
  2654. if (!queryParams)
  2655. return;
  2656. var params = queryParams.substring(1).split("&");
  2657. for (var i = 0; i < params.length; ++i) {
  2658. var pair = params[i].split("=");
  2659. WebInspector.queryParamsObject[pair[0]] = pair[1];
  2660. }
  2661. })();}
  2662.  
  2663. WebInspector.loaded = function()
  2664. {
  2665. InspectorBackend.loadFromJSONIfNeeded();
  2666. if ("page" in WebInspector.queryParamsObject) {
  2667. var page = WebInspector.queryParamsObject.page;
  2668. var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host;
  2669. WebInspector.socket = new WebSocket("ws://" + host + "/devtools/page/" + page);
  2670. WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); }
  2671. WebInspector.socket.onerror = function(error) { console.error(error); }
  2672. WebInspector.socket.onopen = function() {
  2673. InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket);
  2674. WebInspector.doLoadedDone();
  2675. }
  2676. return;
  2677. }
  2678. WebInspector.doLoadedDone();
  2679. }
  2680.  
  2681. WebInspector.doLoadedDone = function()
  2682. {
  2683.  
  2684. WebInspector.installPortStyles();
  2685. if (WebInspector.socket)
  2686. document.body.addStyleClass("remote");
  2687.  
  2688. if (WebInspector.queryParamsObject.toolbarColor && WebInspector.queryParamsObject.textColor)
  2689. WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbarColor, WebInspector.queryParamsObject.textColor);
  2690.  
  2691. InspectorFrontendHost.loaded();
  2692. WebInspector.WorkerManager.loaded();
  2693.  
  2694. DebuggerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "debuggerCausesRecompilation", null));
  2695. DebuggerAgent.supportsNativeBreakpoints(WebInspector._initializeCapability.bind(WebInspector, "nativeInstrumentationEnabled", null));
  2696. ProfilerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "profilerCausesRecompilation", null));
  2697. ProfilerAgent.isSampling(WebInspector._initializeCapability.bind(WebInspector, "samplingCPUProfiler", null));
  2698. ProfilerAgent.hasHeapProfiler(WebInspector._initializeCapability.bind(WebInspector, "heapProfilerPresent", null));
  2699. PageAgent.canOverrideDeviceMetrics(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceMetrics", WebInspector._doLoadedDoneWithCapabilities.bind(WebInspector)));
  2700. }
  2701.  
  2702. WebInspector._doLoadedDoneWithCapabilities = function()
  2703. {
  2704. WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
  2705. this._registerShortcuts();
  2706.  
  2707.  
  2708. WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
  2709. WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
  2710.  
  2711. this.console = new WebInspector.ConsoleModel();
  2712. this.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this);
  2713. this.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
  2714. this.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._updateErrorAndWarningCounts, this);
  2715.  
  2716. this.debuggerModel = new WebInspector.DebuggerModel();
  2717. this.snippetsModel = new WebInspector.SnippetsModel();
  2718. this.debuggerPresentationModel = new WebInspector.DebuggerPresentationModel();
  2719.  
  2720. this.drawer = new WebInspector.Drawer();
  2721. this.consoleView = new WebInspector.ConsoleView(WebInspector.WorkerManager.isWorkerFrontend());
  2722.  
  2723. this.networkManager = new WebInspector.NetworkManager();
  2724. this.resourceTreeModel = new WebInspector.ResourceTreeModel(this.networkManager);
  2725. this.networkLog = new WebInspector.NetworkLog();
  2726. this.domAgent = new WebInspector.DOMAgent();
  2727. new WebInspector.JavaScriptContextManager(this.resourceTreeModel, this.consoleView);
  2728.  
  2729. InspectorBackend.registerInspectorDispatcher(this);
  2730.  
  2731. this.cssModel = new WebInspector.CSSStyleModel();
  2732. this.timelineManager = new WebInspector.TimelineManager();
  2733. this.userAgentSupport = new WebInspector.UserAgentSupport();
  2734. InspectorBackend.registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher());
  2735. InspectorBackend.registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher());
  2736.  
  2737. this.searchController = new WebInspector.SearchController();
  2738. this.advancedSearchController = new WebInspector.AdvancedSearchController();
  2739.  
  2740. if (Capabilities.nativeInstrumentationEnabled)
  2741. this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
  2742.  
  2743. this._zoomLevel = WebInspector.settings.zoomLevel.get();
  2744. if (this._zoomLevel)
  2745. this._requestZoom();
  2746.  
  2747. this._createPanels();
  2748. this._createGlobalStatusBarItems();
  2749.  
  2750. this.toolbar = new WebInspector.Toolbar();
  2751. WebInspector._installDockToRight();
  2752.  
  2753. for (var panelName in this.panels)
  2754. this.addPanel(this.panels[panelName]);
  2755.  
  2756. this.addMainEventListeners(document);
  2757.  
  2758. window.addEventListener("resize", this.windowResize.bind(this), true);
  2759.  
  2760. var errorWarningCount = document.getElementById("error-warning-count");
  2761. errorWarningCount.addEventListener("click", this.showConsole.bind(this), false);
  2762. this._updateErrorAndWarningCounts();
  2763.  
  2764. var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
  2765. var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
  2766. this.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
  2767. this.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
  2768.  
  2769. this.extensionServer.initExtensions();
  2770.  
  2771. this.console.enableAgent();
  2772.  
  2773. function showInitialPanel()
  2774. {
  2775. if (!WebInspector.inspectorView.currentPanel())
  2776. WebInspector.showPanel(WebInspector.settings.lastActivePanel.get());
  2777. }
  2778.  
  2779. InspectorAgent.enable(showInitialPanel);
  2780. DatabaseAgent.enable();
  2781. DOMStorageAgent.enable();
  2782.  
  2783. if (WebInspector.settings.showPaintRects.get())
  2784. PageAgent.setShowPaintRects(true);
  2785.  
  2786. WebInspector.CSSCompletions.requestCSSNameCompletions();
  2787. WebInspector.WorkerManager.loadCompleted();
  2788. InspectorFrontendAPI.loadCompleted();
  2789. }
  2790.  
  2791. WebInspector._installDockToRight = function()
  2792. {
  2793.  
  2794. WebInspector.settings.dockToRight.set(WebInspector.queryParamsObject.dockSide === "right");
  2795.  
  2796. if (WebInspector.settings.dockToRight.get())
  2797. document.body.addStyleClass("dock-to-right");
  2798.  
  2799. if (WebInspector.attached)
  2800. WebInspector._setCompactMode(!WebInspector.settings.dockToRight.get());
  2801.  
  2802. WebInspector.settings.dockToRight.addChangeListener(listener.bind(this));
  2803.  
  2804. function listener(event)
  2805. {
  2806. var value = WebInspector.settings.dockToRight.get();
  2807. if (value) {
  2808. InspectorFrontendHost.requestSetDockSide("right");
  2809. document.body.addStyleClass("dock-to-right");
  2810. } else {
  2811. InspectorFrontendHost.requestSetDockSide("bottom");
  2812. document.body.removeStyleClass("dock-to-right");
  2813. }
  2814. if (WebInspector.attached)
  2815. WebInspector._setCompactMode(!value);
  2816. }
  2817. }
  2818.  
  2819. WebInspector.addPanel = function(panel)
  2820. {
  2821. WebInspector.inspectorView.addPanel(panel);
  2822. }
  2823.  
  2824. var windowLoaded = function()
  2825. {
  2826. var localizedStringsURL = InspectorFrontendHost.localizedStringsURL();
  2827. if (localizedStringsURL) {
  2828. var localizedStringsScriptElement = document.createElement("script");
  2829. localizedStringsScriptElement.addEventListener("load", WebInspector.loaded.bind(WebInspector), false);
  2830. localizedStringsScriptElement.type = "text/javascript";
  2831. localizedStringsScriptElement.src = localizedStringsURL;
  2832. document.head.appendChild(localizedStringsScriptElement);
  2833. } else
  2834. WebInspector.loaded();
  2835.  
  2836. WebInspector.setAttachedWindow(WebInspector.queryParamsObject.docked === "true");
  2837.  
  2838. window.removeEventListener("DOMContentLoaded", windowLoaded, false);
  2839. delete windowLoaded;
  2840. };
  2841.  
  2842. window.addEventListener("DOMContentLoaded", windowLoaded, false);
  2843.  
  2844.  
  2845.  
  2846.  
  2847.  
  2848.  
  2849.  
  2850. var messagesToDispatch = [];
  2851.  
  2852. WebInspector.dispatchQueueIsEmpty = function() {
  2853. return messagesToDispatch.length == 0;
  2854. }
  2855.  
  2856. WebInspector.dispatch = function(message) {
  2857. messagesToDispatch.push(message);
  2858. setTimeout(function() {
  2859. InspectorBackend.dispatch(messagesToDispatch.shift());
  2860. }, 0);
  2861. }
  2862.  
  2863. WebInspector.dispatchMessageFromBackend = function(messageObject)
  2864. {
  2865. WebInspector.dispatch(messageObject);
  2866. }
  2867.  
  2868. WebInspector.windowResize = function(event)
  2869. {
  2870. WebInspector.inspectorView.doResize();
  2871. WebInspector.drawer.resize();
  2872. WebInspector.toolbar.resize();
  2873. }
  2874.  
  2875. WebInspector.setAttachedWindow = function(attached)
  2876. {
  2877. this.attached = attached;
  2878. WebInspector.updateDockToggleButton();
  2879. }
  2880.  
  2881. WebInspector.setDockingUnavailable = function(unavailable)
  2882. {
  2883. this._isDockingUnavailable = unavailable;
  2884. WebInspector.updateDockToggleButton();
  2885. }
  2886.  
  2887. WebInspector.updateDockToggleButton = function()
  2888. {
  2889. if (!this._dockToggleButton)
  2890. return;
  2891. this._dockToggleButton.disabled = this.attached ? false : this._isDockingUnavailable;
  2892. }
  2893.  
  2894. WebInspector.close = function(event)
  2895. {
  2896. if (this._isClosing)
  2897. return;
  2898. this._isClosing = true;
  2899. this.notifications.dispatchEventToListeners(WebInspector.Events.InspectorClosing);
  2900. InspectorFrontendHost.closeWindow();
  2901. }
  2902.  
  2903. WebInspector.documentClick = function(event)
  2904. {
  2905. var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
  2906. if (!anchor || anchor.target === "_blank")
  2907. return;
  2908.  
  2909.  
  2910. event.consume(true);
  2911.  
  2912. function followLink()
  2913. {
  2914. if (WebInspector.isBeingEdited(event.target) || WebInspector._showAnchorLocation(anchor))
  2915. return;
  2916.  
  2917. const profileMatch = WebInspector.ProfileType.URLRegExp.exec(anchor.href);
  2918. if (profileMatch) {
  2919. WebInspector.showProfileForURL(anchor.href);
  2920. return;
  2921. }
  2922.  
  2923. var parsedURL = anchor.href.asParsedURL();
  2924. if (parsedURL && parsedURL.scheme === "webkit-link-action") {
  2925. if (parsedURL.host === "show-panel") {
  2926. var panel = parsedURL.path.substring(1);
  2927. if (WebInspector.panels[panel])
  2928. WebInspector.showPanel(panel);
  2929. }
  2930. return;
  2931. }
  2932.  
  2933. WebInspector.showPanel("resources");
  2934. }
  2935.  
  2936. if (WebInspector.followLinkTimeout)
  2937. clearTimeout(WebInspector.followLinkTimeout);
  2938.  
  2939. if (anchor.preventFollowOnDoubleClick) {
  2940.  
  2941.  
  2942. if (event.detail === 1)
  2943. WebInspector.followLinkTimeout = setTimeout(followLink, 333);
  2944. return;
  2945. }
  2946.  
  2947. followLink();
  2948. }
  2949.  
  2950. WebInspector.openResource = function(resourceURL, inResourcesPanel)
  2951. {
  2952. var resource = WebInspector.resourceForURL(resourceURL);
  2953. if (inResourcesPanel && resource) {
  2954. WebInspector.showPanel("resources");
  2955. WebInspector.panels.resources.showResource(resource);
  2956. } else
  2957. InspectorFrontendHost.openInNewTab(resourceURL);
  2958. }
  2959.  
  2960. WebInspector.openRequestInNetworkPanel = function(resource)
  2961. {
  2962. WebInspector.showPanel("network");
  2963. WebInspector.panels.network.revealAndHighlightResource(resource);
  2964. }
  2965.  
  2966. WebInspector._registerShortcuts = function()
  2967. {
  2968. var shortcut = WebInspector.KeyboardShortcut;
  2969. var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
  2970. var keys = [
  2971. shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta),
  2972. shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta)
  2973. ];
  2974. section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
  2975.  
  2976. var keys = [
  2977. shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
  2978. shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
  2979. ];
  2980. section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
  2981.  
  2982. section.addKey(shortcut.shortcutToString(shortcut.Keys.Esc), WebInspector.UIString("Toggle console"));
  2983. section.addKey(shortcut.shortcutToString("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
  2984.  
  2985. var advancedSearchShortcut = WebInspector.AdvancedSearchController.createShortcut();
  2986. section.addKey(advancedSearchShortcut.name, WebInspector.UIString("Search across all scripts"));
  2987.  
  2988. if (WebInspector.isMac()) {
  2989. keys = [
  2990. shortcut.shortcutToString("g", shortcut.Modifiers.Meta),
  2991. shortcut.shortcutToString("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
  2992. ];
  2993. section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
  2994. }
  2995.  
  2996. var goToShortcut = WebInspector.GoToLineDialog.createShortcut();
  2997. section.addKey(goToShortcut.name, WebInspector.UIString("Go to line"));
  2998. }
  2999.  
  3000. WebInspector.documentKeyDown = function(event)
  3001. {
  3002. const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF";
  3003.  
  3004. if (event.keyIdentifier === "F1" ||
  3005. (event.keyIdentifier === helpKey && event.shiftKey && (!WebInspector.isBeingEdited(event.target) || event.metaKey))) {
  3006. WebInspector.shortcutsScreen.show();
  3007. event.consume(true);
  3008. return;
  3009. }
  3010.  
  3011. if (WebInspector.currentFocusElement() && WebInspector.currentFocusElement().handleKeyEvent) {
  3012. WebInspector.currentFocusElement().handleKeyEvent(event);
  3013. if (event.handled) {
  3014. event.consume(true);
  3015. return;
  3016. }
  3017. }
  3018.  
  3019. if (WebInspector.inspectorView.currentPanel()) {
  3020. WebInspector.inspectorView.currentPanel().handleShortcut(event);
  3021. if (event.handled) {
  3022. event.consume(true);
  3023. return;
  3024. }
  3025. }
  3026.  
  3027. WebInspector.searchController.handleShortcut(event);
  3028. WebInspector.advancedSearchController.handleShortcut(event);
  3029. if (event.handled) {
  3030. event.consume(true);
  3031. return;
  3032. }
  3033.  
  3034. var isMac = WebInspector.isMac();
  3035. switch (event.keyIdentifier) {
  3036. case "U+0052":
  3037. if ((event.metaKey && isMac) || (event.ctrlKey && !isMac)) {
  3038. PageAgent.reload(event.shiftKey);
  3039. event.consume(true);
  3040. }
  3041. break;
  3042. case "F5":
  3043. if (!isMac) {
  3044. PageAgent.reload(event.ctrlKey || event.shiftKey);
  3045. event.consume(true);
  3046. }
  3047. break;
  3048. }
  3049.  
  3050. var isValidZoomShortcut = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) &&
  3051. !event.shiftKey &&
  3052. !event.altKey &&
  3053. !InspectorFrontendHost.isStub;
  3054. switch (event.keyCode) {
  3055. case 107:
  3056. case 187:
  3057. if (isValidZoomShortcut) {
  3058. WebInspector._zoomIn();
  3059. event.consume(true);
  3060. }
  3061. break;
  3062. case 109:
  3063. case 189:
  3064. if (isValidZoomShortcut) {
  3065. WebInspector._zoomOut();
  3066. event.consume(true);
  3067. }
  3068. break;
  3069. case 48:
  3070. if (isValidZoomShortcut) {
  3071. WebInspector._resetZoom();
  3072. event.consume(true);
  3073. }
  3074. break;
  3075. }
  3076. }
  3077.  
  3078. WebInspector.postDocumentKeyDown = function(event)
  3079. {
  3080. if (event.handled)
  3081. return;
  3082.  
  3083. if (event.keyIdentifier === "U+001B") {
  3084.  
  3085. if (!this._toggleConsoleButton.toggled && WebInspector.drawer.visible)
  3086. this.closeDrawerView();
  3087. else
  3088. this._toggleConsoleButtonClicked();
  3089. }
  3090. }
  3091.  
  3092. WebInspector.documentCanCopy = function(event)
  3093. {
  3094. if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
  3095. event.preventDefault();
  3096. }
  3097.  
  3098. WebInspector.documentCopy = function(event)
  3099. {
  3100. if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
  3101. WebInspector.inspectorView.currentPanel().handleCopyEvent(event);
  3102. }
  3103.  
  3104. WebInspector.contextMenuEventFired = function(event)
  3105. {
  3106. if (event.handled || event.target.hasStyleClass("popup-glasspane"))
  3107. event.preventDefault();
  3108. }
  3109.  
  3110. WebInspector.toggleSearchingForNode = function()
  3111. {
  3112. if (this.panels.elements) {
  3113. this.showPanel("elements");
  3114. this.panels.elements.toggleSearchingForNode();
  3115. }
  3116. }
  3117.  
  3118. WebInspector.showConsole = function()
  3119. {
  3120. if (WebInspector._toggleConsoleButton && !WebInspector._toggleConsoleButton.toggled)
  3121. WebInspector._toggleConsoleButtonClicked();
  3122. }
  3123.  
  3124. WebInspector.showPanel = function(panel)
  3125. {
  3126. if (!(panel in this.panels)) {
  3127. if (WebInspector.WorkerManager.isWorkerFrontend())
  3128. panel = "scripts";
  3129. else
  3130. panel = "elements";
  3131. }
  3132. WebInspector.inspectorView.setCurrentPanel(this.panels[panel]);
  3133. }
  3134.  
  3135. WebInspector.bringToFront = function()
  3136. {
  3137. InspectorFrontendHost.bringToFront();
  3138. }
  3139.  
  3140. WebInspector.didCreateWorker = function()
  3141. {
  3142. var workersPane = WebInspector.panels.scripts.sidebarPanes.workers;
  3143. if (workersPane)
  3144. workersPane.addWorker.apply(workersPane, arguments);
  3145. }
  3146.  
  3147. WebInspector.didDestroyWorker = function()
  3148. {
  3149. var workersPane = WebInspector.panels.scripts.sidebarPanes.workers;
  3150. if (workersPane)
  3151. workersPane.removeWorker.apply(workersPane, arguments);
  3152. }
  3153.  
  3154.  
  3155. WebInspector.log = function(message, messageLevel, showConsole)
  3156. {
  3157.  
  3158. var self = this;
  3159.  
  3160.  
  3161. function isLogAvailable()
  3162. {
  3163. return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console;
  3164. }
  3165.  
  3166.  
  3167. function flushQueue()
  3168. {
  3169. var queued = WebInspector.log.queued;
  3170. if (!queued)
  3171. return;
  3172.  
  3173. for (var i = 0; i < queued.length; ++i)
  3174. logMessage(queued[i]);
  3175.  
  3176. delete WebInspector.log.queued;
  3177. }
  3178.  
  3179.  
  3180.  
  3181. function flushQueueIfAvailable()
  3182. {
  3183. if (!isLogAvailable())
  3184. return;
  3185.  
  3186. clearInterval(WebInspector.log.interval);
  3187. delete WebInspector.log.interval;
  3188.  
  3189. flushQueue();
  3190. }
  3191.  
  3192.  
  3193. function logMessage(message)
  3194. {
  3195.  
  3196. var msg = WebInspector.ConsoleMessage.create(
  3197. WebInspector.ConsoleMessage.MessageSource.Other,
  3198. messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
  3199. message);
  3200.  
  3201. self.console.addMessage(msg);
  3202. if (showConsole)
  3203. WebInspector.showConsole();
  3204. }
  3205.  
  3206.  
  3207. if (!isLogAvailable()) {
  3208. if (!WebInspector.log.queued)
  3209. WebInspector.log.queued = [];
  3210.  
  3211. WebInspector.log.queued.push(message);
  3212.  
  3213. if (!WebInspector.log.interval)
  3214. WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000);
  3215.  
  3216. return;
  3217. }
  3218.  
  3219.  
  3220. flushQueue();
  3221.  
  3222.  
  3223. logMessage(message);
  3224. }
  3225.  
  3226. WebInspector.inspect = function(payload, hints)
  3227. {
  3228. var object = WebInspector.RemoteObject.fromPayload(payload);
  3229. if (object.subtype === "node") {
  3230.  
  3231. WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.elements);
  3232. object.pushNodeToFrontend(WebInspector.updateFocusedNode.bind(WebInspector), object.release.bind(object));
  3233. return;
  3234. }
  3235.  
  3236. if (hints.databaseId) {
  3237. WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.resources);
  3238. WebInspector.panels.resources.selectDatabase(hints.databaseId);
  3239. } else if (hints.domStorageId) {
  3240. WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.resources);
  3241. WebInspector.panels.resources.selectDOMStorage(hints.domStorageId);
  3242. }
  3243.  
  3244. object.release();
  3245. }
  3246.  
  3247. WebInspector.updateFocusedNode = function(nodeId)
  3248. {
  3249. this.panels.elements.revealAndSelectNode(nodeId);
  3250. }
  3251.  
  3252. WebInspector.populateResourceContextMenu = function(contextMenu, url, preferredLineNumber)
  3253. {
  3254. var registry = WebInspector.openAnchorLocationRegistry;
  3255.  
  3256. for (var i = 1; i < registry.handlerNames.length; ++i) {
  3257. var handler = registry.handlerNames[i];
  3258. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open using %s" : "Open Using %s", handler),
  3259. registry.dispatchToHandler.bind(registry, handler, { url: url, preferredLineNumber: preferredLineNumber }));
  3260. }
  3261. }
  3262.  
  3263. WebInspector._showAnchorLocation = function(anchor)
  3264. {
  3265. if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
  3266. return true;
  3267. var preferedPanel = this.panels[anchor.preferredPanel || "resources"];
  3268. if (WebInspector._showAnchorLocationInPanel(anchor, preferedPanel))
  3269. return true;
  3270. if (preferedPanel !== this.panels.resources && WebInspector._showAnchorLocationInPanel(anchor, this.panels.resources))
  3271. return true;
  3272. return false;
  3273. }
  3274.  
  3275. WebInspector._showAnchorLocationInPanel = function(anchor, panel)
  3276. {
  3277. if (!panel.canShowAnchorLocation(anchor))
  3278. return false;
  3279.  
  3280.  
  3281. if (anchor.hasStyleClass("webkit-html-external-link")) {
  3282. anchor.removeStyleClass("webkit-html-external-link");
  3283. anchor.addStyleClass("webkit-html-resource-link");
  3284. }
  3285.  
  3286. this.showPanelForAnchorNavigation(panel);
  3287. panel.showAnchorLocation(anchor);
  3288. return true;
  3289. }
  3290.  
  3291. WebInspector.showPanelForAnchorNavigation = function(panel)
  3292. {
  3293. WebInspector.searchController.disableSearchUntilExplicitAction();
  3294. WebInspector.inspectorView.setCurrentPanel(panel);
  3295. }
  3296.  
  3297. WebInspector.showProfileForURL = function(url)
  3298. {
  3299. WebInspector.showPanel("profiles");
  3300. WebInspector.panels.profiles.showProfileForURL(url);
  3301. }
  3302.  
  3303. WebInspector.evaluateInConsole = function(expression, showResultOnly)
  3304. {
  3305. this.showConsole();
  3306. this.consoleView.evaluateUsingTextPrompt(expression, showResultOnly);
  3307. }
  3308.  
  3309. WebInspector.addMainEventListeners = function(doc)
  3310. {
  3311. doc.addEventListener("keydown", this.documentKeyDown.bind(this), true);
  3312. doc.addEventListener("keydown", this.postDocumentKeyDown.bind(this), false);
  3313. doc.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
  3314. doc.addEventListener("copy", this.documentCopy.bind(this), true);
  3315. doc.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);
  3316. doc.addEventListener("click", this.documentClick.bind(this), true);
  3317. }
  3318.  
  3319. WebInspector.frontendReused = function()
  3320. {
  3321. this.resourceTreeModel.frontendReused();
  3322. }
  3323.  
  3324. WebInspector._toolbarItemClicked = function(event)
  3325. {
  3326. var toolbarItem = event.currentTarget;
  3327. WebInspector.inspectorView.setCurrentPanel(toolbarItem.panel);
  3328. }
  3329.  
  3330.  
  3331.  
  3332.  
  3333.  
  3334. WebInspector.elementDragStart = function(element, dividerDrag, elementDragEnd, event, cursor)
  3335. {
  3336. if (WebInspector._elementDraggingEventListener || WebInspector._elementEndDraggingEventListener)
  3337. WebInspector.elementDragEnd(event);
  3338.  
  3339. if (element) {
  3340.  
  3341. if (WebInspector._elementDraggingGlassPane)
  3342. WebInspector._elementDraggingGlassPane.parentElement.removeChild(WebInspector._elementDraggingGlassPane);
  3343.  
  3344. var glassPane = document.createElement("div");
  3345. glassPane.style.cssText = "position:absolute;top:0;bottom:0;left:0;right:0;opacity:0;z-index:1";
  3346. glassPane.id = "glass-pane-for-drag";
  3347. element.ownerDocument.body.appendChild(glassPane);
  3348. WebInspector._elementDraggingGlassPane = glassPane;
  3349. }
  3350.  
  3351. WebInspector._elementDraggingEventListener = dividerDrag;
  3352. WebInspector._elementEndDraggingEventListener = elementDragEnd;
  3353.  
  3354. var targetDocument = event.target.ownerDocument;
  3355. targetDocument.addEventListener("mousemove", dividerDrag, true);
  3356. targetDocument.addEventListener("mouseup", elementDragEnd, true);
  3357.  
  3358. targetDocument.body.style.cursor = cursor;
  3359.  
  3360. event.preventDefault();
  3361. }
  3362.  
  3363. WebInspector.elementDragEnd = function(event)
  3364. {
  3365. var targetDocument = event.target.ownerDocument;
  3366. targetDocument.removeEventListener("mousemove", WebInspector._elementDraggingEventListener, true);
  3367. targetDocument.removeEventListener("mouseup", WebInspector._elementEndDraggingEventListener, true);
  3368.  
  3369. targetDocument.body.style.removeProperty("cursor");
  3370.  
  3371. if (WebInspector._elementDraggingGlassPane)
  3372. WebInspector._elementDraggingGlassPane.parentElement.removeChild(WebInspector._elementDraggingGlassPane);
  3373.  
  3374. delete WebInspector._elementDraggingGlassPane;
  3375. delete WebInspector._elementDraggingEventListener;
  3376. delete WebInspector._elementEndDraggingEventListener;
  3377.  
  3378. event.preventDefault();
  3379. }
  3380.  
  3381. WebInspector.animateStyle = function(animations, duration, callback)
  3382. {
  3383. var interval;
  3384. var complete = 0;
  3385. var hasCompleted = false;
  3386.  
  3387. const intervalDuration = (1000 / 30);
  3388. const animationsLength = animations.length;
  3389. const propertyUnit = {opacity: ""};
  3390. const defaultUnit = "px";
  3391.  
  3392. function cubicInOut(t, b, c, d)
  3393. {
  3394. if ((t/=d/2) < 1) return c/2*t*t*t + b;
  3395. return c/2*((t-=2)*t*t + 2) + b;
  3396. }
  3397.  
  3398.  
  3399. for (var i = 0; i < animationsLength; ++i) {
  3400. var animation = animations[i];
  3401. var element = null, start = null, end = null, key = null;
  3402. for (key in animation) {
  3403. if (key === "element")
  3404. element = animation[key];
  3405. else if (key === "start")
  3406. start = animation[key];
  3407. else if (key === "end")
  3408. end = animation[key];
  3409. }
  3410.  
  3411. if (!element || !end)
  3412. continue;
  3413.  
  3414. if (!start) {
  3415. var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
  3416. start = {};
  3417. for (key in end)
  3418. start[key] = parseInt(computedStyle.getPropertyValue(key), 10);
  3419. animation.start = start;
  3420. } else
  3421. for (key in start)
  3422. element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
  3423. }
  3424.  
  3425. function animateLoop()
  3426. {
  3427. if (hasCompleted)
  3428. return;
  3429.  
  3430.  
  3431. complete += intervalDuration;
  3432. var next = complete + intervalDuration;
  3433.  
  3434.  
  3435. for (var i = 0; i < animationsLength; ++i) {
  3436. var animation = animations[i];
  3437. var element = animation.element;
  3438. var start = animation.start;
  3439. var end = animation.end;
  3440. if (!element || !end)
  3441. continue;
  3442.  
  3443. var style = element.style;
  3444. for (key in end) {
  3445. var endValue = end[key];
  3446. if (next < duration) {
  3447. var startValue = start[key];
  3448. var newValue = cubicInOut(complete, startValue, endValue - startValue, duration);
  3449. style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
  3450. } else
  3451. style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
  3452. }
  3453. }
  3454.  
  3455.  
  3456. if (complete >= duration) {
  3457. hasCompleted = true;
  3458. clearInterval(interval);
  3459. if (callback)
  3460. callback();
  3461. }
  3462. }
  3463.  
  3464. function forceComplete()
  3465. {
  3466. if (hasCompleted)
  3467. return;
  3468.  
  3469. complete = duration;
  3470. animateLoop();
  3471. }
  3472.  
  3473. function cancel()
  3474. {
  3475. hasCompleted = true;
  3476. clearInterval(interval);
  3477. }
  3478.  
  3479. interval = setInterval(animateLoop, intervalDuration);
  3480. return {
  3481. cancel: cancel,
  3482. forceComplete: forceComplete
  3483. };
  3484. }
  3485.  
  3486. WebInspector.isBeingEdited = function(element)
  3487. {
  3488. if (element.hasStyleClass("text-prompt") || element.nodeName === "INPUT")
  3489. return true;
  3490.  
  3491. if (!WebInspector.__editingCount)
  3492. return false;
  3493.  
  3494. while (element) {
  3495. if (element.__editing)
  3496. return true;
  3497. element = element.parentElement;
  3498. }
  3499. return false;
  3500. }
  3501.  
  3502. WebInspector.markBeingEdited = function(element, value)
  3503. {
  3504. if (value) {
  3505. if (element.__editing)
  3506. return false;
  3507. element.__editing = true;
  3508. WebInspector.__editingCount = (WebInspector.__editingCount || 0) + 1;
  3509. } else {
  3510. if (!element.__editing)
  3511. return false;
  3512. delete element.__editing;
  3513. --WebInspector.__editingCount;
  3514. }
  3515. return true;
  3516. }
  3517.  
  3518.  
  3519. WebInspector.EditingConfig = function(commitHandler, cancelHandler, context)
  3520. {
  3521. this.commitHandler = commitHandler;
  3522. this.cancelHandler = cancelHandler
  3523. this.context = context;
  3524.  
  3525.  
  3526. this.pasteHandler;
  3527.  
  3528.  
  3529. this.multiline;
  3530.  
  3531.  
  3532. this.customFinishHandler;
  3533. }
  3534.  
  3535. WebInspector.EditingConfig.prototype = {
  3536. setPasteHandler: function(pasteHandler)
  3537. {
  3538. this.pasteHandler = pasteHandler;
  3539. },
  3540.  
  3541. setMultiline: function(multiline)
  3542. {
  3543. this.multiline = multiline;
  3544. },
  3545.  
  3546. setCustomFinishHandler: function(customFinishHandler)
  3547. {
  3548. this.customFinishHandler = customFinishHandler;
  3549. }
  3550. }
  3551.  
  3552.  
  3553. WebInspector.startEditing = function(element, config)
  3554. {
  3555. if (!WebInspector.markBeingEdited(element, true))
  3556. return null;
  3557.  
  3558. config = config || new WebInspector.EditingConfig(function() {}, function() {});
  3559. var committedCallback = config.commitHandler;
  3560. var cancelledCallback = config.cancelHandler;
  3561. var pasteCallback = config.pasteHandler;
  3562. var context = config.context;
  3563. var oldText = getContent(element);
  3564. var moveDirection = "";
  3565.  
  3566. element.addStyleClass("editing");
  3567.  
  3568. var oldTabIndex = element.getAttribute("tabIndex");
  3569. if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
  3570. element.tabIndex = 0;
  3571.  
  3572. function blurEventListener() {
  3573. editingCommitted.call(element);
  3574. }
  3575.  
  3576. function getContent(element) {
  3577. if (element.tagName === "INPUT" && element.type === "text")
  3578. return element.value;
  3579. else
  3580. return element.textContent;
  3581. }
  3582.  
  3583.  
  3584. function cleanUpAfterEditing()
  3585. {
  3586. WebInspector.markBeingEdited(element, false);
  3587.  
  3588. this.removeStyleClass("editing");
  3589.  
  3590. if (typeof oldTabIndex !== "number")
  3591. element.removeAttribute("tabIndex");
  3592. else
  3593. this.tabIndex = oldTabIndex;
  3594. this.scrollTop = 0;
  3595. this.scrollLeft = 0;
  3596.  
  3597. element.removeEventListener("blur", blurEventListener, false);
  3598. element.removeEventListener("keydown", keyDownEventListener, true);
  3599. if (pasteCallback)
  3600. element.removeEventListener("paste", pasteEventListener, true);
  3601.  
  3602. WebInspector.restoreFocusFromElement(element);
  3603. }
  3604.  
  3605.  
  3606. function editingCancelled()
  3607. {
  3608. if (this.tagName === "INPUT" && this.type === "text")
  3609. this.value = oldText;
  3610. else
  3611. this.textContent = oldText;
  3612.  
  3613. cleanUpAfterEditing.call(this);
  3614.  
  3615. cancelledCallback(this, context);
  3616. }
  3617.  
  3618.  
  3619. function editingCommitted()
  3620. {
  3621. cleanUpAfterEditing.call(this);
  3622.  
  3623. committedCallback(this, getContent(this), oldText, context, moveDirection);
  3624. }
  3625.  
  3626. function defaultFinishHandler(event)
  3627. {
  3628. var isMetaOrCtrl = WebInspector.isMac() ?
  3629. event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
  3630. event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
  3631. if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
  3632. return "commit";
  3633. else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
  3634. return "cancel";
  3635. else if (event.keyIdentifier === "U+0009")
  3636. return "move-" + (event.shiftKey ? "backward" : "forward");
  3637. }
  3638.  
  3639. function handleEditingResult(result, event)
  3640. {
  3641. if (result === "commit") {
  3642. editingCommitted.call(element);
  3643. event.consume(true);
  3644. } else if (result === "cancel") {
  3645. editingCancelled.call(element);
  3646. event.consume(true);
  3647. } else if (result && result.indexOf("move-") === 0) {
  3648. moveDirection = result.substring(5);
  3649. if (event.keyIdentifier !== "U+0009")
  3650. blurEventListener();
  3651. }
  3652. }
  3653.  
  3654. function pasteEventListener(event)
  3655. {
  3656. var result = pasteCallback(event);
  3657. handleEditingResult(result, event);
  3658. }
  3659.  
  3660. function keyDownEventListener(event)
  3661. {
  3662. var handler = config.customFinishHandler || defaultFinishHandler;
  3663. var result = handler(event);
  3664. handleEditingResult(result, event);
  3665. }
  3666.  
  3667. element.addEventListener("blur", blurEventListener, false);
  3668. element.addEventListener("keydown", keyDownEventListener, true);
  3669. if (pasteCallback)
  3670. element.addEventListener("paste", pasteEventListener, true);
  3671.  
  3672. WebInspector.setCurrentFocusElement(element);
  3673. return {
  3674. cancel: editingCancelled.bind(element),
  3675. commit: editingCommitted.bind(element)
  3676. };
  3677. }
  3678.  
  3679.  
  3680. Number.secondsToString = function(seconds, higherResolution)
  3681. {
  3682. if (seconds === 0)
  3683. return "0";
  3684.  
  3685. var ms = seconds * 1000;
  3686. if (higherResolution && ms < 1000)
  3687. return WebInspector.UIString("%.3fms", ms);
  3688. else if (ms < 1000)
  3689. return WebInspector.UIString("%.0fms", ms);
  3690.  
  3691. if (seconds < 60)
  3692. return WebInspector.UIString("%.2fs", seconds);
  3693.  
  3694. var minutes = seconds / 60;
  3695. if (minutes < 60)
  3696. return WebInspector.UIString("%.1fmin", minutes);
  3697.  
  3698. var hours = minutes / 60;
  3699. if (hours < 24)
  3700. return WebInspector.UIString("%.1fhrs", hours);
  3701.  
  3702. var days = hours / 24;
  3703. return WebInspector.UIString("%.1f days", days);
  3704. }
  3705.  
  3706.  
  3707. Number.bytesToString = function(bytes, higherResolution)
  3708. {
  3709. if (typeof higherResolution === "undefined")
  3710. higherResolution = true;
  3711.  
  3712. if (bytes < 1024)
  3713. return WebInspector.UIString("%.0fB", bytes);
  3714.  
  3715. var kilobytes = bytes / 1024;
  3716. if (higherResolution && kilobytes < 1024)
  3717. return WebInspector.UIString("%.2fKB", kilobytes);
  3718. else if (kilobytes < 1024)
  3719. return WebInspector.UIString("%.0fKB", kilobytes);
  3720.  
  3721. var megabytes = kilobytes / 1024;
  3722. if (higherResolution)
  3723. return WebInspector.UIString("%.2fMB", megabytes);
  3724. else
  3725. return WebInspector.UIString("%.0fMB", megabytes);
  3726. }
  3727.  
  3728. Number.withThousandsSeparator = function(num)
  3729. {
  3730. var str = num + "";
  3731. var re = /(\d+)(\d{3})/;
  3732. while (str.match(re))
  3733. str = str.replace(re, "$1\u2009$2");
  3734. return str;
  3735. }
  3736.  
  3737. WebInspector._missingLocalizedStrings = {};
  3738.  
  3739.  
  3740. WebInspector.UIString = function(string, vararg)
  3741. {
  3742. if (Preferences.localizeUI) {
  3743. if (window.localizedStrings && string in window.localizedStrings)
  3744. string = window.localizedStrings[string];
  3745. else {
  3746. if (!(string in WebInspector._missingLocalizedStrings)) {
  3747. console.warn("Localized string \"" + string + "\" not found.");
  3748. WebInspector._missingLocalizedStrings[string] = true;
  3749. }
  3750.  
  3751. if (Preferences.showMissingLocalizedStrings)
  3752. string += " (not localized)";
  3753. }
  3754. }
  3755. return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
  3756. }
  3757.  
  3758. WebInspector.useLowerCaseMenuTitles = function()
  3759. {
  3760. return WebInspector.platform() === "windows" && Preferences.useLowerCaseMenuTitlesOnWindows;
  3761. }
  3762.  
  3763. WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append)
  3764. {
  3765. return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append);
  3766. }
  3767.  
  3768. WebInspector.openLinkExternallyLabel = function()
  3769. {
  3770. return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in new tab" : "Open Link in New Tab");
  3771. }
  3772.  
  3773. WebInspector.openInNetworkPanelLabel = function()
  3774. {
  3775. return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open in network panel" : "Open in Network Panel");
  3776. }
  3777.  
  3778. WebInspector.copyLinkAddressLabel = function()
  3779. {
  3780. return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy link address" : "Copy Link Address");
  3781. }
  3782.  
  3783. WebInspector.platform = function()
  3784. {
  3785. if (!WebInspector._platform)
  3786. WebInspector._platform = InspectorFrontendHost.platform();
  3787. return WebInspector._platform;
  3788. }
  3789.  
  3790. WebInspector.isMac = function()
  3791. {
  3792. if (typeof WebInspector._isMac === "undefined")
  3793. WebInspector._isMac = WebInspector.platform() === "mac";
  3794.  
  3795. return WebInspector._isMac;
  3796. }
  3797.  
  3798. WebInspector.PlatformFlavor = {
  3799. WindowsVista: "windows-vista",
  3800. MacTiger: "mac-tiger",
  3801. MacLeopard: "mac-leopard",
  3802. MacSnowLeopard: "mac-snowleopard"
  3803. }
  3804.  
  3805. WebInspector.platformFlavor = function()
  3806. {
  3807. function detectFlavor()
  3808. {
  3809. const userAgent = navigator.userAgent;
  3810.  
  3811. if (WebInspector.platform() === "windows") {
  3812. var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
  3813. if (match && match[1] >= 6)
  3814. return WebInspector.PlatformFlavor.WindowsVista;
  3815. return null;
  3816. } else if (WebInspector.platform() === "mac") {
  3817. var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/);
  3818. if (!match || match[1] != 10)
  3819. return WebInspector.PlatformFlavor.MacSnowLeopard;
  3820. switch (Number(match[2])) {
  3821. case 4:
  3822. return WebInspector.PlatformFlavor.MacTiger;
  3823. case 5:
  3824. return WebInspector.PlatformFlavor.MacLeopard;
  3825. case 6:
  3826. default:
  3827. return WebInspector.PlatformFlavor.MacSnowLeopard;
  3828. }
  3829. }
  3830. }
  3831.  
  3832. if (!WebInspector._platformFlavor)
  3833. WebInspector._platformFlavor = detectFlavor();
  3834.  
  3835. return WebInspector._platformFlavor;
  3836. }
  3837.  
  3838. WebInspector.port = function()
  3839. {
  3840. if (!WebInspector._port)
  3841. WebInspector._port = InspectorFrontendHost.port();
  3842.  
  3843. return WebInspector._port;
  3844. }
  3845.  
  3846. WebInspector.installPortStyles = function()
  3847. {
  3848. var platform = WebInspector.platform();
  3849. document.body.addStyleClass("platform-" + platform);
  3850. var flavor = WebInspector.platformFlavor();
  3851. if (flavor)
  3852. document.body.addStyleClass("platform-" + flavor);
  3853. var port = WebInspector.port();
  3854. document.body.addStyleClass("port-" + port);
  3855. }
  3856.  
  3857. WebInspector._windowFocused = function(event)
  3858. {
  3859. if (event.target.document.nodeType === Node.DOCUMENT_NODE)
  3860. document.body.removeStyleClass("inactive");
  3861. }
  3862.  
  3863. WebInspector._windowBlurred = function(event)
  3864. {
  3865. if (event.target.document.nodeType === Node.DOCUMENT_NODE)
  3866. document.body.addStyleClass("inactive");
  3867. }
  3868.  
  3869. WebInspector.previousFocusElement = function()
  3870. {
  3871. return WebInspector._previousFocusElement;
  3872. }
  3873.  
  3874. WebInspector.currentFocusElement = function()
  3875. {
  3876. return WebInspector._currentFocusElement;
  3877. }
  3878.  
  3879. WebInspector._focusChanged = function(event)
  3880. {
  3881. WebInspector.setCurrentFocusElement(event.target);
  3882. }
  3883.  
  3884. WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet();
  3885. WebInspector._isTextEditingElement = function(element)
  3886. {
  3887. if (element instanceof HTMLInputElement)
  3888. return element.type in WebInspector._textInputTypes;
  3889.  
  3890. if (element instanceof HTMLTextAreaElement)
  3891. return true;
  3892.  
  3893. return false;
  3894. }
  3895.  
  3896. WebInspector.setCurrentFocusElement = function(x)
  3897. {
  3898. if (WebInspector._currentFocusElement !== x)
  3899. WebInspector._previousFocusElement = WebInspector._currentFocusElement;
  3900. WebInspector._currentFocusElement = x;
  3901.  
  3902. if (WebInspector._currentFocusElement) {
  3903. WebInspector._currentFocusElement.focus();
  3904.  
  3905.  
  3906.  
  3907.  
  3908. var selection = window.getSelection();
  3909. if (!WebInspector._isTextEditingElement(WebInspector._currentFocusElement) && selection.isCollapsed && !WebInspector._currentFocusElement.isInsertionCaretInside()) {
  3910. var selectionRange = WebInspector._currentFocusElement.ownerDocument.createRange();
  3911. selectionRange.setStart(WebInspector._currentFocusElement, 0);
  3912. selectionRange.setEnd(WebInspector._currentFocusElement, 0);
  3913.  
  3914. selection.removeAllRanges();
  3915. selection.addRange(selectionRange);
  3916. }
  3917. } else if (WebInspector._previousFocusElement)
  3918. WebInspector._previousFocusElement.blur();
  3919. }
  3920.  
  3921. WebInspector.restoreFocusFromElement = function(element)
  3922. {
  3923. if (element && element.isSelfOrAncestor(WebInspector.currentFocusElement()))
  3924. WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
  3925. }
  3926.  
  3927. WebInspector.setToolbarColors = function(backgroundColor, color)
  3928. {
  3929. if (!WebInspector._themeStyleElement) {
  3930. WebInspector._themeStyleElement = document.createElement("style");
  3931. document.head.appendChild(WebInspector._themeStyleElement);
  3932. }
  3933. WebInspector._themeStyleElement.textContent =
  3934. "#toolbar {\
  3935. background-image: none !important;\
  3936. background-color: " + backgroundColor + " !important;\
  3937. }\
  3938. \
  3939. .toolbar-label {\
  3940. color: " + color + " !important;\
  3941. text-shadow: none;\
  3942. }";
  3943. }
  3944.  
  3945. WebInspector.resetToolbarColors = function()
  3946. {
  3947. if (WebInspector._themeStyleElement)
  3948. WebInspector._themeStyleElement.textContent = "";
  3949. }
  3950.  
  3951.  
  3952. WebInspector.populateHrefContextMenu = function(contextMenu, contextNode, event)
  3953. {
  3954. var anchorElement = event.target.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || event.target.enclosingNodeOrSelfWithClass("webkit-html-external-link");
  3955. if (!anchorElement)
  3956. return false;
  3957.  
  3958. var resourceURL = WebInspector.resourceURLForRelatedNode(contextNode, anchorElement.href);
  3959. if (!resourceURL)
  3960. return false;
  3961.  
  3962.  
  3963. contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, resourceURL, false));
  3964. if (WebInspector.resourceForURL(resourceURL))
  3965. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in Resources panel" : "Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true));
  3966. contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL));
  3967. return true;
  3968. }
  3969.  
  3970. ;(function() {
  3971.  
  3972. function windowLoaded()
  3973. {
  3974. window.addEventListener("focus", WebInspector._windowFocused, false);
  3975. window.addEventListener("blur", WebInspector._windowBlurred, false);
  3976. document.addEventListener("focus", WebInspector._focusChanged.bind(this), true);
  3977. window.removeEventListener("DOMContentLoaded", windowLoaded, false);
  3978. }
  3979.  
  3980. window.addEventListener("DOMContentLoaded", windowLoaded, false);
  3981.  
  3982. })();
  3983.  
  3984.  
  3985.  
  3986.  
  3987.  
  3988.  
  3989. function InspectorBackendClass()
  3990. {
  3991. this._lastCallbackId = 1;
  3992. this._pendingResponsesCount = 0;
  3993. this._callbacks = {};
  3994. this._domainDispatchers = {};
  3995. this._eventArgs = {};
  3996. this._replyArgs = {};
  3997.  
  3998. this.dumpInspectorTimeStats = false;
  3999. this.dumpInspectorProtocolMessages = false;
  4000. this._initialized = false;
  4001. }
  4002.  
  4003. InspectorBackendClass.prototype = {
  4004. _wrap: function(callback, method)
  4005. {
  4006. var callbackId = this._lastCallbackId++;
  4007. if (!callback)
  4008. callback = function() {};
  4009.  
  4010. this._callbacks[callbackId] = callback;
  4011. callback.methodName = method;
  4012. if (this.dumpInspectorTimeStats)
  4013. callback.sendRequestTime = Date.now();
  4014.  
  4015. return callbackId;
  4016. },
  4017.  
  4018. registerCommand: function(method, signature, replyArgs)
  4019. {
  4020. var domainAndMethod = method.split(".");
  4021. var agentName = domainAndMethod[0] + "Agent";
  4022. if (!window[agentName])
  4023. window[agentName] = {};
  4024.  
  4025. window[agentName][domainAndMethod[1]] = this._sendMessageToBackend.bind(this, method, signature);
  4026. window[agentName][domainAndMethod[1]]["invoke"] = this._invoke.bind(this, method, signature);
  4027. this._replyArgs[method] = replyArgs;
  4028.  
  4029. this._initialized = true;
  4030. },
  4031.  
  4032. registerEvent: function(eventName, params)
  4033. {
  4034. this._eventArgs[eventName] = params;
  4035.  
  4036. this._initialized = true;
  4037. },
  4038.  
  4039. _invoke: function(method, signature, args, callback)
  4040. {
  4041. this._wrapCallbackAndSendMessageObject(method, args, callback);
  4042. },
  4043.  
  4044. _sendMessageToBackend: function(method, signature, vararg)
  4045. {
  4046. var args = Array.prototype.slice.call(arguments, 2);
  4047. var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : null;
  4048.  
  4049. var params = {};
  4050. var hasParams = false;
  4051. for (var i = 0; i < signature.length; ++i) {
  4052. var param = signature[i];
  4053. var paramName = param["name"];
  4054. var typeName = param["type"];
  4055. var optionalFlag = param["optional"];
  4056.  
  4057. if (!args.length && !optionalFlag) {
  4058. console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
  4059. return;
  4060. }
  4061.  
  4062. var value = args.shift();
  4063. if (optionalFlag && typeof value === "undefined") {
  4064. continue;
  4065. }
  4066.  
  4067. if (typeof value !== typeName) {
  4068. console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
  4069. return;
  4070. }
  4071.  
  4072. params[paramName] = value;
  4073. hasParams = true;
  4074. }
  4075.  
  4076. if (args.length === 1 && !callback) {
  4077. if (typeof args[0] !== "undefined") {
  4078. console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
  4079. return;
  4080. }
  4081. }
  4082.  
  4083. this._wrapCallbackAndSendMessageObject(method, hasParams ? params : null, callback);
  4084. },
  4085.  
  4086. _wrapCallbackAndSendMessageObject: function(method, params, callback)
  4087. {
  4088. var messageObject = {};
  4089. messageObject.method = method;
  4090. if (params)
  4091. messageObject.params = params;
  4092. messageObject.id = this._wrap(callback, method);
  4093.  
  4094. if (this.dumpInspectorProtocolMessages)
  4095. console.log("frontend: " + JSON.stringify(messageObject));
  4096.  
  4097. ++this._pendingResponsesCount;
  4098. this.sendMessageObjectToBackend(messageObject);
  4099. },
  4100.  
  4101. sendMessageObjectToBackend: function(messageObject)
  4102. {
  4103. var message = JSON.stringify(messageObject);
  4104. InspectorFrontendHost.sendMessageToBackend(message);
  4105. },
  4106.  
  4107. registerDomainDispatcher: function(domain, dispatcher)
  4108. {
  4109. this._domainDispatchers[domain] = dispatcher;
  4110. },
  4111.  
  4112. dispatch: function(message)
  4113. {
  4114. if (this.dumpInspectorProtocolMessages)
  4115. console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
  4116.  
  4117. var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
  4118.  
  4119. if ("id" in messageObject) {
  4120. if (messageObject.error) {
  4121. messageObject.error.__proto__ = {
  4122. getDescription: function()
  4123. {
  4124. switch(this.code) {
  4125. case -32700: return "Parse error";
  4126. case -32600: return "Invalid Request";
  4127. case -32601: return "Method not found";
  4128. case -32602: return "Invalid params";
  4129. case -32603: return "Internal error";;
  4130. case -32000: return "Server error";
  4131. }
  4132. },
  4133.  
  4134. toString: function()
  4135. {
  4136. var description ="Unknown error code";
  4137. return this.getDescription() + "(" + this.code + "): " + this.message + "." + (this.data ? " " + this.data.join(" ") : "");
  4138. },
  4139.  
  4140. getMessage: function()
  4141. {
  4142. return this.message;
  4143. }
  4144. }
  4145.  
  4146. if (messageObject.error.code !== -32000)
  4147. this.reportProtocolError(messageObject);
  4148. }
  4149.  
  4150. var callback = this._callbacks[messageObject.id];
  4151. if (callback) {
  4152. var argumentsArray = [];
  4153. if (messageObject.result) {
  4154. var paramNames = this._replyArgs[callback.methodName];
  4155. if (paramNames) {
  4156. for (var i = 0; i < paramNames.length; ++i)
  4157. argumentsArray.push(messageObject.result[paramNames[i]]);
  4158. }
  4159. }
  4160.  
  4161. var processingStartTime;
  4162. if (this.dumpInspectorTimeStats && callback.methodName)
  4163. processingStartTime = Date.now();
  4164.  
  4165. argumentsArray.unshift(messageObject.error);
  4166. callback.apply(null, argumentsArray);
  4167. --this._pendingResponsesCount;
  4168. delete this._callbacks[messageObject.id];
  4169.  
  4170. if (this.dumpInspectorTimeStats && callback.methodName)
  4171. console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
  4172. }
  4173.  
  4174. if (this._scripts && !this._pendingResponsesCount)
  4175. this.runAfterPendingDispatches();
  4176.  
  4177. return;
  4178. } else {
  4179. var method = messageObject.method.split(".");
  4180. var domainName = method[0];
  4181. var functionName = method[1];
  4182. if (!(domainName in this._domainDispatchers)) {
  4183. console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
  4184. return;
  4185. }
  4186. var dispatcher = this._domainDispatchers[domainName];
  4187. if (!(functionName in dispatcher)) {
  4188. console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
  4189. return;
  4190. }
  4191.  
  4192. if (!this._eventArgs[messageObject.method]) {
  4193. console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
  4194. return;
  4195. }
  4196.  
  4197. var params = [];
  4198. if (messageObject.params) {
  4199. var paramNames = this._eventArgs[messageObject.method];
  4200. for (var i = 0; i < paramNames.length; ++i)
  4201. params.push(messageObject.params[paramNames[i]]);
  4202. }
  4203.  
  4204. var processingStartTime;
  4205. if (this.dumpInspectorTimeStats)
  4206. processingStartTime = Date.now();
  4207.  
  4208. dispatcher[functionName].apply(dispatcher, params);
  4209.  
  4210. if (this.dumpInspectorTimeStats)
  4211. console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
  4212. }
  4213. },
  4214.  
  4215. reportProtocolError: function(messageObject)
  4216. {
  4217. console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error);
  4218. },
  4219.  
  4220.  
  4221. runAfterPendingDispatches: function(script)
  4222. {
  4223. if (!this._scripts)
  4224. this._scripts = [];
  4225.  
  4226. if (script)
  4227. this._scripts.push(script);
  4228.  
  4229. if (!this._pendingResponsesCount) {
  4230. var scripts = this._scripts;
  4231. this._scripts = []
  4232. for (var id = 0; id < scripts.length; ++id)
  4233. scripts[id].call(this);
  4234. }
  4235. },
  4236.  
  4237. loadFromJSONIfNeeded: function()
  4238. {
  4239. if (this._initialized)
  4240. return;
  4241.  
  4242. var xhr = new XMLHttpRequest();
  4243. xhr.open("GET", "../Inspector.json", false);
  4244. xhr.send(null);
  4245.  
  4246. var schema = JSON.parse(xhr.responseText);
  4247. var jsTypes = { integer: "number", array: "object" };
  4248. var rawTypes = {};
  4249.  
  4250. var domains = schema["domains"];
  4251. for (var i = 0; i < domains.length; ++i) {
  4252. var domain = domains[i];
  4253. for (var j = 0; domain.types && j < domain.types.length; ++j) {
  4254. var type = domain.types[j];
  4255. rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type;
  4256. }
  4257. }
  4258.  
  4259. var result = [];
  4260. for (var i = 0; i < domains.length; ++i) {
  4261. var domain = domains[i];
  4262.  
  4263. var commands = domain["commands"] || [];
  4264. for (var j = 0; j < commands.length; ++j) {
  4265. var command = commands[j];
  4266. var parameters = command["parameters"];
  4267. var paramsText = [];
  4268. for (var k = 0; parameters && k < parameters.length; ++k) {
  4269. var parameter = parameters[k];
  4270.  
  4271. var type;
  4272. if (parameter.type)
  4273. type = jsTypes[parameter.type] || parameter.type;
  4274. else {
  4275. var ref = parameter["$ref"];
  4276. if (ref.indexOf(".") !== -1)
  4277. type = rawTypes[ref];
  4278. else
  4279. type = rawTypes[domain.domain + "." + ref];
  4280. }
  4281.  
  4282. var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}";
  4283. paramsText.push(text);
  4284. }
  4285.  
  4286. var returnsText = [];
  4287. var returns = command["returns"] || [];
  4288. for (var k = 0; k < returns.length; ++k) {
  4289. var parameter = returns[k];
  4290. returnsText.push("\"" + parameter.name + "\"");
  4291. }
  4292. result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "]);");
  4293. }
  4294.  
  4295. for (var j = 0; domain.events && j < domain.events.length; ++j) {
  4296. var event = domain.events[j];
  4297. var paramsText = [];
  4298. for (var k = 0; event.parameters && k < event.parameters.length; ++k) {
  4299. var parameter = event.parameters[k];
  4300. paramsText.push("\"" + parameter.name + "\"");
  4301. }
  4302. result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);");
  4303. }
  4304.  
  4305. result.push("InspectorBackend.register" + domain.domain + "Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"" + domain.domain + "\");");
  4306. }
  4307. eval(result.join("\n"));
  4308. }
  4309. }
  4310.  
  4311. InspectorBackend = new InspectorBackendClass();
  4312.  
  4313.  
  4314.  
  4315.  
  4316.  
  4317.  
  4318.  
  4319.  
  4320.  
  4321.  
  4322.  
  4323. InspectorBackend.registerInspectorDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Inspector");
  4324. InspectorBackend.registerEvent("Inspector.evaluateForTestInFrontend", ["testCallId", "script"]);
  4325. InspectorBackend.registerEvent("Inspector.inspect", ["object", "hints"]);
  4326. InspectorBackend.registerEvent("Inspector.didCreateWorker", ["id", "url", "isShared"]);
  4327. InspectorBackend.registerEvent("Inspector.didDestroyWorker", ["id"]);
  4328. InspectorBackend.registerCommand("Inspector.enable", [], []);
  4329. InspectorBackend.registerCommand("Inspector.disable", [], []);
  4330.  
  4331.  
  4332. InspectorBackend.registerMemoryDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Memory");
  4333. InspectorBackend.registerCommand("Memory.getDOMNodeCount", [], ["domGroups", "strings"]);
  4334.  
  4335.  
  4336. InspectorBackend.registerPageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Page");
  4337. InspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]);
  4338. InspectorBackend.registerEvent("Page.loadEventFired", ["timestamp"]);
  4339. InspectorBackend.registerEvent("Page.frameNavigated", ["frame"]);
  4340. InspectorBackend.registerEvent("Page.frameDetached", ["frameId"]);
  4341. InspectorBackend.registerCommand("Page.enable", [], []);
  4342. InspectorBackend.registerCommand("Page.disable", [], []);
  4343. InspectorBackend.registerCommand("Page.addScriptToEvaluateOnLoad", [{"name": "scriptSource", "type": "string", "optional": false}], ["identifier"]);
  4344. InspectorBackend.registerCommand("Page.removeScriptToEvaluateOnLoad", [{"name": "identifier", "type": "string", "optional": false}], []);
  4345. InspectorBackend.registerCommand("Page.reload", [{"name": "ignoreCache", "type": "boolean", "optional": true}, {"name": "scriptToEvaluateOnLoad", "type": "string", "optional": true}], []);
  4346. InspectorBackend.registerCommand("Page.navigate", [{"name": "url", "type": "string", "optional": false}], []);
  4347. InspectorBackend.registerCommand("Page.getCookies", [], ["cookies", "cookiesString"]);
  4348. InspectorBackend.registerCommand("Page.deleteCookie", [{"name": "cookieName", "type": "string", "optional": false}, {"name": "domain", "type": "string", "optional": false}], []);
  4349. InspectorBackend.registerCommand("Page.getResourceTree", [], ["frameTree"]);
  4350. InspectorBackend.registerCommand("Page.getResourceContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], ["content", "base64Encoded"]);
  4351. InspectorBackend.registerCommand("Page.searchInResource", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
  4352. InspectorBackend.registerCommand("Page.searchInResources", [{"name": "text", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
  4353. InspectorBackend.registerCommand("Page.setDocumentContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "html", "type": "string", "optional": false}], []);
  4354. InspectorBackend.registerCommand("Page.canOverrideDeviceMetrics", [], ["result"]);
  4355. InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "fontScaleFactor", "type": "number", "optional": false}], []);
  4356. InspectorBackend.registerCommand("Page.setShowPaintRects", [{"name": "result", "type": "boolean", "optional": false}], []);
  4357.  
  4358.  
  4359. InspectorBackend.registerCommand("Runtime.evaluate", [{"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptions", "type": "boolean", "optional": true}, {"name": "frameId", "type": "string", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
  4360. InspectorBackend.registerCommand("Runtime.callFunctionOn", [{"name": "objectId", "type": "string", "optional": false}, {"name": "functionDeclaration", "type": "string", "optional": false}, {"name": "arguments", "type": "object", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
  4361. InspectorBackend.registerCommand("Runtime.getProperties", [{"name": "objectId", "type": "string", "optional": false}, {"name": "ownProperties", "type": "boolean", "optional": true}], ["result"]);
  4362. InspectorBackend.registerCommand("Runtime.releaseObject", [{"name": "objectId", "type": "string", "optional": false}], []);
  4363. InspectorBackend.registerCommand("Runtime.releaseObjectGroup", [{"name": "objectGroup", "type": "string", "optional": false}], []);
  4364. InspectorBackend.registerCommand("Runtime.run", [], []);
  4365.  
  4366.  
  4367. InspectorBackend.registerConsoleDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Console");
  4368. InspectorBackend.registerEvent("Console.messageAdded", ["message"]);
  4369. InspectorBackend.registerEvent("Console.messageRepeatCountUpdated", ["count"]);
  4370. InspectorBackend.registerEvent("Console.messagesCleared", []);
  4371. InspectorBackend.registerCommand("Console.enable", [], []);
  4372. InspectorBackend.registerCommand("Console.disable", [], []);
  4373. InspectorBackend.registerCommand("Console.clearMessages", [], []);
  4374. InspectorBackend.registerCommand("Console.setMonitoringXHREnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
  4375. InspectorBackend.registerCommand("Console.addInspectedNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
  4376. InspectorBackend.registerCommand("Console.addInspectedHeapObject", [{"name": "heapObjectId", "type": "number", "optional": false}], []);
  4377.  
  4378.  
  4379. InspectorBackend.registerNetworkDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Network");
  4380. InspectorBackend.registerEvent("Network.requestWillBeSent", ["requestId", "frameId", "loaderId", "documentURL", "request", "timestamp", "initiator", "stackTrace", "redirectResponse"]);
  4381. InspectorBackend.registerEvent("Network.requestServedFromCache", ["requestId"]);
  4382. InspectorBackend.registerEvent("Network.responseReceived", ["requestId", "frameId", "loaderId", "timestamp", "type", "response"]);
  4383. InspectorBackend.registerEvent("Network.dataReceived", ["requestId", "timestamp", "dataLength", "encodedDataLength"]);
  4384. InspectorBackend.registerEvent("Network.loadingFinished", ["requestId", "timestamp"]);
  4385. InspectorBackend.registerEvent("Network.loadingFailed", ["requestId", "timestamp", "errorText", "canceled"]);
  4386. InspectorBackend.registerEvent("Network.requestServedFromMemoryCache", ["requestId", "frameId", "loaderId", "documentURL", "timestamp", "initiator", "resource"]);
  4387. InspectorBackend.registerEvent("Network.webSocketWillSendHandshakeRequest", ["requestId", "timestamp", "request"]);
  4388. InspectorBackend.registerEvent("Network.webSocketHandshakeResponseReceived", ["requestId", "timestamp", "response"]);
  4389. InspectorBackend.registerEvent("Network.webSocketCreated", ["requestId", "url"]);
  4390. InspectorBackend.registerEvent("Network.webSocketClosed", ["requestId", "timestamp"]);
  4391. InspectorBackend.registerCommand("Network.enable", [], []);
  4392. InspectorBackend.registerCommand("Network.disable", [], []);
  4393. InspectorBackend.registerCommand("Network.setUserAgentOverride", [{"name": "userAgent", "type": "string", "optional": false}], []);
  4394. InspectorBackend.registerCommand("Network.setExtraHTTPHeaders", [{"name": "headers", "type": "object", "optional": false}], []);
  4395. InspectorBackend.registerCommand("Network.getResponseBody", [{"name": "requestId", "type": "string", "optional": false}], ["body", "base64Encoded"]);
  4396. InspectorBackend.registerCommand("Network.canClearBrowserCache", [], ["result"]);
  4397. InspectorBackend.registerCommand("Network.clearBrowserCache", [], []);
  4398. InspectorBackend.registerCommand("Network.canClearBrowserCookies", [], ["result"]);
  4399. InspectorBackend.registerCommand("Network.clearBrowserCookies", [], []);
  4400. InspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDisabled", "type": "boolean", "optional": false}], []);
  4401.  
  4402.  
  4403. InspectorBackend.registerDatabaseDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Database");
  4404. InspectorBackend.registerEvent("Database.addDatabase", ["database"]);
  4405. InspectorBackend.registerEvent("Database.sqlTransactionSucceeded", ["transactionId", "columnNames", "values"]);
  4406. InspectorBackend.registerEvent("Database.sqlTransactionFailed", ["transactionId", "sqlError"]);
  4407. InspectorBackend.registerCommand("Database.enable", [], []);
  4408. InspectorBackend.registerCommand("Database.disable", [], []);
  4409. InspectorBackend.registerCommand("Database.getDatabaseTableNames", [{"name": "databaseId", "type": "string", "optional": false}], ["tableNames"]);
  4410. InspectorBackend.registerCommand("Database.executeSQL", [{"name": "databaseId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["success", "transactionId"]);
  4411.  
  4412.  
  4413. InspectorBackend.registerIndexedDBDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "IndexedDB");
  4414. InspectorBackend.registerEvent("IndexedDB.databaseNamesLoaded", ["requestId", "securityOriginWithDatabaseNames"]);
  4415. InspectorBackend.registerEvent("IndexedDB.databaseLoaded", ["requestId", "databaseWithObjectStores"]);
  4416. InspectorBackend.registerEvent("IndexedDB.objectStoreDataLoaded", ["requestId", "objectStoreDataEntries", "hasMore"]);
  4417. InspectorBackend.registerEvent("IndexedDB.indexDataLoaded", ["requestId", "indexDataEntries", "hasMore"]);
  4418. InspectorBackend.registerCommand("IndexedDB.enable", [], []);
  4419. InspectorBackend.registerCommand("IndexedDB.disable", [], []);
  4420. InspectorBackend.registerCommand("IndexedDB.requestDatabaseNamesForFrame", [{"name": "requestId", "type": "number", "optional": false}, {"name": "frameId", "type": "string", "optional": false}], []);
  4421. InspectorBackend.registerCommand("IndexedDB.requestDatabase", [{"name": "requestId", "type": "number", "optional": false}, {"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}], []);
  4422. InspectorBackend.registerCommand("IndexedDB.requestData", [{"name": "requestId", "type": "number", "optional": false}, {"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}, {"name": "indexName", "type": "string", "optional": false}, {"name": "skipCount", "type": "number", "optional": false}, {"name": "pageSize", "type": "number", "optional": false}, {"name": "keyRange", "type": "object", "optional": true}], []);
  4423.  
  4424.  
  4425. InspectorBackend.registerDOMStorageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOMStorage");
  4426. InspectorBackend.registerEvent("DOMStorage.addDOMStorage", ["storage"]);
  4427. InspectorBackend.registerEvent("DOMStorage.updateDOMStorage", ["storageId"]);
  4428. InspectorBackend.registerCommand("DOMStorage.enable", [], []);
  4429. InspectorBackend.registerCommand("DOMStorage.disable", [], []);
  4430. InspectorBackend.registerCommand("DOMStorage.getDOMStorageEntries", [{"name": "storageId", "type": "string", "optional": false}], ["entries"]);
  4431. InspectorBackend.registerCommand("DOMStorage.setDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], ["success"]);
  4432. InspectorBackend.registerCommand("DOMStorage.removeDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}], ["success"]);
  4433.  
  4434.  
  4435. InspectorBackend.registerApplicationCacheDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "ApplicationCache");
  4436. InspectorBackend.registerEvent("ApplicationCache.applicationCacheStatusUpdated", ["frameId", "manifestURL", "status"]);
  4437. InspectorBackend.registerEvent("ApplicationCache.networkStateUpdated", ["isNowOnline"]);
  4438. InspectorBackend.registerCommand("ApplicationCache.getFramesWithManifests", [], ["frameIds"]);
  4439. InspectorBackend.registerCommand("ApplicationCache.enable", [], []);
  4440. InspectorBackend.registerCommand("ApplicationCache.getManifestForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["manifestURL"]);
  4441. InspectorBackend.registerCommand("ApplicationCache.getApplicationCacheForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["applicationCache"]);
  4442.  
  4443.  
  4444. InspectorBackend.registerFileSystemDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "FileSystem");
  4445. InspectorBackend.registerCommand("FileSystem.enable", [], []);
  4446. InspectorBackend.registerCommand("FileSystem.disable", [], []);
  4447.  
  4448.  
  4449. InspectorBackend.registerDOMDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOM");
  4450. InspectorBackend.registerEvent("DOM.documentUpdated", []);
  4451. InspectorBackend.registerEvent("DOM.setChildNodes", ["parentId", "nodes"]);
  4452. InspectorBackend.registerEvent("DOM.attributeModified", ["nodeId", "name", "value"]);
  4453. InspectorBackend.registerEvent("DOM.attributeRemoved", ["nodeId", "name"]);
  4454. InspectorBackend.registerEvent("DOM.inlineStyleInvalidated", ["nodeIds"]);
  4455. InspectorBackend.registerEvent("DOM.characterDataModified", ["nodeId", "characterData"]);
  4456. InspectorBackend.registerEvent("DOM.childNodeCountUpdated", ["nodeId", "childNodeCount"]);
  4457. InspectorBackend.registerEvent("DOM.childNodeInserted", ["parentNodeId", "previousNodeId", "node"]);
  4458. InspectorBackend.registerEvent("DOM.childNodeRemoved", ["parentNodeId", "nodeId"]);
  4459. InspectorBackend.registerEvent("DOM.shadowRootPushed", ["hostId", "root"]);
  4460. InspectorBackend.registerEvent("DOM.shadowRootPopped", ["hostId", "rootId"]);
  4461. InspectorBackend.registerCommand("DOM.getDocument", [], ["root"]);
  4462. InspectorBackend.registerCommand("DOM.requestChildNodes", [{"name": "nodeId", "type": "number", "optional": false}], []);
  4463. InspectorBackend.registerCommand("DOM.querySelector", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeId"]);
  4464. InspectorBackend.registerCommand("DOM.querySelectorAll", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeIds"]);
  4465. InspectorBackend.registerCommand("DOM.setNodeName", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], ["nodeId"]);
  4466. InspectorBackend.registerCommand("DOM.setNodeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
  4467. InspectorBackend.registerCommand("DOM.removeNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
  4468. InspectorBackend.registerCommand("DOM.setAttributeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
  4469. InspectorBackend.registerCommand("DOM.setAttributesAsText", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "name", "type": "string", "optional": true}], []);
  4470. InspectorBackend.registerCommand("DOM.removeAttribute", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], []);
  4471. InspectorBackend.registerCommand("DOM.getEventListenersForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["listeners"]);
  4472. InspectorBackend.registerCommand("DOM.getOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}], ["outerHTML"]);
  4473. InspectorBackend.registerCommand("DOM.setOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "outerHTML", "type": "string", "optional": false}], []);
  4474. InspectorBackend.registerCommand("DOM.performSearch", [{"name": "query", "type": "string", "optional": false}], ["searchId", "resultCount"]);
  4475. InspectorBackend.registerCommand("DOM.getSearchResults", [{"name": "searchId", "type": "string", "optional": false}, {"name": "fromIndex", "type": "number", "optional": false}, {"name": "toIndex", "type": "number", "optional": false}], ["nodeIds"]);
  4476. InspectorBackend.registerCommand("DOM.discardSearchResults", [{"name": "searchId", "type": "string", "optional": false}], []);
  4477. InspectorBackend.registerCommand("DOM.requestNode", [{"name": "objectId", "type": "string", "optional": false}], ["nodeId"]);
  4478. InspectorBackend.registerCommand("DOM.setInspectModeEnabled", [{"name": "enabled", "type": "boolean", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": true}], []);
  4479. InspectorBackend.registerCommand("DOM.highlightRect", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], []);
  4480. InspectorBackend.registerCommand("DOM.highlightNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": false}], []);
  4481. InspectorBackend.registerCommand("DOM.hideHighlight", [], []);
  4482. InspectorBackend.registerCommand("DOM.highlightFrame", [{"name": "frameId", "type": "string", "optional": false}, {"name": "contentColor", "type": "object", "optional": true}, {"name": "contentOutlineColor", "type": "object", "optional": true}], []);
  4483. InspectorBackend.registerCommand("DOM.pushNodeByPathToFrontend", [{"name": "path", "type": "string", "optional": false}], ["nodeId"]);
  4484. InspectorBackend.registerCommand("DOM.resolveNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["object"]);
  4485. InspectorBackend.registerCommand("DOM.getAttributes", [{"name": "nodeId", "type": "number", "optional": false}], ["attributes"]);
  4486. InspectorBackend.registerCommand("DOM.moveTo", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "targetNodeId", "type": "number", "optional": false}, {"name": "insertBeforeNodeId", "type": "number", "optional": true}], ["nodeId"]);
  4487. InspectorBackend.registerCommand("DOM.setTouchEmulationEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
  4488. InspectorBackend.registerCommand("DOM.undo", [], []);
  4489. InspectorBackend.registerCommand("DOM.redo", [], []);
  4490. InspectorBackend.registerCommand("DOM.markUndoableState", [], []);
  4491.  
  4492.  
  4493. InspectorBackend.registerCSSDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "CSS");
  4494. InspectorBackend.registerEvent("CSS.mediaQueryResultChanged", []);
  4495. InspectorBackend.registerEvent("CSS.styleSheetChanged", ["styleSheetId"]);
  4496. InspectorBackend.registerCommand("CSS.enable", [], []);
  4497. InspectorBackend.registerCommand("CSS.disable", [], []);
  4498. InspectorBackend.registerCommand("CSS.getMatchedStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "forcedPseudoClasses", "type": "object", "optional": true}, {"name": "includePseudo", "type": "boolean", "optional": true}, {"name": "includeInherited", "type": "boolean", "optional": true}], ["matchedCSSRules", "pseudoElements", "inherited"]);
  4499. InspectorBackend.registerCommand("CSS.getInlineStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["inlineStyle", "attributesStyle"]);
  4500. InspectorBackend.registerCommand("CSS.getComputedStyleForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "forcedPseudoClasses", "type": "object", "optional": true}], ["computedStyle"]);
  4501. InspectorBackend.registerCommand("CSS.getAllStyleSheets", [], ["headers"]);
  4502. InspectorBackend.registerCommand("CSS.getStyleSheet", [{"name": "styleSheetId", "type": "string", "optional": false}], ["styleSheet"]);
  4503. InspectorBackend.registerCommand("CSS.getStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}], ["text"]);
  4504. InspectorBackend.registerCommand("CSS.setStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "text", "type": "string", "optional": false}], []);
  4505. InspectorBackend.registerCommand("CSS.setPropertyText", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "overwrite", "type": "boolean", "optional": false}], ["style"]);
  4506. InspectorBackend.registerCommand("CSS.toggleProperty", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "disable", "type": "boolean", "optional": false}], ["style"]);
  4507. InspectorBackend.registerCommand("CSS.setRuleSelector", [{"name": "ruleId", "type": "object", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
  4508. InspectorBackend.registerCommand("CSS.addRule", [{"name": "contextNodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
  4509. InspectorBackend.registerCommand("CSS.getSupportedCSSProperties", [], ["cssProperties"]);
  4510. InspectorBackend.registerCommand("CSS.startSelectorProfiler", [], []);
  4511. InspectorBackend.registerCommand("CSS.stopSelectorProfiler", [], ["profile"]);
  4512.  
  4513.  
  4514. InspectorBackend.registerTimelineDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Timeline");
  4515. InspectorBackend.registerEvent("Timeline.eventRecorded", ["record"]);
  4516. InspectorBackend.registerCommand("Timeline.start", [{"name": "maxCallStackDepth", "type": "number", "optional": true}], []);
  4517. InspectorBackend.registerCommand("Timeline.stop", [], []);
  4518. InspectorBackend.registerCommand("Timeline.setIncludeMemoryDetails", [{"name": "enabled", "type": "boolean", "optional": false}], []);
  4519.  
  4520.  
  4521. InspectorBackend.registerDebuggerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Debugger");
  4522. InspectorBackend.registerEvent("Debugger.globalObjectCleared", []);
  4523. InspectorBackend.registerEvent("Debugger.scriptParsed", ["scriptId", "url", "startLine", "startColumn", "endLine", "endColumn", "isContentScript", "sourceMapURL"]);
  4524. InspectorBackend.registerEvent("Debugger.scriptFailedToParse", ["url", "scriptSource", "startLine", "errorLine", "errorMessage"]);
  4525. InspectorBackend.registerEvent("Debugger.breakpointResolved", ["breakpointId", "location"]);
  4526. InspectorBackend.registerEvent("Debugger.paused", ["callFrames", "reason", "data"]);
  4527. InspectorBackend.registerEvent("Debugger.resumed", []);
  4528. InspectorBackend.registerCommand("Debugger.causesRecompilation", [], ["result"]);
  4529. InspectorBackend.registerCommand("Debugger.supportsNativeBreakpoints", [], ["result"]);
  4530. InspectorBackend.registerCommand("Debugger.enable", [], []);
  4531. InspectorBackend.registerCommand("Debugger.disable", [], []);
  4532. InspectorBackend.registerCommand("Debugger.setBreakpointsActive", [{"name": "active", "type": "boolean", "optional": false}], []);
  4533. InspectorBackend.registerCommand("Debugger.setBreakpointByUrl", [{"name": "lineNumber", "type": "number", "optional": false}, {"name": "url", "type": "string", "optional": true}, {"name": "urlRegex", "type": "string", "optional": true}, {"name": "columnNumber", "type": "number", "optional": true}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "locations"]);
  4534. InspectorBackend.registerCommand("Debugger.setBreakpoint", [{"name": "location", "type": "object", "optional": false}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "actualLocation"]);
  4535. InspectorBackend.registerCommand("Debugger.removeBreakpoint", [{"name": "breakpointId", "type": "string", "optional": false}], []);
  4536. InspectorBackend.registerCommand("Debugger.continueToLocation", [{"name": "location", "type": "object", "optional": false}], []);
  4537. InspectorBackend.registerCommand("Debugger.stepOver", [], []);
  4538. InspectorBackend.registerCommand("Debugger.stepInto", [], []);
  4539. InspectorBackend.registerCommand("Debugger.stepOut", [], []);
  4540. InspectorBackend.registerCommand("Debugger.pause", [], []);
  4541. InspectorBackend.registerCommand("Debugger.resume", [], []);
  4542. InspectorBackend.registerCommand("Debugger.searchInContent", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
  4543. InspectorBackend.registerCommand("Debugger.canSetScriptSource", [], ["result"]);
  4544. InspectorBackend.registerCommand("Debugger.setScriptSource", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "scriptSource", "type": "string", "optional": false}, {"name": "preview", "type": "boolean", "optional": true}], ["callFrames", "result"]);
  4545. InspectorBackend.registerCommand("Debugger.getScriptSource", [{"name": "scriptId", "type": "string", "optional": false}], ["scriptSource"]);
  4546. InspectorBackend.registerCommand("Debugger.getFunctionDetails", [{"name": "functionId", "type": "string", "optional": false}], ["details"]);
  4547. InspectorBackend.registerCommand("Debugger.setPauseOnExceptions", [{"name": "state", "type": "string", "optional": false}], []);
  4548. InspectorBackend.registerCommand("Debugger.evaluateOnCallFrame", [{"name": "callFrameId", "type": "string", "optional": false}, {"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
  4549.  
  4550.  
  4551. InspectorBackend.registerCommand("DOMDebugger.setDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
  4552. InspectorBackend.registerCommand("DOMDebugger.removeDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
  4553. InspectorBackend.registerCommand("DOMDebugger.setEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
  4554. InspectorBackend.registerCommand("DOMDebugger.removeEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
  4555. InspectorBackend.registerCommand("DOMDebugger.setInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
  4556. InspectorBackend.registerCommand("DOMDebugger.removeInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
  4557. InspectorBackend.registerCommand("DOMDebugger.setXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);
  4558. InspectorBackend.registerCommand("DOMDebugger.removeXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);
  4559.  
  4560.  
  4561. InspectorBackend.registerProfilerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Profiler");
  4562. InspectorBackend.registerEvent("Profiler.addProfileHeader", ["header"]);
  4563. InspectorBackend.registerEvent("Profiler.addHeapSnapshotChunk", ["uid", "chunk"]);
  4564. InspectorBackend.registerEvent("Profiler.finishHeapSnapshot", ["uid"]);
  4565. InspectorBackend.registerEvent("Profiler.setRecordingProfile", ["isProfiling"]);
  4566. InspectorBackend.registerEvent("Profiler.resetProfiles", []);
  4567. InspectorBackend.registerEvent("Profiler.reportHeapSnapshotProgress", ["done", "total"]);
  4568. InspectorBackend.registerCommand("Profiler.causesRecompilation", [], ["result"]);
  4569. InspectorBackend.registerCommand("Profiler.isSampling", [], ["result"]);
  4570. InspectorBackend.registerCommand("Profiler.hasHeapProfiler", [], ["result"]);
  4571. InspectorBackend.registerCommand("Profiler.enable", [], []);
  4572. InspectorBackend.registerCommand("Profiler.disable", [], []);
  4573. InspectorBackend.registerCommand("Profiler.start", [], []);
  4574. InspectorBackend.registerCommand("Profiler.stop", [], []);
  4575. InspectorBackend.registerCommand("Profiler.getProfileHeaders", [], ["headers"]);
  4576. InspectorBackend.registerCommand("Profiler.getProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], ["profile"]);
  4577. InspectorBackend.registerCommand("Profiler.removeProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], []);
  4578. InspectorBackend.registerCommand("Profiler.clearProfiles", [], []);
  4579. InspectorBackend.registerCommand("Profiler.takeHeapSnapshot", [], []);
  4580. InspectorBackend.registerCommand("Profiler.collectGarbage", [], []);
  4581. InspectorBackend.registerCommand("Profiler.getObjectByHeapObjectId", [{"name": "objectId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["result"]);
  4582.  
  4583.  
  4584. InspectorBackend.registerWorkerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Worker");
  4585. InspectorBackend.registerEvent("Worker.workerCreated", ["workerId", "url", "inspectorConnected"]);
  4586. InspectorBackend.registerEvent("Worker.workerTerminated", ["workerId"]);
  4587. InspectorBackend.registerEvent("Worker.dispatchMessageFromWorker", ["workerId", "message"]);
  4588. InspectorBackend.registerEvent("Worker.disconnectedFromWorker", []);
  4589. InspectorBackend.registerCommand("Worker.setWorkerInspectionEnabled", [{"name": "value", "type": "boolean", "optional": false}], []);
  4590. InspectorBackend.registerCommand("Worker.sendMessageToWorker", [{"name": "workerId", "type": "number", "optional": false}, {"name": "message", "type": "object", "optional": false}], []);
  4591. InspectorBackend.registerCommand("Worker.connectToWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
  4592. InspectorBackend.registerCommand("Worker.disconnectFromWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
  4593. InspectorBackend.registerCommand("Worker.setAutoconnectToWorkers", [{"name": "value", "type": "boolean", "optional": false}], []);
  4594.  
  4595.  
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601. if (!window.InspectorExtensionRegistry) {
  4602.  
  4603.  
  4604. WebInspector.InspectorExtensionRegistryStub = function()
  4605. {
  4606. }
  4607.  
  4608. WebInspector.InspectorExtensionRegistryStub.prototype = {
  4609. getExtensionsAsync: function()
  4610. {
  4611. }
  4612. }
  4613.  
  4614. var InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub();
  4615.  
  4616. }
  4617.  
  4618.  
  4619.  
  4620.  
  4621.  
  4622. InspectorFrontendAPI = {
  4623. _pendingCommands: [],
  4624.  
  4625. isDebuggingEnabled: function()
  4626. {
  4627. return WebInspector.panels.scripts.debuggingEnabled;
  4628. },
  4629.  
  4630. setDebuggingEnabled: function(enabled)
  4631. {
  4632. if (enabled) {
  4633. WebInspector.panels.scripts.enableDebugging();
  4634. WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.scripts);
  4635. } else
  4636. WebInspector.panels.scripts.disableDebugging();
  4637. },
  4638.  
  4639. isTimelineProfilingEnabled: function()
  4640. {
  4641. return WebInspector.panels.timeline.timelineProfilingEnabled;
  4642. },
  4643.  
  4644. setTimelineProfilingEnabled: function(enabled)
  4645. {
  4646. WebInspector.panels.timeline.setTimelineProfilingEnabled(enabled);
  4647. },
  4648.  
  4649. isProfilingJavaScript: function()
  4650. {
  4651. return WebInspector.CPUProfileType.instance && WebInspector.CPUProfileType.instance.isRecordingProfile();
  4652. },
  4653.  
  4654. startProfilingJavaScript: function()
  4655. {
  4656. WebInspector.panels.profiles.enableProfiler();
  4657. WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.profiles);
  4658. if (WebInspector.CPUProfileType.instance)
  4659. WebInspector.CPUProfileType.instance.startRecordingProfile();
  4660. },
  4661.  
  4662. stopProfilingJavaScript: function()
  4663. {
  4664. if (WebInspector.CPUProfileType.instance)
  4665. WebInspector.CPUProfileType.instance.stopRecordingProfile();
  4666. WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.profiles);
  4667. },
  4668.  
  4669. setAttachedWindow: function(attached)
  4670. {
  4671. WebInspector.attached = attached;
  4672. },
  4673.  
  4674. showConsole: function()
  4675. {
  4676. WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.console);
  4677. },
  4678.  
  4679. showMainResourceForFrame: function(frameId)
  4680. {
  4681.  
  4682. },
  4683.  
  4684. showResources: function()
  4685. {
  4686. WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.resources);
  4687. },
  4688.  
  4689. setDockingUnavailable: function(unavailable)
  4690. {
  4691. WebInspector.setDockingUnavailable(unavailable);
  4692. },
  4693.  
  4694. dispatch: function(signature)
  4695. {
  4696. if (WebInspector.panels) {
  4697. var methodName = signature.shift();
  4698. return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature);
  4699. }
  4700. InspectorFrontendAPI._pendingCommands.push(signature);
  4701. },
  4702.  
  4703. loadCompleted: function()
  4704. {
  4705. for (var i = 0; i < InspectorFrontendAPI._pendingCommands.length; ++i)
  4706. InspectorFrontendAPI.dispatch(InspectorFrontendAPI._pendingCommands[i]);
  4707. InspectorFrontendAPI._pendingCommands = [];
  4708. }
  4709. }
  4710.  
  4711.  
  4712.  
  4713.  
  4714.  
  4715.  
  4716. WebInspector.Object = function() {
  4717. }
  4718.  
  4719. WebInspector.Object.prototype = {
  4720.  
  4721. addEventListener: function(eventType, listener, thisObject)
  4722. {
  4723. console.assert(listener);
  4724.  
  4725. if (!this._listeners)
  4726. this._listeners = {};
  4727. if (!this._listeners[eventType])
  4728. this._listeners[eventType] = [];
  4729. this._listeners[eventType].push({ thisObject: thisObject, listener: listener });
  4730. },
  4731.  
  4732.  
  4733. removeEventListener: function(eventType, listener, thisObject)
  4734. {
  4735. console.assert(listener);
  4736.  
  4737. if (!this._listeners || !this._listeners[eventType])
  4738. return;
  4739. var listeners = this._listeners[eventType];
  4740. for (var i = 0; i < listeners.length; ++i) {
  4741. if (listener && listeners[i].listener === listener && listeners[i].thisObject === thisObject)
  4742. listeners.splice(i, 1);
  4743. else if (!listener && thisObject && listeners[i].thisObject === thisObject)
  4744. listeners.splice(i, 1);
  4745. }
  4746.  
  4747. if (!listeners.length)
  4748. delete this._listeners[eventType];
  4749. },
  4750.  
  4751. removeAllListeners: function()
  4752. {
  4753. delete this._listeners;
  4754. },
  4755.  
  4756.  
  4757. hasEventListeners: function(eventType)
  4758. {
  4759. if (!this._listeners || !this._listeners[eventType])
  4760. return false;
  4761. return true;
  4762. },
  4763.  
  4764.  
  4765. dispatchEventToListeners: function(eventType, eventData)
  4766. {
  4767. if (!this._listeners || !this._listeners[eventType])
  4768. return false;
  4769.  
  4770. var event = new WebInspector.Event(this, eventType, eventData);
  4771. var listeners = this._listeners[eventType].slice(0);
  4772. for (var i = 0; i < listeners.length; ++i) {
  4773. listeners[i].listener.call(listeners[i].thisObject, event);
  4774. if (event._stoppedPropagation)
  4775. break;
  4776. }
  4777.  
  4778. return event.defaultPrevented;
  4779. }
  4780. }
  4781.  
  4782.  
  4783. WebInspector.Event = function(target, type, data)
  4784. {
  4785. this.target = target;
  4786. this.type = type;
  4787. this.data = data;
  4788. this.defaultPrevented = false;
  4789. this._stoppedPropagation = false;
  4790. }
  4791.  
  4792. WebInspector.Event.prototype = {
  4793. stopPropagation: function()
  4794. {
  4795. this._stoppedPropagation = true;
  4796. },
  4797.  
  4798. preventDefault: function()
  4799. {
  4800. this.defaultPrevented = true;
  4801. },
  4802.  
  4803.  
  4804. consume: function(preventDefault)
  4805. {
  4806. this.stopPropagation();
  4807. if (preventDefault)
  4808. this.preventDefault();
  4809. }
  4810. }
  4811.  
  4812. WebInspector.notifications = new WebInspector.Object();
  4813.  
  4814.  
  4815.  
  4816.  
  4817.  
  4818.  
  4819. var Preferences = {
  4820. maxInlineTextChildLength: 80,
  4821. minConsoleHeight: 75,
  4822. minSidebarWidth: 100,
  4823. minElementsSidebarWidth: 200,
  4824. minScriptsSidebarWidth: 200,
  4825. styleRulesExpandedState: {},
  4826. showMissingLocalizedStrings: false,
  4827. useLowerCaseMenuTitlesOnWindows: false,
  4828. sharedWorkersDebugNote: undefined,
  4829. localizeUI: true,
  4830. exposeDisableCache: false,
  4831. exposeWorkersInspection: false,
  4832. applicationTitle: "Web Inspector - %s",
  4833. showHeapSnapshotObjectsHiddenProperties: false,
  4834. showDockToRight: false
  4835. }
  4836.  
  4837. var Capabilities = {
  4838. samplingCPUProfiler: false,
  4839. debuggerCausesRecompilation: true,
  4840. profilerCausesRecompilation: true,
  4841. nativeInstrumentationEnabled: false,
  4842. heapProfilerPresent: false,
  4843. canOverrideDeviceMetrics: false
  4844. }
  4845.  
  4846.  
  4847. WebInspector.Settings = function()
  4848. {
  4849. this._eventSupport = new WebInspector.Object();
  4850.  
  4851. this.colorFormat = this.createSetting("colorFormat", "hex");
  4852. this.consoleHistory = this.createSetting("consoleHistory", []);
  4853. this.debuggerEnabled = this.createSetting("debuggerEnabled", false);
  4854. this.domWordWrap = this.createSetting("domWordWrap", true);
  4855. this.profilerEnabled = this.createSetting("profilerEnabled", false);
  4856. this.eventListenersFilter = this.createSetting("eventListenersFilter", "all");
  4857. this.lastActivePanel = this.createSetting("lastActivePanel", "elements");
  4858. this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application");
  4859. this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false);
  4860. this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false);
  4861. this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true);
  4862. this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
  4863. this.resourceViewTab = this.createSetting("resourceViewTab", "preview");
  4864. this.showInheritedComputedStyleProperties = this.createSetting("showInheritedComputedStyleProperties", false);
  4865. this.showUserAgentStyles = this.createSetting("showUserAgentStyles", true);
  4866. this.watchExpressions = this.createSetting("watchExpressions", []);
  4867. this.breakpoints = this.createSetting("breakpoints", []);
  4868. this.eventListenerBreakpoints = this.createSetting("eventListenerBreakpoints", []);
  4869. this.domBreakpoints = this.createSetting("domBreakpoints", []);
  4870. this.xhrBreakpoints = this.createSetting("xhrBreakpoints", []);
  4871. this.sourceMapsEnabled = this.createSetting("sourceMapsEnabled", false);
  4872. this.cacheDisabled = this.createSetting("cacheDisabled", false);
  4873. this.overrideUserAgent = this.createSetting("overrideUserAgent", "");
  4874. this.userAgent = this.createSetting("userAgent", "");
  4875. this.deviceMetrics = this.createSetting("deviceMetrics", "");
  4876. this.showScriptFolders = this.createSetting("showScriptFolders", true);
  4877. this.dockToRight = this.createSetting("dockToRight", false);
  4878. this.emulateTouchEvents = this.createSetting("emulateTouchEvents", false);
  4879. this.showPaintRects = this.createSetting("showPaintRects", false);
  4880. this.zoomLevel = this.createSetting("zoomLevel", 0);
  4881.  
  4882.  
  4883.  
  4884. if (this.breakpoints.get().length > 500000)
  4885. this.breakpoints.set([]);
  4886. }
  4887.  
  4888. WebInspector.Settings.prototype = {
  4889.  
  4890. createSetting: function(key, defaultValue)
  4891. {
  4892. return new WebInspector.Setting(key, defaultValue, this._eventSupport);
  4893. }
  4894. }
  4895.  
  4896.  
  4897. WebInspector.Setting = function(name, defaultValue, eventSupport)
  4898. {
  4899. this._name = name;
  4900. this._defaultValue = defaultValue;
  4901. this._eventSupport = eventSupport;
  4902. }
  4903.  
  4904. WebInspector.Setting.prototype = {
  4905. addChangeListener: function(listener, thisObject)
  4906. {
  4907. this._eventSupport.addEventListener(this._name, listener, thisObject);
  4908. },
  4909.  
  4910. removeChangeListener: function(listener, thisObject)
  4911. {
  4912. this._eventSupport.removeEventListener(this._name, listener, thisObject);
  4913. },
  4914.  
  4915. get name()
  4916. {
  4917. return this._name;
  4918. },
  4919.  
  4920. get: function()
  4921. {
  4922. if (typeof this._value !== "undefined")
  4923. return this._value;
  4924.  
  4925. this._value = this._defaultValue;
  4926. if (window.localStorage != null && this._name in window.localStorage) {
  4927. try {
  4928. this._value = JSON.parse(window.localStorage[this._name]);
  4929. } catch(e) {
  4930. window.localStorage.removeItem(this._name);
  4931. }
  4932. }
  4933. return this._value;
  4934. },
  4935.  
  4936. set: function(value)
  4937. {
  4938. this._value = value;
  4939. if (window.localStorage != null) {
  4940. try {
  4941. window.localStorage[this._name] = JSON.stringify(value);
  4942. } catch(e) {
  4943. console.error("Error saving setting with name:" + this._name);
  4944. }
  4945. }
  4946. this._eventSupport.dispatchEventToListeners(this._name, value);
  4947. }
  4948. }
  4949.  
  4950.  
  4951. WebInspector.ExperimentsSettings = function()
  4952. {
  4953. this._setting = WebInspector.settings.createSetting("experiments", {});
  4954. this._experiments = [];
  4955. this._enabledForTest = {};
  4956.  
  4957.  
  4958. this.timelineVerticalOverview = this._createExperiment("timelineStartAtZero", "Enable vertical overview mode in the Timeline panel");
  4959. this.showShadowDOM = this._createExperiment("showShadowDOM", "Show shadow DOM");
  4960. this.snippetsSupport = this._createExperiment("snippetsSupport", "Snippets support");
  4961.  
  4962. this._cleanUpSetting();
  4963. }
  4964.  
  4965. WebInspector.ExperimentsSettings.prototype = {
  4966.  
  4967. get experiments()
  4968. {
  4969. return this._experiments.slice();
  4970. },
  4971.  
  4972.  
  4973. get experimentsEnabled()
  4974. {
  4975. return "experiments" in WebInspector.queryParamsObject;
  4976. },
  4977.  
  4978.  
  4979. _createExperiment: function(experimentName, experimentTitle)
  4980. {
  4981. var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle);
  4982. this._experiments.push(experiment);
  4983. return experiment;
  4984. },
  4985.  
  4986.  
  4987. isEnabled: function(experimentName)
  4988. {
  4989. if (this._enabledForTest[experimentName])
  4990. return true;
  4991.  
  4992. if (!this.experimentsEnabled)
  4993. return false;
  4994.  
  4995. var experimentsSetting = this._setting.get();
  4996. return experimentsSetting[experimentName];
  4997. },
  4998.  
  4999.  
  5000. setEnabled: function(experimentName, enabled)
  5001. {
  5002. var experimentsSetting = this._setting.get();
  5003. experimentsSetting[experimentName] = enabled;
  5004. this._setting.set(experimentsSetting);
  5005. },
  5006.  
  5007.  
  5008. _enableForTest: function(experimentName)
  5009. {
  5010. this._enabledForTest[experimentName] = true;
  5011. },
  5012.  
  5013. _cleanUpSetting: function()
  5014. {
  5015. var experimentsSetting = this._setting.get();
  5016. var cleanedUpExperimentSetting = {};
  5017. for (var i = 0; i < this._experiments.length; ++i) {
  5018. var experimentName = this._experiments[i].name;
  5019. if (experimentsSetting[experimentName])
  5020. cleanedUpExperimentSetting[experimentName] = true;
  5021. }
  5022. this._setting.set(cleanedUpExperimentSetting);
  5023. }
  5024. }
  5025.  
  5026.  
  5027. WebInspector.Experiment = function(experimentsSettings, name, title)
  5028. {
  5029. this._name = name;
  5030. this._title = title;
  5031. this._experimentsSettings = experimentsSettings;
  5032. }
  5033.  
  5034. WebInspector.Experiment.prototype = {
  5035.  
  5036. get name()
  5037. {
  5038. return this._name;
  5039. },
  5040.  
  5041.  
  5042. get title()
  5043. {
  5044. return this._title;
  5045. },
  5046.  
  5047.  
  5048. isEnabled: function()
  5049. {
  5050. return this._experimentsSettings.isEnabled(this._name);
  5051. },
  5052.  
  5053.  
  5054. setEnabled: function(enabled)
  5055. {
  5056. return this._experimentsSettings.setEnabled(this._name, enabled);
  5057. },
  5058.  
  5059. enableForTest: function()
  5060. {
  5061. this._experimentsSettings._enableForTest(this._name);
  5062. }
  5063. }
  5064.  
  5065. WebInspector.settings = new WebInspector.Settings();
  5066. WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings();
  5067.  
  5068.  
  5069.  
  5070.  
  5071.  
  5072. if (!window.InspectorFrontendHost) {
  5073.  
  5074.  
  5075. WebInspector.InspectorFrontendHostStub = function()
  5076. {
  5077. this._attachedWindowHeight = 0;
  5078. this.isStub = true;
  5079. }
  5080.  
  5081. WebInspector.InspectorFrontendHostStub.prototype = {
  5082. platform: function()
  5083. {
  5084. var match = navigator.userAgent.match(/Windows NT/);
  5085. if (match)
  5086. return "windows";
  5087. match = navigator.userAgent.match(/Mac OS X/);
  5088. if (match)
  5089. return "mac";
  5090. return "linux";
  5091. },
  5092.  
  5093. port: function()
  5094. {
  5095. return "unknown";
  5096. },
  5097.  
  5098. bringToFront: function()
  5099. {
  5100. this._windowVisible = true;
  5101. },
  5102.  
  5103. closeWindow: function()
  5104. {
  5105. this._windowVisible = false;
  5106. },
  5107.  
  5108. requestAttachWindow: function()
  5109. {
  5110. },
  5111.  
  5112. requestDetachWindow: function()
  5113. {
  5114. },
  5115.  
  5116. requestSetDockSide: function()
  5117. {
  5118. },
  5119.  
  5120. setAttachedWindowHeight: function(height)
  5121. {
  5122. },
  5123.  
  5124. moveWindowBy: function(x, y)
  5125. {
  5126. },
  5127.  
  5128. setInjectedScriptForOrigin: function(origin, script)
  5129. {
  5130. },
  5131.  
  5132. loaded: function()
  5133. {
  5134. },
  5135.  
  5136. localizedStringsURL: function()
  5137. {
  5138. return undefined;
  5139. },
  5140.  
  5141. hiddenPanels: function()
  5142. {
  5143. return "";
  5144. },
  5145.  
  5146. inspectedURLChanged: function(url)
  5147. {
  5148. document.title = WebInspector.UIString(Preferences.applicationTitle, url);
  5149. },
  5150.  
  5151. copyText: function()
  5152. {
  5153. },
  5154.  
  5155. openInNewTab: function(url)
  5156. {
  5157. window.open(url, "_blank");
  5158. },
  5159.  
  5160. canSaveAs: function(fileName, content)
  5161. {
  5162. return true;
  5163. },
  5164.  
  5165. saveAs: function(fileName, content)
  5166. {
  5167. var builder = new WebKitBlobBuilder();
  5168. builder.append(content);
  5169. var blob = builder.getBlob("application/octet-stream");
  5170.  
  5171. var fr = new FileReader();
  5172. fr.onload = function(e) {
  5173.  
  5174. window.location = this.result;
  5175. }
  5176. fr.readAsDataURL(blob);
  5177. },
  5178.  
  5179. sendMessageToBackend: function(message)
  5180. {
  5181. },
  5182.  
  5183. recordActionTaken: function(actionCode)
  5184. {
  5185. },
  5186.  
  5187. recordPanelShown: function(panelCode)
  5188. {
  5189. },
  5190.  
  5191. recordSettingChanged: function(settingCode)
  5192. {
  5193. },
  5194.  
  5195. loadResourceSynchronously: function(url)
  5196. {
  5197. return "";
  5198. },
  5199.  
  5200. setZoomFactor: function(zoom)
  5201. {
  5202. }
  5203. }
  5204.  
  5205. var InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();
  5206. Preferences.localizeUI = false;
  5207.  
  5208. }
  5209.  
  5210.  
  5211.  
  5212.  
  5213.  
  5214.  
  5215. WebInspector.Checkbox = function(label, className, tooltip)
  5216. {
  5217. this.element = document.createElement('label');
  5218. this._inputElement = document.createElement('input');
  5219. this._inputElement.type = "checkbox";
  5220.  
  5221. this.element.className = className;
  5222. this.element.appendChild(this._inputElement);
  5223. this.element.appendChild(document.createTextNode(label));
  5224. if (tooltip)
  5225. this.element.title = tooltip;
  5226. }
  5227.  
  5228. WebInspector.Checkbox.prototype = {
  5229. set checked(checked)
  5230. {
  5231. this._inputElement.checked = checked;
  5232. },
  5233.  
  5234. get checked()
  5235. {
  5236. return this._inputElement.checked;
  5237. },
  5238.  
  5239. addEventListener: function(listener)
  5240. {
  5241. function listenerWrapper(event)
  5242. {
  5243. if (listener)
  5244. listener(event);
  5245. event.consume();
  5246. return true;
  5247. }
  5248.  
  5249. this._inputElement.addEventListener("click", listenerWrapper, false);
  5250. this.element.addEventListener("click", listenerWrapper, false);
  5251. }
  5252. }
  5253.  
  5254.  
  5255.  
  5256.  
  5257.  
  5258.  
  5259. WebInspector.ContextMenu = function() {
  5260. this._items = [];
  5261. this._handlers = {};
  5262. }
  5263.  
  5264. WebInspector.ContextMenu.prototype = {
  5265. show: function(event)
  5266. {
  5267.  
  5268. while (this._items.length > 0 && !("id" in this._items[this._items.length - 1]))
  5269. this._items.splice(this._items.length - 1, 1);
  5270.  
  5271. if (this._items.length) {
  5272. WebInspector._contextMenu = this;
  5273. InspectorFrontendHost.showContextMenu(event, this._items);
  5274. }
  5275. event.consume();
  5276. },
  5277.  
  5278.  
  5279. appendItem: function(label, handler, disabled)
  5280. {
  5281. var id = this._items.length;
  5282. this._items.push({type: "item", id: id, label: label, enabled: !disabled});
  5283. this._handlers[id] = handler;
  5284. },
  5285.  
  5286.  
  5287. appendCheckboxItem: function(label, handler, checked, disabled)
  5288. {
  5289. var id = this._items.length;
  5290. this._items.push({type: "checkbox", id: id, label: label, checked: !!checked, enabled: !disabled});
  5291. this._handlers[id] = handler;
  5292. },
  5293.  
  5294. appendSeparator: function()
  5295. {
  5296.  
  5297. if (this._items.length === 0)
  5298. return;
  5299. if (!("id" in this._items[this._items.length - 1]))
  5300. return;
  5301. this._items.push({type: "separator"});
  5302. },
  5303.  
  5304. _itemSelected: function(id)
  5305. {
  5306. if (this._handlers[id])
  5307. this._handlers[id].call(this);
  5308. }
  5309. }
  5310.  
  5311. WebInspector.contextMenuItemSelected = function(id)
  5312. {
  5313. if (WebInspector._contextMenu)
  5314. WebInspector._contextMenu._itemSelected(id);
  5315. }
  5316.  
  5317. WebInspector.contextMenuCleared = function()
  5318. {
  5319.  
  5320.  
  5321. }
  5322.  
  5323.  
  5324.  
  5325.  
  5326.  
  5327. if (!InspectorFrontendHost.showContextMenu) {
  5328.  
  5329.  
  5330. WebInspector.SoftContextMenu = function(items)
  5331. {
  5332. this._items = items;
  5333. }
  5334.  
  5335. WebInspector.SoftContextMenu.prototype = {
  5336. show: function(event)
  5337. {
  5338. this._x = event.x;
  5339. this._y = event.y;
  5340. this._time = new Date().getTime();
  5341.  
  5342.  
  5343. var absoluteX = event.pageX;
  5344. var absoluteY = event.pageY;
  5345. var targetElement = event.target;
  5346. while (targetElement && window !== targetElement.ownerDocument.defaultView) {
  5347. var frameElement = targetElement.ownerDocument.defaultView.frameElement;
  5348. absoluteY += frameElement.totalOffsetTop();
  5349. absoluteX += frameElement.totalOffsetLeft();
  5350. targetElement = frameElement;
  5351. }
  5352.  
  5353.  
  5354. this._glassPaneElement = document.createElement("div");
  5355. this._glassPaneElement.className = "soft-context-menu-glass-pane";
  5356. this._glassPaneElement.tabIndex = 0;
  5357. this._glassPaneElement.addEventListener("mouseup", this._glassPaneMouseUp.bind(this), false);
  5358.  
  5359.  
  5360. this._contextMenuElement = document.createElement("div");
  5361. this._contextMenuElement.className = "soft-context-menu";
  5362. this._contextMenuElement.tabIndex = 0;
  5363. this._contextMenuElement.style.top = absoluteY + "px";
  5364. this._contextMenuElement.style.left = absoluteX + "px";
  5365.  
  5366. this._contextMenuElement.addEventListener("mousedown", this._discardMenu.bind(this), false);
  5367. this._contextMenuElement.addEventListener("keydown", this._menuKeyDown.bind(this), false);
  5368. this._contextMenuElement.addEventListener("blur", this._discardMenu.bind(this), false);
  5369.  
  5370. for (var i = 0; i < this._items.length; ++i)
  5371. this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));
  5372.  
  5373. this._glassPaneElement.appendChild(this._contextMenuElement);
  5374. document.body.appendChild(this._glassPaneElement);
  5375. this._contextMenuElement.focus();
  5376.  
  5377.  
  5378. if (document.body.offsetWidth < this._contextMenuElement.offsetLeft + this._contextMenuElement.offsetWidth)
  5379. this._contextMenuElement.style.left = (absoluteX - this._contextMenuElement.offsetWidth) + "px";
  5380. if (document.body.offsetHeight < this._contextMenuElement.offsetTop + this._contextMenuElement.offsetHeight)
  5381. this._contextMenuElement.style.top = (document.body.offsetHeight - this._contextMenuElement.offsetHeight) + "px";
  5382.  
  5383. event.consume(true);
  5384. },
  5385.  
  5386. _createMenuItem: function(item)
  5387. {
  5388. if (item.type === "separator")
  5389. return this._createSeparator();
  5390.  
  5391. var menuItemElement = document.createElement("div");
  5392. menuItemElement.className = "soft-context-menu-item";
  5393.  
  5394. var checkMarkElement = document.createElement("span");
  5395. checkMarkElement.textContent = "\u2713 ";
  5396. checkMarkElement.className = "soft-context-menu-item-checkmark";
  5397. if (!item.checked)
  5398. checkMarkElement.style.opacity = "0";
  5399.  
  5400. menuItemElement.appendChild(checkMarkElement);
  5401. menuItemElement.appendChild(document.createTextNode(item.label));
  5402.  
  5403. menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
  5404. menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);
  5405.  
  5406.  
  5407. menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
  5408. menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);
  5409.  
  5410. menuItemElement._actionId = item.id;
  5411. return menuItemElement;
  5412. },
  5413.  
  5414. _createSeparator: function()
  5415. {
  5416. var separatorElement = document.createElement("div");
  5417. separatorElement.className = "soft-context-menu-separator";
  5418. separatorElement._isSeparator = true;
  5419. return separatorElement;
  5420. },
  5421.  
  5422. _menuItemMouseDown: function(event)
  5423. {
  5424.  
  5425. event.consume(true);
  5426. },
  5427.  
  5428. _menuItemMouseUp: function(event)
  5429. {
  5430. this._triggerAction(event.target, event);
  5431. },
  5432.  
  5433. _triggerAction: function(menuItemElement, event)
  5434. {
  5435. this._discardMenu(event);
  5436. if (typeof menuItemElement._actionId !== "undefined") {
  5437. WebInspector.contextMenuItemSelected(menuItemElement._actionId);
  5438. delete menuItemElement._actionId;
  5439. }
  5440. },
  5441.  
  5442. _menuItemMouseOver: function(event)
  5443. {
  5444. this._highlightMenuItem(event.target);
  5445. },
  5446.  
  5447. _menuItemMouseOut: function(event)
  5448. {
  5449. this._highlightMenuItem(null);
  5450. },
  5451.  
  5452. _highlightMenuItem: function(menuItemElement)
  5453. {
  5454. if (this._highlightedMenuItemElement)
  5455. this._highlightedMenuItemElement.removeStyleClass("soft-context-menu-item-mouse-over");
  5456. this._highlightedMenuItemElement = menuItemElement;
  5457. if (this._highlightedMenuItemElement)
  5458. this._highlightedMenuItemElement.addStyleClass("soft-context-menu-item-mouse-over");
  5459. },
  5460.  
  5461. _highlightPrevious: function()
  5462. {
  5463. var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild;
  5464. while (menuItemElement && menuItemElement._isSeparator)
  5465. menuItemElement = menuItemElement.previousSibling;
  5466. if (menuItemElement)
  5467. this._highlightMenuItem(menuItemElement);
  5468. },
  5469.  
  5470. _highlightNext: function()
  5471. {
  5472. var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild;
  5473. while (menuItemElement && menuItemElement._isSeparator)
  5474. menuItemElement = menuItemElement.nextSibling;
  5475. if (menuItemElement)
  5476. this._highlightMenuItem(menuItemElement);
  5477. },
  5478.  
  5479. _menuKeyDown: function(event)
  5480. {
  5481. switch (event.keyIdentifier) {
  5482. case "Up":
  5483. this._highlightPrevious(); break;
  5484. case "Down":
  5485. this._highlightNext(); break;
  5486. case "U+001B":
  5487. this._discardMenu(event); break;
  5488. case "Enter":
  5489. if (!isEnterKey(event))
  5490. break;
  5491.  
  5492. case "U+0020":
  5493. if (this._highlightedMenuItemElement)
  5494. this._triggerAction(this._highlightedMenuItemElement, event);
  5495. break;
  5496. }
  5497. event.consume(true);
  5498. },
  5499.  
  5500. _glassPaneMouseUp: function(event)
  5501. {
  5502.  
  5503. if (event.x === this._x && event.y === this._y && new Date().getTime() - this._time < 300)
  5504. return;
  5505. this._discardMenu(event);
  5506. },
  5507.  
  5508. _discardMenu: function(event)
  5509. {
  5510. if (this._glassPaneElement) {
  5511. var glassPane = this._glassPaneElement;
  5512. delete this._glassPaneElement;
  5513.  
  5514. document.body.removeChild(glassPane);
  5515.  
  5516. event.consume(true);
  5517. }
  5518. }
  5519. }
  5520.  
  5521. InspectorFrontendHost.showContextMenu = function(event, items)
  5522. {
  5523. new WebInspector.SoftContextMenu(items).show(event);
  5524. }
  5525.  
  5526. }
  5527.  
  5528.  
  5529.  
  5530.  
  5531.  
  5532.  
  5533. WebInspector.KeyboardShortcut = function()
  5534. {
  5535. }
  5536.  
  5537.  
  5538. WebInspector.KeyboardShortcut.Modifiers = {
  5539. None: 0,
  5540. Shift: 1,
  5541. Ctrl: 2,
  5542. Alt: 4,
  5543. Meta: 8,
  5544. get CtrlOrMeta()
  5545. {
  5546.  
  5547. return WebInspector.isMac() ? this.Meta : this.Ctrl;
  5548. }
  5549. };
  5550.  
  5551. WebInspector.KeyboardShortcut.Keys = {
  5552. Backspace: { code: 8, name: "\u21a4" },
  5553. Tab: { code: 9, name: { mac: "\u21e5", other: "<Tab>" } },
  5554. Enter: { code: 13, name: { mac: "\u21a9", other: "<Enter>" } },
  5555. Esc: { code: 27, name: { mac: "\u238b", other: "<Esc>" } },
  5556. Space: { code: 32, name: "<Space>" },
  5557. PageUp: { code: 33, name: { mac: "\u21de", other: "<PageUp>" } },
  5558. PageDown: { code: 34, name: { mac: "\u21df", other: "<PageDown>" } },
  5559. End: { code: 35, name: { mac: "\u2197", other: "<End>" } },
  5560. Home: { code: 36, name: { mac: "\u2196", other: "<Home>" } },
  5561. Left: { code: 37, name: "\u2190" },
  5562. Up: { code: 38, name: "\u2191" },
  5563. Right: { code: 39, name: "\u2192" },
  5564. Down: { code: 40, name: "\u2193" },
  5565. Delete: { code: 46, name: "<Del>" },
  5566. Zero: { code: 48, name: "0" },
  5567. F1: { code: 112, name: "F1" },
  5568. F2: { code: 113, name: "F2" },
  5569. F3: { code: 114, name: "F3" },
  5570. F4: { code: 115, name: "F4" },
  5571. F5: { code: 116, name: "F5" },
  5572. F6: { code: 117, name: "F6" },
  5573. F7: { code: 118, name: "F7" },
  5574. F8: { code: 119, name: "F8" },
  5575. F9: { code: 120, name: "F9" },
  5576. F10: { code: 121, name: "F10" },
  5577. F11: { code: 122, name: "F11" },
  5578. F12: { code: 123, name: "F12" },
  5579. Semicolon: { code: 186, name: ";" },
  5580. Plus: { code: 187, name: "+" },
  5581. Comma: { code: 188, name: "," },
  5582. Minus: { code: 189, name: "-" },
  5583. Period: { code: 190, name: "." },
  5584. Slash: { code: 191, name: "/" },
  5585. Apostrophe: { code: 192, name: "`" },
  5586. SingleQuote: { code: 222, name: "\'" }
  5587. };
  5588.  
  5589.  
  5590. WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
  5591. {
  5592. if (typeof keyCode === "string")
  5593. keyCode = keyCode.charCodeAt(0) - 32;
  5594. modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
  5595. return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
  5596. }
  5597.  
  5598. WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
  5599. {
  5600. var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
  5601. if (keyboardEvent.shiftKey)
  5602. modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
  5603. if (keyboardEvent.ctrlKey)
  5604. modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
  5605. if (keyboardEvent.altKey)
  5606. modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
  5607. if (keyboardEvent.metaKey)
  5608. modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
  5609. return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
  5610. }
  5611.  
  5612. WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event)
  5613. {
  5614. return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
  5615. }
  5616.  
  5617.  
  5618. WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
  5619. {
  5620. return {
  5621. key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
  5622. name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
  5623. };
  5624. }
  5625.  
  5626.  
  5627. WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
  5628. {
  5629. return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
  5630. }
  5631.  
  5632. WebInspector.KeyboardShortcut._keyName = function(key)
  5633. {
  5634. if (typeof key === "string")
  5635. return key.toUpperCase();
  5636. if (typeof key.name === "string")
  5637. return key.name;
  5638. return key.name[WebInspector.platform()] || key.name.other;
  5639. }
  5640.  
  5641. WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
  5642. {
  5643. return (keyCode & 255) | (modifiers << 8);
  5644. };
  5645.  
  5646. WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
  5647. {
  5648. const cmdKey = "\u2318";
  5649. const optKey = "\u2325";
  5650. const shiftKey = "\u21e7";
  5651. const ctrlKey = "\u2303";
  5652.  
  5653. var isMac = WebInspector.isMac();
  5654. var res = "";
  5655. if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl)
  5656. res += isMac ? ctrlKey : "<Ctrl> + ";
  5657. if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt)
  5658. res += isMac ? optKey : "<Alt> + ";
  5659. if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift)
  5660. res += isMac ? shiftKey : "<Shift> + ";
  5661. if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Meta)
  5662. res += isMac ? cmdKey : "<Win> + ";
  5663.  
  5664. return res;
  5665. };
  5666.  
  5667.  
  5668.  
  5669.  
  5670.  
  5671.  
  5672. WebInspector.TextPrompt = function(completions, stopCharacters)
  5673. {
  5674.  
  5675. this._proxyElement;
  5676. this._proxyElementDisplay = "inline-block";
  5677. this._loadCompletions = completions;
  5678. this._completionStopCharacters = stopCharacters;
  5679. this._suggestForceable = true;
  5680. }
  5681.  
  5682. WebInspector.TextPrompt.Events = {
  5683. ItemApplied: "text-prompt-item-applied",
  5684. ItemAccepted: "text-prompt-item-accepted"
  5685. };
  5686.  
  5687. WebInspector.TextPrompt.prototype = {
  5688. get proxyElement()
  5689. {
  5690. return this._proxyElement;
  5691. },
  5692.  
  5693. setSuggestForceable: function(x)
  5694. {
  5695. this._suggestForceable = x;
  5696. },
  5697.  
  5698. setSuggestBoxEnabled: function(className)
  5699. {
  5700. this._suggestBoxClassName = className;
  5701. },
  5702.  
  5703. renderAsBlock: function()
  5704. {
  5705. this._proxyElementDisplay = "block";
  5706. },
  5707.  
  5708.  
  5709. attach: function(element)
  5710. {
  5711. return this._attachInternal(element);
  5712. },
  5713.  
  5714.  
  5715. attachAndStartEditing: function(element, blurListener)
  5716. {
  5717. this._attachInternal(element);
  5718. this._startEditing(blurListener);
  5719. return this.proxyElement;
  5720. },
  5721.  
  5722. _attachInternal: function(element)
  5723. {
  5724. if (this.proxyElement)
  5725. throw "Cannot attach an attached TextPrompt";
  5726. this._element = element;
  5727.  
  5728. this._boundOnKeyDown = this.onKeyDown.bind(this);
  5729. this._boundSelectStart = this._selectStart.bind(this);
  5730. this._proxyElement = element.ownerDocument.createElement("span");
  5731. this._proxyElement.style.display = this._proxyElementDisplay;
  5732. element.parentElement.insertBefore(this.proxyElement, element);
  5733. this.proxyElement.appendChild(element);
  5734. this._element.addStyleClass("text-prompt");
  5735. this._element.addEventListener("keydown", this._boundOnKeyDown, false);
  5736. this._element.addEventListener("selectstart", this._selectStart.bind(this), false);
  5737.  
  5738. if (typeof this._suggestBoxClassName === "string")
  5739. this._suggestBox = new WebInspector.TextPrompt.SuggestBox(this, this._element, this._suggestBoxClassName);
  5740.  
  5741. return this.proxyElement;
  5742. },
  5743.  
  5744. detach: function()
  5745. {
  5746. this._removeFromElement();
  5747. this.proxyElement.parentElement.insertBefore(this._element, this.proxyElement);
  5748. this.proxyElement.parentElement.removeChild(this.proxyElement);
  5749. delete this._proxyElement;
  5750. WebInspector.restoreFocusFromElement(this._element);
  5751. },
  5752.  
  5753. get text()
  5754. {
  5755. return this._element.textContent;
  5756. },
  5757.  
  5758. set text(x)
  5759. {
  5760. this._removeSuggestionAids();
  5761. if (!x) {
  5762.  
  5763. this._element.removeChildren();
  5764. this._element.appendChild(document.createElement("br"));
  5765. } else
  5766. this._element.textContent = x;
  5767.  
  5768. this.moveCaretToEndOfPrompt();
  5769. this._element.scrollIntoView();
  5770. },
  5771.  
  5772. _removeFromElement: function()
  5773. {
  5774. this.clearAutoComplete(true);
  5775. this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
  5776. this._element.removeEventListener("selectstart", this._boundSelectStart, false);
  5777. if (this._isEditing)
  5778. this._stopEditing();
  5779. if (this._suggestBox)
  5780. this._suggestBox.removeFromElement();
  5781. },
  5782.  
  5783. _startEditing: function(blurListener)
  5784. {
  5785. this._isEditing = true;
  5786. this._element.addStyleClass("editing");
  5787. if (blurListener) {
  5788. this._blurListener = blurListener;
  5789. this._element.addEventListener("blur", this._blurListener, false);
  5790. }
  5791. this._oldTabIndex = this._element.tabIndex;
  5792. if (this._element.tabIndex < 0)
  5793. this._element.tabIndex = 0;
  5794. WebInspector.setCurrentFocusElement(this._element);
  5795. },
  5796.  
  5797. _stopEditing: function()
  5798. {
  5799. this._element.tabIndex = this._oldTabIndex;
  5800. if (this._blurListener)
  5801. this._element.removeEventListener("blur", this._blurListener, false);
  5802. this._element.removeStyleClass("editing");
  5803. delete this._isEditing;
  5804. },
  5805.  
  5806. _removeSuggestionAids: function()
  5807. {
  5808. this.clearAutoComplete();
  5809. this.hideSuggestBox();
  5810. },
  5811.  
  5812. _selectStart: function(event)
  5813. {
  5814. if (this._selectionTimeout)
  5815. clearTimeout(this._selectionTimeout);
  5816.  
  5817. this._removeSuggestionAids();
  5818.  
  5819. function moveBackIfOutside()
  5820. {
  5821. delete this._selectionTimeout;
  5822. if (!this.isCaretInsidePrompt() && window.getSelection().isCollapsed) {
  5823. this.moveCaretToEndOfPrompt();
  5824. this.autoCompleteSoon();
  5825. }
  5826. }
  5827.  
  5828. this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
  5829. },
  5830.  
  5831.  
  5832. defaultKeyHandler: function(event, force)
  5833. {
  5834. this.clearAutoComplete();
  5835. this.autoCompleteSoon(force);
  5836. return false;
  5837. },
  5838.  
  5839. onKeyDown: function(event)
  5840. {
  5841. var handled = false;
  5842. var invokeDefault = true;
  5843.  
  5844. switch (event.keyIdentifier) {
  5845. case "Up":
  5846. handled = this.upKeyPressed(event);
  5847. break;
  5848. case "Down":
  5849. handled = this.downKeyPressed(event);
  5850. break;
  5851. case "PageUp":
  5852. handled = this.pageUpKeyPressed(event);
  5853. break;
  5854. case "PageDown":
  5855. handled = this.pageDownKeyPressed(event);
  5856. break;
  5857. case "U+0009":
  5858. handled = this.tabKeyPressed(event);
  5859. break;
  5860. case "Enter":
  5861. handled = this.enterKeyPressed(event);
  5862. break;
  5863. case "Left":
  5864. case "Home":
  5865. this._removeSuggestionAids();
  5866. invokeDefault = false;
  5867. break;
  5868. case "Right":
  5869. case "End":
  5870. if (this.isCaretAtEndOfPrompt())
  5871. handled = this.acceptAutoComplete();
  5872. else
  5873. this._removeSuggestionAids();
  5874. invokeDefault = false;
  5875. break;
  5876. case "U+001B":
  5877. if (this.isSuggestBoxVisible()) {
  5878. this._suggestBox.hide();
  5879. handled = true;
  5880. }
  5881. break;
  5882. case "U+0020":
  5883. if (this._suggestForceable && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
  5884. this.defaultKeyHandler(event, true);
  5885. handled = true;
  5886. }
  5887. break;
  5888. case "Alt":
  5889. case "Meta":
  5890. case "Shift":
  5891. case "Control":
  5892. invokeDefault = false;
  5893. break;
  5894. }
  5895.  
  5896. if (!handled && invokeDefault)
  5897. handled = this.defaultKeyHandler(event);
  5898.  
  5899. if (handled)
  5900. event.consume(true);
  5901.  
  5902. return handled;
  5903. },
  5904.  
  5905. acceptAutoComplete: function()
  5906. {
  5907. var result = false;
  5908. if (this.isSuggestBoxVisible())
  5909. result = this._suggestBox.acceptSuggestion();
  5910. if (!result)
  5911. result = this.acceptSuggestion();
  5912.  
  5913. return result;
  5914. },
  5915.  
  5916.  
  5917. clearAutoComplete: function(includeTimeout)
  5918. {
  5919. if (includeTimeout && this._completeTimeout) {
  5920. clearTimeout(this._completeTimeout);
  5921. delete this._completeTimeout;
  5922. }
  5923.  
  5924. if (!this.autoCompleteElement)
  5925. return;
  5926.  
  5927. if (this.autoCompleteElement.parentNode)
  5928. this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
  5929. delete this.autoCompleteElement;
  5930.  
  5931. if (!this._userEnteredRange || !this._userEnteredText)
  5932. return;
  5933.  
  5934. this._userEnteredRange.deleteContents();
  5935. this._element.pruneEmptyTextNodes();
  5936.  
  5937. var userTextNode = document.createTextNode(this._userEnteredText);
  5938. this._userEnteredRange.insertNode(userTextNode);
  5939.  
  5940. var selectionRange = document.createRange();
  5941. selectionRange.setStart(userTextNode, this._userEnteredText.length);
  5942. selectionRange.setEnd(userTextNode, this._userEnteredText.length);
  5943.  
  5944. var selection = window.getSelection();
  5945. selection.removeAllRanges();
  5946. selection.addRange(selectionRange);
  5947.  
  5948. delete this._userEnteredRange;
  5949. delete this._userEnteredText;
  5950. },
  5951.  
  5952.  
  5953. autoCompleteSoon: function(force)
  5954. {
  5955. var immediately = this.isSuggestBoxVisible() || force;
  5956. if (!this._completeTimeout)
  5957. this._completeTimeout = setTimeout(this.complete.bind(this, true, force), immediately ? 0 : 250);
  5958. },
  5959.  
  5960.  
  5961. complete: function(auto, force, reverse)
  5962. {
  5963. this.clearAutoComplete(true);
  5964. var selection = window.getSelection();
  5965. if (!selection.rangeCount)
  5966. return;
  5967.  
  5968. var selectionRange = selection.getRangeAt(0);
  5969. var isEmptyInput = selectionRange.commonAncestorContainer === this._element;
  5970.  
  5971. var shouldExit;
  5972.  
  5973.  
  5974. if (auto && isEmptyInput && !force)
  5975. shouldExit = true;
  5976. else if (!auto && !isEmptyInput && !selectionRange.commonAncestorContainer.isDescendant(this._element))
  5977. shouldExit = true;
  5978. else if (auto && !force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible())
  5979. shouldExit = true;
  5980. else if (!selection.isCollapsed)
  5981. shouldExit = true;
  5982. else if (!force) {
  5983.  
  5984. var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.endOffset, this._completionStopCharacters, this._element, "forward");
  5985. if (wordSuffixRange.toString().length)
  5986. shouldExit = true;
  5987. }
  5988. if (shouldExit) {
  5989. this.hideSuggestBox();
  5990. return;
  5991. }
  5992.  
  5993. var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward");
  5994. this._loadCompletions(this, wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, !!reverse));
  5995. },
  5996.  
  5997. _boxForAnchorAtStart: function(selection, textRange)
  5998. {
  5999. var rangeCopy = selection.getRangeAt(0).cloneRange();
  6000. var anchorElement = document.createElement("span");
  6001. anchorElement.textContent = "\u200B";
  6002. textRange.insertNode(anchorElement);
  6003. var box = anchorElement.boxInWindow(window);
  6004. anchorElement.parentElement.removeChild(anchorElement);
  6005. selection.removeAllRanges();
  6006. selection.addRange(rangeCopy);
  6007. return box;
  6008. },
  6009.  
  6010.  
  6011. _buildCommonPrefix: function(completions, wordPrefixLength)
  6012. {
  6013. var commonPrefix = completions[0];
  6014. for (var i = 0; i < completions.length; ++i) {
  6015. var completion = completions[i];
  6016. var lastIndex = Math.min(commonPrefix.length, completion.length);
  6017. for (var j = wordPrefixLength; j < lastIndex; ++j) {
  6018. if (commonPrefix[j] !== completion[j]) {
  6019. commonPrefix = commonPrefix.substr(0, j);
  6020. break;
  6021. }
  6022. }
  6023. }
  6024. return commonPrefix;
  6025. },
  6026.  
  6027.  
  6028. _completionsReady: function(selection, auto, originalWordPrefixRange, reverse, completions)
  6029. {
  6030. if (!completions || !completions.length) {
  6031. this.hideSuggestBox();
  6032. return;
  6033. }
  6034.  
  6035. var selectionRange = selection.getRangeAt(0);
  6036.  
  6037. var fullWordRange = document.createRange();
  6038. fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset);
  6039. fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);
  6040.  
  6041. if (originalWordPrefixRange.toString() + selectionRange.toString() != fullWordRange.toString())
  6042. return;
  6043.  
  6044. this._userEnteredRange = fullWordRange;
  6045. this._userEnteredText = fullWordRange.toString();
  6046.  
  6047. if (this._suggestBox)
  6048. this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), completions, !this.isCaretAtEndOfPrompt());
  6049.  
  6050. var wordPrefixLength = originalWordPrefixRange.toString().length;
  6051.  
  6052. if (auto) {
  6053. var completionText = completions[0];
  6054. var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
  6055.  
  6056. this._commonPrefix = commonPrefix;
  6057. } else {
  6058. if (completions.length === 1) {
  6059. var completionText = completions[0];
  6060. wordPrefixLength = completionText.length;
  6061. } else {
  6062. var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
  6063. wordPrefixLength = commonPrefix.length;
  6064.  
  6065. if (selection.isCollapsed)
  6066. var completionText = completions[0];
  6067. else {
  6068. var currentText = fullWordRange.toString();
  6069.  
  6070. var foundIndex = null;
  6071. for (var i = 0; i < completions.length; ++i) {
  6072. if (completions[i] === currentText)
  6073. foundIndex = i;
  6074. }
  6075.  
  6076. var nextIndex = foundIndex + (reverse ? -1 : 1);
  6077. if (foundIndex === null || nextIndex >= completions.length)
  6078. var completionText = completions[0];
  6079. else if (nextIndex < 0)
  6080. var completionText = completions[completions.length - 1];
  6081. else
  6082. var completionText = completions[nextIndex];
  6083. }
  6084. }
  6085. }
  6086.  
  6087. if (auto) {
  6088. if (this.isCaretAtEndOfPrompt()) {
  6089. this._userEnteredRange.deleteContents();
  6090. this._element.pruneEmptyTextNodes();
  6091. var finalSelectionRange = document.createRange();
  6092. var prefixText = completionText.substring(0, wordPrefixLength);
  6093. var suffixText = completionText.substring(wordPrefixLength);
  6094.  
  6095. var prefixTextNode = document.createTextNode(prefixText);
  6096. fullWordRange.insertNode(prefixTextNode);
  6097.  
  6098. this.autoCompleteElement = document.createElement("span");
  6099. this.autoCompleteElement.className = "auto-complete-text";
  6100. this.autoCompleteElement.textContent = suffixText;
  6101.  
  6102. prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling);
  6103.  
  6104. finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
  6105. finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
  6106. selection.removeAllRanges();
  6107. selection.addRange(finalSelectionRange);
  6108. }
  6109. } else
  6110. this.applySuggestion(completionText, completions.length > 1, originalWordPrefixRange);
  6111. },
  6112.  
  6113. _completeCommonPrefix: function()
  6114. {
  6115. if (!this.autoCompleteElement || !this._commonPrefix || !this._userEnteredText || this._commonPrefix.indexOf(this._userEnteredText) !== 0)
  6116. return;
  6117.  
  6118. if (!this.isSuggestBoxVisible()) {
  6119. this.acceptAutoComplete();
  6120. return;
  6121. }
  6122.  
  6123. this.autoCompleteElement.textContent = this._commonPrefix.substring(this._userEnteredText.length);
  6124. this.acceptSuggestion(true)
  6125. },
  6126.  
  6127.  
  6128. applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange)
  6129. {
  6130. var wordPrefixLength;
  6131. if (originalPrefixRange)
  6132. wordPrefixLength = originalPrefixRange.toString().length;
  6133. else
  6134. wordPrefixLength = this._userEnteredText ? this._userEnteredText.length : 0;
  6135.  
  6136. this._userEnteredRange.deleteContents();
  6137. this._element.pruneEmptyTextNodes();
  6138. var finalSelectionRange = document.createRange();
  6139. var completionTextNode = document.createTextNode(completionText);
  6140. this._userEnteredRange.insertNode(completionTextNode);
  6141. if (this.autoCompleteElement && this.autoCompleteElement.parentNode) {
  6142. this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
  6143. delete this.autoCompleteElement;
  6144. }
  6145.  
  6146. if (isIntermediateSuggestion)
  6147. finalSelectionRange.setStart(completionTextNode, wordPrefixLength);
  6148. else
  6149. finalSelectionRange.setStart(completionTextNode, completionText.length);
  6150.  
  6151. finalSelectionRange.setEnd(completionTextNode, completionText.length);
  6152.  
  6153. var selection = window.getSelection();
  6154. selection.removeAllRanges();
  6155. selection.addRange(finalSelectionRange);
  6156. if (isIntermediateSuggestion)
  6157. this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied, { itemText: completionText });
  6158. },
  6159.  
  6160.  
  6161. acceptSuggestion: function(prefixAccepted)
  6162. {
  6163. if (this._isAcceptingSuggestion)
  6164. return false;
  6165.  
  6166. if (!this.autoCompleteElement || !this.autoCompleteElement.parentNode)
  6167. return false;
  6168.  
  6169. var text = this.autoCompleteElement.textContent;
  6170. var textNode = document.createTextNode(text);
  6171. this.autoCompleteElement.parentNode.replaceChild(textNode, this.autoCompleteElement);
  6172. delete this.autoCompleteElement;
  6173.  
  6174. var finalSelectionRange = document.createRange();
  6175. finalSelectionRange.setStart(textNode, text.length);
  6176. finalSelectionRange.setEnd(textNode, text.length);
  6177.  
  6178. var selection = window.getSelection();
  6179. selection.removeAllRanges();
  6180. selection.addRange(finalSelectionRange);
  6181.  
  6182. if (!prefixAccepted) {
  6183. this.hideSuggestBox();
  6184. this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepted);
  6185. } else
  6186. this.autoCompleteSoon(true);
  6187.  
  6188. return true;
  6189. },
  6190.  
  6191. hideSuggestBox: function()
  6192. {
  6193. if (this.isSuggestBoxVisible())
  6194. this._suggestBox.hide();
  6195. },
  6196.  
  6197. isSuggestBoxVisible: function()
  6198. {
  6199. return this._suggestBox && this._suggestBox.visible;
  6200. },
  6201.  
  6202. isCaretInsidePrompt: function()
  6203. {
  6204. return this._element.isInsertionCaretInside();
  6205. },
  6206.  
  6207. isCaretAtEndOfPrompt: function()
  6208. {
  6209. var selection = window.getSelection();
  6210. if (!selection.rangeCount || !selection.isCollapsed)
  6211. return false;
  6212.  
  6213. var selectionRange = selection.getRangeAt(0);
  6214. var node = selectionRange.startContainer;
  6215. if (!node.isSelfOrDescendant(this._element))
  6216. return false;
  6217.  
  6218. if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length)
  6219. return false;
  6220.  
  6221. var foundNextText = false;
  6222. while (node) {
  6223. if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
  6224. if (foundNextText && (!this.autoCompleteElement || !this.autoCompleteElement.isAncestor(node)))
  6225. return false;
  6226. foundNextText = true;
  6227. }
  6228.  
  6229. node = node.traverseNextNode(this._element);
  6230. }
  6231.  
  6232. return true;
  6233. },
  6234.  
  6235. isCaretOnFirstLine: function()
  6236. {
  6237. var selection = window.getSelection();
  6238. var focusNode = selection.focusNode;
  6239. if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
  6240. return true;
  6241.  
  6242. if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\n") !== -1)
  6243. return false;
  6244. focusNode = focusNode.previousSibling;
  6245.  
  6246. while (focusNode) {
  6247. if (focusNode.nodeType !== Node.TEXT_NODE)
  6248. return true;
  6249. if (focusNode.textContent.indexOf("\n") !== -1)
  6250. return false;
  6251. focusNode = focusNode.previousSibling;
  6252. }
  6253.  
  6254. return true;
  6255. },
  6256.  
  6257. isCaretOnLastLine: function()
  6258. {
  6259. var selection = window.getSelection();
  6260. var focusNode = selection.focusNode;
  6261. if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
  6262. return true;
  6263.  
  6264. if (focusNode.textContent.substring(selection.focusOffset).indexOf("\n") !== -1)
  6265. return false;
  6266. focusNode = focusNode.nextSibling;
  6267.  
  6268. while (focusNode) {
  6269. if (focusNode.nodeType !== Node.TEXT_NODE)
  6270. return true;
  6271. if (focusNode.textContent.indexOf("\n") !== -1)
  6272. return false;
  6273. focusNode = focusNode.nextSibling;
  6274. }
  6275.  
  6276. return true;
  6277. },
  6278.  
  6279. moveCaretToEndOfPrompt: function()
  6280. {
  6281. var selection = window.getSelection();
  6282. var selectionRange = document.createRange();
  6283.  
  6284. var offset = this._element.childNodes.length;
  6285. selectionRange.setStart(this._element, offset);
  6286. selectionRange.setEnd(this._element, offset);
  6287.  
  6288. selection.removeAllRanges();
  6289. selection.addRange(selectionRange);
  6290. },
  6291.  
  6292. tabKeyPressed: function(event)
  6293. {
  6294. this._completeCommonPrefix();
  6295.  
  6296.  
  6297. return true;
  6298. },
  6299.  
  6300. enterKeyPressed: function(event)
  6301. {
  6302. if (this.isSuggestBoxVisible())
  6303. return this._suggestBox.enterKeyPressed(event);
  6304.  
  6305. return false;
  6306. },
  6307.  
  6308. upKeyPressed: function(event)
  6309. {
  6310. if (this.isSuggestBoxVisible())
  6311. return this._suggestBox.upKeyPressed(event);
  6312.  
  6313. return false;
  6314. },
  6315.  
  6316. downKeyPressed: function(event)
  6317. {
  6318. if (this.isSuggestBoxVisible())
  6319. return this._suggestBox.downKeyPressed(event);
  6320.  
  6321. return false;
  6322. },
  6323.  
  6324. pageUpKeyPressed: function(event)
  6325. {
  6326. if (this.isSuggestBoxVisible())
  6327. return this._suggestBox.pageUpKeyPressed(event);
  6328.  
  6329. return false;
  6330. },
  6331.  
  6332. pageDownKeyPressed: function(event)
  6333. {
  6334. if (this.isSuggestBoxVisible())
  6335. return this._suggestBox.pageDownKeyPressed(event);
  6336.  
  6337. return false;
  6338. },
  6339. }
  6340.  
  6341. WebInspector.TextPrompt.prototype.__proto__ = WebInspector.Object.prototype;
  6342.  
  6343.  
  6344. WebInspector.TextPromptWithHistory = function(completions, stopCharacters)
  6345. {
  6346. WebInspector.TextPrompt.call(this, completions, stopCharacters);
  6347.  
  6348.  
  6349. this._data = [];
  6350.  
  6351.  
  6352. this._historyOffset = 1;
  6353.  
  6354.  
  6355. this._coalesceHistoryDupes = true;
  6356. }
  6357.  
  6358. WebInspector.TextPromptWithHistory.prototype = {
  6359. get historyData()
  6360. {
  6361.  
  6362. return this._data;
  6363. },
  6364.  
  6365. setCoalesceHistoryDupes: function(x)
  6366. {
  6367. this._coalesceHistoryDupes = x;
  6368. },
  6369.  
  6370.  
  6371. setHistoryData: function(data)
  6372. {
  6373. this._data = [].concat(data);
  6374. this._historyOffset = 1;
  6375. },
  6376.  
  6377.  
  6378. pushHistoryItem: function(text)
  6379. {
  6380. if (this._uncommittedIsTop) {
  6381. this._data.pop();
  6382. delete this._uncommittedIsTop;
  6383. }
  6384.  
  6385. this._historyOffset = 1;
  6386. if (this._coalesceHistoryDupes && text === this._currentHistoryItem())
  6387. return;
  6388. this._data.push(text);
  6389. },
  6390.  
  6391.  
  6392. _pushCurrentText: function()
  6393. {
  6394. if (this._uncommittedIsTop)
  6395. this._data.pop();
  6396. this._uncommittedIsTop = true;
  6397. this.clearAutoComplete(true);
  6398. this._data.push(this.text);
  6399. },
  6400.  
  6401.  
  6402. _previous: function()
  6403. {
  6404. if (this._historyOffset > this._data.length)
  6405. return undefined;
  6406. if (this._historyOffset === 1)
  6407. this._pushCurrentText();
  6408. ++this._historyOffset;
  6409. return this._currentHistoryItem();
  6410. },
  6411.  
  6412.  
  6413. _next: function()
  6414. {
  6415. if (this._historyOffset === 1)
  6416. return undefined;
  6417. --this._historyOffset;
  6418. return this._currentHistoryItem();
  6419. },
  6420.  
  6421. _currentHistoryItem: function()
  6422. {
  6423. return this._data[this._data.length - this._historyOffset];
  6424. },
  6425.  
  6426.  
  6427. defaultKeyHandler: function(event, force)
  6428. {
  6429. var newText;
  6430. var isPrevious;
  6431.  
  6432. switch (event.keyIdentifier) {
  6433. case "Up":
  6434. if (!this.isCaretOnFirstLine())
  6435. break;
  6436. newText = this._previous();
  6437. isPrevious = true;
  6438. break;
  6439. case "Down":
  6440. if (!this.isCaretOnLastLine())
  6441. break;
  6442. newText = this._next();
  6443. break;
  6444. case "U+0050":
  6445. if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
  6446. newText = this._previous();
  6447. isPrevious = true;
  6448. }
  6449. break;
  6450. case "U+004E":
  6451. if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey)
  6452. newText = this._next();
  6453. break;
  6454. }
  6455.  
  6456. if (newText !== undefined) {
  6457. event.consume(true);
  6458. this.text = newText;
  6459.  
  6460. if (isPrevious) {
  6461. var firstNewlineIndex = this.text.indexOf("\n");
  6462. if (firstNewlineIndex === -1)
  6463. this.moveCaretToEndOfPrompt();
  6464. else {
  6465. var selection = window.getSelection();
  6466. var selectionRange = document.createRange();
  6467.  
  6468. selectionRange.setStart(this._element.firstChild, firstNewlineIndex);
  6469. selectionRange.setEnd(this._element.firstChild, firstNewlineIndex);
  6470.  
  6471. selection.removeAllRanges();
  6472. selection.addRange(selectionRange);
  6473. }
  6474. }
  6475.  
  6476. return true;
  6477. }
  6478.  
  6479. return WebInspector.TextPrompt.prototype.defaultKeyHandler.apply(this, arguments);
  6480. }
  6481. }
  6482.  
  6483. WebInspector.TextPromptWithHistory.prototype.__proto__ = WebInspector.TextPrompt.prototype;
  6484.  
  6485.  
  6486. WebInspector.TextPrompt.SuggestBox = function(textPrompt, inputElement, className)
  6487. {
  6488. this._textPrompt = textPrompt;
  6489. this._inputElement = inputElement;
  6490. this._selectedElement = null;
  6491. this._boundOnScroll = this._onscrollresize.bind(this, true);
  6492. this._boundOnResize = this._onscrollresize.bind(this, false);
  6493. window.addEventListener("scroll", this._boundOnScroll, true);
  6494. window.addEventListener("resize", this._boundOnResize, true);
  6495.  
  6496. this._bodyElement = inputElement.ownerDocument.body;
  6497. this._element = inputElement.ownerDocument.createElement("div");
  6498. this._element.className = "suggest-box " + (className || "");
  6499. this._element.addEventListener("mousedown", this._onboxmousedown.bind(this), true);
  6500. this.containerElement = this._element.createChild("div", "container");
  6501. this.contentElement = this.containerElement.createChild("div", "content");
  6502. }
  6503.  
  6504. WebInspector.TextPrompt.SuggestBox.prototype = {
  6505. get visible()
  6506. {
  6507. return !!this._element.parentElement;
  6508. },
  6509.  
  6510. get hasSelection()
  6511. {
  6512. return !!this._selectedElement;
  6513. },
  6514.  
  6515. _onscrollresize: function(isScroll, event)
  6516. {
  6517. if (isScroll && this._element.isAncestor(event.target) || !this.visible)
  6518. return;
  6519. this._updateBoxPositionWithExistingAnchor();
  6520. },
  6521.  
  6522. _updateBoxPositionWithExistingAnchor: function()
  6523. {
  6524. this._updateBoxPosition(this._anchorBox);
  6525. },
  6526.  
  6527.  
  6528. _updateBoxPosition: function(anchorBox)
  6529. {
  6530.  
  6531. this.contentElement.style.display = "inline-block";
  6532. document.body.appendChild(this.contentElement);
  6533. this.contentElement.positionAt(0, 0);
  6534. var contentWidth = this.contentElement.offsetWidth;
  6535. var contentHeight = this.contentElement.offsetHeight;
  6536. this.contentElement.style.display = "block";
  6537. this.containerElement.appendChild(this.contentElement);
  6538.  
  6539.  
  6540. this._anchorBox = anchorBox;
  6541. const spacer = 6;
  6542.  
  6543. const suggestBoxPaddingX = 21;
  6544. var maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
  6545. var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
  6546. var paddedWidth = contentWidth + suggestBoxPaddingX;
  6547. var boxX = anchorBox.x;
  6548. if (width < paddedWidth) {
  6549.  
  6550. maxWidth = document.body.offsetWidth - spacer;
  6551. width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
  6552. boxX = document.body.offsetWidth - width;
  6553. }
  6554.  
  6555. const suggestBoxPaddingY = 2;
  6556. var boxY;
  6557. var aboveHeight = anchorBox.y;
  6558. var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height;
  6559. var maxHeight = Math.max(underHeight, aboveHeight) - spacer;
  6560. var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY;
  6561. if (underHeight >= aboveHeight) {
  6562.  
  6563. boxY = anchorBox.y + anchorBox.height;
  6564. this._element.removeStyleClass("above-anchor");
  6565. this._element.addStyleClass("under-anchor");
  6566. } else {
  6567.  
  6568. boxY = anchorBox.y - height;
  6569. this._element.removeStyleClass("under-anchor");
  6570. this._element.addStyleClass("above-anchor");
  6571. }
  6572.  
  6573. this._element.positionAt(boxX, boxY);
  6574. this._element.style.width = width + "px";
  6575. this._element.style.height = height + "px";
  6576. },
  6577.  
  6578. _onboxmousedown: function(event)
  6579. {
  6580. event.preventDefault();
  6581. },
  6582.  
  6583. hide: function()
  6584. {
  6585. if (!this.visible)
  6586. return;
  6587.  
  6588. this._element.parentElement.removeChild(this._element);
  6589. delete this._selectedElement;
  6590. },
  6591.  
  6592. removeFromElement: function()
  6593. {
  6594. window.removeEventListener("scroll", this._boundOnScroll, true);
  6595. window.removeEventListener("resize", this._boundOnResize, true);
  6596. this.hide();
  6597. },
  6598.  
  6599.  
  6600. _applySuggestion: function(text, isIntermediateSuggestion)
  6601. {
  6602. if (!this.visible || !(text || this._selectedElement))
  6603. return false;
  6604.  
  6605. var suggestion = text || this._selectedElement.textContent;
  6606. if (!suggestion)
  6607. return false;
  6608.  
  6609. this._textPrompt.applySuggestion(suggestion, isIntermediateSuggestion);
  6610. return true;
  6611. },
  6612.  
  6613.  
  6614. acceptSuggestion: function(text)
  6615. {
  6616. var result = this._applySuggestion(text, false);
  6617. this.hide();
  6618. if (!result)
  6619. return false;
  6620.  
  6621. this._textPrompt.acceptSuggestion();
  6622.  
  6623. return true;
  6624. },
  6625.  
  6626. _onNextItem: function(event, isPageScroll)
  6627. {
  6628. var children = this.contentElement.childNodes;
  6629. if (!children.length)
  6630. return false;
  6631.  
  6632. if (!this._selectedElement)
  6633. this._selectedElement = this.contentElement.firstChild;
  6634. else {
  6635. if (!isPageScroll)
  6636. this._selectedElement = this._selectedElement.nextSibling || this.contentElement.firstChild;
  6637. else {
  6638. var candidate = this._selectedElement;
  6639.  
  6640. for (var itemsLeft = this._rowCountPerViewport; itemsLeft; --itemsLeft) {
  6641. if (candidate.nextSibling)
  6642. candidate = candidate.nextSibling;
  6643. else
  6644. break;
  6645. }
  6646.  
  6647. this._selectedElement = candidate;
  6648. }
  6649. }
  6650. this._updateSelection();
  6651. this._applySuggestion(undefined, true);
  6652. return true;
  6653. },
  6654.  
  6655. _onPreviousItem: function(event, isPageScroll)
  6656. {
  6657. var children = this.contentElement.childNodes;
  6658. if (!children.length)
  6659. return false;
  6660.  
  6661. if (!this._selectedElement)
  6662. this._selectedElement = this.contentElement.lastChild;
  6663. else {
  6664. if (!isPageScroll)
  6665. this._selectedElement = this._selectedElement.previousSibling || this.contentElement.lastChild;
  6666. else {
  6667. var candidate = this._selectedElement;
  6668.  
  6669. for (var itemsLeft = this._rowCountPerViewport; itemsLeft; --itemsLeft) {
  6670. if (candidate.previousSibling)
  6671. candidate = candidate.previousSibling;
  6672. else
  6673. break;
  6674. }
  6675.  
  6676. this._selectedElement = candidate;
  6677. }
  6678. }
  6679. this._updateSelection();
  6680. this._applySuggestion(undefined, true);
  6681. return true;
  6682. },
  6683.  
  6684.  
  6685. updateSuggestions: function(anchorBox, completions, canShowForSingleItem)
  6686. {
  6687. if (this._suggestTimeout) {
  6688. clearTimeout(this._suggestTimeout);
  6689. delete this._suggestTimeout;
  6690. }
  6691. this._completionsReady(anchorBox, completions, canShowForSingleItem);
  6692. },
  6693.  
  6694. _onItemMouseDown: function(text, event)
  6695. {
  6696. this.acceptSuggestion(text);
  6697. event.consume(true);
  6698. },
  6699.  
  6700. _createItemElement: function(prefix, text)
  6701. {
  6702. var element = document.createElement("div");
  6703. element.className = "suggest-box-content-item source-code";
  6704. element.tabIndex = -1;
  6705. if (prefix && prefix.length && !text.indexOf(prefix)) {
  6706. var prefixElement = element.createChild("span", "prefix");
  6707. prefixElement.textContent = prefix;
  6708. var suffixElement = element.createChild("span", "suffix");
  6709. suffixElement.textContent = text.substring(prefix.length);
  6710. } else {
  6711. var suffixElement = element.createChild("span", "suffix");
  6712. suffixElement.textContent = text;
  6713. }
  6714. element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false);
  6715. return element;
  6716. },
  6717.  
  6718.  
  6719. _updateItems: function(items, canShowForSingleItem)
  6720. {
  6721. this.contentElement.removeChildren();
  6722.  
  6723. var userEnteredText = this._textPrompt._userEnteredText;
  6724. for (var i = 0; i < items.length; ++i) {
  6725. var item = items[i];
  6726. var currentItemElement = this._createItemElement(userEnteredText, item);
  6727. this.contentElement.appendChild(currentItemElement);
  6728. }
  6729.  
  6730. this._selectedElement = canShowForSingleItem ? this.contentElement.firstChild : null;
  6731. this._updateSelection();
  6732. },
  6733.  
  6734. _updateSelection: function()
  6735. {
  6736.  
  6737. for (var child = this.contentElement.firstChild; child; child = child.nextSibling) {
  6738. if (child !== this._selectedElement)
  6739. child.removeStyleClass("selected");
  6740. }
  6741. if (this._selectedElement) {
  6742. this._selectedElement.addStyleClass("selected");
  6743. this._selectedElement.scrollIntoViewIfNeeded(false);
  6744. }
  6745. },
  6746.  
  6747.  
  6748. _canShowBox: function(completions, canShowForSingleItem)
  6749. {
  6750. if (!completions || !completions.length)
  6751. return false;
  6752.  
  6753. if (completions.length > 1)
  6754. return true;
  6755.  
  6756.  
  6757. return canShowForSingleItem && completions[0] !== this._textPrompt._userEnteredText;
  6758. },
  6759.  
  6760. _rememberRowCountPerViewport: function()
  6761. {
  6762. if (!this.contentElement.firstChild)
  6763. return;
  6764.  
  6765. this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight);
  6766. },
  6767.  
  6768.  
  6769. _completionsReady: function(anchorBox, completions, canShowForSingleItem)
  6770. {
  6771. if (this._canShowBox(completions, canShowForSingleItem)) {
  6772. this._updateItems(completions, canShowForSingleItem);
  6773. this._updateBoxPosition(anchorBox);
  6774. if (!this.visible)
  6775. this._bodyElement.appendChild(this._element);
  6776. this._rememberRowCountPerViewport();
  6777. } else
  6778. this.hide();
  6779. },
  6780.  
  6781. upKeyPressed: function(event)
  6782. {
  6783. return this._onPreviousItem(event, false);
  6784. },
  6785.  
  6786. downKeyPressed: function(event)
  6787. {
  6788. return this._onNextItem(event, false);
  6789. },
  6790.  
  6791. pageUpKeyPressed: function(event)
  6792. {
  6793. return this._onPreviousItem(event, true);
  6794. },
  6795.  
  6796. pageDownKeyPressed: function(event)
  6797. {
  6798. return this._onNextItem(event, true);
  6799. },
  6800.  
  6801. enterKeyPressed: function(event)
  6802. {
  6803. var hasSelectedItem = !!this._selectedElement;
  6804. this.acceptSuggestion();
  6805.  
  6806.  
  6807.  
  6808. return hasSelectedItem;
  6809. },
  6810.  
  6811. tabKeyPressed: function(event)
  6812. {
  6813. return this.enterKeyPressed(event);
  6814. }
  6815. }
  6816.  
  6817.  
  6818.  
  6819.  
  6820.  
  6821.  
  6822. WebInspector.Popover = function(popoverHelper)
  6823. {
  6824. this.element = document.createElement("div");
  6825. this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll";
  6826.  
  6827. this._popupArrowElement = document.createElement("div");
  6828. this._popupArrowElement.className = "arrow";
  6829. this.element.appendChild(this._popupArrowElement);
  6830.  
  6831. this._contentDiv = document.createElement("div");
  6832. this._contentDiv.className = "content";
  6833. this._visible = false;
  6834. this._popoverHelper = popoverHelper;
  6835. }
  6836.  
  6837. WebInspector.Popover.prototype = {
  6838.  
  6839. show: function(contentElement, anchor, preferredWidth, preferredHeight)
  6840. {
  6841. if (this._disposed)
  6842. return;
  6843. this.contentElement = contentElement;
  6844.  
  6845.  
  6846. if (WebInspector.Popover._popoverElement)
  6847. document.body.removeChild(WebInspector.Popover._popoverElement);
  6848. WebInspector.Popover._popoverElement = this.element;
  6849.  
  6850.  
  6851. this.contentElement.positionAt(0, 0);
  6852. document.body.appendChild(this.contentElement);
  6853. preferredWidth = preferredWidth || this.contentElement.offsetWidth;
  6854. preferredHeight = preferredHeight || this.contentElement.offsetHeight;
  6855.  
  6856. this._contentDiv.appendChild(this.contentElement);
  6857. this.element.appendChild(this._contentDiv);
  6858. document.body.appendChild(this.element);
  6859. this._positionElement(anchor, preferredWidth, preferredHeight);
  6860. this._visible = true;
  6861. if (this._popoverHelper)
  6862. contentElement.addEventListener("mousemove", this._popoverHelper._killHidePopoverTimer.bind(this._popoverHelper), true);
  6863. },
  6864.  
  6865. hide: function()
  6866. {
  6867. if (WebInspector.Popover._popoverElement) {
  6868. delete WebInspector.Popover._popoverElement;
  6869. document.body.removeChild(this.element);
  6870. }
  6871. this._visible = false;
  6872. },
  6873.  
  6874. get visible()
  6875. {
  6876. return this._visible;
  6877. },
  6878.  
  6879. get disposed()
  6880. {
  6881. return this._disposed;
  6882. },
  6883.  
  6884. dispose: function()
  6885. {
  6886. if (this.visible)
  6887. this.hide();
  6888. this._disposed = true;
  6889. },
  6890.  
  6891. setCanShrink: function(canShrink)
  6892. {
  6893. this._hasFixedHeight = !canShrink;
  6894. this._contentDiv.addStyleClass("fixed-height");
  6895. },
  6896.  
  6897. _positionElement: function(anchorElement, preferredWidth, preferredHeight)
  6898. {
  6899. const borderWidth = 25;
  6900. const scrollerWidth = this._hasFixedHeight ? 0 : 11;
  6901. const arrowHeight = 15;
  6902. const arrowOffset = 10;
  6903. const borderRadius = 10;
  6904.  
  6905.  
  6906. preferredWidth = Math.max(preferredWidth, 50);
  6907. const totalWidth = window.innerWidth;
  6908. const totalHeight = window.innerHeight;
  6909.  
  6910. var anchorBox = anchorElement.boxInWindow(window);
  6911. var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };
  6912.  
  6913. var verticalAlignment;
  6914. var roomAbove = anchorBox.y;
  6915. var roomBelow = totalHeight - anchorBox.y - anchorBox.height;
  6916.  
  6917. if (roomAbove > roomBelow) {
  6918.  
  6919. if (anchorBox.y > newElementPosition.height + arrowHeight + borderRadius)
  6920. newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
  6921. else {
  6922. newElementPosition.y = borderRadius;
  6923. newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
  6924. if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
  6925. newElementPosition.y = borderRadius;
  6926. newElementPosition.height = preferredHeight;
  6927. }
  6928. }
  6929. verticalAlignment = "bottom";
  6930. } else {
  6931.  
  6932. newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
  6933. if (newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight) {
  6934. newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;
  6935. if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
  6936. newElementPosition.y = totalHeight - preferredHeight - borderRadius;
  6937. newElementPosition.height = preferredHeight;
  6938. }
  6939. }
  6940.  
  6941. verticalAlignment = "top";
  6942. }
  6943.  
  6944. var horizontalAlignment;
  6945. if (anchorBox.x + newElementPosition.width < totalWidth) {
  6946. newElementPosition.x = Math.max(borderRadius, anchorBox.x - borderRadius - arrowOffset);
  6947. horizontalAlignment = "left";
  6948. } else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
  6949. newElementPosition.x = totalWidth - newElementPosition.width - borderRadius;
  6950. horizontalAlignment = "right";
  6951.  
  6952. var arrowRightPosition = Math.max(0, totalWidth - anchorBox.x - anchorBox.width - borderRadius - arrowOffset);
  6953. arrowRightPosition += anchorBox.width / 2;
  6954. arrowRightPosition = Math.min(arrowRightPosition, newElementPosition.width - borderRadius - arrowOffset);
  6955. this._popupArrowElement.style.right = arrowRightPosition + "px";
  6956. } else {
  6957. newElementPosition.x = borderRadius;
  6958. newElementPosition.width = totalWidth - borderRadius * 2;
  6959. newElementPosition.height += scrollerWidth;
  6960. horizontalAlignment = "left";
  6961. if (verticalAlignment === "bottom")
  6962. newElementPosition.y -= scrollerWidth;
  6963.  
  6964. this._popupArrowElement.style.left = Math.max(0, anchorBox.x - borderRadius * 2 - arrowOffset) + "px";
  6965. this._popupArrowElement.style.left += anchorBox.width / 2;
  6966. }
  6967.  
  6968. this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
  6969. this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth);
  6970. this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
  6971. this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
  6972. }
  6973. }
  6974.  
  6975.  
  6976. WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopover, onHide, disableOnClick)
  6977. {
  6978. this._panelElement = panelElement;
  6979. this._getAnchor = getAnchor;
  6980. this._showPopover = showPopover;
  6981. this._onHide = onHide;
  6982. this._disableOnClick = !!disableOnClick;
  6983. panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
  6984. panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
  6985. this.setTimeout(1000);
  6986. }
  6987.  
  6988. WebInspector.PopoverHelper.prototype = {
  6989. setTimeout: function(timeout)
  6990. {
  6991. this._timeout = timeout;
  6992. },
  6993.  
  6994. _mouseDown: function(event)
  6995. {
  6996. if (this._disableOnClick)
  6997. this.hidePopover();
  6998. else {
  6999. this._killHidePopoverTimer();
  7000. this._handleMouseAction(event, true);
  7001. }
  7002. },
  7003.  
  7004. _mouseMove: function(event)
  7005. {
  7006.  
  7007. if (event.target.isSelfOrDescendant(this._hoverElement))
  7008. return;
  7009.  
  7010.  
  7011. if (this._popover && !this._hidePopoverTimer) {
  7012. var self = this;
  7013. function doHide()
  7014. {
  7015. self._hidePopover();
  7016. delete self._hidePopoverTimer;
  7017. }
  7018. this._hidePopoverTimer = setTimeout(doHide, this._timeout / 2);
  7019. }
  7020.  
  7021. this._handleMouseAction(event, false);
  7022. },
  7023.  
  7024. _handleMouseAction: function(event, isMouseDown)
  7025. {
  7026. this._resetHoverTimer();
  7027. if (event.which && this._disableOnClick)
  7028. return;
  7029. this._hoverElement = this._getAnchor(event.target, event);
  7030. if (!this._hoverElement)
  7031. return;
  7032. const toolTipDelay = isMouseDown ? 0 : (this._popup ? this._timeout * 0.6 : this._timeout);
  7033. this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
  7034. },
  7035.  
  7036. _resetHoverTimer: function()
  7037. {
  7038. if (this._hoverTimer) {
  7039. clearTimeout(this._hoverTimer);
  7040. delete this._hoverTimer;
  7041. }
  7042. },
  7043.  
  7044. isPopoverVisible: function()
  7045. {
  7046. return !!this._popover;
  7047. },
  7048.  
  7049. hidePopover: function()
  7050. {
  7051. this._resetHoverTimer();
  7052. this._hidePopover();
  7053. },
  7054.  
  7055. _hidePopover: function()
  7056. {
  7057. if (!this._popover)
  7058. return;
  7059.  
  7060. if (this._onHide)
  7061. this._onHide();
  7062.  
  7063. this._popover.dispose();
  7064. delete this._popover;
  7065. },
  7066.  
  7067. _mouseHover: function(element)
  7068. {
  7069. delete this._hoverTimer;
  7070.  
  7071. this._hidePopover();
  7072. this._popover = new WebInspector.Popover(this);
  7073. this._showPopover(element, this._popover);
  7074. },
  7075.  
  7076. _killHidePopoverTimer: function()
  7077. {
  7078. if (this._hidePopoverTimer) {
  7079. clearTimeout(this._hidePopoverTimer);
  7080. delete this._hidePopoverTimer;
  7081.  
  7082.  
  7083.  
  7084. this._resetHoverTimer();
  7085. }
  7086. }
  7087. }
  7088.  
  7089.  
  7090.  
  7091.  
  7092.  
  7093.  
  7094. WebInspector.Placard = function(title, subtitle)
  7095. {
  7096. this.element = document.createElement("div");
  7097. this.element.className = "placard";
  7098. this.element.placard = this;
  7099.  
  7100. this.titleElement = document.createElement("div");
  7101. this.titleElement.className = "title";
  7102.  
  7103. this.subtitleElement = document.createElement("div");
  7104. this.subtitleElement.className = "subtitle";
  7105.  
  7106. this.element.appendChild(this.subtitleElement);
  7107. this.element.appendChild(this.titleElement);
  7108.  
  7109. this.title = title;
  7110. this.subtitle = subtitle;
  7111. this.selected = false;
  7112. }
  7113.  
  7114. WebInspector.Placard.prototype = {
  7115.  
  7116. get title()
  7117. {
  7118. return this._title;
  7119. },
  7120.  
  7121. set title(x)
  7122. {
  7123. if (this._title === x)
  7124. return;
  7125. this._title = x;
  7126. this.titleElement.textContent = x;
  7127. },
  7128.  
  7129.  
  7130. get subtitle()
  7131. {
  7132. return this._subtitle;
  7133. },
  7134.  
  7135. set subtitle(x)
  7136. {
  7137. if (this._subtitle === x)
  7138. return;
  7139. this._subtitle = x;
  7140. this.subtitleElement.textContent = x;
  7141. },
  7142.  
  7143.  
  7144. get selected()
  7145. {
  7146. return this._selected;
  7147. },
  7148.  
  7149. set selected(x)
  7150. {
  7151. if (x)
  7152. this.select();
  7153. else
  7154. this.deselect();
  7155. },
  7156.  
  7157. select: function()
  7158. {
  7159. if (this._selected)
  7160. return;
  7161. this._selected = true;
  7162. this.element.addStyleClass("selected");
  7163. },
  7164.  
  7165. deselect: function()
  7166. {
  7167. if (!this._selected)
  7168. return;
  7169. this._selected = false;
  7170. this.element.removeStyleClass("selected");
  7171. },
  7172.  
  7173. toggleSelected: function()
  7174. {
  7175. this.selected = !this.selected;
  7176. },
  7177.  
  7178. discard: function()
  7179. {
  7180. }
  7181. }
  7182.  
  7183.  
  7184.  
  7185.  
  7186.  
  7187.  
  7188. WebInspector.View = function()
  7189. {
  7190. this.element = document.createElement("div");
  7191. this.element.__view = this;
  7192. this._visible = true;
  7193. this._isRoot = false;
  7194. this._isShowing = false;
  7195. this._children = [];
  7196. this._hideOnDetach = false;
  7197. this._cssFiles = [];
  7198. }
  7199.  
  7200. WebInspector.View._cssFileToVisibleViewCount = {};
  7201. WebInspector.View._cssFileToStyleElement = {};
  7202.  
  7203. WebInspector.View.prototype = {
  7204. markAsRoot: function()
  7205. {
  7206. this._isRoot = true;
  7207. },
  7208.  
  7209. isShowing: function()
  7210. {
  7211. return this._isShowing;
  7212. },
  7213.  
  7214. setHideOnDetach: function()
  7215. {
  7216. this._hideOnDetach = true;
  7217. },
  7218.  
  7219. _parentIsShowing: function()
  7220. {
  7221. return this._isRoot || (this._parentView && this._parentView.isShowing());
  7222. },
  7223.  
  7224. _callOnVisibleChildren: function(method)
  7225. {
  7226. for (var i = 0; i < this._children.length; ++i)
  7227. if (this._children[i]._visible)
  7228. method.call(this._children[i]);
  7229. },
Add Comment
Please, Sign In to add comment