summaryrefslogtreecommitdiff
path: root/addons/web_editor
diff options
context:
space:
mode:
authorkujiu <kujiu@users.noreply.github.com>2018-06-22 21:22:21 +0200
committerGitHub <noreply@github.com>2018-06-22 21:22:21 +0200
commit9de1bc0eef6f5bfaa2a8d745431caa361ae91548 (patch)
tree342ddbf7fb2b7303606f864ff9f68cbf1bd8814e /addons/web_editor
parent864357203fc6222cc989b99a5e9f428cd53f413f (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')
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/Renderer.js14
-rw-r--r--addons/web_editor/static/src/js/backend/fields.js2
-rw-r--r--addons/web_editor/static/src/js/tours/rte.js8
-rw-r--r--addons/web_editor/static/src/js/widgets/widgets.js2
-rw-r--r--addons/web_editor/static/src/xml/ace.xml6
-rw-r--r--addons/web_editor/static/src/xml/backend.xml4
-rw-r--r--addons/web_editor/static/src/xml/editor.xml65
-rw-r--r--addons/web_editor/static/src/xml/snippets.xml18
-rw-r--r--addons/web_editor/views/snippets.xml2
9 files changed, 61 insertions, 60 deletions
diff --git a/addons/web_editor/static/lib/summernote/src/js/Renderer.js b/addons/web_editor/static/lib/summernote/src/js/Renderer.js
index 2c2c8f4ac00..c6142333d30 100644
--- a/addons/web_editor/static/lib/summernote/src/js/Renderer.js
+++ b/addons/web_editor/static/lib/summernote/src/js/Renderer.js
@@ -94,18 +94,18 @@ define([
* @param {String} [footer='']
*/
var tplDialog = function (className, title, body, footer) {
- return '<div class="' + className + ' modal" aria-hidden="false">' +
+ return '<div class="' + className + ' modal" role="dialog" aria-hidden="false">' +
'<div class="modal-dialog">' +
'<div class="modal-content">' +
(title ?
- '<div class="modal-header">' +
+ '<header class="modal-header">' +
'<button type="button" class="close" aria-hidden="true" tabindex="-1">&times;</button>' +
'<h4 class="modal-title">' + title + '</h4>' +
- '</div>' : ''
+ '</header>' : ''
) +
- '<div class="modal-body">' + body + '</div>' +
+ '<main class="modal-body">' + body + '</main>' +
(footer ?
- '<div class="modal-footer">' + footer + '</div>' : ''
+ '<header class="modal-footer">' + footer + '</header>' : ''
) +
'</div>' +
'</div>' +
@@ -817,7 +817,7 @@ define([
$dialog.addClass('note-air-layout');
$dialog.attr('id', 'note-dialog-' + id);
$dialog.find('button.close, a.modal-close').click(function () {
- $(this).closest('.modal').modal('hide');
+ $(this).closest('[role="dialog"]').modal('hide');
});
$dialog.appendTo($container);
};
@@ -905,7 +905,7 @@ define([
var $dialogContainer = options.dialogsInBody ? $(document.body) : $editor;
var $dialog = $(tplDialogs(langInfo, options)).prependTo($dialogContainer);
$dialog.find('button.close, a.modal-close').click(function () {
- $(this).closest('.modal').modal('hide');
+ $(this).closest('[role="dialog"]').modal('hide');
});
//09. Editor/Holder switch
diff --git a/addons/web_editor/static/src/js/backend/fields.js b/addons/web_editor/static/src/js/backend/fields.js
index a636b7e5be3..00c84c5fe92 100644
--- a/addons/web_editor/static/src/js/backend/fields.js
+++ b/addons/web_editor/static/src/js/backend/fields.js
@@ -400,7 +400,7 @@ var FieldTextHtml = AbstractField.extend({
return src;
},
old_initialize_content: function () {
- this.$el.closest('.modal-body').css('max-height', 'none');
+ this.$el.closest('main.modal-body').css('max-height', 'none');
this.$iframe = this.$el.find('iframe');
this.document = null;
this.$body = $();
diff --git a/addons/web_editor/static/src/js/tours/rte.js b/addons/web_editor/static/src/js/tours/rte.js
index 6d865116ec2..6d686353cfb 100644
--- a/addons/web_editor/static/src/js/tours/rte.js
+++ b/addons/web_editor/static/src/js/tours/rte.js
@@ -157,7 +157,7 @@ tour.register('rte', {
trigger: '#editor-media-icon.active span.fa:first',
}, {
content: "save pictogram",
- trigger: '.modal-footer > .btn-primary',
+ trigger: 'footer.modal-footer .btn-primary',
extra_trigger: '#editor-media-icon.active span.o_selected',
}, {
content: "select a size for the pictogram",
@@ -180,8 +180,8 @@ tour.register('rte', {
extra_trigger: 'a#link-preview:containsRegex(/^<span [^>]+><\\/span>$/) > span.fa.fa-3x.pull-right',
}, {
content: "save link",
- trigger: '.modal-footer > .btn-primary',
- extra_trigger: 'a#link-preview.btn.btn-success:containsRegex(/^<span [^>]+><\\/span>$/) > span.fa.fa-3x.pull-right',
+ trigger: 'footer.modal-footer .btn-primary',
+ extra_trigger: 'a#link-preview.btn.btn-success span.fa.fa-3x.pull-right',
}, {
content: "click on other picture",
trigger: '#editable_area > section .row > div:last img',
@@ -200,7 +200,7 @@ tour.register('rte', {
extra_trigger: 'a#link-preview:containsRegex(/^<img [^>]+>$/) img',
}, {
content: "save link",
- trigger: '.modal-footer > .btn-primary',
+ trigger: 'footer.modal-footer .btn-primary',
extra_trigger: 'a#link-preview.btn.btn-success[href="mailto:test@test.test"]:containsRegex(/^<img [^>]+>$/) img',
}, {
content: "select for triple enter then double backspace",
diff --git a/addons/web_editor/static/src/js/widgets/widgets.js b/addons/web_editor/static/src/js/widgets/widgets.js
index d0df042fa82..8ff47ba2c5a 100644
--- a/addons/web_editor/static/src/js/widgets/widgets.js
+++ b/addons/web_editor/static/src/js/widgets/widgets.js
@@ -1166,7 +1166,7 @@ var MediaDialog = Dialog.extend({
var self = this;
var defs = [this._super.apply(this, arguments)];
this.$modal.addClass('note-image-dialog');
- this.$modal.find('.modal-dialog').addClass('o_select_media_dialog');
+ this.$modal.find('[role="dialog"]').addClass('o_select_media_dialog');
if (this.imageDialog) {
defs.push(this.imageDialog.appendTo(this.$("#editor-media-image")));
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"/>&#32;Previous</a>
+ <a role="button" class="btn btn-default disabled" href="#"><span class="fa fa-angle-left">&#32;Previous</span></a>
</li>
<li class="next">
- <a class="btn btn-default disabled" href="#">Next&#32;<i class="fa fa-angle-right"/></a>
+ <a role="button" class="btn btn-default disabled" href="#"><span class="fa fa-suffix-angle-right">Next&#32;</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>
diff --git a/addons/web_editor/views/snippets.xml b/addons/web_editor/views/snippets.xml
index 096ea58a2ce..6dbd57764ab 100644
--- a/addons/web_editor/views/snippets.xml
+++ b/addons/web_editor/views/snippets.xml
@@ -6,7 +6,7 @@
<div id="o_scroll">
<div id="snippet_structure" class="o_panel">
<div class="o_panel_header">
- <i class="fa fa-th-large"/> First Panel
+ <span class="fa fa-th-large"> First Panel</span>
</div>
<div class="o_panel_body"/>
</div>