Semantic HTML, Web Components, and Javascript
Oh my!
Problem Domain
Angular Person Directive from RT-WAR
<span>
<a style="cursor: pointer" onclick="SP.UI.ModalDialog.showModalDialog({url:'../_layouts/userdisp.aspx?ID={{ personInfo.ID || personInfo.Author.ID || personInfo.User.ID }}'});">
{{ personInfo.Name || personInfo.Author.Name || personInfo.User.Name }}
</a>
</span>
Whoa, That looked Weird
Mustache Style Templates
<h1>{{title}}</h1>
<div>
{{content}}
</div>
{
"title": "Example",
"content": "Here is some example content"
}
Template and POJO
<h1>Example</h1>
<div>
Here is some example content
</div>
Semantic HTML
- HTML that describes the content
-
Use of HTML to reinforce the meaning
- Semantic tags
- h1, form, table, img
- Non-Semantic tags
- div, span
Examples
<button>Go!</button>
vs
<div class="button">Go!</div>
- or -
<div class="link" data-link-to="/about">About</div>
vs
<a href="/about">About</a>
Why do I care?
- Screen readers work better
- Search engines can understand better
- Easier as a dev to understand
- Encourages better separation of concerns
Semantic HTML...
But...
HTML5!
- Nothing new, boagworld has an article from 2005
- HTML 5 just introduces additional tags
- header, nav, section, article, aside, figure, figcaption, footer, details, summary, mark, time
- Know when to use them
Improve what we had
<a style="cursor: pointer" onclick="SP.UI.ModalDialog.showModalDialog({url:'../_layouts/userdisp.aspx?ID={{ personInfo.ID || personInfo.Author.ID || personInfo.User.ID }}'});">
{{ personInfo.Name || personInfo.Author.Name || personInfo.User.Name }}
</a>
- Both span and anchor's are inline elements
- span provides no value in this scenario
Wait a Minute!
- What is that style doing there?
- Well, lets partially fix now
<a onclick="SP.UI.ModalDialog.showModalDialog({url:'../_layouts/userdisp.aspx?ID={{ personInfo.ID || personInfo.Author.ID || personInfo.User.ID }}'});">
{{ personInfo.Name || personInfo.Author.Name || personInfo.User.Name }}
</a>
Web Components
- Allow web developers to define new HTML elements
- Allows more semantic markup
- Allows bundling of Javascript with an element
<x-gas-products>
</x-gas-products>
How Do I Use This?
- Part of the HTML5 spec
- wait for Microsoft to adopt (NOT part of IE11)
- Chrome and Firefox support
- Use a library or framework
- Ember-Components
- Angular Directives
- Polymer
Improve What We Have
- There is really nothing to do here
- Already using an Angular Directive
- We have been looking at the "internal" markup all along
<div data-person data-person-info="item.Author" />
Wait a minute!
- Non-semantic div
- Data prefixing
- Self Closing
<div data-person data-person-info="item.Author" />
Refactor
onclick="SP.UI.ModalDialog.showModalDialog({url:'../_layouts/userdisp.aspx?ID={{ personInfo.ID || personInfo.Author.ID || personInfo.User.ID }}'});"
By using ngClick
<a ng-click="showUserInfoSPModal()">{{ personObject.Name }}</a>
Directive Controller
// personObject is passed into the controller
...
var userDisplayUrl = '/_layouts/userdisp.aspx?ID=' + personObject.ID;
showUserInfoSPModal = function() {
SP.UI.ModalDialog.showModalDialog({url: userDisplayUrl});
};
...
Refactor
onclick="SP.UI.ModalDialog.showModalDialog({url:'../_layouts/userdisp.aspx?ID={{ personInfo.ID || personInfo.Author.ID || personInfo.User.ID }}'});"
By using ngClick
ng-click="showUserInfoSPModal()"
Directive Controller
// personObject is passed into the controller
...
var userDisplayUrl = '/_layouts/userdisp.aspx?ID=' + personObject.ID;
showUserInfoSPModal = function() {
SP.UI.ModalDialog.showModalDialog({url: userDisplayUrl});
};
...
Notable Changes
- Proper separation of code
- Remove complexity
- Added readability
var id = personInfo.ID || personInfo.Author.ID || personInfo.User.ID;
vs
var id = personObject.ID;
Complete Fix
Alluded to a partial fix previously regarding semantic markup
Whats wrong with this?
Whats wrong with this?
<a ng-click="showUserInfoSPModal()">{{ personObject.Name }}</a>
Right! Anchors have HREFs
<a href="{{ userDisplayUrl }}" ng-click="showUserInfoSPModal()">
{{ personObject.Name }}
</a>
That ALl?
Well, by adding that href we handled the old bad inline style
And here are some more examples of components
- Angular Directive
- Ember Component
Resources
Semantic HTML,
By Ryan Hirsch
Semantic HTML,
- 915