Skip to content

Commit

Permalink
Consistently rename data URI -> data URL.
Browse files Browse the repository at this point in the history
Neither identifier nor locator fits the meaning very well (is it both?),
but data URL is the term used commonly and originally (RFC 2397).
  • Loading branch information
Treora committed Jul 13, 2017
1 parent a5ba6f1 commit 95fcbd0
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 72 deletions.
2 changes: 1 addition & 1 deletion src/activity-logger/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function generateVisitDocId({timestamp, nonce} = {}) {

// Tell whether a page can be stored.
export function isLoggable({url}) {
// Only http(s) pages. Ignoring data uris, newtab, ...
// Only http(s) pages. Ignoring data URLs, newtab, ...
const loggableUrlPattern = /^https?:\/\//
return loggableUrlPattern.test(url)
}
Expand Down
20 changes: 10 additions & 10 deletions src/freeze-dry/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ export function removeNode(node) {
node.parentNode.removeChild(node)
}

export async function urlToDataUri(url) {
export async function urlToDataUrl(url) {
try {
const response = await fetch(url, {cache: 'force-cache'})
const dataUri = await responseToDataUrl(response)
return dataUri
const dataUrl = await responseToDataUrl(response)
return dataUrl
} catch (err) {
return 'about:invalid'
}
}

// Find all URLs in the specified attribute(s) of the specified elements, fetch
// their contents, and replace the URL with the content encoded as a data URI.
// their contents, and replace the URL with the content encoded as a data URL.
// The elements argument can be a query selector string if rootElement is given.
export async function inlineUrlsInAttributes({
elements,
Expand All @@ -44,17 +44,17 @@ export async function inlineUrlsInAttributes({
const urls = attrToUrls(value, attribute)

// Fetch (hopefully from cache) the resource for each URL.
const dataUriPs = urls.map(async url => {
const dataUrlPs = urls.map(async url => {
const absoluteUrl = new URL(url, docUrl)
const dataUri = await urlToDataUri(absoluteUrl)
return dataUri
const dataUrl = await urlToDataUrl(absoluteUrl)
return dataUrl
})
const dataUris = await Promise.all(dataUriPs)
const dataUrls = await Promise.all(dataUrlPs)

// Replace the URLs in the attribute value with the data URIs.
// Replace the URLs in the attribute value with the data URLs.
let newValue = value
for (let i = 0; i < urls.length; i++) {
newValue = newValue.replace(urls[i], dataUris[i])
newValue = newValue.replace(urls[i], dataUrls[i])
}
if (newValue !== value) {
element.setAttribute(attribute, newValue)
Expand Down
34 changes: 17 additions & 17 deletions src/freeze-dry/common.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-env jest */

import { inlineUrlsInAttributes, urlToDataUri, removeNode } from 'src/freeze-dry/common'
import { inlineUrlsInAttributes, urlToDataUrl, removeNode } from 'src/freeze-dry/common'
import * as responseToDataUrl from 'response-to-data-url'
import { dataURLToBlob } from 'blob-util'


const imageDataUri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg=='
const imageDataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg=='

beforeEach(() => {
fetch.resetMocks()
Expand All @@ -23,30 +23,30 @@ describe('removeNode', () => {
})
})

describe('urlToDataUri', () => {
test('should return a dataUri given a URL', async () => {
const someDataUri = 'data:text/html,<h1>bananas</h1>'
describe('urlToDataUrl', () => {
test('should return a dataUrl given a URL', async () => {
const someDataUrl = 'data:text/html,<h1>bananas</h1>'
const spy = jest.spyOn(responseToDataUrl, 'default').mockImplementation(async () => {
return someDataUri
return someDataUrl
})
const dataUri = await urlToDataUri('https://example.com/page')
expect(dataUri).toBe(someDataUri)
const dataUrl = await urlToDataUrl('https://example.com/page')
expect(dataUrl).toBe(someDataUrl)
spy.mockRestore()
})

test('should return a "about:invalid" upon failure', async () => {
const spy = jest.spyOn(responseToDataUrl, 'default').mockImplementation(async () => {
throw new Error('mock error')
})
const dataUri = await urlToDataUri('http://example.com')
expect(dataUri).toBe('about:invalid')
const dataUrl = await urlToDataUrl('http://example.com')
expect(dataUrl).toBe('about:invalid')
spy.mockRestore()
})

test('should return a "about:invalid" when fetching fails', async () => {
fetch.mockRejectOnce()
const dataUri = await urlToDataUri('http://example.com')
expect(dataUri).toBe('about:invalid')
const dataUrl = await urlToDataUrl('http://example.com')
expect(dataUrl).toBe('about:invalid')
})
})

Expand All @@ -56,10 +56,10 @@ describe('inlineUrlsInAttributes', () => {
let imageBlob

beforeAll(async () => {
imageBlob = await dataURLToBlob(imageDataUri)
imageBlob = await dataURLToBlob(imageDataUrl)
})

test('should change the URL in <img> tag to a dataUri', async () => {
test('should change the URL in <img> tag to a dataUrl', async () => {
fetch.mockResponseOnce(imageBlob)
const doc = parser.parseFromString(
'<html><body><img src="public/image/background.png" alt="background" /></body></html>',
Expand All @@ -68,10 +68,10 @@ describe('inlineUrlsInAttributes', () => {
const rootElement = doc.documentElement
await inlineUrlsInAttributes({elements: 'img', attributes: 'src', rootElement, docUrl})
expect(rootElement.querySelector('img').getAttribute('data-original-src')).toBe('public/image/background.png')
expect(rootElement.querySelector('img').getAttribute('src')).toBe(imageDataUri)
expect(rootElement.querySelector('img').getAttribute('src')).toBe(imageDataUrl)
})

test('should change the URL in the <link> tag to a dataUri', async () => {
test('should change the URL in the <link> tag to a dataUrl', async () => {
fetch.mockResponseOnce(imageBlob)
const doc = parser.parseFromString(
'<html><head><link rel="icon" href="public/image/favicon.ico"></head></html>',
Expand All @@ -80,7 +80,7 @@ describe('inlineUrlsInAttributes', () => {
const rootElement = doc.documentElement
await inlineUrlsInAttributes({elements: 'link', attributes: 'href', rootElement, docUrl})
expect(rootElement.querySelector('link').getAttribute('data-original-href')).toBe('public/image/favicon.ico')
expect(rootElement.querySelector('link').getAttribute('href')).toBe(imageDataUri)
expect(rootElement.querySelector('link').getAttribute('href')).toBe(imageDataUrl)
})

test('should remove the attribute integrity from the tag', async () => {
Expand Down
6 changes: 3 additions & 3 deletions src/freeze-dry/fix-links.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ describe('fixLinks', () => {
})

test('should not alter data urls in href attribute', async () => {
const datauri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg=='
const dataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg=='
const rootElement = window.document.createElement('div')
rootElement.innerHTML = `<a href="${datauri}">Link</a>`
rootElement.innerHTML = `<a href="${dataUrl}">Link</a>`
await fixLinks({rootElement, docUrl})
expect(rootElement.querySelector('*[href]').getAttribute('href')).toBe(datauri)
expect(rootElement.querySelector('*[href]').getAttribute('href')).toBe(dataUrl)
})
})
12 changes: 6 additions & 6 deletions src/freeze-dry/inline-styles.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import whenAllSettled from 'when-all-settled'
import { urlToDataUri } from './common'
import { urlToDataUrl } from './common'


// Finds all url(...) occurrances in a string of CSS, then fetches and inlines
// them as data URIs.
// them as data URLs.
// Returns the processed (and possibly much larger) string of CSS.
async function inlineStylesheetContents({stylesheetText, stylesheetUrl}) {
const cssFindUrlsPattern = /url\s*\(\s*('|")?\s*([^"')]+?)\s*\1\s*\)/ig
Expand All @@ -18,14 +18,14 @@ async function inlineStylesheetContents({stylesheetText, stylesheetUrl}) {
? new URL(match[2], stylesheetUrl)
: undefined
})
const dataUris = await Promise.all(urls.map(urlToDataUri))
dataUris.forEach((dataUri, i) => {
stylesheetText = stylesheetText.replace(cssUrls[i], `url(${dataUri})`)
const dataUrls = await Promise.all(urls.map(urlToDataUrl))
dataUrls.forEach((dataUrl, i) => {
stylesheetText = stylesheetText.replace(cssUrls[i], `url(${dataUrl})`)
})
return stylesheetText
}

// In every <link rel="stylesheet"> tag, inline the stylesheet as a data URI,
// In every <link rel="stylesheet"> tag, inline the stylesheet as a data URL,
// and inline every URL within that stylesheet.
async function inlineLinkedStylesheets({rootElement, docUrl}) {
const querySelector = 'link[rel*="stylesheet"][href]'
Expand Down
20 changes: 10 additions & 10 deletions src/freeze-dry/inline-styles.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import * as common from 'src/freeze-dry/common'
import { dataURLToBlob } from 'blob-util'


const imageDataUri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg=='
const imageDataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg=='

describe('inlineStyles', () => {
const parser = new DOMParser()
let imageBlob

beforeAll(async () => {
imageBlob = await dataURLToBlob(imageDataUri)
imageBlob = await dataURLToBlob(imageDataUrl)
})

test('should return <style> tag with the fetched stylesheet', async () => {
Expand All @@ -34,14 +34,14 @@ describe('inlineStyles', () => {
const docUrl = 'https://example.com'
await inlineStyles({rootElement: doc.documentElement, docUrl})
expect(doc.querySelector('style').innerHTML)
.toBe(`div{background-image: url(${imageDataUri});}`)
.toBe(`div{background-image: url(${imageDataUrl});}`)
})

test('should convert the url in <style> to dataUris', async () => {
test('should convert the url in <style> to dataUrls', async () => {
const styleSheet = 'div{background-image: url("public/image/background.jpeg");}'
fetch.mockResponseOnce(new Blob([styleSheet]))
const styleSheetAsDataUri = `data:text/plain;charset=utf-8;base64,aHR0cHM6Ly9leGFtcGxlLmNvbS9wdWJsaWMvaW1hZ2UvYmFja2dyb3VuZC5qcGVn`
const spy = jest.spyOn(common, 'urlToDataUri').mockReturnValue(styleSheetAsDataUri)
const styleSheetAsDataUrl = `data:text/plain;charset=utf-8;base64,aHR0cHM6Ly9leGFtcGxlLmNvbS9wdWJsaWMvaW1hZ2UvYmFja2dyb3VuZC5qcGVn`
const spy = jest.spyOn(common, 'urlToDataUrl').mockReturnValue(styleSheetAsDataUrl)
const doc = parser.parseFromString(
`<html>
<head>
Expand All @@ -58,12 +58,12 @@ describe('inlineStyles', () => {
await inlineStyles({rootElement: doc.documentElement, docUrl})
expect(spy).toHaveBeenCalled()
expect(doc.querySelector('style').innerHTML.trim())
.toBe(`div{background-image: url(${styleSheetAsDataUri});}`)
.toBe(`div{background-image: url(${styleSheetAsDataUrl});}`)
spy.mockRestore()
})

test('should convert the urls in a style attribute to data uris', async () => {
const spy = jest.spyOn(common, 'urlToDataUri').mockReturnValue(imageDataUri)
test('should convert the urls in a style attribute to data URLs', async () => {
const spy = jest.spyOn(common, 'urlToDataUrl').mockReturnValue(imageDataUrl)
const doc = parser.parseFromString(
'<html><div style="background-image: url(\'public/image/background.jpeg\');"></div></html>',
'text/html'
Expand All @@ -72,7 +72,7 @@ describe('inlineStyles', () => {
await inlineStyles({rootElement: doc.documentElement, docUrl})
expect(spy).toHaveBeenCalled()
expect(doc.querySelector('div').getAttribute('style'))
.toBe(`background-image: url(${imageDataUri});`)
.toBe(`background-image: url(${imageDataUrl});`)
spy.mockRestore()
})
})
2 changes: 1 addition & 1 deletion src/freeze-dry/set-content-security-policy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default function setContentSecurityPolicy({doc, policyDirectives}) {
doc.documentElement.insertAdjacentElement('afterbegin', head)
}

// Disallow any sources, except data URIs where we use them.
// Disallow any sources, except data URLs where we use them.
const csp = policyDirectives.join('; ')

const metaEl = doc.createElement('meta')
Expand Down
10 changes: 5 additions & 5 deletions src/overview/components/ImgFromPouch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import omit from 'lodash/fp/omit'
import React from 'react'
import PropTypes from 'prop-types'

import { getAttachmentAsDataUri } from 'src/pouchdb'
import { getAttachmentAsDataUrl } from 'src/pouchdb'


const readHash = ({doc, attachmentId}) =>
Expand All @@ -13,7 +13,7 @@ export default class ImgFromPouch extends React.Component {
constructor(props) {
super(props)
this.state = {
dataUri: undefined,
dataUrl: undefined,
}
}

Expand All @@ -35,9 +35,9 @@ export default class ImgFromPouch extends React.Component {
}

async updateFile({doc, attachmentId}) {
const dataUri = await getAttachmentAsDataUri({doc, attachmentId})
const dataUrl = await getAttachmentAsDataUrl({doc, attachmentId})
if (this._isMounted) {
this.setState({dataUri})
this.setState({dataUrl})
}
}

Expand All @@ -46,7 +46,7 @@ export default class ImgFromPouch extends React.Component {
return (
<img
{...childProps}
src={this.state.dataUri}
src={this.state.dataUrl}
/>
)
}
Expand Down
6 changes: 3 additions & 3 deletions src/page-analysis/background/get-fav-icon.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import responseToDataUrl from 'response-to-data-url'

// Get a tab's fav-icon (website logo) as a data URI
// Get a tab's fav-icon (website logo) as a data URL
async function getFavIcon({tabId}) {
const tab = await browser.tabs.get(tabId)

Expand All @@ -9,8 +9,8 @@ async function getFavIcon({tabId}) {
}

const response = await fetch(tab.favIconUrl)
const dataURI = await responseToDataUrl(response)
return dataURI
const dataUrl = await responseToDataUrl(response)
return dataUrl
}

export default getFavIcon
12 changes: 6 additions & 6 deletions src/page-analysis/background/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ async function performPageAnalysis({pageId, tabId}) {
}

// Get and store the fav-icon
const storeFavIcon = getFavIcon({tabId}).then(async dataUri => {
if (dataUri === undefined) return
const blob = await dataURLToBlob(dataUri)
const storeFavIcon = getFavIcon({tabId}).then(async dataUrl => {
if (dataUrl === undefined) return
const blob = await dataURLToBlob(dataUrl)
await setDocAttachment(db, pageId, 'favIcon')(blob)
})

// Capture a screenshot.
const storeScreenshot = makeScreenshot({tabId}).then(async dataUri => {
if (dataUri === undefined) return
const blob = await dataURLToBlob(dataUri)
const storeScreenshot = makeScreenshot({tabId}).then(async dataUrl => {
if (dataUrl === undefined) return
const blob = await dataURLToBlob(dataUrl)
await setDocAttachment(db, pageId, 'screenshot')(blob)
})

Expand Down
4 changes: 2 additions & 2 deletions src/page-analysis/background/make-screenshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import delay from 'src/util/delay'
import { whenTabActive } from 'src/util/tab-events'

// Take a screenshot of the tabId, if it is active.
// Returns a promise of the screenshot (a png image in a data URI).
// Returns a promise of the screenshot (a png image in a data URL).
// The promise rejects if the tab is not currently active!
async function snapNow({tabId}) {
const tab = await browser.tabs.get(tabId)
Expand All @@ -13,7 +13,7 @@ async function snapNow({tabId}) {
return image
}

// Return the promise of an image (as data URI) of the visible area of the tab,
// Return the promise of an image (as data URL) of the visible area of the tab,
// but only as soon as it is active (due to a limitation of the browser API)
export default async function makeScreenshotOfTabAsap({tabId}) {
await whenTabActive({tabId})
Expand Down
4 changes: 2 additions & 2 deletions src/page-viewer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export function hrefForLocalPage({page}) {
return undefined
}
const pageId = page._id
const uri = `/page-viewer/localpage.html?page=${encodeURIComponent(pageId)}`
const url = `/page-viewer/localpage.html?page=${encodeURIComponent(pageId)}`
const hash = (page.url && page.url.split('#')[1])
const href = (hash !== undefined) ? uri + '#' + hash : uri
const href = (hash !== undefined) ? url + '#' + hash : url
return href
}
4 changes: 2 additions & 2 deletions src/popup/popup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getAttachmentAsDataUri } from 'src/pouchdb'
import { getAttachmentAsDataUrl } from 'src/pouchdb'
import { remoteFunction } from 'src/util/webextensionRPC'
import { hrefForLocalPage } from 'src/page-viewer'

Expand All @@ -22,7 +22,7 @@ async function storeThisPage() {
} finally {
screenshotDimmer.classList.remove('active')
}
const imgData = await getAttachmentAsDataUri({doc: page, attachmentId: 'screenshot'})
const imgData = await getAttachmentAsDataUrl({doc: page, attachmentId: 'screenshot'})
screenshotImg.src = imgData
const href = hrefForLocalPage({page})
if (href) {
Expand Down
Loading

0 comments on commit 95fcbd0

Please sign in to comment.