[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 /** 2 * Toolbar module for wikiEditor 3 */ 4 /*jshint onevar:false */ 5 ( function ( mw, $ ) { $.wikiEditor.modules.toolbar = { 6 7 /** 8 * API accessible functions 9 */ 10 api : { 11 addToToolbar : function ( context, data ) { 12 13 var smooth = true, type, i; 14 15 for ( type in data ) { 16 switch ( type ) { 17 case 'sections': 18 var $sections = context.modules.toolbar.$toolbar.find( 'div.sections' ), 19 $tabs = context.modules.toolbar.$toolbar.find( 'div.tabs' ); 20 for ( var section in data[type] ) { 21 if ( section === 'main' ) { 22 // Section 23 context.modules.toolbar.$toolbar.prepend( 24 $.wikiEditor.modules.toolbar.fn.buildSection( 25 context, section, data[type][section] 26 ) 27 ); 28 continue; 29 } 30 // Section 31 $sections.append( 32 $.wikiEditor.modules.toolbar.fn.buildSection( context, section, data[type][section] ) 33 ); 34 // Tab 35 $tabs.append( 36 $.wikiEditor.modules.toolbar.fn.buildTab( context, section, data[type][section] ) 37 ); 38 } 39 break; 40 case 'groups': 41 if ( !( 'section' in data ) ) { 42 continue; 43 } 44 var $section = context.modules.toolbar.$toolbar.find( 'div[rel="' + data.section + '"].section' ); 45 for ( var group in data[type] ) { 46 // Group 47 $section.append( 48 $.wikiEditor.modules.toolbar.fn.buildGroup( context, group, data[type][group] ) 49 ); 50 } 51 smooth = false; 52 break; 53 case 'tools': 54 if ( !( 'section' in data && 'group' in data ) ) { 55 continue; 56 } 57 var $group = context.modules.toolbar.$toolbar.find( 58 'div[rel="' + data.section + '"].section ' + 'div[rel="' + data.group + '"].group' 59 ); 60 for ( var tool in data[type] ) { 61 // Tool 62 $group.append( $.wikiEditor.modules.toolbar.fn.buildTool( context, tool, data[type][tool] ) ); 63 } 64 if ( $group.children().length ) { 65 $group.removeClass( 'empty' ); 66 } 67 smooth = false; 68 break; 69 case 'pages': 70 if ( !( 'section' in data ) ) { 71 continue; 72 } 73 var $pages = context.modules.toolbar.$toolbar.find( 74 'div[rel="' + data.section + '"].section .pages' 75 ); 76 var $index = context.modules.toolbar.$toolbar.find( 77 'div[rel="' + data.section + '"].section .index' 78 ); 79 for ( var page in data[type] ) { 80 // Page 81 $pages.append( $.wikiEditor.modules.toolbar.fn.buildPage( context, page, data[type][page] ) ); 82 // Index 83 $index.append( 84 $.wikiEditor.modules.toolbar.fn.buildBookmark( context, page, data[type][page] ) 85 ); 86 } 87 $.wikiEditor.modules.toolbar.fn.updateBookletSelection( context, page, $pages, $index ); 88 smooth = false; 89 break; 90 case 'rows': 91 if ( !( 'section' in data && 'page' in data ) ) { 92 continue; 93 } 94 var $table = context.modules.toolbar.$toolbar.find( 95 'div[rel="' + data.section + '"].section ' + 'div[rel="' + data.page + '"].page table' 96 ); 97 for ( i = 0; i < data.rows.length; i++ ) { 98 // Row 99 $table.append( $.wikiEditor.modules.toolbar.fn.buildRow( context, data.rows[i] ) ); 100 } 101 smooth = false; 102 break; 103 case 'characters': 104 if ( !( 'section' in data && 'page' in data ) ) { 105 continue; 106 } 107 var $characters = context.modules.toolbar.$toolbar.find( 108 'div[rel="' + data.section + '"].section ' + 'div[rel="' + data.page + '"].page div' 109 ); 110 var actions = $characters.data( 'actions' ); 111 for ( i = 0; i < data.characters.length; i++ ) { 112 // Character 113 $characters 114 .append( 115 $( $.wikiEditor.modules.toolbar.fn.buildCharacter( data.characters[i], actions ) ) 116 .mousedown( function ( e ) { 117 context.fn.saveCursorAndScrollTop(); 118 // No dragging! 119 e.preventDefault(); 120 return false; 121 } ) 122 .click( function ( e ) { 123 $.wikiEditor.modules.toolbar.fn.doAction( $( this ).parent().data( 'context' ), 124 $( this ).parent().data( 'actions' )[$( this ).attr( 'rel' )] ); 125 e.preventDefault(); 126 return false; 127 } ) 128 ); 129 } 130 smooth = false; 131 break; 132 default: break; 133 } 134 } 135 136 // Fix div.section size after adding things; if smooth is true uses a smooth 137 // animation, otherwise just change height (breaking any ongoing animation) 138 var $divSections = context.modules.toolbar.$toolbar.find( 'div.sections' ); 139 var $visibleSection = $divSections.find( '.section-visible' ); 140 if ( $visibleSection.size() ) { 141 if ( smooth ) { 142 $divSections.animate( { 'height': $visibleSection.outerHeight() }, 'fast' ); 143 } else { 144 $divSections.height( $visibleSection.outerHeight() ); 145 } 146 } 147 }, 148 removeFromToolbar : function ( context, data ) { 149 if ( typeof data.section === 'string' ) { 150 // Section 151 var tab = 'div.tabs span[rel="' + data.section + '"].tab'; 152 var target = 'div[rel="' + data.section + '"].section'; 153 var group = null; 154 if ( typeof data.group === 'string' ) { 155 // Toolbar group 156 target += ' div[rel="' + data.group + '"].group'; 157 if ( typeof data.tool === 'string' ) { 158 // Save for later checking if empty 159 group = target; 160 // Tool 161 target = target + ' a[rel="' + data.tool + '"].tool, ' + target + ' img[rel="' + data.tool + '"].tool'; 162 } 163 } else if ( typeof data.page === 'string' ) { 164 // Booklet page 165 var index = target + ' div.index div[rel="' + data.page + '"]'; 166 target += ' div.pages div[rel="' + data.page + '"].page'; 167 if ( typeof data.character === 'string' ) { 168 // Character 169 target += ' span[rel="' + data.character + '"]'; 170 } else if ( typeof data.row === 'number' ) { 171 // Table row 172 target += ' table tr:not(:has(th)):eq(' + data.row + ')'; 173 } else { 174 // Just a page, remove the index too! 175 context.modules.toolbar.$toolbar.find( index ).remove(); 176 $.wikiEditor.modules.toolbar.fn.updateBookletSelection( 177 context, 178 null, 179 context.modules.toolbar.$toolbar.find( target ), 180 context.modules.toolbar.$toolbar.find( index ) 181 ); 182 } 183 } else { 184 // Just a section, remove the tab too! 185 context.modules.toolbar.$toolbar.find( tab ).remove(); 186 } 187 context.modules.toolbar.$toolbar.find( target ).remove(); 188 // Hide empty groups 189 if ( group ) { 190 var $group = context.modules.toolbar.$toolbar.find( group ); 191 if ( $group.children().length === 0 ) { 192 $group.addClass( 'empty' ); 193 } 194 } 195 } 196 } 197 }, 198 /** 199 * Event handlers 200 */ 201 evt: { 202 /** 203 * @param context 204 * @param event 205 */ 206 resize: function ( context ) { 207 context.$ui.find( '.sections' ).height( context.$ui.find( '.sections .section-visible' ).outerHeight() ); 208 } 209 }, 210 /** 211 * Internally used functions 212 */ 213 fn: { 214 /** 215 * Creates a toolbar module within a wikiEditor 216 * 217 * @param {Object} context Context object of editor to create module in 218 * @param {Object} config Configuration object to create module from 219 */ 220 create : function ( context, config ) { 221 if ( '$toolbar' in context.modules.toolbar ) { 222 return; 223 } 224 context.modules.toolbar.$toolbar = $( '<div>' ) 225 .addClass( 'wikiEditor-ui-toolbar' ) 226 .attr( 'id', 'wikiEditor-ui-toolbar' ); 227 $.wikiEditor.modules.toolbar.fn.build( context, config ); 228 context.$ui.find( '.wikiEditor-ui-top' ).append( context.modules.toolbar.$toolbar ); 229 }, 230 /** 231 * Performs an operation based on parameters 232 * 233 * @param {Object} context 234 * @param {Object} action 235 * @param {Object} source 236 */ 237 doAction : function ( context, action ) { 238 switch ( action.type ) { 239 case 'replace': 240 case 'encapsulate': 241 var parts = { 242 'pre' : $.wikiEditor.autoMsg( action.options, 'pre' ), 243 'peri' : $.wikiEditor.autoMsg( action.options, 'peri' ), 244 'post' : $.wikiEditor.autoMsg( action.options, 'post' ) 245 }; 246 var replace = action.type === 'replace'; 247 if ( 'regex' in action.options && 'regexReplace' in action.options ) { 248 var selection = context.$textarea.textSelection( 'getSelection' ); 249 if ( selection !== '' && selection.match( action.options.regex ) ) { 250 parts.peri = selection.replace( action.options.regex, 251 action.options.regexReplace ); 252 parts.pre = parts.post = ''; 253 replace = true; 254 } 255 } 256 context.$textarea.textSelection( 257 'encapsulateSelection', 258 $.extend( {}, action.options, parts, { 'replace': replace } ) 259 ); 260 break; 261 case 'callback': 262 if ( typeof action.execute === 'function' ) { 263 action.execute( context ); 264 } 265 break; 266 case 'dialog': 267 context.fn.saveSelection(); 268 context.$textarea.wikiEditor( 'openDialog', action.module ); 269 break; 270 default: break; 271 } 272 }, 273 buildGroup : function ( context, id, group ) { 274 var $group = $( '<div>' ).attr( { 'class' : 'group group-' + id, 'rel' : id } ); 275 var label = $.wikiEditor.autoMsg( group, 'label' ); 276 if ( label ) { 277 var $label = $( '<span />' ) 278 .addClass( 'label' ) 279 .html( label ); 280 $group.append( $label ); 281 } 282 var empty = true; 283 if ( 'tools' in group ) { 284 for ( var tool in group.tools ) { 285 tool = $.wikiEditor.modules.toolbar.fn.buildTool( context, tool, group.tools[tool] ); 286 if ( tool ) { 287 // Consider a group with only hidden tools empty as well 288 // .is( ':visible' ) always returns false because tool is not attached to the DOM yet 289 empty = empty && tool.css( 'display' ) === 'none'; 290 $group.append( tool ); 291 } 292 } 293 } 294 if ( empty ) { 295 $group.addClass( 'empty' ); 296 } 297 return $group; 298 }, 299 buildTool : function ( context, id, tool ) { 300 if ( 'filters' in tool ) { 301 for ( var i = 0; i < tool.filters.length; i++ ) { 302 if ( $( tool.filters[i] ).size() === 0 ) { 303 return null; 304 } 305 } 306 } 307 var label = $.wikiEditor.autoMsg( tool, 'label' ); 308 switch ( tool.type ) { 309 case 'button': 310 var src = $.wikiEditor.autoIcon( tool.icon, $.wikiEditor.imgPath + 'toolbar/' ); 311 var $button = null; 312 if ( 'offset' in tool ) { 313 var offsetOrIcon = $.wikiEditor.autoIconOrOffset( tool.icon, tool.offset, 314 $.wikiEditor.imgPath + 'toolbar/' 315 ); 316 if ( typeof offsetOrIcon === 'object' ) { 317 $button = $( '<a>' ) 318 .attr( { 319 'href' : '#', 320 'title' : label, 321 'rel' : id, 322 'role' : 'button', 323 'class' : 'tool tool-button wikiEditor-toolbar-spritedButton' 324 } ) 325 .text( label ) 326 .css( 'backgroundPosition', offsetOrIcon[0] + 'px ' + offsetOrIcon[1] + 'px' ); 327 } 328 } 329 if ( !$button ) { 330 $button = $( '<img>' ) 331 .attr( { 332 'src' : src, 333 'width' : 22, 334 'height' : 22, 335 'alt' : label, 336 'title' : label, 337 'rel' : id, 338 'role' : 'button', 339 'class' : 'tool tool-button' 340 } ); 341 } 342 if ( 'action' in tool ) { 343 $button 344 .data( 'action', tool.action ) 345 .data( 'context', context ) 346 .mousedown( function ( e ) { 347 context.fn.saveCursorAndScrollTop(); 348 // No dragging! 349 e.preventDefault(); 350 return false; 351 } ) 352 .click( function ( e ) { 353 $.wikiEditor.modules.toolbar.fn.doAction( 354 $( this ).data( 'context' ), $( this ).data( 'action' ), $( this ) 355 ); 356 e.preventDefault(); 357 return false; 358 } ); 359 } 360 return $button; 361 case 'select': 362 var $select = $( '<div>' ) 363 .attr( { 'rel' : id, 'class' : 'tool tool-select' } ); 364 var $options = $( '<div>' ).addClass( 'options' ); 365 if ( 'list' in tool ) { 366 for ( var option in tool.list ) { 367 var optionLabel = $.wikiEditor.autoMsg( tool.list[option], 'label' ); 368 $options.append( 369 $( '<a>' ) 370 .data( 'action', tool.list[option].action ) 371 .data( 'context', context ) 372 .mousedown( function ( e ) { 373 context.fn.saveCursorAndScrollTop(); 374 // No dragging! 375 e.preventDefault(); 376 return false; 377 } ) 378 .click( function ( e ) { 379 $.wikiEditor.modules.toolbar.fn.doAction( 380 $( this ).data( 'context' ), $( this ).data( 'action' ), $( this ) 381 ); 382 // Hide the dropdown 383 // Sanity check: if this somehow gets called while the dropdown 384 // is hidden, don't show it 385 if ( $( this ).parent().is( ':visible' ) ) { 386 $( this ).parent().animate( { 'opacity': 'toggle' }, 'fast' ); 387 } 388 e.preventDefault(); 389 return false; 390 } ) 391 .text( optionLabel ) 392 .addClass( 'option' ) 393 .attr( { 'rel': option, 'href': '#' } ) 394 ); 395 } 396 } 397 $select.append( $( '<div>' ).addClass( 'menu' ).append( $options ) ); 398 $select.append( $( '<a>' ) 399 .addClass( 'label' ) 400 .text( label ) 401 .data( 'options', $options ) 402 .attr( 'href', '#' ) 403 .mousedown( function ( e ) { 404 // No dragging! 405 e.preventDefault(); 406 return false; 407 } ) 408 .click( function ( e ) { 409 $( this ).data( 'options' ).animate( { 'opacity': 'toggle' }, 'fast' ); 410 e.preventDefault(); 411 return false; 412 } ) 413 ); 414 return $select; 415 default: 416 return null; 417 } 418 }, 419 buildBookmark : function ( context, id, page ) { 420 var label = $.wikiEditor.autoMsg( page, 'label' ); 421 return $( '<div>' ) 422 .text( label ) 423 .attr( 'rel', id ) 424 .data( 'context', context ) 425 .mousedown( function ( e ) { 426 context.fn.saveCursorAndScrollTop(); 427 // No dragging! 428 e.preventDefault(); 429 return false; 430 } ) 431 .click( function ( event ) { 432 $( this ).parent().parent().find( '.page' ).hide(); 433 $( this ).parent().parent().find( '.page-' + $( this ).attr( 'rel' ) ).show(); 434 $( this ).siblings().removeClass( 'current' ); 435 $( this ).addClass( 'current' ); 436 var section = $( this ).parent().parent().attr( 'rel' ); 437 $.cookie( 438 'wikiEditor-' + $( this ).data( 'context' ).instance + '-booklet-' + section + '-page', 439 $( this ).attr( 'rel' ), 440 { expires: 30, path: '/' } 441 ); 442 context.fn.restoreCursorAndScrollTop(); 443 // No dragging! 444 event.preventDefault(); 445 return false; 446 } ); 447 }, 448 buildPage : function ( context, id, page ) { 449 var html, i; 450 var $page = $( '<div>' ).attr( { 451 'class' : 'page page-' + id, 452 'rel' : id 453 } ); 454 switch ( page.layout ) { 455 case 'table': 456 $page.addClass( 'page-table' ); 457 html = 458 '<table cellpadding=0 cellspacing=0 ' + 'border=0 width="100%" class="table table-' + id + '">'; 459 if ( 'headings' in page ) { 460 html += $.wikiEditor.modules.toolbar.fn.buildHeading( context, page.headings ); 461 } 462 if ( 'rows' in page ) { 463 for ( i = 0; i < page.rows.length; i++ ) { 464 html += $.wikiEditor.modules.toolbar.fn.buildRow( context, page.rows[i] ); 465 } 466 } 467 $page.html( html + '</table>' ); 468 break; 469 case 'characters': 470 $page.addClass( 'page-characters' ); 471 var $characters = $( '<div>' ).data( 'context', context ).data( 'actions', {} ); 472 var actions = $characters.data( 'actions' ); 473 if ( 'language' in page ) { 474 $characters.attr( 'lang', page.language ); 475 } 476 if ( 'direction' in page ) { 477 $characters.attr( 'dir', page.direction ); 478 } else { 479 // By default it should be explicit ltr for all scripts. 480 // Without this some conjoined ltr characters look 481 // weird in rtl wikis. 482 $characters.attr( 'dir', 'ltr' ); 483 } 484 if ( 'characters' in page ) { 485 html = ''; 486 for ( i = 0; i < page.characters.length; i++ ) { 487 html += $.wikiEditor.modules.toolbar.fn.buildCharacter( page.characters[i], actions ); 488 } 489 $characters 490 .html( html ) 491 .children() 492 .mousedown( function ( e ) { 493 context.fn.saveCursorAndScrollTop(); 494 // No dragging! 495 e.preventDefault(); 496 return false; 497 } ) 498 .click( function ( e ) { 499 $.wikiEditor.modules.toolbar.fn.doAction( 500 $( this ).parent().data( 'context' ), 501 $( this ).parent().data( 'actions' )[$( this ).attr( 'rel' )], 502 $( this ) 503 ); 504 e.preventDefault(); 505 return false; 506 } ); 507 } 508 $page.append( $characters ); 509 break; 510 } 511 return $page; 512 }, 513 buildHeading : function ( context, headings ) { 514 var html = '<tr>'; 515 for ( var i = 0; i< headings.length; i++ ) { 516 html += '<th>' + $.wikiEditor.autoMsg( headings[i], ['html', 'text'] ) + '</th>'; 517 } 518 return html + '</tr>'; 519 }, 520 buildRow : function ( context, row ) { 521 var html = '<tr>'; 522 for ( var cell in row ) { 523 html += '<td class="cell cell-' + cell + '"><span>' + 524 $.wikiEditor.autoMsg( row[cell], ['html', 'text'] ) + '</span></td>'; 525 } 526 return html + '</tr>'; 527 }, 528 buildCharacter : function ( character, actions ) { 529 if ( typeof character === 'string' ) { 530 character = { 531 'label' : character, 532 'action' : { 533 'type' : 'replace', 534 'options' : { 535 'peri' : character, 536 'selectPeri': false 537 } 538 } 539 }; 540 // In some cases the label for the character isn't the same as the 541 // character that gets inserted (e.g. Hebrew vowels) 542 } else if ( character && 0 in character && 1 in character ) { 543 character = { 544 'label' : character[0], 545 'action' : { 546 'type' : 'replace', 547 'options' : { 548 'peri' : character[1], 549 'selectPeri': false 550 } 551 } 552 }; 553 } 554 if ( character && 'action' in character && 'label' in character ) { 555 actions[character.label] = character.action; 556 if ( character.titleMsg !== undefined ) { 557 return mw.html.element( 558 'span', 559 { 'rel': character.label, 'title': mw.msg( character.titleMsg ) }, 560 character.label 561 ); 562 } else { 563 return mw.html.element( 'span', { 'rel': character.label }, character.label ); 564 } 565 } 566 mw.log( 'A character for the toolbar was undefined. This is not supposed to happen. Double check the config.' ); 567 // bug 31673; also an additional fix for bug 24208... 568 return ''; 569 }, 570 buildTab : function ( context, id, section ) { 571 var selected = $.cookie( 'wikiEditor-' + context.instance + '-toolbar-section' ); 572 // Re-save cookie 573 if ( selected !== null ) { 574 $.cookie( 'wikiEditor-' + context.instance + '-toolbar-section', selected, { expires: 30, path: '/' } ); 575 } 576 var $link = 577 $( '<a>' ) 578 .addClass( selected === id ? 'current' : null ) 579 .attr( { 580 href: '#', 581 role: 'button', 582 'aria-pressed': 'false', 583 'aria-controls': 'wikiEditor-section-' + id 584 } ) 585 .text( $.wikiEditor.autoMsg( section, 'label' ) ) 586 .data( 'context', context ) 587 .mouseup( function () { 588 $( this ).blur(); 589 } ) 590 .mousedown( function ( e ) { 591 // No dragging! 592 e.preventDefault(); 593 return false; 594 } ) 595 .click( function ( e ) { 596 // We have to set aria-pressed over here, as NVDA wont recognize it 597 // if we do it in the below .each as it seems 598 $( this ).attr( 'aria-pressed', 'true' ); 599 $( '.tab > a' ).each( function ( i, elem ) { 600 if ( elem !== e.target ) { 601 $( elem ).attr( 'aria-pressed', 'false' ); 602 } 603 } ); 604 var $sections = $( this ).data( 'context' ).$ui.find( '.sections' ); 605 var $section = 606 $( this ).data( 'context' ).$ui.find( '.section-' + $( this ).parent().attr( 'rel' ) ); 607 var show = !$section.hasClass( 'section-visible' ); 608 $section.parent().find( '.section-visible' ) 609 .css( 'position', 'absolute' ) 610 .attr( 'aria-expanded', 'false' ) 611 .removeClass( 'section-visible' ) 612 .animate( { opacity: 0 }, 'fast', 'linear', function () { 613 $( this ).addClass( 'section-hidden' ).css( 'position', 'static' ); 614 } ); 615 616 $( this ).parent().parent().find( 'a' ).removeClass( 'current' ); 617 $sections.css( 'overflow', 'hidden' ); 618 var animate = function ( $that ) { 619 $sections 620 .animate( { 'height': $section.outerHeight() }, $section.outerHeight() * 2, function () { 621 $that.css( 'overflow', 'visible' ).css( 'height', 'auto' ); 622 context.fn.trigger( 'resize' ); 623 } ); 624 }; 625 if ( show ) { 626 $section.removeClass( 'section-hidden' ) 627 .attr( 'aria-expanded', 'true' ) 628 .animate( {opacity: 100.0}, 'fast', 'linear', function () { 629 $(this).addClass( 'section-visible' ); 630 } ); 631 632 if ( $section.hasClass( 'loading' ) ) { 633 // Loading of this section was deferred, load it now 634 var $that = $( this ); 635 $that.addClass( 'current loading' ); 636 setTimeout( function () { 637 $section.trigger( 'loadSection' ); 638 animate( $that ); 639 $that.removeClass( 'loading' ); 640 }, 1000 ); 641 } else { 642 animate( $( this ) ); 643 $( this ).addClass( 'current' ); 644 } 645 } else { 646 $sections 647 .css( 'height', $section.outerHeight() ) 648 .animate( { 'height': 0 }, $section.outerHeight() * 2, function () { 649 $( this ).css( { 'overflow': 'visible' } ); 650 context.fn.trigger( 'resize' ); 651 } ); 652 } 653 // Save the currently visible section 654 $.cookie( 655 'wikiEditor-' + $( this ).data( 'context' ).instance + '-toolbar-section', 656 show ? $section.attr( 'rel' ) : null, 657 { expires: 30, path: '/' } 658 ); 659 e.preventDefault(); 660 return false; 661 } ); 662 return $( '<span>' ) 663 .attr( { 664 'class' : 'tab tab-' + id, 665 'rel' : id 666 } ) 667 .append( $link ); 668 }, 669 buildSection: function ( context, id, section ) { 670 var $section = $( '<div>' ).attr( { 671 'class': section.type + ' section section-' + id, 672 'rel': id, 673 id: 'wikiEditor-section-' + id 674 } ); 675 var selected = $.cookie( 'wikiEditor-' + context.instance + '-toolbar-section' ); 676 var show = selected === id; 677 678 if ( section.deferLoad !== undefined && section.deferLoad && id !== 'main' && !show ) { 679 // This class shows the spinner and serves as a marker for the click handler in buildTab() 680 $section.addClass( 'loading' ).append( $( '<div>' ).addClass( 'spinner' ) ); 681 $section.bind( 'loadSection', function () { 682 $.wikiEditor.modules.toolbar.fn.reallyBuildSection( context, id, section, $section ); 683 $section.removeClass( 'loading' ); 684 } ); 685 } else { 686 $.wikiEditor.modules.toolbar.fn.reallyBuildSection( context, id, section, $section ); 687 } 688 689 // Show or hide section 690 if ( id !== 'main' ) { 691 $section.attr( 'aria-expanded', show ? 'true' : 'false' ); 692 693 if ( show ) { 694 $section.addClass( 'section-visible' ); 695 } else { 696 $section.addClass( 'section-hidden' ); 697 } 698 } 699 return $section; 700 }, 701 reallyBuildSection: function ( context, id, section, $section ) { 702 context.$textarea.trigger( 'wikiEditor-toolbar-buildSection-' + $section.attr( 'rel' ), [section] ); 703 switch ( section.type ) { 704 case 'toolbar': 705 if ( 'groups' in section ) { 706 for ( var group in section.groups ) { 707 $section.append( 708 $.wikiEditor.modules.toolbar.fn.buildGroup( context, group, section.groups[group] ) 709 ); 710 } 711 } 712 break; 713 case 'booklet': 714 var $pages = $( '<div>' ).addClass( 'pages' ); 715 var $index = $( '<div>' ).addClass( 'index' ); 716 if ( 'pages' in section ) { 717 for ( var page in section.pages ) { 718 $pages.append( 719 $.wikiEditor.modules.toolbar.fn.buildPage( context, page, section.pages[page] ) 720 ); 721 $index.append( 722 $.wikiEditor.modules.toolbar.fn.buildBookmark( context, page, section.pages[page] ) 723 ); 724 } 725 } 726 $section.append( $index ).append( $pages ); 727 $.wikiEditor.modules.toolbar.fn.updateBookletSelection( context, id, $pages, $index ); 728 break; 729 } 730 }, 731 updateBookletSelection : function ( context, id, $pages, $index ) { 732 /*jshint eqnull:true */ 733 var cookie = 'wikiEditor-' + context.instance + '-booklet-' + id + '-page'; 734 var selected = $.cookie( cookie ); 735 // Re-save cookie 736 if ( selected != null ) { 737 $.cookie( cookie, selected, { expires: 30, path: '/' } ); 738 } 739 var $selectedIndex = $index.find( '*[rel="' + selected + '"]' ); 740 if ( $selectedIndex.size() === 0 ) { 741 $selectedIndex = $index.children().eq( 0 ); 742 selected = $selectedIndex.attr( 'rel' ); 743 $.cookie( cookie, selected, { expires: 30, path: '/' } ); 744 } 745 $pages.children().hide(); 746 $pages.find( '*[rel="' + selected + '"]' ).show(); 747 $index.children().removeClass( 'current' ); 748 $selectedIndex.addClass( 'current' ); 749 }, 750 build : function ( context, config ) { 751 var $tabs = $( '<div>' ).addClass( 'tabs' ).appendTo( context.modules.toolbar.$toolbar ); 752 var $sections = $( '<div>' ).addClass( 'sections' ).appendTo( context.modules.toolbar.$toolbar ); 753 context.modules.toolbar.$toolbar.append( $( '<div>' ).css( 'clear', 'both' ) ); 754 var sectionQueue = []; 755 for ( var section in config ) { 756 if ( section === 'main' ) { 757 context.modules.toolbar.$toolbar.prepend( 758 $.wikiEditor.modules.toolbar.fn.buildSection( context, section, config[section] ) 759 ); 760 } else { 761 sectionQueue.push( { 762 '$sections' : $sections, 763 'context' : context, 764 'id' : section, 765 'config' : config[section] 766 } ); 767 $tabs.append( $.wikiEditor.modules.toolbar.fn.buildTab( context, section, config[section] ) ); 768 } 769 } 770 $.eachAsync( sectionQueue, { 771 'bulk' : 0, 772 'end' : function () { 773 // HACK: Opera doesn't seem to want to redraw after these bits 774 // are added to the DOM, so we can just FORCE it! 775 var oldValue = $( 'body' ).css( 'position' ); 776 $( 'body' ).css( 'position', 'static' ); 777 $( 'body' ).css( 'position', oldValue ); 778 779 context.$textarea.trigger( 'wikiEditor-toolbar-doneInitialSections' ); 780 }, 781 'loop' : function ( i, s ) { 782 s.$sections.append( $.wikiEditor.modules.toolbar.fn.buildSection( s.context, s.id, s.config ) ); 783 var $section = s.$sections.find( '.section-visible' ); 784 if ( $section.size() ) { 785 $sections.animate( { 'height': $section.outerHeight() }, $section.outerHeight() * 2, function ( ) { 786 context.fn.trigger( 'resize' ); 787 } ); 788 } 789 } 790 } ); 791 } 792 } 793 794 }; } )( mediaWiki, jQuery );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |