ginebra2/chrome/bedrockchrome/contextmenu.snippet/contextmenu.js
changeset 3 0954f5dd2cd0
parent 0 1450b09d0cfd
child 16 3c88a81ff781
equal deleted inserted replaced
1:b0dd75e285d2 3:0954f5dd2cd0
     1 function printProp(x) {
     1 var cm_TheContextMenu;
     2     window.app.debug(x + ":");
     2 
     3     for (property in x) {
     3 // Return true if the given element's className includes the given class.
     4         window.chrome.alert("  " + property + ": " + x[property]);
     4 function hasClass(ele,cls) {
     5     }
     5     return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
     6 }
     6 }
     7 
     7 
     8 function historyViewContextEvent(e) {
     8 // Remove a class from an element's className.
     9     window.chrome.alert("history context: " + e + " " + e.itemIndex + 
     9 function removeClass(ele,cls) {
    10                         " x=" + e.pos.x + " y=" + e.pos.y);
    10     if (hasClass(ele,cls)) {
    11     printProp(e);
    11         var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
       
    12         ele.className=ele.className.replace(reg,' ');
       
    13     }
    12 }
    14 }
    13 
    15 
    14 window.chrome.chromeComplete.connect(chromeLoadComplete);
    16 function ContextMenu(snippetId, contentView) {
    15 
    17     this.snippetId = snippetId;
    16 
    18     this.mainDiv = undefined;
    17 function chromeLoadComplete() {
    19     this.tailEl = undefined;
    18        
    20     this.contentView = contentView;
    19     window.snippets.ContextMenuId.externalMouseEvent.connect(
    21     this.showTimeoutId = 0;
    20         function(type, name, description) {
    22     // Width of a tab with no text, just the icon.  Icons must all be the same width.
    21         	
    23     // Update this if icon size or tab border width etc. changes -- or better yet, determine it dynamically.
    22             if ((name == "QGraphicsSceneMouseReleaseEvent") || (name == "QGraphicsSceneResizeEvent")){
    24     this.normalTabWidth = 64;
    23             	  window.snippets.ContextMenuId.hide();                                    
    25     // Height of the menu is the max possible height to be used when positioning the snippet
    24                 window.snippets.ContextMenuId.dontShow = true;
    26     this.menuHeight = 272;
    25                 setTimeout ( 'window.snippets.ContextMenuId.dontShow = false', 500 ); // reset the flag in 0.5 sec.
    27 
    26             } 
    28     // ContextMenu is a singleton to avoid problems with scope-chaining in some of the
    27         }
    29     // callbacks that it uses.  See handleTabActivate.
    28     );
    30     if (cm_TheContextMenu != undefined) app.debug("ERROR: cm_TheContextMenu must be a singleton");
    29  }
    31     cm_TheContextMenu = this;
    30 
    32 
    31 function ContextMenu()
    33     // Create tabs and their corresponding menus based on JSON data.
    32 {
    34     this.createTabsElement = function(data) {
    33 	 // attach internal funcs
    35         this.mainDiv = document.createElement("div");
    34     this.write = writeContextMenu;
    36         this.mainDiv.setAttribute("class", "ContextMenuDiv");
    35 
    37         this.mainDiv.setAttribute("id", "cm_mainDivId");
    36     // do setup
    38 
    37     this.write();
    39         var tabsDiv = document.createElement("div");
    38 }
    40         tabsDiv.setAttribute("class", "TabsDiv");
    39 ////
    41         tabsDiv.setAttribute("id", "cm_tabsDivId");
    40 
    42 
    41 function showBookmarkView()
    43         var menuDiv = document.createElement("div");
    42 {
    44         menuDiv.setAttribute("class", "MenuDiv");
    43     if(window.views.WebView.BookmarkTreeView == undefined) {
    45         menuDiv.setAttribute("id", "cm_menuDivId");
    44         window.views.WebView.createSuperPage("BookmarkTreeView", true);
    46 
    45     }
    47         var tabsUl = document.createElement("ul");
    46     window.views.WebView.BookmarkTreeView.load(chrome.baseDirectory + "bookmarkview.superpage/BookmarkView.html");
    48         tabsUl.setAttribute("class", "TabsUl");
    47 
    49         tabsUl.setAttribute("id", "cm_tabsUlId");
    48     // Show it.
    50         tabsDiv.appendChild(tabsUl);
    49     window.views.WebView.zoomFactor = 1.0;
    51 
    50     window.views.WebView.showSuperPage("BookmarkTreeView");
    52         var currentTabFound = false;
    51 }
    53 
    52 
    54         // Iterate through the list of tabs.
    53 function showSettingsView()
    55         for (var i=0; i < data.tabs.length; i++) {
    54 {
    56             var tab = data.tabs[i];
    55 	   if(window.views.WebView.SettingsView == undefined) {
    57             if (tab.visible != undefined) {
    56         window.views.WebView.createSuperPage("SettingsView", true);
    58                 if (!tab.visible()) {
    57     }
    59                     continue;
    58     window.views.WebView.SettingsView.load(chrome.baseDirectory + "settingsview.superpage/SettingsView.html");
    60                 }
    59 
    61             }
    60     // Show it.
    62 
    61     window.views.WebView.zoomFactor = 1.0;
    63             // Create the tab.
    62     window.views.WebView.showSuperPage("SettingsView");
    64             var tabEl = document.createElement("li");
    63 }
    65             tabsUl.appendChild(tabEl);
    64 
    66             
    65 function showHistoryView()
    67             var tabDiv = document.createElement("div");
    66 {
    68             tabEl.appendChild(tabDiv);
    67     if(window.views.WebView.BookmarkHistoryView == undefined) {
    69 
    68 	        window.views.WebView.createSuperPage("BookmarkHistoryView", true);
    70             var iconEl = undefined;
    69 	  }
    71             var iconHighlightedEl = undefined;
    70 	  window.views.WebView.BookmarkHistoryView.load(chrome.baseDirectory + "historyview.superpage/historyView.html");
    72             
    71      
    73             // Create the tab's icons.
    72     // Show it.
    74             if (tab.icon != undefined) {
    73     window.views.WebView.zoomFactor = 1.0;
    75                 iconEl = document.createElement("img");
    74     window.views.WebView.showSuperPage("BookmarkHistoryView");
    76                 iconEl.setAttribute("id", "icon");
    75 }
    77                 iconEl.setAttribute("src", tab.icon);
    76 
    78                 tabDiv.appendChild(iconEl);
    77 function goToRecentUrlView () {
    79             }
    78 	  showHistoryView();
    80             if (tab.iconHighlighted != undefined) {
    79 	  window.ViewStack.switchView("BookmarkHistoryView", "WebView");
    81                 iconHighlightedEl = document.createElement("img");
    80     }
    82                 iconHighlightedEl.setAttribute("id", "iconHighlighted");
    81 
    83                 iconHighlightedEl.setAttribute("src", tab.iconHighlighted);
    82 function goToBookmarkView () {
    84                 tabDiv.appendChild(iconHighlightedEl);
    83     showBookmarkView();
    85             }
    84     window.ViewStack.switchView("BookmarkTreeView", "WebView");
    86 
       
    87             // Create the tab's text.
       
    88             if (tab.text != undefined) {
       
    89                 var anchorEl = document.createElement("a");
       
    90                 tabDiv.appendChild(anchorEl);
       
    91                 var textEl = document.createTextNode(tab.text);
       
    92                 anchorEl.appendChild(textEl);
       
    93             }
       
    94 
       
    95             // Create the menu for this tab.
       
    96             var menuEl = this.createMenuElement(tab);
       
    97             menuDiv.appendChild(menuEl);
       
    98 
       
    99             var tabClassName;
       
   100             if (tab.current == "true") {
       
   101                 // This is the current, or selected, tab.
       
   102                 tabClassName = "ViewContext_HighlightedTab";
       
   103                 tabDiv.className = "ViewContext_HighlightedTabDiv";
       
   104                 if(iconEl != undefined) {
       
   105                     iconEl.setAttribute("style", "display: none;");
       
   106                 }
       
   107                 currentTabFound = true;
       
   108             }
       
   109             else {
       
   110                 // Not selected.
       
   111                 tabClassName = "ViewContext_NormalTab";
       
   112                 tabDiv.className = "ViewContext_NormalTabDiv";
       
   113                 if(iconHighlightedEl != undefined) {
       
   114                     iconHighlightedEl.setAttribute("style", "display: none;");
       
   115                 }
       
   116 
       
   117                 // Hide its menu.
       
   118                 menuEl.style.display = "none";
       
   119             }
       
   120 
       
   121             if (tab.disabled == "true") {
       
   122                 // The tab is disabled, add the appropriate CSS class to it.
       
   123                 tabClassName += " ViewContext_DisabledTab";
       
   124             }
       
   125 
       
   126             tabEl.className = tabClassName;
       
   127 
       
   128             // Set up callback to show the menu that corresponds to this tab.
       
   129             tabEl.onmouseup = this.handleTabActivate;
       
   130             tabEl.cm_menu = menuEl;
       
   131 
       
   132             // Remember that this tab is disabled.
       
   133             tabEl.cm_disabled = tab.disabled == "true";
       
   134         }
       
   135 
       
   136         // If a "current" tab was not specified, highlight the first tab and display its menu.
       
   137         if (!currentTabFound) {
       
   138             var firstTabEl = tabsUl.firstChild;
       
   139             firstTabEl.className = "ViewContext_HighlightedTab";
       
   140             firstTabEl.firstChild.className = "ViewContext_HighlightedTabDiv";
       
   141             firstTabEl.cm_menu.style.display = "";
       
   142         }
       
   143 
       
   144 //        this.tailEl = document.createElement("img");
       
   145 //        this.mainDiv.appendChild(this.tailEl);
       
   146 //        this.tailEl.setAttribute("id", "cm_tailId");
       
   147 //        this.tailEl.setAttribute("src", "contextmenu.snippet/icons/menu_tail.png");
       
   148 
       
   149         this.mainDiv.appendChild(tabsDiv);
       
   150         this.mainDiv.appendChild(menuDiv);
       
   151         return this.mainDiv;
       
   152     }
       
   153 
       
   154     // Create a single menu based on the given data structure.
       
   155     this.createMenuElement = function(data) {
       
   156         // Create menu list.
       
   157         var menuUl = document.createElement("ul");
       
   158         menuUl.setAttribute("class", "MenuUl");
       
   159 
       
   160         for (var i=0; i < data.menuItems.length; i++) {
       
   161             var menuItem = data.menuItems[i];
       
   162 
       
   163             // Create the item.
       
   164             var itemLi = document.createElement("li");
       
   165             itemLi.setAttribute("class", "MenuLi");
       
   166             var itemSpan = document.createElement("div");
       
   167 
       
   168             // Is it a row if items? enumerate that as a ul inside of this outer li
       
   169             if(menuItem.menuRow != undefined) {
       
   170                 var menuRowUl = document.createElement("ul");
       
   171                 menuRowUl.setAttribute("class", "MenuRowUl");
       
   172                 itemSpan.appendChild(menuRowUl);
       
   173 
       
   174                 for(var j=0; j < menuItem.menuRow.length; j++)
       
   175                 {
       
   176                     var menuRowItem = menuItem.menuRow[j];
       
   177                     
       
   178                     var rowItemLi = document.createElement("li");
       
   179                     rowItemLi.setAttribute("class", "MenuRowLi");
       
   180                     menuRowUl.appendChild(rowItemLi);
       
   181                     
       
   182                     // bind to mouseup
       
   183                     rowItemLi.onmouseup =  (function(handler) {
       
   184                         return function() {
       
   185                             if (handler != undefined)
       
   186                                 handler();
       
   187                             this.hide();
       
   188                         }.bind(this)
       
   189                     }.bind(this))(menuRowItem.onclick);
       
   190 
       
   191                     if (menuRowItem.text != undefined) {
       
   192                         var textEl = document.createTextNode(menuRowItem.text);
       
   193                         rowItemLi.appendChild(textEl);
       
   194                     }
       
   195                 }
       
   196             }
       
   197             else {
       
   198                 itemLi.className += " RegularMenuLi";
       
   199                 if (menuItem.disabled == "true" || data.disabled == "true") {
       
   200                     // Disabled item.
       
   201                     itemLi.className += " ViewContext_DisabledMenuItem";
       
   202                 }
       
   203                 else {
       
   204                     // Enabled item.  Set up the onmouseup handler.
       
   205                     itemLi.onmouseup = (function(handler) {
       
   206                         return function() {
       
   207                             if (handler != undefined)
       
   208                                 handler();
       
   209                             this.hide();
       
   210                         }.bind(this)
       
   211                     }.bind(this))(menuItem.onclick);
       
   212                 }
       
   213 
       
   214                 itemLi.onmouseover = function() {
       
   215                     this.className += " MouseOverItem";
       
   216                 }.bind(itemLi)
       
   217 
       
   218                 itemLi.onmouseout = function() {
       
   219                     removeClass(this, "MouseOverItem");
       
   220                 }.bind(itemLi)
       
   221 
       
   222                 // Create the item's icon.
       
   223                 if (menuItem.icon != undefined) {
       
   224                     var iconEl = document.createElement("img");
       
   225                     itemSpan.appendChild(iconEl);
       
   226                     iconEl.setAttribute("src", menuItem.icon);
       
   227                 }
       
   228 
       
   229                 // Create the item's text.
       
   230                 if (menuItem.text != undefined) {
       
   231                     var anchorEl = document.createElement("a");
       
   232                     itemSpan.appendChild(anchorEl);
       
   233                     var textEl = document.createTextNode(menuItem.text);
       
   234                     anchorEl.appendChild(textEl);
       
   235                 }
       
   236             }
       
   237 
       
   238             menuUl.appendChild(itemLi);
       
   239             itemLi.appendChild(itemSpan);
       
   240         }
       
   241         return menuUl;
    85     }
   242     }
    86     
   243     
    87 function goToSettingsView () {
   244     // Handle mouse clicks on tab elements.
    88     showSettingsView();
   245     // Note: "this" refers to the element that was clicked on, ie. the tab item.
    89     window.ViewStack.switchView("SettingsView", "WebView");
   246     this.handleTabActivate = function() {
    90     //window.snippets.UrlSearchChromeId.hide(false);       
   247         var tabsDivChildren = document.getElementById("cm_tabsUlId").childNodes;
    91 }
   248         var otherTabsWidth = 0;
    92 
   249         // Set the class for each tab.
    93 // "Private" methods
   250         for (var i = 0; i < tabsDivChildren.length; i++) {
    94 function writeContextMenu() {
   251             var tabEl = tabsDivChildren[i];
    95     var html =
   252             var iconHighlighted = getChildById(tabEl, "iconHighlighted");
    96     '<div class="loadImagesTop">'+
   253             var icon = getChildById(tabEl, "icon");
    97     '</div>'+
   254             if (tabEl == this) {
    98     '<div class="loadImagesCenter">'+
   255                 // Activate the tab.
    99     '</div>'+
   256                 tabEl.className = "ViewContext_HighlightedTab";
   100     '<div class="loadImagesBottom">'+
   257                 //tabEl.firstChild.className = "ViewContext_HighlightedTabDiv";
   101     '</div>'+
   258                 
       
   259                 // Show the highlighted icon, if one exists.
       
   260                 if(iconHighlighted != undefined) {
       
   261                     iconHighlighted.style.display = "";
       
   262                     
       
   263                     // Hide the normal icon.
       
   264                     if (icon != undefined) {
       
   265                         icon.style.display = "none";
       
   266                     }
       
   267                 }
       
   268             }
       
   269             else {
       
   270                 // Deactivate the tab.
       
   271                 tabEl.className = "ViewContext_NormalTab";
       
   272                 //tabEl.firstChildclassName = "ViewContext_NormalTabDiv";
       
   273                 
       
   274                 // If a highlighted icon exists, switch to the normal one, otherwise leave
       
   275                 // the normal one alone.
       
   276                 if(iconHighlighted != undefined) {
       
   277                     iconHighlighted.style.display = "none";
       
   278                     if (icon != undefined) {
       
   279                         icon.style.display = "";
       
   280                     }
       
   281                 }
       
   282             }
       
   283             if (tabEl.cm_disabled) {
       
   284                 tabEl.className += " ViewContext_DisabledTab";
       
   285                 //tabEl.firstClassName += " ViewContext_DisabledTabDiv";
       
   286             }
       
   287         }
       
   288 
       
   289         // Show the menu of the tab that was just clicked.
       
   290         var menuDivChildren = document.getElementById("cm_menuDivId").childNodes;
       
   291         for (var i = 0; i < menuDivChildren.length; i++) {
       
   292             var menuEl = menuDivChildren[i];
       
   293             if (menuEl == this.cm_menu) {
       
   294                 menuDivChildren[i].style.display =  "";
       
   295             }
       
   296             else {
       
   297                 menuDivChildren[i].style.display =  "none";
       
   298             }
       
   299         }
       
   300         //cm_TheContextMenu.positionTail();
       
   301         //document.getElementById(this.snippetId).clientHeight = this.mainDiv.clientHeight;
       
   302         //document.getElementById("ContextMenuId").setAttribute("style", "height: " + document.getElementById("cm_mainDivId").clientHeight + "px;")
       
   303 
       
   304         cm_TheContextMenu.updateTabSizes();
       
   305         snippets[cm_TheContextMenu.snippetId].updateOwnerArea();
       
   306     }
       
   307 
       
   308     // Return the width of the "non-content" part of the element box, ie. thickness of
       
   309     // the padding, the border and the margin.
       
   310     this.getNonContentWidth = function(element) {
       
   311         var tabStyle = document.defaultView.getComputedStyle(element, null);
       
   312         return parseInt(tabStyle["margin-left"]) + parseInt(tabStyle["margin-right"]) +
       
   313                parseInt(tabStyle["padding-left"]) + parseInt(tabStyle["padding-right"]) +
       
   314                parseInt(tabStyle["border-left-width"]) + parseInt(tabStyle["border-right-width"]);
       
   315     }
       
   316 
       
   317     // Update the tab widths.  Expand the highlighted tab to its maximum width and shrink the
       
   318     // normal tabs to their minimum widths.  Note: it would be preferable to have this done
       
   319     // by CSS.
       
   320     this.updateTabSizes = function() {
       
   321         var tabsUl = document.getElementById("cm_tabsUlId");
       
   322         var tabsDivChildren = tabsUl.childNodes;
       
   323         var otherTabsWidth = 0;
       
   324         var highlightedTab;
       
   325         for (var i = 0; i < tabsDivChildren.length; i++) {
       
   326             var tabEl = tabsDivChildren[i];
       
   327             if (tabEl.className.indexOf("ViewContext_HighlightedTab") != -1) {
       
   328                 highlightedTab = tabEl;
       
   329             }
       
   330             else {
       
   331                 var newTabWidth = cm_TheContextMenu.normalTabWidth - cm_TheContextMenu.getNonContentWidth(tabEl);
       
   332                 tabEl.style.width = newTabWidth;
       
   333                 otherTabsWidth += tabEl.offsetWidth;
       
   334             }
       
   335         }
       
   336         if (highlightedTab != undefined) {
       
   337             var newWidth = tabsUl.offsetWidth - otherTabsWidth;
       
   338             newWidth -= cm_TheContextMenu.getNonContentWidth(highlightedTab) + 2;
       
   339             highlightedTab.style.width = newWidth;
       
   340         }
       
   341     }
       
   342 
       
   343     this.positionTail = function() {
       
   344         // Move the "tail" into position.
       
   345         var tailEl = document.getElementById("cm_tailId");
       
   346         if (tailEl != undefined) {
       
   347             //var mainDiv = document.getElementById("cm_mainDivId");
       
   348             var tailX = (this.mainDiv.clientWidth - tailEl.clientWidth) / 2;
       
   349             var tailY = this.mainDiv.clientHeight;
       
   350             tailEl.setAttribute("style", "position:absolute; top: " + tailY + "px; left: " + tailX);
       
   351         }
       
   352     }
       
   353 
       
   354     // Create all the DOM elements of the window.
       
   355     this.create = function(menuData) {
       
   356         var snippetEl = document.getElementById(this.snippetId);
       
   357         var el = this.createTabsElement(menuData);
       
   358         snippetEl.appendChild(el);
       
   359     }
       
   360 
       
   361     // Show the content menu.  The menuData must contain an object tree describing the structure of the
       
   362     // tabs and sub-menus.
       
   363     //
       
   364     // Example menu data in JSON format:
       
   365     //        var MenuData = {
       
   366     //            "tabs": [ {
       
   367     //                     "text": "Tab 1",
       
   368     //                     "icon": "tab1.png",
       
   369     //                     "current": "true",
       
   370     //                     "menuItems": [ {
       
   371     //                             "text": Menu item 1,
       
   372     //                             "onclick": handleMenu1,
       
   373     //                             "icon": "menu1.png",
       
   374     //                           },
       
   375     //                           {
       
   376     //                             "text": Menu item 2,
       
   377     //                             "onclick": function() { alert("hello"); },
       
   378     //                             "icon": "menu2.png",
       
   379     //                           },
       
   380     //                         ],
       
   381     //                 },
       
   382     //                 {
       
   383     //                     "text": "Tab 2",
       
   384     //                     "icon": "tab2.png",
       
   385     //                     "menuItems": [ {
       
   386     //                             "text": Menu item 1,
       
   387     //                             "onclick": handleMenu21,
       
   388     //                           },
       
   389     //                           {
       
   390     //                             "text": Menu item 2,
       
   391     //                             "onclick": handleMenu22,
       
   392     //                           },
       
   393     //                         ],
       
   394     //                 },
       
   395     //                ]
       
   396     //        };
       
   397     //
   102     
   398     
   103     '<div class="menuItem menuTop">'+
   399     this.cancel = function() {
   104       '<div class="menuItemContents" onmouseup="goToBookmarkView(); window.snippets.ContextMenuId.hide()">'+
   400         //app.debug("CM: cancel " + this.showTimeoutId);
   105         '<img STYLE="vertical-align: middle; padding-left: 20px; padding-right: 15px;" src="contextmenu.snippet/icons/menu_icon_bookmarks.png">'+
   401         clearTimeout(this.showTimeoutId);
   106         '<span class="menuItemLabel">'+          
   402         this.showTimeoutId = 0;
   107           window.localeDelegate.translateText("content_view_menu_bookmarks")+
   403         this.cleanUp();
   108         '</span>'+
   404     }
   109       '</div>'+
   405 
   110     '</div>'+
   406     this.cleanUp = function() {
   111 
   407         // Remove elements from DOM to save memory.
   112     '<div class="menuItem menuBot">'+
   408         var oldEl = document.getElementById("cm_mainDivId");
   113       '<div class="menuItemContents" onmouseup="goToRecentUrlView();window.snippets.ContextMenuId.hide()">'+
   409         if (oldEl) {
   114         '<img STYLE="vertical-align: middle; padding-left: 20px; padding-right: 15px;" src="contextmenu.snippet/icons/menu_icon_settings.png">'+
   410             var snippetEl = document.getElementById(cm_TheContextMenu.snippetId);
   115         '<span class="menuItemLabel">'+
   411             snippetEl.removeChild(oldEl);
   116         window.localeDelegate.translateText("content_view_menu_history")+
   412         }
   117         '</span>'+
   413     }
   118       '</div>'+
   414 
   119     '</div>';
   415     // Hide this window.
   120    
   416     this.hide = function() {
   121   document.write(html);
   417         snippets[cm_TheContextMenu.snippetId].hide();
   122 }
   418     }
   123 
   419 
   124 
   420     this.onHide = function() {
   125 
   421         this.cleanUp();
       
   422     }
       
   423 
       
   424     this.show = function(menuData) {
       
   425         this.cleanUp();
       
   426         this.create(menuData);
       
   427 
       
   428         cm_TheContextMenu.updateTabSizes();
       
   429         // Use a timer to actually show the window to allow the page re-layout
       
   430         // to finish.  We don't know when this really happens but 50ms seems to
       
   431         // be enough on the N97.  Without this delay the bottom of the window
       
   432         // often gets clipped.
       
   433         setTimeout("cm_TheContextMenu.showIt2()", 50);
       
   434     }
       
   435 
       
   436     this.showIt2 = function() {
       
   437 
       
   438         var snippet = snippets[cm_TheContextMenu.snippetId];
       
   439         snippet.updateOwnerArea();
       
   440         snippet.setZValue(2);
       
   441 
       
   442         this.centerSnippet();
       
   443 
       
   444 //        if (showTail) {
       
   445 //            cm_TheContextMenu.positionTail();
       
   446 //        }
       
   447 
       
   448         snippet.show();
       
   449     }
       
   450 
       
   451 
       
   452     this.centerSnippet = function() {
       
   453 
       
   454         
       
   455         var statusBarHeight = snippets.StatusBarChromeId.geometry.height;
       
   456         
       
   457         var snippet = snippets[cm_TheContextMenu.snippetId];
       
   458         var x = (chrome.displaySize.width - snippet.geometry.width) / 2;
       
   459         
       
   460         // Center the menu in the space between status bar and tool bar
       
   461         var y = (chrome.displaySize.height - statusBarHeight - snippets.WebViewToolbarId.geometry.height - cm_TheContextMenu.menuHeight)/2;
       
   462         snippet.setPosition(x, (y+statusBarHeight));
       
   463     
       
   464     }
       
   465     chrome.chromeComplete.connect(createDelegate(this,
       
   466         function() {
       
   467             var snippet = snippets[cm_TheContextMenu.snippetId];
       
   468 
       
   469             chrome.aspectChanged.connect(createDelegate(this,
       
   470                     function(a) {
       
   471                         this.centerSnippet();
       
   472                     }));
       
   473 
       
   474             snippet.hidden.connect(createDelegate(this, this.onHide));
       
   475 
       
   476         }));
       
   477 }  // End ContextMenu class