Skip to content

Commit

Permalink
fix: correct named export
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremenichelli committed Aug 8, 2019
1 parent 71d7087 commit 9faeb4e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 115 deletions.
104 changes: 104 additions & 0 deletions src/css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Fallback function
* @method noop
* @returns {undefined}
*/
const noop = () => {}

/**
* Method called when a stylesheet is loaded
* @method __onload__
* @param {Object} config
*/
function __onload__(media, storage, logger) {
this.onload = null
this.media = media || 'all'

logger(null, `${this.href} loaded asynchronously`)

if (storage) {
try {
const rules = this.sheet ? this.sheet.cssRules : this.styleSheet.rules
let styles = rules.reduce((acc, rule) => {
return (acc += rule.cssText)
}, '')

// wrap rules with @media statement if necessary
if (media) styles = `@media ${media} {${styles}}`

// save on web storage
window[`${storage}Storage`].setItem(this.href, styles)
} catch (e) {
logger(e, 'Stylesheet could not be saved for future visits')
}
}
}

/**
* Loads stylesheet asynchronously or retrieves it from web storage
* @method css
* @param {Object} config
*/
function css(config = {}) {
const script = document.getElementsByTagName('script')[0]
const ref = config.ref || script
const logger = config.logger || noop
const link = document.createElement('link')
let storedStyles
let el

// create link element to extract correct href path
link.rel = 'stylesheet'
link.href = config.url

/*
* Detect stored stylesheet content only when storage option is present
* and expose an error in console in case web storage is not supported
*/
if (config.storage) {
try {
storedStyles = window[`${config.storage}Storage`].getItem(link.href)
} catch (error) {
logger(
error,
`${link.href} could not be retrieved from ${config.storage}Storage`
)
}
}

/*
* if stylesheet is in web storage inject a style tag with its
* content, else load it using the link tag
*/
if (storedStyles) {
el = document.createElement('style')

el.textContent = storedStyles

logger(null, `${link.href} retrieved from ${config.storage}Storage`)
} else {
/*
* Filament Group approach to prevent stylesheet to block rendering
* https://github.com/filamentgroup/loadCSS/blob/master/src/loadCSS.js#L26
*/
link.media = 'only x'

/*
* Add crossOrigin attribute for external stylesheets, take in count this
* attribute is not widely supported. In those cases CSS rules will not be
* saved in web storage but stylesheet will be loaded
*/
if (config.crossOrigin) link.crossOrigin = config.crossOrigin

link.onload = __onload__.bind(link, config.media, config.storage, logger)
el = link
}

/*
* Node insert approach taken from Paul Irish's 'Surefire DOM Element Insertion'
* http://www.paulirish.com/2011/surefire-dom-element-insertion/
*/
ref.parentNode.insertBefore(el, ref)
}

export default css
105 changes: 1 addition & 104 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,104 +1 @@
/**
* Fallback function
* @method noop
* @returns {undefined}
*/
const noop = () => {}

/**
* Method called when a stylesheet is loaded
* @method __onload__
* @param {Object} config
*/
function __onload__(media, storage, logger) {
this.onload = null
this.media = media || 'all'

logger(null, `${this.href} loaded asynchronously`)

if (storage) {
try {
const rules = this.sheet ? this.sheet.cssRules : this.styleSheet.rules
let styles = rules.reduce((acc, rule) => {
return (acc += rule.cssText)
}, '')

// wrap rules with @media statement if necessary
if (media) styles = `@media ${media} {${styles}}`

// save on web storage
window[`${storage}Storage`].setItem(this.href, styles)
} catch (e) {
logger(e, 'Stylesheet could not be saved for future visits')
}
}
}

/**
* Loads stylesheet asynchronously or retrieves it from web storage
* @method css
* @param {Object} config
*/
function css(config = {}) {
const script = document.getElementsByTagName('script')[0]
const ref = config.ref || script
const logger = config.logger || noop
const link = document.createElement('link')
let storedStyles
let el

// create link element to extract correct href path
link.rel = 'stylesheet'
link.href = config.url

/*
* Detect stored stylesheet content only when storage option is present
* and expose an error in console in case web storage is not supported
*/
if (config.storage) {
try {
storedStyles = window[`${config.storage}Storage`].getItem(link.href)
} catch (error) {
logger(
error,
`${link.href} could not be retrieved from ${config.storage}Storage`
)
}
}

/*
* if stylesheet is in web storage inject a style tag with its
* content, else load it using the link tag
*/
if (storedStyles) {
el = document.createElement('style')

el.textContent = storedStyles

logger(null, `${link.href} retrieved from ${config.storage}Storage`)
} else {
/*
* Filament Group approach to prevent stylesheet to block rendering
* https://github.com/filamentgroup/loadCSS/blob/master/src/loadCSS.js#L26
*/
link.media = 'only x'

/*
* Add crossOrigin attribute for external stylesheets, take in count this
* attribute is not widely supported. In those cases CSS rules will not be
* saved in web storage but stylesheet will be loaded
*/
if (config.crossOrigin) link.crossOrigin = config.crossOrigin

link.onload = __onload__.bind(link, config.media, config.storage, logger)
el = link
}

/*
* Node insert approach taken from Paul Irish's 'Surefire DOM Element Insertion'
* http://www.paulirish.com/2011/surefire-dom-element-insertion/
*/
ref.parentNode.insertBefore(el, ref)
}

export default { css }
export { default as css } from './css'
22 changes: 11 additions & 11 deletions src/index.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import store from '.'
import { css } from '.'
import test from 'ava'
import sinon from 'sinon'
import clone from 'lodash.clonedeep'
Expand Down Expand Up @@ -69,7 +69,7 @@ test.afterEach(() => {

test('loads stylesheet', (t) => {
const url = 'https://path.to/stylesheet.css'
store.css({ url })
css({ url })

// assigned link properties correctly
t.is(ELEMENTS.link.href, url)
Expand All @@ -94,7 +94,7 @@ test('loads stylesheet', (t) => {
test('accepts media in config object', (t) => {
const url = 'https://path.to/stylesheet.css'
const media = '(max-width: 739px'
store.css({ url, media })
css({ url, media })

ELEMENTS.link.onload()
t.is(ELEMENTS.link.media, media)
Expand All @@ -103,15 +103,15 @@ test('accepts media in config object', (t) => {
test('accepts cross origin attribute', (t) => {
const url = 'https://path.to/stylesheet.css'
const crossOrigin = 'anonymous'
store.css({ url, crossOrigin })
css({ url, crossOrigin })

t.is(ELEMENTS.link.crossOrigin, crossOrigin)
})

test('accepts a reference element for link injection', (t) => {
const url = 'https://path.to/stylesheet.css'
const ref = { parentNode: { insertBefore: sinon.spy() } }
store.css({ url, ref })
css({ url, ref })

t.is(ref.parentNode.insertBefore.getCall(0).args[0], ELEMENTS.link)
t.is(ref.parentNode.insertBefore.getCall(0).args[1], ref)
Expand All @@ -120,7 +120,7 @@ test('accepts a reference element for link injection', (t) => {
test('stores result in localStorage', (t) => {
const url = 'https://path.to/stylesheet.css'
const storage = 'local'
store.css({ url, storage })
css({ url, storage })

// styles gets to local storage
ELEMENTS.link.onload()
Expand All @@ -132,7 +132,7 @@ test('stores result in localStorage', (t) => {
test('stores result in sessionStorage', (t) => {
const url = 'https://path.to/stylesheet.css'
const storage = 'session'
store.css({ url, storage })
css({ url, storage })

// styles gets to session storage
ELEMENTS.link.onload()
Expand All @@ -146,7 +146,7 @@ test('retrieves already saved styles from localStorage', (t) => {
const storage = 'local'
const styles = `${firstRule}${secondRule}`
window.localStorage[url] = styles
store.css({ url, storage })
css({ url, storage })

t.is(window.localStorage.getItem.getCall(0).args[0], url)
t.is(ELEMENTS.style.textContent, styles)
Expand All @@ -157,7 +157,7 @@ test('retrieves already saved styles from sessionStorage', (t) => {
const storage = 'session'
const styles = `${firstRule}${secondRule}`
window.sessionStorage[url] = styles
store.css({ url, storage })
css({ url, storage })

t.is(window.sessionStorage.getItem.getCall(0).args[0], url)
t.is(ELEMENTS.style.textContent, styles)
Expand All @@ -168,7 +168,7 @@ test('wraps styles in media when storing', (t) => {
const media = '(max-width: 739px)'
const storage = 'session'
const styles = `${firstRule}${secondRule}`
store.css({ url, media, storage })
css({ url, media, storage })

ELEMENTS.link.onload()
t.is(
Expand All @@ -181,7 +181,7 @@ test('accepts logger method', (t) => {
const url = 'https://path.to/stylesheet.css'
const storage = 'session'
const logger = sinon.spy()
store.css({ url, storage, logger })
css({ url, storage, logger })

ELEMENTS.link.onload()
t.is(logger.getCall(0).args[0], null)
Expand Down

0 comments on commit 9faeb4e

Please sign in to comment.