--- a/mobile/app/mobile.js
+++ b/mobile/app/mobile.js
@@ -137,16 +137,19 @@ pref("signon.rememberSignons", true);
pref("signon.expireMasterPassword", false);
pref("signon.SignonFileName", "signons.txt");
/* form helper */
pref("formhelper.enabled", true);
pref("formhelper.autozoom", true);
pref("formhelper.restore", false);
+/* find helper */
+pref("findhelper.autozoom", true);
+
/* autocomplete */
pref("browser.formfill.enable", true);
#ifdef WINCE
pref("layout.css.devPixelsPerPx", "1");
#endif
/* spellcheck */
--- a/mobile/chrome/content/bindings.xml
+++ b/mobile/chrome/content/bindings.xml
@@ -1072,16 +1072,95 @@
<handler event="mousedown" phase="capturing">
<![CDATA[
event.stopPropagation();
]]>
</handler>
</handlers>
</binding>
+ <binding id="content-navigator">
+ <content pack="end">
+ <children includes="arrowscrollbox|vbox"/>
+ <xul:hbox class="panel-dark" pack="center">
+ <children includes="textbox"/>
+ <xul:button anonid="previous-button" class="button-dark" label="&contentNavigator.previous;" xbl:inherits="command=previous"/>
+ <xul:button anonid="next-button" class="button-dark" label="&contentNavigator.next;" xbl:inherits="command=next"/>
+ <xul:spacer flex="1"/>
+ <xul:toolbarbutton class="close-button" xbl:inherits="command=close"/>
+ </xul:hbox>
+ </content>
+
+ <implementation>
+ <field name="_previousButton">
+ document.getAnonymousElementByAttribute(this, "anonid", "previous-button");
+ </field>
+
+ <field name="_nextButton">
+ document.getAnonymousElementByAttribute(this, "anonid", "next-button");
+ </field>
+
+ <field name="_spacer">
+ document.getElementById(this.getAttribute("spacer"));
+ </field>
+
+ <method name="contentHasChanged">
+ <body><![CDATA[
+ let height = Math.floor(this.getBoundingClientRect().height);
+ this.top = window.innerHeight - height;
+ this._spacer.setAttribute("height", height);
+ ]]></body>
+ </method>
+
+ <field name="_model">null</field>
+ <method name="show">
+ <parameter name="aModel" />
+ <body><![CDATA[
+ // call the hide callback of the current object if any
+ if (this._model && this._model.type != aModel.type)
+ this._model.hide();
+
+ this.setAttribute("type", aModel.type);
+ this.setAttribute("next", aModel.commands.next);
+ this.setAttribute("previous", aModel.commands.previous);
+ this.setAttribute("close", aModel.commands.close);
+
+ // buttons attributes sync with commands doesn not look updated when
+ // we dynamically switch the "command" attribute so we need to ensure
+ // the disabled state of the buttons is right when switching commands
+ this._previousButton.disabled = document.getElementById(aModel.commands.previous).disabled;
+ this._nextButton.disabled = document.getElementById(aModel.commands.next).disabled;
+
+ this._model = aModel;
+ this.contentHasChanged();
+ this._spacer.hidden = false;
+ ]]></body>
+ </method>
+
+ <method name="hide">
+ <parameter name="aModel" />
+ <body><![CDATA[
+ this.removeAttribute("next");
+ this.removeAttribute("previous");
+ this.removeAttribute("close");
+ this.removeAttribute("type");
+
+ this._model = null;
+ this._spacer.hidden = false;
+
+ // give the form spacer area back to the content
+ // XXX this should probably be removed with layers
+ Browser.forceChromeReflow();
+ Browser.contentScrollboxScroller.scrollBy(0, 0);
+ Browser._browserView.onAfterVisibleMove();
+ ]]></body>
+ </method>
+ </implementation>
+ </binding>
+
<binding id="menulist" display="xul:box" extends="chrome://global/content/bindings/menulist.xml#menulist">
<handlers>
<handler event="mousedown" phase="capturing">
<![CDATA[
// Stop the normal menupopup from appearing
event.stopPropagation();
]]>
</handler>
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -334,19 +334,19 @@ var BrowserUI = {
document.getElementById("tabs").resize();
// awesomebar
let popup = document.getElementById("popup_autocomplete");
popup.top = this.toolbarH;
popup.height = windowH - this.toolbarH;
popup.width = windowW;
- // form helper
- let formHelper = document.getElementById("form-helper-container");
- formHelper.top = windowH - formHelper.getBoundingClientRect().height;
+ // content navigator helper
+ let contentHelper = document.getElementById("content-navigator");
+ contentHelper.top = windowH - contentHelper.getBoundingClientRect().height;
},
init: function() {
this._edit = document.getElementById("urlbar-edit");
this._throbber = document.getElementById("urlbar-throbber");
this._favicon = document.getElementById("urlbar-favicon");
this._favicon.addEventListener("error", this, false);
@@ -394,16 +394,17 @@ var BrowserUI = {
PreferencesView.init();
ConsoleView.init();
// Init the sync system
WeaveGlue.init();
});
FormHelperUI.init();
+ FindHelperUI.init();
},
uninit: function() {
ExtensionsView.uninit();
ConsoleView.uninit();
},
update: function(aState) {
@@ -1426,31 +1427,123 @@ var BookmarkList = {
if (this._bookmarks.isRootFolder && this._bookmarks.items.length == 1) {
this._manageButton.disabled = true;
this.toggleManage();
}
}
}
};
+
+var FindHelperUI = {
+ type: "find",
+ commands: {
+ next: "cmd_findNext",
+ previous: "cmd_findPrevious",
+ close: "cmd_findClose"
+ },
+
+ init: function findHelperInit() {
+ this._textbox = document.getElementById("find-helper-textbox");
+ this._container = document.getElementById("content-navigator");
+
+ // Listen for form assistant messages from content
+ messageManager.addMessageListener("FindAssist:Show", this);
+
+ // Listen for events where form assistant should be closed
+ document.getElementById("tabs").addEventListener("TabSelect", this, true);
+ document.getElementById("browsers").addEventListener("URLChanged", this, true);
+ },
+
+ receiveMessage: function findHelperReceiveMessage(aMessage) {
+ let json = aMessage.json;
+ switch(aMessage.name) {
+ case "FindAssist:Show":
+ if (json.rect)
+ this._zoom(Rect.fromRect(json.rect));
+ break;
+ }
+ },
+
+ handleEvent: function findHelperHandleEvent(aEvent) {
+ if (aEvent.type == "TabSelect" || aEvent.type == "URLChanged")
+ this.hide();
+ },
+
+ show: function findHelperShow() {
+ Browser._browserView.ignorePageScroll(true);
+ Browser.selectedBrowser.messageManager.sendAsyncMessage("FindAssist:Find", { searchString: "" });
+ this._container.show(this);
+ this._textbox.focus();
+ },
+
+ hide: function findHelperHide() {
+ Browser._browserView.ignorePageScroll(false);
+ this._textbox.value = "";
+ this._container.hide(this);
+ },
+
+ goToPrevious: function findHelperGoToPrevious() {
+ Browser.selectedBrowser.messageManager.sendAsyncMessage("FindAssist:Previous", { });
+ },
+
+ goToNext: function findHelperGoToNext() {
+ Browser.selectedBrowser.messageManager.sendAsyncMessage("FindAssist:Next", { });
+ },
+
+ search: function findHelperSearch(aValue) {
+ Browser.selectedBrowser.messageManager.sendAsyncMessage("FindAssist:Find", { searchString: aValue });
+ },
+
+ updateFindInPage: function findHelperUpdateFindInPage() {
+ PageActions.removeItems("findinpage");
+ let title = Elements.browserBundle.getString("pageactions.findInPage");
+ let node = PageActions.appendItem("findinpage", title, "");
+ node.onclick = function(event) {
+ BrowserUI._hidePopup();
+ FindHelperUI.show();
+ }
+ },
+
+ _zoom: function _findHelperZoom(aElementRect) {
+ let bv = Browser._browserView;
+ let zoomRect = bv.getVisibleRect();
+
+ // Zoom to a specified Rect
+ if (aElementRect && bv.allowZoom && Services.prefs.getBoolPref("findhelper.autozoom")) {
+ let zoomLevel = Browser._getZoomLevelForRect(bv.browserToViewportRect(aElementRect.clone()));
+ zoomLevel = Math.min(Math.max(kBrowserFormZoomLevelMin, zoomLevel), kBrowserFormZoomLevelMax);
+
+ zoomRect = Browser._getZoomRectForPoint(aElementRect.center().x, aElementRect.y, zoomLevel);
+ Browser.animatedZoomTo(zoomRect);
+ }
+ }
+};
+
/**
* Responsible for navigating forms and filling in information.
* - Navigating forms is handled by next and previous commands.
* - When an element is focused, the browser view zooms in to the control.
* - The caret positionning and the view are sync to keep the type
* in text into view for input fields (text/textarea).
* - Provides autocomplete box for input fields.
*/
var FormHelperUI = {
+ type: "form",
+ commands: {
+ next: "cmd_formNext",
+ previous: "cmd_formPrevious",
+ close: "cmd_formClose"
+ },
+
init: function formHelperInit() {
- this._container = document.getElementById("form-helper-container");
- this._cmdPrevious = document.getElementById("cmd_formPrevious");
- this._cmdNext = document.getElementById("cmd_formNext");
- this._helperSpacer = document.getElementById("form-helper-spacer");
+ this._container = document.getElementById("content-navigator");
this._autofillContainer = document.getElementById("form-helper-autofill");
+ this._cmdPrevious = document.getElementById(this.commands.previous);
+ this._cmdNext = document.getElementById(this.commands.next);
// Listen for form assistant messages from content
messageManager.addMessageListener("FormAssist:Show", this);
messageManager.addMessageListener("FormAssist:Hide", this);
messageManager.addMessageListener("FormAssist:Update", this);
messageManager.addMessageListener("FormAssist:AutoComplete", this);
// Listen for events where form assistant should be closed
@@ -1480,17 +1573,17 @@ var FormHelperUI = {
hide: function formHelperHide() {
if (!this._open)
return;
this._updateContainerForSelect(this._currentElement, null);
this._open = false;
},
- handleEvent: function(aEvent) {
+ handleEvent: function formHelperHandleEvent(aEvent) {
if (aEvent.type == "TabSelect" || aEvent.type == "URLChanged")
this.hide();
},
receiveMessage: function formHelperReceiveMessage(aMessage) {
let json = aMessage.json;
switch (aMessage.name) {
case "FormAssist:Show":
@@ -1503,17 +1596,17 @@ var FormHelperUI = {
}
else {
SelectHelperUI.show(json.current.list);
}
break;
case "FormAssist:AutoComplete":
this._updateAutocompleteFor(json.current);
- this._updateHelperSize();
+ this._container.contentHasChanged();
break;
case "FormAssist:Update":
this._zoom(null, Rect.fromRect(json.caretRect));
break;
}
},
@@ -1527,40 +1620,34 @@ var FormHelperUI = {
doAutoComplete: function formHelperDoAutoComplete(aElement) {
// Suggestions are only in <label>s. Ignore the rest.
if (aElement instanceof Ci.nsIDOMXULLabelElement)
Browser.selectedBrowser.messageManager.sendAsyncMessage("FormAssist:AutoComplete", { value: aElement.value });
},
get _open() {
- return !this._container.hidden;
+ return (this._container.getAttribute("type") == this.type);
},
set _open(aVal) {
if (aVal == this._open)
return;
let bv = Browser._browserView;
bv.ignorePageScroll(aVal);
this._container.hidden = !aVal;
- this._helperSpacer.hidden = !aVal;
if (aVal) {
this._zoomStart();
+ this._container.show(this);
} else {
- this._currentElement = null;
this._zoomFinish();
-
- // give the form spacer area back to the content
- // XXX this should probably be removed with layers
- let bv = Browser._browserView;
- Browser.forceChromeReflow();
- Browser.contentScrollboxScroller.scrollBy(0, 0);
- bv.onAfterVisibleMove();
+ this._currentElement = null;
+ this._container.hide(this);
}
let evt = document.createEvent("UIEvents");
evt.initUIEvent("FormUI", true, true, window, aVal);
this._container.dispatchEvent(evt);
},
_updateAutocompleteFor: function _formHelperUpdateAutocompleteFor(aElement) {
@@ -1604,25 +1691,17 @@ var FormHelperUI = {
},
/** Update the form helper container to reflect new element user is editing. */
_updateContainer: function _formHelperUpdateContainer(aLastElement, aCurrentElement) {
this._updateContainerForSelect(aLastElement, aCurrentElement);
// Setup autofill UI
this._updateAutocompleteFor(aCurrentElement);
- this._updateHelperSize();
- },
-
- _updateHelperSize: function _formHelperUpdateHelperSize() {
- let height = Math.floor(this._container.getBoundingClientRect().height);
- this._container.top = window.innerHeight - height;
-
- let containerHeight = this._container.getBoundingClientRect().height;
- this._helperSpacer.setAttribute("height", containerHeight);
+ this._container.contentHasChanged();
},
/** Helper for _updateContainer that handles the case where the new element is a select. */
_updateContainerForSelect: function _formHelperUpdateContainerForSelect(aLastElement, aCurrentElement) {
let lastHasChoices = aLastElement && (aLastElement.list != null);
let currentHasChoices = aCurrentElement && (aCurrentElement.list != null);
if (!lastHasChoices && currentHasChoices) {
@@ -1632,17 +1711,17 @@ var FormHelperUI = {
SelectHelperUI.reset();
SelectHelperUI.show(aCurrentElement.list);
} else if (lastHasChoices && !currentHasChoices) {
SelectHelperUI.hide();
}
},
/** Zoom and move viewport so that element is legible and touchable. */
- _zoom: function formHelperZoom(aElementRect, aCaretRect) {
+ _zoom: function _formHelperZoom(aElementRect, aCaretRect) {
let bv = Browser._browserView;
let zoomRect = bv.getVisibleRect();
// Zoom to a specified Rect
if (aElementRect && bv.allowZoom && Services.prefs.getBoolPref("formhelper.autozoom")) {
// Zoom to an element by keeping the caret into view
let zoomLevel = Browser._getZoomLevelForRect(bv.browserToViewportRect(aElementRect.clone()));
zoomLevel = Math.min(Math.max(kBrowserFormZoomLevelMin, zoomLevel), kBrowserFormZoomLevelMax);
@@ -1676,26 +1755,26 @@ var FormHelperUI = {
zoom: Browser._browserView.getZoomLevel(),
contentScrollOffset: Browser.getScrollboxPosition(Browser.contentScrollboxScroller),
pageScrollOffset: Browser.getScrollboxPosition(Browser.pageScrollboxScroller)
};
},
/** Element is no longer selected. Restore zoom level if setting is enabled. */
_zoomFinish: function _formHelperZoomFinish() {
- if(!gPrefService.getBoolPref("formhelper.restore"))
+ if(!Services.prefs.getBoolPref("formhelper.restore"))
return;
let restore = this._restore;
Browser._browserView.setZoomLevel(restore.zoom);
Browser.contentScrollboxScroller.scrollTo(restore.contentScrollOffset.x, restore.contentScrollOffset.y);
Browser.pageScrollboxScroller.scrollTo(restore.pageScrollOffset.x, restore.pageScrollOffset.y);
},
- _getOffsetForCaret: function formHelper_getOffsetForCaret(aCaretRect, aRect) {
+ _getOffsetForCaret: function _formHelperGetOffsetForCaret(aCaretRect, aRect) {
// Determine if we need to move left or right to bring the caret into view
let deltaX = 0;
if (aCaretRect.right > aRect.right)
deltaX = aCaretRect.right - aRect.right;
if (aCaretRect.left < aRect.left)
deltaX = aCaretRect.left - aRect.left;
// Determine if we need to move up or down to bring the caret into view
@@ -2003,20 +2082,20 @@ var ContextHelper = {
container.height = height;
container.width = width;
container.top = (window.innerHeight - height) / 2;
container.left = (window.innerWidth - width) / 2;
BrowserUI.pushPopup(this, [container]);
},
-
+
hide: function ch_hide() {
this.popupState = null;
-
+
let container = document.getElementById("context-popup");
container.hidden = true;
BrowserUI.popPopup();
}
};
var ContextCommands = {
--- a/mobile/chrome/content/browser.css
+++ b/mobile/chrome/content/browser.css
@@ -5,16 +5,20 @@ browser[remote="false"] {
browser[remote="true"] {
-moz-binding: url("chrome://browser/content/bindings/browser.xml#remote-browser");
}
#urlbar-edit {
-moz-binding: url("chrome://browser/content/bindings.xml#autocomplete-aligned");
}
+#content-navigator {
+ -moz-binding: url("chrome://browser/content/bindings.xml#content-navigator");
+}
+
#tabs {
-moz-binding: url("chrome://browser/content/tabs.xml#tablist");
}
box[type="documenttab"] {
-moz-binding: url("chrome://browser/content/tabs.xml#documenttab");
}
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -1826,16 +1826,19 @@ IdentityHandler.prototype = {
}
// Push the appropriate strings out to the UI
this._identityPopupContentHost.textContent = host;
this._identityPopupContentOwner.textContent = owner;
this._identityPopupContentSupp.textContent = supplemental;
this._identityPopupContentVerif.textContent = verifier;
+ // Update the find in page in-site menu
+ FindHelperUI.updateFindInPage();
+
// Update the search engines results
BrowserSearch.updatePageSearchEngines();
// Update the per site permissions results
PageActions.updatePagePermissions();
PageActions.updatePageSaveAs();
},
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -146,16 +146,21 @@
<command id="cmd_paste" label="&paste.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_delete" label="&delete.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_selectAll" label="&selectAll.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<!-- forms navigation -->
<command id="cmd_formPrevious" oncommand="FormHelperUI.goToPrevious();"/>
<command id="cmd_formNext" oncommand="FormHelperUI.goToNext();"/>
<command id="cmd_formClose" oncommand="FormHelperUI.hide();"/>
+
+ <!-- find navigation -->
+ <command id="cmd_findPrevious" oncommand="FindHelperUI.goToPrevious();"/>
+ <command id="cmd_findNext" oncommand="FindHelperUI.goToNext();"/>
+ <command id="cmd_findClose" oncommand="FindHelperUI.hide();"/>
</commandset>
<keyset id="mainKeyset">
<!-- basic navigation -->
<key id="key_back" keycode="VK_LEFT" command="cmd_back" modifiers="control"/>
<key id="key_forward" keycode="VK_RIGHT" command="cmd_forward" modifiers="control"/>
<key id="key_back2" keycode="VK_BACK" command="cmd_back"/>
<key id="key_forward2" keycode="VK_BACK" command="cmd_forward" modifiers="shift"/>
@@ -258,40 +263,34 @@
<html:div id="tile-container" style="overflow: hidden;" tabindex="-1">
<html:canvas id="content-overlay" style="display: none; position: absolute; z-index: 1000; left: 0; top: 0;">
</html:canvas>
</html:div>
</scrollbox>
<html:canvas id="view-buffer" style="display: none;" moz-opaque="true">
</html:canvas>
</stack>
- <box id="form-helper-spacer" hidden="true"/>
+ <box id="content-navigator-spacer" hidden="true"/>
</vbox>
-
</vbox>
</scrollbox>
- <!-- popup for form helper -->
- <vbox id="form-helper-container" hidden="true" class="window-width" top="0" pack="end">
+ <!-- popup for content navigator helper -->
+ <vbox id="content-navigator" class="window-width" top="0" spacer="content-navigator-spacer">
<arrowscrollbox id="form-helper-autofill" collapsed="true" align="center" flex="1" orient="horizontal"
onclick="FormHelperUI.doAutoComplete(event.target);"/>
- <hbox id="form-buttons" class="panel-dark" pack="center">
- <button id="form-helper-previous" class="button-dark" label="&formHelper.previous;" command="cmd_formPrevious"/>
- <button id="form-helper-next" class="button-dark" label="&formHelper.next;" command="cmd_formNext"/>
- <spacer flex="1"/>
- <toolbarbutton id="form-helper-close" class="close-button" command="cmd_formClose"/>
- </hbox>
+ <textbox id="find-helper-textbox" oncommand="FindHelperUI.search(this.value)" type="search" flex="1"/>
</vbox>
</stack>
<!-- Right toolbar -->
<vbox class="panel-dark">
<!-- Because of the stack + fixed position of the urlbar when it is in
locked mode the event on the top-right part of the urlbar are
- swallow by this spacer, but not with the mousethrough attribute
+ swallow by this spacer, but not with the mousethrough attribute
-->
<spacer class="toolbar-height" mousethrough="always"/>
<vbox id="browser-controls" style="overflow: -moz-hidden-unscrollable;" class="panel-dark" flex="1">
<toolbarbutton id="tool-star" class="browser-control-button button-image" command="cmd_star"/>
<toolbarbutton id="tool-back" class="browser-control-button button-image" command="cmd_back"/>
<toolbarbutton id="tool-forward" class="browser-control-button button-image" command="cmd_forward"/>
<toolbarspring/>
@@ -487,17 +486,17 @@
</vbox>
<!-- options dialog for select form field -->
<vbox id="select-container" hidden="true" pack="center">
<spacer flex="1000"/>
<vbox id="select-container-inner" class="dialog-dark" flex="1">
<scrollbox id="select-list" flex="1" orient="vertical"/>
<hbox id="select-buttons" pack="center">
- <button id="select-buttons-done" class="button-dark" label="&formHelper.done;" oncommand="SelectHelperUI.hide();"/>
+ <button id="select-buttons-done" class="button-dark" label="&selectHelper.done;" oncommand="SelectHelperUI.hide();"/>
</hbox>
</vbox>
<spacer flex="1000"/>
</vbox>
<!-- bookmark window -->
<vbox id="bookmarklist-container" class="panel-dark" hidden="true">
<hbox id="bookmarklist-header">
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -826,8 +826,75 @@ var FormSubmitObserver = {
!aIID.equals(Ci.nsISupportsWeakReference) &&
!aIID.equals(Ci.nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
FormSubmitObserver.init();
+
+var FindHandler = {
+ get _fastFind() {
+ delete this._fastFind;
+ this._fastFind = Cc["@mozilla.org/typeaheadfind;1"].createInstance(Ci.nsITypeAheadFind);
+ this._fastFind.init(docShell);
+ return this._fastFind;
+ },
+
+ get _selectionController() {
+ delete this._selectionController;
+ return this._selectionController = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsISelectionDisplay)
+ .QueryInterface(Ci.nsISelectionController);
+ },
+
+ init: function findHandlerInit() {
+ addMessageListener("FindAssist:Find", this);
+ addMessageListener("FindAssist:Next", this);
+ addMessageListener("FindAssist:Previous", this);
+ },
+
+ receiveMessage: function findHandlerReceiveMessage(aMessage) {
+ let findResult = Ci.nsITypeAheadFind.FIND_NOTFOUND;
+ let json = aMessage.json;
+ switch (aMessage.name) {
+ case "FindAssist:Find":
+ findResult = this._fastFind.find(json.searchString, false);
+ break;
+
+ case "FindAssist:Previous":
+ findResult = this._fastFind.findAgain(true, false);
+ break;
+
+ case "FindAssist:Next":
+ findResult = this._fastFind.findAgain(false, false);
+ break;
+ }
+
+ if (findResult == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
+ sendAsyncMessage("FindAssist:Show", { rect: null , result: findResult });
+ return;
+ }
+
+ let controller = this._selectionController.getSelection(Ci.nsISelectionController.SELECTION_NORMAL);
+ if (!controller.rangeCount) {
+ // The selection can be into an input or a textarea element
+ let nodes = content.document.querySelectorAll("input[type='text'], textarea");
+ for (let i = 0; i < nodes.length; i++) {
+ let node = nodes[i];
+ if (node instanceof Ci.nsIDOMNSEditableElement && node.editor) {
+ controller = node.editor.selectionController.getSelection(Ci.nsISelectionController.SELECTION_NORMAL);
+ if (controller.rangeCount)
+ break;
+ }
+ }
+ }
+
+ let range = controller.getRangeAt(0);
+ let scroll = Util.getScrollOffset(content);
+ let rect = range.getBoundingClientRect();
+ rect = new Rect(scroll.x + rect.left, scroll.y + rect.top, rect.width, rect.height);
+ sendAsyncMessage("FindAssist:Show", { rect: rect.isEmpty() ? null: rect , result: findResult });
+ }
+};
+
+FindHandler.init();
--- a/mobile/locales/en-US/chrome/browser.dtd
+++ b/mobile/locales/en-US/chrome/browser.dtd
@@ -22,19 +22,20 @@
<!ENTITY bookmarksHeader.label "Bookmarks">
<!ENTITY bookmarksManage.label "Manage">
<!ENTITY editBookmarkRemove.label "Remove">
<!ENTITY editBookmarkDone.label "Done">
<!ENTITY editBookmarkTags.label "Add tags here">
-<!ENTITY formHelper.previous "Previous">
-<!ENTITY formHelper.next "Next">
-<!ENTITY formHelper.done "Done">
+<!ENTITY contentNavigator.previous "Previous">
+<!ENTITY contentNavigator.next "Next">
+
+<!ENTITY selectHelper.done "Done">
<!ENTITY addonsHeader.label "Add-ons">
<!ENTITY addonsLocal.label "Your Add-ons">
<!ENTITY addonsUpdate.label "Update">
<!ENTITY addonsRepo.label "Get Add-ons">
<!ENTITY addonsRecommended.label "Recommended">
<!ENTITY addonsSearch.label "Search">
<!ENTITY addonsSearch2.emptytext "Search Catalog">
--- a/mobile/locales/en-US/chrome/browser.properties
+++ b/mobile/locales/en-US/chrome/browser.properties
@@ -144,16 +144,17 @@ homepage.custom2=Custom Page
pageactions.saveas.pdf=Save As PDF
pageactions.search.addNew=Add Search Engine
pageactions.password.forget=Forget Password
pageactions.reset=Clear Site Preferences
pageactions.geo=Location
pageactions.popup=Popups
pageactions.offline-app=Offline Storage
pageactions.password=Password
+pageactions.findInPage=Find
# Helper App Dialog (Save/Open)
helperApp.title=Opening File
helperApp.prompt=What would you like to do with:
helperApp.open=Open
helperApp.save=Save
helperApp.nothing=Nothing
--- a/mobile/themes/core/browser.css
+++ b/mobile/themes/core/browser.css
@@ -201,19 +201,21 @@ toolbarbutton.urlbar-cap-button {
background: #fff;
margin: 0 !important;
padding: 0 !important;
border: none !important;
border-top: 1px solid #262629 !important;
border-bottom: 3px solid #262629 !important;
-moz-border-radius: 0;
}
+
#urlbar-edit > hbox > .textbox-input-box {
margin: 0;
}
+
#urlbar-edit > hbox > hbox > .textbox-input {
min-height: 60px;
text-indent: 3px;
}
#urlbar-edit:hover:active {
background-color: #8db8d8;
}
@@ -1091,46 +1093,60 @@ pageaction .pageaction-desc[value=""] {
white-space: pre-wrap;
}
/* helperapp (save-as) popup ----------------------------------------------- */
#helperapp-target {
font-size: 18px !important;
}
-/* form popup -------------------------------------------------------------- */
-#form-helper-container > #select-container > #select-container-inner {
+/* navigator popup -------------------------------------------------------------- */
+#content-navigator,
+#content-navigator #select-buttons {
+ display: none;
+}
+
+#content-navigator[type="find"],
+#content-navigator[type="form"] {
+ display: -moz-box;
+}
+
+#content-navigator:not([type="form"]) > #form-helper-autofill {
+ visibility: collapse;
+}
+
+#content-navigator:not([type="form"]) > #select-container,
+#content-navigator:not([type="find"]) > #find-helper-textbox {
+ display: none;
+}
+
+#content-navigator > #select-container > #select-container-inner {
+ border-width: 0;
-moz-border-radius-topleft: 8px;
-moz-border-radius-topright: 8px;
-moz-border-radius-bottomright: 0;
-moz-border-radius-bottomleft: 0;
padding: 8px 4px 8px 4px;
-moz-box-flex: 0;
}
-#form-helper-container > #select-container > #select-container-inner > scrollbox {
+#content-navigator > #select-container > #select-container-inner > scrollbox {
min-height: 70px;
}
-#form-helper-container > #select-container > spacer {
+#content-navigator > #select-container > spacer {
display: none;
}
-#form-helper-container > #select-container > #select-container-inner,
-#form-buttons {
- border: 1px solid gray;
- border-bottom: 0;
-}
-
-#form-buttons,
+#content-navigator > hbox,
#select-buttons {
padding: 4px 8px; /* row size & core spacing */
}
-#form-buttons > button,
+#content-navigator > hbox > button,
#select-buttons > button {
-moz-user-focus: ignore;
-moz-user-select: none;
}
#form-helper-autofill {
padding: 4px 0; /* half core spacing & none (autorepeat arrows compensate) */
border-top: 2px solid #36373b;