Ticket #3624: 3624.patch

File 3624.patch, 3.7 KB (added by Garry Yao, 14 years ago)
  • _source/plugins/a11ycompat/plugin.js

     
    1212        var dtd = CKEDITOR.dtd,
    1313                env = CKEDITOR.env;
    1414
    15         // List of in-use ARIA roles and states. 
     15        // List of in-use ARIA roles and states.
    1616        var roles = [ 'role' ],
    1717                 // List of roles that role type should not be announced.
    1818                 silentRoles = { 'region' : 1 },
     
    2222        function lookupARIASupport( role, tagName )
    2323        {
    2424                return {
    25                                 'dialog' :       env.gecko && env.version >= 10900,
    2625                                'region' : env.gecko && env.version >= 10900
    2726                        }[ role ];
    2827        }
    2928
     29        function speak( textToSpeech, manner )
     30        {
     31                var speaker = CKEDITOR.document.getById( 'live-region' );
     32                if( !speaker )
     33                {
     34                        speaker = CKEDITOR.dom.element.createFromHtml(
     35                                        '<span class="cke_live_region" id="live-region" ' +
     36                                        'style="position: absolute; display: block; width: 0; height: 0; overflow: hidden;"' +
     37                                        '>&nbsp;</span>' );
     38                        CKEDITOR.document.getBody().append( speaker );
     39                }
     40
     41                speaker.setText( textToSpeech );
     42                speaker.setAttribute( 'aria-live', manner || 'rude' );
     43                CKEDITOR.tools.setTimeout( function()
     44                {
     45                        speaker.setText( '\xa0' );
     46                        speaker.setAttribute( 'aria-live', 'off' );
     47                }, 500, this );
     48        }
     49
     50        function extracAriaInfo( element )
     51        {
     52                var doc = element.getDocument(),
     53                        role = element.getAttribute( 'role' ) || '';
     54
     55                var attrValue,
     56                        labelText = element.getAttribute( 'aria-label' ) || ( attrValue = element.getAttribute( 'aria-labelledby' ) ) && doc.getById( attrValue ).getText() || '',
     57                        descriptionText = ( attrValue = element.getAttribute( 'aria-describedby' ) ) && doc.getById( attrValue ).getText() || '',
     58                        composition = [ labelText, role in silentRoles ? '' : role, descriptionText ].join( ' ' );
     59
     60                return composition;
     61        }
     62
    3063        /**
    3164         *  Bring degradeable substitution to standard ARIA widgets. 
    3265         * @param element
     
    5588                        states[ i ] && element.removeAttribute( 'aria-' + states[ i ] );
    5689                }
    5790
    58                 // Translate 'dialog' role by wrapping all containing form fields with a legend that composed of all ARIA
    59                 // attributes of the dialog which leads to be announced by ATs.
    60                 if ( role == 'dialog' )
    61                 {
    62                         var fieldset = CKEDITOR.dom.element.createFromHtml(
    63                                         '<fieldset style="position: relative;height: 100%;">' +
    64                                                 '<legend class="cke_voice_label">' +
    65                                                         CKEDITOR.tools.htmlEncode( allInOne ) +
    66                                                 '</legend>' +
    67                                         '</fieldset>', doc );
    68 
    69                         var parent;
    70                         while( ( parent = element.getParent() ) && !parent.getDtd()[ fieldset.getName() ] )
    71                                 element = parent;
    72                         fieldset.insertBefore( element );
    73                         fieldset.append( element );
    74                 }
    7591                // The only reliable substitution of aria-label on an iframe
    7692                // is to use the content window title of that frame.
    77                 else if ( element.is( 'iframe' ) )
     93                if ( element.is( 'iframe' ) )
    7894                {
    7995                        doc = element.$.contentWindow.document;
    8096                        var title = doc.title;
     
    115131                                        });
    116132                        }
    117133
    118                         // IE doesn't support 'aria-label', use 'aria-labelledby' instead.
    119134                        if ( CKEDITOR.env.ie )
    120135                        {
     136                                // Mannually announce the dialog after showing.
     137                                editor.on( 'dialogShow', function( evt )
     138                                {
     139                                        var dialog = evt.data;
     140                                        setTimeout( function()
     141                                                {
     142                                                        speak(
     143                                                                extracAriaInfo( dialog.parts.dialog ),
     144                                                                'assertive' );
     145                                                }, 500 );
     146                                } );
     147
     148                                // IE doesn't support 'aria-label', use 'aria-labelledby' instead.
    121149                                CKEDITOR.on( 'ariaWidget', function( evt )
    122150                                        {
    123151                                                var target = evt.data,
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy