mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-17 16:50:22 +00:00
Merge conflict, Editor.js
This commit is contained in:
commit
bb1c615dc4
39 changed files with 402 additions and 454 deletions
|
|
@ -10,7 +10,6 @@ module.exports = class MyCustomProvider extends UIPlugin {
|
|||
this.id = this.opts.id || 'MyCustomProvider'
|
||||
Provider.initPlugin(this, opts)
|
||||
|
||||
this.title = 'MyUnsplash'
|
||||
this.icon = () => (
|
||||
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10 9V0h12v9H10zm12 5h10v18H0V14h10v9h12v-9z" fill="#000000" fillRule="nonzero" />
|
||||
|
|
@ -24,6 +23,14 @@ module.exports = class MyCustomProvider extends UIPlugin {
|
|||
pluginId: this.id,
|
||||
})
|
||||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameMyUnsplash: 'MyUnsplash',
|
||||
},
|
||||
}
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('MyUnsplash')
|
||||
|
||||
this.files = []
|
||||
this.onFirstRender = this.onFirstRender.bind(this)
|
||||
this.render = this.render.bind(this)
|
||||
|
|
|
|||
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -89718,7 +89718,7 @@
|
|||
"@uppy/google-drive": "*",
|
||||
"@uppy/informer": "file:../informer",
|
||||
"@uppy/provider-views": "file:../provider-views",
|
||||
"@uppy/status-bar": "*",
|
||||
"@uppy/status-bar": "file:../status-bar",
|
||||
"@uppy/thumbnail-generator": "file:../thumbnail-generator",
|
||||
"@uppy/utils": "file:../utils",
|
||||
"classnames": "^2.2.6",
|
||||
|
|
|
|||
|
|
@ -90,24 +90,11 @@ module.exports = class AwsS3 extends BasePlugin {
|
|||
|
||||
this.opts = { ...defaultOptions, ...opts }
|
||||
|
||||
this.i18nInit()
|
||||
|
||||
this.client = new RequestClient(uppy, opts)
|
||||
this.handleUpload = this.handleUpload.bind(this)
|
||||
this.requests = new RateLimitedQueue(this.opts.limit)
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
getUploadParameters (file) {
|
||||
if (!this.opts.companionUrl) {
|
||||
throw new Error('Expected a `companionUrl` option containing a Companion address.')
|
||||
|
|
|
|||
|
|
@ -32,6 +32,14 @@ module.exports = class Box extends UIPlugin {
|
|||
pluginId: this.id,
|
||||
})
|
||||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameBox: 'Box',
|
||||
},
|
||||
}
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('pluginNameBox')
|
||||
|
||||
this.onFirstRender = this.onFirstRender.bind(this)
|
||||
this.render = this.render.bind(this)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,33 @@ function stripSlash (url) {
|
|||
return url.replace(/\/$/, '')
|
||||
}
|
||||
|
||||
async function handleJSONResponse (res) {
|
||||
if (res.status === 401) {
|
||||
throw new AuthError()
|
||||
}
|
||||
|
||||
const jsonPromise = res.json()
|
||||
|
||||
if (res.status < 200 || res.status > 300) {
|
||||
let errMsg = `Failed request with status: ${res.status}. ${res.statusText}`
|
||||
try {
|
||||
const errData = await jsonPromise
|
||||
errMsg = errData.message ? `${errMsg} message: ${errData.message}` : errMsg
|
||||
errMsg = errData.requestId ? `${errMsg} request-Id: ${errData.requestId}` : errMsg
|
||||
} finally {
|
||||
// eslint-disable-next-line no-unsafe-finally
|
||||
throw new Error(errMsg)
|
||||
}
|
||||
}
|
||||
return jsonPromise
|
||||
}
|
||||
|
||||
module.exports = class RequestClient {
|
||||
// eslint-disable-next-line global-require
|
||||
static VERSION = require('../package.json').version
|
||||
|
||||
#getPostResponseFunc = skip => response => (skip ? response : this.onReceiveResponse(response))
|
||||
|
||||
constructor (uppy, opts) {
|
||||
this.uppy = uppy
|
||||
this.opts = opts
|
||||
|
|
@ -25,32 +49,20 @@ module.exports = class RequestClient {
|
|||
return stripSlash(companion && companion[host] ? companion[host] : host)
|
||||
}
|
||||
|
||||
get defaultHeaders () {
|
||||
return {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'Uppy-Versions': `@uppy/companion-client=${RequestClient.VERSION}`,
|
||||
}
|
||||
static defaultHeaders ={
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'Uppy-Versions': `@uppy/companion-client=${RequestClient.VERSION}`,
|
||||
}
|
||||
|
||||
headers () {
|
||||
const userHeaders = this.opts.companionHeaders || {}
|
||||
return Promise.resolve({
|
||||
...this.defaultHeaders,
|
||||
...RequestClient.defaultHeaders,
|
||||
...userHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
_getPostResponseFunc (skip) {
|
||||
return (response) => {
|
||||
if (!skip) {
|
||||
return this.onReceiveResponse(response)
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
onReceiveResponse (response) {
|
||||
const state = this.uppy.getState()
|
||||
const companion = state.companion || {}
|
||||
|
|
@ -65,28 +77,22 @@ module.exports = class RequestClient {
|
|||
return response
|
||||
}
|
||||
|
||||
_getUrl (url) {
|
||||
#getUrl (url) {
|
||||
if (/^(https?:|)\/\//.test(url)) {
|
||||
return url
|
||||
}
|
||||
return `${this.hostname}/${url}`
|
||||
}
|
||||
|
||||
_json (res) {
|
||||
if (res.status === 401) {
|
||||
throw new AuthError()
|
||||
#errorHandler (method, path) {
|
||||
return (err) => {
|
||||
if (!err?.isAuthError) {
|
||||
const error = new Error(`Could not ${method} ${this.#getUrl(path)}`)
|
||||
error.cause = err
|
||||
err = error // eslint-disable-line no-param-reassign
|
||||
}
|
||||
return Promise.reject(err)
|
||||
}
|
||||
|
||||
if (res.status < 200 || res.status > 300) {
|
||||
let errMsg = `Failed request with status: ${res.status}. ${res.statusText}`
|
||||
return res.json()
|
||||
.then((errData) => {
|
||||
errMsg = errData.message ? `${errMsg} message: ${errData.message}` : errMsg
|
||||
errMsg = errData.requestId ? `${errMsg} request-Id: ${errData.requestId}` : errMsg
|
||||
throw new Error(errMsg)
|
||||
}).catch(() => { throw new Error(errMsg) })
|
||||
}
|
||||
return res.json()
|
||||
}
|
||||
|
||||
preflight (path) {
|
||||
|
|
@ -94,7 +100,7 @@ module.exports = class RequestClient {
|
|||
return Promise.resolve(this.allowedHeaders.slice())
|
||||
}
|
||||
|
||||
return fetch(this._getUrl(path), {
|
||||
return fetch(this.#getUrl(path), {
|
||||
method: 'OPTIONS',
|
||||
})
|
||||
.then((response) => {
|
||||
|
|
@ -117,9 +123,9 @@ module.exports = class RequestClient {
|
|||
.then(([allowedHeaders, headers]) => {
|
||||
// filter to keep only allowed Headers
|
||||
Object.keys(headers).forEach((header) => {
|
||||
if (allowedHeaders.indexOf(header.toLowerCase()) === -1) {
|
||||
this.uppy.log(`[CompanionClient] excluding unallowed header ${header}`)
|
||||
delete headers[header]
|
||||
if (!allowedHeaders.includes(header.toLowerCase())) {
|
||||
this.uppy.log(`[CompanionClient] excluding disallowed header ${header}`)
|
||||
delete headers[header] // eslint-disable-line no-param-reassign
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -128,55 +134,43 @@ module.exports = class RequestClient {
|
|||
}
|
||||
|
||||
get (path, skipPostResponse) {
|
||||
const method = 'get'
|
||||
return this.preflightAndHeaders(path)
|
||||
.then((headers) => fetchWithNetworkError(this._getUrl(path), {
|
||||
method: 'get',
|
||||
.then((headers) => fetchWithNetworkError(this.#getUrl(path), {
|
||||
method,
|
||||
headers,
|
||||
credentials: this.opts.companionCookiesRule || 'same-origin',
|
||||
}))
|
||||
.then(this._getPostResponseFunc(skipPostResponse))
|
||||
.then((res) => this._json(res))
|
||||
.catch((err) => {
|
||||
if (!err.isAuthError) {
|
||||
err.message = `Could not get ${this._getUrl(path)}. ${err.message}`
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
.then(this.#getPostResponseFunc(skipPostResponse))
|
||||
.then(handleJSONResponse)
|
||||
.catch(this.#errorHandler(method, path))
|
||||
}
|
||||
|
||||
post (path, data, skipPostResponse) {
|
||||
const method = 'post'
|
||||
return this.preflightAndHeaders(path)
|
||||
.then((headers) => fetchWithNetworkError(this._getUrl(path), {
|
||||
method: 'post',
|
||||
.then((headers) => fetchWithNetworkError(this.#getUrl(path), {
|
||||
method,
|
||||
headers,
|
||||
credentials: this.opts.companionCookiesRule || 'same-origin',
|
||||
body: JSON.stringify(data),
|
||||
}))
|
||||
.then(this._getPostResponseFunc(skipPostResponse))
|
||||
.then((res) => this._json(res))
|
||||
.catch((err) => {
|
||||
if (!err.isAuthError) {
|
||||
err.message = `Could not post ${this._getUrl(path)}. ${err.message}`
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
.then(this.#getPostResponseFunc(skipPostResponse))
|
||||
.then(handleJSONResponse)
|
||||
.catch(this.#errorHandler(method, path))
|
||||
}
|
||||
|
||||
delete (path, data, skipPostResponse) {
|
||||
const method = 'delete'
|
||||
return this.preflightAndHeaders(path)
|
||||
.then((headers) => fetchWithNetworkError(`${this.hostname}/${path}`, {
|
||||
method: 'delete',
|
||||
method,
|
||||
headers,
|
||||
credentials: this.opts.companionCookiesRule || 'same-origin',
|
||||
body: data ? JSON.stringify(data) : null,
|
||||
}))
|
||||
.then(this._getPostResponseFunc(skipPostResponse))
|
||||
.then((res) => this._json(res))
|
||||
.catch((err) => {
|
||||
if (!err.isAuthError) {
|
||||
err.message = `Could not delete ${this._getUrl(path)}. ${err.message}`
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
.then(this.#getPostResponseFunc(skipPostResponse))
|
||||
.then(handleJSONResponse)
|
||||
.catch(this.#errorHandler(method, path))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,83 +1,84 @@
|
|||
const ee = require('namespace-emitter')
|
||||
|
||||
module.exports = class UppySocket {
|
||||
#queued = []
|
||||
|
||||
#emitter = ee()
|
||||
|
||||
#isOpen = false
|
||||
|
||||
#socket
|
||||
|
||||
constructor (opts) {
|
||||
this.opts = opts
|
||||
this._queued = []
|
||||
this.isOpen = false
|
||||
this.emitter = ee()
|
||||
|
||||
this._handleMessage = this._handleMessage.bind(this)
|
||||
|
||||
this.close = this.close.bind(this)
|
||||
this.emit = this.emit.bind(this)
|
||||
this.on = this.on.bind(this)
|
||||
this.once = this.once.bind(this)
|
||||
this.send = this.send.bind(this)
|
||||
|
||||
if (!opts || opts.autoOpen !== false) {
|
||||
this.open()
|
||||
}
|
||||
}
|
||||
|
||||
get isOpen () { return this.#isOpen }
|
||||
|
||||
[Symbol.for('uppy test: getSocket')] () { return this.#socket }
|
||||
|
||||
[Symbol.for('uppy test: getQueued')] () { return this.#queued }
|
||||
|
||||
open () {
|
||||
this.socket = new WebSocket(this.opts.target)
|
||||
this.#socket = new WebSocket(this.opts.target)
|
||||
|
||||
this.socket.onopen = (e) => {
|
||||
this.isOpen = true
|
||||
this.#socket.onopen = () => {
|
||||
this.#isOpen = true
|
||||
|
||||
while (this._queued.length > 0 && this.isOpen) {
|
||||
const first = this._queued[0]
|
||||
while (this.#queued.length > 0 && this.#isOpen) {
|
||||
const first = this.#queued.shift()
|
||||
this.send(first.action, first.payload)
|
||||
this._queued = this._queued.slice(1)
|
||||
}
|
||||
}
|
||||
|
||||
this.socket.onclose = (e) => {
|
||||
this.isOpen = false
|
||||
this.#socket.onclose = () => {
|
||||
this.#isOpen = false
|
||||
}
|
||||
|
||||
this.socket.onmessage = this._handleMessage
|
||||
this.#socket.onmessage = this.#handleMessage
|
||||
}
|
||||
|
||||
close () {
|
||||
if (this.socket) {
|
||||
this.socket.close()
|
||||
}
|
||||
this.#socket?.close()
|
||||
}
|
||||
|
||||
send (action, payload) {
|
||||
// attach uuid
|
||||
|
||||
if (!this.isOpen) {
|
||||
this._queued.push({ action, payload })
|
||||
if (!this.#isOpen) {
|
||||
this.#queued.push({ action, payload })
|
||||
return
|
||||
}
|
||||
|
||||
this.socket.send(JSON.stringify({
|
||||
this.#socket.send(JSON.stringify({
|
||||
action,
|
||||
payload,
|
||||
}))
|
||||
}
|
||||
|
||||
on (action, handler) {
|
||||
this.emitter.on(action, handler)
|
||||
this.#emitter.on(action, handler)
|
||||
}
|
||||
|
||||
emit (action, payload) {
|
||||
this.emitter.emit(action, payload)
|
||||
this.#emitter.emit(action, payload)
|
||||
}
|
||||
|
||||
once (action, handler) {
|
||||
this.emitter.once(action, handler)
|
||||
this.#emitter.once(action, handler)
|
||||
}
|
||||
|
||||
_handleMessage (e) {
|
||||
#handleMessage= (e) => {
|
||||
try {
|
||||
const message = JSON.parse(e.data)
|
||||
this.emit(message.action, message.payload)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
// TODO: use a more robust error handler.
|
||||
console.log(err) // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@ describe('Socket', () => {
|
|||
webSocketConstructorSpy(target)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
close (args) {
|
||||
webSocketCloseSpy(args)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
send (json) {
|
||||
webSocketSendSpy(json)
|
||||
}
|
||||
|
|
@ -52,7 +54,7 @@ describe('Socket', () => {
|
|||
|
||||
it('should send a message via the websocket if the connection is open', () => {
|
||||
const uppySocket = new UppySocket({ target: 'foo' })
|
||||
const webSocketInstance = uppySocket.socket
|
||||
const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
||||
webSocketInstance.triggerOpen()
|
||||
|
||||
uppySocket.send('bar', 'boo')
|
||||
|
|
@ -66,17 +68,17 @@ describe('Socket', () => {
|
|||
const uppySocket = new UppySocket({ target: 'foo' })
|
||||
|
||||
uppySocket.send('bar', 'boo')
|
||||
expect(uppySocket._queued).toEqual([{ action: 'bar', payload: 'boo' }])
|
||||
expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([{ action: 'bar', payload: 'boo' }])
|
||||
expect(webSocketSendSpy.mock.calls.length).toEqual(0)
|
||||
})
|
||||
|
||||
it('should queue any messages for the websocket if the connection is not open, then send them when the connection is open', () => {
|
||||
const uppySocket = new UppySocket({ target: 'foo' })
|
||||
const webSocketInstance = uppySocket.socket
|
||||
const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
||||
|
||||
uppySocket.send('bar', 'boo')
|
||||
uppySocket.send('moo', 'baa')
|
||||
expect(uppySocket._queued).toEqual([
|
||||
expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([
|
||||
{ action: 'bar', payload: 'boo' },
|
||||
{ action: 'moo', payload: 'baa' },
|
||||
])
|
||||
|
|
@ -84,7 +86,7 @@ describe('Socket', () => {
|
|||
|
||||
webSocketInstance.triggerOpen()
|
||||
|
||||
expect(uppySocket._queued).toEqual([])
|
||||
expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([])
|
||||
expect(webSocketSendSpy.mock.calls.length).toEqual(2)
|
||||
expect(webSocketSendSpy.mock.calls[0]).toEqual([
|
||||
JSON.stringify({ action: 'bar', payload: 'boo' }),
|
||||
|
|
@ -96,19 +98,19 @@ describe('Socket', () => {
|
|||
|
||||
it('should start queuing any messages when the websocket connection is closed', () => {
|
||||
const uppySocket = new UppySocket({ target: 'foo' })
|
||||
const webSocketInstance = uppySocket.socket
|
||||
const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
||||
webSocketInstance.triggerOpen()
|
||||
uppySocket.send('bar', 'boo')
|
||||
expect(uppySocket._queued).toEqual([])
|
||||
expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([])
|
||||
|
||||
webSocketInstance.triggerClose()
|
||||
uppySocket.send('bar', 'boo')
|
||||
expect(uppySocket._queued).toEqual([{ action: 'bar', payload: 'boo' }])
|
||||
expect(uppySocket[Symbol.for('uppy test: getQueued')]()).toEqual([{ action: 'bar', payload: 'boo' }])
|
||||
})
|
||||
|
||||
it('should close the websocket when it is force closed', () => {
|
||||
const uppySocket = new UppySocket({ target: 'foo' })
|
||||
const webSocketInstance = uppySocket.socket
|
||||
const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
||||
webSocketInstance.triggerOpen()
|
||||
|
||||
uppySocket.close()
|
||||
|
|
@ -117,7 +119,7 @@ describe('Socket', () => {
|
|||
|
||||
it('should be able to subscribe to messages received on the websocket', () => {
|
||||
const uppySocket = new UppySocket({ target: 'foo' })
|
||||
const webSocketInstance = uppySocket.socket
|
||||
const webSocketInstance = uppySocket[Symbol.for('uppy test: getSocket')]()
|
||||
|
||||
const emitterListenerMock = jest.fn()
|
||||
uppySocket.on('hi', emitterListenerMock)
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export interface SocketOptions {
|
|||
}
|
||||
|
||||
export class Socket {
|
||||
isOpen: boolean
|
||||
readonly isOpen: boolean
|
||||
|
||||
constructor (opts: SocketOptions)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
*
|
||||
* See `Plugin` for the extended version with Preact rendering for interfaces.
|
||||
*/
|
||||
|
||||
const Translator = require('@uppy/utils/lib/Translator')
|
||||
|
||||
module.exports = class BasePlugin {
|
||||
constructor (uppy, opts = {}) {
|
||||
this.uppy = uppy
|
||||
|
|
@ -34,6 +37,14 @@ module.exports = class BasePlugin {
|
|||
setOptions (newOpts) {
|
||||
this.opts = { ...this.opts, ...newOpts }
|
||||
this.setPluginState() // so that UI re-renders with new options
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
const translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = translator.translate.bind(translator)
|
||||
this.i18nArray = translator.translateArray.bind(translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -54,6 +54,14 @@ class Uppy {
|
|||
|
||||
#emitter = ee()
|
||||
|
||||
#translator
|
||||
|
||||
#preProcessors = new Set()
|
||||
|
||||
#uploaders = new Set()
|
||||
|
||||
#postProcessors = new Set()
|
||||
|
||||
/**
|
||||
* Instantiate Uppy
|
||||
*
|
||||
|
|
@ -173,10 +181,6 @@ class Uppy {
|
|||
// [Practical Check] Firefox, try to upload a big file for a prolonged period of time. Laptop will start to heat up.
|
||||
this.calculateProgress = throttle(this.calculateProgress.bind(this), 500, { leading: true, trailing: true })
|
||||
|
||||
this.preProcessors = []
|
||||
this.uploaders = []
|
||||
this.postProcessors = []
|
||||
|
||||
this.store = this.opts.store
|
||||
this.setState({
|
||||
plugins: {},
|
||||
|
|
@ -279,10 +283,16 @@ class Uppy {
|
|||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.opts.locale])
|
||||
this.locale = this.translator.locale
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.#translator = new Translator([this.defaultLocale, this.opts.locale])
|
||||
this.locale = this.#translator.locale
|
||||
}
|
||||
|
||||
i18n (...args) {
|
||||
return this.#translator.translate(...args)
|
||||
}
|
||||
|
||||
i18nArray (...args) {
|
||||
return this.#translator.translateArray(...args)
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
|
|
@ -335,36 +345,27 @@ class Uppy {
|
|||
}
|
||||
|
||||
addPreProcessor (fn) {
|
||||
this.preProcessors.push(fn)
|
||||
this.#preProcessors.add(fn)
|
||||
}
|
||||
|
||||
removePreProcessor (fn) {
|
||||
const i = this.preProcessors.indexOf(fn)
|
||||
if (i !== -1) {
|
||||
this.preProcessors.splice(i, 1)
|
||||
}
|
||||
return this.#preProcessors.delete(fn)
|
||||
}
|
||||
|
||||
addPostProcessor (fn) {
|
||||
this.postProcessors.push(fn)
|
||||
this.#postProcessors.add(fn)
|
||||
}
|
||||
|
||||
removePostProcessor (fn) {
|
||||
const i = this.postProcessors.indexOf(fn)
|
||||
if (i !== -1) {
|
||||
this.postProcessors.splice(i, 1)
|
||||
}
|
||||
return this.#postProcessors.delete(fn)
|
||||
}
|
||||
|
||||
addUploader (fn) {
|
||||
this.uploaders.push(fn)
|
||||
this.#uploaders.add(fn)
|
||||
}
|
||||
|
||||
removeUploader (fn) {
|
||||
const i = this.uploaders.indexOf(fn)
|
||||
if (i !== -1) {
|
||||
this.uploaders.splice(i, 1)
|
||||
}
|
||||
return this.#uploaders.delete(fn)
|
||||
}
|
||||
|
||||
setMeta (data) {
|
||||
|
|
@ -1199,7 +1200,7 @@ class Uppy {
|
|||
this.setFileState(file.id, {
|
||||
progress: {
|
||||
...currentProgress,
|
||||
postprocess: this.postProcessors.length > 0 ? {
|
||||
postprocess: this.#postProcessors.size > 0 ? {
|
||||
mode: 'indeterminate',
|
||||
} : null,
|
||||
uploadComplete: true,
|
||||
|
|
@ -1592,9 +1593,9 @@ class Uppy {
|
|||
const restoreStep = uploadData.step
|
||||
|
||||
const steps = [
|
||||
...this.preProcessors,
|
||||
...this.uploaders,
|
||||
...this.postProcessors,
|
||||
...this.#preProcessors,
|
||||
...this.#uploaders,
|
||||
...this.#postProcessors,
|
||||
]
|
||||
let lastStep = Promise.resolve()
|
||||
steps.forEach((fn, step) => {
|
||||
|
|
|
|||
|
|
@ -327,24 +327,13 @@ describe('src/Core', () => {
|
|||
})
|
||||
|
||||
describe('preprocessors', () => {
|
||||
it('should add a preprocessor', () => {
|
||||
it('should add and remove preprocessor', () => {
|
||||
const core = new Core()
|
||||
const preprocessor = () => { }
|
||||
expect(core.removePreProcessor(preprocessor)).toBe(false)
|
||||
core.addPreProcessor(preprocessor)
|
||||
expect(core.preProcessors[0]).toEqual(preprocessor)
|
||||
})
|
||||
|
||||
it('should remove a preprocessor', () => {
|
||||
const core = new Core()
|
||||
const preprocessor1 = () => { }
|
||||
const preprocessor2 = () => { }
|
||||
const preprocessor3 = () => { }
|
||||
core.addPreProcessor(preprocessor1)
|
||||
core.addPreProcessor(preprocessor2)
|
||||
core.addPreProcessor(preprocessor3)
|
||||
expect(core.preProcessors.length).toEqual(3)
|
||||
core.removePreProcessor(preprocessor2)
|
||||
expect(core.preProcessors.length).toEqual(2)
|
||||
expect(core.removePreProcessor(preprocessor)).toBe(true)
|
||||
expect(core.removePreProcessor(preprocessor)).toBe(false)
|
||||
})
|
||||
|
||||
it('should execute all the preprocessors when uploading a file', () => {
|
||||
|
|
@ -456,24 +445,13 @@ describe('src/Core', () => {
|
|||
})
|
||||
|
||||
describe('postprocessors', () => {
|
||||
it('should add a postprocessor', () => {
|
||||
it('should add and remove postprocessor', () => {
|
||||
const core = new Core()
|
||||
const postprocessor = () => { }
|
||||
expect(core.removePostProcessor(postprocessor)).toBe(false)
|
||||
core.addPostProcessor(postprocessor)
|
||||
expect(core.postProcessors[0]).toEqual(postprocessor)
|
||||
})
|
||||
|
||||
it('should remove a postprocessor', () => {
|
||||
const core = new Core()
|
||||
const postprocessor1 = () => { }
|
||||
const postprocessor2 = () => { }
|
||||
const postprocessor3 = () => { }
|
||||
core.addPostProcessor(postprocessor1)
|
||||
core.addPostProcessor(postprocessor2)
|
||||
core.addPostProcessor(postprocessor3)
|
||||
expect(core.postProcessors.length).toEqual(3)
|
||||
core.removePostProcessor(postprocessor2)
|
||||
expect(core.postProcessors.length).toEqual(2)
|
||||
expect(core.removePostProcessor(postprocessor)).toBe(true)
|
||||
expect(core.removePostProcessor(postprocessor)).toBe(false)
|
||||
})
|
||||
|
||||
it('should execute all the postprocessors when uploading a file', () => {
|
||||
|
|
@ -586,24 +564,13 @@ describe('src/Core', () => {
|
|||
})
|
||||
|
||||
describe('uploaders', () => {
|
||||
it('should add an uploader', () => {
|
||||
it('should add and remove uploader', () => {
|
||||
const core = new Core()
|
||||
const uploader = () => { }
|
||||
expect(core.removeUploader(uploader)).toBe(false)
|
||||
core.addUploader(uploader)
|
||||
expect(core.uploaders[0]).toEqual(uploader)
|
||||
})
|
||||
|
||||
it('should remove an uploader', () => {
|
||||
const core = new Core()
|
||||
const uploader1 = () => { }
|
||||
const uploader2 = () => { }
|
||||
const uploader3 = () => { }
|
||||
core.addUploader(uploader1)
|
||||
core.addUploader(uploader2)
|
||||
core.addUploader(uploader3)
|
||||
expect(core.uploaders.length).toEqual(3)
|
||||
core.removeUploader(uploader2)
|
||||
expect(core.uploaders.length).toEqual(2)
|
||||
expect(core.removeUploader(uploader)).toBe(true)
|
||||
expect(core.removeUploader(uploader)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -165,18 +165,6 @@ module.exports = class Dashboard extends UIPlugin {
|
|||
this.removeDragOverClassTimeout = null
|
||||
}
|
||||
|
||||
setOptions = (newOpts) => {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit = () => {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
removeTarget = (plugin) => {
|
||||
const pluginState = this.getPluginState()
|
||||
// filter out the one we want to remove
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@ module.exports = class DragDrop extends UIPlugin {
|
|||
// Merge default options with the ones set by user
|
||||
this.opts = { ...defaultOpts, ...opts }
|
||||
|
||||
this.i18nInit()
|
||||
|
||||
// Check for browser dragDrop support
|
||||
this.isDragDropSupported = isDragDropSupported()
|
||||
this.removeDragOverClassTimeout = null
|
||||
|
||||
this.i18nInit()
|
||||
|
||||
// Bind `this` to class methods
|
||||
this.onInputChange = this.onInputChange.bind(this)
|
||||
this.handleDragOver = this.handleDragOver.bind(this)
|
||||
|
|
@ -53,18 +53,6 @@ module.exports = class DragDrop extends UIPlugin {
|
|||
this.render = this.render.bind(this)
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
addFiles (files) {
|
||||
const descriptors = files.map((file) => ({
|
||||
source: this.id,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,14 @@ module.exports = class Dropbox extends UIPlugin {
|
|||
pluginId: this.id,
|
||||
})
|
||||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameDropbox: 'Dropbox',
|
||||
},
|
||||
}
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('pluginNameDropbox')
|
||||
|
||||
this.onFirstRender = this.onFirstRender.bind(this)
|
||||
this.render = this.render.bind(this)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,14 @@ module.exports = class Facebook extends UIPlugin {
|
|||
pluginId: this.id,
|
||||
})
|
||||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameFacebook: 'Facebook',
|
||||
},
|
||||
}
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('pluginNameFacebook')
|
||||
|
||||
this.onFirstRender = this.onFirstRender.bind(this)
|
||||
this.render = this.render.bind(this)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,18 +38,6 @@ module.exports = class FileInput extends UIPlugin {
|
|||
this.handleClick = this.handleClick.bind(this)
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
addFiles (files) {
|
||||
const descriptors = files.map((file) => ({
|
||||
source: this.id,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,14 @@ module.exports = class GoogleDrive extends UIPlugin {
|
|||
pluginId: this.id,
|
||||
})
|
||||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameGoogleDrive: 'Google Drive',
|
||||
},
|
||||
}
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('pluginNameGoogleDrive')
|
||||
|
||||
this.onFirstRender = this.onFirstRender.bind(this)
|
||||
this.render = this.render.bind(this)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,43 +31,15 @@ module.exports = class Editor extends Component {
|
|||
this.cropper.destroy()
|
||||
}
|
||||
|
||||
renderRevert () {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
aria-label={this.props.i18n('revert')}
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
onClick={() => {
|
||||
this.cropper.reset()
|
||||
this.cropper.setAspectRatio(0)
|
||||
}}
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z" />
|
||||
</svg>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
save = () => {
|
||||
const { opts, save, currentImage } = this.props
|
||||
|
||||
renderRotate () {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
onClick={() => this.cropper.rotate(-90)}
|
||||
aria-label={this.props.i18n('rotate')}
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none" />
|
||||
<path d="M14 10a2 2 0 012 2v7a2 2 0 01-2 2H6a2 2 0 01-2-2v-7a2 2 0 012-2h8zm0 1.75H6a.25.25 0 00-.243.193L5.75 12v7a.25.25 0 00.193.243L6 19.25h8a.25.25 0 00.243-.193L14.25 19v-7a.25.25 0 00-.193-.243L14 11.75zM12 .76V4c2.3 0 4.61.88 6.36 2.64a8.95 8.95 0 012.634 6.025L21 13a1 1 0 01-1.993.117L19 13h-.003a6.979 6.979 0 00-2.047-4.95 6.97 6.97 0 00-4.652-2.044L12 6v3.24L7.76 5 12 .76z" />
|
||||
</svg>
|
||||
</button>
|
||||
)
|
||||
this.cropper.getCroppedCanvas(opts.cropperOptions.croppedCanvasOptions)
|
||||
.toBlob(
|
||||
(blob) => save(blob),
|
||||
currentImage.type,
|
||||
opts.quality
|
||||
)
|
||||
}
|
||||
|
||||
granularRotateOnChange = (ev) => {
|
||||
|
|
@ -83,11 +55,15 @@ module.exports = class Editor extends Component {
|
|||
}
|
||||
|
||||
renderGranularRotate () {
|
||||
const { i18n } = this.props
|
||||
const { rotationDelta, rotationAngle } = this.state
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line jsx-a11y/label-has-associated-control
|
||||
<label
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
aria-label={`${this.state.rotationAngle}º`}
|
||||
aria-label={`${rotationAngle}º`}
|
||||
className="uppy-ImageCropper-rangeWrapper uppy-u-reset"
|
||||
>
|
||||
<input
|
||||
|
|
@ -95,23 +71,65 @@ module.exports = class Editor extends Component {
|
|||
type="range"
|
||||
onInput={this.granularRotateOnChange}
|
||||
onChange={this.granularRotateOnChange}
|
||||
value={this.state.rotationDelta}
|
||||
value={rotationDelta}
|
||||
min="-45"
|
||||
max="44"
|
||||
aria-label={this.props.i18n('rotate')}
|
||||
aria-label={i18n('rotate')}
|
||||
/>
|
||||
</label>
|
||||
)
|
||||
}
|
||||
|
||||
renderFlip () {
|
||||
renderRevert () {
|
||||
const { i18n } = this.props
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
aria-label={this.props.i18n('flipHorizontal')}
|
||||
aria-label={i18n('revert')}
|
||||
data-microtip-position="top"
|
||||
onClick={() => {
|
||||
this.cropper.reset()
|
||||
this.cropper.setAspectRatio(0)
|
||||
}}
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z" />
|
||||
</svg>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
renderRotate () {
|
||||
const { i18n } = this.props
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
onClick={() => this.cropper.rotate(-90)}
|
||||
aria-label={i18n('rotate')}
|
||||
data-microtip-position="top"
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none" />
|
||||
<path d="M14 10a2 2 0 012 2v7a2 2 0 01-2 2H6a2 2 0 01-2-2v-7a2 2 0 012-2h8zm0 1.75H6a.25.25 0 00-.243.193L5.75 12v7a.25.25 0 00.193.243L6 19.25h8a.25.25 0 00.243-.193L14.25 19v-7a.25.25 0 00-.193-.243L14 11.75zM12 .76V4c2.3 0 4.61.88 6.36 2.64a8.95 8.95 0 012.634 6.025L21 13a1 1 0 01-1.993.117L19 13h-.003a6.979 6.979 0 00-2.047-4.95 6.97 6.97 0 00-4.652-2.044L12 6v3.24L7.76 5 12 .76z" />
|
||||
</svg>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
renderFlip () {
|
||||
const { i18n } = this.props
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
aria-label={i18n('flipHorizontal')}
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
onClick={() => this.cropper.scaleX(-this.cropper.getData().scaleX || -1)}
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
|
|
@ -123,13 +141,14 @@ module.exports = class Editor extends Component {
|
|||
}
|
||||
|
||||
renderZoomIn () {
|
||||
const { i18n } = this.props
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
aria-label={this.props.i18n('zoomIn')}
|
||||
aria-label={i18n('zoomIn')}
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
onClick={() => this.cropper.zoom(0.1)}
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" height="24" viewBox="0 0 24 24" width="24">
|
||||
|
|
@ -142,13 +161,14 @@ module.exports = class Editor extends Component {
|
|||
}
|
||||
|
||||
renderZoomOut () {
|
||||
const { i18n } = this.props
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
aria-label={this.props.i18n('zoomOut')}
|
||||
aria-label={i18n('zoomOut')}
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
onClick={() => this.cropper.zoom(-0.1)}
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
|
|
@ -160,13 +180,14 @@ module.exports = class Editor extends Component {
|
|||
}
|
||||
|
||||
renderCropSquare () {
|
||||
const { i18n } = this.props
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
aria-label={this.props.i18n('aspectRatioSquare')}
|
||||
aria-label={i18n('aspectRatioSquare')}
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
onClick={() => this.cropper.setAspectRatio(1)}
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
|
|
@ -178,13 +199,14 @@ module.exports = class Editor extends Component {
|
|||
}
|
||||
|
||||
renderCropWidescreen () {
|
||||
const { i18n } = this.props
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
aria-label={this.props.i18n('aspectRatioLandscape')}
|
||||
aria-label={i18n('aspectRatioLandscape')}
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
onClick={() => this.cropper.setAspectRatio(16 / 9)}
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
|
|
@ -196,13 +218,14 @@ module.exports = class Editor extends Component {
|
|||
}
|
||||
|
||||
renderCropWidescreenVertical () {
|
||||
const { i18n } = this.props
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="uppy-u-reset uppy-c-btn"
|
||||
aria-label={this.props.i18n('aspectRatioPortrait')}
|
||||
aria-label={i18n('aspectRatioPortrait')}
|
||||
data-microtip-position="top"
|
||||
role="tooltip"
|
||||
onClick={() => this.cropper.setAspectRatio(9 / 16)}
|
||||
>
|
||||
<svg aria-hidden="true" className="uppy-c-icon" width="24" height="24" viewBox="0 0 24 24">
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ const { h } = require('preact')
|
|||
const Editor = require('./Editor')
|
||||
|
||||
module.exports = class ImageEditor extends UIPlugin {
|
||||
// eslint-disable-next-line global-require
|
||||
static VERSION = require('../package.json').version
|
||||
|
||||
constructor (uppy, opts) {
|
||||
|
|
@ -30,6 +31,7 @@ module.exports = class ImageEditor extends UIPlugin {
|
|||
background: false,
|
||||
autoCropArea: 1,
|
||||
responsive: true,
|
||||
croppedCanvasOptions: {},
|
||||
}
|
||||
|
||||
const defaultActions = {
|
||||
|
|
@ -64,18 +66,7 @@ module.exports = class ImageEditor extends UIPlugin {
|
|||
this.i18nInit()
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
// this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
canEditFile (file) {
|
||||
if (!file.type || file.isRemote) {
|
||||
return false
|
||||
|
|
@ -145,8 +136,9 @@ module.exports = class ImageEditor extends UIPlugin {
|
|||
|
||||
render () {
|
||||
const { currentImage } = this.getPluginState()
|
||||
|
||||
if (currentImage === null || currentImage.isRemote) {
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
7
packages/@uppy/image-editor/types/index.d.ts
vendored
7
packages/@uppy/image-editor/types/index.d.ts
vendored
|
|
@ -1,4 +1,5 @@
|
|||
import type { PluginOptions, UIPlugin, PluginTarget } from '@uppy/core'
|
||||
import type Cropper from 'cropperjs'
|
||||
import ImageEditorLocale from './generatedLocale'
|
||||
|
||||
type Actions = {
|
||||
|
|
@ -13,8 +14,12 @@ type Actions = {
|
|||
cropWidescreenVertical: boolean
|
||||
}
|
||||
|
||||
interface UppyCropperOptions extends Cropper.Options {
|
||||
croppedCanvasOptions: Cropper.GetCroppedCanvasOptions
|
||||
}
|
||||
|
||||
export interface ImageEditorOptions extends PluginOptions {
|
||||
cropperOptions?: Record<string, unknown>
|
||||
cropperOptions?: UppyCropperOptions
|
||||
actions?: Actions
|
||||
quality?: number
|
||||
target?: PluginTarget
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ module.exports = class Instagram extends UIPlugin {
|
|||
super(uppy, opts)
|
||||
this.id = this.opts.id || 'Instagram'
|
||||
Provider.initPlugin(this, opts)
|
||||
this.title = this.opts.title || 'Instagram'
|
||||
this.icon = () => (
|
||||
<svg aria-hidden="true" focusable="false" width="32" height="32" viewBox="0 0 32 32">
|
||||
<g fill="none" fillRule="evenodd">
|
||||
|
|
@ -20,6 +19,14 @@ module.exports = class Instagram extends UIPlugin {
|
|||
</svg>
|
||||
)
|
||||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameInstagram: 'Instagram',
|
||||
},
|
||||
}
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('pluginNameInstagram')
|
||||
|
||||
this.provider = new Provider(uppy, {
|
||||
companionUrl: this.opts.companionUrl,
|
||||
companionHeaders: this.opts.companionHeaders,
|
||||
|
|
|
|||
|
|
@ -91,6 +91,14 @@ en_US.strings = {
|
|||
pause: 'Pause',
|
||||
paused: 'Paused',
|
||||
pauseUpload: 'Pause upload',
|
||||
pluginNameBox: 'Box',
|
||||
pluginNameCamera: 'Camera',
|
||||
pluginNameDropbox: 'Dropbox',
|
||||
pluginNameFacebook: 'Facebook',
|
||||
pluginNameGoogleDrive: 'Google Drive',
|
||||
pluginNameInstagram: 'Instagram',
|
||||
pluginNameOneDrive: 'OneDrive',
|
||||
pluginNameZoom: 'Zoom',
|
||||
poweredBy: 'Powered by %{uppy}',
|
||||
processingXFiles: {
|
||||
'0': 'Processing %{smart_count} file',
|
||||
|
|
|
|||
|
|
@ -31,6 +31,14 @@ module.exports = class OneDrive extends UIPlugin {
|
|||
pluginId: this.id,
|
||||
})
|
||||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameOneDrive: 'OneDrive',
|
||||
},
|
||||
}
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('pluginNameOneDrive')
|
||||
|
||||
this.onFirstRender = this.onFirstRender.bind(this)
|
||||
this.render = this.render.bind(this)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,9 +65,7 @@ module.exports = class ScreenCapture extends UIPlugin {
|
|||
this.opts = { ...defaultOptions, ...opts }
|
||||
|
||||
// i18n
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.i18nInit()
|
||||
|
||||
// uppy plugin class related
|
||||
this.install = this.install.bind(this)
|
||||
|
|
|
|||
|
|
@ -73,17 +73,6 @@ module.exports = class StatusBar extends UIPlugin {
|
|||
this.install = this.install.bind(this)
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
getTotalSpeed (files) {
|
||||
let totalSpeed = 0
|
||||
files.forEach((file) => {
|
||||
|
|
|
|||
|
|
@ -40,19 +40,6 @@ module.exports = class ThumbnailGenerator extends UIPlugin {
|
|||
if (this.opts.lazy && this.opts.waitForThumbnailsBeforeUpload) {
|
||||
throw new Error('ThumbnailGenerator: The `lazy` and `waitForThumbnailsBeforeUpload` options are mutually exclusive. Please ensure at most one of them is set to `true`.')
|
||||
}
|
||||
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -82,18 +82,6 @@ module.exports = class Transloadit extends BasePlugin {
|
|||
this.completedFiles = Object.create(null)
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
#getClientVersion () {
|
||||
const list = [
|
||||
`uppy-core:${this.uppy.constructor.VERSION}`,
|
||||
|
|
|
|||
|
|
@ -65,18 +65,6 @@ module.exports = class Url extends UIPlugin {
|
|||
})
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
getFileNameFromUrl (url) {
|
||||
return url.substring(url.lastIndexOf('/') + 1)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ module.exports = class Webcam extends UIPlugin {
|
|||
// eslint-disable-next-line no-restricted-globals
|
||||
this.protocol = location.protocol.match(/https/i) ? 'https' : 'http'
|
||||
this.id = this.opts.id || 'Webcam'
|
||||
this.title = this.opts.title || 'Camera'
|
||||
this.type = 'acquirer'
|
||||
this.capturedMediaFile = null
|
||||
this.icon = () => (
|
||||
|
|
@ -75,6 +74,7 @@ module.exports = class Webcam extends UIPlugin {
|
|||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameCamera: 'Camera',
|
||||
smile: 'Smile!',
|
||||
takePicture: 'Take a picture',
|
||||
startRecording: 'Begin video recording',
|
||||
|
|
@ -109,12 +109,11 @@ module.exports = class Webcam extends UIPlugin {
|
|||
}
|
||||
|
||||
this.opts = { ...defaultOptions, ...opts }
|
||||
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('pluginNameCamera')
|
||||
|
||||
this.install = this.install.bind(this)
|
||||
this.setPluginState = this.setPluginState.bind(this)
|
||||
|
||||
this.render = this.render.bind(this)
|
||||
|
||||
// Camera controls
|
||||
|
|
@ -154,15 +153,6 @@ module.exports = class Webcam extends UIPlugin {
|
|||
...newOpts?.videoConstraints,
|
||||
},
|
||||
})
|
||||
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.i18nArray = this.translator.translateArray.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
hasCameraCheck () {
|
||||
|
|
|
|||
|
|
@ -119,8 +119,6 @@ module.exports = class XHRUpload extends BasePlugin {
|
|||
|
||||
this.opts = { ...defaultOptions, ...opts }
|
||||
|
||||
this.i18nInit()
|
||||
|
||||
this.handleUpload = this.handleUpload.bind(this)
|
||||
|
||||
// Simultaneous upload limiting is shared across all uploads with this plugin.
|
||||
|
|
@ -137,17 +135,6 @@ module.exports = class XHRUpload extends BasePlugin {
|
|||
this.uploaderEvents = Object.create(null)
|
||||
}
|
||||
|
||||
setOptions (newOpts) {
|
||||
super.setOptions(newOpts)
|
||||
this.i18nInit()
|
||||
}
|
||||
|
||||
i18nInit () {
|
||||
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
this.setPluginState() // so that UI re-renders and we see the updated locale
|
||||
}
|
||||
|
||||
getOptions (file) {
|
||||
const overrides = this.uppy.getState().xhrUpload
|
||||
const { headers } = this.opts
|
||||
|
|
|
|||
|
|
@ -30,6 +30,14 @@ module.exports = class Zoom extends UIPlugin {
|
|||
pluginId: this.id,
|
||||
})
|
||||
|
||||
this.defaultLocale = {
|
||||
strings: {
|
||||
pluginNameZoom: 'Zoom',
|
||||
},
|
||||
}
|
||||
this.i18nInit()
|
||||
this.title = this.i18n('pluginNameZoom')
|
||||
|
||||
this.onFirstRender = this.onFirstRender.bind(this)
|
||||
this.render = this.render.bind(this)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ describe('Chaos monkey', function () {
|
|||
return browser.execute(() => {
|
||||
window.addLogMessage('Cancelling a file')
|
||||
// prefer deleting a file that is uploading right now
|
||||
var selector = Math.random() <= 0.7
|
||||
const selector = Math.random() <= 0.7
|
||||
? '.is-inprogress .uppy-Dashboard-Item-action--remove'
|
||||
: '.uppy-Dashboard-Item-action--remove'
|
||||
var buttons = document.querySelectorAll(selector)
|
||||
var del = buttons[Math.floor(Math.random() * buttons.length)]
|
||||
const buttons = document.querySelectorAll(selector)
|
||||
const del = buttons[Math.floor(Math.random() * buttons.length)]
|
||||
if (del) del.click()
|
||||
})
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ describe('Chaos monkey', function () {
|
|||
function startUploadIfAnyWaitingFiles () {
|
||||
return browser.execute(() => {
|
||||
window.addLogMessage('Starting upload')
|
||||
var start = document.querySelector('.uppy-StatusBar-actionBtn--upload')
|
||||
const start = document.querySelector('.uppy-StatusBar-actionBtn--upload')
|
||||
if (start) start.click()
|
||||
})
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ describe('Chaos monkey', function () {
|
|||
function cancelAll () {
|
||||
return browser.execute(() => {
|
||||
window.addLogMessage('Cancelling everything')
|
||||
var button = document.querySelector('.uppy-DashboardContent-back')
|
||||
const button = document.querySelector('.uppy-DashboardContent-back')
|
||||
if (button) button.click()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ const Dashboard = require('@uppy/dashboard')
|
|||
const Transloadit = require('@uppy/transloadit')
|
||||
|
||||
function initUppyTransloadit (transloaditKey) {
|
||||
var uppyTransloadit = new Uppy({
|
||||
const uppyTransloadit = new Uppy({
|
||||
id: 'uppyTransloadit',
|
||||
debug: true,
|
||||
autoProceed: true,
|
||||
|
|
@ -36,9 +36,9 @@ function initUppyTransloadit (transloaditKey) {
|
|||
console.log('Result here ====>', stepName, result)
|
||||
console.log('Cropped image url is here ====>', result.url)
|
||||
|
||||
var img = new Image()
|
||||
const img = new Image()
|
||||
img.onload = function () {
|
||||
var result = document.createElement('div')
|
||||
const result = document.createElement('div')
|
||||
result.setAttribute('id', 'uppy-result')
|
||||
result.textContent = 'ok'
|
||||
document.body.appendChild(result)
|
||||
|
|
|
|||
|
|
@ -13,18 +13,18 @@ function selectFakeFile (uppyID, name, type, b64) {
|
|||
// https://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
|
||||
function base64toBlob (base64Data, contentType) {
|
||||
contentType = contentType || ''
|
||||
var sliceSize = 1024
|
||||
var byteCharacters = atob(base64Data)
|
||||
var bytesLength = byteCharacters.length
|
||||
var slicesCount = Math.ceil(bytesLength / sliceSize)
|
||||
var byteArrays = new Array(slicesCount)
|
||||
const sliceSize = 1024
|
||||
const byteCharacters = atob(base64Data)
|
||||
const bytesLength = byteCharacters.length
|
||||
const slicesCount = Math.ceil(bytesLength / sliceSize)
|
||||
const byteArrays = new Array(slicesCount)
|
||||
|
||||
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
|
||||
var begin = sliceIndex * sliceSize
|
||||
var end = Math.min(begin + sliceSize, bytesLength)
|
||||
for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
|
||||
const begin = sliceIndex * sliceSize
|
||||
const end = Math.min(begin + sliceSize, bytesLength)
|
||||
|
||||
var bytes = new Array(end - begin)
|
||||
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
|
||||
const bytes = new Array(end - begin)
|
||||
for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
|
||||
bytes[i] = byteCharacters[offset].charCodeAt(0)
|
||||
}
|
||||
byteArrays[sliceIndex] = new Uint8Array(bytes)
|
||||
|
|
@ -32,7 +32,7 @@ function selectFakeFile (uppyID, name, type, b64) {
|
|||
return new Blob(byteArrays, { type: contentType })
|
||||
}
|
||||
|
||||
var blob = base64toBlob(b64, type)
|
||||
const blob = base64toBlob(b64, type)
|
||||
|
||||
window[uppyID].addFile({
|
||||
source: 'test',
|
||||
|
|
@ -43,7 +43,7 @@ function selectFakeFile (uppyID, name, type, b64) {
|
|||
}
|
||||
|
||||
function ensureInputVisible (selector) {
|
||||
var input = document.querySelector(selector)
|
||||
const input = document.querySelector(selector)
|
||||
input.style = 'width: auto; height: auto; opacity: 1; z-index: 199'
|
||||
input.removeAttribute('hidden')
|
||||
input.removeAttribute('aria-hidden')
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ exports.config = {
|
|||
* @param {Array<string>} specs List of spec file paths that are to be run
|
||||
*/
|
||||
before (capabilities, specs) {
|
||||
var chai = require('chai')
|
||||
const chai = require('chai')
|
||||
global.expect = chai.expect
|
||||
global.capabilities = capabilities
|
||||
chai.Should()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
var deepFreeze = require('deep-freeze')
|
||||
const deepFreeze = require('deep-freeze')
|
||||
|
||||
/**
|
||||
* Default store + deepFreeze on setState to make sure nothing is mutated accidentally
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
// We fire our own build-examples.js and tell it which example to build -
|
||||
// that script then writes temporary js files
|
||||
// which we return via the callback.
|
||||
var exec = require('child_process').exec
|
||||
var path = require('path')
|
||||
var fs = require('fs')
|
||||
var uuid = require('uuid')
|
||||
const { exec } = require('child_process')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const uuid = require('uuid')
|
||||
|
||||
var webRoot = path.dirname(path.dirname(__dirname))
|
||||
var browserifyScript = `${webRoot}/build-examples.js`
|
||||
const webRoot = path.dirname(path.dirname(__dirname))
|
||||
const browserifyScript = `${webRoot}/build-examples.js`
|
||||
|
||||
function parseExamplesBrowserify (data, options, callback) {
|
||||
if (!data || !data.path) {
|
||||
|
|
@ -20,9 +20,9 @@ function parseExamplesBrowserify (data, options, callback) {
|
|||
}
|
||||
|
||||
// var slug = data.path.replace(/[^a-zA-Z0-9\_\.]/g, '-')
|
||||
var slug = uuid.v4()
|
||||
var tmpFile = `/tmp/${slug}.js`
|
||||
var cmd = `node ${browserifyScript} ${data.path} ${tmpFile} --colors`
|
||||
const slug = uuid.v4()
|
||||
const tmpFile = `/tmp/${slug}.js`
|
||||
const cmd = `node ${browserifyScript} ${data.path} ${tmpFile} --colors`
|
||||
// hexo.log.i('hexo-renderer-uppyexamples: change detected in examples. running: ' + cmd);
|
||||
exec(cmd, (err, stdout, stderr) => {
|
||||
if (err) {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ uppy.use(ImageEditor, {
|
|||
background: false,
|
||||
autoCropArea: 1,
|
||||
responsive: true,
|
||||
croppedCanvasOptions: {},
|
||||
},
|
||||
actions: {
|
||||
revert: true,
|
||||
|
|
@ -89,7 +90,10 @@ Quality of the resulting blob that will be saved in Uppy after editing/cropping.
|
|||
|
||||
### `cropperOptions`
|
||||
|
||||
Image Editor is using the excellent [Cropper.js](https://fengyuanchen.github.io/cropperjs/), and if you’d like to fine tune the Cropper.js instance, you can pass options to it.
|
||||
Image Editor is using the excellent [Cropper.js](https://fengyuanchen.github.io/cropperjs/).
|
||||
`cropperOptions` will be directly passed to `Cropper` and therefor can expect the same values as documented
|
||||
in their [README](https://github.com/fengyuanchen/cropperjs/blob/HEAD/README.md#options),
|
||||
with the addition of `croppedCanvasOptions`, which will be passed to [`getCroppedCanvas`](https://github.com/fengyuanchen/cropperjs/blob/HEAD/README.md#getcroppedcanvasoptions).
|
||||
|
||||
### `actions`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
(function () {
|
||||
var each = [].forEach
|
||||
var doc = document.documentElement
|
||||
var body = document.body
|
||||
let each = [].forEach
|
||||
let doc = document.documentElement
|
||||
let { body } = document
|
||||
|
||||
var isIndex = body.classList.contains('page-index')
|
||||
let isIndex = body.classList.contains('page-index')
|
||||
|
||||
// On index page
|
||||
if (isIndex) {
|
||||
|
|
@ -15,29 +15,29 @@
|
|||
|
||||
function InnerPage () {
|
||||
// var main = document.querySelector('.js-MainContent')
|
||||
var menuButton = document.querySelector('.js-MenuBtn')
|
||||
var header = document.querySelector('.js-MainHeader')
|
||||
var menu = document.querySelector('.js-Sidebar')
|
||||
var content = document.querySelector('.js-Content')
|
||||
var transloaditBar = document.querySelector('.js-TransloaditBar')
|
||||
let menuButton = document.querySelector('.js-MenuBtn')
|
||||
let header = document.querySelector('.js-MainHeader')
|
||||
let menu = document.querySelector('.js-Sidebar')
|
||||
let content = document.querySelector('.js-Content')
|
||||
let transloaditBar = document.querySelector('.js-TransloaditBar')
|
||||
|
||||
var animating = false
|
||||
var allLinks = []
|
||||
let animating = false
|
||||
let allLinks = []
|
||||
|
||||
// // listen for scroll event to do positioning & highlights
|
||||
// window.addEventListener('scroll', updateSidebar)
|
||||
// window.addEventListener('resize', updateSidebar)
|
||||
|
||||
function makeSidebarTop () {
|
||||
var headerHeight = header.offsetHeight
|
||||
var transloaditBarHeight = 0
|
||||
let headerHeight = header.offsetHeight
|
||||
let transloaditBarHeight = 0
|
||||
|
||||
if (transloaditBar) {
|
||||
transloaditBarHeight = transloaditBar.offsetHeight
|
||||
}
|
||||
|
||||
if (window.matchMedia('(min-width: 1024px)').matches) {
|
||||
var headerTopOffset = header.getBoundingClientRect().top
|
||||
let headerTopOffset = header.getBoundingClientRect().top
|
||||
menu.style.top = `${headerHeight + headerTopOffset}px`
|
||||
} else {
|
||||
menu.style.paddingTop = `${headerHeight + transloaditBarHeight + 20}px`
|
||||
|
|
@ -50,8 +50,8 @@
|
|||
window.addEventListener('resize', makeSidebarTop)
|
||||
|
||||
function updateSidebar () {
|
||||
var top = (doc && doc.scrollTop) || body.scrollTop
|
||||
var headerHeight = header.offsetHeight
|
||||
let top = (doc && doc.scrollTop) || body.scrollTop
|
||||
let headerHeight = header.offsetHeight
|
||||
if (top > (headerHeight - 25)) {
|
||||
// main.classList.add('fix-sidebar')
|
||||
header.classList.add('fix-header')
|
||||
|
|
@ -60,9 +60,9 @@
|
|||
header.classList.remove('fix-header')
|
||||
}
|
||||
if (animating || !allLinks) return
|
||||
var last
|
||||
for (var i = 0; i < allLinks.length; i++) {
|
||||
var link = allLinks[i]
|
||||
let last
|
||||
for (let i = 0; i < allLinks.length; i++) {
|
||||
let link = allLinks[i]
|
||||
if (link.offsetTop > top) {
|
||||
if (!last) last = link
|
||||
break
|
||||
|
|
@ -76,8 +76,8 @@
|
|||
}
|
||||
|
||||
function makeLink (h) {
|
||||
var link = document.createElement('li')
|
||||
var text = h.textContent.replace(/\(.*\)$/, '')
|
||||
let link = document.createElement('li')
|
||||
let text = h.textContent.replace(/\(.*\)$/, '')
|
||||
// make sure the ids are link-able...
|
||||
h.id = h.id
|
||||
.replace(/\(.*\)$/, '')
|
||||
|
|
@ -90,8 +90,8 @@
|
|||
}
|
||||
|
||||
function collectH3s (h) {
|
||||
var h3s = []
|
||||
var next = h.nextSibling
|
||||
let h3s = []
|
||||
let next = h.nextSibling
|
||||
while (next && next.tagName !== 'H2') {
|
||||
if (next.tagName === 'H3') {
|
||||
h3s.push(next)
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
}
|
||||
|
||||
function makeSubLinks (h3s, small) {
|
||||
var container = document.createElement('ul')
|
||||
let container = document.createElement('ul')
|
||||
if (small) {
|
||||
container.className = 'menu-sub'
|
||||
}
|
||||
|
|
@ -113,8 +113,8 @@
|
|||
}
|
||||
|
||||
function setActive (id) {
|
||||
var previousActive = menu.querySelector('.section-link.active')
|
||||
var currentActive = typeof id === 'string'
|
||||
let previousActive = menu.querySelector('.section-link.active')
|
||||
let currentActive = typeof id === 'string'
|
||||
? menu.querySelector(`.section-link[href="#${id}"]`)
|
||||
: id
|
||||
if (currentActive !== previousActive) {
|
||||
|
|
@ -127,7 +127,7 @@
|
|||
if (link.getAttribute('data-scroll') === 'no') {
|
||||
return
|
||||
}
|
||||
var wrapper = document.createElement('a')
|
||||
let wrapper = document.createElement('a')
|
||||
wrapper.href = `#${link.id}`
|
||||
wrapper.setAttribute('data-scroll', '')
|
||||
link.parentNode.insertBefore(wrapper, link)
|
||||
|
|
@ -146,13 +146,13 @@
|
|||
|
||||
function initSubHeaders () {
|
||||
// build sidebar
|
||||
var currentPageAnchor = menu.querySelector('.sidebar-link.current')
|
||||
var isDocs = content.classList.contains('docs')
|
||||
let currentPageAnchor = menu.querySelector('.sidebar-link.current')
|
||||
let isDocs = content.classList.contains('docs')
|
||||
|
||||
if (!isDocs) return
|
||||
|
||||
if (currentPageAnchor) {
|
||||
var sectionContainer
|
||||
let sectionContainer
|
||||
|
||||
// if (false && isAPI) {
|
||||
// sectionContainer = document.querySelector('.menu-root')
|
||||
|
|
@ -166,12 +166,12 @@
|
|||
sectionContainer.className = 'menu-sub'
|
||||
currentPageAnchor.parentNode.appendChild(sectionContainer)
|
||||
|
||||
var h2s = content.querySelectorAll('h2')
|
||||
let h2s = content.querySelectorAll('h2')
|
||||
|
||||
if (h2s.length) {
|
||||
each.call(h2s, (h) => {
|
||||
sectionContainer.appendChild(makeLink(h))
|
||||
var h3s = collectH3s(h)
|
||||
let h3s = collectH3s(h)
|
||||
allLinks.push(h)
|
||||
allLinks.push.apply(allLinks, h3s)
|
||||
if (h3s.length) {
|
||||
|
|
@ -179,7 +179,7 @@
|
|||
}
|
||||
})
|
||||
} else {
|
||||
var h3s = content.querySelectorAll('h3')
|
||||
let h3s = content.querySelectorAll('h3')
|
||||
each.call(h3s, (h) => {
|
||||
sectionContainer.appendChild(makeLink(h))
|
||||
allLinks.push(h)
|
||||
|
|
@ -215,7 +215,7 @@
|
|||
window.addEventListener('resize', updateSidebar)
|
||||
}
|
||||
|
||||
var isBlog = menu.classList.contains('is-blog')
|
||||
let isBlog = menu.classList.contains('is-blog')
|
||||
if (!isBlog) {
|
||||
initSubHeaders()
|
||||
}
|
||||
|
|
@ -224,19 +224,19 @@
|
|||
function IndexPage () {
|
||||
// Tabs
|
||||
window.addEventListener('load', () => {
|
||||
var tabs = document.querySelectorAll('.Tabs-link')
|
||||
let tabs = document.querySelectorAll('.Tabs-link')
|
||||
|
||||
function myTabClicks (tabClickEvent) {
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
tabs[i].classList.remove('Tabs-link--active')
|
||||
}
|
||||
|
||||
var clickedTab = tabClickEvent.currentTarget
|
||||
let clickedTab = tabClickEvent.currentTarget
|
||||
clickedTab.classList.add('Tabs-link--active')
|
||||
tabClickEvent.preventDefault()
|
||||
tabClickEvent.stopPropagation()
|
||||
|
||||
var myContentPanes = document.querySelectorAll('.TabPane')
|
||||
let myContentPanes = document.querySelectorAll('.TabPane')
|
||||
|
||||
for (i = 0; i < myContentPanes.length; i++) {
|
||||
myContentPanes[i].classList.remove('TabPane--active')
|
||||
|
|
@ -244,24 +244,24 @@
|
|||
|
||||
// storing reference to event.currentTarget, otherwise we get
|
||||
// all the children like SVGs, instead of our target — the link element
|
||||
var anchorReference = tabClickEvent.currentTarget
|
||||
var activePaneId = anchorReference.getAttribute('href')
|
||||
var activePane = document.querySelector(activePaneId)
|
||||
let anchorReference = tabClickEvent.currentTarget
|
||||
let activePaneId = anchorReference.getAttribute('href')
|
||||
let activePane = document.querySelector(activePaneId)
|
||||
activePane.classList.add('TabPane--active')
|
||||
}
|
||||
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
tabs[i].addEventListener('click', myTabClicks)
|
||||
}
|
||||
})
|
||||
|
||||
var tagline = document.querySelector('.MainHeader-tagline')
|
||||
var taglinePart = document.querySelector('.MainHeader-taglinePart')
|
||||
var taglineList = document.querySelector('.MainHeader-taglineList')
|
||||
var taglineCounter = taglineList.children.length
|
||||
let tagline = document.querySelector('.MainHeader-tagline')
|
||||
let taglinePart = document.querySelector('.MainHeader-taglinePart')
|
||||
let taglineList = document.querySelector('.MainHeader-taglineList')
|
||||
let taglineCounter = taglineList.children.length
|
||||
|
||||
function shuffleTaglines () {
|
||||
for (var i = taglineList.children.length; i >= 0; i--) {
|
||||
for (let i = taglineList.children.length; i >= 0; i--) {
|
||||
taglineList.appendChild(taglineList.children[Math.random() * i | 0])
|
||||
}
|
||||
}
|
||||
|
|
@ -269,7 +269,7 @@
|
|||
function loopTaglines () {
|
||||
taglineCounter--
|
||||
if (taglineCounter >= 0) {
|
||||
var taglineText = taglineList.children[taglineCounter].textContent
|
||||
let taglineText = taglineList.children[taglineCounter].textContent
|
||||
showTagline(taglineText)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue