diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2017-01-20 00:55:51 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2017-01-20 00:55:51 +0100 |
commit | c63493c899de714b05b0521bb38aab60d19030ef (patch) | |
tree | fcb2b261afa0f3c2bd6b48929b64724c71192bae /sources/plugins/elementspath/plugin.js | |
download | ludivine-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/elementspath/plugin.js')
-rw-r--r-- | sources/plugins/elementspath/plugin.js | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/sources/plugins/elementspath/plugin.js b/sources/plugins/elementspath/plugin.js new file mode 100644 index 0000000..07ba5c2 --- /dev/null +++ b/sources/plugins/elementspath/plugin.js | |||
@@ -0,0 +1,244 @@ | |||
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 | /** | ||
7 | * @fileOverview The "elementspath" plugin. It shows all elements in the DOM | ||
8 | * parent tree relative to the current selection in the editing area. | ||
9 | */ | ||
10 | |||
11 | ( function() { | ||
12 | var commands = { | ||
13 | toolbarFocus: { | ||
14 | editorFocus: false, | ||
15 | readOnly: 1, | ||
16 | exec: function( editor ) { | ||
17 | var idBase = editor._.elementsPath.idBase; | ||
18 | var element = CKEDITOR.document.getById( idBase + '0' ); | ||
19 | |||
20 | // Make the first button focus accessible for IE. (#3417) | ||
21 | // Adobe AIR instead need while of delay. | ||
22 | element && element.focus( CKEDITOR.env.ie || CKEDITOR.env.air ); | ||
23 | } | ||
24 | } | ||
25 | }; | ||
26 | |||
27 | var emptyHtml = '<span class="cke_path_empty"> </span>'; | ||
28 | |||
29 | var extra = ''; | ||
30 | |||
31 | // Some browsers don't cancel key events in the keydown but in the | ||
32 | // keypress. | ||
33 | // TODO: Check if really needed. | ||
34 | if ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) | ||
35 | extra += ' onkeypress="return false;"'; | ||
36 | |||
37 | // With Firefox, we need to force the button to redraw, otherwise it | ||
38 | // will remain in the focus state. | ||
39 | if ( CKEDITOR.env.gecko ) | ||
40 | extra += ' onblur="this.style.cssText = this.style.cssText;"'; | ||
41 | |||
42 | var pathItemTpl = CKEDITOR.addTemplate( 'pathItem', '<a' + | ||
43 | ' id="{id}"' + | ||
44 | ' href="{jsTitle}"' + | ||
45 | ' tabindex="-1"' + | ||
46 | ' class="cke_path_item"' + | ||
47 | ' title="{label}"' + | ||
48 | extra + | ||
49 | ' hidefocus="true" ' + | ||
50 | ' onkeydown="return CKEDITOR.tools.callFunction({keyDownFn},{index}, event );"' + | ||
51 | ' onclick="CKEDITOR.tools.callFunction({clickFn},{index}); return false;"' + | ||
52 | ' role="button" aria-label="{label}">' + | ||
53 | '{text}' + | ||
54 | '</a>' ); | ||
55 | |||
56 | CKEDITOR.plugins.add( 'elementspath', { | ||
57 | // jscs:disable maximumLineLength | ||
58 | lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% | ||
59 | // jscs:enable maximumLineLength | ||
60 | init: function( editor ) { | ||
61 | editor._.elementsPath = { | ||
62 | idBase: 'cke_elementspath_' + CKEDITOR.tools.getNextNumber() + '_', | ||
63 | filters: [] | ||
64 | }; | ||
65 | |||
66 | editor.on( 'uiSpace', function( event ) { | ||
67 | if ( event.data.space == 'bottom' ) | ||
68 | initElementsPath( editor, event.data ); | ||
69 | } ); | ||
70 | } | ||
71 | } ); | ||
72 | |||
73 | function initElementsPath( editor, bottomSpaceData ) { | ||
74 | var spaceId = editor.ui.spaceId( 'path' ), | ||
75 | spaceElement, | ||
76 | getSpaceElement = function() { | ||
77 | if ( !spaceElement ) | ||
78 | spaceElement = CKEDITOR.document.getById( spaceId ); | ||
79 | return spaceElement; | ||
80 | }, | ||
81 | elementsPath = editor._.elementsPath, | ||
82 | idBase = elementsPath.idBase; | ||
83 | |||
84 | bottomSpaceData.html += '<span id="' + spaceId + '_label" class="cke_voice_label">' + editor.lang.elementspath.eleLabel + '</span>' + | ||
85 | '<span id="' + spaceId + '" class="cke_path" role="group" aria-labelledby="' + spaceId + '_label">' + emptyHtml + '</span>'; | ||
86 | |||
87 | // Register the ui element to the focus manager. | ||
88 | editor.on( 'uiReady', function() { | ||
89 | var element = editor.ui.space( 'path' ); | ||
90 | element && editor.focusManager.add( element, 1 ); | ||
91 | } ); | ||
92 | |||
93 | function onClick( elementIndex ) { | ||
94 | var element = elementsPath.list[ elementIndex ], | ||
95 | selection; | ||
96 | |||
97 | if ( element.equals( editor.editable() ) || element.getAttribute( 'contenteditable' ) == 'true' ) { | ||
98 | var range = editor.createRange(); | ||
99 | range.selectNodeContents( element ); | ||
100 | |||
101 | selection = range.select(); | ||
102 | } else { | ||
103 | selection = editor.getSelection(); | ||
104 | selection.selectElement( element ); | ||
105 | } | ||
106 | |||
107 | // Explicitly fire selectionChange when clicking on an element path button. (#13548) | ||
108 | if ( CKEDITOR.env.ie ) { | ||
109 | editor.fire( 'selectionChange', { selection: selection, path: new CKEDITOR.dom.elementPath( element ) } ); | ||
110 | } | ||
111 | |||
112 | // It is important to focus() *after* the above selection | ||
113 | // manipulation, otherwise Firefox will have troubles. #10119 | ||
114 | editor.focus(); | ||
115 | } | ||
116 | |||
117 | elementsPath.onClick = onClick; | ||
118 | |||
119 | var onClickHanlder = CKEDITOR.tools.addFunction( onClick ), | ||
120 | onKeyDownHandler = CKEDITOR.tools.addFunction( function( elementIndex, ev ) { | ||
121 | var idBase = elementsPath.idBase, | ||
122 | element; | ||
123 | |||
124 | ev = new CKEDITOR.dom.event( ev ); | ||
125 | |||
126 | var rtl = editor.lang.dir == 'rtl'; | ||
127 | switch ( ev.getKeystroke() ) { | ||
128 | case rtl ? 39 : 37: // LEFT-ARROW | ||
129 | case 9: // TAB | ||
130 | element = CKEDITOR.document.getById( idBase + ( elementIndex + 1 ) ); | ||
131 | if ( !element ) | ||
132 | element = CKEDITOR.document.getById( idBase + '0' ); | ||
133 | element.focus(); | ||
134 | return false; | ||
135 | |||
136 | case rtl ? 37 : 39: // RIGHT-ARROW | ||
137 | case CKEDITOR.SHIFT + 9: // SHIFT + TAB | ||
138 | element = CKEDITOR.document.getById( idBase + ( elementIndex - 1 ) ); | ||
139 | if ( !element ) | ||
140 | element = CKEDITOR.document.getById( idBase + ( elementsPath.list.length - 1 ) ); | ||
141 | element.focus(); | ||
142 | return false; | ||
143 | |||
144 | case 27: // ESC | ||
145 | editor.focus(); | ||
146 | return false; | ||
147 | |||
148 | case 13: // ENTER // Opera | ||
149 | case 32: // SPACE | ||
150 | onClick( elementIndex ); | ||
151 | return false; | ||
152 | } | ||
153 | return true; | ||
154 | } ); | ||
155 | |||
156 | editor.on( 'selectionChange', function() { | ||
157 | var html = [], | ||
158 | elementsList = elementsPath.list = [], | ||
159 | namesList = [], | ||
160 | filters = elementsPath.filters, | ||
161 | isContentEditable = true, | ||
162 | |||
163 | // Use elementPath to consider children of editable only (#11124). | ||
164 | elementsChain = editor.elementPath().elements, | ||
165 | name; | ||
166 | |||
167 | // Starts iteration from body element, skipping html. | ||
168 | for ( var j = elementsChain.length; j--; ) { | ||
169 | var element = elementsChain[ j ], | ||
170 | ignore = 0; | ||
171 | |||
172 | if ( element.data( 'cke-display-name' ) ) | ||
173 | name = element.data( 'cke-display-name' ); | ||
174 | else if ( element.data( 'cke-real-element-type' ) ) | ||
175 | name = element.data( 'cke-real-element-type' ); | ||
176 | else | ||
177 | name = element.getName(); | ||
178 | |||
179 | isContentEditable = element.hasAttribute( 'contenteditable' ) ? | ||
180 | element.getAttribute( 'contenteditable' ) == 'true' : isContentEditable; | ||
181 | |||
182 | // If elem is non-contenteditable, and it's not specifying contenteditable | ||
183 | // attribute - then elem should be ignored. | ||
184 | if ( !isContentEditable && !element.hasAttribute( 'contenteditable' ) ) | ||
185 | ignore = 1; | ||
186 | |||
187 | for ( var i = 0; i < filters.length; i++ ) { | ||
188 | var ret = filters[ i ]( element, name ); | ||
189 | if ( ret === false ) { | ||
190 | ignore = 1; | ||
191 | break; | ||
192 | } | ||
193 | name = ret || name; | ||
194 | } | ||
195 | |||
196 | if ( !ignore ) { | ||
197 | elementsList.unshift( element ); | ||
198 | namesList.unshift( name ); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | for ( var iterationLimit = elementsList.length, index = 0; index < iterationLimit; index++ ) { | ||
203 | name = namesList[ index ]; | ||
204 | var label = editor.lang.elementspath.eleTitle.replace( /%1/, name ), | ||
205 | item = pathItemTpl.output( { | ||
206 | id: idBase + index, | ||
207 | label: label, | ||
208 | text: name, | ||
209 | jsTitle: 'javascript:void(\'' + name + '\')', // jshint ignore:line | ||
210 | index: index, | ||
211 | keyDownFn: onKeyDownHandler, | ||
212 | clickFn: onClickHanlder | ||
213 | } ); | ||
214 | |||
215 | html.unshift( item ); | ||
216 | } | ||
217 | |||
218 | var space = getSpaceElement(); | ||
219 | space.setHtml( html.join( '' ) + emptyHtml ); | ||
220 | editor.fire( 'elementsPathUpdate', { space: space } ); | ||
221 | } ); | ||
222 | |||
223 | function empty() { | ||
224 | spaceElement && spaceElement.setHtml( emptyHtml ); | ||
225 | delete elementsPath.list; | ||
226 | } | ||
227 | |||
228 | editor.on( 'readOnly', empty ); | ||
229 | editor.on( 'contentDomUnload', empty ); | ||
230 | |||
231 | editor.addCommand( 'elementsPathFocus', commands.toolbarFocus ); | ||
232 | editor.setKeystroke( CKEDITOR.ALT + 122 /*F11*/, 'elementsPathFocus' ); | ||
233 | } | ||
234 | } )(); | ||
235 | |||
236 | /** | ||
237 | * Fired when the contents of the elementsPath are changed. | ||
238 | * | ||
239 | * @event elementsPathUpdate | ||
240 | * @member CKEDITOR.editor | ||
241 | * @param {CKEDITOR.editor} editor This editor instance. | ||
242 | * @param data | ||
243 | * @param {CKEDITOR.dom.element} data.space The elementsPath container. | ||
244 | */ | ||