@v4fire/client
Version:
V4Fire client core library
145 lines (117 loc) • 3.09 kB
text/typescript
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
/**
* [[include:core/component/prop/README.md]]
* @packageDocumentation
*/
import { defProp } from 'core/const/props';
import { defaultWrapper } from 'core/component/const';
import type { ComponentInterface } from 'core/component/interface';
import type { InitPropsObjectOptions } from 'core/component/prop/interface';
export * from 'core/component/prop/interface';
/**
* Initializes input properties of the specified component instance.
* The method returns an object with initialized properties.
*
* @param component
* @param [opts] - additional options
*/
export function initProps(
component: ComponentInterface,
opts: InitPropsObjectOptions = {}
): Dictionary {
opts.store = opts.store ?? {};
const {
unsafe,
unsafe: {meta, meta: {component: {props}}},
isFlyweight
} = component;
const
{store, from} = opts;
const
ssrMode = component.$renderEngine.supports.ssr,
isNotRegular = meta.params.functional === true || component.isFlyweight;
for (let keys = Object.keys(props), i = 0; i < keys.length; i++) {
const
key = keys[i],
el = props[key];
let
needSave = Boolean(isFlyweight) || opts.saveToStore;
if (el == null) {
continue;
}
// Don't initialize a property for a functional component unless explicitly required
if (!ssrMode && isNotRegular && el.functional === false) {
continue;
}
// @ts-ignore (access)
unsafe['$activeField'] = key;
let
val = (from ?? component)[key];
if (val === undefined) {
val = el.default !== undefined ? el.default : Object.fastClone(meta.instance[key]);
}
if (val === undefined) {
const
obj = props[key];
if (obj?.required) {
throw new TypeError(`Missing the required property "${key}" (component "${component.componentName}")`);
}
}
if (Object.isFunction(val)) {
if (opts.saveToStore || val[defaultWrapper] !== true) {
val = isTypeCanBeFunc(el.type) ? val.bind(component) : val.call(component);
needSave = true;
}
}
if (needSave) {
if (isFlyweight) {
const prop = val === undefined ?
defProp :
{
configurable: true,
enumerable: true,
writable: true,
value: val
};
Object.defineProperty(store, key, prop);
component.$props[key] = val;
} else {
store[key] = val;
}
}
}
// @ts-ignore (access)
unsafe['$activeField'] = undefined;
return store;
}
/**
* Returns true if the specified type can be a function
*
* @param type
* @example
* ```js
* isTypeCanBeFunc(Boolean); // false
* isTypeCanBeFunc(Function); // true
* isTypeCanBeFunc([Function, Boolean]); // true
* ```
*/
export function isTypeCanBeFunc(type: CanUndef<CanArray<Function | FunctionConstructor>>): boolean {
if (!type) {
return false;
}
if (Object.isArray(type)) {
for (let i = 0; i < type.length; i++) {
if (type[i] === Function) {
return true;
}
}
return false;
}
return type === Function;
}