JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.2
[ckeditor.git] / _source / plugins / dialogui / plugin.js
index b6cd10c..1567c94 100644 (file)
@@ -13,6 +13,7 @@ CKEDITOR.plugins.add( 'dialogui' );
        {\r
                this._ || ( this._ = {} );\r
                this._['default'] = this._.initValue = elementDefinition['default'] || '';\r
+               this._.required = elementDefinition[ 'required' ] || false;\r
                var args = [ this._ ];\r
                for ( var i = 1 ; i < arguments.length ; i++ )\r
                        args.push( arguments[i] );\r
@@ -34,6 +35,23 @@ CKEDITOR.plugins.add( 'dialogui' );
                        return new CKEDITOR.ui.dialog[elementDefinition.type]( dialog, elementDefinition, output );\r
                }\r
        },\r
+       containerBuilder =\r
+       {\r
+               build : function( dialog, elementDefinition, output )\r
+               {\r
+                       var children = elementDefinition.children,\r
+                               child,\r
+                               childHtmlList = [],\r
+                               childObjList = [];\r
+                       for ( var i = 0 ; ( i < children.length && ( child = children[i] ) ) ; i++ )\r
+                       {\r
+                               var childHtml = [];\r
+                               childHtmlList.push( childHtml );\r
+                               childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) );\r
+                       }\r
+                       return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition );\r
+               }\r
+       },\r
        commonPrototype =\r
        {\r
                isChanged : function()\r
@@ -129,13 +147,14 @@ CKEDITOR.plugins.add( 'dialogui' );
                                {\r
                                        var html = [];\r
                                        if ( elementDefinition.labelLayout != 'horizontal' )\r
-                                               html.push( '<div class="cke_dialog_ui_labeled_label" id="',\r
-                                                               _.labelId,\r
-                                                               '" >',\r
+                                               html.push( '<label class="cke_dialog_ui_labeled_label" ',\r
+                                                               ' id="'+  _.labelId + '"',\r
+                                                               ' for="' + _.inputId + '"',\r
+                                                               ' style="' + elementDefinition.labelStyle + '">',\r
                                                                elementDefinition.label,\r
-                                                               '</div>',\r
-                                                               '<div class="cke_dialog_ui_labeled_content">',\r
-                                                               contentHtml( dialog, elementDefinition ),\r
+                                                               '</label>',\r
+                                                               '<div class="cke_dialog_ui_labeled_content" role="presentation">',\r
+                                                               contentHtml.call( this, dialog, elementDefinition ),\r
                                                                '</div>' );\r
                                        else\r
                                        {\r
@@ -147,14 +166,17 @@ CKEDITOR.plugins.add( 'dialogui' );
                                                        [\r
                                                                {\r
                                                                        type : 'html',\r
-                                                                       html : '<span class="cke_dialog_ui_labeled_label" ' +\r
-                                                                               'id="' + _.labelId + '">' +  CKEDITOR.tools.htmlEncode( elementDefinition.label ) +\r
+                                                                       html : '<label class="cke_dialog_ui_labeled_label"' +\r
+                                                                               ' id="' + _.labelId + '"' +\r
+                                                                               ' for="' + _.inputId + '"' +\r
+                                                                               ' style="' + elementDefinition.labelStyle + '">' +\r
+                                                                                  CKEDITOR.tools.htmlEncode( elementDefinition.label ) +\r
                                                                                '</span>'\r
                                                                },\r
                                                                {\r
                                                                        type : 'html',\r
                                                                        html : '<span class="cke_dialog_ui_labeled_content">' +\r
-                                                                               contentHtml( dialog, elementDefinition ) +\r
+                                                                               contentHtml.call( this, dialog, elementDefinition ) +\r
                                                                                '</span>'\r
                                                                }\r
                                                        ]\r
@@ -163,7 +185,7 @@ CKEDITOR.plugins.add( 'dialogui' );
                                        }\r
                                        return html.join( '' );\r
                                };\r
-                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'div', null, null, innerHTML );\r
+                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'div', null, { role : 'presentation' }, innerHTML );\r
                        },\r
 \r
                        /**\r
@@ -236,12 +258,15 @@ CKEDITOR.plugins.add( 'dialogui' );
                                {\r
                                        // IE BUG: Text input fields in IE at 100% would exceed a <td> or inline\r
                                        // container's width, so need to wrap it inside a <div>.\r
-                                       var html = [ '<div class="cke_dialog_ui_input_', elementDefinition.type, '"' ];\r
+                                       var html = [ '<div class="cke_dialog_ui_input_', elementDefinition.type, '" role="presentation"' ];\r
 \r
                                        if ( elementDefinition.width )\r
                                                html.push( 'style="width:'+ elementDefinition.width +'" ' );\r
 \r
                                        html.push( '><input ' );\r
+\r
+                                       attributes[ 'aria-labelledby' ] = this._.labelId;\r
+                                       this._.required && ( attributes[ 'aria-required' ] = this._.required );\r
                                        for ( var i in attributes )\r
                                                html.push( i + '="' + attributes[i] + '" ' );\r
                                        html.push( ' /></div>' );\r
@@ -290,7 +315,9 @@ CKEDITOR.plugins.add( 'dialogui' );
                                /** @ignore */\r
                                var innerHTML = function()\r
                                {\r
-                                       var html = [ '<div class="cke_dialog_ui_input_textarea"><textarea class="cke_dialog_ui_input_textarea" id="', domId, '" ' ];\r
+                                       attributes[ 'aria-labelledby' ] = this._.labelId;\r
+                                       this._.required && ( attributes[ 'aria-required' ] = this._.required );\r
+                                       var html = [ '<div class="cke_dialog_ui_input_textarea" role="presentation"><textarea class="cke_dialog_ui_input_textarea" id="', domId, '" ' ];\r
                                        for ( var i in attributes )\r
                                                html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[i] ) + '" ' );\r
                                        html.push( '>', CKEDITOR.tools.htmlEncode( me._['default'] ), '</textarea></div>' );\r
