[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/libraries/ckeditor/_source/plugins/dialogui/ -> plugin.js (source)

   1  /*

   2  Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.

   3  For licensing, see LICENSE.html or http://ckeditor.com/license

   4  */
   5  
   6  /** @fileoverview The "dialogui" plugin. */

   7  
   8  CKEDITOR.plugins.add( 'dialogui' );
   9  
  10  (function()
  11  {
  12      var initPrivateObject = function( elementDefinition )
  13      {
  14          this._ || ( this._ = {} );
  15          this._['default'] = this._.initValue = elementDefinition['default'] || '';
  16          this._.required = elementDefinition[ 'required' ] || false;
  17          var args = [ this._ ];
  18          for ( var i = 1 ; i < arguments.length ; i++ )
  19              args.push( arguments[i] );
  20          args.push( true );
  21          CKEDITOR.tools.extend.apply( CKEDITOR.tools, args );
  22          return this._;
  23      },
  24      textBuilder =
  25      {
  26          build : function( dialog, elementDefinition, output )
  27          {
  28              return new CKEDITOR.ui.dialog.textInput( dialog, elementDefinition, output );
  29          }
  30      },
  31      commonBuilder =
  32      {
  33          build : function( dialog, elementDefinition, output )
  34          {
  35              return new CKEDITOR.ui.dialog[elementDefinition.type]( dialog, elementDefinition, output );
  36          }
  37      },
  38      containerBuilder =
  39      {
  40          build : function( dialog, elementDefinition, output )
  41          {
  42              var children = elementDefinition.children,
  43                  child,
  44                  childHtmlList = [],
  45                  childObjList = [];
  46              for ( var i = 0 ; ( i < children.length && ( child = children[i] ) ) ; i++ )
  47              {
  48                  var childHtml = [];
  49                  childHtmlList.push( childHtml );
  50                  childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) );
  51              }
  52              return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition );
  53          }
  54      },
  55      commonPrototype =
  56      {
  57          isChanged : function()
  58          {
  59              return this.getValue() != this.getInitValue();
  60          },
  61  
  62          reset : function( noChangeEvent )
  63          {
  64              this.setValue( this.getInitValue(), noChangeEvent );
  65          },
  66  
  67          setInitValue : function()
  68          {
  69              this._.initValue = this.getValue();
  70          },
  71  
  72          resetInitValue : function()
  73          {
  74              this._.initValue = this._['default'];
  75          },
  76  
  77          getInitValue : function()
  78          {
  79              return this._.initValue;
  80          }
  81      },
  82      commonEventProcessors = CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,
  83          {
  84              onChange : function( dialog, func )
  85              {
  86                  if ( !this._.domOnChangeRegistered )
  87                  {
  88                      dialog.on( 'load', function()
  89                          {
  90                              this.getInputElement().on( 'change', function()
  91                              {
  92                                  // Make sure 'onchange' doesn't get fired after dialog closed. (#5719)

  93                                  if ( !dialog.parts.dialog.isVisible() )
  94                                      return;
  95  
  96                                  this.fire( 'change', { value : this.getValue() } );
  97                              }, this );
  98                          }, this );
  99                      this._.domOnChangeRegistered = true;
 100                  }
 101  
 102                  this.on( 'change', func );
 103              }
 104          }, true ),
 105      eventRegex = /^on([A-Z]\w+)/,
 106      cleanInnerDefinition = function( def )
 107      {
 108          // An inner UI element should not have the parent's type, title or events.

 109          for ( var i in def )
 110          {
 111              if ( eventRegex.test( i ) || i == 'title' || i == 'type' )
 112                  delete def[i];
 113          }
 114          return def;
 115      };
 116  
 117      CKEDITOR.tools.extend( CKEDITOR.ui.dialog,
 118          /** @lends CKEDITOR.ui.dialog */

 119          {
 120              /**

 121               * Base class for all dialog elements with a textual label on the left.

 122               * @constructor

 123               * @example

 124               * @extends CKEDITOR.ui.dialog.uiElement

 125               * @param {CKEDITOR.dialog} dialog

 126               * Parent dialog object.

 127               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 128               * The element definition. Accepted fields:

 129               * <ul>

 130               *     <li><strong>label</strong> (Required) The label string.</li>

 131               *     <li><strong>labelLayout</strong> (Optional) Put 'horizontal' here if the

 132               *     label element is to be layed out horizontally. Otherwise a vertical

 133               *     layout will be used.</li>

 134               *     <li><strong>widths</strong> (Optional) This applies only for horizontal

 135               *     layouts - an 2-element array of lengths to specify the widths of the

 136               *     label and the content element.</li>

 137               * </ul>

 138               * @param {Array} htmlList

 139               * List of HTML code to output to.

 140               * @param {Function} contentHtml

 141               * A function returning the HTML code string to be added inside the content

 142               * cell.

 143               */
 144              labeledElement : function( dialog, elementDefinition, htmlList, contentHtml )
 145              {
 146                  if ( arguments.length < 4 )
 147                      return;
 148  
 149                  var _ = initPrivateObject.call( this, elementDefinition );
 150                  _.labelId = CKEDITOR.tools.getNextId() + '_label';
 151                  var children = this._.children = [];
 152                  /** @ignore */

 153                  var innerHTML = function()
 154                  {
 155                      var html = [],
 156                          requiredClass = elementDefinition.required ? ' cke_required' : '' ;
 157                      if ( elementDefinition.labelLayout != 'horizontal' )
 158                          html.push( '<label class="cke_dialog_ui_labeled_label' + requiredClass + '" ',
 159                                  ' id="'+  _.labelId + '"',
 160                                  ' for="' + _.inputId + '"',
 161                                  ' style="' + elementDefinition.labelStyle + '">',
 162                                  elementDefinition.label,
 163                                  '</label>',
 164                                  '<div class="cke_dialog_ui_labeled_content" role="presentation">',
 165                                  contentHtml.call( this, dialog, elementDefinition ),
 166                                  '</div>' );
 167                      else
 168                      {
 169                          var hboxDefinition = {
 170                              type : 'hbox',
 171                              widths : elementDefinition.widths,
 172                              padding : 0,
 173                              children :
 174                              [
 175                                  {
 176                                      type : 'html',
 177                                      html : '<label class="cke_dialog_ui_labeled_label' + requiredClass + '"' +
 178                                          ' id="' + _.labelId + '"' +
 179                                          ' for="' + _.inputId + '"' +
 180                                          ' style="' + elementDefinition.labelStyle + '">' +
 181                                             CKEDITOR.tools.htmlEncode( elementDefinition.label ) +
 182                                          '</span>'
 183                                  },
 184                                  {
 185                                      type : 'html',
 186                                      html : '<span class="cke_dialog_ui_labeled_content">' +
 187                                          contentHtml.call( this, dialog, elementDefinition ) +
 188                                          '</span>'
 189                                  }
 190                              ]
 191                          };
 192                          CKEDITOR.dialog._.uiElementBuilders.hbox.build( dialog, hboxDefinition, html );
 193                      }
 194                      return html.join( '' );
 195                  };
 196                  CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'div', null, { role : 'presentation' }, innerHTML );
 197              },
 198  
 199              /**

 200               * A text input with a label. This UI element class represents both the

 201               * single-line text inputs and password inputs in dialog boxes.

 202               * @constructor

 203               * @example

 204               * @extends CKEDITOR.ui.dialog.labeledElement

 205               * @param {CKEDITOR.dialog} dialog

 206               * Parent dialog object.

 207               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 208               * The element definition. Accepted fields:

 209               * <ul>

 210               *     <li><strong>default</strong> (Optional) The default value.</li>

 211               *     <li><strong>validate</strong> (Optional) The validation function. </li>

 212               *     <li><strong>maxLength</strong> (Optional) The maximum length of text box

 213               *     contents.</li>

 214               *     <li><strong>size</strong> (Optional) The size of the text box. This is

 215               *     usually overridden by the size defined by the skin, however.</li>

 216               * </ul>

 217               * @param {Array} htmlList

 218               * List of HTML code to output to.

 219               */
 220              textInput : function( dialog, elementDefinition, htmlList )
 221              {
 222                  if ( arguments.length < 3 )
 223                      return;
 224  
 225                  initPrivateObject.call( this, elementDefinition );
 226                  var domId = this._.inputId = CKEDITOR.tools.getNextId() + '_textInput',
 227                      attributes = { 'class' : 'cke_dialog_ui_input_' + elementDefinition.type, id : domId, type : 'text' },
 228                      i;
 229  
 230                  // Set the validator, if any.

 231                  if ( elementDefinition.validate )
 232                      this.validate = elementDefinition.validate;
 233  
 234                  // Set the max length and size.

 235                  if ( elementDefinition.maxLength )
 236                      attributes.maxlength = elementDefinition.maxLength;
 237                  if ( elementDefinition.size )
 238                      attributes.size = elementDefinition.size;
 239  
 240                  if ( elementDefinition.controlStyle )
 241                      attributes.style = elementDefinition.controlStyle;
 242  
 243                  // If user presses Enter in a text box, it implies clicking OK for the dialog.

 244                  var me = this, keyPressedOnMe = false;
 245                  dialog.on( 'load', function()
 246                      {
 247                          me.getInputElement().on( 'keydown', function( evt )
 248                              {
 249                                  if ( evt.data.getKeystroke() == 13 )
 250                                      keyPressedOnMe = true;
 251                              } );
 252  
 253                          // Lower the priority this 'keyup' since 'ok' will close the dialog.(#3749)

 254                          me.getInputElement().on( 'keyup', function( evt )
 255                              {
 256                                  if ( evt.data.getKeystroke() == 13 && keyPressedOnMe )
 257                                  {
 258                                      dialog.getButton( 'ok' ) && setTimeout( function ()
 259                                      {
 260                                          dialog.getButton( 'ok' ).click();
 261                                      }, 0 );
 262                                      keyPressedOnMe = false;
 263                                  }
 264                              }, null, null, 1000 );
 265                      } );
 266  
 267                  /** @ignore */

 268                  var innerHTML = function()
 269                  {
 270                      // IE BUG: Text input fields in IE at 100% would exceed a <td> or inline

 271                      // container's width, so need to wrap it inside a <div>.

 272                      var html = [ '<div class="cke_dialog_ui_input_', elementDefinition.type, '" role="presentation"' ];
 273  
 274                      if ( elementDefinition.width )
 275                          html.push( 'style="width:'+ elementDefinition.width +'" ' );
 276  
 277                      html.push( '><input ' );
 278  
 279                      attributes[ 'aria-labelledby' ] = this._.labelId;
 280                      this._.required && ( attributes[ 'aria-required' ] = this._.required );
 281                      for ( var i in attributes )
 282                          html.push( i + '="' + attributes[i] + '" ' );
 283                      html.push( ' /></div>' );
 284                      return html.join( '' );
 285                  };
 286                  CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );
 287              },
 288  
 289              /**

 290               * A text area with a label on the top or left.

 291               * @constructor

 292               * @extends CKEDITOR.ui.dialog.labeledElement

 293               * @example

 294               * @param {CKEDITOR.dialog} dialog

 295               * Parent dialog object.

 296               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 297               * The element definition. Accepted fields:

 298               * <ul>

 299               *     <li><strong>rows</strong> (Optional) The number of rows displayed.

 300               *     Defaults to 5 if not defined.</li>

 301               *     <li><strong>cols</strong> (Optional) The number of cols displayed.

 302               *     Defaults to 20 if not defined. Usually overridden by skins.</li>

 303               *     <li><strong>default</strong> (Optional) The default value.</li>

 304               *     <li><strong>validate</strong> (Optional) The validation function. </li>

 305               * </ul>

 306               * @param {Array} htmlList

 307               * List of HTML code to output to.

 308               */
 309              textarea : function( dialog, elementDefinition, htmlList )
 310              {
 311                  if ( arguments.length < 3 )
 312                      return;
 313  
 314                  initPrivateObject.call( this, elementDefinition );
 315                  var me = this,
 316                      domId = this._.inputId = CKEDITOR.tools.getNextId() + '_textarea',
 317                      attributes = {};
 318  
 319                  if ( elementDefinition.validate )
 320                      this.validate = elementDefinition.validate;
 321  
 322                  // Generates the essential attributes for the textarea tag.

 323                  attributes.rows = elementDefinition.rows || 5;
 324                  attributes.cols = elementDefinition.cols || 20;
 325  
 326                  /** @ignore */

 327                  var innerHTML = function()
 328                  {
 329                      attributes[ 'aria-labelledby' ] = this._.labelId;
 330                      this._.required && ( attributes[ 'aria-required' ] = this._.required );
 331                      var html = [ '<div class="cke_dialog_ui_input_textarea" role="presentation"><textarea class="cke_dialog_ui_input_textarea" id="', domId, '" ' ];
 332                      for ( var i in attributes )
 333                          html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[i] ) + '" ' );
 334                      html.push( '>', CKEDITOR.tools.htmlEncode( me._['default'] ), '</textarea></div>' );
 335                      return html.join( '' );
 336                  };
 337                  CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );
 338              },
 339  
 340              /**

 341               * A single checkbox with a label on the right.

 342               * @constructor

 343               * @extends CKEDITOR.ui.dialog.uiElement

 344               * @example

 345               * @param {CKEDITOR.dialog} dialog

 346               * Parent dialog object.

 347               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 348               * The element definition. Accepted fields:

 349               * <ul>

 350               *     <li><strong>checked</strong> (Optional) Whether the checkbox is checked

 351               *     on instantiation. Defaults to false.</li>

 352               *     <li><strong>validate</strong> (Optional) The validation function.</li>

 353               *     <li><strong>label</strong> (Optional) The checkbox label.</li>

 354               * </ul>

 355               * @param {Array} htmlList

 356               * List of HTML code to output to.

 357               */
 358              checkbox : function( dialog, elementDefinition, htmlList )
 359              {
 360                  if ( arguments.length < 3 )
 361                      return;
 362  
 363                  var _ = initPrivateObject.call( this, elementDefinition, { 'default' : !!elementDefinition[ 'default' ] } );
 364  
 365                  if ( elementDefinition.validate )
 366                      this.validate = elementDefinition.validate;
 367  
 368                  /** @ignore */

 369                  var innerHTML = function()
 370                  {
 371                      var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition,
 372                              {
 373                                  id : elementDefinition.id ? elementDefinition.id + '_checkbox' : CKEDITOR.tools.getNextId() + '_checkbox'
 374                              }, true ),
 375                          html = [];
 376  
 377                      var labelId = CKEDITOR.tools.getNextId() + '_label';
 378                      var attributes = { 'class' : 'cke_dialog_ui_checkbox_input', type : 'checkbox', 'aria-labelledby' : labelId };
 379                      cleanInnerDefinition( myDefinition );
 380                      if ( elementDefinition[ 'default' ] )
 381                          attributes.checked = 'checked';
 382  
 383                      if (typeof myDefinition.controlStyle != 'undefined')
 384                          myDefinition.style = myDefinition.controlStyle;
 385  
 386                      _.checkbox = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'input', null, attributes );
 387                      html.push( ' <label id="', labelId, '" for="', attributes.id, '">',
 388                              CKEDITOR.tools.htmlEncode( elementDefinition.label ),
 389                              '</label>' );
 390                      return html.join( '' );
 391                  };
 392  
 393                  CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'span', null, null, innerHTML );
 394              },
 395  
 396              /**

 397               * A group of radio buttons.

 398               * @constructor

 399               * @example

 400               * @extends CKEDITOR.ui.dialog.labeledElement

 401               * @param {CKEDITOR.dialog} dialog

 402               * Parent dialog object.

 403               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 404               * The element definition. Accepted fields:

 405               * <ul>

 406               *     <li><strong>default</strong> (Required) The default value.</li>

 407               *     <li><strong>validate</strong> (Optional) The validation function.</li>

 408               *     <li><strong>items</strong> (Required) An array of options. Each option

 409               *     is a 1- or 2-item array of format [ 'Description', 'Value' ]. If 'Value'

 410               *     is missing, then the value would be assumed to be the same as the

 411               *     description.</li>

 412               * </ul>

 413               * @param {Array} htmlList

 414               * List of HTML code to output to.

 415               */
 416              radio : function( dialog, elementDefinition, htmlList )
 417              {
 418                  if ( arguments.length < 3)
 419                      return;
 420  
 421                  initPrivateObject.call( this, elementDefinition );
 422                  if ( !this._['default'] )
 423                      this._['default'] = this._.initValue = elementDefinition.items[0][1];
 424                  if ( elementDefinition.validate )
 425                      this.validate = elementDefinition.valdiate;
 426                  var children = [], me = this;
 427  
 428                  /** @ignore */

 429                  var innerHTML = function()
 430                  {
 431                      var inputHtmlList = [], html = [],
 432                          commonAttributes = { 'class' : 'cke_dialog_ui_radio_item', 'aria-labelledby' : this._.labelId },
 433                          commonName = elementDefinition.id ? elementDefinition.id + '_radio' : CKEDITOR.tools.getNextId() + '_radio';
 434                      for ( var i = 0 ; i < elementDefinition.items.length ; i++ )
 435                      {
 436                          var item = elementDefinition.items[i],
 437                              title = item[2] !== undefined ? item[2] : item[0],
 438                              value = item[1] !== undefined ? item[1] : item[0],
 439                              inputId = CKEDITOR.tools.getNextId() + '_radio_input',
 440                              labelId = inputId + '_label',
 441                              inputDefinition = CKEDITOR.tools.extend( {}, elementDefinition,
 442                                      {
 443                                          id : inputId,
 444                                          title : null,
 445                                          type : null
 446                                      }, true ),
 447                              labelDefinition = CKEDITOR.tools.extend( {}, inputDefinition,
 448                                      {
 449                                          title : title
 450                                      }, true ),
 451                              inputAttributes =
 452                              {
 453                                  type : 'radio',
 454                                  'class' : 'cke_dialog_ui_radio_input',
 455                                  name : commonName,
 456                                  value : value,
 457                                  'aria-labelledby' : labelId
 458                              },
 459                              inputHtml = [];
 460                          if ( me._['default'] == value )
 461                              inputAttributes.checked = 'checked';
 462                          cleanInnerDefinition( inputDefinition );
 463                          cleanInnerDefinition( labelDefinition );
 464  
 465                          if (typeof inputDefinition.controlStyle != 'undefined')
 466                              inputDefinition.style = inputDefinition.controlStyle;
 467  
 468                          children.push( new CKEDITOR.ui.dialog.uiElement( dialog, inputDefinition, inputHtml, 'input', null, inputAttributes ) );
 469                          inputHtml.push( ' ' );
 470                          new CKEDITOR.ui.dialog.uiElement( dialog, labelDefinition, inputHtml, 'label', null, { id : labelId, 'for' : inputAttributes.id },
 471                                 item[0] );
 472                          inputHtmlList.push( inputHtml.join( '' ) );
 473                      }
 474                      new CKEDITOR.ui.dialog.hbox( dialog, [], inputHtmlList, html );
 475                      return html.join( '' );
 476                  };
 477  
 478                  CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );
 479                  this._.children = children;
 480              },
 481  
 482              /**

 483               * A button with a label inside.

 484               * @constructor

 485               * @example

 486               * @extends CKEDITOR.ui.dialog.uiElement

 487               * @param {CKEDITOR.dialog} dialog

 488               * Parent dialog object.

 489               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 490               * The element definition. Accepted fields:

 491               * <ul>

 492               *     <li><strong>label</strong> (Required) The button label.</li>

 493               *     <li><strong>disabled</strong> (Optional) Set to true if you want the

 494               *     button to appear in disabled state.</li>

 495               * </ul>

 496               * @param {Array} htmlList

 497               * List of HTML code to output to.

 498               */
 499              button : function( dialog, elementDefinition, htmlList )
 500              {
 501                  if ( !arguments.length )
 502                      return;
 503  
 504                  if ( typeof elementDefinition == 'function' )
 505                      elementDefinition = elementDefinition( dialog.getParentEditor() );
 506  
 507                  initPrivateObject.call( this, elementDefinition, { disabled : elementDefinition.disabled || false } );
 508  
 509                  // Add OnClick event to this input.

 510                  CKEDITOR.event.implementOn( this );
 511  
 512                  var me = this;
 513  
 514                  // Register an event handler for processing button clicks.

 515                  dialog.on( 'load', function( eventInfo )
 516                      {
 517                          var element = this.getElement();
 518  
 519                          (function()
 520                          {
 521                              element.on( 'click', function( evt )
 522                                  {
 523                                      me.fire( 'click', { dialog : me.getDialog() } );
 524                                      evt.data.preventDefault();
 525                                  } );
 526  
 527                              element.on( 'keydown', function( evt )
 528                                  {
 529                                      if ( evt.data.getKeystroke() in { 32:1 } )
 530                                      {
 531                                          me.click();
 532                                          evt.data.preventDefault();
 533                                      }
 534                                  } );
 535                          })();
 536  
 537                          element.unselectable();
 538                      }, this );
 539  
 540                  var outerDefinition = CKEDITOR.tools.extend( {}, elementDefinition );
 541                  delete outerDefinition.style;
 542  
 543                  var labelId = CKEDITOR.tools.getNextId() + '_label';
 544                  CKEDITOR.ui.dialog.uiElement.call(
 545                      this,
 546                      dialog,
 547                      outerDefinition,
 548                      htmlList,
 549                      'a',
 550                      null,
 551                      {
 552                          style : elementDefinition.style,
 553                          href : 'javascript:void(0)',
 554                          title : elementDefinition.label,
 555                          hidefocus : 'true',
 556                          'class' : elementDefinition['class'],
 557                          role : 'button',
 558                          'aria-labelledby' : labelId
 559                      },
 560                      '<span id="' + labelId + '" class="cke_dialog_ui_button">' +
 561                          CKEDITOR.tools.htmlEncode( elementDefinition.label ) +
 562                      '</span>' );
 563              },
 564  
 565              /**

 566               * A select box.

 567               * @extends CKEDITOR.ui.dialog.uiElement

 568               * @example

 569               * @constructor

 570               * @param {CKEDITOR.dialog} dialog

 571               * Parent dialog object.

 572               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 573               * The element definition. Accepted fields:

 574               * <ul>

 575               *     <li><strong>default</strong> (Required) The default value.</li>

 576               *     <li><strong>validate</strong> (Optional) The validation function.</li>

 577               *     <li><strong>items</strong> (Required) An array of options. Each option

 578               *     is a 1- or 2-item array of format [ 'Description', 'Value' ]. If 'Value'

 579               *     is missing, then the value would be assumed to be the same as the

 580               *     description.</li>

 581               *     <li><strong>multiple</strong> (Optional) Set this to true if you'd like

 582               *     to have a multiple-choice select box.</li>

 583               *     <li><strong>size</strong> (Optional) The number of items to display in

 584               *     the select box.</li>

 585               * </ul>

 586               * @param {Array} htmlList

 587               * List of HTML code to output to.

 588               */
 589              select : function( dialog, elementDefinition, htmlList )
 590              {
 591                  if ( arguments.length < 3 )
 592                      return;
 593  
 594                  var _ = initPrivateObject.call( this, elementDefinition );
 595  
 596                  if ( elementDefinition.validate )
 597                      this.validate = elementDefinition.validate;
 598  
 599                  _.inputId = CKEDITOR.tools.getNextId() + '_select';
 600                  /** @ignore */

 601                  var innerHTML = function()
 602                  {
 603                      var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition,
 604                              {
 605                                  id : elementDefinition.id ? elementDefinition.id + '_select' : CKEDITOR.tools.getNextId() + '_select'
 606                              }, true ),
 607                          html = [],
 608                          innerHTML = [],
 609                          attributes = { 'id' : _.inputId, 'class' : 'cke_dialog_ui_input_select', 'aria-labelledby' : this._.labelId };
 610  
 611                      // Add multiple and size attributes from element definition.

 612                      if ( elementDefinition.size != undefined )
 613                          attributes.size = elementDefinition.size;
 614                      if ( elementDefinition.multiple != undefined )
 615                          attributes.multiple = elementDefinition.multiple;
 616  
 617                      cleanInnerDefinition( myDefinition );
 618                      for ( var i = 0, item ; i < elementDefinition.items.length && ( item = elementDefinition.items[i] ) ; i++ )
 619                      {
 620                          innerHTML.push( '<option value="',
 621                              CKEDITOR.tools.htmlEncode( item[1] !== undefined ? item[1] : item[0] ), '" /> ',
 622                              CKEDITOR.tools.htmlEncode( item[0] ) );
 623                      }
 624  
 625                      if (typeof myDefinition.controlStyle != 'undefined')
 626                          myDefinition.style = myDefinition.controlStyle;
 627  
 628                      _.select = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'select', null, attributes, innerHTML.join( '' ) );
 629                      return html.join( '' );
 630                  };
 631  
 632                  CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );
 633              },
 634  
 635              /**

 636               * A file upload input.

 637               * @extends CKEDITOR.ui.dialog.labeledElement

 638               * @example

 639               * @constructor

 640               * @param {CKEDITOR.dialog} dialog

 641               * Parent dialog object.

 642               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 643               * The element definition. Accepted fields:

 644               * <ul>

 645               *     <li><strong>validate</strong> (Optional) The validation function.</li>

 646               * </ul>

 647               * @param {Array} htmlList

 648               * List of HTML code to output to.

 649               */
 650              file : function( dialog, elementDefinition, htmlList )
 651              {
 652                  if ( arguments.length < 3 )
 653                      return;
 654  
 655                  if ( elementDefinition['default'] === undefined )
 656                      elementDefinition['default'] = '';
 657  
 658                  var _ = CKEDITOR.tools.extend( initPrivateObject.call( this, elementDefinition ), { definition : elementDefinition, buttons : [] } );
 659  
 660                  if ( elementDefinition.validate )
 661                      this.validate = elementDefinition.validate;
 662  
 663                  /** @ignore */

 664                  var innerHTML = function()
 665                  {
 666                      _.frameId = CKEDITOR.tools.getNextId() + '_fileInput';
 667  
 668                      // Support for custom document.domain in IE.

 669                      var isCustomDomain = CKEDITOR.env.isCustomDomain();
 670  
 671                      var html = [
 672                          '<iframe' +
 673                              ' frameborder="0"' +
 674                              ' allowtransparency="0"' +
 675                              ' class="cke_dialog_ui_input_file"' +
 676                              ' id="', _.frameId, '"' +
 677                              ' title="', elementDefinition.label, '"' +
 678                              ' src="javascript:void(' ];
 679  
 680                      html.push(
 681                              isCustomDomain ?
 682                                  '(function(){' +
 683                                      'document.open();' +
 684                                      'document.domain=\'' + document.domain + '\';' +
 685                                      'document.close();' +
 686                                  '})()'
 687                              :
 688                                  '0' );
 689  
 690                      html.push(
 691                              ')">' +
 692                          '</iframe>' );
 693  
 694                      return html.join( '' );
 695                  };
 696  
 697                  // IE BUG: Parent container does not resize to contain the iframe automatically.

 698                  dialog.on( 'load', function()
 699                      {
 700                          var iframe = CKEDITOR.document.getById( _.frameId ),
 701                              contentDiv = iframe.getParent();
 702                          contentDiv.addClass( 'cke_dialog_ui_input_file' );
 703                      } );
 704  
 705                  CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );
 706              },
 707  
 708              /**

 709               * A button for submitting the file in a file upload input.

 710               * @extends CKEDITOR.ui.dialog.button

 711               * @example

 712               * @constructor

 713               * @param {CKEDITOR.dialog} dialog

 714               * Parent dialog object.

 715               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 716               * The element definition. Accepted fields:

 717               * <ul>

 718               *     <li><strong>for</strong> (Required) The file input's page and element Id

 719               *     to associate to, in a 2-item array format: [ 'page_id', 'element_id' ].

 720               *     </li>

 721               *     <li><strong>validate</strong> (Optional) The validation function.</li>

 722               * </ul>

 723               * @param {Array} htmlList

 724               * List of HTML code to output to.

 725               */
 726              fileButton : function( dialog, elementDefinition, htmlList )
 727              {
 728                  if ( arguments.length < 3 )
 729                      return;
 730  
 731                  var _ = initPrivateObject.call( this, elementDefinition ),
 732                      me = this;
 733  
 734                  if ( elementDefinition.validate )
 735                      this.validate = elementDefinition.validate;
 736  
 737                  var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition );
 738                  var onClick = myDefinition.onClick;
 739                  myDefinition.className = ( myDefinition.className ? myDefinition.className + ' ' : '' ) + 'cke_dialog_ui_button';
 740                  myDefinition.onClick = function( evt )
 741                  {
 742                      var target = elementDefinition[ 'for' ];        // [ pageId, elementId ]

 743                      if ( !onClick || onClick.call( this, evt ) !== false )
 744                      {
 745                          dialog.getContentElement( target[0], target[1] ).submit();
 746                          this.disable();
 747                      }
 748                  };
 749  
 750                  dialog.on( 'load', function()
 751                          {
 752                              dialog.getContentElement( elementDefinition[ 'for' ][0], elementDefinition[ 'for' ][1] )._.buttons.push( me );
 753                          } );
 754  
 755                  CKEDITOR.ui.dialog.button.call( this, dialog, myDefinition, htmlList );
 756              },
 757  
 758              html : (function()
 759              {
 760                  var myHtmlRe = /^\s*<[\w:]+\s+([^>]*)?>/,
 761                      theirHtmlRe = /^(\s*<[\w:]+(?:\s+[^>]*)?)((?:.|\r|\n)+)$/,
 762                      emptyTagRe = /\/$/;
 763                  /**

 764                   * A dialog element made from raw HTML code.

 765                   * @extends CKEDITOR.ui.dialog.uiElement

 766                   * @name CKEDITOR.ui.dialog.html

 767                   * @param {CKEDITOR.dialog} dialog Parent dialog object.

 768                   * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition Element definition.

 769                   * Accepted fields:

 770                   * <ul>

 771                   *     <li><strong>html</strong> (Required) HTML code of this element.</li>

 772                   * </ul>

 773                   * @param {Array} htmlList List of HTML code to be added to the dialog's content area.

 774                   * @example

 775                   * @constructor

 776                   */
 777                  return function( dialog, elementDefinition, htmlList )
 778                  {
 779                      if ( arguments.length < 3 )
 780                          return;
 781  
 782                      var myHtmlList = [],
 783                          myHtml,
 784                          theirHtml = elementDefinition.html,
 785                          myMatch, theirMatch;
 786  
 787                      // If the HTML input doesn't contain any tags at the beginning, add a <span> tag around it.

 788                      if ( theirHtml.charAt( 0 ) != '<' )
 789                          theirHtml = '<span>' + theirHtml + '</span>';
 790  
 791                      // Look for focus function in definition.

 792                      var focus = elementDefinition.focus;
 793                      if ( focus )
 794                      {
 795                          var oldFocus = this.focus;
 796                          this.focus = function()
 797                          {
 798                              oldFocus.call( this );
 799                              typeof focus == 'function' && focus.call( this );
 800                              this.fire( 'focus' );
 801                          };
 802                          if ( elementDefinition.isFocusable )
 803                          {
 804                              var oldIsFocusable = this.isFocusable;
 805                              this.isFocusable = oldIsFocusable;
 806                          }
 807                          this.keyboardFocusable = true;
 808                      }
 809  
 810                      CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, myHtmlList, 'span', null, null, '' );
 811  
 812                      // Append the attributes created by the uiElement call to the real HTML.

 813                      myHtml = myHtmlList.join( '' );
 814                      myMatch = myHtml.match( myHtmlRe );
 815                      theirMatch = theirHtml.match( theirHtmlRe ) || [ '', '', '' ];
 816  
 817                      if ( emptyTagRe.test( theirMatch[1] ) )
 818                      {
 819                          theirMatch[1] = theirMatch[1].slice( 0, -1 );
 820                          theirMatch[2] = '/' + theirMatch[2];
 821                      }
 822  
 823                      htmlList.push( [ theirMatch[1], ' ', myMatch[1] || '', theirMatch[2] ].join( '' ) );
 824                  };
 825              })(),
 826  
 827              /**

 828               * Form fieldset for grouping dialog UI elements.

 829               * @constructor

 830               * @extends CKEDITOR.ui.dialog.uiElement

 831               * @param {CKEDITOR.dialog} dialog Parent dialog object.

 832               * @param {Array} childObjList

 833               * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this

 834               * container.

 835               * @param {Array} childHtmlList

 836               * Array of HTML code that correspond to the HTML output of all the

 837               * objects in childObjList.

 838               * @param {Array} htmlList

 839               * Array of HTML code that this element will output to.

 840               * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition

 841               * The element definition. Accepted fields:

 842               * <ul>

 843               *     <li><strong>label</strong> (Optional) The legend of the this fieldset.</li>

 844               *     <li><strong>children</strong> (Required) An array of dialog field definitions which will be grouped inside this fieldset. </li>

 845               * </ul>

 846               */
 847              fieldset : function( dialog, childObjList, childHtmlList, htmlList, elementDefinition )
 848              {
 849                  var legendLabel = elementDefinition.label;
 850                  /** @ignore */

 851                  var innerHTML = function()
 852                  {
 853                      var html = [];
 854                      legendLabel && html.push( '<legend>' + legendLabel + '</legend>' );
 855                      for ( var i = 0; i < childHtmlList.length; i++ )
 856                          html.push( childHtmlList[ i ] );
 857                      return html.join( '' );
 858                  };
 859  
 860                  this._ = { children : childObjList };
 861                  CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'fieldset', null, null, innerHTML );
 862              }
 863  
 864          }, true );
 865  
 866      CKEDITOR.ui.dialog.html.prototype = new CKEDITOR.ui.dialog.uiElement;
 867  
 868      CKEDITOR.ui.dialog.labeledElement.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement,
 869              /** @lends CKEDITOR.ui.dialog.labeledElement.prototype */

 870              {
 871                  /**

 872                   * Sets the label text of the element.

 873                   * @param {String} label The new label text.

 874                   * @returns {CKEDITOR.ui.dialog.labeledElement} The current labeled element.

 875                   * @example

 876                   */
 877                  setLabel : function( label )
 878                  {
 879                      var node = CKEDITOR.document.getById( this._.labelId );
 880                      if ( node.getChildCount() < 1 )
 881                          ( new CKEDITOR.dom.text( label, CKEDITOR.document ) ).appendTo( node );
 882                      else
 883                          node.getChild( 0 ).$.nodeValue = label;
 884                      return this;
 885                  },
 886  
 887                  /**

 888                   * Retrieves the current label text of the elment.

 889                   * @returns {String} The current label text.

 890                   * @example

 891                   */
 892                  getLabel : function()
 893                  {
 894                      var node = CKEDITOR.document.getById( this._.labelId );
 895                      if ( !node || node.getChildCount() < 1 )
 896                          return '';
 897                      else
 898                          return node.getChild( 0 ).getText();
 899                  },
 900  
 901                  /**

 902                   * Defines the onChange event for UI element definitions.

 903                   * @field

 904                   * @type Object

 905                   * @example

 906                   */
 907                  eventProcessors : commonEventProcessors
 908              }, true );
 909  
 910      CKEDITOR.ui.dialog.button.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement,
 911              /** @lends CKEDITOR.ui.dialog.button.prototype */

 912              {
 913                  /**

 914                   * Simulates a click to the button.

 915                   * @example

 916                   * @returns {Object} Return value of the 'click' event.

 917                   */
 918                  click : function()
 919                  {
 920                      if ( !this._.disabled )
 921                          return this.fire( 'click', { dialog : this._.dialog } );
 922                      this.getElement().$.blur();
 923                      return false;
 924                  },
 925  
 926                  /**

 927                   * Enables the button.

 928                   * @example

 929                   */
 930                  enable : function()
 931                  {
 932                      this._.disabled = false;
 933                      var element = this.getElement();
 934                      element && element.removeClass( 'disabled' );
 935                  },
 936  
 937                  /**

 938                   * Disables the button.

 939                   * @example

 940                   */
 941                  disable : function()
 942                  {
 943                      this._.disabled = true;
 944                      this.getElement().addClass( 'disabled' );
 945                  },
 946  
 947                  isVisible : function()
 948                  {
 949                      return this.getElement().getFirst().isVisible();
 950                  },
 951  
 952                  isEnabled : function()
 953                  {
 954                      return !this._.disabled;
 955                  },
 956  
 957                  /**

 958                   * Defines the onChange event and onClick for button element definitions.

 959                   * @field

 960                   * @type Object

 961                   * @example

 962                   */
 963                  eventProcessors : CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,
 964                      {
 965                          /** @ignore */

 966                          onClick : function( dialog, func )
 967                          {
 968                              this.on( 'click', func );
 969                          }
 970                      }, true ),
 971  
 972                  /**

 973                   * Handler for the element's access key up event. Simulates a click to

 974                   * the button.

 975                   * @example

 976                   */
 977                  accessKeyUp : function()
 978                  {
 979                      this.click();
 980                  },
 981  
 982                  /**

 983                   * Handler for the element's access key down event. Simulates a mouse

 984                   * down to the button.

 985                   * @example

 986                   */
 987                  accessKeyDown : function()
 988                  {
 989                      this.focus();
 990                  },
 991  
 992                  keyboardFocusable : true
 993              }, true );
 994  
 995      CKEDITOR.ui.dialog.textInput.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement,
 996              /** @lends CKEDITOR.ui.dialog.textInput.prototype */

 997              {
 998                  /**

 999                   * Gets the text input DOM element under this UI object.

1000                   * @example

1001                   * @returns {CKEDITOR.dom.element} The DOM element of the text input.

1002                   */
1003                  getInputElement : function()
1004                  {
1005                      return CKEDITOR.document.getById( this._.inputId );
1006                  },
1007  
1008                  /**

1009                   * Puts focus into the text input.

1010                   * @example

1011                   */
1012                  focus : function()
1013                  {
1014                      var me = this.selectParentTab();
1015  
1016                      // GECKO BUG: setTimeout() is needed to workaround invisible selections.

1017                      setTimeout( function()
1018                          {
1019                              var element = me.getInputElement();
1020                              element && element.$.focus();
1021                          }, 0 );
1022                  },
1023  
1024                  /**

1025                   * Selects all the text in the text input.

1026                   * @example

1027                   */
1028                  select : function()
1029                  {
1030                      var me = this.selectParentTab();
1031  
1032                      // GECKO BUG: setTimeout() is needed to workaround invisible selections.

1033                      setTimeout( function()
1034                          {
1035                              var e = me.getInputElement();
1036                              if ( e )
1037                              {
1038                                  e.$.focus();
1039                                  e.$.select();
1040                              }
1041                          }, 0 );
1042                  },
1043  
1044                  /**

1045                   * Handler for the text input's access key up event. Makes a select()

1046                   * call to the text input.

1047                   * @example

1048                   */
1049                  accessKeyUp : function()
1050                  {
1051                      this.select();
1052                  },
1053  
1054                  /**

1055                   * Sets the value of this text input object.

1056                   * @param {Object} value The new value.

1057                   * @returns {CKEDITOR.ui.dialog.textInput} The current UI element.

1058                   * @example

1059                   * uiElement.setValue( 'Blamo' );

1060                   */
1061                  setValue : function( value )
1062                  {
1063                      !value && ( value = '' );
1064                      return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply( this, arguments );
1065                  },
1066  
1067                  keyboardFocusable : true
1068              }, commonPrototype, true );
1069  
1070      CKEDITOR.ui.dialog.textarea.prototype = new CKEDITOR.ui.dialog.textInput();
1071  
1072      CKEDITOR.ui.dialog.select.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement,
1073              /** @lends CKEDITOR.ui.dialog.select.prototype */

1074              {
1075                  /**

1076                   * Gets the DOM element of the select box.

1077                   * @returns {CKEDITOR.dom.element} The &lt;select&gt; element of this UI

1078                   * element.

1079                   * @example

1080                   */
1081                  getInputElement : function()
1082                  {
1083                      return this._.select.getElement();
1084                  },
1085  
1086                  /**

1087                   * Adds an option to the select box.

1088                   * @param {String} label Option label.

1089                   * @param {String} value (Optional) Option value, if not defined it'll be

1090                   * assumed to be the same as the label.

1091                   * @param {Number} index (Optional) Position of the option to be inserted

1092                   * to. If not defined the new option will be inserted to the end of list.

1093                   * @example

1094                   * @returns {CKEDITOR.ui.dialog.select} The current select UI element.

1095                   */
1096                  add : function( label, value, index )
1097                  {
1098                      var option = new CKEDITOR.dom.element( 'option', this.getDialog().getParentEditor().document ),
1099                          selectElement = this.getInputElement().$;
1100                      option.$.text = label;
1101                      option.$.value = ( value === undefined || value === null ) ? label : value;
1102                      if ( index === undefined || index === null )
1103                      {
1104                          if ( CKEDITOR.env.ie )
1105                              selectElement.add( option.$ );
1106                          else
1107                              selectElement.add( option.$, null );
1108                      }
1109                      else
1110                          selectElement.add( option.$, index );
1111                      return this;
1112                  },
1113  
1114                  /**

1115                   * Removes an option from the selection list.

1116                   * @param {Number} index Index of the option to be removed.

1117                   * @example

1118                   * @returns {CKEDITOR.ui.dialog.select} The current select UI element.

1119                   */
1120                  remove : function( index )
1121                  {
1122                      var selectElement = this.getInputElement().$;
1123                      selectElement.remove( index );
1124                      return this;
1125                  },
1126  
1127                  /**

1128                   * Clears all options out of the selection list.

1129                   * @returns {CKEDITOR.ui.dialog.select} The current select UI element.

1130                   */
1131                  clear : function()
1132                  {
1133                      var selectElement = this.getInputElement().$;
1134                      while ( selectElement.length > 0 )
1135                          selectElement.remove( 0 );
1136                      return this;
1137                  },
1138  
1139                  keyboardFocusable : true
1140              }, commonPrototype, true );
1141  
1142      CKEDITOR.ui.dialog.checkbox.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement,
1143              /** @lends CKEDITOR.ui.dialog.checkbox.prototype */

