summaryrefslogtreecommitdiff
path: root/node_modules/svelte/src/runtime/internal/utils.js
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /node_modules/svelte/src/runtime/internal/utils.js
init commit
Diffstat (limited to 'node_modules/svelte/src/runtime/internal/utils.js')
-rw-r--r--node_modules/svelte/src/runtime/internal/utils.js291
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'];