OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Based heavily on code from the Google iOS app. | 6 * Based heavily on code from the Google iOS app. |
7 * | 7 * |
8 * @fileoverview A find in page tool. It scans the DOM for elements with the | 8 * @fileoverview A find in page tool. It scans the DOM for elements with the |
9 * text being search for, and wraps them with a span that highlights them. | 9 * text being search for, and wraps them with a span that highlights them. |
10 */ | 10 */ |
11 | 11 |
12 /** | 12 /** |
13 * Namespace for this file. Depends on __gCrWeb having already been injected. | 13 * Namespace for this file. Depends on __gCrWeb having already been injected. |
14 */ | 14 */ |
15 __gCrWeb['findInPage'] = {}; | 15 __gCrWeb['findInPage'] = {}; |
16 | 16 |
17 /** | 17 /** |
18 * Index of the current highlighted choice. -1 means none. | 18 * Index of the current highlighted choice. -1 means none. |
19 * @type {number} | 19 * @type {number} |
20 */ | 20 */ |
21 __gCrWeb['findInPage']['index'] = -1; | 21 __gCrWeb['findInPage']['index'] = -1; |
22 | 22 |
23 /** | 23 /** |
24 * The list of found searches in span form. | 24 * The list of found searches in span form. |
25 * @type {Array.<Element>} | 25 * @type {Array<Element>} |
26 */ | 26 */ |
27 __gCrWeb['findInPage']['spans'] = []; | 27 __gCrWeb['findInPage']['spans'] = []; |
28 | 28 |
29 /** | 29 /** |
30 * The list of frame documents. | 30 * The list of frame documents. |
31 * TODO(justincohen): x-domain frames won't work. | 31 * TODO(justincohen): x-domain frames won't work. |
32 * @type {Array.<Document>} | 32 * @type {Array<Document>} |
33 */ | 33 */ |
34 __gCrWeb['findInPage'].frameDocs = []; | 34 __gCrWeb['findInPage'].frameDocs = []; |
35 | 35 |
36 /** | 36 /** |
37 * Associate array to stash element styles while the element is highlighted. | 37 * Associate array to stash element styles while the element is highlighted. |
38 * @type {Object.<Element,Object<string,string>>} | 38 * @type {Object<Element,Object<string,string>>} |
39 */ | 39 */ |
40 __gCrWeb['findInPage'].savedElementStyles = {}; | 40 __gCrWeb['findInPage'].savedElementStyles = {}; |
41 | 41 |
42 /** | 42 /** |
43 * The style DOM element that we add. | 43 * The style DOM element that we add. |
44 * @type {Element} | 44 * @type {Element} |
45 */ | 45 */ |
46 __gCrWeb['findInPage'].style = null; | 46 __gCrWeb['findInPage'].style = null; |
47 | 47 |
48 /** | 48 /** |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 element.style[style] = savedStyles[style]; | 614 element.style[style] = savedStyles[style]; |
615 } | 615 } |
616 delete __gCrWeb['findInPage'].savedElementStyles[element]; | 616 delete __gCrWeb['findInPage'].savedElementStyles[element]; |
617 } | 617 } |
618 }; | 618 }; |
619 | 619 |
620 /** | 620 /** |
621 * Normalize coordinates according to the current document dimensions. Don't go | 621 * Normalize coordinates according to the current document dimensions. Don't go |
622 * too far off the screen in either direction. Try to center if possible. | 622 * too far off the screen in either direction. Try to center if possible. |
623 * @param {Element} elem Element to find normalized coordinates for. | 623 * @param {Element} elem Element to find normalized coordinates for. |
624 * @return {Array.<number>} Normalized coordinates. | 624 * @return {Array<number>} Normalized coordinates. |
625 */ | 625 */ |
626 __gCrWeb['findInPage'].getNormalizedCoordinates = function(elem) { | 626 __gCrWeb['findInPage'].getNormalizedCoordinates = function(elem) { |
627 var fip = __gCrWeb['findInPage']; | 627 var fip = __gCrWeb['findInPage']; |
628 var pos = fip.findAbsolutePosition(elem); | 628 var pos = fip.findAbsolutePosition(elem); |
629 var maxX = | 629 var maxX = |
630 Math.max(fip.getBodyWidth(), pos[0] + elem.offsetWidth); | 630 Math.max(fip.getBodyWidth(), pos[0] + elem.offsetWidth); |
631 var maxY = | 631 var maxY = |
632 Math.max(fip.getBodyHeight(), pos[1] + elem.offsetHeight); | 632 Math.max(fip.getBodyHeight(), pos[1] + elem.offsetHeight); |
633 // Don't go too far off the screen in either direction. Try to center if | 633 // Don't go too far off the screen in either direction. Try to center if |
634 // possible. | 634 // possible. |
635 var xPos = Math.max(0, | 635 var xPos = Math.max(0, |
636 Math.min(maxX - window.innerWidth, | 636 Math.min(maxX - window.innerWidth, |
637 pos[0] - (window.innerWidth / 2))); | 637 pos[0] - (window.innerWidth / 2))); |
638 var yPos = Math.max(0, | 638 var yPos = Math.max(0, |
639 Math.min(maxY - window.innerHeight, | 639 Math.min(maxY - window.innerHeight, |
640 pos[1] - (window.innerHeight / 2))); | 640 pos[1] - (window.innerHeight / 2))); |
641 return [xPos, yPos]; | 641 return [xPos, yPos]; |
642 }; | 642 }; |
643 | 643 |
644 /** | 644 /** |
645 * Scale coordinates according to the width of the screen, in case the screen | 645 * Scale coordinates according to the width of the screen, in case the screen |
646 * is zoomed out. | 646 * is zoomed out. |
647 * @param {Array.<number>} coordinates Coordinates to scale. | 647 * @param {Array<number>} coordinates Coordinates to scale. |
648 * @return {Array.<number>} Scaled coordinates. | 648 * @return {Array<number>} Scaled coordinates. |
649 */ | 649 */ |
650 __gCrWeb['findInPage'].scaleCoordinates = function(coordinates) { | 650 __gCrWeb['findInPage'].scaleCoordinates = function(coordinates) { |
651 var scaleFactor = __gCrWeb['findInPage'].pageWidth / window.innerWidth; | 651 var scaleFactor = __gCrWeb['findInPage'].pageWidth / window.innerWidth; |
652 return [coordinates[0] * scaleFactor, coordinates[1] * scaleFactor]; | 652 return [coordinates[0] * scaleFactor, coordinates[1] * scaleFactor]; |
653 }; | 653 }; |
654 | 654 |
655 /** | 655 /** |
656 * Finds the position of the result and scrolls to it. | 656 * Finds the position of the result and scrolls to it. |
657 * @param {number} opt_index Index to replace __gCrWeb['findInPage']['index'] | 657 * @param {number} opt_index Index to replace __gCrWeb['findInPage']['index'] |
658 * with. | 658 * with. |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 | 907 |
908 elem = elem.parentNode; | 908 elem = elem.parentNode; |
909 computedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, null); | 909 computedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, null); |
910 } | 910 } |
911 return true; | 911 return true; |
912 }; | 912 }; |
913 | 913 |
914 /** | 914 /** |
915 * Helper function to find the absolute position of an element on the page. | 915 * Helper function to find the absolute position of an element on the page. |
916 * @param {Element} elem Element to check. | 916 * @param {Element} elem Element to check. |
917 * @return {Array.<number>} [x, y] positions. | 917 * @return {Array<number>} [x, y] positions. |
918 */ | 918 */ |
919 __gCrWeb['findInPage'].findAbsolutePosition = function(elem) { | 919 __gCrWeb['findInPage'].findAbsolutePosition = function(elem) { |
920 var boundingRect = elem.getBoundingClientRect(); | 920 var boundingRect = elem.getBoundingClientRect(); |
921 return [boundingRect.left + window.pageXOffset, | 921 return [boundingRect.left + window.pageXOffset, |
922 boundingRect.top + window.pageYOffset]; | 922 boundingRect.top + window.pageYOffset]; |
923 }; | 923 }; |
924 | 924 |
925 /** | 925 /** |
926 * @param {string} text Text to escape. | 926 * @param {string} text Text to escape. |
927 * @return {string} escaped text. | 927 * @return {string} escaped text. |
928 */ | 928 */ |
929 __gCrWeb['findInPage'].escapeHTML = function(text) { | 929 __gCrWeb['findInPage'].escapeHTML = function(text) { |
930 var unusedDiv = document.createElement('div'); | 930 var unusedDiv = document.createElement('div'); |
931 unusedDiv.innerText = text; | 931 unusedDiv.innerText = text; |
932 return unusedDiv.innerHTML; | 932 return unusedDiv.innerHTML; |
933 }; | 933 }; |
934 | 934 |
935 /** | 935 /** |
936 * Escapes regexp special characters. | 936 * Escapes regexp special characters. |
937 * @param {string} text Text to escape. | 937 * @param {string} text Text to escape. |
938 * @return {string} escaped text. | 938 * @return {string} escaped text. |
939 */ | 939 */ |
940 __gCrWeb['findInPage'].escapeRegex = function(text) { | 940 __gCrWeb['findInPage'].escapeRegex = function(text) { |
941 return text.replace(__gCrWeb['findInPage'].REGEX_ESCAPER, '\\$1'); | 941 return text.replace(__gCrWeb['findInPage'].REGEX_ESCAPER, '\\$1'); |
942 }; | 942 }; |
943 | 943 |
944 /** | 944 /** |
945 * Gather all iframes in the main window. | 945 * Gather all iframes in the main window. |
946 * @return {Array.<Document>} frames. | 946 * @return {Array<Document>} frames. |
947 */ | 947 */ |
948 __gCrWeb['findInPage'].frameDocuments = function() { | 948 __gCrWeb['findInPage'].frameDocuments = function() { |
949 var windowsToSearch = [window]; | 949 var windowsToSearch = [window]; |
950 var documents = []; | 950 var documents = []; |
951 while (windowsToSearch.length != 0) { | 951 while (windowsToSearch.length != 0) { |
952 var win = windowsToSearch.pop(); | 952 var win = windowsToSearch.pop(); |
953 for (var i = win.frames.length - 1; i >= 0; i--) { | 953 for (var i = win.frames.length - 1; i >= 0; i--) { |
954 if (win.frames[i].document) { | 954 if (win.frames[i].document) { |
955 documents.push(win.frames[i].document); | 955 documents.push(win.frames[i].document); |
956 windowsToSearch.push(win.frames[i]); | 956 windowsToSearch.push(win.frames[i]); |
957 } | 957 } |
958 } | 958 } |
959 } | 959 } |
960 return documents; | 960 return documents; |
961 }; | 961 }; |
OLD | NEW |