diff options
| author | kujiu <kujiu@users.noreply.github.com> | 2018-06-22 21:22:21 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-06-22 21:22:21 +0200 |
| commit | 9de1bc0eef6f5bfaa2a8d745431caa361ae91548 (patch) | |
| tree | 342ddbf7fb2b7303606f864ff9f68cbf1bd8814e /addons/web_editor/static/src/xml | |
| parent | 864357203fc6222cc989b99a5e9f428cd53f413f (diff) | |
[IMP] Improve compatibility with screen readers (accessibility) (#24574)
Today, Odoo is really tricky to use without seeing the screen, it must be improved to be usable.
This PR forbid to use labels without a "for" attribute, add some title, rule and aria attributes in HTML. With that, Odoo will be fully usable with a screen reader.
* [IMP] Labels must have a for attribute. Improve accessibility.
* [IMP] Better error message when trying to read a missing cached value
* [FIX] Add some aria-label and title attributes for screen readers.
* [FIX] Template name is not included in the error message in case of SyntaxError in QWeb
* [FIX] Improve the Tour failed at step error message to be more explicit.
* [IMP] Add aria-labels
* [FIX] Add missing aria-label on failing test
* [IMP] aria-hidden means hidden. Fix all bad aria-hidden and hide aria-hidden for all.
* [IMP] Color names on kanban views and many2many tags
* [IMP] Add some checks on views for accessibility.
* [IMP] Add `alt` attribute on `img` tags.
* [IMP] Add aria-label and title on non-described icons
* [IMP] Add button role to widgets with btn class
* [IMP] Translate aria and formatted attributes.
* [IMP] Remove wrong aria-labelledby
* [IMP] Add menu role on dropdowns
* [IMP] Buttons must be focusable
* [IMP] Add aria attributes on progress bars
* [IMP] Improve accessibility of basic widgets
* [IMP] Change main layout to more semantic tags
* [IMP] Add menuitem role when missing
* [IMP] Remove wrong role='presentation'
* [IMP] Improve accessibility of tab panels
* [IMP] Add aria-invalid on invalid fields
* [IMP] Add aria-sort on ordered columns
* [IMP] Add role on alerts
* [IMP] Use dialog role, header, main and footer tags for modals
* [IMP] Add labels on o_status
* [IMP] Improve accessibility of kanban view with feeds and articles
* [IMP] Add alerts in case of new messages
* [IMP] Add widget, navigation or img role to aria-labelled items
Diffstat (limited to 'addons/web_editor/static/src/xml')
| -rw-r--r-- | addons/web_editor/static/src/xml/ace.xml | 6 | ||||
| -rw-r--r-- | addons/web_editor/static/src/xml/backend.xml | 4 | ||||
| -rw-r--r-- | addons/web_editor/static/src/xml/editor.xml | 65 | ||||
| -rw-r--r-- | addons/web_editor/static/src/xml/snippets.xml | 18 |
4 files changed, 47 insertions, 46 deletions
diff --git a/addons/web_editor/static/src/xml/ace.xml b/addons/web_editor/static/src/xml/ace.xml index 6687d65645d..a9cd23cbaaf 100644 --- a/addons/web_editor/static/src/xml/ace.xml +++ b/addons/web_editor/static/src/xml/ace.xml @@ -7,8 +7,8 @@ <div class="btn-group o_ace_type_switcher"> <button type="button" class="btn btn-sm btn-info dropdown-toggle" data-toggle="dropdown">XML (HTML)</button> <ul class="dropdown-menu" role="menu"> - <li><a href="#" class="o_ace_type_switcher_choice" data-type="xml">XML (HTML)</a></li> - <li><a href="#" class="o_ace_type_switcher_choice" data-type="scss">SCSS (CSS)</a></li> + <li><a role="menuitem" href="#" class="o_ace_type_switcher_choice" data-type="xml">XML (HTML)</a></li> + <li><a role="menuitem" href="#" class="o_ace_type_switcher_choice" data-type="scss">SCSS (CSS)</a></li> </ul> </div> <select id="ace-view-list" class="o_res_list"/> @@ -33,7 +33,7 @@ <div id="ace-view-id"> <span/> <div class="pull-right"> - <button data-action="reset" type="button" class="btn btn-xs btn-danger"><i class="fa fa-undo"/> Reset</button> + <button data-action="reset" type="button" class="btn btn-xs btn-danger" icon="fa-undo" string="Reset"></button> <button data-action="format" type="button" class="btn btn-xs btn-link">Format</button> </div> </div> diff --git a/addons/web_editor/static/src/xml/backend.xml b/addons/web_editor/static/src/xml/backend.xml index 082efdbc5a0..40be4f05d07 100644 --- a/addons/web_editor/static/src/xml/backend.xml +++ b/addons/web_editor/static/src/xml/backend.xml @@ -9,7 +9,7 @@ <t t-name="web_editor.FieldTextHtml.button.translate"> <div class="btn-group pull-right"> - <button t-if="widget.field.translate" class="o_field_translate btn btn-default btn-sm btn-small" style="height: 24px; padding: 1px 17px 0px 5px"> + <button t-if="widget.field.translate" class="o_field_translate btn btn-default btn-sm btn-small" style="height: 24px; padding: 1px 17px 0px 5px" aria-label="Translate" title="Translate"> <span class="fa fa-language fa-lg oe_input_icon"/> </button> </div> @@ -18,7 +18,7 @@ <t t-name="web_editor.FieldTextHtml.fullscreen"> <span style="margin: 5px; position: fixed; top: 0; right: 0; z-index: 2000;"> <button class="o_fullscreen btn btn-primary" style="width: 24px; height: 24px; background-color: #337ab7; border: 1px solid #2e6da4; border-radius: 4px; padding: 0; position: relative;"> - <img src="/web_editor/font_to_img/61541/rgb(255,255,255)/16" style="position: absolute; top: 3px; left: 4px;"/> + <img src="/web_editor/font_to_img/61541/rgb(255,255,255)/16" style="position: absolute; top: 3px; left: 4px;" alt="Fullscreen"/> </button> </span> </t> diff --git a/addons/web_editor/static/src/xml/editor.xml b/addons/web_editor/static/src/xml/editor.xml index 9821ceb38bd..e0626801e68 100644 --- a/addons/web_editor/static/src/xml/editor.xml +++ b/addons/web_editor/static/src/xml/editor.xml @@ -9,8 +9,8 @@ <div id="web_editor-top-edit"> <div id="web_editor-toolbars"/> <form class="navbar-form text-muted"> - <button type="button" class="btn btn-sm btn-default" data-action="cancel"><i class="fa fa-times"/> Discard</button> - <button type="button" class="btn btn-sm btn-primary" data-action="save"><i class="fa fa-floppy-o"/> Save</button> + <button type="button" class="btn btn-sm btn-default fa fa-times" data-action="cancel">Discard</button> + <button type="button" class="btn btn-sm btn-primary fa fa-floppy-o" data-action="save">Save</button> </form> </div> </t> @@ -46,34 +46,34 @@ <!-- Media Dialog (allows to choose an img/pictogram/video) --> <div t-name="web_editor.dialog.media"> - <ul class="nav nav-tabs"> - <li class="active"><a href="#editor-media-image" data-toggle="tab" t-att-class="widget.noImages ? 'hidden' : ''">Image</a></li> - <li><a href="#editor-media-document" data-toggle="tab" t-att-class="widget.noDocuments ? 'hidden' : ''">Document</a></li> - <li><a href="#editor-media-icon" data-toggle="tab" t-att-class="widget.noIcons ? 'hidden' : ''">Pictogram</a></li> - <li><a href="#editor-media-video" data-toggle="tab" t-att-class="widget.noVideos ? 'hidden' : ''">Video</a></li> + <ul class="nav nav-tabs" role="tablist"> + <li class="active"><a role="tab" href="#editor-media-image" aria-controls="editor-media-image" data-toggle="tab" t-att-class="widget.noImages ? 'hidden' : ''">Image</a></li> + <li><a role="tab" href="#editor-media-document" aria-controls="editor-media-document" data-toggle="tab" t-att-class="widget.noDocuments ? 'hidden' : ''">Document</a></li> + <li><a role="tab" href="#editor-media-icon" aria-controls="editor-media-icon" data-toggle="tab" t-att-class="widget.noIcons ? 'hidden' : ''">Pictogram</a></li> + <li><a role="tab" href="#editor-media-video" aria-controls="editor-media-video" data-toggle="tab" t-att-class="widget.noVideos ? 'hidden' : ''">Video</a></li> <li class="search pull-right"> <ul class="pager mb0 mt0"> <li class="previous"> - <a class="btn btn-default disabled" href="#"><i class="fa fa-angle-left"/> Previous</a> + <a role="button" class="btn btn-default disabled" href="#"><span class="fa fa-angle-left"> Previous</span></a> </li> <li class="next"> - <a class="btn btn-default disabled" href="#">Next <i class="fa fa-angle-right"/></a> + <a role="button" class="btn btn-default disabled" href="#"><span class="fa fa-suffix-angle-right">Next </span></a> </li> </ul> </li> <li class="search pull-right"> <div class="form-group"> <input class="form-control" id="icon-search" type="search"/> - <span class="fa fa-search"/> + <span class="fa fa-search" title="Search" role="img" aria-label="Search"/> </div> </li> </ul> <!-- Tab panes --> <div class="tab-content"> - <div class="tab-pane fade in active" id="editor-media-image"/> - <div class="tab-pane fade" id="editor-media-document"/> - <div class="tab-pane fade" id="editor-media-icon"/> - <div class="tab-pane fade" id="editor-media-video"/> + <div role="tabpanel" class="tab-pane fade in active" id="editor-media-image"/> + <div role="tabpanel" class="tab-pane fade" id="editor-media-document"/> + <div role="tabpanel" class="tab-pane fade" id="editor-media-icon"/> + <div role="tabpanel" class="tab-pane fade" id="editor-media-video"/> </div> </div> @@ -100,7 +100,7 @@ </button> <ul class="dropdown-menu" role="menu"> <li> - <a class="o_upload_image_button_no_optimization">Upload image without optimization</a> + <a role="menuitem" class="o_upload_image_button_no_optimization">Upload image without optimization</a> </li> </ul> </div> @@ -122,20 +122,20 @@ </form> </t> <t t-name="web_editor.dialog.image.existing"> - <div class="modal" tabindex="-1" role="dialog" aria-hidden="true"> + <div role="dialog" class="modal" tabindex="-1"> <div class="modal-dialog select-image"> <div class="modal-content"> - <div class="modal-header"> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <header class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button> <h3 class="modal-title">Select a Picture</h3> - </div> - <div class="modal-body has-error"> + </header> + <main class="modal-body has-error"> <div class="existing-attachments"/> <div class="help-block"/> - </div> - <div class="modal-footer"> - <a data-dismiss="modal" href="#" aria-hidden="true">Discard</a> - </div> + </main> + <footer class="modal-footer"> + <a data-dismiss="modal" href="#" aria-label="Discard">Discard</a> + </footer> </div> </div> </div> @@ -144,9 +144,9 @@ <div class="existing-attachments"> <div class="row mt16" t-as="row" t-foreach="rows"> <div class="col-sm-2 o_existing_attachment_cell" t-as="attachment" t-foreach="row"> - <i t-if="attachment.res_model === 'ir.ui.view'" class="fa fa-times o_existing_attachment_remove" title="This file is a public view attachment" t-att-data-id="attachment.id"/> - <i t-else="" class="fa fa-times o_existing_attachment_remove" title="This file is attached to the current record" t-att-data-id="attachment.id"/> - <div class="o_attachment_border" t-att-style="attachment.res_model === 'ir.ui.view' ? null : 'border: 1px solid #5cb85c;'"><div t-att-data-src="attachment.src" t-att-data-url="attachment.url" t-att-alt="attachment.name" t-att-title="attachment.name" t-att-data-id="attachment.id" t-att-data-mimetype="attachment.mimetype" class="o_image o_image_loading"/></div> + <i t-if="attachment.res_model === 'ir.ui.view'" class="fa fa-times o_existing_attachment_remove" title="This file is a public view attachment" role="img" aria-label="This file is a public view attachment" t-att-data-id="attachment.id"/> + <i t-else="" class="fa fa-times o_existing_attachment_remove" title="This file is attached to the current record" role="img" aria-label="This file is attached to the current record" t-att-data-id="attachment.id"/> + <div class="o_attachment_border" t-att-style="attachment.res_model === 'ir.ui.view' ? null : 'border: 1px solid #5cb85c;'"><div t-att-data-src="attachment.src" t-att-data-url="attachment.url" role="img" t-att-aria-label="attachment.name" t-att-title="attachment.name" t-att-data-id="attachment.id" t-att-data-mimetype="attachment.mimetype" class="o_image o_image_loading"/></div> </div> </div> </div> @@ -180,6 +180,7 @@ <span t-foreach="data.cssData" t-as="cssData" t-att-data-id="cssData.names[0]" t-att-title="cssData.names[0]" + t-att-aria-label="cssData.names[0]" role="img" t-attf-class="font-icons-icon #{data.base} #{cssData.names[0]}" t-att-data-alias="cssData.names.join(',')"/> </t> @@ -192,7 +193,7 @@ <div class="form-group" id="o_video_form_group"> <label class="mt8" for="o_video_text">Video code <small class="text-muted">(URL or Embed)</small></label> <textarea class="form-control url" id="o_video_text" placeholder="Copy-paste your URL or embed code here"/> - <label class="control-label o_validate_feedback" for="o_video_text"><i class="fa fa-check"/><i class="fa fa-exclamation-triangle"/></label> + <label class="control-label o_validate_feedback" for="o_video_text"><i class="fa fa-check" role="img" aria-label="Checked" title="Checked"/><i class="fa fa-exclamation-triangle" role="img" aria-label="Attention" title="Attention"/></label> </div> <div class="text-right"> <small class="text-muted">Accepts <b><i>Youtube</i></b>, <b><i>Instagram</i></b>, <b><i>Vine.co</i></b>, <b><i>Vimeo</i></b>, <b><i>Dailymotion</i></b> and <b><i>Youku</i></b> videos</small> @@ -265,13 +266,13 @@ <label class="control-label col-sm-3">Color</label> <div class="col-sm-9"> <div class="o_link_dialog_color"> - <label t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-link text-center" data-color=""> + <label role="button" t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-link text-center" data-color=""> <span>L</span> <input class="hidden link-style" name="link_style_color" type="radio" value=""/> <i class="fa"/> </label> <t t-foreach="['primary', 'default', 'success', 'info', 'warning', 'danger', 'alpha', 'beta', 'gamma', 'delta', 'epsilon']" t-as="color"> - <label t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-#{color}"> + <label role="button" t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-#{color}" t-attf-aria-label="Color for #{color}" t-attf-title="Color for #{color}"> <input type="radio" name="link_style_color" class="hidden link-style" t-att-value="color"/> <i class="fa"/> </label> @@ -293,7 +294,7 @@ <div class="form-group text-center"> <label>Preview</label> <div style="overflow: auto; max-width: 100%; max-height: 200px;"> - <a href="#" id="link-preview"/> + <a href="#" id="link-preview" aria-label="Preview" title="Preview"/> </div> </div> </div> @@ -302,7 +303,7 @@ <!-- Crop Image Dialog (allows to crop image on the page) --> <div t-name="web_editor.dialog.crop_image" class="o_crop_image_dialog"> - <div t-if="widget.imageData.isExternalImage" class="alert alert-warning text-center"> + <div t-if="widget.imageData.isExternalImage" class="alert alert-warning text-center" role="alert"> <i class="fa fa-exclamation-triangle fa-2x"/> <h4>This image is an external image</h4> <p> diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml index 594a7615951..3eecae059ad 100644 --- a/addons/web_editor/static/src/xml/snippets.xml +++ b/addons/web_editor/static/src/xml/snippets.xml @@ -10,14 +10,14 @@ </div> <div class="oe_overlay_options" contentEditable="false"> <div class="btn-group"> - <a href="#" class="btn btn-default btn-sm oe_snippet_parent" title="Select Parent Container"><i class="fa fa-lg fa-level-up"/></a> + <a role="button" href="#" class="btn btn-default btn-sm oe_snippet_parent" title="Select Parent Container" aria-label="Select Parent Container"><i class="fa fa-lg fa-level-up"/></a> <div class="dropdown oe_options hidden btn-group"> - <a href="#" data-toggle="dropdown" class="btn btn-primary btn-sm" title="Customize">Customize</a> + <a role="button" href="#" data-toggle="dropdown" class="btn btn-primary btn-sm" title="Customize">Customize</a> <ul class="dropdown-menu" role="menu"/> </div> - <a href="#" class="btn btn-default btn-sm oe_snippet_move" title="Drag to Move"><i class="fa fa-arrows ml4 mr4"></i></a> - <a href="#" class="btn btn-default btn-sm oe_snippet_clone" title="Duplicate Container"><i class="fa fa-files-o ml4 mr4"></i></a> - <a href="#" class="btn btn-default btn-sm oe_snippet_remove" title="Remove Block"><i class="fa fa-trash-o ml4 mr4"></i></a> + <a role="button" href="#" class="btn btn-default btn-sm oe_snippet_move" title="Drag to Move" aria-label="Drag to Move"><i class="fa fa-arrows ml4 mr4"></i></a> + <a role="button" href="#" class="btn btn-default btn-sm oe_snippet_clone" title="Duplicate Container" aria-label="Duplicate Container"><i class="fa fa-files-o ml4 mr4"></i></a> + <a role="button" href="#" class="btn btn-default btn-sm oe_snippet_remove" title="Remove Block" aria-label="Remove Block"><i class="fa fa-trash-o ml4 mr4"></i></a> </div> </div> </div> @@ -27,7 +27,7 @@ <div t-name="web_editor.snippet.option.colorpicker" class="colorpicker"> <div class="note-palette-title">Background Color</div> <div class="btn-group palette-reset"> - <div class="note-color-reset" data-event="foreColor" data-value="inherit" title="None"> + <div class="note-color-reset" data-event="foreColor" data-value="inherit" title="None" role="img" aria-label="No color"> <i class="fa fa-ban"/> </div> </div> @@ -40,16 +40,16 @@ <!-- t-field options --> <t t-name="web_editor.many2one.button"> <div class="btn-group"> - <a href="#" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" title="Search Contact"><i class="fa fa-search"></i></a> + <a role="button" href="#" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" title="Search Contact" aria-label="Search Contact">><i class="fa fa-search"></i></a> <ul class="dropdown-menu contact_menu" role="menu"> - <li><a><input href="#" type="email" placeholder="Search"/></a></li> + <li><a role="menuitem"><input href="#" type="email" placeholder="Search"/></a></li> </ul> </div> </t> <t t-name="web_editor.many2one.search"> <t t-foreach="contacts" t-as="item"> - <li><a href="#" t-att-data-id="item.id" t-att-data-name="item.display_name"><t t-esc="item.display_name"/> <t t-if="item.city or item.country_id"><small class="text-muted">(<t t-esc="item.city"/> <t t-esc="item.country_id and item.country_id[1]"/>)</small></t></a></li> + <li><a role="menuitem" href="#" t-att-data-id="item.id" t-att-data-name="item.display_name"><t t-esc="item.display_name"/> <t t-if="item.city or item.country_id"><small class="text-muted">(<t t-esc="item.city"/> <t t-esc="item.country_id and item.country_id[1]"/>)</small></t></a></li> </t> </t> </templates> |
