Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve a11y (closes #1206) #1665

Merged
merged 1 commit into from
Sep 29, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion common.blocks/attach/attach.tmpl-specs/10-simple.html
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
<span class="attach attach_theme_simple attach_size_l i-bem" data-bem="{&quot;attach&quot;:{}}"><span class="button button_theme_islands button_size_m button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button"><input class="attach__control" type="file" name="attach-name" tabindex="1"/></span><span class="attach__no-file">no file</span></span>
<span class="attach attach_theme_simple attach_size_l i-bem" data-bem="{&quot;attach&quot;:{}}">
<span class="button button_theme_islands button_size_m button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button">
<input class="attach__control" type="file" name="attach-name" tabindex="1"/>
</span>
<span class="attach__no-file">no file</span>
</span>
8 changes: 7 additions & 1 deletion common.blocks/attach/attach.tmpl-specs/20-disabled.html
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
<span class="attach attach_theme_simple attach_disabled i-bem" data-bem="{&quot;attach&quot;:{}}"><span class="button button_theme_simple button_disabled button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button" aria-disabled="true"><input class="attach__control" type="file" disabled="disabled"/><span class="button__text">file</span></span><span class="attach__no-file">no file</span></span>
<span class="attach attach_theme_simple attach_disabled i-bem" data-bem="{&quot;attach&quot;:{}}">
<span class="button button_theme_simple button_disabled button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button" aria-disabled="true">
<input class="attach__control" type="file" disabled="disabled"/>
<span class="button__text">file</span>
</span>
<span class="attach__no-file">no file</span>
</span>
5 changes: 5 additions & 0 deletions common.blocks/button/_togglable/button_togglable.bh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function(bh) {
bh.match(['button_togglable_check', 'button_togglable_radio'], function(ctx) {
ctx.attr('aria-pressed', String(!!ctx.mod('checked')));
});
};
21 changes: 21 additions & 0 deletions common.blocks/button/_togglable/button_togglable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @module button
*/

modules.define('button', function(provide, Button) {

/**
* @exports
* @class button
* @bem
*/
provide(Button.decl({ modName : 'togglable' }, /** @lends button.prototype */{
onSetMod : {
'checked' : function(_, modVal) {
this.__base.apply(this, arguments);
this.domElem.attr('aria-pressed', !!modVal);
}
}
}));

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
block('button').mod('togglable', 'check').attrs()(function() {
return this.extend(applyNext(), { 'aria-pressed' : !!this.mods.checked });
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('button_togglable_check', function() {
});

describe('check/uncheck', function() {
it('should switch "checked" mod on "pointerpress"/"pointerreleaase" only if "pointerrelease" target is in block', function() {
it('should switch "checked" mod on "pointerpress"/"pointerrelease" only if "pointerrelease" target is in block', function() {
function triggerPointerUpPointerDown(onBlock) {
button.domElem
.trigger('pointerpress')
Expand All @@ -50,6 +50,13 @@ describe('button_togglable_check', function() {
triggerPointerUpPointerDown(false);
button.hasMod('checked').should.be.false;
});

it('should update aria-attributes properly', function() {
button.setMod('checked');
button.domElem.attr('aria-pressed').should.be.equal('true');
button.delMod('checked');
button.domElem.attr('aria-pressed').should.be.equal('false');
});
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
block('button').mod('togglable', 'radio').attrs()(function() {
return this.extend(applyNext(), { 'aria-pressed' : !!this.mods.checked });
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ describe('button_togglable_radio', function() {
triggerPointerUpPointerDown(false);
button.hasMod('checked').should.be.false;
});

it('should update aria-attributes properly', function() {
button.setMod('checked');
button.domElem.attr('aria-pressed').should.be.equal('true');
button.delMod('checked');
button.domElem.attr('aria-pressed').should.be.equal('false');
});
});
});

Expand Down
2 changes: 1 addition & 1 deletion common.blocks/button/_type/button_type_link.bemhtml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ block('button').mod('type', 'link')(

attrs()(function() {
var ctx = this.ctx,
attrs = {};
attrs = { role : 'link' };

ctx.target && (attrs.target = ctx.target);
this.mods.disabled?
Expand Down
4 changes: 3 additions & 1 deletion common.blocks/button/_type/button_type_link.bh.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
module.exports = function(bh) {

bh.match('button_type_link', function(ctx, json) {
ctx.tag('a');
ctx
.tag('a')
.attr('role', 'link');

json.target && ctx.attr('target', json.target);
ctx.mod('disabled')?
Expand Down
8 changes: 6 additions & 2 deletions common.blocks/button/_type/button_type_link.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ provide(Button.decl({ modName : 'type', modVal : 'link' }, /** @lends button.pro
'disabled' : {
'true' : function() {
this.__base.apply(this, arguments);
this.domElem.removeAttr('href');
this.domElem
.removeAttr('href')
.attr('aria-disabled', true);
},

'' : function() {
this.__base.apply(this, arguments);
this.domElem.attr('href', this._url);
this.domElem
.attr('href', this._url)
.removeAttr('aria-disabled');
}
}
},
Expand Down
4 changes: 3 additions & 1 deletion common.blocks/button/_type/button_type_link.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@ describe('button_type_link', function() {
expect(button.domElem.attr('href')).to.be.undefined;
});

it('should remove "href" attribute on disable', function() {
it('should update attributes properly', function() {
button.setMod('disabled');
button.domElem.attr('aria-disabled').should.be.equal('true');
expect(button.domElem.attr('href')).to.be.undefined;

button.delMod('disabled');
button.domElem.attr('href').should.be.equal('/');
expect(button.domElem.attr('aria-disabled')).to.be.undefined;
});
});

Expand Down
5 changes: 5 additions & 0 deletions common.blocks/button/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ provide(BEMDOM.decl({ block : this.name, baseBlock : Control }, /** @lends butto
'true' : function() {
this.__base.apply(this, arguments);
this.hasMod('togglable') || this.delMod('pressed');
this.domElem.attr('aria-disabled', true);
},
'' : function() {
this.__base.apply(this, arguments);
this.domElem.removeAttr('aria-disabled');
}
},

Expand Down
15 changes: 13 additions & 2 deletions common.blocks/button/button.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
modules.define(
'spec',
['button', 'i-bem__dom', 'jquery', 'BEMHTML', 'sinon', 'keyboard__codes'],
function(provide, Button, BEMDOM, $, BEMHTML, sinon, keyCodes) {
['button', 'i-bem__dom', 'jquery', 'BEMHTML', 'sinon', 'keyboard__codes', 'chai'],
function(provide, Button, BEMDOM, $, BEMHTML, sinon, keyCodes, chai) {

var expect = chai.expect;

describe('button', function() {
var button;
Expand Down Expand Up @@ -83,6 +85,15 @@ describe('button', function() {

button.hasMod('pressed').should.be.false;
});

it('should set/remove "aria-disabled" attribute properly', function () {
button
.setMod('disabled')
.domElem.attr('aria-disabled').should.be.equal('true');

button.delMod('disabled');
expect(button.domElem.attr('aria-disabled')).to.be.undefined;
});
});

describe('click', function() {
Expand Down
5 changes: 4 additions & 1 deletion common.blocks/button/button.tmpl-specs/10-params.html
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<button class="button button_focused button__control i-bem" data-bem="{&quot;button&quot;:{&quot;live&quot;:false}}" role="button" tabindex="0" type="button" id="btn" name="name" value="value"><span aria-hidden="true" class="icon icon_social_twitter"></span><span class="button__text">button</span></button>
<button class="button button_focused button__control i-bem" data-bem="{&quot;button&quot;:{&quot;live&quot;:false}}" role="button" tabindex="0" type="button" id="btn" name="name" value="value">
<span class="icon icon_social_twitter"></span>
<span class="button__text">button</span>
</button>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a class="button button_type_link button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button" target="_blank" href="//ya.ru/yandsearch?text=&lt;script type=&quot;javascript&quot;&gt;&amp;amp;=test">content</a>
<a class="button button_type_link button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="link" target="_blank" href="//ya.ru/yandsearch?text=&lt;script type=&quot;javascript&quot;&gt;&amp;amp;=test">content</a>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a class="button button_type_link button_disabled button__control i-bem" data-bem="{&quot;button&quot;:{&quot;url&quot;:&quot;#&quot;}}" role="button" aria-disabled="true"></a>
<a class="button button_type_link button_disabled button__control i-bem" data-bem="{&quot;button&quot;:{&quot;url&quot;:&quot;#&quot;}}" role="link" aria-disabled="true"></a>
2 changes: 2 additions & 0 deletions common.blocks/checkbox-group/checkbox-group.bemhtml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
block('checkbox-group')(
tag()('span'),

attrs()({ role : 'group' }),

js()(true),

mix()([{ block : 'control-group' }]),
Expand Down
1 change: 1 addition & 0 deletions common.blocks/checkbox-group/checkbox-group.bh.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = function(bh) {
bh.match('checkbox-group', function(ctx, json) {
ctx
.tag('span')
.attrs({ role : 'group' })
.js(true)
.mix({ block : 'control-group' });

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
<span class="checkbox-group checkbox-group_theme_islands checkbox-group_size_m control-group i-bem" data-bem="{&quot;checkbox-group&quot;:{}}"><label class="checkbox checkbox_theme_islands checkbox_size_m i-bem" data-bem="{&quot;checkbox&quot;:{}}"><span class="checkbox__box"><input class="checkbox__control" type="checkbox" autocomplete="off" name="default" value="1"/></span>first</label><br/><label class="checkbox checkbox_theme_islands checkbox_size_m checkbox_checked checkbox_disabled i-bem" data-bem="{&quot;checkbox&quot;:{}}"><span class="checkbox__box"><input class="checkbox__control" type="checkbox" autocomplete="off" name="default" value="3" checked="checked" disabled="disabled"/></span>third</label></span>
<span class="checkbox-group checkbox-group_theme_islands checkbox-group_size_m control-group i-bem" role="group" data-bem="{&quot;checkbox-group&quot;:{}}">
<label class="checkbox checkbox_theme_islands checkbox_size_m i-bem" data-bem="{&quot;checkbox&quot;:{}}">
<span class="checkbox__box"><input class="checkbox__control" type="checkbox" autocomplete="off" name="default" value="1"/></span>
<span class="checkbox__text" role="presentation">first</span>
</label><br/>
<label class="checkbox checkbox_theme_islands checkbox_size_m checkbox_checked checkbox_disabled i-bem" data-bem="{&quot;checkbox&quot;:{}}">
<span class="checkbox__box"><input class="checkbox__control" type="checkbox" autocomplete="off" name="default" value="3" checked="checked" disabled="disabled"/></span>
<span class="checkbox__text" role="presentation">third</span>
</label>
</span>
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
<span class="checkbox-group checkbox-group_type_button checkbox-group_disabled control-group i-bem" data-bem="{&quot;checkbox-group&quot;:{}}"><label class="checkbox checkbox_type_button checkbox_disabled i-bem" data-bem="{&quot;checkbox&quot;:{}}"><button class="button button_togglable_check button_disabled button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button" type="button" disabled="disabled"><span class="button__text">first</span></button><input class="checkbox__control" type="checkbox" autocomplete="off" disabled="disabled"/></label><label class="checkbox checkbox_type_button checkbox_disabled i-bem" data-bem="{&quot;checkbox&quot;:{}}"><button class="button button_togglable_check button_disabled button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button" type="button" disabled="disabled"><span aria-hidden="true" class="icon icon_social_vk"></span><span class="button__text">VK</span></button><input class="checkbox__control" type="checkbox" autocomplete="off" disabled="disabled"/></label></span>
<span class="checkbox-group checkbox-group_type_button checkbox-group_disabled control-group i-bem" role="group" data-bem="{&quot;checkbox-group&quot;:{}}">
<label class="checkbox checkbox_type_button checkbox_disabled i-bem" data-bem="{&quot;checkbox&quot;:{}}">
<button class="button button_togglable_check button_disabled button__control i-bem" role="checkbox" type="button" disabled="disabled" aria-checked="false" data-bem="{&quot;button&quot;:{}}"><span class="button__text">first</span></button>
<input class="checkbox__control" type="checkbox" autocomplete="off" disabled="disabled"/>
</label>
<label class="checkbox checkbox_type_button checkbox_disabled i-bem" data-bem="{&quot;checkbox&quot;:{}}">
<button class="button button_togglable_check button_disabled button__control i-bem" role="checkbox" type="button" disabled="disabled" aria-checked="false" data-bem="{&quot;button&quot;:{}}"><span class="icon icon_social_vk"></span><span class="button__text">VK</span></button>
<input class="checkbox__control" type="checkbox" autocomplete="off" disabled="disabled"/>
</label>
</span>
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
<span class="checkbox-group control-group i-bem" data-bem="{&quot;checkbox-group&quot;:{}}"><label class="checkbox checkbox_checked i-bem" data-bem="{&quot;checkbox&quot;:{}}"><span class="checkbox__box"><input class="checkbox__control" type="checkbox" autocomplete="off" checked="checked" value="1"/></span></label></span>
<span class="checkbox-group control-group i-bem" role="group" data-bem="{&quot;checkbox-group&quot;:{}}">
<label class="checkbox checkbox_checked i-bem" data-bem="{&quot;checkbox&quot;:{}}"><span class="checkbox__box"><input class="checkbox__control" type="checkbox" autocomplete="off" value="1" checked="checked"/></span></label>
</span>
4 changes: 4 additions & 0 deletions common.blocks/checkbox/__text/checkbox__text.bemhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
block('checkbox').elem('text')(
tag()('span'),
attrs()({ role : 'presentation' })
);
7 changes: 7 additions & 0 deletions common.blocks/checkbox/__text/checkbox__text.bh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = function(bh) {
bh.match('checkbox__text', function(ctx) {
ctx
.tag('span')
.attrs({ role : 'presentation' });
});
};
5 changes: 5 additions & 0 deletions common.blocks/checkbox/_type/checkbox_type_button.bemhtml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ block('checkbox').mod('type', 'button')(
theme : mods.theme,
size : mods.size
},
attrs : {
role : 'checkbox',
'aria-pressed' : undefined,
'aria-checked' : !!mods.checked
},
title : ctx.title,
content : [
ctx.icon,
Expand Down
5 changes: 5 additions & 0 deletions common.blocks/checkbox/_type/checkbox_type_button.bh.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ module.exports = function(bh) {
theme : mods.theme,
size : mods.size
},
attrs : {
role : 'checkbox',
'aria-pressed' : null,
'aria-checked' : String(!!mods.checked)
},
title : json.title,
content : [
json.icon,
Expand Down
2 changes: 1 addition & 1 deletion common.blocks/checkbox/_type/checkbox_type_button.deps.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[{
mustDeps : 'button'
shouldDeps : { block : 'button', mods : { togglable : 'check' } }
},
{
tech : 'spec.js',
Expand Down
7 changes: 6 additions & 1 deletion common.blocks/checkbox/_type/checkbox_type_button.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ provide(Checkbox.decl({ modName : 'type', modVal : 'button' }, /** @lends checkb
}
},

'checked' : proxyModToButton,
'checked' : function(_, checked) {
proxyModToButton.apply(this, arguments);
this._button.domElem
.removeAttr('aria-pressed') // checkbox accepts aria-checked instead of aria-pressed
.attr('aria-checked', !!checked);
},
'disabled' : proxyModToButton,
'focused' : function(modName, modVal) {
proxyModToButton.call(this, modName, modVal, false);
Expand Down
30 changes: 21 additions & 9 deletions common.blocks/checkbox/_type/checkbox_type_button.spec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
modules.define(
'spec',
['checkbox', 'i-bem__dom', 'jquery', 'dom', 'BEMHTML'],
function(provide, Checkbox, BEMDOM, $, dom, BEMHTML) {
['checkbox', 'i-bem__dom', 'jquery', 'dom', 'BEMHTML', 'chai'],
function(provide, Checkbox, BEMDOM, $, dom, BEMHTML, chai) {

describe('checkbox_type_button', function() {
var checkbox;
var expect = chai.expect,
checkbox, button;

function buildCheckbox() {
return BEMDOM.init($(BEMHTML.apply({
Expand All @@ -20,6 +21,7 @@ describe('checkbox_type_button', function() {

beforeEach(function() {
checkbox = buildCheckbox();
button = checkbox.findBlockInside('button');
});

afterEach(function() {
Expand All @@ -29,30 +31,40 @@ describe('checkbox_type_button', function() {
describe('checked', function() {
it('should set/unset "checked" mod for button according to self', function() {
checkbox.setMod('checked');
checkbox.findBlockInside('button').hasMod('checked').should.be.true;
button.hasMod('checked').should.be.true;

checkbox.delMod('checked');
checkbox.findBlockInside('button').hasMod('checked').should.be.false;
button.hasMod('checked').should.be.false;
});

it('should set/unset aria-attributes properly', function() {
checkbox.setMod('checked');
expect(button.domElem.attr('aria-pressed')).to.be.undefined;
button.domElem.attr('aria-checked').should.be.equal('true');

checkbox.delMod('checked');
expect(button.domElem.attr('aria-pressed')).to.be.undefined;
button.domElem.attr('aria-checked').should.be.equal('false');
});
});

describe('disabled', function() {
it('should set/unset "disabled" mod for button according to self', function() {
checkbox.setMod('disabled');
checkbox.findBlockInside('button').hasMod('disabled').should.be.true;
button.hasMod('disabled').should.be.true;

checkbox.delMod('disabled');
checkbox.findBlockInside('button').hasMod('disabled').should.be.false;
button.hasMod('disabled').should.be.false;
});
});

describe('focused', function() {
it('should set/unset "focused" mod for button according to self', function() {
checkbox.setMod('focused');
checkbox.findBlockInside('button').hasMod('focused').should.be.true;
button.hasMod('focused').should.be.true;

checkbox.delMod('focused');
checkbox.findBlockInside('button').hasMod('focused').should.be.false;
button.hasMod('focused').should.be.false;
});
});
});
Expand Down
5 changes: 4 additions & 1 deletion common.blocks/checkbox/checkbox.bemhtml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ block('checkbox')(
val : ctx.val
}
},
ctx.text
ctx.text && {
elem : 'text',
content : ctx.text
}
];
})
);
5 changes: 4 additions & 1 deletion common.blocks/checkbox/checkbox.bh.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ module.exports = function(bh) {
val : json.val
}
},
json.text
json.text && {
elem : 'text',
content : json.text
}
]);
});

Expand Down
Loading