Skip to content

Instantly share code, notes, and snippets.

@jacopotarantino
Created February 29, 2016 23:05
Show Gist options
  • Select an option

  • Save jacopotarantino/5d14810daaf9d40e5be7 to your computer and use it in GitHub Desktop.

Select an option

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.
/**
* 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