SlideShare una empresa de Scribd logo
1 de 91
Descargar para leer sin conexión
Aligning Ember with

Web Standards
EmberConf 2015
@mixonic
Matthew Beale
201 Created
The JavaScript standardization

process is about to change
#1
STANDARDS PROCESS
WHATWG + W3C
TC39 + Ecma International
WHATWG + W3C
TC39 + Ecma International
DOM
HTML WebComponents XHR, Fetch
Promises for loops var, let, const classes
WHATWG W3C
TC39 Ecma International
WHATWG W3C
TC39 Ecma International
WORKING
GROUPS
STANDARDS
GROUPS
The plan at the time was to finish the specification this
year and publish a snapshot of "HTML5" in 2012.
However, shortly after that we realized that the
demand for new features in HTML remained high,
and so we would have to continue maintaining HTML
and adding features to it before we could call “HTML5"
complete, and as a result we moved to a new
development model, where the technology is not
versioned and instead we just have a living document
that defines the technology as it evolves.
Ian Hickson, 2011
“Living Standard”
ES3
ES4
ES5
ES6
ES6
ES2015
“ES2015” signifies a new

standardization process
github.com/

tc39/ecma262
0. Strawman
1. Proposal
2. Draft
3. Candidate
4. Finished
0. Strawman
1. Proposal -> Polyfills
2. Draft -> Experimental
3. Candidate -> Compliant
4. Finished -> Shipping
a “Living Web”
Aligning with standards

is not a one time event
Aligning with standards

is not free
Why standards?
Productivity
1. are portable
2. reflect best practices
3. endure
Standards…
Participants win
Design
Polyfill, demo
Real world use
Learning
Design
Polyfill, demo
Real world use
Learning
2. Transpilers are here
to stay
This is not the first time features
have been added to JavaScript
ES3 -> ES5
HTML5
“Polyfill”
- Remy Sharp
ES5 -> ES2015
var map = new Map();
map.set('key', 'value');
var value = map.get('key');
var map = new Map();
map.set('key', 'value');
var value = map.get('key');
1 var delayed = new Promise(
2 function(resolve, reject){
3 setTimeout(resolve, 100);
4 }
5 );
6 delayed.then(function(){
7 console.log('HTMLBars');
8 });
1 var delayed = new Promise(
2 function(resolve, reject){
3 setTimeout(resolve, 100);
4 }
5 );
6 delayed.then(function(){
7 console.log('HTMLBars');
8 });
1 var loggingObject = new Proxy({}, {
2 get(target, propertyKey, receiver) {
3 console.log('GET '+propertyKey);
4 return target[propertyKey];
5 }
6 });
7
8 loggingObject.whatever; // Logs: GET whatever
1 var loggingObject = new Proxy({}, {
2 get(target, propertyKey, receiver) {
3 console.log('GET '+propertyKey);
4 return target[propertyKey];
5 }
6 });
7
8 loggingObject.whatever; // Logs: GET whatever
1 var runner = {
2 count: 0,
3 call: function() {
4 setTimeout(() => {
5 console.log(this.count++);
6 }, 100);
7 }
8 };
9
10 runner.call();
1 var runner = {
2 count: 0,
3 call: function() {
4 setTimeout(() => {
5 console.log(this.count++);
6 }, 100);
7 }
8 };
9
10 runner.call();
“Babel will turn your ES6+
code into ES5 friendly code,
so you can start using it right
now without waiting for
browser support.”
1 "use strict";
2
3 var runner = {
4 count: 0,
5 call: function call() {
6 var _this = this;
7
8 setTimeout(function () {
9 console.log(_this.count++);
10 }, 100);
11 }
12 };
13
14 runner.call();
1 var runner = {
2 count: 0,
3 call: function() {
4 setTimeout(() => {
5 console.log(this.count++);
6 }, 100);
7 }
8 };
9
10 runner.call();
1. syntax (fat arrow, let)
2. APIs (Map, Set)
3. not everything
Enables new…
“Not born to die”
- James Kyle
kangax.github.io/compat-table/es6
ES2015 feature: Uint8Array
ES2015 feature: Uint8Array
IE10+
ES2015 feature: Spread Operator
var list = [1,2,3];
Math.max(...list);
ES2015 feature: Spread Operator
var list = [1,2,3];
Math.max(...list);
Firefox only
ES2015 feature: Block-level function scope
1 "use strict";
2 function a(){ return 1; }
3 {
4 function a(){ return 2; }
5 };
6
7 a() === 1;
ES2015 feature: Block-level function scope
Chrome only
1 "use strict";
2 function a(){ return 1; }
3 {
4 function a(){ return 2; }
5 };
6
7 a() === 1;
The target platforms of Babel

are inconsistent
Babel
Chrome
Firefox
The platforms your
application supports will drive
what features are transpiled.
Targeting platforms can be
done by tweaking the enabled
features list.
IMO a mapping to platforms
would be better.
What you transpile today,

you will blacklist in two years
Yes, you will be transpiling

in two years
Yes, you will be transpiling

in five years
Yes, you will be transpiling

in ?!!?!?! years
Transpilers are here to stay
3. Aligning Ember’s object model
1. stable
2. a good pattern
3. implemented correctly
4. implemented performantly
Is this feature:
ES Classes
1. class
2. extend
3. super
Three new tools:
1 class Car {
2 constructor(gearCount){
3 this.gearCount = gearCount;
4 }
5
6 toString() {
7 return `A car with: ${gearCount} gears`;
8 }
9 }
10
11 var car = new Car(3);
12 car.toString(); // A car with 3 gears
1 class Vehicle {
2 constructor(gearCount){
3 this.gearCount = gearCount;
4 }
5 }
6 class Car extends Vehicle {
7 toString() {
8 return `A car with: ${this.gearCount} gears`;
9 }
10 }
11
12 var car = new Car(3);
13 car.toString(); // A car with 3 gears
1 class Vehicle {
2 constructor(gearCount){
3 this.gearCount = gearCount;
4 }
5 toString() {
6 return `${this.gearCount} gears`;
7 }
8 }
9 class Car extends Vehicle {
10 toString() {
11 return `A car with: ${super.toString()}`;
12 }
13 }
1 class Vehicle {
2 constructor(gearCount){
3 this.gearCount = gearCount;
4 }
5 toString() {
6 return `${this.gearCount} gears`;
7 }
8 }
9 class Car extends Vehicle {
10 constructor(...args) {
11 console.log(`Created with ${args[0]}`);
12 super(args);
13 }
14 toString() {
15 return `A car with: ${super.toString()}`;
16 }
17 }
1. new syntax
2. super semantics change
3. mixins
gotachas:
4. setUnknownProperty
5. merged/concat properties
6. transpiler ouput?!
more gotachas:
7. only halfway there
7. only halfway there
ES Decorators
1 class Car {
2 +attr('gearsCount')
3 +attr('wheelsCount')
4
5 constructor(gearsCount) {
6 this.gearsCount = gearsCount;
7 }
8
9 -dependsOn('gearsCount')
10 get isModern() {
11 return this.gearsCount > 3;
12 }
13 }
14
15 var car = new Car(3);
16 car.isModern; // false
Aligning
1. provide legacy wrapper
2. use syntax as a carrot
3. private use can start sooner
strategy:
1 import EmberObject from "ember/object";
2 import computed from "ember/computed";
3
4 class Car extends EmberObject.extend({
5
6 init(gearsCount) {
7 this._super(...arguments);
8 this.set('gearsCount', gearsCount);
9 },
10
11 isModern: computed('gearsCount', function(){
12 return this.get('gearsCount') > 3;
13 })
14 });
15
16 export default Car;
1 import EmberObject from "ember/object";
2
3 class Car extends EmberObject {
4
5 constructor(gearsCount) {
6 super(...arguments);
7 this.gearsCount = gearsCount;
8 }
9
10 get isModern() {
11 return this.gearsCount > 3;
12 }
13 }
14
15 export default Car;
1 import Component from "ember/component";
2
3 class Car extends Component {
4
5 get isModern() {
6 return this.attrs.gearsCount > 3;
7 }
8 }
9
10 export default Car;
This is a story of Ember 2.0 -> 3.0
Reminder: Standards are
a two-way street
ONE MORE THING
201-created.com/

ember-community-survey-2015
@ClimbingNarc
201-created.com/ember-community-survey-2015
201-created.com/ember-community-survey-2015
Thank you,
you wonderful people.
@mixonic

Más contenido relacionado

La actualidad más candente

Rapid Application Development with WSO2 Platform
Rapid Application Development with WSO2 PlatformRapid Application Development with WSO2 Platform
Rapid Application Development with WSO2 Platform
WSO2
 
Build Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache Sling
Bob Paulin
 

La actualidad más candente (20)

High Performance JavaScript - jQuery Conference SF Bay Area 2010
High Performance JavaScript - jQuery Conference SF Bay Area 2010High Performance JavaScript - jQuery Conference SF Bay Area 2010
High Performance JavaScript - jQuery Conference SF Bay Area 2010
 
Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJS
 
Beyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisBeyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic Analysis
 
Web Development with NodeJS
Web Development with NodeJSWeb Development with NodeJS
Web Development with NodeJS
 
EWD 3 Training Course Part 14: Using Ajax for QEWD Messages
EWD 3 Training Course Part 14: Using Ajax for QEWD MessagesEWD 3 Training Course Part 14: Using Ajax for QEWD Messages
EWD 3 Training Course Part 14: Using Ajax for QEWD Messages
 
Rapid Application Development with WSO2 Platform
Rapid Application Development with WSO2 PlatformRapid Application Development with WSO2 Platform
Rapid Application Development with WSO2 Platform
 
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
 
Build Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache Sling
 
How to Build Real-time Chat App with Express, ReactJS, and Socket.IO?
How to Build Real-time Chat App with Express, ReactJS, and Socket.IO?How to Build Real-time Chat App with Express, ReactJS, and Socket.IO?
How to Build Real-time Chat App with Express, ReactJS, and Socket.IO?
 
HTML5 Real-Time and Connectivity
HTML5 Real-Time and ConnectivityHTML5 Real-Time and Connectivity
HTML5 Real-Time and Connectivity
 
Django in the Real World
Django in the Real WorldDjango in the Real World
Django in the Real World
 
Taming Functional Web Testing with Spock and Geb
Taming Functional Web Testing with Spock and GebTaming Functional Web Testing with Spock and Geb
Taming Functional Web Testing with Spock and Geb
 
NodeJS : Communication and Round Robin Way
NodeJS : Communication and Round Robin WayNodeJS : Communication and Round Robin Way
NodeJS : Communication and Round Robin Way
 
RESTful Web Applications with Apache Sling
RESTful Web Applications with Apache SlingRESTful Web Applications with Apache Sling
RESTful Web Applications with Apache Sling
 
Web components with java by Haijian Wang
Web components with java by Haijian WangWeb components with java by Haijian Wang
Web components with java by Haijian Wang
 
Asp.Net Core MVC , Razor page , Entity Framework Core
Asp.Net Core MVC , Razor page , Entity Framework CoreAsp.Net Core MVC , Razor page , Entity Framework Core
Asp.Net Core MVC , Razor page , Entity Framework Core
 
Dsc Charusat Learning React Part 1
Dsc Charusat Learning React Part 1 Dsc Charusat Learning React Part 1
Dsc Charusat Learning React Part 1
 
Node JS Express: Steps to Create Restful Web App
Node JS Express: Steps to Create Restful Web AppNode JS Express: Steps to Create Restful Web App
Node JS Express: Steps to Create Restful Web App
 
EWD 3 Training Course Part 20: The DocumentNode Object
EWD 3 Training Course Part 20: The DocumentNode ObjectEWD 3 Training Course Part 20: The DocumentNode Object
EWD 3 Training Course Part 20: The DocumentNode Object
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011
 

Similar a Aligning Ember.js with Web Standards

Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
Ganesh Gembali
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
David Padbury
 

Similar a Aligning Ember.js with Web Standards (20)

HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
ES6 Simplified
ES6 SimplifiedES6 Simplified
ES6 Simplified
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Design Summit - UI Roadmap - Dan Clarizio, Martin Povolny
Design Summit - UI Roadmap - Dan Clarizio, Martin PovolnyDesign Summit - UI Roadmap - Dan Clarizio, Martin Povolny
Design Summit - UI Roadmap - Dan Clarizio, Martin Povolny
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
 
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra  SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Workshop React.js
Workshop React.jsWorkshop React.js
Workshop React.js
 
Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
BOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala appsBOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala apps
 
React Native Evening
React Native EveningReact Native Evening
React Native Evening
 
JS class slides (2016)
JS class slides (2016)JS class slides (2016)
JS class slides (2016)
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBox
 
JS Class 2016
JS Class 2016JS Class 2016
JS Class 2016
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
Module design pattern i.e. express js
Module design pattern i.e. express jsModule design pattern i.e. express js
Module design pattern i.e. express js
 
The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 

Más de Matthew Beale

Scalable vector ember
Scalable vector emberScalable vector ember
Scalable vector ember
Matthew Beale
 

Más de Matthew Beale (15)

Ember.js Module Loading
Ember.js Module LoadingEmber.js Module Loading
Ember.js Module Loading
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component Patterns
 
Ember Community 2016 - Be the Bark
Ember Community 2016 - Be the BarkEmber Community 2016 - Be the Bark
Ember Community 2016 - Be the Bark
 
Attribute actions
Attribute actionsAttribute actions
Attribute actions
 
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)
 
New Component Patterns in Ember.js
New Component Patterns in Ember.jsNew Component Patterns in Ember.js
New Component Patterns in Ember.js
 
Scalable vector ember
Scalable vector emberScalable vector ember
Scalable vector ember
 
Testing Ember Apps: Managing Dependency
Testing Ember Apps: Managing DependencyTesting Ember Apps: Managing Dependency
Testing Ember Apps: Managing Dependency
 
Parse Apps with Ember.js
Parse Apps with Ember.jsParse Apps with Ember.js
Parse Apps with Ember.js
 
Snappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember AppsSnappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember Apps
 
Client-side Auth with Ember.js
Client-side Auth with Ember.jsClient-side Auth with Ember.js
Client-side Auth with Ember.js
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.js
 
Complex Architectures in Ember
Complex Architectures in EmberComplex Architectures in Ember
Complex Architectures in Ember
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 

Último

Último (20)

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 

Aligning Ember.js with Web Standards