17 this.snippetId = snippetId; |
17 this.snippetId = snippetId; |
18 this.mainDiv = undefined; |
18 this.mainDiv = undefined; |
19 this.tailEl = undefined; |
19 this.tailEl = undefined; |
20 this.contentView = contentView; |
20 this.contentView = contentView; |
21 this.showTimeoutId = 0; |
21 this.showTimeoutId = 0; |
|
22 this.editingSnippet = undefined; |
22 // Width of a tab with no text, just the icon. Icons must all be the same width. |
23 // Width of a tab with no text, just the icon. Icons must all be the same width. |
23 // Update this if icon size or tab border width etc. changes -- or better yet, determine it dynamically. |
24 // Update this if icon size or tab border width etc. changes -- or better yet, determine it dynamically. |
24 this.normalTabWidth = 64; |
25 this.normalTabWidth = 64; |
25 // Height of the menu is the max possible height to be used when positioning the snippet |
26 // Height of the menu is the max possible height to be used when positioning the snippet |
26 this.menuHeight = 272; |
27 this.menuHeight = 272; |
27 |
28 this.snippetWidth = 0; |
|
29 // Width of the menu when it has no tab |
|
30 this.menuWidth = 130; |
28 // ContextMenu is a singleton to avoid problems with scope-chaining in some of the |
31 // ContextMenu is a singleton to avoid problems with scope-chaining in some of the |
29 // callbacks that it uses. See handleTabActivate. |
32 // callbacks that it uses. See handleTabActivate. |
30 if (cm_TheContextMenu != undefined) app.debug("ERROR: cm_TheContextMenu must be a singleton"); |
33 if (cm_TheContextMenu != undefined) app.debug("ERROR: cm_TheContextMenu must be a singleton"); |
31 cm_TheContextMenu = this; |
34 cm_TheContextMenu = this; |
32 |
35 |
48 tabsUl.setAttribute("class", "TabsUl"); |
51 tabsUl.setAttribute("class", "TabsUl"); |
49 tabsUl.setAttribute("id", "cm_tabsUlId"); |
52 tabsUl.setAttribute("id", "cm_tabsUlId"); |
50 tabsDiv.appendChild(tabsUl); |
53 tabsDiv.appendChild(tabsUl); |
51 |
54 |
52 var currentTabFound = false; |
55 var currentTabFound = false; |
|
56 if (data.tabs == undefined) { |
|
57 var menuEl = this.createMenuElement(data.menus[0], true); |
|
58 menuDiv.appendChild(menuEl); |
|
59 document.getElementById(this.snippetId).style.width = this.menuWidth; |
|
60 this.mainDiv.appendChild(menuDiv); |
|
61 return this.mainDiv; |
|
62 } |
53 |
63 |
54 // Iterate through the list of tabs. |
64 // Iterate through the list of tabs. |
55 for (var i=0; i < data.tabs.length; i++) { |
65 for (var i=0; i < data.tabs.length; i++) { |
56 var tab = data.tabs[i]; |
66 var tab = data.tabs[i]; |
57 if (tab.visible != undefined) { |
67 if (tab.visible != undefined) { |
142 } |
152 } |
143 |
153 |
144 // this.tailEl = document.createElement("img"); |
154 // this.tailEl = document.createElement("img"); |
145 // this.mainDiv.appendChild(this.tailEl); |
155 // this.mainDiv.appendChild(this.tailEl); |
146 // this.tailEl.setAttribute("id", "cm_tailId"); |
156 // this.tailEl.setAttribute("id", "cm_tailId"); |
147 // this.tailEl.setAttribute("src", "contextmenu.snippet/icons/menu_tail.png"); |
157 // this.tailEl.setAttribute("src", "/contextmenu/menu_tail.png"); |
148 |
158 |
149 this.mainDiv.appendChild(tabsDiv); |
159 this.mainDiv.appendChild(tabsDiv); |
150 this.mainDiv.appendChild(menuDiv); |
160 this.mainDiv.appendChild(menuDiv); |
151 return this.mainDiv; |
161 return this.mainDiv; |
152 } |
162 } |
153 |
163 |
154 // Create a single menu based on the given data structure. |
164 // Create a single menu based on the given data structure. |
155 this.createMenuElement = function(data) { |
165 this.createMenuElement = function(data, noTab) { |
156 // Create menu list. |
166 // Create menu list. |
157 var menuUl = document.createElement("ul"); |
167 var menuUl = document.createElement("ul"); |
158 menuUl.setAttribute("class", "MenuUl"); |
168 menuUl.setAttribute("class", "MenuUl"); |
159 |
169 |
160 for (var i=0; i < data.menuItems.length; i++) { |
170 for (var i=0; i < data.menuItems.length; i++) { |
161 var menuItem = data.menuItems[i]; |
171 var menuItem = data.menuItems[i]; |
162 |
172 |
163 // Create the item. |
173 // Create the item. |
164 var itemLi = document.createElement("li"); |
174 var itemLi = document.createElement("li"); |
165 itemLi.setAttribute("class", "MenuLi"); |
175 if(noTab == true) |
|
176 itemLi.setAttribute("class", "SpMenuLi"); |
|
177 else |
|
178 itemLi.setAttribute("class", "MenuLi"); |
166 var itemSpan = document.createElement("div"); |
179 var itemSpan = document.createElement("div"); |
167 |
180 |
168 // Is it a row if items? enumerate that as a ul inside of this outer li |
181 // Is it a row if items? enumerate that as a ul inside of this outer li |
169 if(menuItem.menuRow != undefined) { |
182 if(menuItem.menuRow != undefined) { |
170 var menuRowUl = document.createElement("ul"); |
183 var menuRowUl = document.createElement("ul"); |
196 } |
209 } |
197 else { |
210 else { |
198 itemLi.className += " RegularMenuLi"; |
211 itemLi.className += " RegularMenuLi"; |
199 if (menuItem.disabled == "true" || data.disabled == "true") { |
212 if (menuItem.disabled == "true" || data.disabled == "true") { |
200 // Disabled item. |
213 // Disabled item. |
201 itemLi.className += " ViewContext_DisabledMenuItem"; |
214 if (noTab == "true") |
|
215 itemLi.setAttribute("color", "#888"); |
|
216 else |
|
217 itemLi.className += " ViewContext_DisabledMenuItem"; |
202 } |
218 } |
203 else { |
219 else { |
204 // Enabled item. Set up the onmouseup handler. |
220 // Enabled item. Set up the onmouseup handler. |
205 itemLi.onmouseup = (function(handler) { |
221 itemLi.onmouseup = (function(handler) { |
206 return function() { |
222 return function() { |
354 // Create all the DOM elements of the window. |
370 // Create all the DOM elements of the window. |
355 this.create = function(menuData) { |
371 this.create = function(menuData) { |
356 var snippetEl = document.getElementById(this.snippetId); |
372 var snippetEl = document.getElementById(this.snippetId); |
357 var el = this.createTabsElement(menuData); |
373 var el = this.createTabsElement(menuData); |
358 snippetEl.appendChild(el); |
374 snippetEl.appendChild(el); |
|
375 snippetEl.insertAdjacentHTML('beforeEnd', '<div class="hiddenLoadImages"></div>'); |
359 } |
376 } |
360 |
377 |
361 // Show the content menu. The menuData must contain an object tree describing the structure of the |
378 // Show the content menu. The menuData must contain an object tree describing the structure of the |
362 // tabs and sub-menus. |
379 // tabs and sub-menus. |
363 // |
380 // |
413 } |
430 } |
414 |
431 |
415 // Hide this window. |
432 // Hide this window. |
416 this.hide = function() { |
433 this.hide = function() { |
417 snippets[cm_TheContextMenu.snippetId].hide(); |
434 snippets[cm_TheContextMenu.snippetId].hide(); |
|
435 if (this.editingSnippet != undefined) |
|
436 this.editingSnippet.setContextMenuStatus(false); |
418 } |
437 } |
419 |
438 |
420 this.onHide = function() { |
439 this.onHide = function() { |
421 this.cleanUp(); |
440 this.cleanUp(); |
422 } |
441 } |
423 |
442 |
424 this.show = function(menuData) { |
443 this.show = function(menuData) { |
|
444 if (this.editingSnippet != undefined) |
|
445 this.editingSnippet.setContextMenuStatus(true); |
|
446 |
|
447 document.getElementById(this.snippetId).style.width = this.snippetWidth; |
425 this.cleanUp(); |
448 this.cleanUp(); |
426 this.create(menuData); |
449 this.create(menuData); |
427 |
450 if (menuData.tabs != undefined) |
428 cm_TheContextMenu.updateTabSizes(); |
451 cm_TheContextMenu.updateTabSizes(); |
429 // Use a timer to actually show the window to allow the page re-layout |
452 // 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 |
453 // 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 |
454 // be enough on the N97. Without this delay the bottom of the window |
432 // often gets clipped. |
455 // often gets clipped. |
433 setTimeout("cm_TheContextMenu.showIt2()", 50); |
456 setTimeout("cm_TheContextMenu.showIt2()", 50); |
450 |
473 |
451 |
474 |
452 this.centerSnippet = function() { |
475 this.centerSnippet = function() { |
453 |
476 |
454 |
477 |
455 var statusBarHeight = snippets.StatusBarChromeId.geometry.height; |
478 var statusBarHeight = snippets.StatusBarChromeId.visible ? snippets.StatusBarChromeId.geometry.height : 0; |
456 |
479 |
457 var snippet = snippets[cm_TheContextMenu.snippetId]; |
480 var snippet = snippets[cm_TheContextMenu.snippetId]; |
458 var x = (chrome.displaySize.width - snippet.geometry.width) / 2; |
481 var x = (chrome.displaySize.width - snippet.geometry.width) / 2; |
459 |
482 |
460 // Center the menu in the space between status bar and tool bar |
483 // Center the menu in the space between status bar and tool bar |
463 |
486 |
464 } |
487 } |
465 chrome.chromeComplete.connect(createDelegate(this, |
488 chrome.chromeComplete.connect(createDelegate(this, |
466 function() { |
489 function() { |
467 var snippet = snippets[cm_TheContextMenu.snippetId]; |
490 var snippet = snippets[cm_TheContextMenu.snippetId]; |
468 |
491 this.snippetWidth = document.getElementById(cm_TheContextMenu.snippetId).style.width; |
469 chrome.aspectChanged.connect(createDelegate(this, |
492 chrome.aspectChanged.connect(createDelegate(this, |
470 function(a) { |
493 function(a) { |
471 this.centerSnippet(); |
494 this.centerSnippet(); |
472 })); |
495 })); |
473 |
496 |