]> git.immae.eu Git - perso/Immae/Projets/packagist/ludivine-ckeditor-component.git/blame - sources/plugins/elementspath/plugin.js
Update to 4.7.3
[perso/Immae/Projets/packagist/ludivine-ckeditor-component.git] / sources / plugins / elementspath / plugin.js
CommitLineData
c63493c8
IB
1/**\r
2 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
3 * For licensing, see LICENSE.md or http://ckeditor.com/license\r
4 */\r
5\r
6/**\r
7 * @fileOverview The "elementspath" plugin. It shows all elements in the DOM\r
8 * parent tree relative to the current selection in the editing area.\r
9 */\r
10\r
11( function() {\r
12 var commands = {\r
13 toolbarFocus: {\r
14 editorFocus: false,\r
15 readOnly: 1,\r
16 exec: function( editor ) {\r
17 var idBase = editor._.elementsPath.idBase;\r
18 var element = CKEDITOR.document.getById( idBase + '0' );\r
19\r
1794320d 20 // Make the first button focus accessible for IE. (http://dev.ckeditor.com/ticket/3417)\r
c63493c8
IB
21 // Adobe AIR instead need while of delay.\r
22 element && element.focus( CKEDITOR.env.ie || CKEDITOR.env.air );\r
23 }\r
24 }\r
25 };\r
26\r
27 var emptyHtml = '<span class="cke_path_empty">&nbsp;</span>';\r
28\r
29 var extra = '';\r
30\r
31 // Some browsers don't cancel key events in the keydown but in the\r
32 // keypress.\r
33 // TODO: Check if really needed.\r
34 if ( CKEDITOR.env.gecko && CKEDITOR.env.mac )\r
35 extra += ' onkeypress="return false;"';\r
36\r
37 // With Firefox, we need to force the button to redraw, otherwise it\r
38 // will remain in the focus state.\r
39 if ( CKEDITOR.env.gecko )\r
40 extra += ' onblur="this.style.cssText = this.style.cssText;"';\r
41\r
42 var pathItemTpl = CKEDITOR.addTemplate( 'pathItem', '<a' +\r
43 ' id="{id}"' +\r
44 ' href="{jsTitle}"' +\r
45 ' tabindex="-1"' +\r
46 ' class="cke_path_item"' +\r
47 ' title="{label}"' +\r
48 extra +\r
49 ' hidefocus="true" ' +\r
50 ' onkeydown="return CKEDITOR.tools.callFunction({keyDownFn},{index}, event );"' +\r
51 ' onclick="CKEDITOR.tools.callFunction({clickFn},{index}); return false;"' +\r
52 ' role="button" aria-label="{label}">' +\r
53 '{text}' +\r
54 '</a>' );\r
55\r
56 CKEDITOR.plugins.add( 'elementspath', {\r
57 // jscs:disable maximumLineLength\r
1794320d 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,es-mx,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%\r
c63493c8
IB
59 // jscs:enable maximumLineLength\r
60 init: function( editor ) {\r
61 editor._.elementsPath = {\r
62 idBase: 'cke_elementspath_' + CKEDITOR.tools.getNextNumber() + '_',\r
63 filters: []\r
64 };\r
65\r
66 editor.on( 'uiSpace', function( event ) {\r
67 if ( event.data.space == 'bottom' )\r
68 initElementsPath( editor, event.data );\r
69 } );\r
70 }\r
71 } );\r
72\r
73 function initElementsPath( editor, bottomSpaceData ) {\r
74 var spaceId = editor.ui.spaceId( 'path' ),\r
75 spaceElement,\r
76 getSpaceElement = function() {\r
77 if ( !spaceElement )\r
78 spaceElement = CKEDITOR.document.getById( spaceId );\r
79 return spaceElement;\r
80 },\r
81 elementsPath = editor._.elementsPath,\r
82 idBase = elementsPath.idBase;\r
83\r
84 bottomSpaceData.html += '<span id="' + spaceId + '_label" class="cke_voice_label">' + editor.lang.elementspath.eleLabel + '</span>' +\r
85 '<span id="' + spaceId + '" class="cke_path" role="group" aria-labelledby="' + spaceId + '_label">' + emptyHtml + '</span>';\r
86\r
87 // Register the ui element to the focus manager.\r
88 editor.on( 'uiReady', function() {\r
89 var element = editor.ui.space( 'path' );\r
90 element && editor.focusManager.add( element, 1 );\r
91 } );\r
92\r
93 function onClick( elementIndex ) {\r
94 var element = elementsPath.list[ elementIndex ],\r
95 selection;\r
96\r
97 if ( element.equals( editor.editable() ) || element.getAttribute( 'contenteditable' ) == 'true' ) {\r
98 var range = editor.createRange();\r
99 range.selectNodeContents( element );\r
100\r
101 selection = range.select();\r
102 } else {\r
103 selection = editor.getSelection();\r
104 selection.selectElement( element );\r
105 }\r
106\r
1794320d 107 // Explicitly fire selectionChange when clicking on an element path button. (http://dev.ckeditor.com/ticket/13548)\r
c63493c8
IB
108 if ( CKEDITOR.env.ie ) {\r
109 editor.fire( 'selectionChange', { selection: selection, path: new CKEDITOR.dom.elementPath( element ) } );\r
110 }\r
111\r
112 // It is important to focus() *after* the above selection\r
1794320d 113 // manipulation, otherwise Firefox will have troubles. http://dev.ckeditor.com/ticket/10119\r
c63493c8
IB
114 editor.focus();\r
115 }\r
116\r
117 elementsPath.onClick = onClick;\r
118\r
119 var onClickHanlder = CKEDITOR.tools.addFunction( onClick ),\r
120 onKeyDownHandler = CKEDITOR.tools.addFunction( function( elementIndex, ev ) {\r
121 var idBase = elementsPath.idBase,\r
122 element;\r
123\r
124 ev = new CKEDITOR.dom.event( ev );\r
125\r
126 var rtl = editor.lang.dir == 'rtl';\r
127 switch ( ev.getKeystroke() ) {\r
128 case rtl ? 39 : 37: // LEFT-ARROW\r
129 case 9: // TAB\r
130 element = CKEDITOR.document.getById( idBase + ( elementIndex + 1 ) );\r
131 if ( !element )\r
132 element = CKEDITOR.document.getById( idBase + '0' );\r
133 element.focus();\r
134 return false;\r
135\r
136 case rtl ? 37 : 39: // RIGHT-ARROW\r
137 case CKEDITOR.SHIFT + 9: // SHIFT + TAB\r
138 element = CKEDITOR.document.getById( idBase + ( elementIndex - 1 ) );\r
139 if ( !element )\r
140 element = CKEDITOR.document.getById( idBase + ( elementsPath.list.length - 1 ) );\r
141 element.focus();\r
142 return false;\r
143\r
144 case 27: // ESC\r
145 editor.focus();\r
146 return false;\r
147\r
148 case 13: // ENTER // Opera\r
149 case 32: // SPACE\r
150 onClick( elementIndex );\r
151 return false;\r
152 }\r
153 return true;\r
154 } );\r
155\r
156 editor.on( 'selectionChange', function() {\r
157 var html = [],\r
158 elementsList = elementsPath.list = [],\r
159 namesList = [],\r
160 filters = elementsPath.filters,\r
161 isContentEditable = true,\r
162\r
1794320d 163 // Use elementPath to consider children of editable only (http://dev.ckeditor.com/ticket/11124).\r
c63493c8
IB
164 elementsChain = editor.elementPath().elements,\r
165 name;\r
166\r
167 // Starts iteration from body element, skipping html.\r
168 for ( var j = elementsChain.length; j--; ) {\r
169 var element = elementsChain[ j ],\r
170 ignore = 0;\r
171\r
172 if ( element.data( 'cke-display-name' ) )\r
173 name = element.data( 'cke-display-name' );\r
174 else if ( element.data( 'cke-real-element-type' ) )\r
175 name = element.data( 'cke-real-element-type' );\r
176 else\r
177 name = element.getName();\r
178\r
179 isContentEditable = element.hasAttribute( 'contenteditable' ) ?\r
180 element.getAttribute( 'contenteditable' ) == 'true' : isContentEditable;\r
181\r
182 // If elem is non-contenteditable, and it's not specifying contenteditable\r
183 // attribute - then elem should be ignored.\r
184 if ( !isContentEditable && !element.hasAttribute( 'contenteditable' ) )\r
185 ignore = 1;\r
186\r
187 for ( var i = 0; i < filters.length; i++ ) {\r
188 var ret = filters[ i ]( element, name );\r
189 if ( ret === false ) {\r
190 ignore = 1;\r
191 break;\r
192 }\r
193 name = ret || name;\r
194 }\r
195\r
196 if ( !ignore ) {\r
197 elementsList.unshift( element );\r
198 namesList.unshift( name );\r
199 }\r
200 }\r
201\r
202 for ( var iterationLimit = elementsList.length, index = 0; index < iterationLimit; index++ ) {\r
203 name = namesList[ index ];\r
204 var label = editor.lang.elementspath.eleTitle.replace( /%1/, name ),\r
205 item = pathItemTpl.output( {\r
206 id: idBase + index,\r
207 label: label,\r
208 text: name,\r
209 jsTitle: 'javascript:void(\'' + name + '\')', // jshint ignore:line\r
210 index: index,\r
211 keyDownFn: onKeyDownHandler,\r
212 clickFn: onClickHanlder\r
213 } );\r
214\r
215 html.unshift( item );\r
216 }\r
217\r
218 var space = getSpaceElement();\r
219 space.setHtml( html.join( '' ) + emptyHtml );\r
220 editor.fire( 'elementsPathUpdate', { space: space } );\r
221 } );\r
222\r
223 function empty() {\r
224 spaceElement && spaceElement.setHtml( emptyHtml );\r
225 delete elementsPath.list;\r
226 }\r
227\r
228 editor.on( 'readOnly', empty );\r
229 editor.on( 'contentDomUnload', empty );\r
230\r
231 editor.addCommand( 'elementsPathFocus', commands.toolbarFocus );\r
232 editor.setKeystroke( CKEDITOR.ALT + 122 /*F11*/, 'elementsPathFocus' );\r
233 }\r
234} )();\r
235\r
236/**\r
237 * Fired when the contents of the elementsPath are changed.\r
238 *\r
239 * @event elementsPathUpdate\r
240 * @member CKEDITOR.editor\r
241 * @param {CKEDITOR.editor} editor This editor instance.\r
242 * @param data\r
243 * @param {CKEDITOR.dom.element} data.space The elementsPath container.\r
244 */\r