Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Details and Button components #761

Merged
merged 8 commits into from
Jun 5, 2018
8 changes: 6 additions & 2 deletions src/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ import Header from './components/header/header'
import Radios from './components/radios/radios'

function initAll () {
new Button().init()
new Details().init()
new Button(document).init()

var $details = document.querySelectorAll('details')
nodeListForEach($details, function ($detail) {
new Details($detail).init()
})

var $checkboxes = document.querySelectorAll('[data-module="checkboxes"]')
nodeListForEach($checkboxes, function ($checkbox) {
Expand Down
79 changes: 15 additions & 64 deletions src/common.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,3 @@
/**
* Add event construct for modern browsers or IE8
* which fires the callback with a pre-converted target reference
* @param {object} node element
* @param {string} type event type (e.g. click, load, or error)
* @param {function} callback function
*/
export function addEvent (node, type, callback) {
// Support: IE9+ and other browsers
if (node.addEventListener) {
node.addEventListener(type, function (event) {
callback(event, event.target)
}, false)
// Support: IE8
} else if (node.attachEvent) {
node.attachEvent('on' + type, function (event) {
callback(event, event.srcElement)
})
}
}

/**
* Remove event utility for modern browsers or IE8
* @param {object} node element
* @param {string} type event type (e.g. click, load, or error)
* @param {function} callback function
*/
export function removeEvent (node, type, callback) {
// Support: IE9+ and other browsers
if (node.removeEventListener) {
node.removeEventListener(type, function (event) {
callback(event, event.target)
}, false)
// Support: IE8
} else if (node.detachEvent) {
node.detachEvent('on' + type, function (event) {
callback(event, event.srcElement)
})
}
}

/**
* Cross-browser character code / key pressed
* @param {object} event event
* @returns {number} character code
*/
export function charCode (event) {
return (typeof event.which === 'number') ? event.which : event.keyCode
}

/**
* Cross-browser preventing default action
* @param {object} event event
*/
export function preventDefault (event) {
// Support: IE9+ and other browsers
if (event.preventDefault) {
event.preventDefault()
// Support: IE8
} else {
event.returnValue = false
}
}

/**
* TODO: Ideally this would be a NodeList.prototype.forEach polyfill
* This seems to fail in IE8, requires more investigation.
Expand All @@ -75,3 +11,18 @@ export function nodeListForEach (nodes, callback) {
callback.call(window, nodes[i], i, nodes)
}
}

// Used to generate a unique string, allows multiple instances of the component without
// Them conflicting with each other.
// https://stackoverflow.com/a/8809472
export function generateUniqueID () {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a simpler version of this?

Copy link
Contributor

@alex-ju alex-ju Jun 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be a bit of an overkill for what we need, but I get is trying to follow rfc4122, so it should be ok.

var d = new Date().getTime()
if (typeof window.performance !== 'undefined' && typeof window.performance.now === 'function') {
d += window.performance.now() // use high-precision timer if available
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0
d = Math.floor(d / 16)
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
})
}
14 changes: 8 additions & 6 deletions src/components/button/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
* Usage instructions:
* the 'shim' will be automatically initialised
*/
import { addEvent, charCode, preventDefault } from '../../common'
import '../../vendor/polyfills/Event' // addEventListener and event.target normaliziation

var KEY_SPACE = 32

function Button () { }
function Button ($module) {
this.$module = $module
}

/**
* Add event handler for KeyDown
Expand All @@ -22,10 +24,10 @@ function Button () { }
*/
Button.prototype.handleKeyDown = function (event) {
// get the target element
var target = event.target || event.srcElement
var target = event.target
// if the element has a role='button' and the pressed key is a space, we'll simulate a click
if (target.getAttribute('role') === 'button' && charCode(event) === KEY_SPACE) {
preventDefault(event)
if (target.getAttribute('role') === 'button' && event.keyCode === KEY_SPACE) {
event.preventDefault()
// trigger the target's click event
target.click()
}
Expand All @@ -36,7 +38,7 @@ Button.prototype.handleKeyDown = function (event) {
* this will help listening for later inserted elements with a role="button"
*/
Button.prototype.init = function () {
addEvent(document, 'keydown', this.handleKeyDown)
this.$module.addEventListener('keydown', this.handleKeyDown)
}

export default Button
Loading