@@ -334,13 +361,15 @@ CKEDITOR.plugins.add( 'dialogui' );
                                                        {\r
                                                                id : elementDefinition.id ? elementDefinition.id + '_checkbox' : CKEDITOR.tools.getNextNumber() + '_checkbox'\r
                                                        }, true ),\r
-                                               html = [],\r
-                                               attributes = { 'class' : 'cke_dialog_ui_checkbox_input', type : 'checkbox' };\r
+                                               html = [];\r
+\r
+                                       var labelId = CKEDITOR.tools.getNextNumber() + '_label';\r
+                                       var attributes = { 'class' : 'cke_dialog_ui_checkbox_input', type : 'checkbox', 'aria-labelledby' : labelId };\r
                                        cleanInnerDefinition( myDefinition );\r
                                        if ( elementDefinition[ 'default' ] )\r
                                                attributes.checked = 'checked';\r
                                        _.checkbox = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'input', null, attributes );\r
-                                       html.push( ' <label for="', attributes.id, '">',\r
+                                       html.push( ' <label id="', labelId, '" for="', attributes.id, '">',\r
                                                        CKEDITOR.tools.htmlEncode( elementDefinition.label ),\r
                                                        '</label>' );\r
                                        return html.join( '' );\r
@@ -385,22 +414,23 @@ CKEDITOR.plugins.add( 'dialogui' );
                                var innerHTML = function()\r
                                {\r
                                        var inputHtmlList = [], html = [],\r
-                                               commonAttributes = { 'class' : 'cke_dialog_ui_radio_item' },\r
+                                               commonAttributes = { 'class' : 'cke_dialog_ui_radio_item', 'aria-labelledby' : this._.labelId },\r
                                                commonName = elementDefinition.id ? elementDefinition.id + '_radio' : CKEDITOR.tools.getNextNumber() + '_radio';\r
                                        for ( var i = 0 ; i < elementDefinition.items.length ; i++ )\r
                                        {\r
                                                var item = elementDefinition.items[i],\r
                                                        title = item[2] !== undefined ? item[2] : item[0],\r
                                                        value = item[1] !== undefined ? item[1] : item[0],\r
+                                                       inputId = CKEDITOR.tools.getNextNumber() + '_radio_input',\r
+                                                       labelId = inputId + '_label',\r
                                                        inputDefinition = CKEDITOR.tools.extend( {}, elementDefinition,\r
                                                                        {\r
-                                                                               id : CKEDITOR.tools.getNextNumber() + '_radio_input',\r
+                                                                               id : inputId,\r
                                                                                title : null,\r
                                                                                type : null\r
                                                                        }, true ),\r
                                                        labelDefinition = CKEDITOR.tools.extend( {}, inputDefinition,\r
                                                                        {\r
-                                                                               id : null,\r
                                                                                title : title\r
                                                                        }, true ),\r
                                                        inputAttributes =\r
@@ -408,7 +438,8 @@ CKEDITOR.plugins.add( 'dialogui' );
                                                                type : 'radio',\r
                                                                'class' : 'cke_dialog_ui_radio_input',\r
                                                                name : commonName,\r
-                                                               value : value\r
+                                                               value : value,\r
+                                                               'aria-labelledby' : labelId\r
                                                        },\r
                                                        inputHtml = [];\r
                                                if ( me._['default'] == value )\r
@@ -417,7 +448,7 @@ CKEDITOR.plugins.add( 'dialogui' );
                                                cleanInnerDefinition( labelDefinition );\r
                                                children.push( new CKEDITOR.ui.dialog.uiElement( dialog, inputDefinition, inputHtml, 'input', null, inputAttributes ) );\r
                                                inputHtml.push( ' ' );\r
-                                               new CKEDITOR.ui.dialog.uiElement( dialog, labelDefinition, inputHtml, 'label', null, { 'for' : inputAttributes.id },\r
+                                               new CKEDITOR.ui.dialog.uiElement( dialog, labelDefinition, inputHtml, 'label', null, { id : labelId, 'for' : inputAttributes.id },\r
                                                           item[0] );\r
                                                inputHtmlList.push( inputHtml.join( '' ) );\r
                                        }\r
@@ -473,6 +504,15 @@ CKEDITOR.plugins.add( 'dialogui' );
                                                                        me.fire( 'click', { dialog : me.getDialog() } );\r
                                                                        evt.data.preventDefault();\r
                                                                } );\r
+\r
+                                                       element.on( 'keydown', function( evt )\r
+                                                               {\r
+                                                                       if ( evt.data.getKeystroke() in { 32:1, 13:1 } )\r
+                                                                       {\r
+                                                                               me.click();\r
+                                                                               evt.data.preventDefault();\r
+                                                                       }\r
+                                                               } );\r
                                                })();\r
 \r
                                                element.unselectable();\r
@@ -481,6 +521,7 @@ CKEDITOR.plugins.add( 'dialogui' );
                                var outerDefinition = CKEDITOR.tools.extend( {}, elementDefinition );\r
                                delete outerDefinition.style;\r
 \r
+                               var labelId = CKEDITOR.tools.getNextNumber() + '_label';\r
                                CKEDITOR.ui.dialog.uiElement.call(\r
                                        this,\r
                                        dialog,\r
@@ -493,9 +534,11 @@ CKEDITOR.plugins.add( 'dialogui' );
                                                href : 'javascript:void(0)',\r
                                                title : elementDefinition.label,\r
                                                hidefocus : 'true',\r
-                                               'class' : elementDefinition['class']\r
+                                               'class' : elementDefinition['class'],\r
+                                               role : 'button',\r
+                                               'aria-labelledby' : labelId\r
                                        },\r
-                                       '<span class="cke_dialog_ui_button">' +\r
+                                       '<span id="' + labelId + '" class="cke_dialog_ui_button">' +\r
                                                CKEDITOR.tools.htmlEncode( elementDefinition.label ) +\r
                                        '</span>' );\r
                        },\r
@@ -534,6 +577,7 @@ CKEDITOR.plugins.add( 'dialogui' );
                                if ( elementDefinition.validate )\r
                                        this.validate = elementDefinition.validate;\r
 \r
+                               _.inputId = CKEDITOR.tools.getNextNumber() + '_select';\r
                                /** @ignore */\r
                                var innerHTML = function()\r
                                {\r
@@ -543,7 +587,7 @@ CKEDITOR.plugins.add( 'dialogui' );
                                                        }, true ),\r
                                                html = [],\r
                                                innerHTML = [],\r
