r53990 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r53989‎ | r53990 | r53991 >
Date:00:18, 30 July 2009
Author:tparscal
Status:deferred
Tags:
Comment:
Changed references to jQuery to be compatible with the upcoming switch to js2 - also cleaned up some toolbar code, moving the majority of the code into it's own plugin.
Modified paths:
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditWarning/EditWarning.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/OptIn/OptIn.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/SimpleSearch/SimpleSearch.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/jquery.combined.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/jquery.combined.min.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/jquery.toolbar.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/messages.js (deleted) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/SimpleSearch/SimpleSearch.js
@@ -1,14 +1,15 @@
22 /* JavaScript for SimpleSearch extension */
33
4 -$( document ).ready( function() {
 4+js2AddOnloadHook( function() {
55 // Only use this function in conjuction with the Vector skin
66 if( skin != 'vector' )
77 return;
88
99 // Adds form submission handler
10 - $( 'div#simpleSearch > input#searchInput' )
 10+ $j( 'div#simpleSearch > input#searchInput' )
1111 .each( function() {
12 - $( '<label>' + gM( 'simplesearch-search' ) + '</label>' )
 12+ $j( '<label></label>' )
 13+ .text( gM( 'simplesearch-search' ) )
1314 .css({
1415 'display': 'none',
1516 'position' : 'absolute',
@@ -17,21 +18,21 @@
1819 'color': '#999999',
1920 'cursor': 'text'
2021 })
21 - .css( ( $( 'body.rtl' ).size() > 0 ? 'right' : 'left' ), 0 )
 22+ .css( ( $j( 'body.rtl' ).size() > 0 ? 'right' : 'left' ), 0 )
2223 .click( function() {
23 - $(this).parent().find( 'input#searchInput' ).focus();
 24+ $j(this).parent().find( 'input#searchInput' ).focus();
2425 })
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();
2829 }
2930 })
3031 .focus( function() {
31 - $(this).parent().find( 'label' ).hide();
 32+ $j(this).parent().find( 'label' ).hide();
3233 })
3334 .blur( function() {
34 - if ( $(this).val() == '' ) {
35 - $(this).parent().find( 'label' ).show();
 35+ if ( $j(this).val() == '' ) {
 36+ $j(this).parent().find( 'label' ).show();
3637 }
3738 });
3839 });
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.php
@@ -20,9 +20,6 @@
2121
2222 /* Configuration */
2323
24 -// Set this to true to simply override the stock toolbar for everyone
25 -$wgUsabilityInitiativeCoesxistWithMvEmbed = false;
26 -
2724 // Set this to false to include all plugins individually
2825 $wgUsabilityInitiativeJsMode = 'combined';
2926
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -28,36 +28,39 @@
2929 array( 'src' => 'js/jquery.browser.js', 'version' => 2 ),
3030 array( 'src' => 'js/jquery.cookie.js', 'version' => 2 ),
3131 array( 'src' => 'js/jquery.textSelection.js', 'version' => 2 ),
 32+ array( 'src' => 'js/jquery.toolbar.js', 'version' => 2 ),
3233 array( 'src' => 'js/jquery.wikiOutline.js', 'version' => 2 ),
3334 ),
3435 ),
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 ),
3839 )
3940 );
4041
4142 /* Static Functions */
42 -
 43+