1144              {
1145                  /**

1146                   * Gets the checkbox DOM element.

1147                   * @example

1148                   * @returns {CKEDITOR.dom.element} The DOM element of the checkbox.

1149                   */
1150                  getInputElement : function()
1151                  {
1152                      return this._.checkbox.getElement();
1153                  },
1154  
1155                  /**

1156                   * Sets the state of the checkbox.

1157                   * @example

1158                   * @param {Boolean} true to tick the checkbox, false to untick it.

1159                   * @param {Boolean} noChangeEvent Internal commit, to supress 'change' event on this element.

1160                   */
1161                  setValue : function( checked, noChangeEvent )
1162                  {
1163                      this.getInputElement().$.checked = checked;
1164                      !noChangeEvent && this.fire( 'change', { value : checked } );
1165                  },
1166  
1167                  /**

1168                   * Gets the state of the checkbox.

1169                   * @example

1170                   * @returns {Boolean} true means the checkbox is ticked, false means it's not ticked.

1171                   */
1172                  getValue : function()
1173                  {
1174                      return this.getInputElement().$.checked;
1175                  },
1176  
1177                  /**

1178                   * Handler for the access key up event. Toggles the checkbox.

1179                   * @example

1180                   */
1181                  accessKeyUp : function()
1182                  {
1183                      this.setValue( !this.getValue() );
1184                  },
1185  
1186                  /**

1187                   * Defines the onChange event for UI element definitions.

1188                   * @field

1189                   * @type Object

1190                   * @example

1191                   */
1192                  eventProcessors :
1193                  {
1194                      onChange : function( dialog, func )
1195                      {
1196                          if ( !CKEDITOR.env.ie )
1197                              return commonEventProcessors.onChange.apply( this, arguments );
1198                          else
1199                          {
1200                              dialog.on( 'load', function()
1201                                  {
1202                                      var element = this._.checkbox.getElement();
1203                                      element.on( 'propertychange', function( evt )
1204                                          {
1205                                              evt = evt.data.$;
1206                                              if ( evt.propertyName == 'checked' )
1207                                                  this.fire( 'change', { value : element.$.checked } );
1208                                          }, this );
1209                                  }, this );
1210                              this.on( 'change', func );
1211                          }
1212                          return null;
1213                      }
1214                  },
1215  
1216                  keyboardFocusable : true
1217              }, commonPrototype, true );
1218  
1219      CKEDITOR.ui.dialog.radio.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement,
1220              /** @lends CKEDITOR.ui.dialog.radio.prototype */

