Giter Site home page Giter Site logo

medialize / ally.js Goto Github PK

View Code? Open in Web Editor NEW
1.5K 51.0 85.0 5.06 MB

JavaScript library to help modern web applications with accessibility concerns

Home Page: http://allyjs.io/

License: MIT License

JavaScript 70.29% HTML 28.75% CSS 0.91% PHP 0.05%
accessibility a11y javascript focus keyboard keyboard-navigation

ally.js's Introduction

ally.js - making accessibility simpler


NPM version NPM Downloads MIT License Travis CI Code Climate Test coverage

Dependencies Dev-Dependencies


ally.js is a JavaScript library simplifying certain accessibility features, functions and behaviors. Its goal is to be A JavaScript library to help web applications with accessibility concerns. The intention is to separate these generic components from actual applications and other libraries.

See the website for more


Requirements

Dependencies

Resources

Supported by

  • BrowserStack and SauceLabs provide VMs for automated testing - free for open source projects.
  • Code Climate and Coveralls provide us with automated code analysis and coverage reports - free for open source projects.
  • Travis CI provides a build server - free for open source projects.
  • Algolia provides a search interface - free for open source projects.

License

ally.js is published under the MIT License.

ally.js's People

Contributors

braincrumbz avatar cvan avatar gitter-badger avatar jantimon avatar jordanaustin avatar patrickarlt avatar rodneyrehm avatar ryan-ludwig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ally.js's Issues

CLA snafu

ally.js is being published under MIT license for the time being. Should the project ever achieve its goals (i.e. move into a FOSS foundation), it is likely that the license has to be changed a bit.

I wonder if it's wise to begin collecting signatures for a CLA (Contributor License Agreement) right away, rather than having to hunt them down later.

I also wonder if it is sufficient to make authors agree to the CLA (e.g. jQuery CLA) via a comment in the PR.

rename `focus/*` to `maintain/*`

The intention of the namespace "focus" is not very clear. The behavior of the functions in this group is to maintain a certain behavior until that behavior is disengaged.

add ancestrySiblings()

When opening a modal dialog it is not enough to disable all the focusable elements, you also need to mark them "hidden" by way of aria-hidden="true". example

Marcy built that into angular dialog component and we should provide the same feature.

design website

the website needs some styles…

git clone [email protected]:medialize/ally.js.git
cd ally.js
git checkout master
npm install
npm run build-website

Will clone the repository, install the tools and generate the website to ally.js/web.

Assets (like stylesheets, images, …) are maintained in ally.js/metalsmith/assets.

add build tool

make a11y.js compatible with CJS, AMD and global comsumption

Why two projects?

Hey! I'm the primary maintainer of a11y.js. I love what you're doing here, but curious why a separate project as opposed to working on one project? a11y.js currently only does states, but that's because it was our primary need at the time. The goals of the two projects are the same, to make accessibility easier in a library independent way.

Why don't we combine forces and work together?

`dom/is-visible` fails focusable children of `<canvas>`

The <canvas> element may have children for compatibility. Those children, while not rendered, can be focused and tabbed to. But because they're not rendered, they do not necessarily have dimension and are thus considered hidden by dom/is-visible.

ally.query.tabsequence: tabindex sorting within ShadowRoot

Because ally.query.focusable can find shadowed elements, util/sort-element-by-tabindex must be extended.

  • The tabindex of an element within a ShadowRoot does not affect the global tabbing order, only the one within the ShadowRoot.
  • Firefox (currently) ignores positive tabindex [tabindex="1"] within ShadowRoot - these elements are not added to the tabbing order. Firefox sorts tabindex globally, not limited to ShadowRoot.

util/sort-element-by-tabindex should sort the children of a ShadowRoot independently of the document. Within a document, the ShadowRoot must be treated as an immutable group.

Replace jQuery UI's focusable and tabbable implementations?

To give a brief Twitter discussion a more formal home: jQuery UI implements tabbable and focusable as jQuery selectors. We've recently improved the implementation to deal with visibility:visible inside visibility:hidden elements, but there's still lots that we're missing (okay for jQuery UI's needs, so far).

To be able to replace our implementations, we would need to be able to import the relevant ally.js modules as an external dependency, then wrap them as jQuery selectors.

If we do that, we probably should also merge our tests, and remove the one's on jQuery UI's end: https://github.com/jquery/jquery-ui/blob/master/tests/unit/core/selector.js

/cc @scottgonzalez