-                                               attributes = { 'class' : 'cke_dialog_ui_input_select' };\r
+                                               attributes = { 'id' : _.inputId, 'class' : 'cke_dialog_ui_input_select', 'aria-labelledby' : this._.labelId };\r
 \r
                                        // Add multiple and size attributes from element definition.\r
                                        if ( elementDefinition.size != undefined )\r
@@ -723,13 +767,14 @@ CKEDITOR.plugins.add( 'dialogui' );
                                                theirHtml = '<span>' + theirHtml + '</span>';\r
 \r
                                        // Look for focus function in definition.\r
-                                       if ( elementDefinition.focus )\r
+                                       var focus = elementDefinition.focus;\r
+                                       if ( focus )\r
                                        {\r
                                                var oldFocus = this.focus;\r
                                                this.focus = function()\r
                                                {\r
                                                        oldFocus.call( this );\r
-                                                       elementDefinition.focus.call( this );\r
+                                                       typeof focus == 'function' && focus.call( this );\r
                                                        this.fire( 'focus' );\r
                                                };\r
                                                if ( elementDefinition.isFocusable )\r
@@ -755,7 +800,45 @@ CKEDITOR.plugins.add( 'dialogui' );
 \r
                                        htmlList.push( [ theirMatch[1], ' ', myMatch[1] || '', theirMatch[2] ].join( '' ) );\r
                                };\r
-                       })()\r
+                       })(),\r
+\r
+                       /**\r
+                        * Form fieldset for grouping dialog UI elements.\r
+                        * @constructor\r
+                        * @extends CKEDITOR.ui.dialog.uiElement\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog object.\r
+                        * @param {Array} childObjList\r
+                        * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this\r
+                        * container.\r
+                        * @param {Array} childHtmlList\r
+                        * Array of HTML code that correspond to the HTML output of all the\r
+                        * objects in childObjList.\r
+                        * @param {Array} htmlList\r
+                        * Array of HTML code that this element will output to.\r
+                        * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        * <ul>\r
+                        *      <li><strong>label</strong> (Optional) The legend of the this fieldset.</li>\r
+                        *      <li><strong>children</strong> (Required) An array of dialog field definitions which will be grouped inside this fieldset. </li>\r
+                        * </ul>\r
+                        */\r
+                       fieldset : function( dialog, childObjList, childHtmlList, htmlList, elementDefinition )\r
+                       {\r
+                               var legendLabel = elementDefinition.label;\r
+                               /** @ignore */\r
+                               var innerHTML = function()\r
+                               {\r
+                                       var html = [];\r
+                                       legendLabel && html.push( '<legend>' + legendLabel + '</legend>' );\r
+                                       for ( var i = 0; i < childHtmlList.length; i++ )\r
+                                               html.push( childHtmlList[ i ] );\r
+                                       return html.join( '' );\r
+                               };\r
+\r
+                               this._ = { children : childObjList };\r
+                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'fieldset', null, null, innerHTML );\r
+                       }\r
+\r
                }, true );\r
 \r
        CKEDITOR.ui.dialog.html.prototype = new CKEDITOR.ui.dialog.uiElement;\r
@@ -1309,6 +1392,8 @@ CKEDITOR.plugins.add( 'dialogui' );
 \r
        CKEDITOR.ui.dialog.fileButton.prototype = new CKEDITOR.ui.dialog.button;\r
 \r
+       CKEDITOR.ui.dialog.fieldset.prototype = CKEDITOR.tools.clone( CKEDITOR.ui.dialog.hbox.prototype );\r
+\r
        CKEDITOR.dialog.addUIElement( 'text', textBuilder );\r
        CKEDITOR.dialog.addUIElement( 'password', textBuilder );\r
        CKEDITOR.dialog.addUIElement( 'textarea', commonBuilder );\r
@@ -1319,4 +1404,5 @@ CKEDITOR.plugins.add( 'dialogui' );
        CKEDITOR.dialog.addUIElement( 'file', commonBuilder );\r
        CKEDITOR.dialog.addUIElement( 'fileButton', commonBuilder );\r
        CKEDITOR.dialog.addUIElement( 'html', commonBuilder );\r
+       CKEDITOR.dialog.addUIElement( 'fieldset', containerBuilder );\r
 })();\r