From 48bc9651f53f3e7c23f73006c31db1d799182a64 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Fri, 20 Dec 2019 14:41:45 +0300 Subject: [PATCH 01/78] Add .editorconfig --- .editorconfig | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..121558840 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true From 4de5e98073f61950573a99fd1126527603b0072d Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Fri, 20 Dec 2019 14:44:28 +0300 Subject: [PATCH 02/78] Remove $ from progress.js --- src/ui/progress.js | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/ui/progress.js b/src/ui/progress.js index b8fca7930..93f4fb324 100644 --- a/src/ui/progress.js +++ b/src/ui/progress.js @@ -1,4 +1,3 @@ -import $ from 'jquery' import { canvas } from '../utils/abilities' import { tpl } from '../templates' @@ -56,9 +55,9 @@ class Circle { class BaseRenderer { constructor(el) { - this.element = $(el) - this.element.data('uploadcare-progress-renderer', this) - this.element.addClass('uploadcare--progress') + this.element = document.querySelector(el) + this.element.dataset['uploadcare-progress-renderer'] = this + this.element.classList.add('uploadcare--progress') } update() {} @@ -67,31 +66,36 @@ class BaseRenderer { class TextRenderer extends BaseRenderer { constructor() { super(...arguments) - this.element.addClass('uploadcare--progress_type_text') - this.element.html(tpl('progress__text')) - this.text = this.element.find('.uploadcare--progress__text') + this.element.classList.add('uploadcare--progress_type_text') + this.element.innerHTML = tpl('progress__text') + this.text = this.element.querySelector('.uploadcare--progress__text') } setValue(val) { val = Math.round(val * 100) - return this.text.html(`${val} %`) + return (this.text.innerHTML = `${val} %`) } } class CanvasRenderer extends BaseRenderer { constructor() { super(...arguments) - this.canvasEl = $('') - .addClass('uploadcare--progress__canvas') - .get(0) - this.element.addClass('uploadcare--progress_type_canvas') - this.element.html(this.canvasEl) + this.canvasEl = document + .createElement('canvas') + .classList.add('uploadcare--progress__canvas') + this.element.classList.add('uploadcare--progress_type_canvas') + this.element.innerHTML = this.canvasEl this.setValue(0, true) } update() { var arc, ctx, half, size - half = Math.floor(Math.min(this.element.width(), this.element.height())) + const getWidth = element => + parseFloat(getComputedStyle(element, null).width.replace('px', '')) + const getHeight = element => element.offsetHeight + + half = Math.floor(Math.min(getWidth(this.element), getHeight(this.element))) + size = half * 2 if (half) { if (this.canvasEl.width !== size || this.canvasEl.height !== size) { @@ -150,7 +154,7 @@ class CanvasRenderer extends BaseRenderer { __setValue(val) { this.val = val - this.element.attr('aria-valuenow', (val * 100).toFixed(0)) + this.element.setAttribute('aria-valuenow', (val * 100).toFixed(0)); return this.update() } From 1f500cbb361fb2e928d55f35969dd9b70229aeda Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Fri, 20 Dec 2019 15:03:51 +0300 Subject: [PATCH 03/78] Add window --- src/ui/progress.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/progress.js b/src/ui/progress.js index 93f4fb324..4093757e3 100644 --- a/src/ui/progress.js +++ b/src/ui/progress.js @@ -91,7 +91,7 @@ class CanvasRenderer extends BaseRenderer { update() { var arc, ctx, half, size const getWidth = element => - parseFloat(getComputedStyle(element, null).width.replace('px', '')) + parseFloat(window.getComputedStyle(element, null).width.replace('px', '')) const getHeight = element => element.offsetHeight half = Math.floor(Math.min(getWidth(this.element), getHeight(this.element))) From df8172175209b44fbc7ba8323f2f40d783b8b960 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 14:26:38 +0300 Subject: [PATCH 04/78] Remove $ from files.js --- src/files.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/files.js b/src/files.js index 923ba9638..eb3619014 100644 --- a/src/files.js +++ b/src/files.js @@ -1,4 +1,3 @@ -import $ from 'jquery' import { build } from './settings' import { ObjectFile } from './files/object' @@ -28,7 +27,7 @@ const filesFrom = function(type, data, s) { info = undefined - if ($.isArray(param)) { + if (Array.isArray(param)) { info = param[1] param = param[0] } From f3d3ef30ed47cd3bc0e2fa2620a73423d28fc677 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 14:27:03 +0300 Subject: [PATCH 05/78] Add isFunction to utils.js --- src/utils.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index e467ecd0f..779cf61af 100644 --- a/src/utils.js +++ b/src/utils.js @@ -435,6 +435,14 @@ const fixedPipe = function(promise, ...fns) { }).promise() } +const isFunction = ( fn ) => { + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof fn === "function" && typeof fn.nodeType !== "number" +} + export { unique, defer, @@ -466,5 +474,6 @@ export { jsonp, canvasToBlob, taskRunner, - fixedPipe + fixedPipe, + isFunction, } From fe5a6397c6784674bbc22cb4cbd9717b3d0cdda3 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 14:27:22 +0300 Subject: [PATCH 06/78] Remove $ from locale.js --- src/locale.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/locale.js b/src/locale.js index c91ef9968..d4e3c2cda 100644 --- a/src/locale.js +++ b/src/locale.js @@ -1,7 +1,6 @@ -import $ from 'jquery' - import { build as buildSettings } from './settings' import locales from './locales' +import {isFunction} from './utils' let currentLocale = null @@ -59,14 +58,13 @@ const _build = function(stgs) { if (!currentLocale) { const settings = buildSettings(stgs) const lang = settings.locale || defaults.lang - const translations = $.extend( - true, + const translations = Object.assign( {}, locale.translations[lang], settings.localeTranslations ) - const pluralize = $.isFunction(settings.localePluralize) + const pluralize = isFunction(settings.localePluralize) ? settings.localePluralize : locale.pluralize[lang] From be059ed476d286d8e583b63dbcaf8e9180a38f0c Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 14:27:44 +0300 Subject: [PATCH 07/78] Remove $ from stylesheets.js --- src/stylesheets.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/stylesheets.js b/src/stylesheets.js index 570083e11..7345663e6 100644 --- a/src/stylesheets.js +++ b/src/stylesheets.js @@ -1,5 +1,3 @@ -import $ from 'jquery' - import { tpl } from './templates' import { waitForSettings } from './settings' import { isWindowDefined } from './utils/is-window-defined' @@ -16,6 +14,7 @@ isWindowDefined() && } else { style.appendChild(document.createTextNode(css)) } + const head = document.querySelector('head') - return $('head').prepend(style) + return head.insertBefore(style, head.firstChild) }) From f925f9d6032636b797536a09c9827fd07c4f2a9f Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 14:30:42 +0300 Subject: [PATCH 08/78] Remove $ from settings.js --- src/settings.js | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/settings.js b/src/settings.js index 1bc597071..4d62eaa86 100644 --- a/src/settings.js +++ b/src/settings.js @@ -107,13 +107,13 @@ script = scripts = document.getElementsByTagName('script') return scripts[scripts.length - 1] })()) -integration = isWindowDefined() && $(script).data('integration') +integration = isWindowDefined() && script.dataset.integration if (integration && integration != null) { - defaults = $.extend(defaults, { integration }) + defaults = Object.assign(defaults, { integration }) } str2arr = function(value) { - if (!$.isArray(value)) { - value = $.trim(value) + if (!Array.isArray(value)) { + value = value.trim() value = value ? value.split(' ') : [] } return value @@ -161,7 +161,7 @@ flagOptions = function(settings, keys) { if (typeof value === 'string') { // "", "..." -> true // "false", "disabled" -> false - value = $.trim(value).toLowerCase() + value = value.trim().toLowerCase() settings[key] = !(value === 'false' || value === 'disabled') } else { settings[key] = !!value @@ -214,7 +214,7 @@ constrainOptions = function(settings, constraints) { parseCrop = function(val) { var ratio, reRatio reRatio = /^([0-9]+)([x:])([0-9]+)\s*(|upscale|minimum)$/i - ratio = reRatio.exec($.trim(val.toLowerCase())) || [] + ratio = reRatio.exec(val.toLowerCase().trim()) || [] return { downscale: ratio[2] === 'x', upscale: !!ratio[4], @@ -226,7 +226,7 @@ parseCrop = function(val) { parseShrink = function(val) { var reShrink, shrink, size reShrink = /^([0-9]+)x([0-9]+)(?:\s+(\d{1,2}|100)%)?$/i - shrink = reShrink.exec($.trim(val.toLowerCase())) || [] + shrink = reShrink.exec(val.toLowerCase().trim()) || [] if (!shrink.length) { return false } @@ -296,17 +296,17 @@ normalize = function(settings) { transformOptions(settings, transforms) constrainOptions(settings, constraints) integrationToUserAgent(settings) - if (settings.crop !== false && !$.isArray(settings.crop)) { + if (settings.crop !== false && !Array.isArray(settings.crop)) { if (/^(disabled?|false|null)$/i.test(settings.crop)) { settings.crop = false - } else if ($.isPlainObject(settings.crop)) { + } else if (isPlainObject(settings.crop)) { // old format settings.crop = [settings.crop] } else { - settings.crop = $.map(('' + settings.crop).split(','), parseCrop) + settings.crop = ('' + settings.crop).split(',').map(parseCrop) } } - if (settings.imageShrink && !$.isPlainObject(settings.imageShrink)) { + if (settings.imageShrink && !isPlainObject(settings.imageShrink)) { settings.imageShrink = parseShrink(settings.imageShrink) } if (settings.crop || settings.multiple) { @@ -346,9 +346,9 @@ const globals = function() { const common = once(function(settings, ignoreGlobals) { var result if (!ignoreGlobals) { - defaults = $.extend(defaults, globals()) + defaults = Object.assign(defaults, globals()) } - result = normalize($.extend(defaults, settings || {})) + result = normalize(Object.assign(defaults, settings || {})) waitForSettings.fire(result) return result }) @@ -356,9 +356,9 @@ const common = once(function(settings, ignoreGlobals) { // Defaults + global variables + global overrides + local overrides const build = function(settings) { var result - result = $.extend({}, common()) - if (!$.isEmptyObject(settings)) { - result = normalize($.extend(result, settings)) + result = Object.assign({}, common()) + if (settings && !Object.keys(settings).length === 0) { + result = normalize(Object.assign(result, settings)) } return result } @@ -385,6 +385,10 @@ const CssCollector = class CssCollector { } } +const isPlainObject = (obj) => { + return Object.prototype.toString.call(obj) === '[object Object]' +} + const emptyKeyText = '
\n
Hello!
\n
Your public key is not set.
\n
Add this to the <head> tag to start uploading files:
\n
<script>\nUPLOADCARE_PUBLIC_KEY = \'your_public_key\';\n</script>
\n
' From 8ad72955b2cf7adf055da894ce4ed69135ca0552 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 15:07:08 +0300 Subject: [PATCH 09/78] Add replacement for $.Callbacks --- src/utils.js | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 255 insertions(+), 2 deletions(-) diff --git a/src/utils.js b/src/utils.js index 779cf61af..2ded004f6 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,6 +1,7 @@ import $ from 'jquery' import { warn } from './utils/warnings' +import ar from './locales/ar' var indexOf = [].indexOf @@ -435,12 +436,263 @@ const fixedPipe = function(promise, ...fns) { }).promise() } -const isFunction = ( fn ) => { +const isFunction = fn => { // Support: Chrome <=57, Firefox <=52 // In some browsers, typeof returns "function" for HTML elements // (i.e., `typeof document.createElement( "object" ) === "function"`). // We don't want to classify *any* DOM node as a function. - return typeof fn === "function" && typeof fn.nodeType !== "number" + return typeof fn === 'function' && typeof fn.nodeType !== 'number' +} + +const inArray = (elem, arr, i) => { + return arr == null ? -1 : indexOf.call(arr, elem, i) +} + +function toType(obj) { + if (obj == null) { + return obj + '' + } + + const class2type = {} + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === 'object' || typeof obj === 'function' + ? class2type[toString.call(obj)] || 'object' + : typeof obj +} + +const isArrayLike = obj => { + function isWindow(obj) { + return obj != null && obj === obj.window + } + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && 'length' in obj && obj.length + var type = toType(obj) + + if (isFunction(obj) || isWindow(obj)) { + return false + } + + return ( + type === 'array' || + length === 0 || + (typeof length === 'number' && length > 0 && length - 1 in obj) + ) +} + +const callbacks = function(options) { + const each = function(obj, callback) { + var length + var i = 0 + + if (isArrayLike(obj)) { + length = obj.length + for (; i < length; i++) { + if (callback.call(obj[i], i, obj[i]) === false) { + break + } + } + } else { + for (i in obj) { + if (callback.call(obj[i], i, obj[i]) === false) { + break + } + } + } + + return obj + } + + // Convert String-formatted options into Object-formatted ones + function createOptions(options) { + var object = {} + const arr = options.match(/[^\x20\t\r\n\f]+/g) || [] + arr.forEach(function(_, flag) { + object[flag] = true + }) + return object + } + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = + typeof options === 'string' + ? createOptions(options) + : Object.assign({}, options) + + // Flag to know if list is currently firing + var firing + // Last fire value for non-forgettable lists + var memory + // Flag to know if list was already fired + var fired + // Flag to prevent firing + var locked + // Actual callback list + var list = [] + // Queue of execution data for repeatable lists + var queue = [] + // Index of currently firing callback (modified by add/remove as needed) + var firingIndex = -1 + // Fire callbacks + var fire = function() { + // Enforce single-firing + locked = locked || options.once + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true + for (; queue.length; firingIndex = -1) { + memory = queue.shift() + while (++firingIndex < list.length) { + // Run callback and check for early termination + if ( + list[firingIndex].apply(memory[0], memory[1]) === false && + options.stopOnFalse + ) { + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length + memory = false + } + } + } + + // Forget the data if we're done with it + if (!options.memory) { + memory = false + } + + firing = false + + // Clean up if we're done firing for good + if (locked) { + // Keep an empty list if we have data for future add calls + if (memory) { + list = [] + + // Otherwise, this object is spent + } else { + list = '' + } + } + } + // Actual Callbacks object + var self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if (list) { + // If we have memory from a past run, we should fire after adding + if (memory && !firing) { + firingIndex = list.length - 1 + queue.push(memory) + } + + ;(function add(args) { + each(args, function(_, arg) { + if (isFunction(arg)) { + if (!options.unique || !self.has(arg)) { + list.push(arg) + } + } else if (arg && arg.length && toType(arg) !== 'string') { + // Inspect recursively + add(arg) + } + }) + })(arguments) + + if (memory && !firing) { + fire() + } + } + return this + }, + + // Remove a callback from the list + remove: function() { + each(arguments, function(_, arg) { + var index + while ((index = inArray(arg, list, index)) > -1) { + list.splice(index, 1) + + // Handle firing indexes + if (index <= firingIndex) { + firingIndex-- + } + } + }) + return this + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function(fn) { + return fn ? inArray(fn, list) > -1 : list.length > 0 + }, + + // Remove all callbacks from the list + empty: function() { + if (list) { + list = [] + } + return this + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = [] + list = memory = '' + return this + }, + disabled: function() { + return !list + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = [] + if (!memory && !firing) { + list = memory = '' + } + return this + }, + locked: function() { + return !!locked + }, + + // Call all callbacks with the given context and arguments + fireWith: function(context, args) { + if (!locked) { + args = args || [] + args = [context, args.slice ? args.slice() : args] + queue.push(args) + if (!firing) { + fire() + } + } + return this + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith(this, arguments) + return this + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired + } + } + + return self } export { @@ -476,4 +728,5 @@ export { taskRunner, fixedPipe, isFunction, + callbacks } From a0dbe0279759c3d12043a5386c5716bac1344668 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 15:07:25 +0300 Subject: [PATCH 10/78] Remove $.Callbacks from settings.js --- src/settings.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/settings.js b/src/settings.js index 4d62eaa86..47f860723 100644 --- a/src/settings.js +++ b/src/settings.js @@ -1,9 +1,8 @@ -import $ from 'jquery' import { version } from '../package.json' import { sendFileAPI } from './utils/abilities' import { warnOnce } from './utils/warnings' -import { unique, once, upperCase, normalizeUrl } from './utils' +import {unique, once, upperCase, normalizeUrl, callbacks} from './utils' import { isWindowDefined } from './utils/is-window-defined' var indexOf = [].indexOf @@ -363,7 +362,7 @@ const build = function(settings) { return result } -const waitForSettings = isWindowDefined() && $.Callbacks('once memory') +const waitForSettings = isWindowDefined() && callbacks('once memory') const CssCollector = class CssCollector { constructor() { From b4225f16901a29676974e49b91bec27e6dbaaff5 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 15:11:23 +0300 Subject: [PATCH 11/78] Remove ar locale from utils (autocomplete error) --- src/utils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index 2ded004f6..5ff3f6071 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,7 +1,6 @@ import $ from 'jquery' import { warn } from './utils/warnings' -import ar from './locales/ar' var indexOf = [].indexOf From 22b25a6d0787208c3d82864154c24737ab376885 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 15:16:51 +0300 Subject: [PATCH 12/78] Remove $ from utils/pusher.js --- src/utils/pusher.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/utils/pusher.js b/src/utils/pusher.js index 2e31ca230..5ae24d449 100644 --- a/src/utils/pusher.js +++ b/src/utils/pusher.js @@ -1,5 +1,3 @@ -import $ from 'jquery' - import { Pusher } from '../vendor/pusher' // utils.pusher @@ -24,7 +22,7 @@ class ManagedPusher extends Pusher { unsubscribe(name) { super.unsubscribe(...arguments) // Schedule disconnect if no channels left. - if ($.isEmptyObject(this.channels.channels)) { + if (this.channels.channels && Object.keys(this.channels.channels).length === 0) { this.disconnectTimeout = setTimeout(() => { this.disconnectTimeout = null return this.disconnect() From 480468ab38bd2e82b12a777a2746c07857735bac Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 15:35:23 +0300 Subject: [PATCH 13/78] Add extend function to utils.js --- src/utils.js | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index 5ff3f6071..e1cf122ba 100644 --- a/src/utils.js +++ b/src/utils.js @@ -694,6 +694,84 @@ const callbacks = function(options) { return self } +const extend = function() { + var options + var name + var src + var copy + var copyIsArray + var clone + var target = arguments[0] || {} + var i = 1 + var length = arguments.length + var deep = false + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target + + // Skip the boolean and the target + target = arguments[i] || {} + i++ + } + + // Handle case when target is a string or something (possible in deep copy) + if (typeof target !== 'object' && !isFunction(target)) { + target = {} + } + + // Extend jQuery itself if only one argument is passed + if (i === length) { + target = this + i-- + } + + for (; i < length; i++) { + // Only deal with non-null/undefined values + if ((options = arguments[i]) != null) { + // Extend the base object + for (name in options) { + copy = options[name] + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if (name === '__proto__' || target === copy) { + continue + } + + // Recurse if we're merging plain objects or arrays + if ( + deep && + copy && + (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy))) + ) { + src = target[name] + + // Ensure proper type for the source value + if (copyIsArray && !Array.isArray(src)) { + clone = [] + } else if (!copyIsArray && !jQuery.isPlainObject(src)) { + clone = {} + } else { + clone = src + } + copyIsArray = false + + // Never move original objects, clone them + target[name] = extend(deep, clone, copy) + + // Don't bring in undefined values + } else if (copy !== undefined) { + target[name] = copy + } + } + } + } + + // Return the modified object + return target +} + export { unique, defer, @@ -727,5 +805,7 @@ export { taskRunner, fixedPipe, isFunction, - callbacks + callbacks, + inArray, + extend } From 65af19d8a1d5fce9fc5d8858cc59f8cee78e7639 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 15:35:45 +0300 Subject: [PATCH 14/78] Replace Object.assign with deep extend function --- src/locale.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locale.js b/src/locale.js index d4e3c2cda..b54516e6a 100644 --- a/src/locale.js +++ b/src/locale.js @@ -1,6 +1,6 @@ import { build as buildSettings } from './settings' import locales from './locales' -import {isFunction} from './utils' +import { extend, isFunction } from './utils' let currentLocale = null @@ -58,7 +58,7 @@ const _build = function(stgs) { if (!currentLocale) { const settings = buildSettings(stgs) const lang = settings.locale || defaults.lang - const translations = Object.assign( + const translations = extend( {}, locale.translations[lang], settings.localeTranslations From 39ef623ad5afe9b84b02f326adf7de854611f3c7 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 15:38:48 +0300 Subject: [PATCH 15/78] Replace Object.assign with deep extend function --- src/settings.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/settings.js b/src/settings.js index 47f860723..59d69219d 100644 --- a/src/settings.js +++ b/src/settings.js @@ -2,7 +2,14 @@ import { version } from '../package.json' import { sendFileAPI } from './utils/abilities' import { warnOnce } from './utils/warnings' -import {unique, once, upperCase, normalizeUrl, callbacks} from './utils' +import { + unique, + once, + upperCase, + normalizeUrl, + callbacks, + extend +} from './utils' import { isWindowDefined } from './utils/is-window-defined' var indexOf = [].indexOf @@ -108,7 +115,7 @@ script = })()) integration = isWindowDefined() && script.dataset.integration if (integration && integration != null) { - defaults = Object.assign(defaults, { integration }) + defaults = extend(defaults, { integration }) } str2arr = function(value) { if (!Array.isArray(value)) { @@ -345,9 +352,9 @@ const globals = function() { const common = once(function(settings, ignoreGlobals) { var result if (!ignoreGlobals) { - defaults = Object.assign(defaults, globals()) + defaults = extend(defaults, globals()) } - result = normalize(Object.assign(defaults, settings || {})) + result = normalize(extend(defaults, settings || {})) waitForSettings.fire(result) return result }) @@ -355,9 +362,9 @@ const common = once(function(settings, ignoreGlobals) { // Defaults + global variables + global overrides + local overrides const build = function(settings) { var result - result = Object.assign({}, common()) + result = extend({}, common()) if (settings && !Object.keys(settings).length === 0) { - result = normalize(Object.assign(result, settings)) + result = normalize(extend(result, settings)) } return result } @@ -384,7 +391,7 @@ const CssCollector = class CssCollector { } } -const isPlainObject = (obj) => { +const isPlainObject = obj => { return Object.prototype.toString.call(obj) === '[object Object]' } From 959277c01e3228c1dea192a21907820a27ffde47 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Tue, 24 Dec 2019 15:45:20 +0300 Subject: [PATCH 16/78] Add isPlainObject --- src/utils.js | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/utils.js b/src/utils.js index e1cf122ba..656f04a8d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -694,6 +694,34 @@ const callbacks = function(options) { return self } +const isPlainObject = function(obj) { + var proto, Ctor + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if (!obj || toString.call(obj) !== '[object Object]') { + return false + } + + proto = Object.getPrototypeOf(obj) + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if (!proto) { + return true + } + + var class2type = {} + var hasOwn = class2type.hasOwnProperty + var fnToString = hasOwn.toString + var ObjectFunctionString = fnToString.call(Object) + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call(proto, 'constructor') && proto.constructor + return ( + typeof Ctor === 'function' && fnToString.call(Ctor) === ObjectFunctionString + ) +} + const extend = function() { var options var name @@ -743,14 +771,14 @@ const extend = function() { if ( deep && copy && - (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy))) + (isPlainObject(copy) || (copyIsArray = Array.isArray(copy))) ) { src = target[name] // Ensure proper type for the source value if (copyIsArray && !Array.isArray(src)) { clone = [] - } else if (!copyIsArray && !jQuery.isPlainObject(src)) { + } else if (!copyIsArray && !isPlainObject(src)) { clone = {} } else { clone = src From 8bd75ffd70a215d3159356a3e6e4955d9525ab08 Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Wed, 25 Dec 2019 10:51:10 +0300 Subject: [PATCH 17/78] Remove $ from messages.js --- src/utils.js | 22 +++++++++++++++++++++- src/utils/messages.js | 6 +++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/utils.js b/src/utils.js index 656f04a8d..a36747fc9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -800,6 +800,25 @@ const extend = function() { return target } +const grep = (elems, callback, invert) => { + var callbackInverse + var matches = [] + var i = 0 + var length = elems.length + var callbackExpect = !invert + + // Go through the array, only saving the items + // that pass the validator function + for (; i < length; i++) { + callbackInverse = !callback(elems[i], i) + if (callbackInverse !== callbackExpect) { + matches.push(elems[i]) + } + } + + return matches +} + export { unique, defer, @@ -835,5 +854,6 @@ export { isFunction, callbacks, inArray, - extend + extend, + grep, } diff --git a/src/utils/messages.js b/src/utils/messages.js index f903b19ab..652364ff3 100644 --- a/src/utils/messages.js +++ b/src/utils/messages.js @@ -1,12 +1,12 @@ -import $ from 'jquery' import { isWindowDefined } from './is-window-defined' +import { grep } from '../utils' // utils var callbacks = {} isWindowDefined() && - $(window).on('message', ({ originalEvent: e }) => { + window.addEventListener('message', ({ originalEvent: e }) => { var i, item, len, message, ref, results try { message = JSON.parse(e.data) @@ -41,7 +41,7 @@ const registerMessage = function(type, sender, callback) { const unregisterMessage = function(type, sender) { if (type in callbacks) { - callbacks[type] = $.grep(callbacks[type], function(item) { + callbacks[type] = grep(callbacks[type], function(item) { return item[0] !== sender }) From 32608d5385f5fadc2cfe4582fd2eb0279db01fcc Mon Sep 17 00:00:00 2001 From: Siarhei Bautrukevich Date: Wed, 25 Dec 2019 11:30:26 +0300 Subject: [PATCH 18/78] Remove $ from image-loader.js --- src/utils/image-loader.js | 42 +++++++++++++++++++++------------- src/widget/tabs/preview-tab.js | 4 ++-- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/utils/image-loader.js b/src/utils/image-loader.js index b0ce04fec..3a56890f5 100644 --- a/src/utils/image-loader.js +++ b/src/utils/image-loader.js @@ -2,30 +2,34 @@ import $ from 'jquery' // utils const trackLoading = function(image, src) { - var def - def = $.Deferred() + let promiseResolve + let promiseReject + const promise = new Promise((resolve, reject) => { + resolve = promiseResolve + reject = promiseReject + }) if (src) { image.src = src } if (image.complete) { - def.resolve(image) + promiseResolve(image) } else { $(image).one('load', () => { - return def.resolve(image) + return promiseResolve(image) }) $(image).one('error', () => { - return def.reject(image) + return promiseReject(image) }) } - return def.promise() + return promise } const imageLoader = function(image) { // if argument is an array, treat as // load(['1.jpg', '2.jpg']) - if ($.isArray(image)) { - return $.when.apply(null, $.map(image, imageLoader)) + if (Array.isArray(image)) { + return $.when.apply(null, image.map(imageLoader)) } if (image.src) { return trackLoading(image) @@ -35,16 +39,22 @@ const imageLoader = function(image) { } const videoLoader = function(src) { - var def = $.Deferred() + let promiseResolve + let promiseReject + const promise = new Promise((resolve, reject) => { + resolve = promiseResolve + reject = promiseReject + }) + const video = document.createElement('video') - $('