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 })); |