UNPKG

@vime-js/utils

Version:
113 lines (101 loc) 3.66 kB
import { element } from 'svelte/internal'; import { IS_CLIENT } from './support'; import { is_null_or_undefined, is_array } from './unit'; export const try_decode_uri_component = (component, fallback = '') => { if (!IS_CLIENT) return fallback; try { return window.decodeURIComponent(component); } catch (e) { return fallback; } }; // eslint-disable-next-line max-len // @see https://github.com/ampproject/amphtml/blob/c7c46cec71bac92f5c5da31dcc6366c18577f566/src/url-parse-query-string.js#L31 const QUERY_STRING_REGEX = /(?:^[#?]?|&)([^=&]+)(?:=([^&]*))?/g; export const parse_query_string = (qs) => { const params = Object.create(null); if (!qs) return params; let match; // eslint-disable-next-line no-cond-assign while ((match = QUERY_STRING_REGEX.exec(qs))) { const name = try_decode_uri_component(match[1], match[1]).replace('[]', ''); const value = match[2] ? try_decode_uri_component(match[2].replace(/\+/g, ' '), match[2]) : ''; const currValue = params[name]; if (currValue && !is_array(currValue)) params[name] = [currValue]; currValue ? params[name].push(value) : (params[name] = value); } return params; }; export const serialize_query_string = (params) => { const qs = []; const appendQueryParam = (param, v) => { qs.push(`${encodeURIComponent(param)}=${encodeURIComponent(v)}`); }; Object.keys(params).forEach((param) => { const value = params[param]; if (is_null_or_undefined(value)) return; if (is_array(value)) { value.forEach((v) => appendQueryParam(param, v)); } else { appendQueryParam(param, value); } }); return qs.join('&'); }; export const apppend_querystring_to_url = (url, qs) => { if (!qs) return url; const mainAndQuery = url.split('?', 2); return mainAndQuery[0] + (mainAndQuery[1] ? `?${mainAndQuery[1]}&${qs}` : `?${qs}`); }; export const add_params_to_url = ( url, params, ) => apppend_querystring_to_url(url, serialize_query_string(params)); export const prefetch = (rel, url, as) => { if (!IS_CLIENT) return false; const link = element('link'); link.rel = rel; link.href = url; if (as) link.as = as; link.crossorigin = true; document.head.append(link); return true; }; // Does not handle relative URL's. export const parse_url = (url) => { if (!IS_CLIENT) return {}; const parser = element('a'); parser.href = url; // Handle chrome which will default to domain where script is called from if invalid. return url.indexOf(parser.hostname) !== -1 ? parser : ''; }; const START_TIMESTAMP = /(\d+)(h|m|s)/g; const parse_time_string = (stamp) => { let seconds = 0; let array = START_TIMESTAMP.exec(stamp); while (array !== null) { const [, count, period] = array; if (period === 'h') seconds += parseInt(count, 10) * 60 * 60; if (period === 'm') seconds += parseInt(count, 10) * 60; if (period === 's') seconds += parseInt(count, 10); array = START_TIMESTAMP.exec(stamp); } return seconds; }; const NUMERIC = /^\d+$/; // Parse URL for a start time param, ie ?t=1h14m30s and return the start time in seconds const parse_time_param = (url, pattern) => { const match = url.match(pattern); if (match) { const stamp = match[1]; if (stamp.match(START_TIMESTAMP)) return parse_time_string(stamp); if (NUMERIC.test(stamp)) return parseInt(stamp, 10); } return null; }; const START_TIME_QUERY = /[?&#](?:start|t)=([0-9hms]+)/; export const parse_start_time = (url) => parse_time_param(url, START_TIME_QUERY); const END_TIME_QUERY = /[?&#]end=([0-9hms]+)/; export const parse_end_time = (url) => parse_time_param(url, END_TIME_QUERY);