--- a/ginebra2/chrome/bedrockchrome/suggests.snippet/suggests.js Fri May 14 15:40:36 2010 +0300
+++ b/ginebra2/chrome/bedrockchrome/suggests.snippet/suggests.js Tue Jun 29 00:46:29 2010 -0400
@@ -1,69 +1,263 @@
+/*!
+ \file suggests.js This module contains the Suggests class.
+*/
+
+/*!
+ Class to handle displaying URL suggestions from history and bookmarks.
+*/
function Suggests()
{
- // attach internal funcs
- this.write = writeSuggests;
+ // "Private" member variables
+ var suggestsXOffset = 20;
+ var inputTimeoutId = null;
+ var inputTimeoutDelay = _getTimeoutDelaySetting();
+ var maxHeight = 0; // maximum height of suggest list
+ var urlSearchHeight = 0;
- // do setup
- this.write();
+ // "Private" methods
- this.showSuggests = function() {
- window.chrome.alert("showSuggests");
- //window.snippets.updateGeometry();
- window.snippets.SuggestsId.repaint();
+ //! Calculates the maximum height for the suggest list.
+ //! If not all suggest items can fit in list, only half an item should be
+ //! visible the end when scrolled to the top. This is to indicate more items.
+ function _setMaxHeight()
+ {
+ // Calculate height of available space for suggest list.
+ var statusbarSz = snippets.StatusBarChromeId.getGeometry();
+ var urlSearchSz = snippets.UrlSearchChromeId.getGeometry();
+ var toolbarSz = snippets.WebViewToolbarId.getGeometry();
+ // leave some space between suggest and toolbar (~10% of display height)
+ var bufferHeight = Math.ceil(chrome.displaySize.height / 10);
+ var availableHeight = chrome.displaySize.height -
+ (statusbarSz.height + urlSearchSz.height + toolbarSz.height + bufferHeight);
+ // Calculate number of elements that can fit in available space.
+ var elementHeight = 70; // set in suggests.css
+ var numElements = Math.floor(availableHeight / elementHeight);
- var curPos = window.snippets.SuggestsId.getPosition();
- window.chrome.alert(curPos.x);
- if (curPos.y == 0)
- window.snippets.SuggestsId.setPosition(5,68);
- window.snippets.SuggestsId.show();
- window.snippets.SuggestsId.zValue = 10;
+ // in order to make room for 1/2 entry at end of list we may
+ // need to sacrifice 1 full element.
+ if ((availableHeight % elementHeight) < (elementHeight / 2)) {
+ numElements -= 1;
+ }
+ numElements += 0.5; // half of final visible entry
+ // max suggest list height in pixels
+ maxHeight = Math.floor(numElements * elementHeight);
+ }
+
+ //! Temporary substitute for settings function to get the delay for
+ //! displaying the URL suggests list.
+ function _getTimeoutDelaySetting()
+ {
+ // no setting stored for this currently
+ return (1000); // 1 second
}
- this.hideSuggests = function() {
- window.snippets.SuggestsId.hide();
+ //! Displays and updates suggest list.
+ function _showSuggests()
+ {
+ // make sure the input is the latest
+ var input = window.snippets.UrlSearchChromeId.url;
+
+ // only display suggestions if there is input
+ if (input.length != 0) {
+ _updateSuggestList(input);
+ this.updateSuggestsSize();
+
+ if (!snippets.SuggestsChromeId.visible
+ && (pageController.loadState == Suggests.GotoModeEditing)) {
+ window.scrollTo(0, 0);
+ // Disable the content view, leave the URL serach bar and status bar enabled.
+ views.WebView.enabled = false;
+ views.WebView.freeze();
+ snippets.SuggestsChromeId.show(false);
+ }
+ } else {
+ // no user input so hide suggestions
+ _hideSuggests();
+ }
+ }
+
+ //! Updates the suggestion list based on the specified input.
+ /*!
+ \param input the current URL box text
+ */
+ function _updateSuggestList(input)
+ {
+ var recenturl;
+ var recenttitle = window.localeDelegate.translateText(
+ "txt_browser_chrome_suggests_search_for");
+ var snippetId = document.getElementById('SuggestsId');
+ var suggests = window.pageController.fetchSuggestions(input);
+ var suggestUL = document.createElement('ul');
+ var suggestLI = document.createElement('li');
+ var pattern = new RegExp(input, "ig");
+
+ snippetId.innerHTML = ""; // clear previous results
+ suggestUL.id = 'suggestUlId';
+ suggestLI.id = "searchLiId";
+
+ // always provide an option to search for user entry
+ recenttitle = recenttitle.replace(/%1/, "<b>" + input + "</b>");
+
+ suggestLI.innerHTML = '<a href="#" onclick="searchSuggests.searchUrlValue(\''+input+'\');'+
+ 'return false;">'+
+ '<div class="SuggestElement">'+'<span class="aTitle">'+recenttitle+'</span>'+'</div></a>';
+ suggestUL.appendChild(suggestLI);
+
+ // add each search suggestion to unordered list
+ for (i=0; i < suggests.length; i++) {
+ recenturl = suggests[i].url;
+ recenttitle = suggests[i].title;
+ suggestLI = document.createElement('li');
+ suggestLI.id = "suggestsLiId";
+
+ // bold search text
+ recenttitle = recenttitle.replace(pattern, "<b>$&</b>");
+ recenturl = recenturl.replace(pattern, "<b>$&</b>");
+
+ suggestLI.innerHTML = '<a href="#" onclick="searchSuggests.gotoUrl(\''+suggests[i].url+'\');' +
+ ' return false;">'+
+ '<div class="SuggestElement">'+
+ '<span class="aTitle">'+recenttitle+'</span><br/>'+
+ '<span class="aUrl">'+recenturl+'</span></div></a>';
+ suggestUL.appendChild(suggestLI);
+ }
+
+ snippetId.appendChild(suggestUL);
}
- this.setWidth = function(width) {
- document.getElementById("SuggestsId").style.width = width;
- //window.chrome.alert("set width:" + document.getElementById("SuggestsId").offsetWidth);
+ //! Hides suggests list and support items.
+ function _hideSuggests()
+ {
+ clearTimeout(inputTimeoutId);
+ window.snippets.SuggestsChromeId.hide(false);
+ views.WebView.enabled = true;
+ views.WebView.unfreeze();
+ }
+
+ // Public Functions
+
+ //! Handler for onload javascript event.
+ this.loadComplete = function()
+ {
+ var urlSearchSz = snippets.UrlSearchChromeId.getGeometry();
+
+ urlSearchHeight = urlSearchSz.height;
+ snippets.SuggestsChromeId.anchorTo("UrlSearchChromeId", suggestsXOffset, urlSearchHeight);
+ snippets.SuggestsChromeId.zValue = 10;
+
+ _setMaxHeight(); // calculate max suggest list height
+
+ // hide suggests on external mouse events
+ snippets.SuggestsChromeId.externalMouseEvent.connect(this.handleExternalMouseEvent);
+ // need to resize suggest page snippet on geometry change
+ chrome.prepareForGeometryChange.connect(createDelegate(this, this.handleGeometryChange));
}
- this.setHeight = function(height) {
- document.getElementById("SuggestsId").style.height = height;
- //window.chrome.alert("set height:" + document.getElementById("SuggestsId").offsetHeight);
+ //! Updates the size of the suggests window depending on the size of the
+ //! main DIV -- which changes as the number of items changes.
+ this.updateSuggestsSize = function()
+ {
+ if (snippets.SuggestsChromeId != undefined) {
+ var totalW = chrome.displaySize.width;
+ var divHeight = document.getElementById("SuggestsId").clientHeight + 2;
+ var displayHeight = Math.min(maxHeight, divHeight);
+ var displayWidth = totalW - (2 * suggestsXOffset);
+
+ // reset snippet height
+ snippets.SuggestsChromeId.setSize(displayWidth, displayHeight);
+ }
+ }
+
+ //! Handles the geometry change signal. Need to re-calculate max height
+ //! and then update suggest page height.
+ this.handleGeometryChange = function()
+ {
+ _setMaxHeight(); // max height is based on display height
+ this.updateSuggestsSize();
+ }
+
+ //! Loads google search page for search string.
+ /*!
+ \param input value to search for
+ */
+ this.searchUrlValue = function(input)
+ {
+ var searchurl = window.pageController.searchUrl(input);
+
+ _hideSuggests();
+
+ window.pageController.currentLoad(searchurl);
+ window.pageController.urlTextChanged(searchurl);
}
- this.removeAllItems = function() {
- var parentList = document.getElementById("SuggestsUListId");
- while (parentList.childNodes[0]) {
- parentList.removeChild(parentList.childNodes[0]);
+ //! Hides suggests list and loads specified page.
+ /*!
+ \param url address of page to load
+ */
+ this.gotoUrl = function(url)
+ {
+ _hideSuggests();
+ url = window.pageController.guessUrlFromString(url);
+ window.pageController.currentLoad(url);
+ window.pageController.urlTextChanged(url);
+ }
+
+ //! Handles external mouse events - dismisses suggests list.
+ /*!
+ \param type the type of event
+ \param name the name of event
+ \param description event description
+ */
+ this.handleExternalMouseEvent = function(type, name, description)
+ {
+ if (name == "MouseClick") {
+ _hideSuggests();
}
- this.setHeight(0);
}
- this.addItem = function(str) {
- this.setHeight(document.getElementById("SuggestsId").offsetHeight + 26); // FIXME 26 is the row height
- var parentList = document.getElementById("SuggestsUListId");
- var item = document.createElement("li");
- item.innerHTML = str;
- item.onclick=function() { window.chrome.alert(item.innerHTML + " is selected."); window.snippets.SuggestsId.hide();}
- item.onmouseover=function() { item.style.backgroundColor = 'Aquamarine'; }
- item.onmouseout=function() { item.style.backgroundColor = ''; }
- parentList.appendChild(item);
+ //! Updates the user input for suggestion list.
+ /*!
+ \param input the current user input
+ */
+ this.updateUserInput = function()
+ {
+ // user still editing URL - don't show/update suggests yet
+ clearTimeout(inputTimeoutId);
+ inputTimeoutId = setTimeout(_showSuggests.bind(this), inputTimeoutDelay);
+ }
+
+ //! Called when load state changes. Suggests should only be called when
+ //! the load state is editing.
+ this.updateLoadState = function()
+ {
+ if (pageController.loadState != Suggests.GotoModeEditing) {
+ // loading or reloadable - suggests not ok
+ _hideSuggests(); // ensure suggests are hidden
+ }
+ }
+
+ //! Called when URL search bar looses focus. The external mouse event
+ //! handler deals with most cases where the suggestion list should be
+ //! dismissed but we don't get those events when the list isn't visible
+ //! so this handler is needed to cancel the timer in those cases.
+ this.urlSearchLostFocus = function()
+ {
+ // if visible user may be scrolling suggestion page so ignore focus change
+ if (!snippets.SuggestsChromeId.visible) {
+ // prevent suggestion list from being displayed until URL edited again
+ clearTimeout(inputTimeoutId);
+ }
+ }
+
+ //! Sets the user input URL suggest delay.
+ /*!
+ \param to the new delay time.
+ */
+ this.setSuggestTimeout = function(to)
+ {
+ inputTimeoutDelay = to;
}
}
-// "Private" methods
-function writeSuggests() {
- var html =
- '<div class="suggestsBox">' +
- '<div class="suggestBoxBody">' +
- '<div id="SuggestsListId" class="show">' +
- '<ul id="SuggestsUListId">' +
- '</ul>' +
- '</div>' +
- '</div>' +
- '</div>';
- document.write(html);
-}
-
+// we don't have access to WRT::LoadController::GotoModeEditing
+Suggests.GotoModeEditing = 1;