put ally.js on a CDN

because ally.js is not yet on cdnjs, we went ahead and pulled it off brcdn.org, which made us litter the following snippet all over the place:

<!-- FIXME: replace brcdn with cdnjs when ready -->
<script src="//brcdn.org/C1Jp8gmo8YhM1FQ8uuU78uKsA.js"></script>
<script>ally = ally.js;</script>

this needs to go before we can release the website and 1.0.0

ally/query/focusable does not find scrollable elements

Internet Explorer 10-11 consider any scrollable container and its scrollable body focusable - no other browser does this.

<div style="width: 100px; height: 50px;">
   <div style="width: 500px; height: 40px;">scrollable content</div>
</div>

drop html and body from is/focusable

<html> is focused in some browsers upon entering the document. But that doesn't mean a script can do the same.

<body> is the default activeElement, which receives focus on document.activeElement.blur() - but it can't be focused directly

refactor ally/focus/disable

extract element disabling into element/disabled, so it is available outside of focus/disable as well.

the purpose of focus/disable remains to cover sub-tree querying and mutation montoring.

The name should be "disabled" as the survey confirms.

  • base filters on "query everything focus relevant and only-tabbable"
  • extract actual disable methods to ally/element/disable
  • extend ally/element/disable to properly disable form elements
  • add docs for ally/element/disable noting how to target in CSS
  • extend ally/is/disabled to identify non-form elements disabled by ally/element/disable

ally/query/focusable does not find `a > img[ismap]` elements

Internet Explorer 10-11 and MS Edge consider the <img> element in the following snippet keyboard focusable ("tabbable") - no other browser does this.

<a href="http://example.org">
  <img ismap src="">
</a>

<!-- img remains keyboard focusable, a does not -->
<a href="http://example.org" tabindex="-1">
  <img ismap src="">
</a>

`focus/trap` stacking

Since only one focus-trap-handler can be active at any given time, we may want to offer an API that can stack these contexts. Trapping focus in context B while focus is already trapped in context A would remember the currently focused element of context A, abort trapping in context A, push context A onto a stack and activate trapping for context B. Upon deactivating the focus trap for context B, the trap for context A would be reactivated and the last foucsed element of context A would regain focus.

prepare legacy files for website

Everything in tests/ needs to remain available at medialize.github.io/ally.js/tests/.

But since we're not throwing node_modules (formerly bower_components) into gh-pages anymore, we need to pull resources from somewhere else, e.g. cdnjs.

ally.query.tabsequence: `<area>` vs `<img usemap>` location in sequence

Issue with ally.query.tabsequence

While Blink and WebKit add <area> elements to the tabbing sequence where they occur in the DOM, Firefox and IE do not. Gecko and Trident remove <area> from the sequence and inject them (possibly multiple times) for every <img usemap> referencing the <map> those <area>s are defined in.

Trident will redirect focus from <img usemap> to the first <area> of the referenced <map>. Firefox does not do this. As this is undetectable behavior, differention in code would have to rely on platform.js (i.e. user agent sniffing).

This should not require refactoring util/sort-element-by-tabindex, since the issue only exists with ally.query.tabsequence.

`focus/trap` cannot deal with positive tabindex (`[tabindex="1"]`)

focus/trap is trying to do as little intervention as possible - it only reacts to focus leaving the context.

Chrome's implementation of <dialog> behaves similar to its implementation of ShadowDOM in respect to positive tabindex values ([tabindex="1"]) - i.e. they're treated as if they were local to the context (<dialog> / ShadowRoot).

To achieve the same effect in with focus/trap we would have to intercept and handle all Tab and Shift Tab calls. We could not rely upon the browser picking the proper element to focus, because [tabindex="1"] is considered globally (when not in a <dialog> or ShadowRoot). We can use dom/query-tabsequence to identify and properly sort a local tabbing sequence.

The question remaining is if listening for Tab and Shift Tab is sufficient. There may be browsers / OS / AT that have different ideas about this.

fix is/focus-relevant to understand SVG tabindex/focusable

Only Blink and WebKit understand tabindex on SVGElements - detectable through element.tabIndex !== undefined.

IE understands the focusable attribute on SVGElement, where focusable="true" behaves like tabindex="0" and focusable="false" renders the element inert. Not sure how to detect this yet.

related #7, #37

handle unwanted focus-events in focus/disable

  • if an element gains focus that has ['data-ally-disabled'] it must be blur()ed
  • if an element gains focus that matches the filter-critera it must be blur()ed

