building for accessibility
TRANSCRIPT
![Page 1: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/1.jpg)
Designing
![Page 2: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/2.jpg)
Is This Designing?
http://www.adobe.com/inspire/2013/11/photoshop-reflow-generator.html
![Page 4: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/4.jpg)
Is This Designing?
http://thisoldcity.com/advocacy/photos-what-snow-tells-us-about-creating-better-public-spaces-e-passyunk-avenue
![Page 6: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/6.jpg)
Yes.
![Page 7: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/7.jpg)
@nathanhammond nathanhammond.com
nathanhammond
![Page 8: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/8.jpg)
http://www.unicode.org/reports/tr51/tr51-2.html#Emoji_Modifiers
![Page 9: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/9.jpg)
Good Design
https://flic.kr/p/die16e, https://flic.kr/p/99ad9q
![Page 10: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/10.jpg)
Universal Design
Stokke Tripp Trapp
![Page 11: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/11.jpg)
Universal?
![Page 12: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/12.jpg)
Designing for Accessibility
![Page 13: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/13.jpg)
![Page 14: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/14.jpg)
![Page 15: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/15.jpg)
![Page 16: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/16.jpg)
![Page 17: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/17.jpg)
http://www.istockphoto.com/photo/group-of-business-men-and-women-in-a-meeting-37790018
![Page 19: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/19.jpg)
https://commons.wikimedia.org/wiki/File:US_House_Committee.jpg
![Page 21: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/21.jpg)
![Page 22: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/22.jpg)
Demo
![Page 23: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/23.jpg)
Learnings• Screen readers start reading from the top of the
page on each page load.
• Dynamically updating the DOM results in no information being passed to the user by default.
• Markup is still important. Ember's real links and the code you write in your templates is important.
• ARIA roles still do what we expect.
![Page 24: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/24.jpg)
Building for Accessibility
![Page 25: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/25.jpg)
Page LoadingWe want to emulate the page load behavior
demonstrated with static pages.
![Page 26: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/26.jpg)
End-User Goals• Have the screen reader automatically start reading
the content of the page.
• Have it start reading the content from the best point in the application hierarchy.
• Make it clear to the user that the content on the page has changed.
• Follow other recommended patterns that screen reader users are familiar with.
![Page 27: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/27.jpg)
Ember Goals• Have the solution work with current idiomatic
Ember code or minimize migration cost.
• Make the change in a backwards compatible way to meet Ember's stability without stagnation goal.
• The default approach should be accessible, API design is a feature.
• Provide for extensibility with hooks enabling enhancement of this higher-level feature.
![Page 28: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/28.jpg)
Exploration
![Page 29: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/29.jpg)
InventoryRouter, Transitions, Routes,
Templates, Outlets, HTMLBars
![Page 30: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/30.jpg)
Outlet FocusingWhat if we set the focus on the route's outlet immediately
after the transition completes?
![Page 31: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/31.jpg)
Research
![Page 32: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/32.jpg)
Screen Readers• It's like the Internet Explorer and Netscape HTML/
CSS/JS compatibility workarounds all over again.
• Screen readers tend to read whatever you focus.
• Nobody likes being dumped into forms mode.
• Screen readers are aware of content on the page changing, but don't present that to the user until it is asked for.
![Page 33: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/33.jpg)
Ember• The top level outlet is generated and wrapped in a
containing DIV.
• All other outlets are populated by their templates without first being wrapped in a containing DIV.
• Routes have no reference to their rendered output.
• You can have multiple outlets in a single route.
• No-op transitions trigger no route hooks.
![Page 34: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/34.jpg)
Solution Design
![Page 35: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/35.jpg)
API DesignIt'd be nice if every route had a `focus` hook that was
called with the outlet contents.
![Page 36: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/36.jpg)
Ember.Route.reopen({! focus(morph) {! var elem = morph.firstNode;!! try {! if (!elem.getAttribute('tabindex')) {! if (isInteractive(elem)) {! elem.setAttribute('tabindex', 0);! } else {! elem.setAttribute('tabindex', -1);! }! }!! elem.focus();! } catch (e) {}! }!});
![Page 37: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/37.jpg)
DevelopmentHow do we call the `focus` hook?
![Page 38: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/38.jpg)
Ember.Route.reopen({! enter(transition) {! var route = this;!! // Focus "up one level" for index routes.! if (! transition.pivotHandler &&! this.routeName === transition.pH.routeName + '.index'! ) {! transition.pivot = transition.pivotHandler.routeName;! route = transition.pivotHandler;! this._focus(route, transition);! }!! // Handle fresh entries.! if (!transition.pivot) {! transition.pivot = this.routeName;! this._focus(route, transition)! }!! return this._super(...arguments);! }!});
![Page 39: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/39.jpg)
Ember.Route.reopen({! _focus(route, transition, parent) {! var focus = new Ember.RSVP.Promise(function(resolve, reject) {! this.focusPromiseResolve = resolve;! }.bind(route));!! // Set up our context for after the transition completes.! var transitionResolve = (function(transition, route) {! return function(result) {! delete transition.pivot;!! Ember.run.scheduleOnce('afterRender', route, function() {! route.focus(result.focus)! });! };! })(transition, route);!! // Clean up after ourselves in case there is a transition.retry() call.! var transitionReject = (function(transition, route) {! return function() {! delete transition.pivot;! };! })(transition, route);!! Ember.RSVP.hash({ focus, transition })! .then(transitionResolve)! .catch(transitionReject);! }!});
![Page 40: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/40.jpg)
IntegrationWhat happens when Ember needs to be modified.
![Page 41: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/41.jpg)
diff --git a/packages/ember-htmlbars/lib/keywords/outlet.js b/packages/ember-htmlbars/lib/keywords/outlet.js!index 317e899..6b01753 100644!--- a/packages/ember-htmlbars/lib/keywords/outlet.js!+++ b/packages/ember-htmlbars/lib/keywords/outlet.js!@@ -17,6 +17,10 @@ export default function(morph, env, scope, params, hash, template, inverse, visi!+ if (env.outletState.main.render.focusPromiseResolve) {!+ env.outletState.main.render.focusPromiseResolve(morph);!+ delete env.outletState.main.render.focusPromiseResolve;!+ }! keyword('@real_outlet', morph, env, scope, params, hash, template, inverse, visitor);!!diff --git a/packages/ember-routing/lib/system/router.js b/packages/ember-routing/lib/system/router.js!index bb157c1..5600f99 100644!--- a/packages/ember-routing/lib/system/router.js!+++ b/packages/ember-routing/lib/system/router.js!@@ -202,10 +202,18 @@ var EmberRouter = EmberObject.extend(Evented, {! for (var j = 0; j < connections.length; j++) {!+ delete connections[j].focusPromiseResolve;! var appended = appendLiveRoute(liveRoutes, defaultParentState, connections[j]);! liveRoutes = appended.liveRoutes;! if (appended.ownState.render.name === route.routeName || appended.ownState.render.outlet === 'main') {! ownState = appended.ownState;!+ // Pass forward the focus promise resolve hook from the route to the appropriate connection.!+ if (route.focusPromiseResolve) {!+ ownState.render.focusPromiseResolve = route.focusPromiseResolve;!+ delete route.focusPromiseResolve;!+ }
![Page 42: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/42.jpg)
Contributing Back
![Page 43: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/43.jpg)
Write an RFC!You've created and tested a feature!
It's time to get it shipped!
![Page 45: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/45.jpg)
Usage Notes• You can use this today! http://bit.ly/outletfocusing
• All template content must be wrapped in a `<div>`. Child outlets must also appear inside that `<div>`.
• Automatically generated templates are just `{{outlet}}` and will thus have problems.
• Provide feedback on RFC #66!
![Page 46: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/46.jpg)
Demo
![Page 47: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/47.jpg)
Learnings
• It's a different experience from the static site.
• We have programmatic control over the focusing behavior.
• Setting the focus has additional consequences in terms of scrolling behavior.
![Page 48: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/48.jpg)
Challenge
![Page 49: Building for Accessibility](https://reader034.vdocuments.us/reader034/viewer/2022042819/55cadf60bb61eb7f148b469c/html5/thumbnails/49.jpg)