aboutsummaryrefslogtreecommitdiff
path: root/sources/plugins/tab
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2017-01-20 00:55:51 +0100
committerIsmaël Bouya <ismael.bouya@normalesup.org>2017-01-20 00:55:51 +0100
commitc63493c899de714b05b0521bb38aab60d19030ef (patch)
treefcb2b261afa0f3c2bd6b48929b64724c71192bae /sources/plugins/tab
downloadludivine-ckeditor-component-c63493c899de714b05b0521bb38aab60d19030ef.tar.gz
ludivine-ckeditor-component-c63493c899de714b05b0521bb38aab60d19030ef.tar.zst
ludivine-ckeditor-component-c63493c899de714b05b0521bb38aab60d19030ef.zip
Validation initiale4.6.2.1
Diffstat (limited to 'sources/plugins/tab')
-rw-r--r--sources/plugins/tab/plugin.js302
1 files changed, 302 insertions, 0 deletions
diff --git a/sources/plugins/tab/plugin.js b/sources/plugins/tab/plugin.js
new file mode 100644
index 0000000..98acb2e
--- /dev/null
+++ b/sources/plugins/tab/plugin.js
@@ -0,0 +1,302 @@
1/**
2 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.md or http://ckeditor.com/license
4 */
5
6( function() {
7 var meta = {
8 editorFocus: false,
9 modes: { wysiwyg: 1, source: 1 }
10 };
11
12 var blurCommand = {
13 exec: function( editor ) {
14 editor.container.focusNext( true, editor.tabIndex );
15 }
16 };
17
18 var blurBackCommand = {
19 exec: function( editor ) {
20 editor.container.focusPrevious( true, editor.tabIndex );
21 }
22 };
23
24 function selectNextCellCommand( backward ) {
25 return {
26 editorFocus: false,
27 canUndo: false,
28 modes: { wysiwyg: 1 },
29 exec: function( editor ) {
30 if ( editor.editable().hasFocus ) {
31 var sel = editor.getSelection(),
32 path = new CKEDITOR.dom.elementPath( sel.getCommonAncestor(), sel.root ),
33 cell;
34
35 if ( ( cell = path.contains( { td: 1, th: 1 }, 1 ) ) ) {
36 var resultRange = editor.createRange(),
37 next = CKEDITOR.tools.tryThese( function() {
38 var row = cell.getParent(),
39 next = row.$.cells[ cell.$.cellIndex + ( backward ? -1 : 1 ) ];
40
41 // Invalid any empty value.
42 next.parentNode.parentNode;
43 return next;
44 }, function() {
45 var row = cell.getParent(),
46 table = row.getAscendant( 'table' ),
47 nextRow = table.$.rows[ row.$.rowIndex + ( backward ? -1 : 1 ) ];
48
49 return nextRow.cells[ backward ? nextRow.cells.length - 1 : 0 ];
50 } );
51
52 // Clone one more row at the end of table and select the first newly established cell.
53 if ( !( next || backward ) ) {
54 var table = cell.getAscendant( 'table' ).$,
55 cells = cell.getParent().$.cells;
56
57 var newRow = new CKEDITOR.dom.element( table.insertRow( -1 ), editor.document );
58
59 for ( var i = 0, count = cells.length; i < count; i++ ) {
60 var newCell = newRow.append( new CKEDITOR.dom.element( cells[ i ], editor.document ).clone( false, false ) );
61 newCell.appendBogus();
62 }
63
64 resultRange.moveToElementEditStart( newRow );
65 } else if ( next ) {
66 next = new CKEDITOR.dom.element( next );
67 resultRange.moveToElementEditStart( next );
68 // Avoid selecting empty block makes the cursor blind.
69 if ( !( resultRange.checkStartOfBlock() && resultRange.checkEndOfBlock() ) )
70 resultRange.selectNodeContents( next );
71 } else {
72 return true;
73 }
74
75 resultRange.select( true );
76 return true;
77 }
78 }
79
80 return false;
81 }
82 };
83 }
84
85 CKEDITOR.plugins.add( 'tab', {
86 init: function( editor ) {
87 var tabTools = editor.config.enableTabKeyTools !== false,
88 tabSpaces = editor.config.tabSpaces || 0,
89 tabText = '';
90
91 while ( tabSpaces-- )
92 tabText += '\xa0';
93
94 if ( tabText ) {
95 editor.on( 'key', function( ev ) {
96 // TAB.
97 if ( ev.data.keyCode == 9 ) {
98 editor.insertText( tabText );
99 ev.cancel();
100 }
101 } );
102 }
103
104 if ( tabTools ) {
105 editor.on( 'key', function( ev ) {
106 if ( ev.data.keyCode == 9 && editor.execCommand( 'selectNextCell' ) || // TAB
107 ev.data.keyCode == ( CKEDITOR.SHIFT + 9 ) && editor.execCommand( 'selectPreviousCell' ) ) // SHIFT+TAB
108 ev.cancel();
109 } );
110 }
111
112 editor.addCommand( 'blur', CKEDITOR.tools.extend( blurCommand, meta ) );
113 editor.addCommand( 'blurBack', CKEDITOR.tools.extend( blurBackCommand, meta ) );
114 editor.addCommand( 'selectNextCell', selectNextCellCommand() );
115 editor.addCommand( 'selectPreviousCell', selectNextCellCommand( true ) );
116 }
117 } );
118} )();
119
120/**
121 * Moves the UI focus to the element following this element in the tabindex order.
122 *
123 * var element = CKEDITOR.document.getById( 'example' );
124 * element.focusNext();
125 *
126 * @param {Boolean} [ignoreChildren=false]
127 * @param {Number} [indexToUse]
128 * @member CKEDITOR.dom.element
129 */
130CKEDITOR.dom.element.prototype.focusNext = function( ignoreChildren, indexToUse ) {
131 var curTabIndex = ( indexToUse === undefined ? this.getTabIndex() : indexToUse ),
132 passedCurrent, enteredCurrent, elected, electedTabIndex, element, elementTabIndex;
133
134 if ( curTabIndex <= 0 ) {
135 // If this element has tabindex <= 0 then we must simply look for any
136 // element following it containing tabindex=0.
137
138 element = this.getNextSourceNode( ignoreChildren, CKEDITOR.NODE_ELEMENT );
139
140 while ( element ) {
141 if ( element.isVisible() && element.getTabIndex() === 0 ) {
142 elected = element;
143 break;
144 }
145
146 element = element.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT );
147 }
148 } else {
149 // If this element has tabindex > 0 then we must look for:
150 // 1. An element following this element with the same tabindex.
151 // 2. The first element in source other with the lowest tabindex
152 // that is higher than this element tabindex.
153 // 3. The first element with tabindex=0.
154
155 element = this.getDocument().getBody().getFirst();
156
157 while ( ( element = element.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) ) {
158 if ( !passedCurrent ) {
159 if ( !enteredCurrent && element.equals( this ) ) {
160 enteredCurrent = true;
161
162 // Ignore this element, if required.
163 if ( ignoreChildren ) {
164 if ( !( element = element.getNextSourceNode( true, CKEDITOR.NODE_ELEMENT ) ) )
165 break;
166 passedCurrent = 1;
167 }
168 } else if ( enteredCurrent && !this.contains( element ) ) {
169 passedCurrent = 1;
170 }
171 }
172
173 if ( !element.isVisible() || ( elementTabIndex = element.getTabIndex() ) < 0 )
174 continue;
175
176 if ( passedCurrent && elementTabIndex == curTabIndex ) {
177 elected = element;
178 break;
179 }
180
181 if ( elementTabIndex > curTabIndex && ( !elected || !electedTabIndex || elementTabIndex < electedTabIndex ) ) {
182 elected = element;
183 electedTabIndex = elementTabIndex;
184 } else if ( !elected && elementTabIndex === 0 ) {
185 elected = element;
186 electedTabIndex = elementTabIndex;
187 }
188 }
189 }
190
191 if ( elected )
192 elected.focus();
193};
194
195/**
196 * Moves the UI focus to the element before this element in the tabindex order.
197 *
198 * var element = CKEDITOR.document.getById( 'example' );
199 * element.focusPrevious();
200 *
201 * @param {Boolean} [ignoreChildren=false]
202 * @param {Number} [indexToUse]
203 * @member CKEDITOR.dom.element
204 */
205CKEDITOR.dom.element.prototype.focusPrevious = function( ignoreChildren, indexToUse ) {
206 var curTabIndex = ( indexToUse === undefined ? this.getTabIndex() : indexToUse ),
207 passedCurrent, enteredCurrent, elected,
208 electedTabIndex = 0,
209 elementTabIndex;
210
211 var element = this.getDocument().getBody().getLast();
212
213 while ( ( element = element.getPreviousSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) ) {
214 if ( !passedCurrent ) {
215 if ( !enteredCurrent && element.equals( this ) ) {
216 enteredCurrent = true;
217
218 // Ignore this element, if required.
219 if ( ignoreChildren ) {
220 if ( !( element = element.getPreviousSourceNode( true, CKEDITOR.NODE_ELEMENT ) ) )
221 break;
222 passedCurrent = 1;
223 }
224 } else if ( enteredCurrent && !this.contains( element ) ) {
225 passedCurrent = 1;
226 }
227 }
228
229 if ( !element.isVisible() || ( elementTabIndex = element.getTabIndex() ) < 0 )
230 continue;
231
232 if ( curTabIndex <= 0 ) {
233 // If this element has tabindex <= 0 then we must look for:
234 // 1. An element before this one containing tabindex=0.
235 // 2. The last element with the highest tabindex.
236
237 if ( passedCurrent && elementTabIndex === 0 ) {
238 elected = element;
239 break;
240 }
241
242 if ( elementTabIndex > electedTabIndex ) {
243 elected = element;
244 electedTabIndex = elementTabIndex;
245 }
246 } else {
247 // If this element has tabindex > 0 we must look for:
248 // 1. An element preceeding this one, with the same tabindex.
249 // 2. The last element in source other with the highest tabindex
250 // that is lower than this element tabindex.
251
252 if ( passedCurrent && elementTabIndex == curTabIndex ) {
253 elected = element;
254 break;
255 }
256
257 if ( elementTabIndex < curTabIndex && ( !elected || elementTabIndex > electedTabIndex ) ) {
258 elected = element;
259 electedTabIndex = elementTabIndex;
260 }
261 }
262 }
263
264 if ( elected )
265 elected.focus();
266};
267
268/**
269 * Intructs the editor to add a number of spaces (`&nbsp;`) to the text when
270 * hitting the <kbd>Tab</kbd> key. If set to zero, the <kbd>Tab</kbd> key will be used to move the
271 * cursor focus to the next element in the page, out of the editor focus.
272 *
273 * config.tabSpaces = 4;
274 *
275 * @cfg {Number} [tabSpaces=0]
276 * @member CKEDITOR.config
277 */
278
279/**
280 * Allow context-sensitive <kbd>Tab</kbd> key behaviors, including the following scenarios:
281 *
282 * When selection is anchored inside **table cells**:
283 *
284 * * If <kbd>Tab</kbd> is pressed, select the content of the "next" cell. If in the last
285 * cell in the table, add a new row to it and focus its first cell.
286 * * If <kbd>Shift+Tab</kbd> is pressed, select the content of the "previous" cell.
287 * Do nothing when it is in the first cell.
288 *
289 * Example:
290 *
291 * config.enableTabKeyTools = false;
292 *
293 * @cfg {Boolean} [enableTabKeyTools=true]
294 * @member CKEDITOR.config
295 */
296
297// If the <kbd>Tab</kbd> key is not supposed to be enabled for navigation, the following
298// settings could be used alternatively:
299// config.keystrokes.push(
300// [ CKEDITOR.ALT + 38 /*Arrow Up*/, 'selectPreviousCell' ],
301// [ CKEDITOR.ALT + 40 /*Arrow Down*/, 'selectNextCell' ]
302// );