Skip to content

Commit

Permalink
Improve a11y
Browse files Browse the repository at this point in the history
  • Loading branch information
hcodes authored and aristov committed Mar 19, 2015
1 parent fc9aa24 commit 515e23e
Show file tree
Hide file tree
Showing 127 changed files with 636 additions and 96 deletions.
3 changes: 3 additions & 0 deletions .enb/make.js
Expand Up @@ -349,6 +349,9 @@ module.exports = function(config) {
destPath : platform + '.tmpl-specs',
levels : getLibLevels(platform),
sourceLevels : getSpecLevels(platform),
htmlDiffer : {
ignoreAttributes : ['id', 'for', 'aria-labelledby', 'aria-controls']
},
engines : {
bh : {
tech : 'enb-bh/techs/bh-server',
Expand Down
31 changes: 31 additions & 0 deletions common.blocks/a11y-hidden/a11y-hidden.ru.md
@@ -0,0 +1,31 @@
# а11y-hidden
Обеспечивает доступность веб-контента людям с ограниченными возможностями. Предоставляет необходимые сведения об элементах интерфейса программам чтения с экрана, для альтернативного воспроизведения.

Блок визуально скрыт и доступен только специальным приложениям. Является вспомогательным для других блоков и самостоятельно не используется.

### Подключение блока
`а11y-hidden` подключается примиксовыванием к другому блоку:

```js
({
block: 'info',
mix: [{ block: 'a11y-hidden' }],
content: 'Информация для людей с ограниченными возможностями.' // скрытое содержимое
})
```

В HTML блока будет добавлен дополнительный класс `а11y-hidden` и текст для альтернативного воспроизведения.

```html
<div class="info a11y-hidden">Информация для людей с ограниченными возможностями.</div>
```

Блок реализован посредством CSS:

```css
.a11y-hidden
{
position: absolute;
left: -32767px;
}
```
5 changes: 5 additions & 0 deletions common.blocks/a11y-hidden/a11y-hidden.styl
@@ -0,0 +1,5 @@
.a11y-hidden
{
position: absolute;
left: -32767px;
}
7 changes: 7 additions & 0 deletions common.blocks/attach/__button/attach__button.bemhtml
Expand Up @@ -8,3 +8,10 @@ block('button')
];
})
);

