diff options
Diffstat (limited to 'node_modules/svelte/src/runtime/internal/utils.js')
| -rw-r--r-- | node_modules/svelte/src/runtime/internal/utils.js | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/node_modules/svelte/src/runtime/internal/utils.js b/node_modules/svelte/src/runtime/internal/utils.js new file mode 100644 index 0000000..ec39c0d --- /dev/null +++ b/node_modules/svelte/src/runtime/internal/utils.js @@ -0,0 +1,291 @@ +/** @returns {void} */ +export function noop() {} + +export const identity = (x) => x; + +/** + * @template T + * @template S + * @param {T} tar + * @param {S} src + * @returns {T & S} + */ +export function assign(tar, src) { + // @ts-ignore + for (const k in src) tar[k] = src[k]; + return /** @type {T & S} */ (tar); +} + +// Adapted from https://github.com/then/is-promise/blob/master/index.js +// Distributed under MIT License https://github.com/then/is-promise/blob/master/LICENSE +/** + * @param {any} value + * @returns {value is PromiseLike<any>} + */ +export function is_promise(value) { + return ( + !!value && + (typeof value === 'object' || typeof value === 'function') && + typeof (/** @type {any} */ (value).then) === 'function' + ); +} + +/** @returns {void} */ +export function add_location(element, file, line, column, char) { + element.__svelte_meta = { + loc: { file, line, column, char } + }; +} + +export function run(fn) { + return fn(); +} + +export function blank_object() { + return Object.create(null); +} + +/** + * @param {Function[]} fns + * @returns {void} + */ +export function run_all(fns) { + fns.forEach(run); +} + +/** + * @param {any} thing + * @returns {thing is Function} + */ +export function is_function(thing) { + return typeof thing === 'function'; +} + +/** @returns {boolean} */ +export function safe_not_equal(a, b) { + return a != a ? b == b : a !== b || (a && typeof a === 'object') || typeof a === 'function'; +} + +let src_url_equal_anchor; + +/** + * @param {string} element_src + * @param {string} url + * @returns {boolean} + */ +export function src_url_equal(element_src, url) { + if (element_src === url) return true; + if (!src_url_equal_anchor) { + src_url_equal_anchor = document.createElement('a'); + } + // This is actually faster than doing URL(..).href + src_url_equal_anchor.href = url; + return element_src === src_url_equal_anchor.href; +} + +/** @param {string} srcset */ +function split_srcset(srcset) { + return srcset.split(',').map((src) => src.trim().split(' ').filter(Boolean)); +} + +/** + * @param {HTMLSourceElement | HTMLImageElement} element_srcset + * @param {string | undefined | null} srcset + * @returns {boolean} + */ +export function srcset_url_equal(element_srcset, srcset) { + const element_urls = split_srcset(element_srcset.srcset); + const urls = split_srcset(srcset || ''); + + return ( + urls.length === element_urls.length && + urls.every( + ([url, width], i) => + width === element_urls[i][1] && + // We need to test both ways because Vite will create an a full URL with + // `new URL(asset, import.meta.url).href` for the client when `base: './'`, and the + // relative URLs inside srcset are not automatically resolved to absolute URLs by + // browsers (in contrast to img.src). This means both SSR and DOM code could + // contain relative or absolute URLs. + (src_url_equal(element_urls[i][0], url) || src_url_equal(url, element_urls[i][0])) + ) + ); +} + +/** @returns {boolean} */ +export function not_equal(a, b) { + return a != a ? b == b : a !== b; +} + +/** @returns {boolean} */ +export function is_empty(obj) { + return Object.keys(obj).length === 0; +} + +/** @returns {void} */ +export function validate_store(store, name) { + if (store != null && typeof store.subscribe !== 'function') { + throw new Error(`'${name}' is not a store with a 'subscribe' method`); + } +} + +export function subscribe(store, ...callbacks) { + if (store == null) { + for (const callback of callbacks) { + callback(undefined); + } + return noop; + } + const unsub = store.subscribe(...callbacks); + return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; +} + +/** + * Get the current value from a store by subscribing and immediately unsubscribing. + * + * https://svelte.dev/docs/svelte-store#get + * @template T + * @param {import('../store/public.js').Readable<T>} store + * @returns {T} + */ +export function get_store_value(store) { + let value; + subscribe(store, (_) => (value = _))(); + return value; +} + +/** @returns {void} */ +export function component_subscribe(component, store, callback) { + component.$$.on_destroy.push(subscribe(store, callback)); +} + +export function create_slot(definition, ctx, $$scope, fn) { + if (definition) { + const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); + return definition[0](slot_ctx); + } +} + +function get_slot_context(definition, ctx, $$scope, fn) { + return definition[1] && fn ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) : $$scope.ctx; +} + +export function get_slot_changes(definition, $$scope, dirty, fn) { + if (definition[2] && fn) { + const lets = definition[2](fn(dirty)); + if ($$scope.dirty === undefined) { + return lets; + } + if (typeof lets === 'object') { + const merged = []; + const len = Math.max($$scope.dirty.length, lets.length); + for (let i = 0; i < len; i += 1) { + merged[i] = $$scope.dirty[i] | lets[i]; + } + return merged; + } + return $$scope.dirty | lets; + } + return $$scope.dirty; +} + +/** @returns {void} */ +export function update_slot_base( + slot, + slot_definition, + ctx, + $$scope, + slot_changes, + get_slot_context_fn +) { + if (slot_changes) { + const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn); + slot.p(slot_context, slot_changes); + } +} + +/** @returns {void} */ +export function update_slot( + slot, + slot_definition, + ctx, + $$scope, + dirty, + get_slot_changes_fn, + get_slot_context_fn +) { + const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn); + update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn); +} + +/** @returns {any[] | -1} */ +export function get_all_dirty_from_scope($$scope) { + if ($$scope.ctx.length > 32) { + const dirty = []; + const length = $$scope.ctx.length / 32; + for (let i = 0; i < length; i++) { + dirty[i] = -1; + } + return dirty; + } + return -1; +} + +/** @returns {{}} */ +export function exclude_internal_props(props) { + const result = {}; + for (const k in props) if (k[0] !== '$') result[k] = props[k]; + return result; +} + +/** @returns {{}} */ +export function compute_rest_props(props, keys) { + const rest = {}; + keys = new Set(keys); + for (const k in props) if (!keys.has(k) && k[0] !== '$') rest[k] = props[k]; + return rest; +} + +/** @returns {{}} */ +export function compute_slots(slots) { + const result = {}; + for (const key in slots) { + result[key] = true; + } + return result; +} + +/** @returns {(this: any, ...args: any[]) => void} */ +export function once(fn) { + let ran = false; + return function (...args) { + if (ran) return; + ran = true; + fn.call(this, ...args); + }; +} + +export function null_to_empty(value) { + return value == null ? '' : value; +} + +export function set_store_value(store, ret, value) { + store.set(value); + return ret; +} + +export const has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); + +export function action_destroyer(action_result) { + return action_result && is_function(action_result.destroy) ? action_result.destroy : noop; +} + +/** @param {number | string} value + * @returns {[number, string]} + */ +export function split_css_unit(value) { + const split = typeof value === 'string' && value.match(/^\s*(-?[\d.]+)([^\s]*)\s*$/); + return split ? [parseFloat(split[1]), split[2] || 'px'] : [/** @type {number} */ (value), 'px']; +} + +export const contenteditable_truthy_values = ['', true, 1, 'true', 'contenteditable']; |
