Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ const QRCode = require('./core/qrcode')
const CanvasRenderer = require('./renderer/canvas')
const SvgRenderer = require('./renderer/svg-tag.js')

function renderFuncHasCallback (renderFunc) {
return renderFunc === CanvasRenderer.renderToBlob || renderFunc === CanvasRenderer.renderToArrayBuffer
}

function renderCanvas (renderFunc, canvas, text, opts, cb) {
const args = [].slice.call(arguments, 1)
const argsNum = args.length
const isLastArgCb = typeof args[argsNum - 1] === 'function'
const renderFnHasCallback = renderFuncHasCallback(renderFunc)

if (!isLastArgCb && !canPromise()) {
throw new Error('Callback required as last argument')
Expand Down Expand Up @@ -51,7 +56,14 @@ function renderCanvas (renderFunc, canvas, text, opts, cb) {
return new Promise(function (resolve, reject) {
try {
const data = QRCode.create(text, opts)
resolve(renderFunc(data, canvas, opts))
if (renderFnHasCallback) {
renderFunc(data, canvas, opts, (err, result) => {
if (err) reject(err)
else resolve(result)
})
} else {
resolve(renderFunc(data, canvas, opts))
}
} catch (e) {
reject(e)
}
Expand All @@ -60,7 +72,11 @@ function renderCanvas (renderFunc, canvas, text, opts, cb) {

try {
const data = QRCode.create(text, opts)
cb(null, renderFunc(data, canvas, opts))
if (renderFnHasCallback) {
renderFunc(data, canvas, opts, cb)
} else {
cb(null, renderFunc(data, canvas, opts))
}
} catch (e) {
cb(e)
}
Expand All @@ -69,6 +85,8 @@ function renderCanvas (renderFunc, canvas, text, opts, cb) {
exports.create = QRCode.create
exports.toCanvas = renderCanvas.bind(null, CanvasRenderer.render)
exports.toDataURL = renderCanvas.bind(null, CanvasRenderer.renderToDataURL)
exports.toBlob = renderCanvas.bind(null, CanvasRenderer.renderToBlob)
exports.toArrayBuffer = renderCanvas.bind(null, CanvasRenderer.renderToArrayBuffer)

// only svg for now.
exports.toString = renderCanvas.bind(null, function (data, _, opts) {
Expand Down
50 changes: 50 additions & 0 deletions lib/renderer/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,53 @@ exports.renderToDataURL = function renderToDataURL (qrData, canvas, options) {

return canvasEl.toDataURL(type, rendererOpts.quality)
}

exports.renderToBlob = function renderToBlob (qrData, canvas, options, callback) {
let opts = options

if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {
opts = canvas
canvas = undefined
}

if (!opts) opts = {}

const canvasEl = exports.render(qrData, canvas, opts)
const type = opts.type || 'image/png'
const rendererOpts = opts.rendererOpts || {}

canvasEl.toBlob((blobOrNull) => {
if (blobOrNull === null) {
callback(new Error('Failed to get canvas as blob'))
} else {
callback(null, blobOrNull)
}
}, type, rendererOpts.quality)
}

exports.renderToArrayBuffer = function renderToArrayBuffer (qrData, canvas, options, callback) {
let opts = options

if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {
opts = canvas
canvas = undefined
}

if (!opts) opts = {}

const canvasEl = exports.render(qrData, canvas, opts)
const type = opts.type || 'image/png'

canvasEl.toBlob(async (blobOrNull) => {
if (blobOrNull === null) {
callback(new Error('Failed to get canvas as blob'))
} else {
try {
const arrayBuffer = await blobOrNull.arrayBuffer()
callback(null, arrayBuffer)
} catch (e) {
callback(e)
}
}
}, type, opts.rendererOpts.quality)
}