parent
ad1c88912c
commit
45ea5187c9
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"props": {
|
||||
"cname": 43,
|
||||
"cname": 47,
|
||||
"props": {
|
||||
"$_dirty": "__d",
|
||||
"$_disable": "__x",
|
||||
|
@ -42,7 +42,11 @@
|
|||
"$_customStyleContent": "O",
|
||||
"$__hasChildren": "P",
|
||||
"$__prevProps": "Q",
|
||||
"$__needUpdate_": "R"
|
||||
"$__needUpdate_": "R",
|
||||
"$__o_": "S",
|
||||
"$__r_": "T",
|
||||
"$__p_": "U",
|
||||
"$__c_": "V"
|
||||
}
|
||||
},
|
||||
"vars": {
|
||||
|
|
|
@ -59,13 +59,13 @@ declare namespace Omis {
|
|||
>;
|
||||
|
||||
interface FunctionalComponent<P = {}> {
|
||||
(props: RenderableProps<P>, context?: any): VNode<any> | null;
|
||||
(props: RenderableProps<P>, $?: any): VNode<any> | null;
|
||||
displayName?: string;
|
||||
defaultProps?: Partial<P>;
|
||||
}
|
||||
|
||||
interface ComponentConstructor<P = {}, S = {}> {
|
||||
new (props: P, context?: any): Component<P, S>;
|
||||
new (props: P, $?: any): Component<P, S>;
|
||||
displayName?: string;
|
||||
defaultProps?: Partial<P>;
|
||||
}
|
||||
|
@ -85,18 +85,18 @@ declare namespace Omis {
|
|||
}
|
||||
|
||||
abstract class Component<P, S> {
|
||||
constructor(props?: P, context?: any);
|
||||
constructor(props?: P, $?: any);
|
||||
|
||||
static displayName?: string;
|
||||
static defaultProps?: any;
|
||||
|
||||
props: RenderableProps<P>;
|
||||
context: any;
|
||||
$: any;
|
||||
base?: HTMLElement;
|
||||
|
||||
update(callback?: () => void): void;
|
||||
|
||||
abstract render(props?: RenderableProps<P>, context?: any): ComponentChild;
|
||||
abstract render(props?: RenderableProps<P>, $?: any): ComponentChild;
|
||||
|
||||
// Add these variables to avoid descendants shadowing them (some from properties.json for minification)
|
||||
private __key;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* omis v0.6.0 http://omijs.org
|
||||
* omis v0.7.0 http://omijs.org
|
||||
* Omi === Preact + Scoped CSS + Store System + Native Support in 3kb javascript.
|
||||
* By dntzhang https://github.com/dntzhang
|
||||
* Github: https://github.com/Tencent/omis
|
||||
|
@ -249,6 +249,116 @@
|
|||
*/
|
||||
var defer = typeof Promise == 'function' ? Promise.resolve().then.bind(Promise.resolve()) : setTimeout;
|
||||
|
||||
function getPath(obj) {
|
||||
if (Object.prototype.toString.call(obj) === '[object Array]') {
|
||||
var result = {};
|
||||
obj.forEach(function (item) {
|
||||
if (typeof item === 'string') {
|
||||
result[item] = true;
|
||||
} else {
|
||||
var tempPath = item[Object.keys(item)[0]];
|
||||
if (typeof tempPath === 'string') {
|
||||
result[tempPath] = true;
|
||||
} else {
|
||||
if (typeof tempPath[0] === 'string') {
|
||||
result[tempPath[0]] = true;
|
||||
} else {
|
||||
tempPath[0].forEach(function (path) {
|
||||
return result[path] = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} else {
|
||||
return getUpdatePath(obj);
|
||||
}
|
||||
}
|
||||
|
||||
function getUpdatePath(data) {
|
||||
var result = {};
|
||||
dataToPath(data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function dataToPath(data, result) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[key] = true;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(data[key], key, result);
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(data[key], key, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _objToPath(data, path, result) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[path + '.' + key] = true;
|
||||
delete result[path];
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(data[key], path + '.' + key, result);
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(data[key], path + '.' + key, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _arrayToPath(data, path, result) {
|
||||
data.forEach(function (item, index) {
|
||||
result[path + '[' + index + ']'] = true;
|
||||
delete result[path];
|
||||
var type = Object.prototype.toString.call(item);
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(item, path + '[' + index + ']', result);
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(item, path + '[' + index + ']', result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getUse(data, paths) {
|
||||
var obj = [];
|
||||
paths.forEach(function (path, index) {
|
||||
var isPath = typeof path === 'string';
|
||||
if (isPath) {
|
||||
obj[index] = getTargetByPath(data, path);
|
||||
} else {
|
||||
var key = Object.keys(path)[0];
|
||||
var value = path[key];
|
||||
if (typeof value === 'string') {
|
||||
obj[index] = getTargetByPath(data, value);
|
||||
} else {
|
||||
var tempPath = value[0];
|
||||
if (typeof tempPath === 'string') {
|
||||
var tempVal = getTargetByPath(data, tempPath);
|
||||
obj[index] = value[1] ? value[1](tempVal) : tempVal;
|
||||
} else {
|
||||
var args = [];
|
||||
tempPath.forEach(function (path) {
|
||||
args.push(getTargetByPath(data, path));
|
||||
});
|
||||
obj[index] = value[1].apply(null, args);
|
||||
}
|
||||
}
|
||||
obj[key] = obj[index];
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
function getTargetByPath(origin, path) {
|
||||
var arr = path.replace(/]/g, '').replace(/\[/g, '.').split('.');
|
||||
var current = origin;
|
||||
for (var i = 0, len = arr.length; i < len; i++) {
|
||||
current = current[arr[i]];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the given VNode, optionally adding attributes/props and replacing its
|
||||
* children.
|
||||
|
@ -497,14 +607,14 @@
|
|||
* @param {import('../dom').OmiElement} dom A DOM node to mutate into the shape of a `vnode`
|
||||
* @param {import('../vnode').VNode} vnode A VNode (with descendants forming a tree) representing
|
||||
* the desired DOM structure
|
||||
* @param {object} context The current context
|
||||
* @param {object} $ The current $
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
* @param {Element} parent ?
|
||||
* @param {boolean} componentRoot ?
|
||||
* @returns {import('../dom').OmiElement} The created/mutated element
|
||||
* @private
|
||||
*/
|
||||
function diff(dom, vnode, context, mountAll, parent, componentRoot, store) {
|
||||
function diff(dom, vnode, $, mountAll, parent, componentRoot, store) {
|
||||
// diffLevel having been 0 here indicates initial entry into the diff (not a subdiff)
|
||||
if (!diffLevel++) {
|
||||
// when first starting the diff, check if we're diffing an SVG or within an SVG
|
||||
|
@ -514,7 +624,7 @@
|
|||
hydrating = dom != null && !('prevProps' in dom);
|
||||
}
|
||||
|
||||
var ret = idiff(dom, vnode, context, mountAll, componentRoot, store);
|
||||
var ret = idiff(dom, vnode, $, mountAll, componentRoot, store);
|
||||
|
||||
// append the element if its a new parent
|
||||
if (parent && ret.parentNode !== parent) parent.appendChild(ret);
|
||||
|
@ -533,12 +643,12 @@
|
|||
* Internals of `diff()`, separated to allow bypassing diffLevel / mount flushing.
|
||||
* @param {import('../dom').OmiElement} dom A DOM node to mutate into the shape of a `vnode`
|
||||
* @param {import('../vnode').VNode} vnode A VNode (with descendants forming a tree) representing the desired DOM structure
|
||||
* @param {object} context The current context
|
||||
* @param {object} $ The current $
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
* @param {boolean} [componentRoot] ?
|
||||
* @private
|
||||
*/
|
||||
function idiff(dom, vnode, context, mountAll, componentRoot, store) {
|
||||
function idiff(dom, vnode, $, mountAll, componentRoot, store) {
|
||||
var out = dom,
|
||||
prevSvgMode = isSvgMode;
|
||||
|
||||
|
@ -571,7 +681,7 @@
|
|||
// If the VNode represents a Component, perform a component diff:
|
||||
var vnodeName = vnode.nodeName;
|
||||
if (typeof vnodeName === 'function') {
|
||||
return buildComponentFromVNode(dom, vnode, context, mountAll);
|
||||
return buildComponentFromVNode(dom, vnode, $, mountAll);
|
||||
}
|
||||
|
||||
// Tracks entering and exiting SVG namespace when descending through the tree.
|
||||
|
@ -613,7 +723,7 @@
|
|||
}
|
||||
// otherwise, if there are existing or new children, diff them:
|
||||
else if (vchildren && vchildren.length || fc != null) {
|
||||
innerDiffNode(out, vchildren, context, mountAll, hydrating || props.dangerouslySetInnerHTML != null, store);
|
||||
innerDiffNode(out, vchildren, $, mountAll, hydrating || props.dangerouslySetInnerHTML != null, store);
|
||||
}
|
||||
|
||||
// Apply attributes/props from VNode to the DOM Element:
|
||||
|
@ -629,13 +739,13 @@
|
|||
* Apply child and attribute changes between a VNode and a DOM Node to the DOM.
|
||||
* @param {import('../dom').OmiElement} dom Element whose children should be compared & mutated
|
||||
* @param {Array<import('../vnode').VNode>} vchildren Array of VNodes to compare to `dom.childNodes`
|
||||
* @param {object} context Implicitly descendant context object (from most
|
||||
* @param {object} $ Implicitly descendant $ object (from most
|
||||
* recent `getChildContext()`)
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
* @param {boolean} isHydrating if `true`, consumes externally created elements
|
||||
* similar to hydration
|
||||
*/
|
||||
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating, store) {
|
||||
function innerDiffNode(dom, vchildren, $, mountAll, isHydrating, store) {
|
||||
var originalChildren = dom.childNodes,
|
||||
children = [],
|
||||
keyed = {},
|
||||
|
@ -693,7 +803,7 @@
|
|||
}
|
||||
|
||||
// morph the matched/found/created DOM child to match vchild (deep)
|
||||
child = idiff(child, vchild, context, mountAll, null, store);
|
||||
child = idiff(child, vchild, $, mountAll, null, store);
|
||||
|
||||
f = originalChildren[i];
|
||||
if (child && child !== dom && child !== f) {
|
||||
|
@ -797,14 +907,14 @@
|
|||
* Components.
|
||||
* @param {function} Ctor The constructor of the component to create
|
||||
* @param {object} props The initial props of the component
|
||||
* @param {object} context The initial context of the component
|
||||
* @param {object} $ The initial $ of the component
|
||||
* @returns {import('../component').Component}
|
||||
*/
|
||||
function createComponent(Ctor, props, context) {
|
||||
function createComponent(Ctor, props, $) {
|
||||
var inst,
|
||||
i = recyclerComponents.length;
|
||||
|
||||
inst = new Component(props, context);
|
||||
inst = new Component(props, $);
|
||||
inst.constructor = Ctor;
|
||||
inst.render = doRender;
|
||||
if (Ctor.store) {
|
||||
|
@ -812,6 +922,20 @@
|
|||
inst.store.update = inst.update.bind(inst);
|
||||
}
|
||||
|
||||
if (inst.$ && inst.$.data) {
|
||||
|
||||
if (inst.constructor.use) {
|
||||
inst.constructor.updatePath = getPath(inst.constructor.use);
|
||||
inst.using = getUse(inst.$.data, inst.constructor.use);
|
||||
inst.$.instances.push(inst);
|
||||
} else if (inst.use) {
|
||||
var use = inst.use();
|
||||
inst._updatePath = getPath(use);
|
||||
inst.using = getUse(inst.$.data, use);
|
||||
inst.$.instances.push(inst);
|
||||
}
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
if (recyclerComponents[i].constructor === Ctor) {
|
||||
inst.nextBase = recyclerComponents[i].nextBase;
|
||||
|
@ -824,8 +948,8 @@
|
|||
}
|
||||
|
||||
/** The `.render()` method for a PFC backing instance. */
|
||||
function doRender(props, context) {
|
||||
return this.constructor(props, this.store, context);
|
||||
function doRender(props, $) {
|
||||
return this.constructor(props, this.store, $);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -833,10 +957,10 @@
|
|||
* @param {import('../component').Component} component The Component to set props on
|
||||
* @param {object} props The new props
|
||||
* @param {number} renderMode Render options - specifies how to re-render the component
|
||||
* @param {object} context The new context
|
||||
* @param {object} $ The new $
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
*/
|
||||
function setComponentProps(component, props, renderMode, context, mountAll) {
|
||||
function setComponentProps(component, props, renderMode, $, mountAll) {
|
||||
if (component._disable) return;
|
||||
component._disable = true;
|
||||
|
||||
|
@ -850,16 +974,15 @@
|
|||
if (component.store.install) component.store.install();
|
||||
} else {
|
||||
// if (component.componentWillReceiveProps) {
|
||||
// component.componentWillReceiveProps(props, context);
|
||||
// component.componentWillReceiveProps(props, $);
|
||||
// }
|
||||
if (component.store.receiveProps) {
|
||||
component.__needUpdate_ = component.store.receiveProps(props, context);
|
||||
component.__needUpdate_ = component.store.receiveProps(props, $);
|
||||
}
|
||||
}
|
||||
|
||||
if (context && context !== component.context) {
|
||||
if (!component.prevContext) component.prevContext = component.context;
|
||||
component.context = context;
|
||||
if ($ && $ !== component.$) {
|
||||
component.$ = $;
|
||||
}
|
||||
|
||||
if (!component.prevProps) component.prevProps = component.props;
|
||||
|
@ -891,15 +1014,13 @@
|
|||
if (component._disable) return;
|
||||
|
||||
var props = component.props,
|
||||
context = component.context,
|
||||
$ = component.$,
|
||||
previousProps = component.prevProps || props,
|
||||
previousContext = component.prevContext || context,
|
||||
isUpdate = component.base,
|
||||
nextBase = component.nextBase,
|
||||
initialBase = isUpdate || nextBase,
|
||||
initialChildComponent = component._component,
|
||||
skip = false,
|
||||
snapshot = previousContext,
|
||||
rendered,
|
||||
inst,
|
||||
cbase;
|
||||
|
@ -907,12 +1028,11 @@
|
|||
// if updating
|
||||
if (isUpdate) {
|
||||
component.props = previousProps;
|
||||
component.context = previousContext;
|
||||
|
||||
if (component.__needUpdate_ !== false) {
|
||||
skip = false;
|
||||
if (component.store.beforeUpdate) {
|
||||
component.store.beforeUpdate(props, context);
|
||||
component.store.beforeUpdate(props, $);
|
||||
}
|
||||
} else {
|
||||
skip = true;
|
||||
|
@ -920,7 +1040,6 @@
|
|||
delete component.__needUpdate_;
|
||||
|
||||
component.props = props;
|
||||
component.context = context;
|
||||
}
|
||||
|
||||
component.prevProps = component.prevContext = component.nextBase = null;
|
||||
|
@ -931,18 +1050,9 @@
|
|||
if (component.store.beforeRender) {
|
||||
component.store.beforeRender();
|
||||
}
|
||||
rendered = component.render(props, context);
|
||||
rendered = component.render(props, $);
|
||||
options.runTimeComponent = null;
|
||||
|
||||
// context to pass to the child, can be updated via (grand-)parent component
|
||||
if (component.getChildContext) {
|
||||
context = extend(extend({}, context), component.getChildContext());
|
||||
}
|
||||
|
||||
if (isUpdate && component.getSnapshotBeforeUpdate) {
|
||||
snapshot = component.getSnapshotBeforeUpdate(previousProps);
|
||||
}
|
||||
|
||||
var childComponent = rendered && rendered.nodeName,
|
||||
toUnmount,
|
||||
base;
|
||||
|
@ -954,14 +1064,14 @@
|
|||
inst = initialChildComponent;
|
||||
|
||||
if (inst && inst.constructor === childComponent && childProps.key == inst.__key) {
|
||||
setComponentProps(inst, childProps, 1, context, false);
|
||||
setComponentProps(inst, childProps, 1, $, false);
|
||||
} else {
|
||||
toUnmount = inst;
|
||||
|
||||
component._component = inst = createComponent(childComponent, childProps, context);
|
||||
component._component = inst = createComponent(childComponent, childProps, $);
|
||||
inst.nextBase = inst.nextBase || nextBase;
|
||||
inst._parentComponent = component;
|
||||
setComponentProps(inst, childProps, 0, context, false);
|
||||
setComponentProps(inst, childProps, 0, $, false);
|
||||
renderComponent(inst, 1, mountAll, true);
|
||||
}
|
||||
|
||||
|
@ -977,7 +1087,7 @@
|
|||
|
||||
if (initialBase || renderMode === 1) {
|
||||
if (cbase) cbase._component = null;
|
||||
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true, component.store);
|
||||
base = diff(cbase, rendered, $, mountAll || !isUpdate, initialBase && initialBase.parentNode, true, component.store);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1018,7 +1128,7 @@
|
|||
// flushMounts();
|
||||
|
||||
if (component.store.updated) {
|
||||
component.store.updated(previousProps, snapshot);
|
||||
component.store.updated(previousProps);
|
||||
}
|
||||
if (options.afterUpdate) options.afterUpdate(component);
|
||||
}
|
||||
|
@ -1032,12 +1142,12 @@
|
|||
* Apply the Component referenced by a VNode to the DOM.
|
||||
* @param {import('../dom').OmiElement} dom The DOM node to mutate
|
||||
* @param {import('../vnode').VNode} vnode A Component-referencing VNode
|
||||
* @param {object} context The current context
|
||||
* @param {object} $ The current $
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
* @returns {import('../dom').OmiElement} The created/mutated element
|
||||
* @private
|
||||
*/
|
||||
function buildComponentFromVNode(dom, vnode, context, mountAll) {
|
||||
function buildComponentFromVNode(dom, vnode, $, mountAll) {
|
||||
var c = dom && dom._component,
|
||||
originalComponent = c,
|
||||
oldDom = dom,
|
||||
|
@ -1049,7 +1159,7 @@
|
|||
}
|
||||
|
||||
if (c && isOwner && (!mountAll || c._component)) {
|
||||
setComponentProps(c, props, 3, context, mountAll);
|
||||
setComponentProps(c, props, 3, $, mountAll);
|
||||
dom = c.base;
|
||||
} else {
|
||||
if (originalComponent && !isDirectOwner) {
|
||||
|
@ -1057,13 +1167,13 @@
|
|||
dom = oldDom = null;
|
||||
}
|
||||
|
||||
c = createComponent(vnode.nodeName, props, context);
|
||||
c = createComponent(vnode.nodeName, props, $);
|
||||
if (dom && !c.nextBase) {
|
||||
c.nextBase = dom;
|
||||
// passing dom/oldDom as nextBase will recycle it if unused, so bypass recycling on L229:
|
||||
oldDom = null;
|
||||
}
|
||||
setComponentProps(c, props, 1, context, mountAll);
|
||||
setComponentProps(c, props, 1, $, mountAll);
|
||||
dom = c.base;
|
||||
|
||||
if (oldDom && dom !== oldDom) {
|
||||
|
@ -1127,15 +1237,15 @@
|
|||
|
||||
var id = 0;
|
||||
|
||||
function Component(props, context) {
|
||||
function Component(props, $) {
|
||||
this._dirty = true;
|
||||
this.elementId = id++;
|
||||
/**
|
||||
* @public
|
||||
* @type {object}
|
||||
*/
|
||||
this.context = context;
|
||||
this.store = {};
|
||||
this.$ = $;
|
||||
/**
|
||||
* @public
|
||||
* @type {object}
|
||||
|
@ -1171,6 +1281,182 @@
|
|||
render: function render() {}
|
||||
});
|
||||
|
||||
/*
|
||||
* obaa 2.0.3
|
||||
* By dntzhang
|
||||
* Github: https://github.com/Tencent/omi/tree/master/packages/obaa
|
||||
* MIT Licensed.
|
||||
*/
|
||||
|
||||
// __r_: root
|
||||
// __c_: prop change callback
|
||||
// __p_: path
|
||||
|
||||
function obaa(target, arr, callback) {
|
||||
|
||||
var eventPropArr = [];
|
||||
if (isArray(target)) {
|
||||
if (target.length === 0) {
|
||||
target.__o_ = {
|
||||
__r_: target,
|
||||
__p_: '#'
|
||||
};
|
||||
}
|
||||
mock(target, target);
|
||||
}
|
||||
for (var prop in target) {
|
||||
if (target.hasOwnProperty(prop)) {
|
||||
if (callback) {
|
||||
if (isArray(arr) && isInArray(arr, prop)) {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
} else if (isString(arr) && prop == arr) {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
}
|
||||
} else {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!target.__c_) {
|
||||
target.__c_ = [];
|
||||
}
|
||||
var propChanged = callback ? callback : arr;
|
||||
target.__c_.push({
|
||||
all: !callback,
|
||||
propChanged: propChanged,
|
||||
eventPropArr: eventPropArr
|
||||
});
|
||||
}
|
||||
|
||||
var triggerStr = ['concat', 'copyWithin', 'fill', 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'size'].join(',');
|
||||
|
||||
var methods = ['concat', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values', 'size'];
|
||||
|
||||
function mock(target, root) {
|
||||
methods.forEach(function (item) {
|
||||
target[item] = function () {
|
||||
var old = Array.prototype.slice.call(this, 0);
|
||||
var result = Array.prototype[item].apply(this, Array.prototype.slice.call(arguments));
|
||||
if (new RegExp('\\b' + item + '\\b').test(triggerStr)) {
|
||||
for (var cprop in this) {
|
||||
if (this.hasOwnProperty(cprop) && !isFunction(this[cprop])) {
|
||||
watch(this, cprop, this.__o_.__p_, root);
|
||||
}
|
||||
}
|
||||
//todo
|
||||
onPropertyChanged('Array-' + item, this, old, this, this.__o_.__p_, root);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
target['pure' + item.substring(0, 1).toUpperCase() + item.substring(1)] = function () {
|
||||
return Array.prototype[item].apply(this, Array.prototype.slice.call(arguments));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function watch(target, prop, path, root) {
|
||||
if (prop === '__o_') return;
|
||||
if (isFunction(target[prop])) return;
|
||||
if (!target.__o_) target.__o_ = {
|
||||
__r_: root
|
||||
};
|
||||
if (path !== undefined && path !== null) {
|
||||
target.__o_.__p_ = path;
|
||||
} else {
|
||||
target.__o_.__p_ = '#';
|
||||
}
|
||||
|
||||
var currentValue = target.__o_[prop] = target[prop];
|
||||
Object.defineProperty(target, prop, {
|
||||
get: function get() {
|
||||
return this.__o_[prop];
|
||||
},
|
||||
set: function set(value) {
|
||||
var old = this.__o_[prop];
|
||||
this.__o_[prop] = value;
|
||||
onPropertyChanged(prop, value, old, this, target.__o_.__p_, root);
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
if (typeof currentValue == 'object') {
|
||||
if (isArray(currentValue)) {
|
||||
mock(currentValue, root);
|
||||
if (currentValue.length === 0) {
|
||||
if (!currentValue.__o_) currentValue.__o_ = {};
|
||||
if (path !== undefined && path !== null) {
|
||||
currentValue.__o_.__p_ = path + '-' + prop;
|
||||
} else {
|
||||
currentValue.__o_.__p_ = '#' + '-' + prop;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var cprop in currentValue) {
|
||||
if (currentValue.hasOwnProperty(cprop)) {
|
||||
watch(currentValue, cprop, target.__o_.__p_ + '-' + prop, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onPropertyChanged(prop, value, oldValue, target, path, root) {
|
||||
if (value !== oldValue && root.__c_) {
|
||||
var rootName = getRootName(prop, path);
|
||||
for (var i = 0, len = root.__c_.length; i < len; i++) {
|
||||
var handler = root.__c_[i];
|
||||
if (handler.all || isInArray(handler.eventPropArr, rootName) || rootName.indexOf('Array-') === 0) {
|
||||
handler.propChanged.call(target, prop, value, oldValue, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.indexOf('Array-') !== 0 && typeof value === 'object') {
|
||||
watch(target, prop, target.__o_.__p_, root);
|
||||
}
|
||||
}
|
||||
|
||||
function isFunction(obj) {
|
||||
return Object.prototype.toString.call(obj) == '[object Function]';
|
||||
}
|
||||
|
||||
function isArray(obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Array]';
|
||||
}
|
||||
|
||||
function isString(obj) {
|
||||
return typeof obj === 'string';
|
||||
}
|
||||
|
||||
function isInArray(arr, item) {
|
||||
for (var i = arr.length; --i > -1;) {
|
||||
if (item === arr[i]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRootName(prop, path) {
|
||||
if (path === '#') {
|
||||
return prop;
|
||||
}
|
||||
return path.split('-')[1];
|
||||
}
|
||||
|
||||
obaa.add = function (obj, prop) {
|
||||
watch(obj, prop, obj.__o_.__p_, obj.__o_.__r_);
|
||||
};
|
||||
|
||||
obaa.set = function (obj, prop, value) {
|
||||
watch(obj, prop, obj.__o_.__p_, obj.__o_.__r_);
|
||||
obj[prop] = value;
|
||||
};
|
||||
|
||||
Array.prototype.size = function (length) {
|
||||
this.length = length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render JSX into a `parent` Element.
|
||||
* @param {import('./vnode').VNode} vnode A (JSX) VNode to render
|
||||
|
@ -1188,8 +1474,103 @@
|
|||
* const Thing = ({ name }) => <span>{ name }</span>;
|
||||
* render(<Thing name="one" />, document.querySelector('#foo'));
|
||||
*/
|
||||
function render(vnode, parent, merge) {
|
||||
return diff(merge, vnode, {}, false, typeof parent === 'string' ? document.querySelector(parent) : parent, false);
|
||||
function render(vnode, parent, globalStore) {
|
||||
obsStore(globalStore);
|
||||
return diff(null, vnode, globalStore, false, typeof parent === 'string' ? document.querySelector(parent) : parent, false);
|
||||
}
|
||||
|
||||
function obsStore(store) {
|
||||
if (store && store.data) {
|
||||
store.instances = [];
|
||||
extendStoreUpate(store);
|
||||
|
||||
obaa(store.data, function (prop, val, old, path) {
|
||||
var patchs = {};
|
||||
var key = fixPath(path + '-' + prop);
|
||||
patchs[key] = true;
|
||||
store.update(patchs);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function extendStoreUpate(store) {
|
||||
store.update = function (patch) {
|
||||
var _this = this;
|
||||
|
||||
var updateAll = matchGlobalData(this.globalData, patch);
|
||||
if (Object.keys(patch).length > 0) {
|
||||
|
||||
this.instances.forEach(function (instance) {
|
||||
if (updateAll || _this.updateAll || instance.constructor.updatePath && needUpdate(patch, instance.constructor.updatePath) || instance._updatePath && needUpdate(patch, instance._updatePath)) {
|
||||
//update this.using
|
||||
if (instance.constructor.use) {
|
||||
instance.using = getUse(store.data, instance.constructor.use);
|
||||
} else if (instance.use) {
|
||||
instance.using = getUse(store.data, instance.initUse());
|
||||
}
|
||||
|
||||
instance.update();
|
||||
}
|
||||
});
|
||||
this.onChange && this.onChange(patch);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function matchGlobalData(globalData, diffResult) {
|
||||
if (!globalData) return false;
|
||||
for (var keyA in diffResult) {
|
||||
if (globalData.indexOf(keyA) > -1) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0, len = globalData.length; i < len; i++) {
|
||||
if (includePath(keyA, globalData[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function needUpdate(diffResult, updatePath) {
|
||||
for (var keyA in diffResult) {
|
||||
if (updatePath[keyA]) {
|
||||
return true;
|
||||
}
|
||||
for (var keyB in updatePath) {
|
||||
if (includePath(keyA, keyB)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function includePath(pathA, pathB) {
|
||||
if (pathA.indexOf(pathB) === 0) {
|
||||
var next = pathA.substr(pathB.length, 1);
|
||||
if (next === '[' || next === '.') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function fixPath(path) {
|
||||
var mpPath = '';
|
||||
var arr = path.replace('#-', '').split('-');
|
||||
arr.forEach(function (item, index) {
|
||||
if (index) {
|
||||
if (isNaN(Number(item))) {
|
||||
mpPath += '.' + item;
|
||||
} else {
|
||||
mpPath += '[' + item + ']';
|
||||
}
|
||||
} else {
|
||||
mpPath += item;
|
||||
}
|
||||
});
|
||||
return mpPath;
|
||||
}
|
||||
|
||||
function createRef() {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* omis v0.6.0 http://omijs.org
|
||||
* omis v0.7.0 http://omijs.org
|
||||
* Omi === Preact + Scoped CSS + Store System + Native Support in 3kb javascript.
|
||||
* By dntzhang https://github.com/dntzhang
|
||||
* Github: https://github.com/Tencent/omis
|
||||
|
@ -246,6 +246,116 @@ function applyRef(ref, value) {
|
|||
*/
|
||||
var defer = typeof Promise == 'function' ? Promise.resolve().then.bind(Promise.resolve()) : setTimeout;
|
||||
|
||||
function getPath(obj) {
|
||||
if (Object.prototype.toString.call(obj) === '[object Array]') {
|
||||
var result = {};
|
||||
obj.forEach(function (item) {
|
||||
if (typeof item === 'string') {
|
||||
result[item] = true;
|
||||
} else {
|
||||
var tempPath = item[Object.keys(item)[0]];
|
||||
if (typeof tempPath === 'string') {
|
||||
result[tempPath] = true;
|
||||
} else {
|
||||
if (typeof tempPath[0] === 'string') {
|
||||
result[tempPath[0]] = true;
|
||||
} else {
|
||||
tempPath[0].forEach(function (path) {
|
||||
return result[path] = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} else {
|
||||
return getUpdatePath(obj);
|
||||
}
|
||||
}
|
||||
|
||||
function getUpdatePath(data) {
|
||||
var result = {};
|
||||
dataToPath(data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function dataToPath(data, result) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[key] = true;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(data[key], key, result);
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(data[key], key, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _objToPath(data, path, result) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[path + '.' + key] = true;
|
||||
delete result[path];
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(data[key], path + '.' + key, result);
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(data[key], path + '.' + key, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _arrayToPath(data, path, result) {
|
||||
data.forEach(function (item, index) {
|
||||
result[path + '[' + index + ']'] = true;
|
||||
delete result[path];
|
||||
var type = Object.prototype.toString.call(item);
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(item, path + '[' + index + ']', result);
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(item, path + '[' + index + ']', result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getUse(data, paths) {
|
||||
var obj = [];
|
||||
paths.forEach(function (path, index) {
|
||||
var isPath = typeof path === 'string';
|
||||
if (isPath) {
|
||||
obj[index] = getTargetByPath(data, path);
|
||||
} else {
|
||||
var key = Object.keys(path)[0];
|
||||
var value = path[key];
|
||||
if (typeof value === 'string') {
|
||||
obj[index] = getTargetByPath(data, value);
|
||||
} else {
|
||||
var tempPath = value[0];
|
||||
if (typeof tempPath === 'string') {
|
||||
var tempVal = getTargetByPath(data, tempPath);
|
||||
obj[index] = value[1] ? value[1](tempVal) : tempVal;
|
||||
} else {
|
||||
var args = [];
|
||||
tempPath.forEach(function (path) {
|
||||
args.push(getTargetByPath(data, path));
|
||||
});
|
||||
obj[index] = value[1].apply(null, args);
|
||||
}
|
||||
}
|
||||
obj[key] = obj[index];
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
function getTargetByPath(origin, path) {
|
||||
var arr = path.replace(/]/g, '').replace(/\[/g, '.').split('.');
|
||||
var current = origin;
|
||||
for (var i = 0, len = arr.length; i < len; i++) {
|
||||
current = current[arr[i]];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the given VNode, optionally adding attributes/props and replacing its
|
||||
* children.
|
||||
|
@ -494,14 +604,14 @@ function flushMounts() {
|
|||
* @param {import('../dom').OmiElement} dom A DOM node to mutate into the shape of a `vnode`
|
||||
* @param {import('../vnode').VNode} vnode A VNode (with descendants forming a tree) representing
|
||||
* the desired DOM structure
|
||||
* @param {object} context The current context
|
||||
* @param {object} $ The current $
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
* @param {Element} parent ?
|
||||
* @param {boolean} componentRoot ?
|
||||
* @returns {import('../dom').OmiElement} The created/mutated element
|
||||
* @private
|
||||
*/
|
||||
function diff(dom, vnode, context, mountAll, parent, componentRoot, store) {
|
||||
function diff(dom, vnode, $, mountAll, parent, componentRoot, store) {
|
||||
// diffLevel having been 0 here indicates initial entry into the diff (not a subdiff)
|
||||
if (!diffLevel++) {
|
||||
// when first starting the diff, check if we're diffing an SVG or within an SVG
|
||||
|
@ -511,7 +621,7 @@ function diff(dom, vnode, context, mountAll, parent, componentRoot, store) {
|
|||
hydrating = dom != null && !('prevProps' in dom);
|
||||
}
|
||||
|
||||
var ret = idiff(dom, vnode, context, mountAll, componentRoot, store);
|
||||
var ret = idiff(dom, vnode, $, mountAll, componentRoot, store);
|
||||
|
||||
// append the element if its a new parent
|
||||
if (parent && ret.parentNode !== parent) parent.appendChild(ret);
|
||||
|
@ -530,12 +640,12 @@ function diff(dom, vnode, context, mountAll, parent, componentRoot, store) {
|
|||
* Internals of `diff()`, separated to allow bypassing diffLevel / mount flushing.
|
||||
* @param {import('../dom').OmiElement} dom A DOM node to mutate into the shape of a `vnode`
|
||||
* @param {import('../vnode').VNode} vnode A VNode (with descendants forming a tree) representing the desired DOM structure
|
||||
* @param {object} context The current context
|
||||
* @param {object} $ The current $
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
* @param {boolean} [componentRoot] ?
|
||||
* @private
|
||||
*/
|
||||
function idiff(dom, vnode, context, mountAll, componentRoot, store) {
|
||||
function idiff(dom, vnode, $, mountAll, componentRoot, store) {
|
||||
var out = dom,
|
||||
prevSvgMode = isSvgMode;
|
||||
|
||||
|
@ -568,7 +678,7 @@ function idiff(dom, vnode, context, mountAll, componentRoot, store) {
|
|||
// If the VNode represents a Component, perform a component diff:
|
||||
var vnodeName = vnode.nodeName;
|
||||
if (typeof vnodeName === 'function') {
|
||||
return buildComponentFromVNode(dom, vnode, context, mountAll);
|
||||
return buildComponentFromVNode(dom, vnode, $, mountAll);
|
||||
}
|
||||
|
||||
// Tracks entering and exiting SVG namespace when descending through the tree.
|
||||
|
@ -610,7 +720,7 @@ function idiff(dom, vnode, context, mountAll, componentRoot, store) {
|
|||
}
|
||||
// otherwise, if there are existing or new children, diff them:
|
||||
else if (vchildren && vchildren.length || fc != null) {
|
||||
innerDiffNode(out, vchildren, context, mountAll, hydrating || props.dangerouslySetInnerHTML != null, store);
|
||||
innerDiffNode(out, vchildren, $, mountAll, hydrating || props.dangerouslySetInnerHTML != null, store);
|
||||
}
|
||||
|
||||
// Apply attributes/props from VNode to the DOM Element:
|
||||
|
@ -626,13 +736,13 @@ function idiff(dom, vnode, context, mountAll, componentRoot, store) {
|
|||
* Apply child and attribute changes between a VNode and a DOM Node to the DOM.
|
||||
* @param {import('../dom').OmiElement} dom Element whose children should be compared & mutated
|
||||
* @param {Array<import('../vnode').VNode>} vchildren Array of VNodes to compare to `dom.childNodes`
|
||||
* @param {object} context Implicitly descendant context object (from most
|
||||
* @param {object} $ Implicitly descendant $ object (from most
|
||||
* recent `getChildContext()`)
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
* @param {boolean} isHydrating if `true`, consumes externally created elements
|
||||
* similar to hydration
|
||||
*/
|
||||
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating, store) {
|
||||
function innerDiffNode(dom, vchildren, $, mountAll, isHydrating, store) {
|
||||
var originalChildren = dom.childNodes,
|
||||
children = [],
|
||||
keyed = {},
|
||||
|
@ -690,7 +800,7 @@ function innerDiffNode(dom, vchildren, context, mountAll, isHydrating, store) {
|
|||
}
|
||||
|
||||
// morph the matched/found/created DOM child to match vchild (deep)
|
||||
child = idiff(child, vchild, context, mountAll, null, store);
|
||||
child = idiff(child, vchild, $, mountAll, null, store);
|
||||
|
||||
f = originalChildren[i];
|
||||
if (child && child !== dom && child !== f) {
|
||||
|
@ -794,14 +904,14 @@ var recyclerComponents = [];
|
|||
* Components.
|
||||
* @param {function} Ctor The constructor of the component to create
|
||||
* @param {object} props The initial props of the component
|
||||
* @param {object} context The initial context of the component
|
||||
* @param {object} $ The initial $ of the component
|
||||
* @returns {import('../component').Component}
|
||||
*/
|
||||
function createComponent(Ctor, props, context) {
|
||||
function createComponent(Ctor, props, $) {
|
||||
var inst,
|
||||
i = recyclerComponents.length;
|
||||
|
||||
inst = new Component(props, context);
|
||||
inst = new Component(props, $);
|
||||
inst.constructor = Ctor;
|
||||
inst.render = doRender;
|
||||
if (Ctor.store) {
|
||||
|
@ -809,6 +919,20 @@ function createComponent(Ctor, props, context) {
|
|||
inst.store.update = inst.update.bind(inst);
|
||||
}
|
||||
|
||||
if (inst.$ && inst.$.data) {
|
||||
|
||||
if (inst.constructor.use) {
|
||||
inst.constructor.updatePath = getPath(inst.constructor.use);
|
||||
inst.using = getUse(inst.$.data, inst.constructor.use);
|
||||
inst.$.instances.push(inst);
|
||||
} else if (inst.use) {
|
||||
var use = inst.use();
|
||||
inst._updatePath = getPath(use);
|
||||
inst.using = getUse(inst.$.data, use);
|
||||
inst.$.instances.push(inst);
|
||||
}
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
if (recyclerComponents[i].constructor === Ctor) {
|
||||
inst.nextBase = recyclerComponents[i].nextBase;
|
||||
|
@ -821,8 +945,8 @@ function createComponent(Ctor, props, context) {
|
|||
}
|
||||
|
||||
/** The `.render()` method for a PFC backing instance. */
|
||||
function doRender(props, context) {
|
||||
return this.constructor(props, this.store, context);
|
||||
function doRender(props, $) {
|
||||
return this.constructor(props, this.store, $);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -830,10 +954,10 @@ function doRender(props, context) {
|
|||
* @param {import('../component').Component} component The Component to set props on
|
||||
* @param {object} props The new props
|
||||
* @param {number} renderMode Render options - specifies how to re-render the component
|
||||
* @param {object} context The new context
|
||||
* @param {object} $ The new $
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
*/
|
||||
function setComponentProps(component, props, renderMode, context, mountAll) {
|
||||
function setComponentProps(component, props, renderMode, $, mountAll) {
|
||||
if (component._disable) return;
|
||||
component._disable = true;
|
||||
|
||||
|
@ -847,16 +971,15 @@ function setComponentProps(component, props, renderMode, context, mountAll) {
|
|||
if (component.store.install) component.store.install();
|
||||
} else {
|
||||
// if (component.componentWillReceiveProps) {
|
||||
// component.componentWillReceiveProps(props, context);
|
||||
// component.componentWillReceiveProps(props, $);
|
||||
// }
|
||||
if (component.store.receiveProps) {
|
||||
component.__needUpdate_ = component.store.receiveProps(props, context);
|
||||
component.__needUpdate_ = component.store.receiveProps(props, $);
|
||||
}
|
||||
}
|
||||
|
||||
if (context && context !== component.context) {
|
||||
if (!component.prevContext) component.prevContext = component.context;
|
||||
component.context = context;
|
||||
if ($ && $ !== component.$) {
|
||||
component.$ = $;
|
||||
}
|
||||
|
||||
if (!component.prevProps) component.prevProps = component.props;
|
||||
|
@ -888,15 +1011,13 @@ function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
if (component._disable) return;
|
||||
|
||||
var props = component.props,
|
||||
context = component.context,
|
||||
$ = component.$,
|
||||
previousProps = component.prevProps || props,
|
||||
previousContext = component.prevContext || context,
|
||||
isUpdate = component.base,
|
||||
nextBase = component.nextBase,
|
||||
initialBase = isUpdate || nextBase,
|
||||
initialChildComponent = component._component,
|
||||
skip = false,
|
||||
snapshot = previousContext,
|
||||
rendered,
|
||||
inst,
|
||||
cbase;
|
||||
|
@ -904,12 +1025,11 @@ function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
// if updating
|
||||
if (isUpdate) {
|
||||
component.props = previousProps;
|
||||
component.context = previousContext;
|
||||
|
||||
if (component.__needUpdate_ !== false) {
|
||||
skip = false;
|
||||
if (component.store.beforeUpdate) {
|
||||
component.store.beforeUpdate(props, context);
|
||||
component.store.beforeUpdate(props, $);
|
||||
}
|
||||
} else {
|
||||
skip = true;
|
||||
|
@ -917,7 +1037,6 @@ function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
delete component.__needUpdate_;
|
||||
|
||||
component.props = props;
|
||||
component.context = context;
|
||||
}
|
||||
|
||||
component.prevProps = component.prevContext = component.nextBase = null;
|
||||
|
@ -928,18 +1047,9 @@ function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
if (component.store.beforeRender) {
|
||||
component.store.beforeRender();
|
||||
}
|
||||
rendered = component.render(props, context);
|
||||
rendered = component.render(props, $);
|
||||
options.runTimeComponent = null;
|
||||
|
||||
// context to pass to the child, can be updated via (grand-)parent component
|
||||
if (component.getChildContext) {
|
||||
context = extend(extend({}, context), component.getChildContext());
|
||||
}
|
||||
|
||||
if (isUpdate && component.getSnapshotBeforeUpdate) {
|
||||
snapshot = component.getSnapshotBeforeUpdate(previousProps);
|
||||
}
|
||||
|
||||
var childComponent = rendered && rendered.nodeName,
|
||||
toUnmount,
|
||||
base;
|
||||
|
@ -951,14 +1061,14 @@ function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
inst = initialChildComponent;
|
||||
|
||||
if (inst && inst.constructor === childComponent && childProps.key == inst.__key) {
|
||||
setComponentProps(inst, childProps, 1, context, false);
|
||||
setComponentProps(inst, childProps, 1, $, false);
|
||||
} else {
|
||||
toUnmount = inst;
|
||||
|
||||
component._component = inst = createComponent(childComponent, childProps, context);
|
||||
component._component = inst = createComponent(childComponent, childProps, $);
|
||||
inst.nextBase = inst.nextBase || nextBase;
|
||||
inst._parentComponent = component;
|
||||
setComponentProps(inst, childProps, 0, context, false);
|
||||
setComponentProps(inst, childProps, 0, $, false);
|
||||
renderComponent(inst, 1, mountAll, true);
|
||||
}
|
||||
|
||||
|
@ -974,7 +1084,7 @@ function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
|
||||
if (initialBase || renderMode === 1) {
|
||||
if (cbase) cbase._component = null;
|
||||
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true, component.store);
|
||||
base = diff(cbase, rendered, $, mountAll || !isUpdate, initialBase && initialBase.parentNode, true, component.store);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1015,7 +1125,7 @@ function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
// flushMounts();
|
||||
|
||||
if (component.store.updated) {
|
||||
component.store.updated(previousProps, snapshot);
|
||||
component.store.updated(previousProps);
|
||||
}
|
||||
if (options.afterUpdate) options.afterUpdate(component);
|
||||
}
|
||||
|
@ -1029,12 +1139,12 @@ function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
* Apply the Component referenced by a VNode to the DOM.
|
||||
* @param {import('../dom').OmiElement} dom The DOM node to mutate
|
||||
* @param {import('../vnode').VNode} vnode A Component-referencing VNode
|
||||
* @param {object} context The current context
|
||||
* @param {object} $ The current $
|
||||
* @param {boolean} mountAll Whether or not to immediately mount all components
|
||||
* @returns {import('../dom').OmiElement} The created/mutated element
|
||||
* @private
|
||||
*/
|
||||
function buildComponentFromVNode(dom, vnode, context, mountAll) {
|
||||
function buildComponentFromVNode(dom, vnode, $, mountAll) {
|
||||
var c = dom && dom._component,
|
||||
originalComponent = c,
|
||||
oldDom = dom,
|
||||
|
@ -1046,7 +1156,7 @@ function buildComponentFromVNode(dom, vnode, context, mountAll) {
|
|||
}
|
||||
|
||||
if (c && isOwner && (!mountAll || c._component)) {
|
||||
setComponentProps(c, props, 3, context, mountAll);
|
||||
setComponentProps(c, props, 3, $, mountAll);
|
||||
dom = c.base;
|
||||
} else {
|
||||
if (originalComponent && !isDirectOwner) {
|
||||
|
@ -1054,13 +1164,13 @@ function buildComponentFromVNode(dom, vnode, context, mountAll) {
|
|||
dom = oldDom = null;
|
||||
}
|
||||
|
||||
c = createComponent(vnode.nodeName, props, context);
|
||||
c = createComponent(vnode.nodeName, props, $);
|
||||
if (dom && !c.nextBase) {
|
||||
c.nextBase = dom;
|
||||
// passing dom/oldDom as nextBase will recycle it if unused, so bypass recycling on L229:
|
||||
oldDom = null;
|
||||
}
|
||||
setComponentProps(c, props, 1, context, mountAll);
|
||||
setComponentProps(c, props, 1, $, mountAll);
|
||||
dom = c.base;
|
||||
|
||||
if (oldDom && dom !== oldDom) {
|
||||
|
@ -1124,15 +1234,15 @@ function unmountComponent(component) {
|
|||
|
||||
var id = 0;
|
||||
|
||||
function Component(props, context) {
|
||||
function Component(props, $) {
|
||||
this._dirty = true;
|
||||
this.elementId = id++;
|
||||
/**
|
||||
* @public
|
||||
* @type {object}
|
||||
*/
|
||||
this.context = context;
|
||||
this.store = {};
|
||||
this.$ = $;
|
||||
/**
|
||||
* @public
|
||||
* @type {object}
|
||||
|
@ -1168,6 +1278,182 @@ extend(Component.prototype, {
|
|||
render: function render() {}
|
||||
});
|
||||
|
||||
/*
|
||||
* obaa 2.0.3
|
||||
* By dntzhang
|
||||
* Github: https://github.com/Tencent/omi/tree/master/packages/obaa
|
||||
* MIT Licensed.
|
||||
*/
|
||||
|
||||
// __r_: root
|
||||
// __c_: prop change callback
|
||||
// __p_: path
|
||||
|
||||
function obaa(target, arr, callback) {
|
||||
|
||||
var eventPropArr = [];
|
||||
if (isArray(target)) {
|
||||
if (target.length === 0) {
|
||||
target.__o_ = {
|
||||
__r_: target,
|
||||
__p_: '#'
|
||||
};
|
||||
}
|
||||
mock(target, target);
|
||||
}
|
||||
for (var prop in target) {
|
||||
if (target.hasOwnProperty(prop)) {
|
||||
if (callback) {
|
||||
if (isArray(arr) && isInArray(arr, prop)) {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
} else if (isString(arr) && prop == arr) {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
}
|
||||
} else {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!target.__c_) {
|
||||
target.__c_ = [];
|
||||
}
|
||||
var propChanged = callback ? callback : arr;
|
||||
target.__c_.push({
|
||||
all: !callback,
|
||||
propChanged: propChanged,
|
||||
eventPropArr: eventPropArr
|
||||
});
|
||||
}
|
||||
|
||||
var triggerStr = ['concat', 'copyWithin', 'fill', 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'size'].join(',');
|
||||
|
||||
var methods = ['concat', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values', 'size'];
|
||||
|
||||
function mock(target, root) {
|
||||
methods.forEach(function (item) {
|
||||
target[item] = function () {
|
||||
var old = Array.prototype.slice.call(this, 0);
|
||||
var result = Array.prototype[item].apply(this, Array.prototype.slice.call(arguments));
|
||||
if (new RegExp('\\b' + item + '\\b').test(triggerStr)) {
|
||||
for (var cprop in this) {
|
||||
if (this.hasOwnProperty(cprop) && !isFunction(this[cprop])) {
|
||||
watch(this, cprop, this.__o_.__p_, root);
|
||||
}
|
||||
}
|
||||
//todo
|
||||
onPropertyChanged('Array-' + item, this, old, this, this.__o_.__p_, root);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
target['pure' + item.substring(0, 1).toUpperCase() + item.substring(1)] = function () {
|
||||
return Array.prototype[item].apply(this, Array.prototype.slice.call(arguments));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function watch(target, prop, path, root) {
|
||||
if (prop === '__o_') return;
|
||||
if (isFunction(target[prop])) return;
|
||||
if (!target.__o_) target.__o_ = {
|
||||
__r_: root
|
||||
};
|
||||
if (path !== undefined && path !== null) {
|
||||
target.__o_.__p_ = path;
|
||||
} else {
|
||||
target.__o_.__p_ = '#';
|
||||
}
|
||||
|
||||
var currentValue = target.__o_[prop] = target[prop];
|
||||
Object.defineProperty(target, prop, {
|
||||
get: function get() {
|
||||
return this.__o_[prop];
|
||||
},
|
||||
set: function set(value) {
|
||||
var old = this.__o_[prop];
|
||||
this.__o_[prop] = value;
|
||||
onPropertyChanged(prop, value, old, this, target.__o_.__p_, root);
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
if (typeof currentValue == 'object') {
|
||||
if (isArray(currentValue)) {
|
||||
mock(currentValue, root);
|
||||
if (currentValue.length === 0) {
|
||||
if (!currentValue.__o_) currentValue.__o_ = {};
|
||||
if (path !== undefined && path !== null) {
|
||||
currentValue.__o_.__p_ = path + '-' + prop;
|
||||
} else {
|
||||
currentValue.__o_.__p_ = '#' + '-' + prop;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var cprop in currentValue) {
|
||||
if (currentValue.hasOwnProperty(cprop)) {
|
||||
watch(currentValue, cprop, target.__o_.__p_ + '-' + prop, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onPropertyChanged(prop, value, oldValue, target, path, root) {
|
||||
if (value !== oldValue && root.__c_) {
|
||||
var rootName = getRootName(prop, path);
|
||||
for (var i = 0, len = root.__c_.length; i < len; i++) {
|
||||
var handler = root.__c_[i];
|
||||
if (handler.all || isInArray(handler.eventPropArr, rootName) || rootName.indexOf('Array-') === 0) {
|
||||
handler.propChanged.call(target, prop, value, oldValue, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.indexOf('Array-') !== 0 && typeof value === 'object') {
|
||||
watch(target, prop, target.__o_.__p_, root);
|
||||
}
|
||||
}
|
||||
|
||||
function isFunction(obj) {
|
||||
return Object.prototype.toString.call(obj) == '[object Function]';
|
||||
}
|
||||
|
||||
function isArray(obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Array]';
|
||||
}
|
||||
|
||||
function isString(obj) {
|
||||
return typeof obj === 'string';
|
||||
}
|
||||
|
||||
function isInArray(arr, item) {
|
||||
for (var i = arr.length; --i > -1;) {
|
||||
if (item === arr[i]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRootName(prop, path) {
|
||||
if (path === '#') {
|
||||
return prop;
|
||||
}
|
||||
return path.split('-')[1];
|
||||
}
|
||||
|
||||
obaa.add = function (obj, prop) {
|
||||
watch(obj, prop, obj.__o_.__p_, obj.__o_.__r_);
|
||||
};
|
||||
|
||||
obaa.set = function (obj, prop, value) {
|
||||
watch(obj, prop, obj.__o_.__p_, obj.__o_.__r_);
|
||||
obj[prop] = value;
|
||||
};
|
||||
|
||||
Array.prototype.size = function (length) {
|
||||
this.length = length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render JSX into a `parent` Element.
|
||||
* @param {import('./vnode').VNode} vnode A (JSX) VNode to render
|
||||
|
@ -1185,8 +1471,103 @@ extend(Component.prototype, {
|
|||
* const Thing = ({ name }) => <span>{ name }</span>;
|
||||
* render(<Thing name="one" />, document.querySelector('#foo'));
|
||||
*/
|
||||
function render(vnode, parent, merge) {
|
||||
return diff(merge, vnode, {}, false, typeof parent === 'string' ? document.querySelector(parent) : parent, false);
|
||||
function render(vnode, parent, globalStore) {
|
||||
obsStore(globalStore);
|
||||
return diff(null, vnode, globalStore, false, typeof parent === 'string' ? document.querySelector(parent) : parent, false);
|
||||
}
|
||||
|
||||
function obsStore(store) {
|
||||
if (store && store.data) {
|
||||
store.instances = [];
|
||||
extendStoreUpate(store);
|
||||
|
||||
obaa(store.data, function (prop, val, old, path) {
|
||||
var patchs = {};
|
||||
var key = fixPath(path + '-' + prop);
|
||||
patchs[key] = true;
|
||||
store.update(patchs);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function extendStoreUpate(store) {
|
||||
store.update = function (patch) {
|
||||
var _this = this;
|
||||
|
||||
var updateAll = matchGlobalData(this.globalData, patch);
|
||||
if (Object.keys(patch).length > 0) {
|
||||
|
||||
this.instances.forEach(function (instance) {
|
||||
if (updateAll || _this.updateAll || instance.constructor.updatePath && needUpdate(patch, instance.constructor.updatePath) || instance._updatePath && needUpdate(patch, instance._updatePath)) {
|
||||
//update this.using
|
||||
if (instance.constructor.use) {
|
||||
instance.using = getUse(store.data, instance.constructor.use);
|
||||
} else if (instance.use) {
|
||||
instance.using = getUse(store.data, instance.initUse());
|
||||
}
|
||||
|
||||
instance.update();
|
||||
}
|
||||
});
|
||||
this.onChange && this.onChange(patch);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function matchGlobalData(globalData, diffResult) {
|
||||
if (!globalData) return false;
|
||||
for (var keyA in diffResult) {
|
||||
if (globalData.indexOf(keyA) > -1) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0, len = globalData.length; i < len; i++) {
|
||||
if (includePath(keyA, globalData[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function needUpdate(diffResult, updatePath) {
|
||||
for (var keyA in diffResult) {
|
||||
if (updatePath[keyA]) {
|
||||
return true;
|
||||
}
|
||||
for (var keyB in updatePath) {
|
||||
if (includePath(keyA, keyB)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function includePath(pathA, pathB) {
|
||||
if (pathA.indexOf(pathB) === 0) {
|
||||
var next = pathA.substr(pathB.length, 1);
|
||||
if (next === '[' || next === '.') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function fixPath(path) {
|
||||
var mpPath = '';
|
||||
var arr = path.replace('#-', '').split('-');
|
||||
arr.forEach(function (item, index) {
|
||||
if (index) {
|
||||
if (isNaN(Number(item))) {
|
||||
mpPath += '.' + item;
|
||||
} else {
|
||||
mpPath += '[' + item + ']';
|
||||
}
|
||||
} else {
|
||||
mpPath += item;
|
||||
}
|
||||
});
|
||||
return mpPath;
|
||||
}
|
||||
|
||||
function createRef() {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -74,6 +74,79 @@
|
|||
function applyRef(ref, value) {
|
||||
if (ref) if ('function' == typeof ref) ref(value); else ref.current = value;
|
||||
}
|
||||
function getPath(obj) {
|
||||
if ('[object Array]' === Object.prototype.toString.call(obj)) {
|
||||
var result = {};
|
||||
obj.forEach(function(item) {
|
||||
if ('string' == typeof item) result[item] = !0; else {
|
||||
var tempPath = item[Object.keys(item)[0]];
|
||||
if ('string' == typeof tempPath) result[tempPath] = !0; else if ('string' == typeof tempPath[0]) result[tempPath[0]] = !0; else tempPath[0].forEach(function(path) {
|
||||
return result[path] = !0;
|
||||
});
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} else return getUpdatePath(obj);
|
||||
}
|
||||
function getUpdatePath(data) {
|
||||
var result = {};
|
||||
dataToPath(data, result);
|
||||
return result;
|
||||
}
|
||||
function dataToPath(data, result) {
|
||||
Object.keys(data).forEach(function(key) {
|
||||
result[key] = !0;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === OBJECTTYPE) _objToPath(data[key], key, result); else if (type === ARRAYTYPE) _arrayToPath(data[key], key, result);
|
||||
});
|
||||
}
|
||||
function _objToPath(data, path, result) {
|
||||
Object.keys(data).forEach(function(key) {
|
||||
result[path + '.' + key] = !0;
|
||||
delete result[path];
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === OBJECTTYPE) _objToPath(data[key], path + '.' + key, result); else if (type === ARRAYTYPE) _arrayToPath(data[key], path + '.' + key, result);
|
||||
});
|
||||
}
|
||||
function _arrayToPath(data, path, result) {
|
||||
data.forEach(function(item, index) {
|
||||
result[path + '[' + index + ']'] = !0;
|
||||
delete result[path];
|
||||
var type = Object.prototype.toString.call(item);
|
||||
if (type === OBJECTTYPE) _objToPath(item, path + '[' + index + ']', result); else if (type === ARRAYTYPE) _arrayToPath(item, path + '[' + index + ']', result);
|
||||
});
|
||||
}
|
||||
function getUse(data, paths) {
|
||||
var obj = [];
|
||||
paths.forEach(function(path, index) {
|
||||
var isPath = 'string' == typeof path;
|
||||
if (isPath) obj[index] = getTargetByPath(data, path); else {
|
||||
var key = Object.keys(path)[0];
|
||||
var value = path[key];
|
||||
if ('string' == typeof value) obj[index] = getTargetByPath(data, value); else {
|
||||
var tempPath = value[0];
|
||||
if ('string' == typeof tempPath) {
|
||||
var tempVal = getTargetByPath(data, tempPath);
|
||||
obj[index] = value[1] ? value[1](tempVal) : tempVal;
|
||||
} else {
|
||||
var args = [];
|
||||
tempPath.forEach(function(path) {
|
||||
args.push(getTargetByPath(data, path));
|
||||
});
|
||||
obj[index] = value[1].apply(null, args);
|
||||
}
|
||||
}
|
||||
obj[key] = obj[index];
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
function getTargetByPath(origin, path) {
|
||||
var arr = path.replace(/]/g, '').replace(/\[/g, '.').split('.');
|
||||
var current = origin;
|
||||
for (var i = 0, len = arr.length; i < len; i++) current = current[arr[i]];
|
||||
return current;
|
||||
}
|
||||
function cloneElement(vnode, props) {
|
||||
return h(vnode.nodeName, extend(extend({}, vnode.attributes), props), arguments.length > 2 ? [].slice.call(arguments, 2) : vnode.children);
|
||||
}
|
||||
|
@ -149,12 +222,12 @@
|
|||
if (c.store.installed) c.store.installed();
|
||||
}
|
||||
}
|
||||
function diff(dom, vnode, context, mountAll, parent, componentRoot, store) {
|
||||
function diff(dom, vnode, $, mountAll, parent, componentRoot, store) {
|
||||
if (!diffLevel++) {
|
||||
isSvgMode = null != parent && void 0 !== parent.ownerSVGElement;
|
||||
hydrating = null != dom && !('prevProps' in dom);
|
||||
}
|
||||
var ret = idiff(dom, vnode, context, mountAll, componentRoot, store);
|
||||
var ret = idiff(dom, vnode, $, mountAll, componentRoot, store);
|
||||
if (parent && ret.parentNode !== parent) parent.appendChild(ret);
|
||||
if (!--diffLevel) {
|
||||
hydrating = !1;
|
||||
|
@ -162,7 +235,7 @@
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
function idiff(dom, vnode, context, mountAll, componentRoot, store) {
|
||||
function idiff(dom, vnode, $, mountAll, componentRoot, store) {
|
||||
var out = dom, prevSvgMode = isSvgMode;
|
||||
if (null == vnode || 'boolean' == typeof vnode) vnode = '';
|
||||
if ('string' == typeof vnode || 'number' == typeof vnode) {
|
||||
|
@ -179,7 +252,7 @@
|
|||
return out;
|
||||
}
|
||||
var vnodeName = vnode.nodeName;
|
||||
if ('function' == typeof vnodeName) return buildComponentFromVNode(dom, vnode, context, mountAll);
|
||||
if ('function' == typeof vnodeName) return buildComponentFromVNode(dom, vnode, $, mountAll);
|
||||
isSvgMode = 'svg' === vnodeName ? !0 : 'foreignObject' === vnodeName ? !1 : isSvgMode;
|
||||
vnodeName = String(vnodeName);
|
||||
if (!dom || !isNamedNode(dom, vnodeName)) {
|
||||
|
@ -197,12 +270,12 @@
|
|||
}
|
||||
if (!hydrating && vchildren && 1 === vchildren.length && 'string' == typeof vchildren[0] && null != fc && void 0 !== fc.splitText && null == fc.nextSibling) {
|
||||
if (fc.nodeValue != vchildren[0]) fc.nodeValue = vchildren[0];
|
||||
} else if (vchildren && vchildren.length || null != fc) innerDiffNode(out, vchildren, context, mountAll, hydrating || null != props.dangerouslySetInnerHTML, store);
|
||||
} else if (vchildren && vchildren.length || null != fc) innerDiffNode(out, vchildren, $, mountAll, hydrating || null != props.dangerouslySetInnerHTML, store);
|
||||
diffAttributes(out, vnode.attributes, props, store);
|
||||
isSvgMode = prevSvgMode;
|
||||
return out;
|
||||
}
|
||||
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating, store) {
|
||||
function innerDiffNode(dom, vchildren, $, mountAll, isHydrating, store) {
|
||||
var j, c, f, vchild, child, originalChildren = dom.childNodes, children = [], keyed = {}, keyedLen = 0, min = 0, len = originalChildren.length, childrenLen = 0, vlen = vchildren ? vchildren.length : 0;
|
||||
if (0 !== len) for (var i = 0; i < len; i++) {
|
||||
var _child = originalChildren[i], props = _child.__p, key = vlen && props ? _child._component ? _child._component.__k : props.key : null;
|
||||
|
@ -228,7 +301,7 @@
|
|||
if (j === min) min++;
|
||||
break;
|
||||
}
|
||||
child = idiff(child, vchild, context, mountAll, null, store);
|
||||
child = idiff(child, vchild, $, mountAll, null, store);
|
||||
f = originalChildren[i];
|
||||
if (child && child !== dom && child !== f) if (null == f) dom.appendChild(child); else if (child === f.nextSibling) removeNode(f); else dom.insertBefore(child, f);
|
||||
}
|
||||
|
@ -256,15 +329,25 @@
|
|||
for (name in old) if ((!attrs || null == attrs[name]) && null != old[name]) setAccessor(dom, name, old[name], old[name] = void 0, isSvgMode, store);
|
||||
for (name in attrs) if (!('children' === name || 'innerHTML' === name || name in old && attrs[name] === ('value' === name || 'checked' === name ? dom[name] : old[name]))) setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode, store);
|
||||
}
|
||||
function createComponent(Ctor, props, context) {
|
||||
function createComponent(Ctor, props, $) {
|
||||
var inst, i = recyclerComponents.length;
|
||||
inst = new Component(props, context);
|
||||
inst = new Component(props, $);
|
||||
inst.constructor = Ctor;
|
||||
inst.render = doRender;
|
||||
if (Ctor.store) {
|
||||
inst.store = Ctor.store(inst);
|
||||
inst.store.update = inst.update.bind(inst);
|
||||
}
|
||||
if (inst.$ && inst.$.data) if (inst.constructor.use) {
|
||||
inst.constructor.updatePath = getPath(inst.constructor.use);
|
||||
inst.using = getUse(inst.$.data, inst.constructor.use);
|
||||
inst.$.instances.push(inst);
|
||||
} else if (inst.use) {
|
||||
var use = inst.use();
|
||||
inst.M = getPath(use);
|
||||
inst.using = getUse(inst.$.data, use);
|
||||
inst.$.instances.push(inst);
|
||||
}
|
||||
while (i--) if (recyclerComponents[i].constructor === Ctor) {
|
||||
inst.__b = recyclerComponents[i].__b;
|
||||
recyclerComponents.splice(i, 1);
|
||||
|
@ -272,10 +355,10 @@
|
|||
}
|
||||
return inst;
|
||||
}
|
||||
function doRender(props, context) {
|
||||
return this.constructor(props, this.store, context);
|
||||
function doRender(props, $) {
|
||||
return this.constructor(props, this.store, $);
|
||||
}
|
||||
function setComponentProps(component, props, renderMode, context, mountAll) {
|
||||
function setComponentProps(component, props, renderMode, $, mountAll) {
|
||||
if (!component.__x) {
|
||||
component.__x = !0;
|
||||
component.__r = props.ref;
|
||||
|
@ -284,11 +367,8 @@
|
|||
delete props.key;
|
||||
if (!component.base || mountAll) {
|
||||
if (component.store.install) component.store.install();
|
||||
} else if (component.store.receiveProps) component.R = component.store.receiveProps(props, context);
|
||||
if (context && context !== component.context) {
|
||||
if (!component.__c) component.__c = component.context;
|
||||
component.context = context;
|
||||
}
|
||||
} else if (component.store.receiveProps) component.R = component.store.receiveProps(props, $);
|
||||
if ($ && $ !== component.$) component.$ = $;
|
||||
if (!component.__p) component.__p = component.props;
|
||||
component.props = props;
|
||||
component.__x = !1;
|
||||
|
@ -298,37 +378,33 @@
|
|||
}
|
||||
function renderComponent(component, renderMode, mountAll, isChild) {
|
||||
if (!component.__x) {
|
||||
var rendered, inst, cbase, props = component.props, context = component.context, previousProps = component.__p || props, previousContext = component.__c || context, isUpdate = component.base, nextBase = component.__b, initialBase = isUpdate || nextBase, initialChildComponent = component._component, skip = !1, snapshot = previousContext;
|
||||
var rendered, inst, cbase, props = component.props, $ = component.$, previousProps = component.__p || props, isUpdate = component.base, nextBase = component.__b, initialBase = isUpdate || nextBase, initialChildComponent = component._component, skip = !1;
|
||||
if (isUpdate) {
|
||||
component.props = previousProps;
|
||||
component.context = previousContext;
|
||||
if (!1 !== component.R) {
|
||||
skip = !1;
|
||||
if (component.store.beforeUpdate) component.store.beforeUpdate(props, context);
|
||||
if (component.store.beforeUpdate) component.store.beforeUpdate(props, $);
|
||||
} else skip = !0;
|
||||
delete component.R;
|
||||
component.props = props;
|
||||
component.context = context;
|
||||
}
|
||||
component.__p = component.__c = component.__b = null;
|
||||
component.__d = !1;
|
||||
if (!skip) {
|
||||
options.runTimeComponent = component;
|
||||
if (component.store.beforeRender) component.store.beforeRender();
|
||||
rendered = component.render(props, context);
|
||||
rendered = component.render(props, $);
|
||||
options.runTimeComponent = null;
|
||||
if (component.getChildContext) context = extend(extend({}, context), component.getChildContext());
|
||||
if (isUpdate && component.getSnapshotBeforeUpdate) snapshot = component.getSnapshotBeforeUpdate(previousProps);
|
||||
var toUnmount, base, childComponent = rendered && rendered.nodeName;
|
||||
if ('function' == typeof childComponent) {
|
||||
var childProps = getNodeProps(rendered);
|
||||
inst = initialChildComponent;
|
||||
if (inst && inst.constructor === childComponent && childProps.key == inst.__k) setComponentProps(inst, childProps, 1, context, !1); else {
|
||||
if (inst && inst.constructor === childComponent && childProps.key == inst.__k) setComponentProps(inst, childProps, 1, $, !1); else {
|
||||
toUnmount = inst;
|
||||
component._component = inst = createComponent(childComponent, childProps, context);
|
||||
component._component = inst = createComponent(childComponent, childProps, $);
|
||||
inst.__b = inst.__b || nextBase;
|
||||
inst.__u = component;
|
||||
setComponentProps(inst, childProps, 0, context, !1);
|
||||
setComponentProps(inst, childProps, 0, $, !1);
|
||||
renderComponent(inst, 1, mountAll, !0);
|
||||
}
|
||||
base = inst.base;
|
||||
|
@ -338,7 +414,7 @@
|
|||
if (toUnmount) cbase = component._component = null;
|
||||
if (initialBase || 1 === renderMode) {
|
||||
if (cbase) cbase._component = null;
|
||||
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, !0, component.store);
|
||||
base = diff(cbase, rendered, $, mountAll || !isUpdate, initialBase && initialBase.parentNode, !0, component.store);
|
||||
}
|
||||
}
|
||||
if (initialBase && base !== initialBase && inst !== initialChildComponent) {
|
||||
|
@ -361,30 +437,30 @@
|
|||
}
|
||||
}
|
||||
if (!isUpdate || mountAll) mounts.push(component); else if (!skip) {
|
||||
if (component.store.updated) component.store.updated(previousProps, snapshot);
|
||||
if (component.store.updated) component.store.updated(previousProps);
|
||||
if (options.afterUpdate) options.afterUpdate(component);
|
||||
}
|
||||
while (component.__h.length) component.__h.pop().call(component);
|
||||
if (!diffLevel && !isChild) flushMounts();
|
||||
}
|
||||
}
|
||||
function buildComponentFromVNode(dom, vnode, context, mountAll) {
|
||||
function buildComponentFromVNode(dom, vnode, $, mountAll) {
|
||||
var c = dom && dom._component, originalComponent = c, oldDom = dom, isDirectOwner = c && dom._componentConstructor === vnode.nodeName, isOwner = isDirectOwner, props = getNodeProps(vnode);
|
||||
while (c && !isOwner && (c = c.__u)) isOwner = c.constructor === vnode.nodeName;
|
||||
if (c && isOwner && (!mountAll || c._component)) {
|
||||
setComponentProps(c, props, 3, context, mountAll);
|
||||
setComponentProps(c, props, 3, $, mountAll);
|
||||
dom = c.base;
|
||||
} else {
|
||||
if (originalComponent && !isDirectOwner) {
|
||||
unmountComponent(originalComponent);
|
||||
dom = oldDom = null;
|
||||
}
|
||||
c = createComponent(vnode.nodeName, props, context);
|
||||
c = createComponent(vnode.nodeName, props, $);
|
||||
if (dom && !c.__b) {
|
||||
c.__b = dom;
|
||||
oldDom = null;
|
||||
}
|
||||
setComponentProps(c, props, 1, context, mountAll);
|
||||
setComponentProps(c, props, 1, $, mountAll);
|
||||
dom = c.base;
|
||||
if (oldDom && dom !== oldDom) {
|
||||
oldDom._component = null;
|
||||
|
@ -409,16 +485,164 @@
|
|||
}
|
||||
applyRef(component.__r, null);
|
||||
}
|
||||
function Component(props, context) {
|
||||
function Component(props, $) {
|
||||
this.__d = !0;
|
||||
this.elementId = id++;
|
||||
this.context = context;
|
||||
this.store = {};
|
||||
this.$ = $;
|
||||
this.props = props;
|
||||
this.__h = [];
|
||||
}
|
||||
function render(vnode, parent, merge) {
|
||||
return diff(merge, vnode, {}, !1, 'string' == typeof parent ? document.querySelector(parent) : parent, !1);
|
||||
function obaa(target, arr, callback) {
|
||||
var eventPropArr = [];
|
||||
if (isArray(target)) {
|
||||
if (0 === target.length) target.S = {
|
||||
T: target,
|
||||
U: '#'
|
||||
};
|
||||
mock(target, target);
|
||||
}
|
||||
for (var prop in target) if (target.hasOwnProperty(prop)) if (callback) {
|
||||
if (isArray(arr) && isInArray(arr, prop)) {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
} else if (isString(arr) && prop == arr) {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
}
|
||||
} else {
|
||||
eventPropArr.push(prop);
|
||||
watch(target, prop, null, target);
|
||||
}
|
||||
if (!target.V) target.V = [];
|
||||
var propChanged = callback ? callback : arr;
|
||||
target.V.push({
|
||||
all: !callback,
|
||||
propChanged: propChanged,
|
||||
eventPropArr: eventPropArr
|
||||
});
|
||||
}
|
||||
function mock(target, root) {
|
||||
methods.forEach(function(item) {
|
||||
target[item] = function() {
|
||||
var old = Array.prototype.slice.call(this, 0);
|
||||
var result = Array.prototype[item].apply(this, Array.prototype.slice.call(arguments));
|
||||
if (new RegExp('\\b' + item + '\\b').test(triggerStr)) {
|
||||
for (var cprop in this) if (this.hasOwnProperty(cprop) && !isFunction(this[cprop])) watch(this, cprop, this.S.U, root);
|
||||
onPropertyChanged('Array-' + item, this, old, this, this.S.U, root);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
target['pure' + item.substring(0, 1).toUpperCase() + item.substring(1)] = function() {
|
||||
return Array.prototype[item].apply(this, Array.prototype.slice.call(arguments));
|
||||
};
|
||||
});
|
||||
}
|
||||
function watch(target, prop, path, root) {
|
||||
if ('__o_' !== prop) if (!isFunction(target[prop])) {
|
||||
if (!target.S) target.S = {
|
||||
T: root
|
||||
};
|
||||
if (void 0 !== path && null !== path) target.S.U = path; else target.S.U = '#';
|
||||
var currentValue = target.S[prop] = target[prop];
|
||||
if ('object' == typeof currentValue) {
|
||||
if (isArray(currentValue)) {
|
||||
mock(currentValue, root);
|
||||
if (0 === currentValue.length) {
|
||||
if (!currentValue.S) currentValue.S = {};
|
||||
if (void 0 !== path && null !== path) currentValue.S.U = path + '-' + prop; else currentValue.S.U = "#-" + prop;
|
||||
}
|
||||
}
|
||||
for (var cprop in currentValue) if (currentValue.hasOwnProperty(cprop)) watch(currentValue, cprop, target.S.U + '-' + prop, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
function onPropertyChanged(prop, value, oldValue, target, path, root) {
|
||||
if (value !== oldValue && root.V) {
|
||||
var rootName = getRootName(prop, path);
|
||||
for (var i = 0, len = root.V.length; i < len; i++) {
|
||||
var handler = root.V[i];
|
||||
if (handler.all || isInArray(handler.eventPropArr, rootName) || 0 === rootName.indexOf('Array-')) handler.propChanged.call(target, prop, value, oldValue, path);
|
||||
}
|
||||
}
|
||||
if (0 !== prop.indexOf('Array-') && 'object' == typeof value) watch(target, prop, target.S.U, root);
|
||||
}
|
||||
function isFunction(obj) {
|
||||
return '[object Function]' == Object.prototype.toString.call(obj);
|
||||
}
|
||||
function isArray(obj) {
|
||||
return '[object Array]' === Object.prototype.toString.call(obj);
|
||||
}
|
||||
function isString(obj) {
|
||||
return 'string' == typeof obj;
|
||||
}
|
||||
function isInArray(arr, item) {
|
||||
for (var i = arr.length; --i > -1; ) if (item === arr[i]) return !0;
|
||||
return !1;
|
||||
}
|
||||
function getRootName(prop, path) {
|
||||
if ('#' === path) return prop; else return path.split('-')[1];
|
||||
}
|
||||
function render(vnode, parent, globalStore) {
|
||||
obsStore(globalStore);
|
||||
return diff(null, vnode, globalStore, !1, 'string' == typeof parent ? document.querySelector(parent) : parent, !1);
|
||||
}
|
||||
function obsStore(store) {
|
||||
if (store && store.data) {
|
||||
store.instances = [];
|
||||
extendStoreUpate(store);
|
||||
obaa(store.data, function(prop, val, old, path) {
|
||||
var patchs = {};
|
||||
var key = fixPath(path + '-' + prop);
|
||||
patchs[key] = !0;
|
||||
store.update(patchs);
|
||||
});
|
||||
}
|
||||
}
|
||||
function extendStoreUpate(store) {
|
||||
store.update = function(patch) {
|
||||
var _this = this;
|
||||
var updateAll = matchGlobalData(this.globalData, patch);
|
||||
if (Object.keys(patch).length > 0) {
|
||||
this.instances.forEach(function(instance) {
|
||||
if (updateAll || _this.updateAll || instance.constructor.updatePath && needUpdate(patch, instance.constructor.updatePath) || instance.M && needUpdate(patch, instance.M)) {
|
||||
if (instance.constructor.use) instance.using = getUse(store.data, instance.constructor.use); else if (instance.use) instance.using = getUse(store.data, instance.initUse());
|
||||
instance.update();
|
||||
}
|
||||
});
|
||||
this.onChange && this.onChange(patch);
|
||||
}
|
||||
};
|
||||
}
|
||||
function matchGlobalData(globalData, diffResult) {
|
||||
if (!globalData) return !1;
|
||||
for (var keyA in diffResult) {
|
||||
if (globalData.indexOf(keyA) > -1) return !0;
|
||||
for (var i = 0, len = globalData.length; i < len; i++) if (includePath(keyA, globalData[i])) return !0;
|
||||
}
|
||||
return !1;
|
||||
}
|
||||
function needUpdate(diffResult, updatePath) {
|
||||
for (var keyA in diffResult) {
|
||||
if (updatePath[keyA]) return !0;
|
||||
for (var keyB in updatePath) if (includePath(keyA, keyB)) return !0;
|
||||
}
|
||||
return !1;
|
||||
}
|
||||
function includePath(pathA, pathB) {
|
||||
if (0 === pathA.indexOf(pathB)) {
|
||||
var next = pathA.substr(pathB.length, 1);
|
||||
if ('[' === next || '.' === next) return !0;
|
||||
}
|
||||
return !1;
|
||||
}
|
||||
function fixPath(path) {
|
||||
var mpPath = '';
|
||||
var arr = path.replace('#-', '').split('-');
|
||||
arr.forEach(function(item, index) {
|
||||
if (index) if (isNaN(Number(item))) mpPath += '.' + item; else mpPath += '[' + item + ']'; else mpPath += item;
|
||||
});
|
||||
return mpPath;
|
||||
}
|
||||
function createRef() {
|
||||
return {};
|
||||
|
@ -448,6 +672,18 @@
|
|||
},
|
||||
render: function() {}
|
||||
});
|
||||
var triggerStr = [ 'concat', 'copyWithin', 'fill', 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'size' ].join(',');
|
||||
var methods = [ 'concat', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values', 'size' ];
|
||||
obaa.add = function(obj, prop) {
|
||||
watch(obj, prop, obj.S.U, obj.S.T);
|
||||
};
|
||||
obaa.set = function(obj, prop, value) {
|
||||
watch(obj, prop, obj.S.U, obj.S.T);
|
||||
obj[prop] = value;
|
||||
};
|
||||
Array.prototype.size = function(length) {
|
||||
this.length = length;
|
||||
};
|
||||
var Omis = {
|
||||
h: h,
|
||||
createElement: h,
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1608,51 +1608,113 @@
|
|||
Omis.h(
|
||||
'span',
|
||||
null,
|
||||
this.$.data.a
|
||||
this.using[0]
|
||||
),
|
||||
Omis.h(
|
||||
'button',
|
||||
{ onClick: store.add },
|
||||
'+'
|
||||
),
|
||||
Omis.h(
|
||||
'div',
|
||||
null,
|
||||
Omis.h(
|
||||
'span',
|
||||
null,
|
||||
this.using[1]
|
||||
),
|
||||
Omis.h(
|
||||
'button',
|
||||
{ onClick: store.rename },
|
||||
'rename'
|
||||
)
|
||||
),
|
||||
Omis.h(
|
||||
'div',
|
||||
null,
|
||||
this.using.reverseMotto
|
||||
),
|
||||
Omis.h(
|
||||
'button',
|
||||
{ onClick: store.changeMotto },
|
||||
'change motto'
|
||||
),
|
||||
Omis.h(
|
||||
'div',
|
||||
null,
|
||||
this.using.name
|
||||
),
|
||||
Omis.h(
|
||||
'div',
|
||||
null,
|
||||
this.using[3]
|
||||
),
|
||||
Omis.h(
|
||||
'div',
|
||||
null,
|
||||
this.using.fullName,
|
||||
Omis.h(
|
||||
'button',
|
||||
{ onClick: store.changeFirstName },
|
||||
'change first name'
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
var Counter2 = function Counter2(props, store, context) {
|
||||
|
||||
Counter.store = function (_) {
|
||||
return {
|
||||
add: function add(e) {
|
||||
_.$.data.count++;
|
||||
},
|
||||
sub: function sub() {
|
||||
_.$.data.count--;
|
||||
},
|
||||
rename: function rename() {
|
||||
_.$.data.arr[0] = 'aa';
|
||||
},
|
||||
changeMotto: function changeMotto() {
|
||||
_.$.data.motto = 'ok';
|
||||
},
|
||||
changeFirstName: function changeFirstName() {
|
||||
_.$.data.userInfo.firstName = 'DNT';
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var CounterB = function CounterB(props, store) {
|
||||
|
||||
return Omis.h(
|
||||
'div',
|
||||
null,
|
||||
Omis.h(
|
||||
'button',
|
||||
{ onClick: store.sub },
|
||||
'-'
|
||||
),
|
||||
Omis.h(
|
||||
'span',
|
||||
null,
|
||||
this.$.data.a
|
||||
this.$.data.count
|
||||
),
|
||||
Omis.h(
|
||||
'ul',
|
||||
null,
|
||||
this.$.data.arr.map(function (item) {
|
||||
return Omis.h(
|
||||
'li',
|
||||
null,
|
||||
item
|
||||
);
|
||||
})
|
||||
),
|
||||
Omis.h(
|
||||
'button',
|
||||
{ onClick: store.add },
|
||||
'+'
|
||||
{ onClick: store.push },
|
||||
'array push'
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
Counter2.store = function (_) {
|
||||
CounterB.store = function (_) {
|
||||
return {
|
||||
count: 1,
|
||||
add: function add(e) {
|
||||
this.count++;
|
||||
this.update();
|
||||
_.props.onChange(this.count);
|
||||
},
|
||||
sub: function sub() {
|
||||
_.$.data.a = Math.random();
|
||||
this.count--;
|
||||
// this.update()
|
||||
// _.props.onChange(this.count)
|
||||
push: function push() {
|
||||
_.$.data.arr.push(Math.random());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1665,16 +1727,37 @@
|
|||
'div',
|
||||
null,
|
||||
'Count from child event: ',
|
||||
this.$.data.a
|
||||
this.using.motto
|
||||
),
|
||||
Omis.h(Counter, { onChange: store.changeHandle }),
|
||||
Omis.h(Counter2, { onChange: store.changeHandle })
|
||||
Omis.h('br', null),
|
||||
Omis.h('br', null),
|
||||
Omis.h(CounterB, { onChange: store.changeHandle })
|
||||
);
|
||||
};
|
||||
|
||||
Counter2.use = ['a'];
|
||||
Counter.use = ['a'];
|
||||
App.use = ['a'];
|
||||
Counter.use = ['count', //Direct string, accessible through this.using[0]
|
||||
'arr[0]', //It also supports path, which is accessible through this.using[1]
|
||||
//Support JSON
|
||||
{
|
||||
//Alias, accessible through this.using.reverseMotto
|
||||
reverseMotto: ['motto', //path
|
||||
function (target) {
|
||||
return target.split('').reverse().join('');
|
||||
} //computed
|
||||
]
|
||||
}, { name: 'arr[1]' }, //{ alias: path },accessible through this.using.name
|
||||
{
|
||||
//alias,accessible through this.using.fullName
|
||||
fullName: [['userInfo.firstName', 'userInfo.lastName'], //path array
|
||||
function (firstName, lastName) {
|
||||
return firstName + lastName;
|
||||
} //computed
|
||||
]
|
||||
}];
|
||||
|
||||
CounterB.use = ['count', { list: 'arr' }];
|
||||
App.use = [{ motto: 'motto' }];
|
||||
|
||||
App.store = function (_) {
|
||||
return {
|
||||
|
@ -1686,7 +1769,18 @@
|
|||
};
|
||||
};
|
||||
|
||||
render(Omis.h(App, null), 'body', { data: { a: 11 } });
|
||||
render(Omis.h(App, null), 'body', {
|
||||
data: {
|
||||
count: 0,
|
||||
arr: ['china', 'tencent'],
|
||||
motto: 'I love omis.',
|
||||
userInfo: {
|
||||
firstName: 'dnt',
|
||||
lastName: 'zhang',
|
||||
age: 18
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}());
|
||||
//# sourceMappingURL=b.js.map
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,60 +1,109 @@
|
|||
import { render, h } from '../../src/omis'
|
||||
|
||||
const Counter = function(props, store, context) {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={store.sub}>-</button>
|
||||
<span>{this.$.data.a}</span>
|
||||
<button onClick={store.add}>+</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const Counter2 = function(props, store, context) {
|
||||
const Counter = function (props, store, context) {
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={store.sub}>-</button>
|
||||
<span>{this.$.data.a}</span>
|
||||
<span>{this.using[0]}</span>
|
||||
<button onClick={store.add}>+</button>
|
||||
<div>
|
||||
<span>{this.using[1]}</span>
|
||||
<button onClick={store.rename}>rename</button>
|
||||
</div>
|
||||
<div>{this.using.reverseMotto}</div><button onClick={store.changeMotto}>change motto</button>
|
||||
<div>{this.using.name}</div>
|
||||
<div>{this.using[3]}</div>
|
||||
<div>
|
||||
{this.using.fullName}
|
||||
<button onClick={store.changeFirstName}>change first name</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
Counter2.store = _ => {
|
||||
|
||||
Counter.store = _ => {
|
||||
return {
|
||||
count: 1,
|
||||
add(e) {
|
||||
this.count++
|
||||
this.update()
|
||||
_.props.onChange(this.count)
|
||||
|
||||
_.$.data.count++
|
||||
|
||||
},
|
||||
sub() {
|
||||
_.$.data.a = Math.random()
|
||||
this.count--
|
||||
// this.update()
|
||||
// _.props.onChange(this.count)
|
||||
_.$.data.count--
|
||||
},
|
||||
rename() {
|
||||
_.$.data.arr[0] = 'aa'
|
||||
},
|
||||
changeMotto() {
|
||||
_.$.data.motto = 'ok'
|
||||
},
|
||||
changeFirstName() {
|
||||
_.$.data.userInfo.firstName = 'DNT'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const CounterB = function (props, store) {
|
||||
|
||||
const App = function(props, store){
|
||||
return (
|
||||
<div>
|
||||
<div>Count from child event: {this.$.data.a}</div>
|
||||
<Counter onChange={store.changeHandle}></Counter>
|
||||
<Counter2 onChange={store.changeHandle}></Counter2>
|
||||
<span>{this.$.data.count}</span>
|
||||
<ul>
|
||||
{this.$.data.arr.map(item => <li>{item}</li>)}
|
||||
</ul>
|
||||
<button onClick={store.push}>array push</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Counter2.use = ['a']
|
||||
Counter.use = ['a']
|
||||
App.use = ['a']
|
||||
CounterB.store = _ => ({
|
||||
push() {
|
||||
_.$.data.arr.push(Math.random())
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const App = function (props, store) {
|
||||
return (
|
||||
<div>
|
||||
<div>Count from child event: {this.using.motto}</div>
|
||||
<Counter onChange={store.changeHandle}></Counter>
|
||||
<br></br>
|
||||
<br></br>
|
||||
<CounterB onChange={store.changeHandle}></CounterB>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Counter.use = [
|
||||
'count', //Direct string, accessible through this.using[0]
|
||||
'arr[0]', //It also supports path, which is accessible through this.using[1]
|
||||
//Support JSON
|
||||
{
|
||||
//Alias, accessible through this.using.reverseMotto
|
||||
reverseMotto: [
|
||||
'motto', //path
|
||||
target => target.split('').reverse().join('') //computed
|
||||
]
|
||||
},
|
||||
{ name: 'arr[1]' }, //{ alias: path },accessible through this.using.name
|
||||
{
|
||||
//alias,accessible through this.using.fullName
|
||||
fullName: [
|
||||
['userInfo.firstName', 'userInfo.lastName'], //path array
|
||||
(firstName, lastName) => firstName + lastName //computed
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
CounterB.use = ['count', { list: 'arr' }]
|
||||
App.use = [{ motto: 'motto' }]
|
||||
|
||||
|
||||
App.store = _ => ({
|
||||
|
@ -65,4 +114,15 @@ App.store = _ => ({
|
|||
}
|
||||
})
|
||||
|
||||
render(<App />, 'body', { data: {a:11} })
|
||||
render(<App />, 'body', {
|
||||
data: {
|
||||
count: 0,
|
||||
arr: ['china', 'tencent'],
|
||||
motto: 'I love omis.',
|
||||
userInfo: {
|
||||
firstName: 'dnt',
|
||||
lastName: 'zhang',
|
||||
age: 18
|
||||
}
|
||||
}
|
||||
})
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "omis",
|
||||
"version": "0.6.0",
|
||||
"version": "0.7.0",
|
||||
"description": "Functional Component with store, scoped css and easy hyperscript.",
|
||||
"main": "dist/omis.js",
|
||||
"jsnext:main": "dist/omis.esm.js",
|
||||
|
|
|
@ -59,13 +59,13 @@ declare namespace Omis {
|
|||
>;
|
||||
|
||||
interface FunctionalComponent<P = {}> {
|
||||
(props: RenderableProps<P>, context?: any): VNode<any> | null;
|
||||
(props: RenderableProps<P>, $?: any): VNode<any> | null;
|
||||
displayName?: string;
|
||||
defaultProps?: Partial<P>;
|
||||
}
|
||||
|
||||
interface ComponentConstructor<P = {}, S = {}> {
|
||||
new (props: P, context?: any): Component<P, S>;
|
||||
new (props: P, $?: any): Component<P, S>;
|
||||
displayName?: string;
|
||||
defaultProps?: Partial<P>;
|
||||
}
|
||||
|
@ -85,18 +85,18 @@ declare namespace Omis {
|
|||
}
|
||||
|
||||
abstract class Component<P, S> {
|
||||
constructor(props?: P, context?: any);
|
||||
constructor(props?: P, $?: any);
|
||||
|
||||
static displayName?: string;
|
||||
static defaultProps?: any;
|
||||
|
||||
props: RenderableProps<P>;
|
||||
context: any;
|
||||
$: any;
|
||||
base?: HTMLElement;
|
||||
|
||||
update(callback?: () => void): void;
|
||||
|
||||
abstract render(props?: RenderableProps<P>, context?: any): ComponentChild;
|
||||
abstract render(props?: RenderableProps<P>, $?: any): ComponentChild;
|
||||
|
||||
// Add these variables to avoid descendants shadowing them (some from properties.json for minification)
|
||||
private __key;
|
||||
|
|
Loading…
Reference in New Issue