some elements might not dispatch focus event, so we need to observe document.activeElement to be sure.

create when/key to observe simple commands

It is very common for widgets to be required to handle certain keys during their lifetime. According to ARIA Practices the dialog widget should handle Enter and Escape, next to Tab and Shift+Tab.

This is required for the "keyboard accessible dialog tutorial"

maintain/disabled should handle aria-disabled on ancestry-siblings

It does not make sense to disable the interactive components of a sub-tree without also marking the entire sub-tree as disabled. Therefore the module maintain/disabled (formerly focus/disable) should also engage and disengage aria-disabled. A refactoring of get/ancestry-siblings may be necessary to allow multiple context and filters.

var ancestrySiblings = getAncestrySiblings({
  context: dialog,
});
ancestrySiblings.forEach(function(element) {
  element.setAttribute('aria-disabled', 'true');
});

document supports/*

while fixing mismatches in is/focusable, a few new focus-detection scripts have been added to supports. These need to be documented in docs/supports.md

reorganize /dist to simplify CommonJS import

While discussing ally with @darobin, it became clear that using modules (with systems like browserify) is not ideal yet. We're assuming two things:

  1. users will (at least currently) prefer CommonJS modules
  2. users of AMD and ES6 can configure paths and are used to it

the current structure is

node_modules/ally.js/
├── dist
│   ├── ally.min.js (UMD)
│   ├── ally.min.js.map (UMD)
│   ├── amd
│   │   └── <AMD files>
│   └── common
│       └── <CJS files>
└── src
    └── <ES6 files>

the proposed structure is

node_modules/ally.js/
├── ally.min.js (UMD)
├── ally.min.js.map (UMD)
├── <CJS files>
├── amd
│   └── <AMD files>
└── src
    └── <ES6 files>

which would allow the following - without any configuration - in CommonJS based systems:

// load ally.min.js UMD bundle
var bundle = require('ally.js');
// load the same structure as the UMD bundle, but from CommonJS modules
var bundleFromModules = require('ally.js/ally');
// load a specific module
var module = require('ally.js/query/focusable');

You can configure AMD to load the UMD:

require.config({
  paths: {
    'ally.js': 'node_modules/ally.js/ally.min',
  }
});
// load ally.min.js UMD bundle
var bundle = require('ally.js');

OR you can configure AMD to load the modules:

require.config({
  paths: {
    'ally.js': 'node_modules/ally.js/amd',
  }
});
// load the same structure as the UMD bundle, but from AMD modules
var bundleFromModules = require('ally.js/ally');
// load a specific module
var module = require('ally.js/query/focusable');

The same applies to es6-module-loader.

ally/query/focusable does not find `user-modify: read-write;` elements

user-modify, although dropped from CSS UI, is implemented in WebKit, Blink and Gecko. While -moz-user-modify seems to do nothing, -webkit-user-modify makes an element behave similar to [contenteditable] and also makes it behave like [tabindex="0"] was set.

I'm not sure how an element can be found by "having a certain style" other than filtering the CSSOM for appropriate selectors (and missing instances using element.style). At this point a "known issue" seems like the way to go.

Investigate utilities to simplify a11y for WebComponents

With Custom Elements on the rise and the specification itself promoting the use of WAI-ARIA it is even more important to make this stuff as simple as possible.

The <taco-button> example illustrates how disabling a role="button" is supposed to work: by removing tabindex, onclick, onkeypress and adding aria-disabled="true" - that is a lot of DOM action necessary to compensate for something otherwise as simple as <button … disabled>.

It looks like form element semantics like [disabled] and :disabled will be available to Type Extensions (<input … is="my-cool-thing">) only.

scroll element into view

investigate how well Element.scrollIntoView() is supported, what WebKit's proprietary scrollIntoViewIfNeeded() (polyfill) brings to the table and how any of this can/should be used in scrollable lists. scrollIntoViewIfNeeded is likely not going to happen, but CSSOM View may have an answer.

scrollIntoView() may cause scrolling even when the element in question already is in view. I assume that's why WebKit introduced scrollIntoViewIfNeeded(). It may also move the entire page, instead of only the next scroll container

add gh-pages redirects

from 0.0.7 to 1.0.0 a lot of files have been moved around. to make sure old links don't break we should add redirection-pages (e.g. like this) during the npm build docs or npm build website phase.

  • tests/focusable/table.html
  • tests/static-results/*

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.