@v4fire/client
Version:
V4Fire client core library
334 lines (252 loc) • 7.12 kB
text/typescript
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
import { identity } from 'core/functools/helpers';
import type { VNodeData } from 'vue';
import config from 'core/component/engines/zero/config';
import { document } from 'core/component/engines/zero/const';
import { warn } from 'core/component/engines/zero/helpers';
import { reservedAttrs } from 'core/component/engines/zero/context/const';
import type { KeyCode } from 'core/component/engines/zero/context/interface';
export * from 'core/component/engines/zero/context/const';
export default {
_o: identity,
_q: Object.fastCompare.bind(Object),
_s(value: unknown): string {
if (Object.isPrimitive(value)) {
return String(value);
}
return Object.fastHash(value);
},
_v(value: string): Text {
return document.createTextNode(value);
},
_e(value: Nullable<string>): Comment | Text {
if (value != null) {
return document.createComment(value);
}
return document.createTextNode('');
},
_f(id: string): Function {
return resolveAsset(this.$options, 'filters', id, true) ?? identity;
},
_n(value: string): number | string {
const n = parseFloat(value);
return isNaN(n) ? value : n;
},
_i(arr: unknown[], value: unknown): number {
for (let i = 0; i < arr.length; i++) {
if (this._q(arr[i], value) === true) {
return i;
}
}
return -1;
},
_m(index: number, isInFor: boolean): Node {
const
cached = this._staticTrees ?? (this._staticTrees = []);
let
tree = cached[index];
if (tree == null && !isInFor) {
return tree;
}
tree = this.$options.staticRenderFns[index]
.call(this._renderProxy, null, this);
cached[index] = tree;
return tree;
},
_l(value: unknown, render: Function): unknown[] {
let
res;
if (Object.isArray(value) || Object.isString(value)) {
res = new Array(value.length);
for (let i = 0, l = value.length; i < l; i++) {
res[i] = render(value[i], i);
}
} else if (Object.isNumber(value)) {
res = new Array(value);
for (let i = 0; i < value; i++) {
res[i] = render(i + 1, i);
}
} else if (value != null && typeof value === 'object') {
const keys = Object.keys(value);
res = new Array(keys.length);
for (let i = 0, l = keys.length; i < l; i++) {
const key = keys[i];
res[i] = render(value[key], key, i);
}
}
if (res != null) {
(res)._isVList = true;
}
return res;
},
_g(data: VNodeData, value?: Dictionary<CanArray<Function>>): VNodeData {
if (Object.isDictionary(value)) {
const on = data.on != null ? {...data.on} : {};
data.on = on;
// eslint-disable-next-line guard-for-in
for (const key in value) {
const
ours = value[key],
existing = on[key];
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
on[key] = existing != null ? Array.concat([], existing, ours) : ours ?? [];
}
} else {
warn('v-on without argument expects an Object value', this);
}
return data;
},
_k(
eventKeyCode: string,
key: KeyCode,
builtInKeyCode?: Nullable<KeyCode>,
eventKeyName?: string,
builtInKeyName?: Nullable<KeyCode>
): boolean {
const
configCodes = config.keyCodes[key],
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
mappedKeyCode = configCodes ?? builtInKeyCode;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (builtInKeyName != null && eventKeyName != null && configCodes == null) {
return isKeyNotMatch(builtInKeyName, eventKeyName);
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (mappedKeyCode != null) {
return isKeyNotMatch(mappedKeyCode, eventKeyCode);
}
if (eventKeyName != null) {
return eventKeyName.dasherize() !== key;
}
return false;
},
_b(data: VNodeData, tag: string, value: unknown, asProp: boolean, isSync: boolean): VNodeData {
if (value != null && typeof value === 'object') {
const
obj = Object.isArray(value) ? Object.assign({}, ...value) : value;
let hash;
const loop = (key) => {
if (key === 'class' || key === 'style' || reservedAttrs[key] === true) {
hash = data;
} else {
hash = asProp ? data.domProps ?? (data.domProps = {}) : data.attrs ?? (data.attrs = {});
}
if (!(key in hash)) {
hash[key] = obj[key];
if (isSync) {
const on = data.on ?? (data.on = {});
on[`update:${key}`] = ($event) => {
obj[key] = $event;
};
}
}
};
// eslint-disable-next-line guard-for-in
for (const key in obj) {
loop(key);
}
} else {
warn('v-bind without argument expects an Object or Array value', this);
}
return data;
},
_t(name: string, fallback: CanArray<Element>, props?: Dictionary, bindObject?: Dictionary): Element[] {
const
scopedSlotFn = this.$scopedSlots[name];
let
nodes;
if (scopedSlotFn != null) {
props ??= {};
if (bindObject) {
if (typeof bindObject !== 'object') {
warn('slot v-bind without argument expects an Object', this);
}
props = {...bindObject, ...props};
}
nodes = scopedSlotFn(props) ?? fallback;
} else {
const
slotNodes = this.$slots[name];
if (slotNodes != null) {
slotNodes._rendered = true;
}
nodes = slotNodes ?? fallback;
}
const
target = props?.slot;
if (target != null) {
return this.$createElement('template', {slot: target}, nodes);
}
return nodes;
},
_u(
fns: Array<CanArray<CanUndef<{
key: string;
fn: Function;
proxy?: boolean;
}>>>,
res: CanUndef<Dictionary>,
hasDynamicKeys: boolean,
contentHashKey?: string
): Dictionary {
res ??= {$stable: !hasDynamicKeys};
for (let i = 0; i < fns.length; i++) {
const
slot = fns[i];
if (Array.isArray(slot)) {
this._u(slot, res, hasDynamicKeys);
} else if (slot != null) {
if (slot.proxy) {
// @ts-ignore (access)
slot.fn.proxy = true;
}
res[slot.key] = slot.fn;
}
}
if (contentHashKey != null) {
res.$key = contentHashKey;
}
return res;
}
};
function resolveAsset(opts: Dictionary, type: string, id: string, warnMissing: boolean): CanUndef<Function> {
if (!Object.isString(id)) {
return;
}
const
assets = <Nullable<Dictionary<Function>>>opts[type];
if (assets == null) {
return;
}
if (Object.hasOwnProperty(assets, id)) {
return assets[id];
}
const
camelizedId = id.camelize(false);
if (Object.hasOwnProperty(assets, camelizedId)) {
return assets[camelizedId];
}
const
PascalCaseId = id.camelize();
if (Object.hasOwnProperty(assets, PascalCaseId)) {
return assets[PascalCaseId];
}
const
res = assets[id] ?? assets[camelizedId] ?? assets[PascalCaseId];
if (warnMissing && res == null) {
warn(`Failed to resolve ${type.slice(0, -1)}: ${id}`, opts);
}
return res;
}
function isKeyNotMatch(expect: CanArray<KeyCode>, actual: KeyCode): boolean {
if (Object.isArray(expect)) {
return !expect.includes(actual);
}
return expect !== actual;
}