block('button').elem('text')
.match(this._attach)(
attrs()(function() {
return { id : this._textId };
})
);
9 changes: 8 additions & 1 deletion common.blocks/attach/__button/attach__button.bh.js
@@ -1,7 +1,7 @@
module.exports = function(bh) {

bh.match('button', function(ctx) {
if(ctx.tParam('_attach')) {
if(ctx.tParam('attach')) {
ctx
.applyBase()
.tag('span', true)
Expand All @@ -12,4 +12,11 @@ module.exports = function(bh) {
}
});

bh.match('button__text', function(ctx) {
if(ctx.tParam('attach')) {
ctx
.applyBase()
.attr('id', ctx.tParam('textId'));
}
});
};
6 changes: 5 additions & 1 deletion common.blocks/attach/__control/attach__control.bemhtml
Expand Up @@ -3,14 +3,18 @@ block('attach').elem('control')(
tag()('input'),

attrs()(function() {
var attrs = { type : 'file' },
var attrs = {
type : 'file'
},
attach = this._attach;

// в js генерим html для attach__control без самого attach
if(attach) {
attrs.name = attach.name;
attach.mods && attach.mods.disabled && (attrs.disabled = 'disabled');
attach.tabIndex && (attrs.tabindex = attach.tabIndex);
attrs['aria-label'] = attach.ariaLabel;
attrs['aria-labelledby'] = attach.ariaLabelledby || this._textId;
}

return attrs;
Expand Down
8 changes: 6 additions & 2 deletions common.blocks/attach/__control/attach__control.bh.js
@@ -1,14 +1,18 @@
module.exports = function(bh) {

bh.match('attach__control', function(ctx) {
var attrs = { type : 'file' },
attach = ctx.tParam('_attach');
var attrs = {
type : 'file'
},
attach = ctx.tParam('attach');

// в js генерим html для attach__control без самого attach
if(attach) {
attrs.name = attach.name;
attach.mods && attach.mods.disabled && (attrs.disabled = 'disabled');
attach.tabIndex && (attrs.tabindex = attach.tabIndex);
attrs['aria-label'] = attach.ariaLabel;
attrs['aria-labelledby'] = attach.ariaLabelledby || ctx.tParam('textId');
}

ctx
Expand Down
5 changes: 4 additions & 1 deletion common.blocks/attach/attach.bemhtml
@@ -1,5 +1,7 @@
block('attach')(
def()(function() { applyNext({ _attach : this.ctx }); }),
def()(function() {
applyNext({ _attach : this.ctx, _textId : this.identify() });
}),

tag()('span'),

Expand All @@ -26,6 +28,7 @@ block('attach')(
button,
{
elem : 'no-file',
attrs : { 'aria-hidden' : true },
content : this.ctx.noFileText
}
];
Expand Down
4 changes: 3 additions & 1 deletion common.blocks/attach/attach.bh.js
Expand Up @@ -2,7 +2,8 @@ module.exports = function(bh) {

bh.match('attach', function(ctx, json) {
ctx
.tParam('_attach', json)
.tParam('attach', json)
.tParam('textId', ctx.generateId())
.tag('span')
.js(true);

Expand All @@ -23,6 +24,7 @@ module.exports = function(bh) {
button,
{
elem : 'no-file',
attrs : { 'aria-hidden' : true },
content : json.noFileText
}
], true);
Expand Down
2 changes: 1 addition & 1 deletion common.blocks/attach/attach.tmpl-specs/10-simple.html
@@ -1 +1 @@
<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" type="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" type="button"><input class="attach__control" type="file" name="attach-name" tabindex="1" aria-labelledby=""/></span><span class="attach__no-file" aria-hidden="true">no file</span></span>
2 changes: 1 addition & 1 deletion common.blocks/attach/attach.tmpl-specs/20-disabled.html
@@ -1 +1 @@
<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" type="button" disabled="disabled"><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" type="button" disabled="disabled"><input class="attach__control" type="file" disabled="disabled" aria-labelledby=""/><span class="button__text" id="">file</span></span><span class="attach__no-file" aria-hidden="true">no file</span></span>
Expand Up @@ -43,12 +43,15 @@ describe('button_togglable_check', function() {

triggerPointerUpPointerDown(true);
button.hasMod('checked').should.be.true;
button.domElem.attr('aria-pressed').should.be.equal('true');

triggerPointerUpPointerDown(true);
button.hasMod('checked').should.be.false;
button.domElem.attr('aria-pressed').should.be.equal('false');

triggerPointerUpPointerDown(false);
button.hasMod('checked').should.be.false;
button.domElem.attr('aria-pressed').should.be.equal('false');
});
});
});
Expand Down
Expand Up @@ -43,13 +43,16 @@ describe('button_togglable_radio', function() {

triggerPointerUpPointerDown(true);
button.hasMod('checked').should.be.true;
button.domElem.attr('aria-pressed').should.be.equal('true');

triggerPointerUpPointerDown(true);
button.hasMod('checked').should.be.true;
button.domElem.attr('aria-pressed').should.be.equal('true');

button.delMod('checked');
triggerPointerUpPointerDown(false);
button.hasMod('checked').should.be.false;
button.domElem.attr('aria-pressed').should.be.equal('false');
});
});
});
Expand Down
2 changes: 2 additions & 0 deletions common.blocks/button/_type/button_type_link.js
Expand Up @@ -23,11 +23,13 @@ provide(Button.decl({ modName : 'type', modVal : 'link' }, /** @lends button.pro
'disabled' : {
'true' : function() {
this.__base.apply(this, arguments);

this.domElem.removeAttr('href');
},

'' : function() {
this.__base.apply(this, arguments);

this.domElem.attr('href', this._url);
}
}
Expand Down
6 changes: 5 additions & 1 deletion common.blocks/button/button.bemhtml
Expand Up @@ -17,7 +17,9 @@ block('button')(
role : 'button',
tabindex : ctx.tabIndex,
id : ctx.id,
title : ctx.title
title : ctx.title,
'aria-label' : ctx.ariaLabel,
'aria-labelledby' : ctx.ariaLabelledby
};
},

Expand All @@ -30,6 +32,8 @@ block('button')(
value : ctx.val
};

this.mods.togglable && (attrs['aria-pressed'] = !!this.mods.checked);

this.mods.disabled && (attrs.disabled = 'disabled');

return this.extend(applyNext(), attrs);
Expand Down
6 changes: 5 additions & 1 deletion common.blocks/button/button.bh.js
Expand Up @@ -15,10 +15,14 @@ module.exports = function(bh) {
type : isRealButton? modType || 'button' : undefined,
name : json.name,
value : json.val,
title : json.title
title : json.title,
'aria-label' : json.ariaLabel,
'aria-labelledby' : json.ariaLabelledby
})
.mix({ elem : 'control' }); // NOTE: satisfy interface of `control`

ctx.mod('togglable') && ctx.attr('aria-pressed', !!ctx.mod('checked'));

isRealButton &&
ctx.mod('disabled') &&
ctx.attr('disabled', 'disabled');
Expand Down
6 changes: 6 additions & 0 deletions common.blocks/button/button.js
Expand Up @@ -37,6 +37,12 @@ provide(BEMDOM.decl({ block : this.name, baseBlock : Control }, /** @lends butto
}
},

'checked' : {
'*' : function(modName, modValue) {
this.domElem.attr('aria-pressed', !!modValue);
}
},

'disabled' : {
'true' : function() {
this.__base.apply(this, arguments);
Expand Down
11 changes: 11 additions & 0 deletions common.blocks/button/button.tmpl-specs/60-a11y.bemjson.js
@@ -0,0 +1,11 @@
({
block : 'button',
mods : { focused : true, togglable : 'check' },
name : 'name',
val : 'value',
id : 'btn',
text : 'button',
tabIndex : 0,
ariaLabel : 'label',
ariaLabelledby : 'id'
});
1 change: 1 addition & 0 deletions common.blocks/button/button.tmpl-specs/60-a11y.html
@@ -0,0 +1 @@
<button class="button button_focused button_togglable_check 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" aria-label="label" aria-labelledby="id" aria-pressed="false"><span class="button__text">button</span></button>
4 changes: 3 additions & 1 deletion common.blocks/checkbox-group/checkbox-group.bemhtml
Expand Up @@ -29,7 +29,9 @@ block('checkbox-group')(
val : option.val,
text : option.text,
title : option.title,
icon : option.icon
icon : option.icon,
ariaLabel : option.ariaLabel,
ariaLabelledby : option.ariaLabelledby
}
];
});
Expand Down
4 changes: 3 additions & 1 deletion common.blocks/checkbox-group/checkbox-group.bh.js
Expand Up @@ -28,7 +28,9 @@ module.exports = function(bh) {
val : option.val,
text : option.text,
title : option.title,
icon : option.icon
icon : option.icon,
ariaLabel : option.ariaLabel,
ariaLabelledby : option.ariaLabelledby
}
];
}));
Expand Down
@@ -1 +1 @@
<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"><i aria-hidden="true" class="icon icon_social_vk"></i><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" 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" aria-pressed="false"><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" aria-pressed="false"><i aria-hidden="true" class="icon icon_social_vk"></i><span class="button__text">VK</span></button><input class="checkbox__control" type="checkbox" autocomplete="off" disabled="disabled"/></label></span>
3 changes: 3 additions & 0 deletions common.blocks/checkbox/__control/checkbox__control.bemhtml
Expand Up @@ -8,6 +8,9 @@ block('checkbox').elem('control')(

attrs.name = ctx.name;
attrs.value = ctx.val;
attrs['aria-label'] = ctx.ariaLabel;
attrs['aria-labelledby'] = ctx.ariaLabelledby;

ctx.checked && (attrs.checked = 'checked');
ctx.disabled && (attrs.disabled = 'disabled');

Expand Down
3 changes: 3 additions & 0 deletions common.blocks/checkbox/__control/checkbox__control.bh.js
Expand Up @@ -8,6 +8,9 @@ module.exports = function(bh) {

attrs.name = json.name;
attrs.value = json.val;
attrs['aria-label'] = json.ariaLabel;
attrs['aria-labelledby'] = json.ariaLabelledby;

json.checked && (attrs.checked = 'checked');
json.disabled && (attrs.disabled = 'disabled');

Expand Down
2 changes: 2 additions & 0 deletions common.blocks/checkbox/_type/checkbox_type_button.bemhtml
Expand Up @@ -13,6 +13,8 @@ block('checkbox').mod('type', 'button')(
size : mods.size
},
title : ctx.title,
ariaLabel : ctx.ariaLabel,
ariaLabelledby : ctx.ariaLabelledby,
content : [
ctx.icon,
typeof ctx.text !== 'undefined'?
Expand Down
2 changes: 2 additions & 0 deletions common.blocks/checkbox/_type/checkbox_type_button.bh.js
Expand Up @@ -13,6 +13,8 @@ module.exports = function(bh) {
size : mods.size
},
title : json.title,
ariaLabel : json.ariaLabel,
ariaLabelledby : json.ariaLabelledby,
content : [
json.icon,
typeof json.text !== 'undefined'?
Expand Down
4 changes: 3 additions & 1 deletion common.blocks/checkbox/checkbox.bemhtml
Expand Up @@ -15,7 +15,9 @@ block('checkbox')(
checked : mods.checked,
disabled : mods.disabled,
name : ctx.name,
val : ctx.val
val : ctx.val,
ariaLabel : ctx.ariaLabel,
ariaLabelledby : ctx.ariaLabelledby
}
},
ctx.text
Expand Down
4 changes: 3 additions & 1 deletion common.blocks/checkbox/checkbox.bh.js
Expand Up @@ -11,7 +11,9 @@ module.exports = function(bh) {
checked : ctx.mod('checked'),
disabled : ctx.mod('disabled'),
name : json.name,
val : json.val
val : json.val,
ariaLabel : json.ariaLabel,
ariaLabelledby : json.ariaLabelledby
}
},
json.text
Expand Down
@@ -1 +1 @@
<label class="checkbox checkbox_type_button checkbox_checked checkbox_disabled checkbox_theme_islands checkbox_size_l i-bem" data-bem="{&quot;checkbox&quot;:{}}"><button class="button button_togglable_check button_checked button_disabled button_theme_islands button_size_l button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button" type="button" disabled="disabled"><i aria-hidden="true" class="icon icon_social_twitter"></i><span class="button__text">type-button</span></button><input class="checkbox__control" type="checkbox" autocomplete="off" name="checkbox-name" value="checkbox-val" checked="checked" disabled="disabled"/></label>
<label class="checkbox checkbox_type_button checkbox_checked checkbox_disabled checkbox_theme_islands checkbox_size_l i-bem" data-bem="{&quot;checkbox&quot;:{}}"><button class="button button_togglable_check button_checked button_disabled button_theme_islands button_size_l button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button" type="button" disabled="disabled" aria-pressed="true"><i aria-hidden="true" class="icon icon_social_twitter"></i><span class="button__text">type-button</span></button><input class="checkbox__control" type="checkbox" autocomplete="off" name="checkbox-name" value="checkbox-val" checked="checked" disabled="disabled"/></label>
9 changes: 9 additions & 0 deletions common.blocks/checkbox/checkbox.tmpl-specs/40-a11y.bemjson.js
@@ -0,0 +1,9 @@
({
block : 'checkbox',
mods : { checked : true, disabled : true },
text : 'checkbox-text',
name : 'checkbox-name',
ariaLabel : 'label',
ariaLabelledby : 'id',
val : 'checkbox-val'
})
1 change: 1 addition & 0 deletions common.blocks/checkbox/checkbox.tmpl-specs/40-a11y.html
@@ -0,0 +1 @@
<label class="checkbox checkbox_checked checkbox_disabled i-bem" data-bem="{&quot;checkbox&quot;:{}}"><span class="checkbox__box"><input class="checkbox__control" type="checkbox" autocomplete="off" name="checkbox-name" value="checkbox-val" checked="checked" disabled="disabled" aria-label="label" aria-labelledby="" /></span>checkbox-text</label>
@@ -0,0 +1,10 @@
({
block : 'checkbox',
mods : { type : 'button', checked : true, disabled : true, theme : 'islands', size : 'l' },
name : 'checkbox-name',
val : 'checkbox-val',
text : 'type-button',
icon : { block : 'icon', mods : { social : 'twitter' } },
ariaLabel : 'label',
ariaLabelledby : 'id'
})
@@ -0,0 +1 @@
<label class="checkbox checkbox_type_button checkbox_checked checkbox_disabled checkbox_theme_islands checkbox_size_l i-bem" data-bem="{&quot;checkbox&quot;:{}}"><button class="button button_togglable_check button_checked button_disabled button_theme_islands button_size_l button__control i-bem" data-bem="{&quot;button&quot;:{}}" role="button" type="button" disabled="disabled" aria-pressed="true" aria-label="label" aria-labelledby=""><i aria-hidden="true" class="icon icon_social_twitter"></i><span class="button__text">type-button</span></button><input class="checkbox__control" type="checkbox" autocomplete="off" name="checkbox-name" value="checkbox-val" checked="checked" disabled="disabled"/></label>

0 comments on commit 515e23e

Please sign in to comment.