ginebra2/chrome/bedrockchrome/contextmenu.snippet/contextmenu.js
changeset 6 1c3b8676e58c
parent 5 0f2326c2a325
equal deleted inserted replaced
5:0f2326c2a325 6:1c3b8676e58c
     1 var cm_TheContextMenu;
     1 var cm_TheContextMenu;
     2     
     2 
       
     3 // Return true if the given element's className includes the given class.
       
     4 function hasClass(ele,cls) {
       
     5     return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
       
     6 }
       
     7 
       
     8 // Remove a class from an element's className.
       
     9 function removeClass(ele,cls) {
       
    10     if (hasClass(ele,cls)) {
       
    11         var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
       
    12         ele.className=ele.className.replace(reg,' ');
       
    13     }
       
    14 }
       
    15 
     3 function ContextMenu(snippetId, contentView) {
    16 function ContextMenu(snippetId, contentView) {
     4     this.snippetId = snippetId;
    17     this.snippetId = snippetId;
     5     this.mainDiv = undefined;
    18     this.mainDiv = undefined;
     6     this.tailEl = undefined;
    19     this.tailEl = undefined;
     7     this.contentView = contentView;
    20     this.contentView = contentView;
     8     this.showTimeoutId = 0;
    21     this.showTimeoutId = 0;
     9     // Width of a tab with no text, just the icon.  Icons must all be the same width.
    22     // Width of a tab with no text, just the icon.  Icons must all be the same width.
    10     // Update this if icon size or tab border width etc. changes -- or better yet, determine it dynamically.
    23     // Update this if icon size or tab border width etc. changes -- or better yet, determine it dynamically.
    11     this.normalTabWidth = 64;
    24     this.normalTabWidth = 64;
       
    25     // Height of the menu is the max possible height to be used when positioning the snippet
       
    26     this.menuHeight = 272;
    12 
    27 
    13     // ContextMenu is a singleton to avoid problems with scope-chaining in some of the
    28     // ContextMenu is a singleton to avoid problems with scope-chaining in some of the
    14     // callbacks that it uses.  See handleTabActivate.
    29     // callbacks that it uses.  See handleTabActivate.
    15     if (cm_TheContextMenu != undefined) app.debug("ERROR: cm_TheContextMenu must be a singleton");
    30     if (cm_TheContextMenu != undefined) app.debug("ERROR: cm_TheContextMenu must be a singleton");
    16     cm_TheContextMenu = this;
    31     cm_TheContextMenu = this;
   193                                 handler();
   208                                 handler();
   194                             this.hide();
   209                             this.hide();
   195                         }.bind(this)
   210                         }.bind(this)
   196                     }.bind(this))(menuItem.onclick);
   211                     }.bind(this))(menuItem.onclick);
   197                 }
   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)
   198 
   221 
   199                 // Create the item's icon.
   222                 // Create the item's icon.
   200                 if (menuItem.icon != undefined) {
   223                 if (menuItem.icon != undefined) {
   201                     var iconEl = document.createElement("img");
   224                     var iconEl = document.createElement("img");
   202                     itemSpan.appendChild(iconEl);
   225                     itemSpan.appendChild(iconEl);
   377         //app.debug("CM: cancel " + this.showTimeoutId);
   400         //app.debug("CM: cancel " + this.showTimeoutId);
   378         clearTimeout(this.showTimeoutId);
   401         clearTimeout(this.showTimeoutId);
   379         this.showTimeoutId = 0;
   402         this.showTimeoutId = 0;
   380         this.cleanUp();
   403         this.cleanUp();
   381     }
   404     }
   382     
       
   383     this.show = function(menuData) {
       
   384         this.cleanUp();
       
   385         this.create(menuData);
       
   386         this.showTimeoutId = setTimeout('cm_TheContextMenu.showIt()', 10);
       
   387     }
       
   388 
   405 
   389     this.cleanUp = function() {
   406     this.cleanUp = function() {
   390         // Remove elements from DOM to save memory.
   407         // Remove elements from DOM to save memory.
   391         var oldEl = document.getElementById("cm_mainDivId");
   408         var oldEl = document.getElementById("cm_mainDivId");
   392         if (oldEl) {
   409         if (oldEl) {
   402 
   419 
   403     this.onHide = function() {
   420     this.onHide = function() {
   404         this.cleanUp();
   421         this.cleanUp();
   405     }
   422     }
   406 
   423 
   407     this.showIt = function() {
   424     this.show = function(menuData) {
       
   425         this.cleanUp();
       
   426         this.create(menuData);
       
   427 
   408         cm_TheContextMenu.updateTabSizes();
   428         cm_TheContextMenu.updateTabSizes();
   409         // Use a timer to actually show the window to allow the page re-layout
   429         // Use a timer to actually show the window to allow the page re-layout
   410         // to finish.  We don't know when this really happens but 50ms seems to
   430         // to finish.  We don't know when this really happens but 50ms seems to
   411         // be enough on the N97.  Without this delay the bottom of the window
   431         // be enough on the N97.  Without this delay the bottom of the window
   412         // often gets clipped.
   432         // often gets clipped.
   413         setTimeout("cm_TheContextMenu.showIt2()", 50);
   433         setTimeout("cm_TheContextMenu.showIt2()", 50);
   414     }
   434     }
   415 
   435 
   416     this.showIt2 = function() {
   436     this.showIt2 = function() {
       
   437 
   417         var snippet = snippets[cm_TheContextMenu.snippetId];
   438         var snippet = snippets[cm_TheContextMenu.snippetId];
   418 
       
   419         snippet.updateOwnerArea();
   439         snippet.updateOwnerArea();
   420         snippet.setZValue(2);
   440         snippet.setZValue(2);
   421 
   441 
   422         centerSnippet(snippet);
   442         this.centerSnippet();
   423 
   443 
   424 //        if (showTail) {
   444 //        if (showTail) {
   425 //            cm_TheContextMenu.positionTail();
   445 //            cm_TheContextMenu.positionTail();
   426 //        }
   446 //        }
   427 
   447 
   428         snippet.show();
   448         snippet.show();
   429     }
   449     }
   430 
   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     }
   431     chrome.chromeComplete.connect(createDelegate(this,
   465     chrome.chromeComplete.connect(createDelegate(this,
   432         function() {
   466         function() {
   433             var snippet = snippets[this.snippetId];
   467             var snippet = snippets[cm_TheContextMenu.snippetId];
   434 
   468 
   435             chrome.aspectChanged.connect(createDelegate(this,
   469             chrome.aspectChanged.connect(createDelegate(this,
   436                     function(a) {
   470                     function(a) {
   437                         centerSnippet(snippets[this.snippetId]);
   471                         this.centerSnippet();
   438                     }));
   472                     }));
   439 
   473 
   440             snippet.hidden.connect(createDelegate(this, this.onHide));
   474             snippet.hidden.connect(createDelegate(this, this.onHide));
   441 
   475 
   442         }));
   476         }));