]> git.wh0rd.org Git - tt-rss.git/blob - lib/dijit/_PaletteMixin.js.uncompressed.js
modify dojo rebuild script to remove uncompressed files
[tt-rss.git] / lib / dijit / _PaletteMixin.js.uncompressed.js
1 define("dijit/_PaletteMixin", [
2         "dojo/_base/declare", // declare
3         "dojo/dom-attr", // domAttr.set
4         "dojo/dom-class", // domClass.add domClass.remove
5         "dojo/dom-construct", // domConstruct.create domConstruct.place
6         "dojo/_base/event", // event.stop
7         "dojo/keys", // keys
8         "dojo/_base/lang", // lang.getObject
9         "./_CssStateMixin",
10         "./focus",
11         "./typematic"
12 ], function(declare, domAttr, domClass, domConstruct, event, keys, lang, _CssStateMixin, focus, typematic){
13
14 // module:
15 //              dijit/_PaletteMixin
16
17 return declare("dijit._PaletteMixin", [_CssStateMixin], {
18         // summary:
19         //              A keyboard accessible palette, for picking a color/emoticon/etc.
20         // description:
21         //              A mixin for a grid showing various entities, so the user can pick a certain entity.
22
23         // defaultTimeout: Number
24         //              Number of milliseconds before a held key or button becomes typematic
25         defaultTimeout: 500,
26
27         // timeoutChangeRate: Number
28         //              Fraction of time used to change the typematic timer between events
29         //              1.0 means that each typematic event fires at defaultTimeout intervals
30         //              Less than 1.0 means that each typematic event fires at an increasing faster rate
31         timeoutChangeRate: 0.90,
32
33         // value: String
34         //              Currently selected color/emoticon/etc.
35         value: "",
36
37         // _selectedCell: [private] Integer
38         //              Index of the currently selected cell. Initially, none selected
39         _selectedCell: -1,
40
41 /*=====
42         // _currentFocus: [private] DomNode
43         //              The currently focused cell (if the palette itself has focus), or otherwise
44         //              the cell to be focused when the palette itself gets focus.
45         //              Different from value, which represents the selected (i.e. clicked) cell.
46         _currentFocus: null,
47 =====*/
48
49 /*=====
50         // _xDim: [protected] Integer
51         //              This is the number of cells horizontally across.
52         _xDim: null,
53 =====*/
54
55 /*=====
56         // _yDim: [protected] Integer
57         //              This is the number of cells vertically down.
58         _yDim: null,
59 =====*/
60
61         // tabIndex: String
62         //              Widget tab index.
63         tabIndex: "0",
64
65         // cellClass: [protected] String
66         //              CSS class applied to each cell in the palette
67         cellClass: "dijitPaletteCell",
68
69         // dyeClass: [protected] Constructor
70         //              Constructor for Object created for each cell of the palette.
71         //              dyeClass should implements dijit.Dye interface
72         dyeClass: null,
73         
74         // summary: String
75         //              Localized summary for the palette table
76         summary: '',
77         _setSummaryAttr: "paletteTableNode",
78
79         _dyeFactory: function(value /*===== , row, col, title =====*/){
80                 // summary:
81                 //              Return instance of dijit.Dye for specified cell of palette
82                 // tags:
83                 //              extension
84
85                 // Remove string support for 2.0
86                 var dyeClassObj = typeof this.dyeClass == "string" ? lang.getObject(this.dyeClass) : this.dyeClass;
87                 return new dyeClassObj(value);
88         },
89
90         _preparePalette: function(choices, titles) {
91                 // summary:
92                 //              Subclass must call _preparePalette() from postCreate(), passing in the tooltip
93                 //              for each cell
94                 // choices: String[][]
95                 //              id's for each cell of the palette, used to create Dye JS object for each cell
96                 // titles: String[]
97                 //              Localized tooltip for each cell
98
99                 this._cells = [];
100                 var url = this._blankGif;
101
102                 this.connect(this.gridNode, "ondijitclick", "_onCellClick");
103
104                 for(var row=0; row < choices.length; row++){
105                         var rowNode = domConstruct.create("tr", {tabIndex: "-1"}, this.gridNode);
106                         for(var col=0; col < choices[row].length; col++){
107                                 var value = choices[row][col];
108                                 if(value){
109                                         var cellObject = this._dyeFactory(value, row, col, titles[value]);
110
111                                         var cellNode = domConstruct.create("td", {
112                                                 "class": this.cellClass,
113                                                 tabIndex: "-1",
114                                                 title: titles[value],
115                                                 role: "gridcell"
116                                         }, rowNode);
117
118                                         // prepare cell inner structure
119                                         cellObject.fillCell(cellNode, url);
120
121                                         cellNode.idx = this._cells.length;
122
123                                         // save cell info into _cells
124                                         this._cells.push({node:cellNode, dye:cellObject});
125                                 }
126                         }
127                 }
128                 this._xDim = choices[0].length;
129                 this._yDim = choices.length;
130
131                 // Now set all events
132                 // The palette itself is navigated to with the tab key on the keyboard
133                 // Keyboard navigation within the Palette is with the arrow keys
134                 // Spacebar selects the cell.
135                 // For the up key the index is changed by negative the x dimension.
136
137                 var keyIncrementMap = {
138                         UP_ARROW: -this._xDim,
139                         // The down key the index is increase by the x dimension.
140                         DOWN_ARROW: this._xDim,
141                         // Right and left move the index by 1.
142                         RIGHT_ARROW: this.isLeftToRight() ? 1 : -1,
143                         LEFT_ARROW: this.isLeftToRight() ? -1 : 1
144                 };
145                 for(var key in keyIncrementMap){
146                         this.own(
147                                 typematic.addKeyListener(
148                                         this.domNode,
149                                         {charOrCode:keys[key], ctrlKey:false, altKey:false, shiftKey:false},
150                                         this,
151                                         function(){
152                                                 var increment = keyIncrementMap[key];
153                                                 return function(count){ this._navigateByKey(increment, count); };
154                                         }(),
155                                         this.timeoutChangeRate,
156                                         this.defaultTimeout
157                                 )
158                         );
159                 }
160         },
161
162         postCreate: function(){
163                 this.inherited(arguments);
164
165                 // Set initial navigable node.
166                 this._setCurrent(this._cells[0].node);
167         },
168
169         focus: function(){
170                 // summary:
171                 //              Focus this widget.  Puts focus on the most recently focused cell.
172
173                 // The cell already has tabIndex set, just need to set CSS and focus it
174                 focus.focus(this._currentFocus);
175         },
176
177         _onCellClick: function(/*Event*/ evt){
178                 // summary:
179                 //              Handler for click, enter key & space key. Selects the cell.
180                 // evt:
181                 //              The event.
182                 // tags:
183                 //              private
184
185                 var target = evt.target;
186
187                 // Find TD associated with click event.   For ColorPalette user likely clicked IMG inside of TD
188                 while(target.tagName != "TD"){
189                         if(!target.parentNode || target == this.gridNode){      // probably can never happen, but just in case
190                                 return;
191                         }
192                         target = target.parentNode;
193                 }
194
195                 var value = this._getDye(target).getValue();
196
197                 // First focus the clicked cell, and then send onChange() notification.
198                 // onChange() (via _setValueAttr) must be after the focus call, because
199                 // it may trigger a refocus to somewhere else (like the Editor content area), and that
200                 // second focus should win.
201                 this._setCurrent(target);
202                 focus.focus(target);
203                 this._setValueAttr(value, true);
204
205                 event.stop(evt);
206         },
207
208         _setCurrent: function(/*DomNode*/ node){
209                 // summary:
210                 //              Sets which node is the focused cell.
211                 // description:
212                 //              At any point in time there's exactly one
213                 //              cell with tabIndex != -1.   If focus is inside the palette then
214                 //              focus is on that cell.
215                 //
216                 //              After calling this method, arrow key handlers and mouse click handlers
217                 //              should focus the cell in a setTimeout().
218                 // tags:
219                 //              protected
220                 if("_currentFocus" in this){
221                         // Remove tabIndex on old cell
222                         domAttr.set(this._currentFocus, "tabIndex", "-1");
223                 }
224
225                 // Set tabIndex of new cell
226                 this._currentFocus = node;
227                 if(node){
228                         domAttr.set(node, "tabIndex", this.tabIndex);
229                 }
230         },
231
232         _setValueAttr: function(value, priorityChange){
233                 // summary:
234                 //              This selects a cell. It triggers the onChange event.
235                 // value: String
236                 //              Value of the cell to select
237                 // tags:
238                 //              protected
239                 // priorityChange: Boolean?
240                 //              Optional parameter used to tell the select whether or not to fire
241                 //              onChange event.
242
243                 // clear old selected cell
244                 if(this._selectedCell >= 0){
245                         domClass.remove(this._cells[this._selectedCell].node, this.cellClass + "Selected");
246                 }
247                 this._selectedCell = -1;
248
249                 // search for cell matching specified value
250                 if(value){
251                         for(var i = 0; i < this._cells.length; i++){
252                                 if(value == this._cells[i].dye.getValue()){
253                                         this._selectedCell = i;
254                                         domClass.add(this._cells[i].node, this.cellClass + "Selected");
255                                         break;
256                                 }
257                         }
258                 }
259
260                 // record new value, or null if no matching cell
261                 this._set("value", this._selectedCell >= 0 ? value : null);
262
263                 if(priorityChange || priorityChange === undefined){
264                         this.onChange(value);
265                 }
266         },
267
268         onChange: function(/*===== value =====*/){
269                 // summary:
270                 //              Callback when a cell is selected.
271                 // value: String
272                 //              Value corresponding to cell.
273         },
274
275         _navigateByKey: function(increment, typeCount){
276                 // summary:
277                 //              This is the callback for typematic.
278                 //              It changes the focus and the highlighed cell.
279                 // increment:
280                 //              How much the key is navigated.
281                 // typeCount:
282                 //              How many times typematic has fired.
283                 // tags:
284                 //              private
285
286                 // typecount == -1 means the key is released.
287                 if(typeCount == -1){ return; }
288
289                 var newFocusIndex = this._currentFocus.idx + increment;
290                 if(newFocusIndex < this._cells.length && newFocusIndex > -1){
291                         var focusNode = this._cells[newFocusIndex].node;
292                         this._setCurrent(focusNode);
293
294                         // Actually focus the node, for the benefit of screen readers.
295                         // Use defer because IE doesn't like changing focus inside of an event handler
296                         this.defer(lang.hitch(focus, "focus", focusNode));
297                 }
298         },
299
300         _getDye: function(/*DomNode*/ cell){
301                 // summary:
302                 //              Get JS object for given cell DOMNode
303
304                 return this._cells[cell.idx].dye;
305         }
306 });
307
308 /*=====
309 declare("dijit.Dye",
310         null,
311         {
312                 // summary:
313                 //              Interface for the JS Object associated with a palette cell (i.e. DOMNode)
314
315                 constructor: function(alias, row, col){
316                         // summary:
317                         //              Initialize according to value or alias like "white"
318                         // alias: String
319                 },
320
321                 getValue: function(){
322                         // summary:
323                         //              Return "value" of cell; meaning of "value" varies by subclass.
324                         // description:
325                         //              For example color hex value, emoticon ascii value etc, entity hex value.
326                 },
327
328                 fillCell: function(cell, blankGif){
329                         // summary:
330                         //              Add cell DOMNode inner structure
331                         // cell: DomNode
332                         //              The surrounding cell
333                         // blankGif: String
334                         //              URL for blank cell image
335                 }
336         }
337 );
338 =====*/
339
340 });