1221              {
1222                  /**

1223                   * Checks one of the radio buttons in this button group.

1224                   * @example

1225                   * @param {String} value The value of the button to be chcked.

1226                   * @param {Boolean} noChangeEvent Internal commit, to supress 'change' event on this element.

1227                   */
1228                  setValue : function( value, noChangeEvent )
1229                  {
1230                      var children = this._.children,
1231                          item;
1232                      for ( var i = 0 ; ( i < children.length ) && ( item = children[i] ) ; i++ )
1233                          item.getElement().$.checked = ( item.getValue() == value );
1234                      !noChangeEvent && this.fire( 'change', { value : value } );
1235                  },
1236  
1237                  /**

1238                   * Gets the value of the currently checked radio button.

1239                   * @example

1240                   * @returns {String} The currently checked button's value.

1241                   */
1242                  getValue : function()
1243                  {
1244                      var children = this._.children;
1245                      for ( var i = 0 ; i < children.length ; i++ )
1246                      {
1247                          if ( children[i].getElement().$.checked )
1248                              return children[i].getValue();
1249                      }
1250                      return null;
1251                  },
1252  
1253                  /**

1254                   * Handler for the access key up event. Focuses the currently

1255                   * selected radio button, or the first radio button if none is

1256                   * selected.

1257                   * @example

1258                   */
1259                  accessKeyUp : function()
1260                  {
1261                      var children = this._.children, i;
1262                      for ( i = 0 ; i < children.length ; i++ )
1263                      {
1264                          if ( children[i].getElement().$.checked )
1265                          {
1266                              children[i].getElement().focus();
1267                              return;
1268                          }
1269                      }
1270                      children[0].getElement().focus();
1271                  },
1272  
1273                  /**

1274                   * Defines the onChange event for UI element definitions.

1275                   * @field

1276                   * @type Object

1277                   * @example

1278                   */
1279                  eventProcessors :
1280                  {
1281                      onChange : function( dialog, func )
1282                      {
1283                          if ( !CKEDITOR.env.ie )
1284                              return commonEventProcessors.onChange.apply( this, arguments );
1285                          else
1286                          {
1287                              dialog.on( 'load', function()
1288                                  {
1289                                      var children = this._.children, me = this;
1290                                      for ( var i = 0 ; i < children.length ; i++ )
1291                                      {
1292                                          var element = children[i].getElement();
1293                                          element.on( 'propertychange', function( evt )
1294                                              {
1295                                                  evt = evt.data.$;
1296                                                  if ( evt.propertyName == 'checked' && this.$.checked )
1297                                                      me.fire( 'change', { value : this.getAttribute( 'value' ) } );
1298                                              } );
1299                                      }
1300                                  }, this );
1301                              this.on( 'change', func );
1302                          }
1303                          return null;
1304                      }
1305                  },
1306  
1307                  keyboardFocusable : true
1308              }, commonPrototype, true );
1309  
1310      CKEDITOR.ui.dialog.file.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement,
1311              commonPrototype,
1312              /** @lends CKEDITOR.ui.dialog.file.prototype */