4344 public static function initialize() {
4445 global $wgUsabilityInitiativeJsMode;
4546 global $wgUsabilityInitiativeCoesxistWithMvEmbed;
4647
4748 // Only do this the first time!
4849 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+ }
4956 // Default to raw
5057 $mode = $wgUsabilityInitiativeJsMode; // Just an alias
5158 if ( !isset( self::$scriptFiles['base_sets'][$mode] ) ) {
5259 $mode = 'raw';
5360 }
5461 // 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+ );
6265 }
6366 self::$doOutput = true;
6467 }
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js
@@ -1,451 +1,28 @@
22 /* JavaScript for EditToolbar extension */
33
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>' )
4317 .attr( 'id', 'edit-ui' )
4328 );
433 - $( 'textarea#wpTextbox1' ).wrap(
434 - $( '<div></div>' )
 9+ $j( 'textarea#wpTextbox1' ).wrap(
 10+ $j( '<div></div>' )
43511 .attr( 'id', 'edit-ui-left' )
43612 );
437 - $( 'div#edit-ui' ).append(
438 - $( '<div></div>' )
 13+ $j( 'div#edit-ui' ).append(
 14+ $j( '<div></div>' )
43915 .attr( 'id', 'edit-ui-right' )
44016 );
441 - $( 'div#edit-ui-left' ).prepend(
442 - $( '<div></div>' )
 17+ $j( 'div#edit-ui-left' ).prepend(
 18+ $j( '<div></div>' )
44319 .attr( 'id', 'edit-toolbar' )
44420 );
445 - $( 'div#edit-toolbar' ).toolbar(
446 - $( 'textarea#wpTextbox1' ),
 21+ $j( 'div#edit-toolbar' ).toolbar(
 22+ $j( 'textarea#wpTextbox1' ),
44723 editToolbarConfiguration
44824 );
44925 });
 26+
45027 /**
45128 * This enormous structure is what makes the toolbar what it is. Customization
45229 * of this structure prior to the document being ready and thus executing the
Index: trunk/extensions/UsabilityInitiative/OptIn/OptIn.js
@@ -1,33 +1,60 @@
22 /* JavaScript for OptIn extension */
33
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
530 var browserIndex = 'other';
6 - switch ( $.browser.name ) {
 31+ switch ( $j.browser.name ) {
732 case 'msie':
8 - browserIndex = 'ie'+ parseInt( $.browser.versionNumber );
 33+ browserIndex = 'ie'+ parseInt( $j.browser.versionNumber );
934 break;
1035 case 'firefox':
11 - browserIndex = 'ff' + parseInt( $.browser.versionNumber );
 36+ browserIndex = 'ff' + parseInt( $j.browser.versionNumber );
1237 break;
1338 case 'chrome':
14 - browserIndex = 'c' + parseInt( $.browser.versionNumber ); // FIXME: Chrome Beta?
 39+ // FIXME: Chrome Beta?
 40+ browserIndex = 'c' + parseInt( $j.browser.versionNumber );
1541 break;
1642 case 'safari':
17 - browserIndex = 's' + parseInt( $.browser.versionNumber );
 43+ browserIndex = 's' + parseInt( $j.browser.versionNumber );
1844 break;
1945 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' )
2248 browserIndex = 'o9.5';
2349 else
2450 browserIndex = 'o9';
25 - } else if ( parseInt( $.browser.versionNumber ) == 10 )
 51+ } else if ( parseInt( $j.browser.versionNumber ) == 10 )
2652 browserIndex = 'o10';
2753 break;
2854 }
29 -
 55+ $j( '#survey-browser' ).val( browserIndex );
 56+ // Detect operating system
3057 var osIndex = 'other';
31 - switch ( $.os.name ) {
 58+ switch ( $j.os.name ) {
3259 case 'win':
3360 osIndex = 'windows';
3461 break;
@@ -38,48 +65,10 @@
3966 osIndex = 'linux';
4067 break;
4168 }
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
7871 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 );
8274 }
83 -
84 - $( '#survey-browser' ).val( detected['survey-browser'] );
85 - $( '#survey-os' ).val( detected['survey-os'] );
8675 });
Index: trunk/extensions/UsabilityInitiative/EditWarning/EditWarning.js
@@ -1,15 +1,14 @@
22 /* JavaScript for EditWarning extension */
33
4 -$( document ).ready( function() {
 4+js2AddOnloadHook( function() {
55 // Only use this function in conjuction with the Vector skin
66 if( skin != 'vector' )
77 return;
8 -
98 // 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() );
1211 });
13 -
 12+ // Attach our own handler for onbeforeunload which respects the current one
1413 fallbackWindowOnBeforeUnload = window.onbeforeunload;
1514 window.onbeforeunload = function() {
1615 var fallbackResult = null;
@@ -26,15 +25,15 @@
2726 // Check if the current values of some form elements are the same as
2827 // the original values
2928 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()
3231 ) {
3332 // Return our message
3433 return gM( 'editwarning-warning' );
3534 }
3635 }
3736 // Add form submission handler
38 - $( 'form' ).submit( function() {
 37+ $j( 'form' ).submit( function() {
3938 // Restore whatever previous onbeforeload hook existed
4039 window.onbeforeunload = fallbackWindowOnBeforeUnload;
4140 });
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 @@
49074907 })(jQuery);
49084908
49094909 /**
 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);/**
49105364 * Plugin for parsing wikitext, building outlines, and keeping them up to date
49115365 */
49125366 (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
155 + native
Index: trunk/extensions/UsabilityInitiative/js/jquery.combined.min.js
@@ -476,7 +476,37 @@
477477 return($.os.name=='mac'?13:($.os.name=='linux'?15:16))*row;}
478478 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;}
479479 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;}
481511 text=$.trim(text);var startLevel=0;for(var c=0;c<text.length;c++){if(text.charAt(c)=='='){startLevel++;}else{break;}}
482512 var endLevel=0;for(var c=text.length-1;c>=0;c--){if(text.charAt(c)=='='){endLevel++;}else{break;}}
483513 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 @@
22 /* JavaScript for NavigableTOC extension */
33
4 -jQuery( document ).ready( function() {
5 - var list = $( '<div></div>' )
 4+js2AddOnloadHook( function() {
 5+ var list = $j( '<div></div>' )
66 .attr( 'id', 'edit-toc' )
7 - .appendTo( $( 'div#edit-ui-right' ) );
8 - $( '#wpTextbox1' )
 7+ .appendTo( $j( 'div#edit-ui-right' ) );
 8+ $j( '#wpTextbox1' )
99 .eachAsync( {
1010 bulk: 0,
1111 loop: function() {
12 - $(this)
 12+ $j(this)
1313 .parseOutline()
1414 .buildOutline( list )
1515 .updateOutline( list );
@@ -16,10 +16,10 @@
1717 } )
1818 .bind( 'keyup encapsulateSelection', { 'list': list },
1919 function( event ) {
20 - $(this).eachAsync( {
 20+ $j(this).eachAsync( {
2121 bulk: 0,
2222 loop: function() {
23 - $(this)
 23+ $j(this)
2424 .parseOutline()
2525 .buildOutline( event.data.list )
2626 .updateOutline( event.data.list );
@@ -29,10 +29,10 @@
3030 )
3131 .bind( 'mouseup scrollToPosition', { 'list': list },
3232 function( event ) {
33 - $(this).eachAsync( {
 33+ $j(this).eachAsync( {
3434 bulk: 0,
3535 loop: function() {
36 - $(this).updateOutline( event.data.list )
 36+ $j(this).updateOutline( event.data.list )
3737 }
3838 } );
3939 }

Follow-up revisions

RevisionCommit summaryAuthorDate
r54008Fix up r53990: forgotten jQuery referencecatrope09:55, 30 July 2009
r54663OptIn: Fix browser+OS registration that got borked by r53990 and was commente...catrope15:00, 9 August 2009

Status & tagging log