Index: trunk/extensions/UsabilityInitiative/SimpleSearch/SimpleSearch.js |
— | — | @@ -1,14 +1,15 @@ |
2 | 2 | /* JavaScript for SimpleSearch extension */ |
3 | 3 | |
4 | | -$( document ).ready( function() { |
| 4 | +js2AddOnloadHook( function() { |
5 | 5 | // Only use this function in conjuction with the Vector skin |
6 | 6 | if( skin != 'vector' ) |
7 | 7 | return; |
8 | 8 | |
9 | 9 | // Adds form submission handler |
10 | | - $( 'div#simpleSearch > input#searchInput' ) |
| 10 | + $j( 'div#simpleSearch > input#searchInput' ) |
11 | 11 | .each( function() { |
12 | | - $( '<label>' + gM( 'simplesearch-search' ) + '</label>' ) |
| 12 | + $j( '<label></label>' ) |
| 13 | + .text( gM( 'simplesearch-search' ) ) |
13 | 14 | .css({ |
14 | 15 | 'display': 'none', |
15 | 16 | 'position' : 'absolute', |
— | — | @@ -17,21 +18,21 @@ |
18 | 19 | 'color': '#999999', |
19 | 20 | 'cursor': 'text' |
20 | 21 | }) |
21 | | - .css( ( $( 'body.rtl' ).size() > 0 ? 'right' : 'left' ), 0 ) |
| 22 | + .css( ( $j( 'body.rtl' ).size() > 0 ? 'right' : 'left' ), 0 ) |
22 | 23 | .click( function() { |
23 | | - $(this).parent().find( 'input#searchInput' ).focus(); |
| 24 | + $j(this).parent().find( 'input#searchInput' ).focus(); |
24 | 25 | }) |
25 | | - .appendTo( $(this).parent() ); |
26 | | - if ( $(this).val() == '' ) { |
27 | | - $(this).parent().find( 'label' ).show(); |
| 26 | + .appendTo( $j(this).parent() ); |
| 27 | + if ( $j(this).val() == '' ) { |
| 28 | + $j(this).parent().find( 'label' ).show(); |
28 | 29 | } |
29 | 30 | }) |
30 | 31 | .focus( function() { |
31 | | - $(this).parent().find( 'label' ).hide(); |
| 32 | + $j(this).parent().find( 'label' ).hide(); |
32 | 33 | }) |
33 | 34 | .blur( function() { |
34 | | - if ( $(this).val() == '' ) { |
35 | | - $(this).parent().find( 'label' ).show(); |
| 35 | + if ( $j(this).val() == '' ) { |
| 36 | + $j(this).parent().find( 'label' ).show(); |
36 | 37 | } |
37 | 38 | }); |
38 | 39 | }); |
\ No newline at end of file |
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.php |
— | — | @@ -20,9 +20,6 @@ |
21 | 21 | |
22 | 22 | /* Configuration */ |
23 | 23 | |
24 | | -// Set this to true to simply override the stock toolbar for everyone |
25 | | -$wgUsabilityInitiativeCoesxistWithMvEmbed = false; |
26 | | - |
27 | 24 | // Set this to false to include all plugins individually |
28 | 25 | $wgUsabilityInitiativeJsMode = 'combined'; |
29 | 26 | |
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php |
— | — | @@ -28,36 +28,39 @@ |
29 | 29 | array( 'src' => 'js/jquery.browser.js', 'version' => 2 ), |
30 | 30 | array( 'src' => 'js/jquery.cookie.js', 'version' => 2 ), |
31 | 31 | array( 'src' => 'js/jquery.textSelection.js', 'version' => 2 ), |
| 32 | + array( 'src' => 'js/jquery.toolbar.js', 'version' => 2 ), |
32 | 33 | array( 'src' => 'js/jquery.wikiOutline.js', 'version' => 2 ), |
33 | 34 | ), |
34 | 35 | ), |
35 | | - // Code to include when mv_embed is not present |
36 | | - 'no_mv_embed' => array( |
37 | | - array( 'src' => 'js/messages.js', 'version' => 1 ), |
| 36 | + // Code to include when js2 is not present |
| 37 | + 'no_js2' => array( |
| 38 | + array( 'src' => 'js/js2.js', 'version' => 1 ), |
38 | 39 | ) |
39 | 40 | ); |
40 | 41 | |
41 | 42 | /* Static Functions */ |
42 | | - |
| 43 | + |
43 | 44 | public static function initialize() { |
44 | 45 | global $wgUsabilityInitiativeJsMode; |
45 | 46 | global $wgUsabilityInitiativeCoesxistWithMvEmbed; |
46 | 47 | |
47 | 48 | // Only do this the first time! |
48 | 49 | if ( !self::$doOutput ) { |
| 50 | + // Provide support for js2 conventions in it's absence |
| 51 | + if ( !$wgEnableJS2system ) { |
| 52 | + self::$scripts = array_merge( |
| 53 | + self::$scriptFiles['no_js2'], self::$scripts |
| 54 | + ); |
| 55 | + } |
49 | 56 | // Default to raw |
50 | 57 | $mode = $wgUsabilityInitiativeJsMode; // Just an alias |
51 | 58 | if ( !isset( self::$scriptFiles['base_sets'][$mode] ) ) { |
52 | 59 | $mode = 'raw'; |
53 | 60 | } |
54 | 61 | // Inlcude base-set of scripts |
55 | | - self::$scripts = self::$scriptFiles['base_sets'][$mode]; |
56 | | - // Play nice with mv_embed |
57 | | - if ( !$wgUsabilityInitiativeCoesxistWithMvEmbed ) { |
58 | | - self::$scripts = array_merge( |
59 | | - self::$scriptFiles['no_mv_embed'], self::$scripts |
60 | | - ); |
61 | | - } |
| 62 | + self::$scripts = array_merge( |
| 63 | + self::$scriptFiles['base_sets'][$mode], self::$scripts |
| 64 | + ); |
62 | 65 | } |
63 | 66 | self::$doOutput = true; |
64 | 67 | } |
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js |
— | — | @@ -1,451 +1,28 @@ |
2 | 2 | /* JavaScript for EditToolbar extension */ |
3 | 3 | |
4 | | -/** |
5 | | - * This is the toolbar plugin, which can be used like |
6 | | - * $( 'div#edittoolbar' ).toolbar( '#wpTextbox1', tools ); |
7 | | - * Where tools is an array of objects which describe each tool (see below for |
8 | | - * specific examples) (THIS NEEDS BETTER DOCUMENTATION WHEN I HAVE TIME) |
9 | | - */ |
10 | | -(function($){ |
11 | | - $.fn.extend({ |
12 | | - /** |
13 | | - * |
14 | | - * @param {Object} textbox |
15 | | - * @param {Object} tools |
16 | | - */ |
17 | | - toolbar: function( textbox, tools ) { |
18 | | - return this.each(function() { |
19 | | - // Checks if main section is in the structure |
20 | | - if ( 'main' in tools ) { |
21 | | - // Adds main section to toolbar |
22 | | - $(this).addToolbarSection( tools.main, textbox, 'main' ); |
23 | | - } |
24 | | - // Appends additional section tabs |
25 | | - var tabDiv = $( '<div />' ) |
26 | | - .attr( 'class', 'tabs' ) |
27 | | - .appendTo( $(this) ); |
28 | | - // Appends additional section |
29 | | - var sectionsDiv = $( '<div />' ) |
30 | | - .attr( 'class', 'sections' ) |
31 | | - .appendTo( $(this) ); |
32 | | - // Appends float-clearing div |
33 | | - $(this).append( $( '<div class="break"></div>' ) ); |
34 | | - // Cookie name for storing section state |
35 | | - var sectionCookie = 'edittoolbar-' + $(this).attr( 'id' ) + '-section'; |
36 | | - // Queue for sections to be built asynchonously |
37 | | - var sectionQueue = []; |
38 | | - // Loops over each section |
39 | | - for ( section in tools ) { |
40 | | - // Skips over main (was handled as special case already) |
41 | | - if ( section == 'main' ) { |
42 | | - continue; |
43 | | - } |
44 | | - // Appends section content |
45 | | - var sectionDiv = $( '<div />') |
46 | | - .attr( { 'class': 'section', 'id': $(this).attr( 'id' ) + '-section-' + section } ) |
47 | | - .appendTo( sectionsDiv ) |
48 | | - .addClass( 'loading' ) |
49 | | - .append( |
50 | | - $( '<div />' ) |
51 | | - .addClass( 'progress' ) |
52 | | - .text( gM( 'edittoolbar-loading' ) |
53 | | - ) |
54 | | - ); |
55 | | - // Respects state |
56 | | - var current = false; |
57 | | - if ( $.cookie( sectionCookie ) == sectionDiv.attr( 'id' ) ) { |
58 | | - sectionDiv.attr( 'style', 'display:block' ); |
59 | | - current = true; |
60 | | - } |
61 | | - // Appends toolbar to section div |
62 | | - sectionQueue[sectionQueue.length] = { |
63 | | - 'sectionDiv': sectionDiv, |
64 | | - 'tools': tools[section], |
65 | | - 'textbox': textbox |
66 | | - }; |
67 | | - // Appends section tab |
68 | | - tabDiv.append( |
69 | | - $( '<span />' ) |
70 | | - .attr( 'class', 'tab' ) |
71 | | - .append( |
72 | | - $( '<a />' ) |
73 | | - .text( tools[section].label || gM( tools[section].labelMsg ) ) |
74 | | - .attr( { 'href': '#', 'rel': section, 'class': current ? 'current' : null } ) |
75 | | - .data( 'sectionDiv', sectionDiv ) |
76 | | - .data( 'sectionCookie', sectionCookie ) |
77 | | - .data( 'textbox', textbox ) |
78 | | - .click( function() { |
79 | | - $(this).blur(); |
80 | | - var show = ( $(this).data( 'sectionDiv' ).css( 'display' ) == 'none' ); |
81 | | - $(this).data( 'sectionDiv' ).parent().children().hide(); |
82 | | - $(this).parent().parent().find( 'a' ).removeClass( 'current' ); |
83 | | - if ( show ) { |
84 | | - $(this).data( 'sectionDiv' ).show(); |
85 | | - $(this).addClass( 'current' ); |
86 | | - } |
87 | | - // Sets or deletes cookie when sections are shown or hidden |
88 | | - $.cookie( |
89 | | - $(this).data( 'sectionCookie' ), |
90 | | - show ? $(this).data( 'sectionDiv' ).attr( 'id' ) : null |
91 | | - ); |
92 | | - return false; |
93 | | - }) |
94 | | - ) |
95 | | - ); |
96 | | - } |
97 | | - $.eachAsync( sectionQueue, { |
98 | | - bulk: 0, |
99 | | - loop: function( index, value ) { |
100 | | - value.sectionDiv.addToolbarSection( value.tools, value.textbox, index ); |
101 | | - value.sectionDiv.removeClass( 'loading' ) |
102 | | - } |
103 | | - } ) |
104 | | - }); |
105 | | - }, |
106 | | - /** |
107 | | - * Adds a toolbar section to a containing div |
108 | | - * @param {Object} section Section data to build toolbar from |
109 | | - * @param {Object} textbox |
110 | | - * @param {String} section ID (used for cookies) |
111 | | - */ |
112 | | - addToolbarSection: function( section, textbox, id ) { |
113 | | - // Path to images (THIS WILL HAVE TO CHANGE IF YOU MOVE THIS INTO CORE) |
114 | | - var imagePath = wgScriptPath + |
115 | | - '/extensions/UsabilityInitiative/EditToolbar/images/'; |
116 | | - function msgSet( object, property ) { |
117 | | - return property in object || property + 'Msg' in object; |
118 | | - } |
119 | | - function msg( object, property ) { |
120 | | - return object[property] || gM( object[property + 'Msg'] ); |
121 | | - } |
122 | | - // Creates generic action |
123 | | - var action = function( event ) { |
124 | | - $(this).useTool( |
125 | | - $(this).data( 'context' ).tool, |
126 | | - $(this).data( 'context' ).textbox |
127 | | - ); |
128 | | - event.preventDefault(); |
129 | | - }; |
130 | | - switch ( section.type ) { |
131 | | - case 'toolbar': |
132 | | - // Check for groups |
133 | | - if ( !( 'groups' in section ) ) { |
134 | | - return; |
135 | | - } |
136 | | - // Loops over each group |
137 | | - for ( group in section.groups ) { |
138 | | - // Appends group |
139 | | - var groupDiv = $( '<div />' ) |
140 | | - .attr( 'class', 'group' ) |
141 | | - .appendTo( $(this) ); |
142 | | - // Checks if there's a label for this group |
143 | | - if ( msgSet( section.groups[group], 'label' ) ) { |
144 | | - groupDiv.append( |
145 | | - $( '<div />' ) |
146 | | - .attr( 'class', 'label' ) |
147 | | - .text( msg( section.groups[group], 'label' ) ) |
148 | | - ) |
149 | | - } |
150 | | - // Loops over each tool |
151 | | - for ( tool in section.groups[group].tools ) { |
152 | | - // Filters are jQuery selectors which must select 1 or more |
153 | | - // elements for this tool to apear. This is especailly |
154 | | - // useful for restricting some tools to certain namespaces |
155 | | - if ( 'filters' in section.groups[group].tools[tool] ) { |
156 | | - var filters = section.groups[group].tools[tool].filters; |
157 | | - var skip = false; |
158 | | - for ( filter in filters ) { |
159 | | - if ( $( filters[filter] ).size() == 0 ) { |
160 | | - skip = true; |
161 | | - } |
162 | | - } |
163 | | - if ( skip ) { |
164 | | - continue; |
165 | | - } |
166 | | - } |
167 | | - // Creates context for use in action |
168 | | - var context = { 'tool': section.groups[group].tools[tool], 'textbox': textbox }; |
169 | | - // Creates the label of the tool |
170 | | - var label = msg( section.groups[group].tools[tool], 'label' ); |
171 | | - switch ( section.groups[group].tools[tool].type ) { |
172 | | - case 'button': |
173 | | - // Appends button |
174 | | - groupDiv.append( |
175 | | - $( '<input />' ) |
176 | | - .attr( { |
177 | | - src: imagePath + section.groups[group].tools[tool].icon, |
178 | | - alt: label, |
179 | | - title: label, |
180 | | - 'class': 'tool', |
181 | | - 'type': 'image' |
182 | | - } ) |
183 | | - .data( 'context', context ) |
184 | | - .click( action ) |
185 | | - ); |
186 | | - break; |
187 | | - case 'select': |
188 | | - // Appends select |
189 | | - var selectDiv = $( '<select />' ) |
190 | | - .data( 'context', context ) |
191 | | - .change( action ) |
192 | | - .append( |
193 | | - $( '<option />' ) .text( label ) |
194 | | - ) |
195 | | - .appendTo( groupDiv ); |
196 | | - // Appends options |
197 | | - for ( option in section.groups[group].tools[tool].list ) { |
198 | | - selectDiv.append( |
199 | | - $( '<option/>' ) |
200 | | - .text( msg( section.groups[group].tools[tool].list[option], 'label' ) ) |
201 | | - .attr( 'value', option ) |
202 | | - ); |
203 | | - } |
204 | | - break; |
205 | | - default: break; |
206 | | - } |
207 | | - } |
208 | | - } |
209 | | - break; |
210 | | - case 'booklet': |
211 | | - // Check for pages |
212 | | - if ( !( 'pages' in section ) ) { |
213 | | - return; |
214 | | - } |
215 | | - // Appends index |
216 | | - var indexDiv = $( '<div />' ) |
217 | | - .attr( 'class', 'index' ) |
218 | | - .appendTo( $(this) ); |
219 | | - // Builds name name of booklet state cookie |
220 | | - var bookletCookie = 'edittoolbar-' + $(this).attr( 'id' ) + '-booklet-' + id; |
221 | | - // Gets ID of selected page |
222 | | - var selectedID = $.cookie( bookletCookie ); |
223 | | - // Loops over each page |
224 | | - for ( page in section.pages ) { |
225 | | - // Fallback to current (first) page for selectedID |
226 | | - if ( selectedID === null ) { |
227 | | - selectedID = page; |
228 | | - } |
229 | | - // Appends index entry |
230 | | - indexDiv.append( |
231 | | - $( '<div />' ) |
232 | | - .attr( 'class', page === selectedID ? 'current' : null ) |
233 | | - .text( msg( section.pages[page], 'label' ) ) |
234 | | - .data( 'page', page ) |
235 | | - .data( 'cookie', bookletCookie ) |
236 | | - .click( function() { |
237 | | - $(this).parent().parent().find( 'div.pages > div.page' ).hide(); |
238 | | - $(this).parent().find( 'div' ).removeClass( 'current' ); |
239 | | - $(this).parent().parent().find( 'div.pages > div.page-' + $(this).data( 'page' ) ).show(); |
240 | | - $(this).addClass( 'current' ); |
241 | | - |
242 | | - // Update cookie |
243 | | - $.cookie( $(this).data( 'cookie'), $(this).data( 'page' ) ); |
244 | | - } ) |
245 | | - ); |
246 | | - } |
247 | | - var pagesDiv = $( '<div />' ) |
248 | | - .attr( 'class', 'pages' ) |
249 | | - .appendTo( $(this) ); |
250 | | - // Loops over each page |
251 | | - for ( page in section.pages ) { |
252 | | - // Appends page |
253 | | - var pageDiv = $( '<div />' ) |
254 | | - .attr( 'class', 'page page-' + page ) |
255 | | - .css( 'display', page === selectedID ? 'block' : 'none' ) |
256 | | - .appendTo( pagesDiv ); |
257 | | - // Checks if there's content for this page |
258 | | - switch ( section.pages[page].layout ) { |
259 | | - case 'table': |
260 | | - // Appends table to page |
261 | | - var contentTable = $( '<table />' ) |
262 | | - .attr( { |
263 | | - 'cellpadding': '0', |
264 | | - 'cellspacing': '0', |
265 | | - 'border': '0', |
266 | | - 'width': '100%' |
267 | | - } ) |
268 | | - .appendTo( pageDiv ); |
269 | | - var headingRow = $( '<tr />' ) |
270 | | - .appendTo( contentTable ); |
271 | | - // Appends headings to table |
272 | | - for ( heading in section.pages[page].headings ) { |
273 | | - headingRow.append( |
274 | | - $( '<th />' ) |
275 | | - .text( msg( section.pages[page].headings[heading], 'content' ) ) |
276 | | - ); |
277 | | - } |
278 | | - // Appends rows to table |
279 | | - for ( row in section.pages[page].rows ) { |
280 | | - var contentRow = $( '<tr />' ) |
281 | | - .appendTo( contentTable ); |
282 | | - for ( cell in section.pages[page].rows[row] ) { |
283 | | - contentRow.append( |
284 | | - $( '<td />' ) |
285 | | - .attr( { |
286 | | - 'class': cell, |
287 | | - 'valign': 'top' |
288 | | - } ) |
289 | | - .append( |
290 | | - $( '<span>' + msg( section.pages[page].rows[row][cell], 'content' ) + '</span>' ) |
291 | | - ) |
292 | | - ); |
293 | | - } |
294 | | - } |
295 | | - break; |
296 | | - case 'characters': |
297 | | - // Appends special character adders |
298 | | - var charsDiv = $( '<div />' ) |
299 | | - .attr( section.pages[page].attributes ) |
300 | | - .css( section.pages[page].styles ) |
301 | | - .appendTo( pageDiv ); |
302 | | - for ( character in section.pages[page].characters ) { |
303 | | - switch( section.pages[page].characters[character].type ) { |
304 | | - case 'link': |
305 | | - var context = { |
306 | | - 'tool' : section.pages[page].characters[character], |
307 | | - 'textbox': textbox |
308 | | - }; |
309 | | - charsDiv.append( |
310 | | - $( '<a />' ) |
311 | | - .attr( 'href', '#' ) |
312 | | - .text( section.pages[page].characters[character].label ) |
313 | | - .data( 'context', context) |
314 | | - .click( action ) |
315 | | - .click( function() { return false; } ) |
316 | | - ); |
317 | | - break; |
318 | | - } |
319 | | - } |
320 | | - break; |
321 | | - default: break; |
322 | | - } |
323 | | - } |
324 | | - break; |
325 | | - default: break; |
326 | | - } |
327 | | - }, |
328 | | - /** |
329 | | - * Performs action on a textbox using a tool |
330 | | - * @param {Object} tool |
331 | | - * @param {Object} textbox |
332 | | - */ |
333 | | - useTool: function( tool, textbox ) { |
334 | | - function performAction( action, textbox ) { |
335 | | - switch ( action.type) { |
336 | | - case 'encapsulate': |
337 | | - var parts = { 'pre': '', 'peri': '', 'post': '' }; |
338 | | - for ( part in parts ) { |
339 | | - if ( part + 'Msg' in action.options ) { |
340 | | - parts[part] = gM( action.options[part + 'Msg'], ( action.options[part] || null ) ); |
341 | | - } else { |
342 | | - parts[part] = ( action.options[part] || '' ) |
343 | | - } |
344 | | - } |
345 | | - textbox.encapsulateSelection( parts.pre, parts.peri, parts.post ); |
346 | | - break; |
347 | | - default: break; |
348 | | - } |
349 | | - } |
350 | | - switch ( tool.type ) { |
351 | | - case 'button': |
352 | | - case 'link': |
353 | | - performAction( tool.action, textbox ); |
354 | | - break; |
355 | | - case 'select': |
356 | | - if ( $(this).val() in tool.list ) { |
357 | | - performAction( tool.list[$(this).val()].action, textbox ); |
358 | | - } |
359 | | - $(this).find(":selected").attr( 'selected', false ); |
360 | | - $(this).find(":first").attr( 'selected', true ); |
361 | | - break; |
362 | | - default: break; |
363 | | - } |
364 | | - }, |
365 | | - |
366 | | - /** |
367 | | - * Converts a charinsert array like the one used on dewiki to |
368 | | - * the format expected in editToolbarConfiguration |
369 | | - */ |
370 | | - parseCharinsert: function( charinsert ) { |
371 | | - var retval = {}; |
372 | | - for( page in charinsert ) { |
373 | | - var pageKey = page.replace(/[^A-Za-z]/g, '-'); |
374 | | - var characters = [], attributes = {}, styles = {}; |
375 | | - var i = 0; |
376 | | - for( line in charinsert[page] ) { |
377 | | - if( !( charinsert[page][line] instanceof Array ) ) { |
378 | | - for( attr in charinsert[page][line] ) { |
379 | | - switch( attr ) { |
380 | | - case 'class': |
381 | | - case 'lang': |
382 | | - attributes[attr] = charinsert[page][line][attr]; |
383 | | - break; |
384 | | - default: |
385 | | - styles[attr] = charinsert[page][line][attr]; |
386 | | - } |
387 | | - } |
388 | | - continue; |
389 | | - } |
390 | | - for( character in charinsert[page][line] ) { |
391 | | - var tool = { |
392 | | - type: 'link', |
393 | | - label: '', |
394 | | - action: { |
395 | | - type: 'encapsulate', |
396 | | - options: { |
397 | | - pre: '', |
398 | | - post: '' |
399 | | - } |
400 | | - } |
401 | | - }; |
402 | | - if( charinsert[page][line][character] instanceof Array ) { |
403 | | - tool.action.options.pre = charinsert[page][line][character][0]; |
404 | | - tool.action.options.post = charinsert[page][line][character][1]; |
405 | | - } else { |
406 | | - tool.action.options.pre = charinsert[page][line][character]; |
407 | | - } |
408 | | - tool.label = tool.action.options.pre + tool.action.options.post; |
409 | | - characters[i++] = tool; |
410 | | - } |
411 | | - } |
412 | | - retval[pageKey] = { |
413 | | - label: page, |
414 | | - layout: 'characters', |
415 | | - attributes: attributes, |
416 | | - styles: styles, |
417 | | - characters: characters |
418 | | - }; |
419 | | - } |
420 | | - return retval; |
421 | | - } |
422 | | - }); |
423 | | -})(jQuery); |
424 | | -/** |
425 | | - * This initializes an edit toolbar on div#edittoolbar and connects it to |
426 | | - * textarea#wpTextbox1 - which needs to be done after the document is loaded. |
427 | | - */ |
428 | | -jQuery( document ).ready( function() { |
429 | | - $( 'textarea#wpTextbox1' ).wrap( |
430 | | - $( '<div></div>' ) |
| 4 | +js2AddOnloadHook( function() { |
| 5 | + $j( 'textarea#wpTextbox1' ).wrap( |
| 6 | + $j( '<div></div>' ) |
431 | 7 | .attr( 'id', 'edit-ui' ) |
432 | 8 | ); |
433 | | - $( 'textarea#wpTextbox1' ).wrap( |
434 | | - $( '<div></div>' ) |
| 9 | + $j( 'textarea#wpTextbox1' ).wrap( |
| 10 | + $j( '<div></div>' ) |
435 | 11 | .attr( 'id', 'edit-ui-left' ) |
436 | 12 | ); |
437 | | - $( 'div#edit-ui' ).append( |
438 | | - $( '<div></div>' ) |
| 13 | + $j( 'div#edit-ui' ).append( |
| 14 | + $j( '<div></div>' ) |
439 | 15 | .attr( 'id', 'edit-ui-right' ) |
440 | 16 | ); |
441 | | - $( 'div#edit-ui-left' ).prepend( |
442 | | - $( '<div></div>' ) |
| 17 | + $j( 'div#edit-ui-left' ).prepend( |
| 18 | + $j( '<div></div>' ) |
443 | 19 | .attr( 'id', 'edit-toolbar' ) |
444 | 20 | ); |
445 | | - $( 'div#edit-toolbar' ).toolbar( |
446 | | - $( 'textarea#wpTextbox1' ), |
| 21 | + $j( 'div#edit-toolbar' ).toolbar( |
| 22 | + $j( 'textarea#wpTextbox1' ), |
447 | 23 | editToolbarConfiguration |
448 | 24 | ); |
449 | 25 | }); |
| 26 | + |
450 | 27 | /** |
451 | 28 | * This enormous structure is what makes the toolbar what it is. Customization |
452 | 29 | * of this structure prior to the document being ready and thus executing the |
Index: trunk/extensions/UsabilityInitiative/OptIn/OptIn.js |
— | — | @@ -1,33 +1,60 @@ |
2 | 2 | /* JavaScript for OptIn extension */ |
3 | 3 | |
4 | | -function optInGetPOSTData() { |
| 4 | +js2AddOnloadHook( function() { |
| 5 | + $j( '.optin-other-select' ).parent().hide(); |
| 6 | + $j( 'select.optin-need-other' ).change( function() { |
| 7 | + if( $j(this).val() == 'other' ) |
| 8 | + $j( '#' + $j(this).attr( 'id' ) + '-other' ).parent().slideDown( 'fast' ); |
| 9 | + else |
| 10 | + $j( '#' + $j(this).attr( 'id' ) + '-other' ).parent().slideUp( 'fast' ); |
| 11 | + }); |
| 12 | + $j( '.optin-other-radios, .optin-other-checks' ).click( function() { |
| 13 | + $j(this).prev().prev().attr( 'checked', true ); |
| 14 | + }); |
| 15 | + $j( '.survey-ifyes, .survey-ifno' ).hide(); |
| 16 | + $j( '.survey-yes, .survey-no' ).change( function() { |
| 17 | + yesrow = $j( '#' + $j(this).attr( 'name' ) + '-ifyes-row' ); |
| 18 | + norow = $j( '#' + $j(this).attr( 'name' ) + '-ifno-row' ); |
| 19 | + if( $j(this).is( '.survey-yes:checked' ) ) { |
| 20 | + yesrow.slideDown( 'fast' ); |
| 21 | + norow.slideUp( 'fast' ); |
| 22 | + } else if( $j(this).is( '.survey-no:checked' ) ) { |
| 23 | + yesrow.slideUp( 'fast' ); |
| 24 | + norow.slideDown( 'fast' ); |
| 25 | + } |
| 26 | + }); |
| 27 | + // Load initial state |
| 28 | + $j( '.survey-yes, .survey-no' ).change(); |
| 29 | + // Detect browser |
5 | 30 | var browserIndex = 'other'; |
6 | | - switch ( $.browser.name ) { |
| 31 | + switch ( $j.browser.name ) { |
7 | 32 | case 'msie': |
8 | | - browserIndex = 'ie'+ parseInt( $.browser.versionNumber ); |
| 33 | + browserIndex = 'ie'+ parseInt( $j.browser.versionNumber ); |
9 | 34 | break; |
10 | 35 | case 'firefox': |
11 | | - browserIndex = 'ff' + parseInt( $.browser.versionNumber ); |
| 36 | + browserIndex = 'ff' + parseInt( $j.browser.versionNumber ); |
12 | 37 | break; |
13 | 38 | case 'chrome': |
14 | | - browserIndex = 'c' + parseInt( $.browser.versionNumber ); // FIXME: Chrome Beta? |
| 39 | + // FIXME: Chrome Beta? |
| 40 | + browserIndex = 'c' + parseInt( $j.browser.versionNumber ); |
15 | 41 | break; |
16 | 42 | case 'safari': |
17 | | - browserIndex = 's' + parseInt( $.browser.versionNumber ); |
| 43 | + browserIndex = 's' + parseInt( $j.browser.versionNumber ); |
18 | 44 | break; |
19 | 45 | case 'opera': |
20 | | - if ( parseInt( $.browser.versionNumber ) == 9 ) { |
21 | | - if ( $.browser.version.substr( 0, 3 ) == '9.5' ) |
| 46 | + if ( parseInt( $j.browser.versionNumber ) == 9 ) { |
| 47 | + if ( $j.browser.version.substr( 0, 3 ) == '9.5' ) |
22 | 48 | browserIndex = 'o9.5'; |
23 | 49 | else |
24 | 50 | browserIndex = 'o9'; |
25 | | - } else if ( parseInt( $.browser.versionNumber ) == 10 ) |
| 51 | + } else if ( parseInt( $j.browser.versionNumber ) == 10 ) |
26 | 52 | browserIndex = 'o10'; |
27 | 53 | break; |
28 | 54 | } |
29 | | - |
| 55 | + $j( '#survey-browser' ).val( browserIndex ); |
| 56 | + // Detect operating system |
30 | 57 | var osIndex = 'other'; |
31 | | - switch ( $.os.name ) { |
| 58 | + switch ( $j.os.name ) { |
32 | 59 | case 'win': |
33 | 60 | osIndex = 'windows'; |
34 | 61 | break; |
— | — | @@ -38,48 +65,10 @@ |
39 | 66 | osIndex = 'linux'; |
40 | 67 | break; |
41 | 68 | } |
42 | | - |
43 | | - return { 'survey-browser': browserIndex, 'survey-os': osIndex, |
44 | | - 'survey-res-x': screen.width, 'survey-res-y': screen.height, |
45 | | - 'opt': 'browser' }; |
46 | | -} |
47 | | - |
48 | | -$( document ).ready( function() { |
49 | | - $( '.optin-other-select' ).parent().hide(); |
50 | | - $( 'select.optin-need-other' ).change( function() { |
51 | | - if( $(this).val() == 'other' ) |
52 | | - $( '#' + $(this).attr( 'id' ) + '-other' ).parent().slideDown( 'fast' ); |
53 | | - else |
54 | | - $( '#' + $(this).attr( 'id' ) + '-other' ).parent().slideUp( 'fast' ); |
55 | | - }); |
56 | | - |
57 | | - $( '.optin-other-radios, .optin-other-checks' ).click( function() { |
58 | | - $(this).prev().prev().attr( 'checked', true ); |
59 | | - }); |
60 | | - |
61 | | - $( '.survey-ifyes, .survey-ifno' ).hide(); |
62 | | - $( '.survey-yes, .survey-no' ).change( function() { |
63 | | - yesrow = $( '#' + $(this).attr( 'name' ) + '-ifyes-row' ); |
64 | | - norow = $( '#' + $(this).attr( 'name' ) + '-ifno-row' ); |
65 | | - if( $(this).is( '.survey-yes:checked' ) ) { |
66 | | - yesrow.slideDown( 'fast' ); |
67 | | - norow.slideUp( 'fast' ); |
68 | | - } else if( $(this).is( '.survey-no:checked' ) ) { |
69 | | - yesrow.slideUp( 'fast' ); |
70 | | - norow.slideDown( 'fast' ); |
71 | | - } |
72 | | - }); |
73 | | - // Load initial state |
74 | | - $( '.survey-yes, .survey-no' ).change(); |
75 | | - |
76 | | - var detected = optInGetPOSTData(); |
77 | | - // Detect screen resolution |
| 69 | + $j( '#survey-os' ).val( osIndex ); |
| 70 | + // Detect screen dimensions |
78 | 71 | if ( screen.width && screen.height ) { |
79 | | - $( '.optin-resolution-x' ).val( detected['survey-res-x'] ); |
80 | | - $( '.optin-resolution-y' ).val( detected['survey-res-y'] ); |
81 | | - // Hide the fields? |
| 72 | + $j( '.optin-resolution-x' ).val( screen.width ); |
| 73 | + $j( '.optin-resolution-y' ).val( screen.height ); |
82 | 74 | } |
83 | | - |
84 | | - $( '#survey-browser' ).val( detected['survey-browser'] ); |
85 | | - $( '#survey-os' ).val( detected['survey-os'] ); |
86 | 75 | }); |
Index: trunk/extensions/UsabilityInitiative/EditWarning/EditWarning.js |
— | — | @@ -1,15 +1,14 @@ |
2 | 2 | /* JavaScript for EditWarning extension */ |
3 | 3 | |
4 | | -$( document ).ready( function() { |
| 4 | +js2AddOnloadHook( function() { |
5 | 5 | // Only use this function in conjuction with the Vector skin |
6 | 6 | if( skin != 'vector' ) |
7 | 7 | return; |
8 | | - |
9 | 8 | // Get the original values of some form elements |
10 | | - $( '#wpTextbox1, #wpSummary' ).each( function() { |
11 | | - $(this).data( 'origtext', $(this).val() ); |
| 9 | + $j( '#wpTextbox1, #wpSummary' ).each( function() { |
| 10 | + $j(this).data( 'origtext', $j(this).val() ); |
12 | 11 | }); |
13 | | - |
| 12 | + // Attach our own handler for onbeforeunload which respects the current one |
14 | 13 | fallbackWindowOnBeforeUnload = window.onbeforeunload; |
15 | 14 | window.onbeforeunload = function() { |
16 | 15 | var fallbackResult = null; |
— | — | @@ -26,15 +25,15 @@ |
27 | 26 | // Check if the current values of some form elements are the same as |
28 | 27 | // the original values |
29 | 28 | if( |
30 | | - $( '#wpTextbox1' ).data( 'origtext' ) != $( '#wpTextbox1' ).val() || |
31 | | - $( '#wpSummary' ).data( 'origtext' ) != $( '#wpSummary' ).val() |
| 29 | + $j( '#wpTextbox1' ).data( 'origtext' ) != $j( '#wpTextbox1' ).val() |
| 30 | + || $j( '#wpSummary' ).data( 'origtext' ) != $j( '#wpSummary' ).val() |
32 | 31 | ) { |
33 | 32 | // Return our message |
34 | 33 | return gM( 'editwarning-warning' ); |
35 | 34 | } |
36 | 35 | } |
37 | 36 | // Add form submission handler |
38 | | - $( 'form' ).submit( function() { |
| 37 | + $j( 'form' ).submit( function() { |
39 | 38 | // Restore whatever previous onbeforeload hook existed |
40 | 39 | window.onbeforeunload = fallbackWindowOnBeforeUnload; |
41 | 40 | }); |
Index: trunk/extensions/UsabilityInitiative/js/messages.js |
— | — | @@ -1,42 +0,0 @@ |
2 | | -/* JavaScript for UsabilityInitiative extensions */ |
3 | | - |
4 | | -/** |
5 | | - * This is designed to be directly compatible with (and is essentially taken |
6 | | - * directly from) the mv_embed code for bringing internationalized messages into |
7 | | - * the JavaScript space. As such, if we get to the point of merging that stuff |
8 | | - * into the main branch this code will be uneeded and probably cause issues. |
9 | | - */ |
10 | | -// Creates global message object if not already in existence |
11 | | -if ( !gMsg ) var gMsg = {}; |
12 | | -/** |
13 | | - * Caches a list of messages for later retrieval |
14 | | - * @param {Object} msgSet Hash of key:value pairs of messages to cache |
15 | | - */ |
16 | | -function loadGM( msgSet ){ |
17 | | - for ( var i in msgSet ){ |
18 | | - gMsg[ i ] = msgSet[i]; |
19 | | - } |
20 | | -} |
21 | | -/** |
22 | | - * Retieves a message from the global message cache, performing on-the-fly |
23 | | - * replacements using MediaWiki message syntax ($1, $2, etc.) |
24 | | - * @param {String} key Name of message as it is in MediaWiki |
25 | | - * @param {Array} args Array of replacement arguments |
26 | | - */ |
27 | | -function gM( key, args ) { |
28 | | - var ms = ''; |
29 | | - if ( key in gMsg ) { |
30 | | - ms = gMsg[ key ]; |
31 | | - if ( typeof args == 'object' || typeof args == 'array' ) { |
32 | | - for ( var v in args ){ |
33 | | - var rep = '\$'+ ( parseInt(v) + 1 ); |
34 | | - ms = ms.replace( rep, args[v]); |
35 | | - } |
36 | | - } else if ( typeof args =='string' || typeof args =='number' ) { |
37 | | - ms = ms.replace( /\$1/, args ); |
38 | | - } |
39 | | - return ms; |
40 | | - } else { |
41 | | - return '[' + key + ']'; |
42 | | - } |
43 | | -} |
Index: trunk/extensions/UsabilityInitiative/js/jquery.combined.js |
— | — | @@ -4906,6 +4906,460 @@ |
4907 | 4907 | })(jQuery); |
4908 | 4908 | |
4909 | 4909 | /** |
| 4910 | + * This is the toolbar plugin, which can be used like |
| 4911 | + * $j( 'div#edittoolbar' ).toolbar( '#wpTextbox1', tools ); |
| 4912 | + * Where tools is an array of objects which describe each tool (see below for |
| 4913 | + * specific examples) (THIS NEEDS BETTER DOCUMENTATION WHEN I HAVE TIME) |
| 4914 | + */ |
| 4915 | +(function($){ $.fn.extend({ |
| 4916 | +/** |
| 4917 | + * Builds toolbar |
| 4918 | + * @param {Object} textbox |
| 4919 | + * @param {Object} tools |
| 4920 | + */ |
| 4921 | +toolbar: function( textbox, tools ) { |
| 4922 | + return this.each(function() { |
| 4923 | + if ( 'main' in tools ) { |
| 4924 | + $(this).addToolbarSection( tools.main, textbox, 'main' ); |
| 4925 | + } |
| 4926 | + var tabDiv = $( '<div></div>' ) |
| 4927 | + .attr( 'class', 'tabs' ) |
| 4928 | + .appendTo( $(this) ); |
| 4929 | + var sectionsDiv = $( '<div></div>' ) |
| 4930 | + .attr( 'class', 'sections' ) |
| 4931 | + .appendTo( $(this) ); |
| 4932 | + $(this).append( $( '<div></div>' ).addClass( 'break' ) ); |
| 4933 | + var sectionCookie = 'edittoolbar-' + $(this).attr( 'id' ) + '-section'; |
| 4934 | + var sectionQueue = []; |
| 4935 | + for ( section in tools ) { |
| 4936 | + if ( section == 'main' ) { |
| 4937 | + continue; |
| 4938 | + } |
| 4939 | + var sectionDiv = $( '<div></div>') |
| 4940 | + .attr( { |
| 4941 | + 'class': 'section', |
| 4942 | + 'id': $(this).attr( 'id' ) + '-section-' + section |
| 4943 | + } ) |
| 4944 | + .appendTo( sectionsDiv ) |
| 4945 | + .addClass( 'loading' ) |
| 4946 | + .append( |
| 4947 | + $( '<div></div>' ) |
| 4948 | + .addClass( 'progress' ) |
| 4949 | + .text( gM( 'edittoolbar-loading' ) |
| 4950 | + ) |
| 4951 | + ); |
| 4952 | + var current = false; |
| 4953 | + if ( $.cookie( sectionCookie ) == sectionDiv.attr( 'id' ) ) { |
| 4954 | + sectionDiv.attr( 'style', 'display:block' ); |
| 4955 | + current = true; |
| 4956 | + } |
| 4957 | + sectionQueue[sectionQueue.length] = { |
| 4958 | + 'sectionDiv': sectionDiv, |
| 4959 | + 'tools': tools[section], |
| 4960 | + 'textbox': textbox |
| 4961 | + }; |
| 4962 | + tabDiv.append( |
| 4963 | + $( '<span></span>' ) |
| 4964 | + .attr( 'class', 'tab' ) |
| 4965 | + .append( |
| 4966 | + $( '<a></a>' ) |
| 4967 | + .text( |
| 4968 | + tools[section].label || |
| 4969 | + gM( tools[section].labelMsg ) |
| 4970 | + ) |
| 4971 | + .attr( { |
| 4972 | + 'href': '#', |
| 4973 | + 'rel': section, |
| 4974 | + 'class': current ? 'current' : null |
| 4975 | + } ) |
| 4976 | + .data( 'sectionDiv', sectionDiv ) |
| 4977 | + .data( 'sectionCookie', sectionCookie ) |
| 4978 | + .data( 'textbox', textbox ) |
| 4979 | + .click( function() { |
| 4980 | + $(this).blur(); |
| 4981 | + var show = ( |
| 4982 | + $(this).data( 'sectionDiv' ) |
| 4983 | + .css( 'display' ) == 'none' |
| 4984 | + ); |
| 4985 | + $(this).data( 'sectionDiv' ) |
| 4986 | + .parent().children().hide(); |
| 4987 | + $(this) |
| 4988 | + .parent() |
| 4989 | + .parent() |
| 4990 | + .find( 'a' ) |
| 4991 | + .removeClass( 'current' ); |
| 4992 | + if ( show ) { |
| 4993 | + $(this).data( 'sectionDiv' ).show(); |
| 4994 | + $(this).addClass( 'current' ); |
| 4995 | + } |
| 4996 | + $.cookie( |
| 4997 | + $(this).data( 'sectionCookie' ), |
| 4998 | + show ? |
| 4999 | + $(this).data( 'sectionDiv' ) |
| 5000 | + .attr( 'id' ) |
| 5001 | + : null |
| 5002 | + ); |
| 5003 | + return false; |
| 5004 | + }) |
| 5005 | + ) |
| 5006 | + ); |
| 5007 | + } |
| 5008 | + $.eachAsync( sectionQueue, { |
| 5009 | + bulk: 0, |
| 5010 | + loop: function( index, value ) { |
| 5011 | + value.sectionDiv.addToolbarSection( |
| 5012 | + value.tools, value.textbox, index |
| 5013 | + ); |
| 5014 | + value.sectionDiv.removeClass( 'loading' ) |
| 5015 | + } |
| 5016 | + } ) |
| 5017 | + }); |
| 5018 | +}, |
| 5019 | +/** |
| 5020 | + * Adds a toolbar section to a containing div |
| 5021 | + * @param {Object} section Section data to build toolbar from |
| 5022 | + * @param {Object} textbox |
| 5023 | + * @param {String} section ID (used for cookies) |
| 5024 | + */ |
| 5025 | +addToolbarSection: function( section, textbox, id ) { |
| 5026 | + // Path to images (THIS WILL HAVE TO CHANGE IF YOU MOVE THIS INTO CORE) |
| 5027 | + var imagePath = wgScriptPath + |
| 5028 | + '/extensions/UsabilityInitiative/EditToolbar/images/'; |
| 5029 | + function msgSet( object, property ) { |
| 5030 | + return property in object || property + 'Msg' in object; |
| 5031 | + } |
| 5032 | + function msg( object, property ) { |
| 5033 | + return object[property] || gM( object[property + 'Msg'] ); |
| 5034 | + } |
| 5035 | + var action = function( event ) { |
| 5036 | + $(this).useTool( |
| 5037 | + $(this).data( 'context' ).tool, |
| 5038 | + $(this).data( 'context' ).textbox |
| 5039 | + ); |
| 5040 | + event.preventDefault(); |
| 5041 | + }; |
| 5042 | + switch ( section.type ) { |
| 5043 | + case 'toolbar': |
| 5044 | + if ( !( 'groups' in section ) ) { |
| 5045 | + return; |
| 5046 | + } |
| 5047 | + for ( group in section.groups ) { |
| 5048 | + var groupDiv = $( '<div></div>' ) |
| 5049 | + .attr( 'class', 'group' ) |
| 5050 | + .appendTo( $(this) ); |
| 5051 | + if ( msgSet( section.groups[group], 'label' ) ) { |
| 5052 | + groupDiv.append( |
| 5053 | + $( '<div></div>' ) |
| 5054 | + .attr( 'class', 'label' ) |
| 5055 | + .text( msg( section.groups[group], 'label' ) ) |
| 5056 | + ) |
| 5057 | + } |
| 5058 | + for ( tool in section.groups[group].tools ) { |
| 5059 | + if ( 'filters' in section.groups[group].tools[tool] ) { |
| 5060 | + var filters = section.groups[group].tools[tool].filters; |
| 5061 | + var skip = false; |
| 5062 | + for ( filter in filters ) { |
| 5063 | + if ( $( filters[filter] ).size() == 0 ) { |
| 5064 | + skip = true; |
| 5065 | + } |
| 5066 | + } |
| 5067 | + if ( skip ) { |
| 5068 | + continue; |
| 5069 | + } |
| 5070 | + } |
| 5071 | + var context = { |
| 5072 | + 'tool': section.groups[group].tools[tool], |
| 5073 | + 'textbox': textbox |
| 5074 | + }; |
| 5075 | + var label = |
| 5076 | + msg( section.groups[group].tools[tool], 'label' ); |
| 5077 | + switch ( section.groups[group].tools[tool].type ) { |
| 5078 | + case 'button': |
| 5079 | + groupDiv.append( |
| 5080 | + $( '<input />' ) |
| 5081 | + .attr( { |
| 5082 | + src: imagePath + |
| 5083 | + section.groups[group].tools[tool].icon, |
| 5084 | + alt: label, |
| 5085 | + title: label, |
| 5086 | + 'class': 'tool', |
| 5087 | + 'type': 'image' |
| 5088 | + } ) |
| 5089 | + .data( 'context', context ) |
| 5090 | + .click( action ) |
| 5091 | + ); |
| 5092 | + break; |
| 5093 | + case 'select': |
| 5094 | + var selectDiv = $( '<select></select>' ) |
| 5095 | + .data( 'context', context ) |
| 5096 | + .change( action ) |
| 5097 | + .append( |
| 5098 | + $( '<option></option>' ) .text( label ) |
| 5099 | + ) |
| 5100 | + .appendTo( groupDiv ); |
| 5101 | + for ( |
| 5102 | + option in section.groups[group].tools[tool].list |
| 5103 | + ) { |
| 5104 | + selectDiv.append( |
| 5105 | + $( '<option></option>' ) |
| 5106 | + .text( |
| 5107 | + msg( |
| 5108 | + section.groups[group] |
| 5109 | + .tools[tool].list[option], |
| 5110 | + 'label' |
| 5111 | + ) |
| 5112 | + ) |
| 5113 | + .attr( 'value', option ) |
| 5114 | + ); |
| 5115 | + } |
| 5116 | + break; |
| 5117 | + default: break; |
| 5118 | + } |
| 5119 | + } |
| 5120 | + } |
| 5121 | + break; |
| 5122 | + case 'booklet': |
| 5123 | + if ( !( 'pages' in section ) ) { |
| 5124 | + return; |
| 5125 | + } |
| 5126 | + var indexDiv = $( '<div></div>' ) |
| 5127 | + .attr( 'class', 'index' ) |
| 5128 | + .appendTo( $(this) ); |
| 5129 | + var bookletCookie = |
| 5130 | + 'edittoolbar-' + $(this).attr( 'id' ) + '-booklet-' + id; |
| 5131 | + var selectedID = $.cookie( bookletCookie ); |
| 5132 | + for ( page in section.pages ) { |
| 5133 | + if ( selectedID === null ) { |
| 5134 | + selectedID = page; |
| 5135 | + } |
| 5136 | + indexDiv.append( |
| 5137 | + $( '<div></div>' ) |
| 5138 | + .attr( 'class', page === selectedID ? 'current' : null ) |
| 5139 | + .text( msg( section.pages[page], 'label' ) ) |
| 5140 | + .data( 'page', page ) |
| 5141 | + .data( 'cookie', bookletCookie ) |
| 5142 | + .click( function() { |
| 5143 | + $(this) |
| 5144 | + .parent() |
| 5145 | + .parent() |
| 5146 | + .find( 'div.pages > div.page' ) |
| 5147 | + .hide() |
| 5148 | + .end() |
| 5149 | + .parent() |
| 5150 | + .find( 'div' ) |
| 5151 | + .removeClass( 'current' ) |
| 5152 | + .end() |
| 5153 | + .parent() |
| 5154 | + .parent() |
| 5155 | + .find( |
| 5156 | + 'div.pages > div.page-' + |
| 5157 | + $(this).data( 'page' ) |
| 5158 | + ) |
| 5159 | + .show() |
| 5160 | + .end() |
| 5161 | + .addClass( 'current' ); |
| 5162 | + $.cookie( |
| 5163 | + $(this).data( 'cookie'), $(this).data( 'page' ) |
| 5164 | + ); |
| 5165 | + } ) |
| 5166 | + ); |
| 5167 | + } |
| 5168 | + var pagesDiv = $( '<div></div>' ) |
| 5169 | + .attr( 'class', 'pages' ) |
| 5170 | + .appendTo( $(this) ); |
| 5171 | + for ( page in section.pages ) { |
| 5172 | + var pageDiv = $( '<div></div>' ) |
| 5173 | + .attr( 'class', 'page page-' + page ) |
| 5174 | + .css( 'display', page === selectedID ? 'block' : 'none' ) |
| 5175 | + .appendTo( pagesDiv ); |
| 5176 | + switch ( section.pages[page].layout ) { |
| 5177 | + case 'table': |
| 5178 | + var contentTable = $( '<table></table>' ) |
| 5179 | + .attr( { |
| 5180 | + 'cellpadding': '0', |
| 5181 | + 'cellspacing': '0', |
| 5182 | + 'border': '0', |
| 5183 | + 'width': '100%' |
| 5184 | + } ) |
| 5185 | + .appendTo( pageDiv ); |
| 5186 | + var headingRow = $( '<tr></tr>' ) |
| 5187 | + .appendTo( contentTable ); |
| 5188 | + for ( heading in section.pages[page].headings ) { |
| 5189 | + $( '<th></th>' ) |
| 5190 | + .text( |
| 5191 | + msg( |
| 5192 | + section.pages[page] |
| 5193 | + .headings[heading], |
| 5194 | + 'content' |
| 5195 | + ) |
| 5196 | + ) |
| 5197 | + .appendTo( headingRow ); |
| 5198 | + } |
| 5199 | + for ( row in section.pages[page].rows ) { |
| 5200 | + var contentRow = $( '<tr></tr>' ) |
| 5201 | + .appendTo( contentTable ); |
| 5202 | + for ( cell in section.pages[page].rows[row] ) { |
| 5203 | + $( '<td></td>' ) |
| 5204 | + .attr( { |
| 5205 | + 'class': cell, |
| 5206 | + 'valign': 'top' |
| 5207 | + } ) |
| 5208 | + .append( |
| 5209 | + $( '<span></span>' ) |
| 5210 | + .text( |
| 5211 | + msg( |
| 5212 | + section.pages[page] |
| 5213 | + .rows[row][cell], |
| 5214 | + 'content' |
| 5215 | + ) |
| 5216 | + ) |
| 5217 | + ) |
| 5218 | + .appendTo( contentRow ); |
| 5219 | + } |
| 5220 | + } |
| 5221 | + break; |
| 5222 | + case 'characters': |
| 5223 | + var charsDiv = $( '<div />' ) |
| 5224 | + .attr( section.pages[page].attributes ) |
| 5225 | + .css( section.pages[page].styles ) |
| 5226 | + .appendTo( pageDiv ); |
| 5227 | + for ( character in section.pages[page].characters ) { |
| 5228 | + switch ( |
| 5229 | + section.pages[page].characters[character].type |
| 5230 | + ) { |
| 5231 | + case 'link': |
| 5232 | + var context = { |
| 5233 | + 'tool' : section.pages[page] |
| 5234 | + .characters[character], |
| 5235 | + 'textbox': textbox |
| 5236 | + }; |
| 5237 | + charsDiv.append( |
| 5238 | + $( '<a />' ) |
| 5239 | + .attr( 'href', '#' ) |
| 5240 | + .text( |
| 5241 | + section.pages[page] |
| 5242 | + .characters[character].label |
| 5243 | + ) |
| 5244 | + .data( 'context', context) |
| 5245 | + .click( action ) |
| 5246 | + .click( |
| 5247 | + function() { return false; } |
| 5248 | + ) |
| 5249 | + ); |
| 5250 | + break; |
| 5251 | + } |
| 5252 | + } |
| 5253 | + break; |
| 5254 | + default: break; |
| 5255 | + } |
| 5256 | + } |
| 5257 | + break; |
| 5258 | + default: break; |
| 5259 | + } |
| 5260 | +}, |
| 5261 | +/** |
| 5262 | + * Performs action on a textbox using a tool |
| 5263 | + * @param {Object} tool |
| 5264 | + * @param {Object} textbox |
| 5265 | + */ |
| 5266 | +useTool: function( tool, textbox ) { |
| 5267 | + function performAction( action, textbox ) { |
| 5268 | + switch ( action.type) { |
| 5269 | + case 'encapsulate': |
| 5270 | + var parts = { 'pre': '', 'peri': '', 'post': '' }; |
| 5271 | + for ( part in parts ) { |
| 5272 | + if ( part + 'Msg' in action.options ) { |
| 5273 | + parts[part] = gM( |
| 5274 | + action.options[part + 'Msg'], |
| 5275 | + ( action.options[part] || null ) |
| 5276 | + ); |
| 5277 | + } else { |
| 5278 | + parts[part] = ( action.options[part] || '' ) |
| 5279 | + } |
| 5280 | + } |
| 5281 | + textbox.encapsulateSelection( |
| 5282 | + parts.pre, parts.peri, parts.post |
| 5283 | + ); |
| 5284 | + break; |
| 5285 | + default: break; |
| 5286 | + } |
| 5287 | + } |
| 5288 | + switch ( tool.type ) { |
| 5289 | + case 'button': |
| 5290 | + case 'link': |
| 5291 | + performAction( tool.action, textbox ); |
| 5292 | + break; |
| 5293 | + case 'select': |
| 5294 | + if ( $(this).val() in tool.list ) { |
| 5295 | + performAction( tool.list[$(this).val()].action, textbox ); |
| 5296 | + } |
| 5297 | + $(this).find(":selected").attr( 'selected', false ); |
| 5298 | + $(this).find(":first").attr( 'selected', true ); |
| 5299 | + break; |
| 5300 | + default: break; |
| 5301 | + } |
| 5302 | +}, |
| 5303 | + |
| 5304 | +/** |
| 5305 | + * Converts a charinsert array like the one used on dewiki to |
| 5306 | + * the format expected in editToolbarConfiguration |
| 5307 | + */ |
| 5308 | +parseCharinsert: function( charinsert ) { |
| 5309 | + var retval = {}; |
| 5310 | + for( page in charinsert ) { |
| 5311 | + var pageKey = page.replace(/[^A-Za-z]/g, '-'); |
| 5312 | + var characters = [], attributes = {}, styles = {}; |
| 5313 | + var i = 0; |
| 5314 | + for( line in charinsert[page] ) { |
| 5315 | + if( !( charinsert[page][line] instanceof Array ) ) { |
| 5316 | + for( attr in charinsert[page][line] ) { |
| 5317 | + switch( attr ) { |
| 5318 | + case 'class': |
| 5319 | + case 'lang': |
| 5320 | + attributes[attr] = charinsert[page][line][attr]; |
| 5321 | + break; |
| 5322 | + default: |
| 5323 | + styles[attr] = charinsert[page][line][attr]; |
| 5324 | + } |
| 5325 | + } |
| 5326 | + continue; |
| 5327 | + } |
| 5328 | + for( character in charinsert[page][line] ) { |
| 5329 | + var tool = { |
| 5330 | + type: 'link', |
| 5331 | + label: '', |
| 5332 | + action: { |
| 5333 | + type: 'encapsulate', |
| 5334 | + options: { |
| 5335 | + pre: '', |
| 5336 | + post: '' |
| 5337 | + } |
| 5338 | + } |
| 5339 | + }; |
| 5340 | + if( charinsert[page][line][character] instanceof Array ) { |
| 5341 | + tool.action.options.pre = |
| 5342 | + charinsert[page][line][character][0]; |
| 5343 | + tool.action.options.post = |
| 5344 | + charinsert[page][line][character][1]; |
| 5345 | + } else { |
| 5346 | + tool.action.options.pre = charinsert[page][line][character]; |
| 5347 | + } |
| 5348 | + tool.label = tool.action.options.pre + tool.action.options.post; |
| 5349 | + characters[i++] = tool; |
| 5350 | + } |
| 5351 | + } |
| 5352 | + retval[pageKey] = { |
| 5353 | + label: page, |
| 5354 | + layout: 'characters', |
| 5355 | + attributes: attributes, |
| 5356 | + styles: styles, |
| 5357 | + characters: characters |
| 5358 | + }; |
| 5359 | + } |
| 5360 | + return retval; |
| 5361 | +} |
| 5362 | + |
| 5363 | +}); })(jQuery);/** |
4910 | 5364 | * Plugin for parsing wikitext, building outlines, and keeping them up to date |
4911 | 5365 | */ |
4912 | 5366 | (function($){$.fn.extend({ |
Index: trunk/extensions/UsabilityInitiative/js/js2.js |
— | — | @@ -0,0 +1,53 @@ |
| 2 | +/* JavaScript for UsabilityInitiative extensions */ |
| 3 | + |
| 4 | +/** |
| 5 | + * This is designed to be directly compatible with (and is essentially taken |
| 6 | + * directly from) the mv_embed code for bringing internationalized messages into |
| 7 | + * the JavaScript space. As such, if we get to the point of merging that stuff |
| 8 | + * into the main branch this code will be uneeded and probably cause issues. |
| 9 | + */ |
| 10 | +// Creates global message object if not already in existence |
| 11 | +if ( !gMsg ) var gMsg = {}; |
| 12 | +/** |
| 13 | + * Caches a list of messages for later retrieval |
| 14 | + * @param {Object} msgSet Hash of key:value pairs of messages to cache |
| 15 | + */ |
| 16 | +function loadGM( msgSet ){ |
| 17 | + for ( var i in msgSet ){ |
| 18 | + gMsg[ i ] = msgSet[i]; |
| 19 | + } |
| 20 | +} |
| 21 | +/** |
| 22 | + * Retieves a message from the global message cache, performing on-the-fly |
| 23 | + * replacements using MediaWiki message syntax ($1, $2, etc.) |
| 24 | + * @param {String} key Name of message as it is in MediaWiki |
| 25 | + * @param {Array} args Array of replacement arguments |
| 26 | + */ |
| 27 | +function gM( key, args ) { |
| 28 | + var ms = ''; |
| 29 | + if ( key in gMsg ) { |
| 30 | + ms = gMsg[ key ]; |
| 31 | + if ( typeof args == 'object' || typeof args == 'array' ) { |
| 32 | + for ( var v in args ){ |
| 33 | + var rep = '\$'+ ( parseInt(v) + 1 ); |
| 34 | + ms = ms.replace( rep, args[v]); |
| 35 | + } |
| 36 | + } else if ( typeof args =='string' || typeof args =='number' ) { |
| 37 | + ms = ms.replace( /\$1/, args ); |
| 38 | + } |
| 39 | + return ms; |
| 40 | + } else { |
| 41 | + return '[' + key + ']'; |
| 42 | + } |
| 43 | +} |
| 44 | +/** |
| 45 | + * Mimics the no-conflict method used by the js2 stuff |
| 46 | + */ |
| 47 | +$j = jQuery.noConflict(); |
| 48 | +/** |
| 49 | + * Provides js2 compatible onload hook |
| 50 | + * @param func Function to call when ready |
| 51 | + */ |
| 52 | +function js2AddOnloadHook( func ) { |
| 53 | + $j(document).ready( func ); |
| 54 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/UsabilityInitiative/js/js2.js |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 55 | + native |
Index: trunk/extensions/UsabilityInitiative/js/jquery.combined.min.js |
— | — | @@ -476,7 +476,37 @@ |
477 | 477 | return($.os.name=='mac'?13:($.os.name=='linux'?15:16))*row;} |
478 | 478 | return this.each(function(){$(this).focus();if(this.selectionStart||this.selectionStart=='0'){this.selectionStart=this.selectionEnd=pos;$(this).scrollTop(getCaretPosition(this));}else if(document.selection&&document.selection.createRange){range=document.selection.createRange();oldPos=$(this).bytePos();goBack=false;if(oldPos==pos){pos++;goBack=true;} |
479 | 479 | range.moveToElementText(this);range.collapse();range.move('character',pos);range.select();this.scrollTop+=range.offsetTop;if(goBack){range.move('character',-1);range.select();}} |
480 | | -$(this).trigger('scrollToPosition');});}});})(jQuery);(function($){$.fn.extend({parseOutline:function(){return this.each(function(){var wikitext='\n'+$(this).val()+'\n';var headings=wikitext.match(/\n={1,5}.*={1,5}(?=\n)/g);var outline=[];var offset=0;for(var h=0;h<headings.length;h++){text=headings[h];var position=wikitext.indexOf(text,offset);if(position>offset){offset=position;}else if(position==-1){continue;} |
| 480 | +$(this).trigger('scrollToPosition');});}});})(jQuery);(function($){$.fn.extend({toolbar:function(textbox,tools){return this.each(function(){if('main'in tools){$(this).addToolbarSection(tools.main,textbox,'main');} |
| 481 | +var tabDiv=$('<div></div>').attr('class','tabs').appendTo($(this));var sectionsDiv=$('<div></div>').attr('class','sections').appendTo($(this));$(this).append($('<div></div>').addClass('break'));var sectionCookie='edittoolbar-'+$(this).attr('id')+'-section';var sectionQueue=[];for(section in tools){if(section=='main'){continue;} |
| 482 | +var sectionDiv=$('<div></div>').attr({'class':'section','id':$(this).attr('id')+'-section-'+section}).appendTo(sectionsDiv).addClass('loading').append($('<div></div>').addClass('progress').text(gM('edittoolbar-loading')));var current=false;if($.cookie(sectionCookie)==sectionDiv.attr('id')){sectionDiv.attr('style','display:block');current=true;} |
| 483 | +sectionQueue[sectionQueue.length]={'sectionDiv':sectionDiv,'tools':tools[section],'textbox':textbox};tabDiv.append($('<span></span>').attr('class','tab').append($('<a></a>').text(tools[section].label||gM(tools[section].labelMsg)).attr({'href':'#','rel':section,'class':current?'current':null}).data('sectionDiv',sectionDiv).data('sectionCookie',sectionCookie).data('textbox',textbox).click(function(){$(this).blur();var show=($(this).data('sectionDiv').css('display')=='none');$(this).data('sectionDiv').parent().children().hide();$(this).parent().parent().find('a').removeClass('current');if(show){$(this).data('sectionDiv').show();$(this).addClass('current');} |
| 484 | +$.cookie($(this).data('sectionCookie'),show?$(this).data('sectionDiv').attr('id'):null);return false;})));} |
| 485 | +$.eachAsync(sectionQueue,{bulk:0,loop:function(index,value){value.sectionDiv.addToolbarSection(value.tools,value.textbox,index);value.sectionDiv.removeClass('loading')}})});},addToolbarSection:function(section,textbox,id){var imagePath=wgScriptPath+'/extensions/UsabilityInitiative/EditToolbar/images/';function msgSet(object,property){return property in object||property+'Msg'in object;} |
| 486 | +function msg(object,property){return object[property]||gM(object[property+'Msg']);} |
| 487 | +var action=function(event){$(this).useTool($(this).data('context').tool,$(this).data('context').textbox);event.preventDefault();};switch(section.type){case'toolbar':if(!('groups'in section)){return;} |
| 488 | +for(group in section.groups){var groupDiv=$('<div></div>').attr('class','group').appendTo($(this));if(msgSet(section.groups[group],'label')){groupDiv.append($('<div></div>').attr('class','label').text(msg(section.groups[group],'label')))} |
| 489 | +for(tool in section.groups[group].tools){if('filters'in section.groups[group].tools[tool]){var filters=section.groups[group].tools[tool].filters;var skip=false;for(filter in filters){if($(filters[filter]).size()==0){skip=true;}} |
| 490 | +if(skip){continue;}} |
| 491 | +var context={'tool':section.groups[group].tools[tool],'textbox':textbox};var label=msg(section.groups[group].tools[tool],'label');switch(section.groups[group].tools[tool].type){case'button':groupDiv.append($('<input />').attr({src:imagePath+ |
| 492 | +section.groups[group].tools[tool].icon,alt:label,title:label,'class':'tool','type':'image'}).data('context',context).click(action));break;case'select':var selectDiv=$('<select></select>').data('context',context).change(action).append($('<option></option>').text(label)).appendTo(groupDiv);for(option in section.groups[group].tools[tool].list){selectDiv.append($('<option></option>').text(msg(section.groups[group].tools[tool].list[option],'label')).attr('value',option));} |
| 493 | +break;default:break;}}} |
| 494 | +break;case'booklet':if(!('pages'in section)){return;} |
| 495 | +var indexDiv=$('<div></div>').attr('class','index').appendTo($(this));var bookletCookie='edittoolbar-'+$(this).attr('id')+'-booklet-'+id;var selectedID=$.cookie(bookletCookie);for(page in section.pages){if(selectedID===null){selectedID=page;} |
| 496 | +indexDiv.append($('<div></div>').attr('class',page===selectedID?'current':null).text(msg(section.pages[page],'label')).data('page',page).data('cookie',bookletCookie).click(function(){$(this).parent().parent().find('div.pages > div.page').hide().end().parent().find('div').removeClass('current').end().parent().parent().find('div.pages > div.page-'+ |
| 497 | +$(this).data('page')).show().end().addClass('current');$.cookie($(this).data('cookie'),$(this).data('page'));}));} |
| 498 | +var pagesDiv=$('<div></div>').attr('class','pages').appendTo($(this));for(page in section.pages){var pageDiv=$('<div></div>').attr('class','page page-'+page).css('display',page===selectedID?'block':'none').appendTo(pagesDiv);switch(section.pages[page].layout){case'table':var contentTable=$('<table></table>').attr({'cellpadding':'0','cellspacing':'0','border':'0','width':'100%'}).appendTo(pageDiv);var headingRow=$('<tr></tr>').appendTo(contentTable);for(heading in section.pages[page].headings){$('<th></th>').text(msg(section.pages[page].headings[heading],'content')).appendTo(headingRow);} |
| 499 | +for(row in section.pages[page].rows){var contentRow=$('<tr></tr>').appendTo(contentTable);for(cell in section.pages[page].rows[row]){$('<td></td>').attr({'class':cell,'valign':'top'}).append($('<span></span>').text(msg(section.pages[page].rows[row][cell],'content'))).appendTo(contentRow);}} |
| 500 | +break;case'characters':var charsDiv=$('<div />').attr(section.pages[page].attributes).css(section.pages[page].styles).appendTo(pageDiv);for(character in section.pages[page].characters){switch(section.pages[page].characters[character].type){case'link':var context={'tool':section.pages[page].characters[character],'textbox':textbox};charsDiv.append($('<a />').attr('href','#').text(section.pages[page].characters[character].label).data('context',context).click(action).click(function(){return false;}));break;}} |
| 501 | +break;default:break;}} |
| 502 | +break;default:break;}},useTool:function(tool,textbox){function performAction(action,textbox){switch(action.type){case'encapsulate':var parts={'pre':'','peri':'','post':''};for(part in parts){if(part+'Msg'in action.options){parts[part]=gM(action.options[part+'Msg'],(action.options[part]||null));}else{parts[part]=(action.options[part]||'')}} |
| 503 | +textbox.encapsulateSelection(parts.pre,parts.peri,parts.post);break;default:break;}} |
| 504 | +switch(tool.type){case'button':case'link':performAction(tool.action,textbox);break;case'select':if($(this).val()in tool.list){performAction(tool.list[$(this).val()].action,textbox);} |
| 505 | +$(this).find(":selected").attr('selected',false);$(this).find(":first").attr('selected',true);break;default:break;}},parseCharinsert:function(charinsert){var retval={};for(page in charinsert){var pageKey=page.replace(/[^A-Za-z]/g,'-');var characters=[],attributes={},styles={};var i=0;for(line in charinsert[page]){if(!(charinsert[page][line]instanceof Array)){for(attr in charinsert[page][line]){switch(attr){case'class':case'lang':attributes[attr]=charinsert[page][line][attr];break;default:styles[attr]=charinsert[page][line][attr];}} |
| 506 | +continue;} |
| 507 | +for(character in charinsert[page][line]){var tool={type:'link',label:'',action:{type:'encapsulate',options:{pre:'',post:''}}};if(charinsert[page][line][character]instanceof Array){tool.action.options.pre=charinsert[page][line][character][0];tool.action.options.post=charinsert[page][line][character][1];}else{tool.action.options.pre=charinsert[page][line][character];} |
| 508 | +tool.label=tool.action.options.pre+tool.action.options.post;characters[i++]=tool;}} |
| 509 | +retval[pageKey]={label:page,layout:'characters',attributes:attributes,styles:styles,characters:characters};} |
| 510 | +return retval;}});})(jQuery);(function($){$.fn.extend({parseOutline:function(){return this.each(function(){var wikitext='\n'+$(this).val()+'\n';var headings=wikitext.match(/\n={1,5}.*={1,5}(?=\n)/g);var outline=[];var offset=0;for(var h=0;h<headings.length;h++){text=headings[h];var position=wikitext.indexOf(text,offset);if(position>offset){offset=position;}else if(position==-1){continue;} |
481 | 511 | text=$.trim(text);var startLevel=0;for(var c=0;c<text.length;c++){if(text.charAt(c)=='='){startLevel++;}else{break;}} |
482 | 512 | var endLevel=0;for(var c=text.length-1;c>=0;c--){if(text.charAt(c)=='='){endLevel++;}else{break;}} |
483 | 513 | var level=Math.min(startLevel,endLevel);text=$.trim(text.substr(level,text.length-(level*2)));outline[h]={'text':text,'position':position,'level':level,'index':h};} |
Index: trunk/extensions/UsabilityInitiative/js/jquery.toolbar.js |
— | — | @@ -0,0 +1,455 @@ |
| 2 | +/** |
| 3 | + * This is the toolbar plugin, which can be used like |
| 4 | + * $j( 'div#edittoolbar' ).toolbar( '#wpTextbox1', tools ); |
| 5 | + * Where tools is an array of objects which describe each tool (see below for |
| 6 | + * specific examples) (THIS NEEDS BETTER DOCUMENTATION WHEN I HAVE TIME) |
| 7 | + */ |
| 8 | +(function($){ $.fn.extend({ |
| 9 | +/** |
| 10 | + * Builds toolbar |
| 11 | + * @param {Object} textbox |
| 12 | + * @param {Object} tools |
| 13 | + */ |
| 14 | +toolbar: function( textbox, tools ) { |
| 15 | + return this.each(function() { |
| 16 | + if ( 'main' in tools ) { |
| 17 | + $(this).addToolbarSection( tools.main, textbox, 'main' ); |
| 18 | + } |
| 19 | + var tabDiv = $( '<div></div>' ) |
| 20 | + .attr( 'class', 'tabs' ) |
| 21 | + .appendTo( $(this) ); |
| 22 | + var sectionsDiv = $( '<div></div>' ) |
| 23 | + .attr( 'class', 'sections' ) |
| 24 | + .appendTo( $(this) ); |
| 25 | + $(this).append( $( '<div></div>' ).addClass( 'break' ) ); |
| 26 | + var sectionCookie = 'edittoolbar-' + $(this).attr( 'id' ) + '-section'; |
| 27 | + var sectionQueue = []; |
| 28 | + for ( section in tools ) { |
| 29 | + if ( section == 'main' ) { |
| 30 | + continue; |
| 31 | + } |
| 32 | + var sectionDiv = $( '<div></div>') |
| 33 | + .attr( { |
| 34 | + 'class': 'section', |
| 35 | + 'id': $(this).attr( 'id' ) + '-section-' + section |
| 36 | + } ) |
| 37 | + .appendTo( sectionsDiv ) |
| 38 | + .addClass( 'loading' ) |
| 39 | + .append( |
| 40 | + $( '<div></div>' ) |
| 41 | + .addClass( 'progress' ) |
| 42 | + .text( gM( 'edittoolbar-loading' ) |
| 43 | + ) |
| 44 | + ); |
| 45 | + var current = false; |
| 46 | + if ( $.cookie( sectionCookie ) == sectionDiv.attr( 'id' ) ) { |
| 47 | + sectionDiv.attr( 'style', 'display:block' ); |
| 48 | + current = true; |
| 49 | + } |
| 50 | + sectionQueue[sectionQueue.length] = { |
| 51 | + 'sectionDiv': sectionDiv, |
| 52 | + 'tools': tools[section], |
| 53 | + 'textbox': textbox |
| 54 | + }; |
| 55 | + tabDiv.append( |
| 56 | + $( '<span></span>' ) |
| 57 | + .attr( 'class', 'tab' ) |
| 58 | + .append( |
| 59 | + $( '<a></a>' ) |
| 60 | + .text( |
| 61 | + tools[section].label || |
| 62 | + gM( tools[section].labelMsg ) |
| 63 | + ) |
| 64 | + .attr( { |
| 65 | + 'href': '#', |
| 66 | + 'rel': section, |
| 67 | + 'class': current ? 'current' : null |
| 68 | + } ) |
| 69 | + .data( 'sectionDiv', sectionDiv ) |
| 70 | + .data( 'sectionCookie', sectionCookie ) |
| 71 | + .data( 'textbox', textbox ) |
| 72 | + .click( function() { |
| 73 | + $(this).blur(); |
| 74 | + var show = ( |
| 75 | + $(this).data( 'sectionDiv' ) |
| 76 | + .css( 'display' ) == 'none' |
| 77 | + ); |
| 78 | + $(this).data( 'sectionDiv' ) |
| 79 | + .parent().children().hide(); |
| 80 | + $(this) |
| 81 | + .parent() |
| 82 | + .parent() |
| 83 | + .find( 'a' ) |
| 84 | + .removeClass( 'current' ); |
| 85 | + if ( show ) { |
| 86 | + $(this).data( 'sectionDiv' ).show(); |
| 87 | + $(this).addClass( 'current' ); |
| 88 | + } |
| 89 | + $.cookie( |
| 90 | + $(this).data( 'sectionCookie' ), |
| 91 | + show ? |
| 92 | + $(this).data( 'sectionDiv' ) |
| 93 | + .attr( 'id' ) |
| 94 | + : null |
| 95 | + ); |
| 96 | + return false; |
| 97 | + }) |
| 98 | + ) |
| 99 | + ); |
| 100 | + } |
| 101 | + $.eachAsync( sectionQueue, { |
| 102 | + bulk: 0, |
| 103 | + loop: function( index, value ) { |
| 104 | + value.sectionDiv.addToolbarSection( |
| 105 | + value.tools, value.textbox, index |
| 106 | + ); |
| 107 | + value.sectionDiv.removeClass( 'loading' ) |
| 108 | + } |
| 109 | + } ) |
| 110 | + }); |
| 111 | +}, |
| 112 | +/** |
| 113 | + * Adds a toolbar section to a containing div |
| 114 | + * @param {Object} section Section data to build toolbar from |
| 115 | + * @param {Object} textbox |
| 116 | + * @param {String} section ID (used for cookies) |
| 117 | + */ |
| 118 | +addToolbarSection: function( section, textbox, id ) { |
| 119 | + // Path to images (THIS WILL HAVE TO CHANGE IF YOU MOVE THIS INTO CORE) |
| 120 | + var imagePath = wgScriptPath + |
| 121 | + '/extensions/UsabilityInitiative/EditToolbar/images/'; |
| 122 | + function msgSet( object, property ) { |
| 123 | + return property in object || property + 'Msg' in object; |
| 124 | + } |
| 125 | + function msg( object, property ) { |
| 126 | + return object[property] || gM( object[property + 'Msg'] ); |
| 127 | + } |
| 128 | + var action = function( event ) { |
| 129 | + $(this).useTool( |
| 130 | + $(this).data( 'context' ).tool, |
| 131 | + $(this).data( 'context' ).textbox |
| 132 | + ); |
| 133 | + event.preventDefault(); |
| 134 | + }; |
| 135 | + switch ( section.type ) { |
| 136 | + case 'toolbar': |
| 137 | + if ( !( 'groups' in section ) ) { |
| 138 | + return; |
| 139 | + } |
| 140 | + for ( group in section.groups ) { |
| 141 | + var groupDiv = $( '<div></div>' ) |
| 142 | + .attr( 'class', 'group' ) |
| 143 | + .appendTo( $(this) ); |
| 144 | + if ( msgSet( section.groups[group], 'label' ) ) { |
| 145 | + groupDiv.append( |
| 146 | + $( '<div></div>' ) |
| 147 | + .attr( 'class', 'label' ) |
| 148 | + .text( msg( section.groups[group], 'label' ) ) |
| 149 | + ) |
| 150 | + } |
| 151 | + for ( tool in section.groups[group].tools ) { |
| 152 | + if ( 'filters' in section.groups[group].tools[tool] ) { |
| 153 | + var filters = section.groups[group].tools[tool].filters; |
| 154 | + var skip = false; |
| 155 | + for ( filter in filters ) { |
| 156 | + if ( $( filters[filter] ).size() == 0 ) { |
| 157 | + skip = true; |
| 158 | + } |
| 159 | + } |
| 160 | + if ( skip ) { |
| 161 | + continue; |
| 162 | + } |
| 163 | + } |
| 164 | + var context = { |
| 165 | + 'tool': section.groups[group].tools[tool], |
| 166 | + 'textbox': textbox |
| 167 | + }; |
| 168 | + var label = |
| 169 | + msg( section.groups[group].tools[tool], 'label' ); |
| 170 | + switch ( section.groups[group].tools[tool].type ) { |
| 171 | + case 'button': |
| 172 | + groupDiv.append( |
| 173 | + $( '<input />' ) |
| 174 | + .attr( { |
| 175 | + src: imagePath + |
| 176 | + section.groups[group].tools[tool].icon, |
| 177 | + alt: label, |
| 178 | + title: label, |
| 179 | + 'class': 'tool', |
| 180 | + 'type': 'image' |
| 181 | + } ) |
| 182 | + .data( 'context', context ) |
| 183 | + .click( action ) |
| 184 | + ); |
| 185 | + break; |
| 186 | + case 'select': |
| 187 | + var selectDiv = $( '<select></select>' ) |
| 188 | + .data( 'context', context ) |
| 189 | + .change( action ) |
| 190 | + .append( |
| 191 | + $( '<option></option>' ) .text( label ) |
| 192 | + ) |
| 193 | + .appendTo( groupDiv ); |
| 194 | + for ( |
| 195 | + option in section.groups[group].tools[tool].list |
| 196 | + ) { |
| 197 | + selectDiv.append( |
| 198 | + $( '<option></option>' ) |
| 199 | + .text( |
| 200 | + msg( |
| 201 | + section.groups[group] |
| 202 | + .tools[tool].list[option], |
| 203 | + 'label' |
| 204 | + ) |
| 205 | + ) |
| 206 | + .attr( 'value', option ) |
| 207 | + ); |
| 208 | + } |
| 209 | + break; |
| 210 | + default: break; |
| 211 | + } |
| 212 | + } |
| 213 | + } |
| 214 | + break; |
| 215 | + case 'booklet': |
| 216 | + if ( !( 'pages' in section ) ) { |
| 217 | + return; |
| 218 | + } |
| 219 | + var indexDiv = $( '<div></div>' ) |
| 220 | + .attr( 'class', 'index' ) |
| 221 | + .appendTo( $(this) ); |
| 222 | + var bookletCookie = |
| 223 | + 'edittoolbar-' + $(this).attr( 'id' ) + '-booklet-' + id; |
| 224 | + var selectedID = $.cookie( bookletCookie ); |
| 225 | + for ( page in section.pages ) { |
| 226 | + if ( selectedID === null ) { |
| 227 | + selectedID = page; |
| 228 | + } |
| 229 | + indexDiv.append( |
| 230 | + $( '<div></div>' ) |
| 231 | + .attr( 'class', page === selectedID ? 'current' : null ) |
| 232 | + .text( msg( section.pages[page], 'label' ) ) |
| 233 | + .data( 'page', page ) |
| 234 | + .data( 'cookie', bookletCookie ) |
| 235 | + .click( function() { |
| 236 | + $(this) |
| 237 | + .parent() |
| 238 | + .parent() |
| 239 | + .find( 'div.pages > div.page' ) |
| 240 | + .hide() |
| 241 | + .end() |
| 242 | + .parent() |
| 243 | + .find( 'div' ) |
| 244 | + .removeClass( 'current' ) |
| 245 | + .end() |
| 246 | + .parent() |
| 247 | + .parent() |
| 248 | + .find( |
| 249 | + 'div.pages > div.page-' + |
| 250 | + $(this).data( 'page' ) |
| 251 | + ) |
| 252 | + .show() |
| 253 | + .end() |
| 254 | + .addClass( 'current' ); |
| 255 | + $.cookie( |
| 256 | + $(this).data( 'cookie'), $(this).data( 'page' ) |
| 257 | + ); |
| 258 | + } ) |
| 259 | + ); |
| 260 | + } |
| 261 | + var pagesDiv = $( '<div></div>' ) |
| 262 | + .attr( 'class', 'pages' ) |
| 263 | + .appendTo( $(this) ); |
| 264 | + for ( page in section.pages ) { |
| 265 | + var pageDiv = $( '<div></div>' ) |
| 266 | + .attr( 'class', 'page page-' + page ) |
| 267 | + .css( 'display', page === selectedID ? 'block' : 'none' ) |
| 268 | + .appendTo( pagesDiv ); |
| 269 | + switch ( section.pages[page].layout ) { |
| 270 | + case 'table': |
| 271 | + var contentTable = $( '<table></table>' ) |
| 272 | + .attr( { |
| 273 | + 'cellpadding': '0', |
| 274 | + 'cellspacing': '0', |
| 275 | + 'border': '0', |
| 276 | + 'width': '100%' |
| 277 | + } ) |
| 278 | + .appendTo( pageDiv ); |
| 279 | + var headingRow = $( '<tr></tr>' ) |
| 280 | + .appendTo( contentTable ); |
| 281 | + for ( heading in section.pages[page].headings ) { |
| 282 | + $( '<th></th>' ) |
| 283 | + .text( |
| 284 | + msg( |
| 285 | + section.pages[page] |
| 286 | + .headings[heading], |
| 287 | + 'content' |
| 288 | + ) |
| 289 | + ) |
| 290 | + .appendTo( headingRow ); |
| 291 | + } |
| 292 | + for ( row in section.pages[page].rows ) { |
| 293 | + var contentRow = $( '<tr></tr>' ) |
| 294 | + .appendTo( contentTable ); |
| 295 | + for ( cell in section.pages[page].rows[row] ) { |
| 296 | + $( '<td></td>' ) |
| 297 | + .attr( { |
| 298 | + 'class': cell, |
| 299 | + 'valign': 'top' |
| 300 | + } ) |
| 301 | + .append( |
| 302 | + $( '<span></span>' ) |
| 303 | + .text( |
| 304 | + msg( |
| 305 | + section.pages[page] |
| 306 | + .rows[row][cell], |
| 307 | + 'content' |
| 308 | + ) |
| 309 | + ) |
| 310 | + ) |
| 311 | + .appendTo( contentRow ); |
| 312 | + } |
| 313 | + } |
| 314 | + break; |
| 315 | + case 'characters': |
| 316 | + var charsDiv = $( '<div />' ) |
| 317 | + .attr( section.pages[page].attributes ) |
| 318 | + .css( section.pages[page].styles ) |
| 319 | + .appendTo( pageDiv ); |
| 320 | + for ( character in section.pages[page].characters ) { |
| 321 | + switch ( |
| 322 | + section.pages[page].characters[character].type |
| 323 | + ) { |
| 324 | + case 'link': |
| 325 | + var context = { |
| 326 | + 'tool' : section.pages[page] |
| 327 | + .characters[character], |
| 328 | + 'textbox': textbox |
| 329 | + }; |
| 330 | + charsDiv.append( |
| 331 | + $( '<a />' ) |
| 332 | + .attr( 'href', '#' ) |
| 333 | + .text( |
| 334 | + section.pages[page] |
| 335 | + .characters[character].label |
| 336 | + ) |
| 337 | + .data( 'context', context) |
| 338 | + .click( action ) |
| 339 | + .click( |
| 340 | + function() { return false; } |
| 341 | + ) |
| 342 | + ); |
| 343 | + break; |
| 344 | + } |
| 345 | + } |
| 346 | + break; |
| 347 | + default: break; |
| 348 | + } |
| 349 | + } |
| 350 | + break; |
| 351 | + default: break; |
| 352 | + } |
| 353 | +}, |
| 354 | +/** |
| 355 | + * Performs action on a textbox using a tool |
| 356 | + * @param {Object} tool |
| 357 | + * @param {Object} textbox |
| 358 | + */ |
| 359 | +useTool: function( tool, textbox ) { |
| 360 | + function performAction( action, textbox ) { |
| 361 | + switch ( action.type) { |
| 362 | + case 'encapsulate': |
| 363 | + var parts = { 'pre': '', 'peri': '', 'post': '' }; |
| 364 | + for ( part in parts ) { |
| 365 | + if ( part + 'Msg' in action.options ) { |
| 366 | + parts[part] = gM( |
| 367 | + action.options[part + 'Msg'], |
| 368 | + ( action.options[part] || null ) |
| 369 | + ); |
| 370 | + } else { |
| 371 | + parts[part] = ( action.options[part] || '' ) |
| 372 | + } |
| 373 | + } |
| 374 | + textbox.encapsulateSelection( |
| 375 | + parts.pre, parts.peri, parts.post |
| 376 | + ); |
| 377 | + break; |
| 378 | + default: break; |
| 379 | + } |
| 380 | + } |
| 381 | + switch ( tool.type ) { |
| 382 | + case 'button': |
| 383 | + case 'link': |
| 384 | + performAction( tool.action, textbox ); |
| 385 | + break; |
| 386 | + case 'select': |
| 387 | + if ( $(this).val() in tool.list ) { |
| 388 | + performAction( tool.list[$(this).val()].action, textbox ); |
| 389 | + } |
| 390 | + $(this).find(":selected").attr( 'selected', false ); |
| 391 | + $(this).find(":first").attr( 'selected', true ); |
| 392 | + break; |
| 393 | + default: break; |
| 394 | + } |
| 395 | +}, |
| 396 | + |
| 397 | +/** |
| 398 | + * Converts a charinsert array like the one used on dewiki to |
| 399 | + * the format expected in editToolbarConfiguration |
| 400 | + */ |
| 401 | +parseCharinsert: function( charinsert ) { |
| 402 | + var retval = {}; |
| 403 | + for( page in charinsert ) { |
| 404 | + var pageKey = page.replace(/[^A-Za-z]/g, '-'); |
| 405 | + var characters = [], attributes = {}, styles = {}; |
| 406 | + var i = 0; |
| 407 | + for( line in charinsert[page] ) { |
| 408 | + if( !( charinsert[page][line] instanceof Array ) ) { |
| 409 | + for( attr in charinsert[page][line] ) { |
| 410 | + switch( attr ) { |
| 411 | + case 'class': |
| 412 | + case 'lang': |
| 413 | + attributes[attr] = charinsert[page][line][attr]; |
| 414 | + break; |
| 415 | + default: |
| 416 | + styles[attr] = charinsert[page][line][attr]; |
| 417 | + } |
| 418 | + } |
| 419 | + continue; |
| 420 | + } |
| 421 | + for( character in charinsert[page][line] ) { |
| 422 | + var tool = { |
| 423 | + type: 'link', |
| 424 | + label: '', |
| 425 | + action: { |
| 426 | + type: 'encapsulate', |
| 427 | + options: { |
| 428 | + pre: '', |
| 429 | + post: '' |
| 430 | + } |
| 431 | + } |
| 432 | + }; |
| 433 | + if( charinsert[page][line][character] instanceof Array ) { |
| 434 | + tool.action.options.pre = |
| 435 | + charinsert[page][line][character][0]; |
| 436 | + tool.action.options.post = |
| 437 | + charinsert[page][line][character][1]; |
| 438 | + } else { |
| 439 | + tool.action.options.pre = charinsert[page][line][character]; |
| 440 | + } |
| 441 | + tool.label = tool.action.options.pre + tool.action.options.post; |
| 442 | + characters[i++] = tool; |
| 443 | + } |
| 444 | + } |
| 445 | + retval[pageKey] = { |
| 446 | + label: page, |
| 447 | + layout: 'characters', |
| 448 | + attributes: attributes, |
| 449 | + styles: styles, |
| 450 | + characters: characters |
| 451 | + }; |
| 452 | + } |
| 453 | + return retval; |
| 454 | +} |
| 455 | + |
| 456 | +}); })(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.js |
— | — | @@ -1,14 +1,14 @@ |
2 | 2 | /* JavaScript for NavigableTOC extension */ |
3 | 3 | |
4 | | -jQuery( document ).ready( function() { |
5 | | - var list = $( '<div></div>' ) |
| 4 | +js2AddOnloadHook( function() { |
| 5 | + var list = $j( '<div></div>' ) |
6 | 6 | .attr( 'id', 'edit-toc' ) |
7 | | - .appendTo( $( 'div#edit-ui-right' ) ); |
8 | | - $( '#wpTextbox1' ) |
| 7 | + .appendTo( $j( 'div#edit-ui-right' ) ); |
| 8 | + $j( '#wpTextbox1' ) |
9 | 9 | .eachAsync( { |
10 | 10 | bulk: 0, |
11 | 11 | loop: function() { |
12 | | - $(this) |
| 12 | + $j(this) |
13 | 13 | .parseOutline() |
14 | 14 | .buildOutline( list ) |
15 | 15 | .updateOutline( list ); |
— | — | @@ -16,10 +16,10 @@ |
17 | 17 | } ) |
18 | 18 | .bind( 'keyup encapsulateSelection', { 'list': list }, |
19 | 19 | function( event ) { |
20 | | - $(this).eachAsync( { |
| 20 | + $j(this).eachAsync( { |
21 | 21 | bulk: 0, |
22 | 22 | loop: function() { |
23 | | - $(this) |
| 23 | + $j(this) |
24 | 24 | .parseOutline() |
25 | 25 | .buildOutline( event.data.list ) |
26 | 26 | .updateOutline( event.data.list ); |
— | — | @@ -29,10 +29,10 @@ |
30 | 30 | ) |
31 | 31 | .bind( 'mouseup scrollToPosition', { 'list': list }, |
32 | 32 | function( event ) { |
33 | | - $(this).eachAsync( { |
| 33 | + $j(this).eachAsync( { |
34 | 34 | bulk: 0, |
35 | 35 | loop: function() { |
36 | | - $(this).updateOutline( event.data.list ) |
| 36 | + $j(this).updateOutline( event.data.list ) |
37 | 37 | } |
38 | 38 | } ); |
39 | 39 | } |