1313              {
1314                  /**

1315                   * Gets the &lt;input&gt; element of this file input.

1316                   * @returns {CKEDITOR.dom.element} The file input element.

1317                   * @example

1318                   */
1319                  getInputElement : function()
1320                  {
1321                      var frameDocument = CKEDITOR.document.getById( this._.frameId ).getFrameDocument();
1322                      return frameDocument.$.forms.length > 0 ?
1323                          new CKEDITOR.dom.element( frameDocument.$.forms[0].elements[0] ) :
1324                          this.getElement();
1325                  },
1326  
1327                  /**

1328                   * Uploads the file in the file input.

1329                   * @returns {CKEDITOR.ui.dialog.file} This object.

1330                   * @example

1331                   */
1332                  submit : function()
1333                  {
1334                      this.getInputElement().getParent().$.submit();
1335                      return this;
1336                  },
1337  
1338                  /**

1339                   * Get the action assigned to the form.

1340                   * @returns {String} The value of the action.

1341                   * @example

1342                   */
1343                  getAction : function()
1344                  {
1345                      return this.getInputElement().getParent().$.action;
1346                  },
1347  
1348                  /**

1349                   * The events must be applied on the inner input element, and

1350                   * that must be done when the iframe & form has been loaded

1351                   */
1352                  registerEvents : function( definition )
1353                  {
1354                      var regex = /^on([A-Z]\w+)/,
1355                          match;
1356  
1357                      var registerDomEvent = function( uiElement, dialog, eventName, func )
1358                      {
1359                          uiElement.on( 'formLoaded', function()
1360                          {
1361                              uiElement.getInputElement().on( eventName, func, uiElement );
1362                          });
1363                      };
1364  
1365                      for ( var i in definition )
1366                      {
1367                          if ( !( match = i.match( regex ) ) )
1368                              continue;
1369  
1370                          if ( this.eventProcessors[i] )
1371                              this.eventProcessors[i].call( this, this._.dialog, definition[i] );
1372                          else
1373                              registerDomEvent( this, this._.dialog, match[1].toLowerCase(), definition[i] );
1374                      }
1375  
1376                      return this;
1377                  },
1378  
1379                  /**

1380                   * Redraws the file input and resets the file path in the file input.

1381                   * The redraw logic is necessary because non-IE browsers tend to clear

1382                   * the &lt;iframe&gt; containing the file input after closing the dialog.

1383                   * @example

1384                   */
1385                  reset : function()
1386                  {
1387                      var frameElement = CKEDITOR.document.getById( this._.frameId ),
1388                          frameDocument = frameElement.getFrameDocument(),
1389                          elementDefinition = this._.definition,
1390                          buttons = this._.buttons,
1391                          callNumber = this.formLoadedNumber,
1392                          unloadNumber = this.formUnloadNumber,
1393                          langDir = this._.dialog._.editor.lang.dir,
1394                          langCode = this._.dialog._.editor.langCode;
1395  
1396                      // The callback function for the iframe, but we must call tools.addFunction only once

1397                      // so we store the function number in this.formLoadedNumber

1398                      if (!callNumber)
1399                      {
1400                          callNumber = this.formLoadedNumber = CKEDITOR.tools.addFunction(
1401                              function()
1402                              {
1403                                  // Now we can apply the events to the input type=file

1404                                  this.fire( 'formLoaded' ) ;
1405                              }, this ) ;
1406  
1407                          // Remove listeners attached to the content of the iframe (the file input)

1408                          unloadNumber = this.formUnloadNumber = CKEDITOR.tools.addFunction(
1409                              function()
1410                              {
1411                                  this.getInputElement().clearCustomData();
1412                              }, this ) ;
1413  
1414                          this.getDialog()._.editor.on( 'destroy', function()
1415                                  {
1416                                      CKEDITOR.tools.removeFunction( callNumber );
1417                                      CKEDITOR.tools.removeFunction( unloadNumber );
1418                                  } );
1419                      }
1420  
1421  					function generateFormField()
1422                      {
1423                          frameDocument.$.open();
1424  
1425                          // Support for custom document.domain in IE.

1426                          if ( CKEDITOR.env.isCustomDomain() )
1427                              frameDocument.$.domain = document.domain;
1428  
1429                          var size = '';
1430                          if ( elementDefinition.size )
1431                              size = elementDefinition.size - ( CKEDITOR.env.ie  ? 7 : 0 );    // "Browse" button is bigger in IE.

1432  
1433                          frameDocument.$.write( [ '<html dir="' + langDir + '" lang="' + langCode + '"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">',
1434                                  '<form enctype="multipart/form-data" method="POST" dir="' + langDir + '" lang="' + langCode + '" action="',
1435                                  CKEDITOR.tools.htmlEncode( elementDefinition.action ),
1436                                  '">',
1437                                  '<input type="file" name="',
1438                                  CKEDITOR.tools.htmlEncode( elementDefinition.id || 'cke_upload' ),
1439                                  '" size="',
1440                                  CKEDITOR.tools.htmlEncode( size > 0 ? size : "" ),
1441                                  '" />',
1442                                  '</form>',
1443                                  '</body></html>',
1444                                  '<script>window.parent.CKEDITOR.tools.callFunction(' + callNumber + ');',
1445                                  'window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(' + unloadNumber + ')}</script>' ].join( '' ) );
1446  
1447                          frameDocument.$.close();
1448  
1449                          for ( var i = 0 ; i < buttons.length ; i++ )
1450                              buttons[i].enable();
1451                      }
1452  
1453                      // #3465: Wait for the browser to finish rendering the dialog first.

1454                      if ( CKEDITOR.env.gecko )
1455                          setTimeout( generateFormField, 500 );
1456                      else
1457                          generateFormField();
1458                  },
1459  
1460                  getValue : function()
1461                  {
1462                      return this.getInputElement().$.value;
1463                  },
1464  
1465                  /***

1466                   * The default value of input type="file" is an empty string, but during initialization

1467                   * of this UI element, the iframe still isn't ready so it can't be read from that object

1468                   * Setting it manually prevents later issues about the current value ("") being different

1469                   * of the initial value (undefined as it asked for .value of a div)

1470                   */
1471                  setInitValue : function()
1472                  {
1473                      this._.initValue = '';
1474                  },
1475  
1476                  /**

1477                   * Defines the onChange event for UI element definitions.

1478                   * @field

1479                   * @type Object

1480                   * @example

1481                   */
1482                  eventProcessors :
1483                  {
1484                      onChange : function( dialog, func )
1485                      {
1486                          // If this method is called several times (I'm not sure about how this can happen but the default

1487                          // onChange processor includes this protection)

1488                          // In order to reapply to the new element, the property is deleted at the beggining of the registerEvents method

1489                          if ( !this._.domOnChangeRegistered )
1490                          {
1491                              // By listening for the formLoaded event, this handler will get reapplied when a new

1492                              // form is created

1493                              this.on( 'formLoaded', function()
1494                              {
1495                                  this.getInputElement().on( 'change', function(){ this.fire( 'change', { value : this.getValue() } ); }, this );
1496                              }, this );
1497                              this._.domOnChangeRegistered = true;
1498                          }
1499  
1500                          this.on( 'change', func );
1501                      }
1502                  },
1503  
1504                  keyboardFocusable : true
1505              }, true );
1506  
1507      CKEDITOR.ui.dialog.fileButton.prototype = new CKEDITOR.ui.dialog.button;
1508  
1509      CKEDITOR.ui.dialog.fieldset.prototype = CKEDITOR.tools.clone( CKEDITOR.ui.dialog.hbox.prototype );
1510  
1511      CKEDITOR.dialog.addUIElement( 'text', textBuilder );
1512      CKEDITOR.dialog.addUIElement( 'password', textBuilder );
1513      CKEDITOR.dialog.addUIElement( 'textarea', commonBuilder );
1514      CKEDITOR.dialog.addUIElement( 'checkbox', commonBuilder );
1515      CKEDITOR.dialog.addUIElement( 'radio', commonBuilder );
1516      CKEDITOR.dialog.addUIElement( 'button', commonBuilder );
1517      CKEDITOR.dialog.addUIElement( 'select', commonBuilder );
1518      CKEDITOR.dialog.addUIElement( 'file', commonBuilder );
1519      CKEDITOR.dialog.addUIElement( 'fileButton', commonBuilder );
1520      CKEDITOR.dialog.addUIElement( 'html', commonBuilder );
1521      CKEDITOR.dialog.addUIElement( 'fieldset', containerBuilder );
1522  })();


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7