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