]>
Commit | Line | Data |
---|---|---|
3332bebe | 1 | /**\r |
317f8f8f | 2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r |
3332bebe IB |
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license\r |
4 | */\r | |
5 | \r | |
6 | CKEDITOR.plugins.add( 'listblock', {\r | |
7 | requires: 'panel',\r | |
8 | \r | |
9 | onLoad: function() {\r | |
10 | var list = CKEDITOR.addTemplate( 'panel-list', '<ul role="presentation" class="cke_panel_list">{items}</ul>' ),\r | |
11 | listItem = CKEDITOR.addTemplate( 'panel-list-item', '<li id="{id}" class="cke_panel_listItem" role=presentation>' +\r | |
12 | '<a id="{id}_option" _cke_focus=1 hidefocus=true' +\r | |
13 | ' title="{title}"' +\r | |
14 | ' href="javascript:void(\'{val}\')" ' +\r | |
317f8f8f | 15 | ' {onclick}="CKEDITOR.tools.callFunction({clickFn},\'{val}\'); return false;"' + // http://dev.ckeditor.com/ticket/188\r |
3332bebe IB |
16 | ' role="option">' +\r |
17 | '{text}' +\r | |
18 | '</a>' +\r | |
19 | '</li>' ),\r | |
20 | listGroup = CKEDITOR.addTemplate( 'panel-list-group', '<h1 id="{id}" class="cke_panel_grouptitle" role="presentation" >{label}</h1>' ),\r | |
21 | reSingleQuote = /\'/g,\r | |
22 | escapeSingleQuotes = function( str ) {\r | |
23 | return str.replace( reSingleQuote, '\\\'' );\r | |
24 | };\r | |
25 | \r | |
26 | CKEDITOR.ui.panel.prototype.addListBlock = function( name, definition ) {\r | |
27 | return this.addBlock( name, new CKEDITOR.ui.listBlock( this.getHolderElement(), definition ) );\r | |
28 | };\r | |
29 | \r | |
30 | CKEDITOR.ui.listBlock = CKEDITOR.tools.createClass( {\r | |
31 | base: CKEDITOR.ui.panel.block,\r | |
32 | \r | |
33 | $: function( blockHolder, blockDefinition ) {\r | |
34 | blockDefinition = blockDefinition || {};\r | |
35 | \r | |
36 | var attribs = blockDefinition.attributes || ( blockDefinition.attributes = {} );\r | |
37 | ( this.multiSelect = !!blockDefinition.multiSelect ) && ( attribs[ 'aria-multiselectable' ] = true );\r | |
38 | // Provide default role of 'listbox'.\r | |
39 | !attribs.role && ( attribs.role = 'listbox' );\r | |
40 | \r | |
41 | // Call the base contructor.\r | |
42 | this.base.apply( this, arguments );\r | |
43 | \r | |
44 | // Set the proper a11y attributes.\r | |
45 | this.element.setAttribute( 'role', attribs.role );\r | |
46 | \r | |
47 | var keys = this.keys;\r | |
48 | keys[ 40 ] = 'next'; // ARROW-DOWN\r | |
49 | keys[ 9 ] = 'next'; // TAB\r | |
50 | keys[ 38 ] = 'prev'; // ARROW-UP\r | |
51 | keys[ CKEDITOR.SHIFT + 9 ] = 'prev'; // SHIFT + TAB\r | |
52 | keys[ 32 ] = CKEDITOR.env.ie ? 'mouseup' : 'click'; // SPACE\r | |
317f8f8f | 53 | CKEDITOR.env.ie && ( keys[ 13 ] = 'mouseup' ); // Manage ENTER, since onclick is blocked in IE (http://dev.ckeditor.com/ticket/8041).\r |
3332bebe IB |
54 | \r |
55 | this._.pendingHtml = [];\r | |
56 | this._.pendingList = [];\r | |
57 | this._.items = {};\r | |
58 | this._.groups = {};\r | |
59 | },\r | |
60 | \r | |
61 | _: {\r | |
62 | close: function() {\r | |
63 | if ( this._.started ) {\r | |
64 | var output = list.output( { items: this._.pendingList.join( '' ) } );\r | |
65 | this._.pendingList = [];\r | |
66 | this._.pendingHtml.push( output );\r | |
67 | delete this._.started;\r | |
68 | }\r | |
69 | },\r | |
70 | \r | |
71 | getClick: function() {\r | |
72 | if ( !this._.click ) {\r | |
73 | this._.click = CKEDITOR.tools.addFunction( function( value ) {\r | |
74 | var marked = this.toggle( value );\r | |
75 | if ( this.onClick )\r | |
76 | this.onClick( value, marked );\r | |
77 | }, this );\r | |
78 | }\r | |
79 | return this._.click;\r | |
80 | }\r | |
81 | },\r | |
82 | \r | |
83 | proto: {\r | |
84 | add: function( value, html, title ) {\r | |
85 | var id = CKEDITOR.tools.getNextId();\r | |
86 | \r | |
87 | if ( !this._.started ) {\r | |
88 | this._.started = 1;\r | |
89 | this._.size = this._.size || 0;\r | |
90 | }\r | |
91 | \r | |
92 | this._.items[ value ] = id;\r | |
93 | \r | |
94 | var data = {\r | |
95 | id: id,\r | |
96 | val: escapeSingleQuotes( CKEDITOR.tools.htmlEncodeAttr( value ) ),\r | |
97 | onclick: CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick',\r | |
98 | clickFn: this._.getClick(),\r | |
99 | title: CKEDITOR.tools.htmlEncodeAttr( title || value ),\r | |
100 | text: html || value\r | |
101 | };\r | |
102 | \r | |
103 | this._.pendingList.push( listItem.output( data ) );\r | |
104 | },\r | |
105 | \r | |
106 | startGroup: function( title ) {\r | |
107 | this._.close();\r | |
108 | \r | |
109 | var id = CKEDITOR.tools.getNextId();\r | |
110 | \r | |
111 | this._.groups[ title ] = id;\r | |
112 | \r | |
113 | this._.pendingHtml.push( listGroup.output( { id: id, label: title } ) );\r | |
114 | },\r | |
115 | \r | |
116 | commit: function() {\r | |
117 | this._.close();\r | |
118 | this.element.appendHtml( this._.pendingHtml.join( '' ) );\r | |
119 | delete this._.size;\r | |
120 | \r | |
121 | this._.pendingHtml = [];\r | |
122 | },\r | |
123 | \r | |
124 | toggle: function( value ) {\r | |
125 | var isMarked = this.isMarked( value );\r | |
126 | \r | |
127 | if ( isMarked )\r | |
128 | this.unmark( value );\r | |
129 | else\r | |
130 | this.mark( value );\r | |
131 | \r | |
132 | return !isMarked;\r | |
133 | },\r | |
134 | \r | |
135 | hideGroup: function( groupTitle ) {\r | |
136 | var group = this.element.getDocument().getById( this._.groups[ groupTitle ] ),\r | |
137 | list = group && group.getNext();\r | |
138 | \r | |
139 | if ( group ) {\r | |
140 | group.setStyle( 'display', 'none' );\r | |
141 | \r | |
142 | if ( list && list.getName() == 'ul' )\r | |
143 | list.setStyle( 'display', 'none' );\r | |
144 | }\r | |
145 | },\r | |
146 | \r | |
147 | hideItem: function( value ) {\r | |
148 | this.element.getDocument().getById( this._.items[ value ] ).setStyle( 'display', 'none' );\r | |
149 | },\r | |
150 | \r | |
151 | showAll: function() {\r | |
152 | var items = this._.items,\r | |
153 | groups = this._.groups,\r | |
154 | doc = this.element.getDocument();\r | |
155 | \r | |
156 | for ( var value in items ) {\r | |
157 | doc.getById( items[ value ] ).setStyle( 'display', '' );\r | |
158 | }\r | |
159 | \r | |
160 | for ( var title in groups ) {\r | |
161 | var group = doc.getById( groups[ title ] ),\r | |
162 | list = group.getNext();\r | |
163 | \r | |
164 | group.setStyle( 'display', '' );\r | |
165 | \r | |
166 | if ( list && list.getName() == 'ul' )\r | |
167 | list.setStyle( 'display', '' );\r | |
168 | }\r | |
169 | },\r | |
170 | \r | |
171 | mark: function( value ) {\r | |
172 | if ( !this.multiSelect )\r | |
173 | this.unmarkAll();\r | |
174 | \r | |
175 | var itemId = this._.items[ value ],\r | |
176 | item = this.element.getDocument().getById( itemId );\r | |
177 | item.addClass( 'cke_selected' );\r | |
178 | \r | |
179 | this.element.getDocument().getById( itemId + '_option' ).setAttribute( 'aria-selected', true );\r | |
180 | this.onMark && this.onMark( item );\r | |
181 | },\r | |
182 | \r | |
317f8f8f IB |
183 | markFirstDisplayed: function() {\r |
184 | var context = this;\r | |
185 | this._.markFirstDisplayed( function() {\r | |
186 | if ( !context.multiSelect )\r | |
187 | context.unmarkAll();\r | |
188 | } );\r | |
189 | },\r | |
190 | \r | |
3332bebe IB |
191 | unmark: function( value ) {\r |
192 | var doc = this.element.getDocument(),\r | |
193 | itemId = this._.items[ value ],\r | |
194 | item = doc.getById( itemId );\r | |
195 | \r | |
196 | item.removeClass( 'cke_selected' );\r | |
197 | doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' );\r | |
198 | \r | |
199 | this.onUnmark && this.onUnmark( item );\r | |
200 | },\r | |
201 | \r | |
202 | unmarkAll: function() {\r | |
203 | var items = this._.items,\r | |
204 | doc = this.element.getDocument();\r | |
205 | \r | |
206 | for ( var value in items ) {\r | |
207 | var itemId = items[ value ];\r | |
208 | \r | |
209 | doc.getById( itemId ).removeClass( 'cke_selected' );\r | |
210 | doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' );\r | |
211 | }\r | |
212 | \r | |
213 | this.onUnmark && this.onUnmark();\r | |
214 | },\r | |
215 | \r | |
216 | isMarked: function( value ) {\r | |
217 | return this.element.getDocument().getById( this._.items[ value ] ).hasClass( 'cke_selected' );\r | |
218 | },\r | |
219 | \r | |
220 | focus: function( value ) {\r | |
221 | this._.focusIndex = -1;\r | |
222 | \r | |
223 | var links = this.element.getElementsByTag( 'a' ),\r | |
224 | link,\r | |
225 | selected,\r | |
226 | i = -1;\r | |
227 | \r | |
228 | if ( value ) {\r | |
229 | selected = this.element.getDocument().getById( this._.items[ value ] ).getFirst();\r | |
230 | \r | |
231 | while ( ( link = links.getItem( ++i ) ) ) {\r | |
232 | if ( link.equals( selected ) ) {\r | |
233 | this._.focusIndex = i;\r | |
234 | break;\r | |
235 | }\r | |
236 | }\r | |
237 | }\r | |
238 | else {\r | |
239 | this.element.focus();\r | |
240 | }\r | |
241 | \r | |
242 | selected && setTimeout( function() {\r | |
243 | selected.focus();\r | |
244 | }, 0 );\r | |
245 | }\r | |
246 | }\r | |
247 | } );\r | |
248 | }\r | |
249 | } );\r |