|
35 | 35 | open: $.noop, // menu was opened
|
36 | 36 | select: $.noop // menu option was selected; return `false` to prevent closing
|
37 | 37 | },
|
| 38 | + /** |
| 39 | + * |
| 40 | + */ |
38 | 41 | _create: function () {
|
39 | 42 | var opts = this.options,
|
40 | 43 | eventNames = "contextmenu" + NS,
|
41 | 44 | targetId = this.element.uniqueId().attr("id");
|
42 | 45 |
|
| 46 | + this.$headStyle = null; |
| 47 | + this.orgMenu = null; |
| 48 | + this.currentTarget = null; |
| 49 | + |
43 | 50 | if(opts.taphold){
|
44 | 51 | eventNames += " taphold" + NS;
|
45 | 52 | }
|
46 | 53 | if(opts.preventSelect){
|
47 | 54 | // Create a global style for all potential menu targets
|
48 | 55 | this.$headStyle = $("<style>")
|
49 | 56 | .prop("type", "text/css")
|
50 |
| - .html("#" + targetId + " " + opts.delegate + " {" + |
51 |
| - "-webkit-user-select: none;" + |
52 |
| - "-khtml-user-select: none;" + |
53 |
| - "-moz-user-select: none;" + |
54 |
| - "-ms-user-select: none;" + |
55 |
| - "user-select: none;" + |
| 57 | + .html("#" + targetId + " " + opts.delegate + " { " + |
| 58 | + "-webkit-user-select: none; " + |
| 59 | + "-khtml-user-select: none; " + |
| 60 | + "-moz-user-select: none; " + |
| 61 | + "-ms-user-select: none; " + |
| 62 | + "user-select: none; " + |
56 | 63 | "}")
|
57 | 64 | .appendTo("head");
|
58 | 65 | // TODO: the selectstart is not supported by FF?
|
|
66 | 73 | this.orgMenu = opts.menu;
|
67 | 74 | opts.menu = $.ui.contextmenu.createMenuMarkup(opts.menu);
|
68 | 75 | }
|
| 76 | + // Create - but hide - context-menu |
| 77 | + this._getMenu() |
| 78 | + .hide() |
| 79 | + .addClass("ui-contextmenu") |
| 80 | + // Create a menu instance that delegates events to our widget |
| 81 | + .menu({ |
| 82 | + blur: $.proxy(this.options.blur, this), |
| 83 | + create: $.proxy(this.options.create, this), |
| 84 | + focus: $.proxy(this.options.focus, this), |
| 85 | + select: $.proxy(function(event, ui){ |
| 86 | + // Also pass the target that the menu was triggered on: |
| 87 | + event.relatedTarget = this.currentTarget; |
| 88 | + // ignore clicks, if they only open a sub-menu |
| 89 | + var isParent = (ui.item.has(">a[aria-haspopup='true']").length > 0); |
| 90 | + if( !isParent || !this.options.ignoreParentSelect){ |
| 91 | + if( this._trigger.call(this, "select", event, ui) !== false ){ |
| 92 | + this._closeMenu.call(this); |
| 93 | + } |
| 94 | + event.preventDefault(); |
| 95 | + } |
| 96 | + }, this) |
| 97 | + }); |
69 | 98 | this.element.delegate(opts.delegate, eventNames, $.proxy(this._openMenu, this));
|
70 | 99 | // emulate a 'taphold' event
|
71 | 100 | this._trigger("init");
|
|
110 | 139 | $menu = this._getMenu(),
|
111 | 140 | openEvent = event,
|
112 | 141 | // if called by 'open' method, 'relatedTarget' is the requested target object
|
113 |
| - parentTarget = openEvent.target ? openEvent.target : openEvent; |
| 142 | + parentTarget = openEvent.target ? openEvent.target : openEvent, |
| 143 | + ui = {menu: $menu}; |
| 144 | + this.currentTarget = openEvent.target; |
114 | 145 | // Prevent browser from opening the system context menu
|
115 | 146 | event.preventDefault();
|
116 | 147 | // Also pass the target that the menu was triggered on as 'relatedTarget'.
|
117 | 148 | // This is required because our _trigger() calls will create events
|
118 | 149 | // that refer to the contextmenu's context (which is the target *container*)
|
119 |
| - event.relatedTarget = openEvent.target; |
| 150 | + event.relatedTarget = this.currentTarget; |
120 | 151 |
|
121 |
| - if( this._trigger("beforeOpen", event) === false ){ |
| 152 | + if( this._trigger("beforeOpen", event, ui) === false ){ |
122 | 153 | return false;
|
123 | 154 | }
|
| 155 | + |
| 156 | + // TODO: $menu.refresh() if menu was modified |
| 157 | + |
124 | 158 | // Create - but hide - context-menu
|
125 |
| - $menu |
126 |
| - .hide() |
127 |
| - .addClass("ui-contextmenu") |
128 |
| - // Create a menu instance that delegates events to our widget |
129 |
| - .menu({ |
130 |
| - blur: $.proxy(this.options.blur, this), |
131 |
| - create: $.proxy(this.options.create, this), |
132 |
| - focus: $.proxy(this.options.focus, this), |
133 |
| - select: function(event, ui){ |
134 |
| - // Also pass the target that the menu was triggered on: |
135 |
| - event.relatedTarget = openEvent.target; |
136 |
| - // ignore clicks, if they only open a sub-menu |
137 |
| - var isParent = (ui.item.has(">a[aria-haspopup='true']").length > 0); |
138 |
| - if( !isParent || !self.options.ignoreParentSelect){ |
139 |
| - if( self._trigger.call(self, "select", event, ui) !== false ){ |
140 |
| - self._closeMenu.call(self); |
141 |
| - } |
142 |
| - event.preventDefault(); |
143 |
| - } |
144 |
| - } |
145 |
| - }); |
| 159 | +// $menu |
| 160 | +// .hide() |
| 161 | +// .addClass("ui-contextmenu") |
| 162 | +// // Create a menu instance that delegates events to our widget |
| 163 | +// .menu({ |
| 164 | +// blur: $.proxy(this.options.blur, this), |
| 165 | +// create: $.proxy(this.options.create, this), |
| 166 | +// focus: $.proxy(this.options.focus, this), |
| 167 | +// select: function(event, ui){ |
| 168 | +// // Also pass the target that the menu was triggered on: |
| 169 | +// event.relatedTarget = openEvent.target; |
| 170 | +// // ignore clicks, if they only open a sub-menu |
| 171 | +// var isParent = (ui.item.has(">a[aria-haspopup='true']").length > 0); |
| 172 | +// if( !isParent || !self.options.ignoreParentSelect){ |
| 173 | +// if( self._trigger.call(self, "select", event, ui) !== false ){ |
| 174 | +// self._closeMenu.call(self); |
| 175 | +// } |
| 176 | +// event.preventDefault(); |
| 177 | +// } |
| 178 | +// } |
| 179 | +// }); |
146 | 180 | // Register global event handlers that close the dropdown-menu
|
147 | 181 | $(document).bind("keydown" + NS, function(event){
|
148 | 182 | if( event.which === $.ui.keyCode.ESCAPE ){
|
|
174 | 208 | _closeMenu: function(){
|
175 | 209 | var self = this,
|
176 | 210 | $menu = this._getMenu();
|
177 |
| - if(this.tapTimer){ |
178 |
| - clearTimeout(this.tapTimer); |
179 |
| - this.tapTimer = null; |
180 |
| - } |
181 | 211 | $menu.fadeOut(function() {
|
182 | 212 | self._trigger("close");
|
| 213 | + this.currentTarget = null; |
183 | 214 | });
|
| 215 | + $(document) |
| 216 | + .unbind("mousedown" + NS) |
| 217 | + .unbind("touchstart" + NS) |
| 218 | + .unbind("keydown" + NS); |
184 | 219 | },
|
185 | 220 | /**
|
186 | 221 | * Open context menu on a specific target (must match options.delegate)
|
187 | 222 | */
|
188 | 223 | open: function(target){
|
189 |
| - // Fake a contextmenu event |
| 224 | + // Fake a 'contextmenu' event |
190 | 225 | var e = jQuery.Event("contextmenu", {target: target.get(0)});
|
191 | 226 | return this.element.trigger(e);
|
192 | 227 | },
|
193 |
| - /** |
194 |
| - * Close context menu. |
195 |
| - */ |
| 228 | + /** Close context menu. */ |
196 | 229 | close: function(){
|
197 | 230 | return this._closeMenu.call(this);
|
| 231 | + }, |
| 232 | + /** Enable or disable the menu command. */ |
| 233 | + enableEntry: function(cmd, flag){ |
| 234 | + var $entry = this.element.find("a[href=#" + cmd + "]"); |
| 235 | + $entry.toggleClass("ui-status-disabled", (flag === false)); |
198 | 236 | }
|
199 | 237 | });
|
200 | 238 |
|
|
0 commit comments