1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/metro/base/content/helperui/FindHelperUI.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,227 @@ 1.4 +// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* We don't support zooming yet, disable Animated zoom by clamping it to the default zoom. */ 1.10 +const kBrowserFindZoomLevelMin = 1; 1.11 +const kBrowserFindZoomLevelMax = 1; 1.12 + 1.13 +var FindHelperUI = { 1.14 + type: "find", 1.15 + commands: { 1.16 + next: "cmd_findNext", 1.17 + previous: "cmd_findPrevious", 1.18 + close: "cmd_findClose" 1.19 + }, 1.20 + 1.21 + _finder: null, 1.22 + _open: false, 1.23 + _status: null, 1.24 + _searchString: "", 1.25 + 1.26 + /* 1.27 + * Properties 1.28 + */ 1.29 + 1.30 + get isActive() { 1.31 + return this._open; 1.32 + }, 1.33 + 1.34 + get status() { 1.35 + return this._status; 1.36 + }, 1.37 + 1.38 + set status(val) { 1.39 + if (val != this._status) { 1.40 + this._status = val; 1.41 + if (!val) 1.42 + this._textbox.removeAttribute("status"); 1.43 + else 1.44 + this._textbox.setAttribute("status", val); 1.45 + this.updateCommands(this._textbox.value); 1.46 + } 1.47 + }, 1.48 + 1.49 + init: function findHelperInit() { 1.50 + this._textbox = document.getElementById("findbar-textbox"); 1.51 + this._container = Elements.findbar; 1.52 + 1.53 + this._cmdPrevious = document.getElementById(this.commands.previous); 1.54 + this._cmdNext = document.getElementById(this.commands.next); 1.55 + 1.56 + this._textbox.addEventListener("keydown", this); 1.57 + 1.58 + // Listen for events where form assistant should be closed 1.59 + Elements.tabList.addEventListener("TabSelect", this, true); 1.60 + Elements.browsers.addEventListener("URLChanged", this, true); 1.61 + window.addEventListener("MozAppbarShowing", this); 1.62 + window.addEventListener("MozFlyoutPanelShowing", this, false); 1.63 + }, 1.64 + 1.65 + handleEvent: function findHelperHandleEvent(aEvent) { 1.66 + switch (aEvent.type) { 1.67 + case "TabSelect": 1.68 + this.hide(); 1.69 + break; 1.70 + 1.71 + case "URLChanged": 1.72 + if (aEvent.detail && aEvent.target == getBrowser()) 1.73 + this.hide(); 1.74 + break; 1.75 + 1.76 + case "keydown": 1.77 + if (aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN) { 1.78 + let backwardsSearch = aEvent.shiftKey; 1.79 + this.searchAgain(this._searchString, backwardsSearch); 1.80 + } 1.81 + break; 1.82 + 1.83 + case "MozAppbarShowing": 1.84 + case "MozFlyoutPanelShowing": 1.85 + if (aEvent.target != this._container) { 1.86 + this.hide(); 1.87 + } 1.88 + break; 1.89 + } 1.90 + }, 1.91 + 1.92 + show: function findHelperShow() { 1.93 + if (BrowserUI.isStartTabVisible) { 1.94 + return; 1.95 + } 1.96 + if (this._open) { 1.97 + setTimeout(() => { 1.98 + this._textbox.select(); 1.99 + this._textbox.focus(); 1.100 + }, 0); 1.101 + return; 1.102 + } 1.103 + 1.104 + // Hide any menus 1.105 + ContextUI.dismiss(); 1.106 + 1.107 + // Shutdown selection related ui 1.108 + SelectionHelperUI.closeEditSession(); 1.109 + 1.110 + let findbar = this._container; 1.111 + setTimeout(() => { 1.112 + findbar.show(); 1.113 + this.search(this._textbox.value); 1.114 + this._textbox.select(); 1.115 + this._textbox.focus(); 1.116 + 1.117 + this._open = true; 1.118 + }, 0); 1.119 + 1.120 + // Prevent the view to scroll automatically while searching 1.121 + Browser.selectedBrowser.scrollSync = false; 1.122 + }, 1.123 + 1.124 + hide: function findHelperHide() { 1.125 + if (!this._open) 1.126 + return; 1.127 + 1.128 + ContentAreaObserver.shiftBrowserDeck(0); 1.129 + 1.130 + let onTransitionEnd = () => { 1.131 + this._container.removeEventListener("transitionend", onTransitionEnd, true); 1.132 + this._textbox.value = ""; 1.133 + this.status = null; 1.134 + this._open = false; 1.135 + if (this._finder) { 1.136 + this._finder.removeResultListener(this); 1.137 + this._finder = null 1.138 + } 1.139 + // Restore the scroll synchronisation 1.140 + Browser.selectedBrowser.scrollSync = true; 1.141 + }; 1.142 + 1.143 + this._textbox.blur(); 1.144 + this._container.addEventListener("transitionend", onTransitionEnd, true); 1.145 + this._container.dismiss(); 1.146 + }, 1.147 + 1.148 + search: function findHelperSearch(aValue) { 1.149 + if (!this._finder) { 1.150 + this._finder = Browser.selectedBrowser.finder; 1.151 + this._finder.addResultListener(this); 1.152 + } 1.153 + this._searchString = aValue; 1.154 + if (aValue != "") { 1.155 + this._finder.fastFind(aValue, false, false); 1.156 + } else { 1.157 + this.updateCommands(); 1.158 + } 1.159 + }, 1.160 + 1.161 + searchAgain: function findHelperSearchAgain(aValue, aFindBackwards) { 1.162 + // This can happen if the user taps next/previous after re-opening the search bar 1.163 + if (!this._finder) { 1.164 + this.search(aValue); 1.165 + return; 1.166 + } 1.167 + 1.168 + this._finder.findAgain(aFindBackwards, false, false); 1.169 + }, 1.170 + 1.171 + goToPrevious: function findHelperGoToPrevious() { 1.172 + this.searchAgain(this._searchString, true); 1.173 + }, 1.174 + 1.175 + goToNext: function findHelperGoToNext() { 1.176 + this.searchAgain(this._searchString, false); 1.177 + }, 1.178 + 1.179 + onFindResult: function(aData) { 1.180 + this._status = aData.result; 1.181 + if (aData.rect) { 1.182 + this._zoom(aData.rect, Browser.selectedBrowser.contentDocumentHeight); 1.183 + } 1.184 + this.updateCommands(); 1.185 + }, 1.186 + 1.187 + updateCommands: function findHelperUpdateCommands() { 1.188 + let disabled = (this._status == Ci.nsITypeAheadFind.FIND_NOTFOUND) || (this._searchString == ""); 1.189 + this._cmdPrevious.setAttribute("disabled", disabled); 1.190 + this._cmdNext.setAttribute("disabled", disabled); 1.191 + }, 1.192 + 1.193 + _zoom: function _findHelperZoom(aElementRect, aContentHeight) { 1.194 + // The rect we get here is the content rect including scroll offset 1.195 + // in the page. 1.196 + 1.197 + // If the text falls below the find bar and keyboard shift content up. 1.198 + let browserShift = 0; 1.199 + // aElementRect.y is the top left origin of the selection rect. 1.200 + if ((aElementRect.y + aElementRect.height) > 1.201 + (aContentHeight - this._container.boxObject.height)) { 1.202 + browserShift += this._container.boxObject.height; 1.203 + } 1.204 + browserShift += Services.metro.keyboardHeight; 1.205 + 1.206 + // If the rect top of the selection is above the view, don't shift content 1.207 + // (or if it's already shifted, shift it back down). 1.208 + if (aElementRect.y < browserShift) { 1.209 + browserShift = 0; 1.210 + } 1.211 + 1.212 + // Shift the deck so that the selection is within the visible view. 1.213 + ContentAreaObserver.shiftBrowserDeck(browserShift); 1.214 + 1.215 + // Adjust for keyboad display and position the text selection rect in 1.216 + // the middle of the viewable area. 1.217 + let xPos = aElementRect.x; 1.218 + let yPos = aElementRect.y; 1.219 + let scrollAdjust = ((ContentAreaObserver.height - Services.metro.keyboardHeight) * .5) + 1.220 + Services.metro.keyboardHeight; 1.221 + yPos -= scrollAdjust; 1.222 + if (yPos < 0) { 1.223 + yPos = 0; 1.224 + } 1.225 + 1.226 + // TODO zoom via apzc, right now all we support is scroll 1.227 + // positioning. 1.228 + Browser.selectedBrowser.contentWindow.scrollTo(xPos, yPos); 1.229 + } 1.230 +};