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

Side by Side Diff: chrome/browser/resources/new_new_tab.js

Issue 149163: A couple of NNTP bug fixes (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/new_new_tab.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 // Helpers 2 // Helpers
3 3
4 function $(id) { 4 function $(id) {
5 return document.getElementById(id); 5 return document.getElementById(id);
6 } 6 }
7 7
8 // TODO(arv): Remove these when classList is available in HTML5. 8 // TODO(arv): Remove these when classList is available in HTML5.
9 // https://bugs.webkit.org/show_bug.cgi?id=20709 9 // https://bugs.webkit.org/show_bug.cgi?id=20709
10 function hasClass(el, name) { 10 function hasClass(el, name) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 var newClassName = getThumbnailClassName(d); 172 var newClassName = getThumbnailClassName(d);
173 if (oldClassName != newClassName) { 173 if (oldClassName != newClassName) {
174 t.className = newClassName; 174 t.className = newClassName;
175 } 175 }
176 176
177 // No need to continue if this is a filler. 177 // No need to continue if this is a filler.
178 if (newClassName == 'thumbnail-container filler') { 178 if (newClassName == 'thumbnail-container filler') {
179 continue; 179 continue;
180 } 180 }
181 181
182 t.title = d.title;
183 t.href = d.url; 182 t.href = d.url;
184 t.querySelector('.pin').title = localStrings.getString(d.pinned ? 183 t.querySelector('.pin').title = localStrings.getString(d.pinned ?
185 'unpinthumbnailtooltip' : 'pinthumbnailtooltip'); 184 'unpinthumbnailtooltip' : 'pinthumbnailtooltip');
186 t.querySelector('.remove').title = 185 t.querySelector('.remove').title =
187 localStrings.getString('removethumbnailtooltip'); 186 localStrings.getString('removethumbnailtooltip');
188 187
189 // There was some concern that a malformed malicious URL could cause an XSS 188 // There was some concern that a malformed malicious URL could cause an XSS
190 // attack but setting style.backgroundImage = 'url(javascript:...)' does 189 // attack but setting style.backgroundImage = 'url(javascript:...)' does
191 // not execute the JavaScript in WebKit. 190 // not execute the JavaScript in WebKit.
192 t.querySelector('.thumbnail-wrapper').style.backgroundImage = 191 t.querySelector('.thumbnail-wrapper').style.backgroundImage =
193 'url(chrome://thumb/' + d.url + ')'; 192 'url("chrome://thumb/' + d.url + '")';
194 var titleDiv = t.querySelector('.title > div'); 193 var titleDiv = t.querySelector('.title > div');
195 titleDiv.textContent = d.title; 194 titleDiv.title = titleDiv.textContent = d.title;
196 titleDiv.style.backgroundImage = 'url(chrome://favicon/' + d.url + ')'; 195 titleDiv.style.backgroundImage = 'url("chrome://favicon/' + d.url + '")';
197 titleDiv.dir = d.direction; 196 titleDiv.dir = d.direction;
198 } 197 }
199 } 198 }
200 199
201 /** 200 /**
202 * Calls chrome.send with a callback and restores the original afterwards. 201 * Calls chrome.send with a callback and restores the original afterwards.
203 */ 202 */
204 function chromeSend(name, params, callbackName, callback) { 203 function chromeSend(name, params, callbackName, callback) {
205 var old = global[callbackName]; 204 var old = global[callbackName];
206 global[callbackName] = function() { 205 global[callbackName] = function() {
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 * This handles the option menu. 726 * This handles the option menu.
728 * @param {Element} button The button element. 727 * @param {Element} button The button element.
729 * @param {Element} menu The menu element. 728 * @param {Element} menu The menu element.
730 * @constructor 729 * @constructor
731 */ 730 */
732 function OptionMenu(button, menu) { 731 function OptionMenu(button, menu) {
733 this.button = button; 732 this.button = button;
734 this.menu = menu; 733 this.menu = menu;
735 this.button.onmousedown = bind(this.handleMouseDown, this); 734 this.button.onmousedown = bind(this.handleMouseDown, this);
736 this.button.onkeydown = bind(this.handleKeyDown, this); 735 this.button.onkeydown = bind(this.handleKeyDown, this);
737 this.boundHideMenu_ = bind(this.hideMenu, this); 736 this.boundHideMenu_ = bind(this.hide, this);
738 this.boundMaybeHide_ = bind(this.maybeHide_, this); 737 this.boundMaybeHide_ = bind(this.maybeHide_, this);
739 this.menu.onmouseover = bind(this.handleMouseOver, this); 738 this.menu.onmouseover = bind(this.handleMouseOver, this);
740 this.menu.onmouseout = bind(this.handleMouseOut, this); 739 this.menu.onmouseout = bind(this.handleMouseOut, this);
741 this.menu.onmouseup = bind(this.handleMouseUp, this); 740 this.menu.onmouseup = bind(this.handleMouseUp, this);
742 } 741 }
743 742
744 OptionMenu.prototype = { 743 OptionMenu.prototype = {
745 showMenu: function() { 744 show: function() {
745 windowMenu.hide();
746
746 this.menu.style.display = 'block'; 747 this.menu.style.display = 'block';
747 this.button.focus(); 748 this.button.focus();
748 749
749 // Listen to document and window events so that we hide the menu when the 750 // Listen to document and window events so that we hide the menu when the
750 // user clicks outside the menu or tabs away or the whole window is blurred. 751 // user clicks outside the menu or tabs away or the whole window is blurred.
751 document.addEventListener('focus', this.boundMaybeHide_, true); 752 document.addEventListener('focus', this.boundMaybeHide_, true);
752 document.addEventListener('mousedown', this.boundMaybeHide_, true); 753 document.addEventListener('mousedown', this.boundMaybeHide_, true);
753 window.addEventListener('blur', this.boundHideMenu_);
754 }, 754 },
755 755
756 hideMenu: function() { 756 hide: function() {
757 this.menu.style.display = 'none'; 757 this.menu.style.display = 'none';
758 this.setSelectedIndex(-1); 758 this.setSelectedIndex(-1);
759 759
760 document.removeEventListener('focus', this.boundMaybeHide_, true); 760 document.removeEventListener('focus', this.boundMaybeHide_, true);
761 document.removeEventListener('mousedown', this.boundMaybeHide_, true); 761 document.removeEventListener('mousedown', this.boundMaybeHide_, true);
762 window.removeEventListener('blur', this.boundHide_);
763 }, 762 },
764 763
765 isMenuShown: function() { 764 isShown: function() {
766 return this.menu.style.display == 'block'; 765 return this.menu.style.display == 'block';
767 }, 766 },
768 767
769 /** 768 /**
770 * Callback for document mousedown and focus. It checks if the user tried to 769 * Callback for document mousedown and focus. It checks if the user tried to
771 * navigate to a different element on the page and if so hides the menu. 770 * navigate to a different element on the page and if so hides the menu.
772 * @param {Event} e The mouse or focus event. 771 * @param {Event} e The mouse or focus event.
773 * @private 772 * @private
774 */ 773 */
775 maybeHide_: function(e) { 774 maybeHide_: function(e) {
776 if (!this.menu.contains(e.target) && !this.button.contains(e.target)) { 775 if (!this.menu.contains(e.target) && !this.button.contains(e.target)) {
777 this.hideMenu(); 776 this.hide();
778 } 777 }
779 }, 778 },
780 779
781 handleMouseDown: function(e) { 780 handleMouseDown: function(e) {
782 if (this.isMenuShown()) { 781 if (this.isShown()) {
783 this.hideMenu(); 782 this.hide();
784 } else { 783 } else {
785 this.showMenu(); 784 this.show();
786 } 785 }
787 }, 786 },
788 787
789 handleMouseOver: function(e) { 788 handleMouseOver: function(e) {
790 var el = e.target; 789 var el = e.target;
791 var index = Array.prototype.indexOf.call(this.menu.children, el); 790 var index = Array.prototype.indexOf.call(this.menu.children, el);
792 this.setSelectedIndex(index); 791 this.setSelectedIndex(index);
793 }, 792 },
794 793
795 handleMouseOut: function(e) { 794 handleMouseOut: function(e) {
(...skipping 26 matching lines...) Expand all
822 break; 821 break;
823 } 822 }
824 } 823 }
825 if (item) { 824 if (item) {
826 self.setSelectedIndex(i); 825 self.setSelectedIndex(i);
827 } 826 }
828 } 827 }
829 828
830 switch (e.keyIdentifier) { 829 switch (e.keyIdentifier) {
831 case 'Down': 830 case 'Down':
832 if (!this.isMenuShown()) { 831 if (!this.isShown()) {
833 this.showMenu(); 832 this.show();
834 } 833 }
835 selectNextVisible(1); 834 selectNextVisible(1);
835 e.preventDefault();
836 break; 836 break;
837 case 'Up': 837 case 'Up':
838 if (!this.isMenuShown()) { 838 if (!this.isShown()) {
839 this.showMenu(); 839 this.show();
840 } 840 }
841 selectNextVisible(-1); 841 selectNextVisible(-1);
842 e.preventDefault();
842 break; 843 break;
843 case 'Esc': 844 case 'Esc':
844 case 'U+001B': // Maybe this is remote desktop playing a prank? 845 case 'U+001B': // Maybe this is remote desktop playing a prank?
845 this.hideMenu(); 846 this.hide();
846 break; 847 break;
847 case 'Enter': 848 case 'Enter':
848 if (this.isMenuShown()) { 849 case 'U+0020': // Space
850 if (this.isShown()) {
849 if (item) { 851 if (item) {
850 this.executeItem(item); 852 this.executeItem(item);
853 } else {
854 this.hide();
851 } 855 }
852 } else { 856 } else {
853 this.showMenu(); 857 this.show();
854 } 858 }
859 e.preventDefault();
855 break; 860 break;
856 } 861 }
857 }, 862 },
858 863
859 selectedIndex_: -1, 864 selectedIndex_: -1,
860 setSelectedIndex: function(i) { 865 setSelectedIndex: function(i) {
861 if (i != this.selectedIndex_) { 866 if (i != this.selectedIndex_) {
862 var items = this.menu.children; 867 var items = this.menu.children;
863 var oldItem = items[this.selectedIndex_]; 868 var oldItem = items[this.selectedIndex_];
864 if (oldItem) { 869 if (oldItem) {
(...skipping 13 matching lines...) Expand all
878 883
879 executeItem: function(item) { 884 executeItem: function(item) {
880 var section = Section[item.getAttribute('section')]; 885 var section = Section[item.getAttribute('section')];
881 var show = item.getAttribute('show') == 'true'; 886 var show = item.getAttribute('show') == 'true';
882 if (show) { 887 if (show) {
883 showSection(section); 888 showSection(section);
884 } else { 889 } else {
885 hideSection(section); 890 hideSection(section);
886 } 891 }
887 892
888 this.hideMenu(); 893 this.hide();
889 saveShownSections(); 894 saveShownSections();
890 } 895 }
891 }; 896 };
892 897
893 new OptionMenu($('option-button'), $('option-menu')); 898 var optionMenu = new OptionMenu($('option-button'), $('option-menu'));
894 899
895 $('most-visited').addEventListener('click', function(e) { 900 $('most-visited').addEventListener('click', function(e) {
896 var target = e.target; 901 var target = e.target;
897 if (hasClass(target, 'pin')) { 902 if (hasClass(target, 'pin')) {
898 mostVisited.togglePinned(mostVisited.getItem(target)); 903 mostVisited.togglePinned(mostVisited.getItem(target));
899 e.preventDefault(); 904 e.preventDefault();
900 } else if (hasClass(target, 'remove')) { 905 } else if (hasClass(target, 'remove')) {
901 mostVisited.blacklist(mostVisited.getItem(target)); 906 mostVisited.blacklist(mostVisited.getItem(target));
902 e.preventDefault(); 907 e.preventDefault();
903 } 908 }
(...skipping 29 matching lines...) Expand all
933 return el.sessionId !== undefined; 938 return el.sessionId !== undefined;
934 }); 939 });
935 if (el) { 940 if (el) {
936 chrome.send('reopenTab', [String(el.sessionId)]); 941 chrome.send('reopenTab', [String(el.sessionId)]);
937 e.preventDefault(); 942 e.preventDefault();
938 } 943 }
939 } 944 }
940 945
941 recentTabs.addEventListener('mouseover', maybeShowWindowMenu); 946 recentTabs.addEventListener('mouseover', maybeShowWindowMenu);
942 recentTabs.addEventListener('focus', maybeShowWindowMenu, true); 947 recentTabs.addEventListener('focus', maybeShowWindowMenu, true);
943 recentTabs.addEventListener('mouseout', maybeHideWindowMenu); 948
944 recentTabs.addEventListener('blur', maybeHideWindowMenu, true);
945 949
946 function maybeShowWindowMenu(e) { 950 function maybeShowWindowMenu(e) {
947 var el = findAncestor(e.target, function(el) { 951 var el = findAncestor(e.target, function(el) {
948 return el.tabItems !== undefined; 952 return el.tabItems !== undefined;
949 }); 953 });
950 if (el) { 954 if (el) {
951 showWindowMenu(el, el.tabItems); 955 windowMenu.show(e, el, el.tabItems);
952 } 956 }
953 } 957 }
954 958
955 function maybeHideWindowMenu(e) { 959 /**
956 var el = findAncestor(e.target, function(el) { 960 * This object represents a window/tooltip representing a closed window. It is
957 return el.tabItems !== undefined; 961 * shown when hovering over a closed window item or when the item is focused. It
958 }); 962 * gets hidden when blurred or when mousing out of the menu or the item.
959 if (el) { 963 * @param {Element} menuEl The element to use as the menu.
960 $('window-menu').style.display = 'none'; 964 * @constructor
965 */
966 function WindowMenu(menuEl) {
967 this.menuEl = menuEl;
968 var self = this;
969 this.boundHide_ = bind(this.hide, this);
970 menuEl.onmouseover = function() {
971 clearTimeout(self.timer);
972 };
973 menuEl.onmouseout = this.boundHide_;
974 }
975
976 WindowMenu.prototype = {
977 timer: 0,
978 show: function(e, linkEl, tabs) {
979 optionMenu.hide();
980
981 clearTimeout(this.timer);
982 processData('#window-menu', tabs);
983 var rect = linkEl.getBoundingClientRect();
984 var bodyRect = document.body.getBoundingClientRect()
985 var rtl = document.documentElement.dir == 'rtl';
986
987 this.menuEl.style.display = 'block';
988 this.menuEl.style.left = (rtl ?
989 rect.left + bodyRect.left + rect.width - this.menuEl.offsetWidth :
990 rect.left + bodyRect.left) + 'px';
991 this.menuEl.style.top = rect.top + bodyRect.top + rect.height + 'px';
992
993 if (e.type == 'focus') {
994 linkEl.onblur = this.boundHide_;
995 } else { // mouseover
996 linkEl.onmouseout = this.boundHide_;
997 }
998 },
999 hide: function() {
1000 // Delay before hiding.
1001 var self = this;
1002 this.timer = setTimeout(function() {
1003 self.menuEl.style.display = 'none';
1004 }, 100);
1005 }
1006 };
1007
1008 var windowMenu = new WindowMenu($('window-menu'));
1009
1010 function getCheckboxHandler(section) {
1011 return function(e) {
1012 if (e.type == 'keydown') {
1013 if (e.keyIdentifier == 'Enter') {
1014 e.target.checked = !e.target.checked;
1015 } else {
1016 return;
1017 }
1018 }
1019 if (e.target.checked) {
1020 showSection(section);
1021 } else {
1022 hideSection(section);
1023 }
1024 saveShownSections();
961 } 1025 }
962 } 1026 }
963 1027
964 function showWindowMenu(el, tabs) { 1028 $('thumb-checkbox').addEventListener('change',
965 var menuEl = $('window-menu'); 1029 getCheckboxHandler(Section.THUMB));
966 processData('#window-menu', tabs); 1030 $('thumb-checkbox').addEventListener('keydown',
967 var rect = el.getBoundingClientRect(); 1031 getCheckboxHandler(Section.THUMB));
968 var bodyRect = document.body.getBoundingClientRect() 1032 $('list-checkbox').addEventListener('change',
969 var rtl = document.documentElement.dir == 'rtl'; 1033 getCheckboxHandler(Section.LIST));
970 1034 $('list-checkbox').addEventListener('keydown',
971 menuEl.style.display = 'block'; 1035 getCheckboxHandler(Section.LIST));
972 menuEl.style.left = (rtl ?
973 rect.left + bodyRect.left + rect.width - menuEl.offsetWidth :
974 rect.left + bodyRect.left) + 'px';
975 menuEl.style.top = rect.top + bodyRect.top + rect.height + 'px';
976
977 }
978
979 $('thumb-checkbox').addEventListener('change', function(e) {
980 if (e.target.checked) {
981 showSection(Section.THUMB);
982 } else {
983 hideSection(Section.THUMB);
984 }
985 saveShownSections();
986 });
987
988 $('list-checkbox').addEventListener('change', function(e) {
989 if (e.target.checked) {
990 showSection(Section.LIST);
991 } else {
992 hideSection(Section.LIST);
993 }
994 saveShownSections();
995 });
996 1036
997 window.addEventListener('load', bind(logEvent, global, 'onload fired')); 1037 window.addEventListener('load', bind(logEvent, global, 'onload fired'));
998 window.addEventListener('load', onDataLoaded); 1038 window.addEventListener('load', onDataLoaded);
999 window.addEventListener('resize', handleWindowResize); 1039 window.addEventListener('resize', handleWindowResize);
1000 document.addEventListener('DOMContentLoaded', bind(logEvent, global, 1040 document.addEventListener('DOMContentLoaded', bind(logEvent, global,
1001 'domcontentloaded fired')); 1041 'domcontentloaded fired'));
1002 1042
1043 function hideAllMenus() {
1044 windowMenu.hide();
1045 optionMenu.hide();
1046 }
1047
1048 window.addEventListener('blur', hideAllMenus);
1049 window.addEventListener('keydown', function(e) {
1050 if (e.keyIdentifier == 'Alt' || e.keyIdentifier == 'Meta') {
1051 hideAllMenus();
1052 }
1053 }, true);
1054
1003 // DnD 1055 // DnD
1004 1056
1005 var dnd = { 1057 var dnd = {
1006 currentOverItem: null, 1058 currentOverItem: null,
1007 dragItem: null, 1059 dragItem: null,
1008 startX: 0, 1060 startX: 0,
1009 startY: 0, 1061 startY: 0,
1010 startScreenX: 0, 1062 startScreenX: 0,
1011 startScreenY: 0, 1063 startScreenY: 0,
1012 dragEndTimer: null, 1064 dragEndTimer: null,
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 el.addEventListener('dragover', bind(this.handleDragOver, this)); 1170 el.addEventListener('dragover', bind(this.handleDragOver, this));
1119 el.addEventListener('dragleave', bind(this.handleDragLeave, this)); 1171 el.addEventListener('dragleave', bind(this.handleDragLeave, this));
1120 el.addEventListener('drop', bind(this.handleDrop, this)); 1172 el.addEventListener('drop', bind(this.handleDrop, this));
1121 el.addEventListener('dragend', bind(this.handleDragEnd, this)); 1173 el.addEventListener('dragend', bind(this.handleDragEnd, this));
1122 el.addEventListener('drag', bind(this.handleDrag, this)); 1174 el.addEventListener('drag', bind(this.handleDrag, this));
1123 el.addEventListener('mousedown', bind(this.handleMouseDown, this)); 1175 el.addEventListener('mousedown', bind(this.handleMouseDown, this));
1124 } 1176 }
1125 }; 1177 };
1126 1178
1127 dnd.init(); 1179 dnd.init();
OLDNEW
« no previous file with comments | « chrome/browser/resources/new_new_tab.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698