Created
February 29, 2016 23:05
-
-
Save jacopotarantino/5d14810daaf9d40e5be7 to your computer and use it in GitHub Desktop.
A UI component for the body text of an article. This is a test to see what would become challenging in rendering normal page content in a more interactive-content fashion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Concerns: | |
| * How to render inline images, links, smart content(eg. `[twitter: @jacopotarantino]`), etc... | |
| * Do those sub-components actually need to be subcomponents or can we just `.innerHTML`? | |
| * What about updating article content? | |
| * Do articles ever really have events on/in them? | |
| */ | |
| import { analytics } from 'services' | |
| import { UIComponent } from 'ui-component' | |
| class Link extends UIComponent { | |
| constructor (link_node) { | |
| // a real implementation of this class would need to take more options like textContent but bear with me for this contrived example. | |
| this.node = link_node || document.createElement('a') | |
| this.node.addEventListener('click', event => { | |
| analytics.track('clicked on a link', {text: event.target.textContent}) | |
| }) | |
| } | |
| } | |
| class Article extends UIComponent { | |
| constructor (contents) { | |
| this.node = document.createElement('article') | |
| // this assumes we want to just fill up the article's insides. does not address the idea of parsing the contents before adding them to the article. | |
| this.node.innerHTML = contents | |
| // possibly add a behavior to the links? | |
| // note, this is semi-pseudocode | |
| // in this case we're mostly falling back on the old technique of scanning a document for stuff and using jQuery to move that stuff around. | |
| let links = this.node.querySelectorAll('a') | |
| [].prototype.forEach.call(links, link => { | |
| link.addEventListener('click', event => { | |
| analytics.track('clicked on a link', {text: event.target.textContent}) | |
| }) | |
| }) | |
| // or replace the links with Link instances? | |
| // in this case we can treat the links like proper objects with APIs if we want to do something with them. | |
| // or we can add all of the link instance behavior including analytics to the Link class. | |
| // it's a bit sloppy to leave the initialization to the Article instance though... | |
| let links = this.node.querySelectorAll('a') | |
| [].prototype.forEach.call(links, current_link_node => { | |
| let link = new Link(current_link_node) | |
| }) | |
| // or add the behavior on the article instance itself? | |
| // this avoids modifying the contents of the article at all but conflates the behavior of stuff *in* the article with the article itself which is mostly just a div.. | |
| // could lead to a very bloated Article instance but requires zero parsing of the contents... is that more maintainable? | |
| this.node.addEventListener('click', event => { | |
| // if we capture a click event and it's on an anchor | |
| if (event.originalTarget.nodeName === 'a') { | |
| // stop redirection | |
| event.preventDefault() | |
| // run analytics or something | |
| do_something() | |
| // then continue... | |
| then_redirect_to(event.originalTarget.href) | |
| } | |
| }) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment