ginebra2/chrome/bedrockchrome/suggests.snippet/suggests.js
changeset 5 0f2326c2a325
parent 0 1450b09d0cfd
child 6 1c3b8676e58c
--- a/ginebra2/chrome/bedrockchrome/suggests.snippet/suggests.js	Fri May 14 15:40:36 2010 +0300
+++ b/ginebra2/chrome/bedrockchrome/suggests.snippet/suggests.js	Wed Jun 23 17:59:43 2010 +0300
@@ -1,69 +1,250 @@
+/*!
+  \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);
     }
 
-    this.hideSuggests = function() {
-        window.snippets.SuggestsId.hide();
+    //! 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
+    }
+
+    //! 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();
+        }
     }
 
-    this.setWidth = function(width) {
-        document.getElementById("SuggestsId").style.width = width;
-        //window.chrome.alert("set width:" + document.getElementById("SuggestsId").offsetWidth);
+    //! 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_url_bar_drop_down_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.setHeight = function(height) {
-        document.getElementById("SuggestsId").style.height = height;
-        //window.chrome.alert("set height:" + document.getElementById("SuggestsId").offsetHeight);
+    //! 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.removeAllItems = function() {
-        var parentList = document.getElementById("SuggestsUListId");
-        while (parentList.childNodes[0]) {
-            parentList.removeChild(parentList.childNodes[0]);
+    //! 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);
         }
-        this.setHeight(0);
+    }
+
+    //! 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.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);
+    //! 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 == "QGraphicsSceneMousePressEvent") {
+            _hideSuggests();
+        }
+    }
+
+    //! 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
+        }
+    }
+
+    //! 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;