|
48 | 48 | this.$menu = null;
|
49 | 49 | this.menuIsTemp = false;
|
50 | 50 | this.currentTarget = null;
|
51 |
| - this.ns = "." + this.widgetName; |
52 | 51 |
|
53 | 52 | if(opts.preventSelect){
|
54 | 53 | // Create a global style for all potential menu targets
|
|
67 | 66 | .appendTo("head");
|
68 | 67 | // TODO: the selectstart is not supported by FF?
|
69 | 68 | if(supportSelectstart){
|
70 |
| - this.element.delegate(opts.delegate, "selectstart" + this.ns, function(event){ |
| 69 | + this.element.delegate(opts.delegate, "selectstart" + this.eventNamespace, function(event){ |
71 | 70 | event.preventDefault();
|
72 | 71 | });
|
73 | 72 | }
|
74 | 73 | }
|
75 | 74 | this._createUiMenu(opts.menu);
|
76 | 75 |
|
77 |
| - eventNames = "contextmenu" + this.ns; |
| 76 | + eventNames = "contextmenu" + this.eventNamespace; |
78 | 77 | if(opts.taphold){
|
79 |
| - eventNames += " taphold" + this.ns; |
| 78 | + eventNames += " taphold" + this.eventNamespace; |
80 | 79 | }
|
| 80 | + console.log("_create() - element.delegate('" + this.eventNamespace + "')"); |
81 | 81 | this.element.delegate(opts.delegate, eventNames, $.proxy(this._openMenu, this));
|
82 |
| - |
83 |
| - console.log("_create() - delegate"); |
84 |
| - |
85 |
| -// this._trigger("init"); |
86 | 82 | },
|
87 | 83 | /** Destructor, called on $().contextmenu("destroy"). */
|
88 | 84 | _destroy: function(){
|
89 |
| - console.log("_destroy() undelegate NS menu=", this.$menu); |
90 |
| - this.element.undelegate(this.ns); |
91 |
| - if(this.isOpen()){ |
92 |
| - this._closeMenu(); |
93 |
| - } |
| 85 | + console.log("_destroy() element.undelegate('" + this.eventNamespace + "'), menu=", this.$menu); |
| 86 | + this.element.undelegate(this.eventNamespace); |
| 87 | + |
94 | 88 | this._createUiMenu(null);
|
| 89 | + |
95 | 90 | if(this.$headStyle){
|
96 | 91 | this.$headStyle.remove();
|
97 | 92 | this.$headStyle = null;
|
|
100 | 95 | /** (Re)Create jQuery UI Menu. */
|
101 | 96 | _createUiMenu: function(menuDef){
|
102 | 97 | // Remove temporary <ul> if any
|
103 |
| - console.log("_createUiMenu()", menuDef); |
| 98 | + console.log("_createUiMenu("+ menuDef + ")"); |
| 99 | + |
| 100 | + if(this.isOpen()){ |
| 101 | + // close without animation, to force async mode |
| 102 | + this._closeMenu(true); |
| 103 | + } |
| 104 | + |
104 | 105 | if(this.menuIsTemp){
|
105 |
| - console.log("_createUiMenu - remove ", this.$menu); |
| 106 | + console.log("_createUiMenu - remove $menu", this.$menu); |
106 | 107 | this.$menu.remove(); // this will also destroy ui.menu
|
107 |
| - this.menuIsTemp = false; |
108 | 108 | } else if(this.$menu){
|
109 |
| - console.log("_createUiMenu - destroy ", this.$menu); |
| 109 | + console.log("_createUiMenu - destroy $menu", this.$menu); |
110 | 110 | this.$menu.menu("destroy").hide();
|
111 | 111 | }
|
| 112 | + this.$menu = null; |
| 113 | + this.menuIsTemp = false; |
112 | 114 | // If a menu definition array was passed, create a hidden <ul>
|
113 | 115 | // and generate the structure now
|
114 | 116 | if( ! menuDef ){
|
115 |
| - this.$menu = null; |
116 | 117 | return;
|
117 | 118 | } else if($.isArray(menuDef)){
|
118 | 119 | this.$menu = $.moogle.contextmenu.createMenuMarkup(menuDef);
|
|
123 | 124 | this.$menu = menuDef;
|
124 | 125 | }
|
125 | 126 | // Create - but hide - the jQuery UI Menu widget
|
| 127 | + console.log("_createUiMenu - create $menu", this.$menu); |
126 | 128 | this.$menu
|
127 | 129 | .hide()
|
128 | 130 | // .addClass("moogle-contextmenu")
|
|
132 | 134 | create: $.proxy(this.options.createMenu, this),
|
133 | 135 | focus: $.proxy(this.options.focus, this),
|
134 | 136 | select: $.proxy(function(event, ui){
|
135 |
| -// window.console.log("select proxy"); |
136 | 137 | var isParent = (ui.item.has(">a[aria-haspopup='true']").length > 0);
|
137 | 138 | ui.cmd = normCommand(ui.item.find(">a").attr("href"));
|
138 | 139 | ui.target = $(this.currentTarget);
|
|
158 | 159 | event.preventDefault();
|
159 | 160 |
|
160 | 161 | if( this._trigger("beforeOpen", event, ui) === false ){
|
| 162 | + this.currentTarget = null; |
161 | 163 | return false;
|
162 | 164 | }
|
163 | 165 | ui.menu = this.$menu; // Might have changed in beforeOpen
|
164 | 166 | // Register global event handlers that close the dropdown-menu
|
165 |
| - console.log("_openMenu() - document.bind: " + this.ns, this.menuIsTemp, this.$menu); |
166 |
| - $(document).bind("keydown" + this.ns, function(event){ |
| 167 | + console.log("_openMenu() - document.bind('" + this.eventNamespace + "')", this.menuIsTemp, this.$menu); |
| 168 | + $(document).bind("keydown" + this.eventNamespace, function(event){ |
167 | 169 | if( event.which === $.ui.keyCode.ESCAPE ){
|
168 | 170 | self._closeMenu();
|
169 | 171 | }
|
170 |
| - }).bind("mousedown" + this.ns + " touchstart" + this.ns, function(event){ |
| 172 | + }).bind("mousedown" + this.eventNamespace + " touchstart" + this.eventNamespace, function(event){ |
171 | 173 | // Close menu when clicked outside menu
|
172 | 174 | if( !$(event.target).closest(".ui-menu-item").length ){
|
173 | 175 | self._closeMenu();
|
|
198 | 200 |
|
199 | 201 | this._show(this.$menu, this.options.show, function(){
|
200 | 202 | self._trigger.call(self, "open", event, ui);
|
| 203 | + console.log("_openMenu() - done"); |
201 | 204 | });
|
202 | 205 | },
|
203 | 206 | /** Close popup. */
|
204 |
| - _closeMenu: function(){ |
205 |
| - var self = this; |
| 207 | + _closeMenu: function(immediately){ |
| 208 | + var self = this, |
| 209 | + hideOpts = immediately ? false : this.options.hide; |
206 | 210 |
|
207 |
| - console.log("_closeMenu() - document.unbind: " + this.ns, this.menuIsTemp, this.$menu); |
| 211 | + console.log("_closeMenu() - document.unbind('" + this.eventNamespace + "')", this.menuIsTemp, this.$menu); |
208 | 212 | $(document)
|
209 |
| - .unbind("mousedown" + this.ns) |
210 |
| - .unbind("touchstart" + this.ns) |
211 |
| - .unbind("keydown" + this.ns); |
212 |
| - |
213 |
| - this._hide(this.$menu, this.options.hide, function() { |
| 213 | + .unbind("mousedown" + this.eventNamespace) |
| 214 | + .unbind("touchstart" + this.eventNamespace) |
| 215 | + .unbind("keydown" + this.eventNamespace); |
| 216 | + |
| 217 | + this._hide(this.$menu, hideOpts, function() { |
214 | 218 | self._trigger("close");
|
215 | 219 | self.currentTarget = null;
|
| 220 | + console.log("_closeMenu() - done"); |
216 | 221 | });
|
217 | 222 | },
|
218 | 223 | /** Handle $().contextmenu("option", key, value) calls. */
|
|
229 | 234 | var $entry = this.$menu.find("li a[href=#" + normCommand(cmd) + "]");
|
230 | 235 | return wantLi ? $entry.closest("li") : $entry;
|
231 | 236 | },
|
| 237 | + /** Close context menu. */ |
| 238 | + close: function(){ |
| 239 | + if(this.isOpen()){ |
| 240 | + this._closeMenu(); |
| 241 | + } |
| 242 | + }, |
| 243 | + /** Enable or disable the menu command. */ |
| 244 | + enableEntry: function(cmd, flag){ |
| 245 | + this._getMenuEntry(cmd, true).toggleClass("ui-state-disabled", (flag === false)); |
| 246 | + }, |
| 247 | + /** Redefine the whole menu. */ |
232 | 248 | /** Return Menu element (UL). */
|
233 | 249 | getMenu: function(){
|
234 | 250 | return this.$menu;
|
|
244 | 260 | var e = jQuery.Event("contextmenu", {target: target.get(0)});
|
245 | 261 | return this.element.trigger(e);
|
246 | 262 | },
|
247 |
| - /** Close context menu. */ |
248 |
| - close: function(){ |
249 |
| - return this._closeMenu.call(this); |
250 |
| - }, |
251 |
| - /** Enable or disable the menu command. */ |
252 |
| - enableEntry: function(cmd, flag){ |
253 |
| - this._getMenuEntry(cmd, true).toggleClass("ui-state-disabled", (flag === false)); |
254 |
| - }, |
255 |
| - /** Redefine the whole menu. */ |
256 | 263 | replaceMenu: function(data){
|
257 | 264 | this._createUiMenu(data);
|
258 | 265 | },
|
|
0 commit comments