diff --git a/runtime/main/app/bundle.ts b/runtime/main/app/bundle.ts index a7b382f1..c7ccf1df 100644 --- a/runtime/main/app/bundle.ts +++ b/runtime/main/app/bundle.ts @@ -39,6 +39,8 @@ import { App } from './App'; const APP_LIFE_CYCLE_TYPES: string[] = ['onCreate', 'onError', 'onDestroy', 'onShow', 'onHide']; +export let CSS_INHERITANCE: string[]; + /** * Parse app page code. * @param {Page} page @@ -49,7 +51,7 @@ const APP_LIFE_CYCLE_TYPES: string[] = ['onCreate', 'onError', 'onDestroy', 'onS export const defineFn = function(page: Page, packageName: string, name?: string, ...args: any[] | null): void { Log.debug(`Define a page ${name}.`); const parseContent: Function = args[1]; - let bundleContent: object = null; + let bundleContent: any = null; // Function to obtain bundle content. if (parseContent) { @@ -65,6 +67,14 @@ export const defineFn = function(page: Page, packageName: string, name?: string, const moduleContent = { exports: {} }; parseContent(pageRequire, moduleContent.exports, moduleContent); bundleContent = moduleContent.exports; + + let minPlatformVersion: number = 5; + if (bundleContent.manifest) { + minPlatformVersion = bundleContent.manifest.minPlatformVersion; + } + CSS_INHERITANCE = minPlatformVersion > 5 ? + ['fontFamily', 'fontWeight', 'fontSize', 'fontStyle', 'textAlign', 'lineHeight', 'letterSpacing', 'color', 'visibility'] : + []; } // Apply bundleContent. diff --git a/runtime/main/model/compiler.ts b/runtime/main/model/compiler.ts index 8f6e1781..1e0c653c 100644 --- a/runtime/main/model/compiler.ts +++ b/runtime/main/model/compiler.ts @@ -730,11 +730,11 @@ function watchBlock(vm: Vm, fragBlock: FragBlockInterface, calc: Function, type: */ function mergeContext(context: Vm, mergedData: object): any { const newContext = Object.create(context); - newContext.data = mergedData; - newContext.shareData = {}; + newContext._data = mergedData; + newContext._shareData = {}; initData(newContext); initComputed(newContext); - newContext.realParent = context; + newContext._realParent = context; return newContext; } diff --git a/runtime/main/model/directive.ts b/runtime/main/model/directive.ts index e6e8761d..0d3aaf08 100644 --- a/runtime/main/model/directive.ts +++ b/runtime/main/model/directive.ts @@ -513,6 +513,18 @@ function selectStyle(css: object, key: string, vm: Vm): any { * @param {string[]} classList - List of class label. */ function setClassStyle(el: Element, css: object, classList: string[], vm?: Vm): void { + const SPACE_REG: RegExp = /\s+/; + const newClassList: string[] = []; + if (Array.isArray(classList)) { + classList.forEach(v => { + if (typeof v === 'string' && SPACE_REG.test(v)) { + newClassList.push(...v.trim().split(SPACE_REG)); + } else { + newClassList.push(v); + } + }); + } + classList = newClassList; const classStyle = {}; const length = classList.length; if (length === 1) { @@ -681,7 +693,9 @@ function setAnimation(style: any, css: any): void { const keyframes = css['@KEYFRAMES']; if (animationName && keyframes) { style['animationName'] = keyframes[animationName]; - style['animationName'].push({'animationName': animationName}); + if (style['animationName']) { + style['animationName'].push({'animationName': animationName}); + } } } diff --git a/runtime/main/model/index.ts b/runtime/main/model/index.ts index 683c3d84..6783c1d7 100755 --- a/runtime/main/model/index.ts +++ b/runtime/main/model/index.ts @@ -444,11 +444,13 @@ export default class Vm { * @param {*} value - Property */ public $set(key: string, value: any): void { - if (typeof key !== 'string' || key.indexOf('.') === -1) { + if (typeof key !== 'string') { Log.warn(`Invalid parameter type: The type of 'key' should be string with '.', not ${typeof key}.`); return; } - _proxySet(this.data, key, value); + if (key.indexOf('.') !== -1) { + _proxySet(this.data, key, value); + } set(this.data, key, value); } @@ -544,12 +546,15 @@ export default class Vm { /** * Type of this Vm. * @type {string} - * @readonly */ public get type() { return this._type; } + public set type(newType) { + this._type = newType; + } + /** * Css of this Vm. * @type {[key: string]: any} @@ -886,6 +891,9 @@ function getRoot(vm: any): Vm { * @param {Element} el - Element object. */ function fireNodeDetached(el: Element) { + if (!el) { + return; + } if (el.event && el.event['detached']) { el.fireEvent('detached', {}); } diff --git a/runtime/main/reactivity/state.js b/runtime/main/reactivity/state.js index e8c58456..3c7c456a 100644 --- a/runtime/main/reactivity/state.js +++ b/runtime/main/reactivity/state.js @@ -120,6 +120,10 @@ function proxyMethods(vm, key) { enumerable: true, get: function proxyGetter () { return vm._methods[key]; + }, + set: function proxySetter(newMethod) { + vm._methods[key] = typeof newMethod === 'function' && key !== 'data' ? + newMethod.bind(vm) : newMethod; } - }) + }); } diff --git a/runtime/vdom/Element.ts b/runtime/vdom/Element.ts index c7d14451..f36c673c 100644 --- a/runtime/vdom/Element.ts +++ b/runtime/vdom/Element.ts @@ -28,8 +28,7 @@ import Document from './Document'; import { TaskCenter } from '../main/manage/event/TaskCenter'; import { FragBlockInterface } from '../main/model/compiler'; import Vm from '../main/model'; - -const CSS_INHERITANCE: string[] = ['fontFamily', 'fontWeight', 'fontSize', 'fontStyle', 'textAlign', 'lineHeight', 'letterSpacing', 'color', 'visibility']; +import { CSS_INHERITANCE } from '../main/app/bundle'; /** * Element is a basic class to describe a tree node in vdom. @@ -842,27 +841,29 @@ class Element extends Node { * @param {*} dest - Target style object. */ public assignStyle(src: any, dest: any): void { - const keys = Object.keys(dest); + if (dest) { + const keys = Object.keys(dest); - // Margin and padding style: the style should be empty in the first. - keys.sort(function(style1, style2) { - if (dest[style1] === '') { - return 1; - } else { - return -1; - } - }); - let i = keys.length; - while (i--) { - const key = keys[i]; - const val = dest[key]; - if (val) { - src[key] = val; - } else { - if ((val === '' || val === undefined) && src[key]) { - return; + // Margin and padding style: the style should be empty in the first. + keys.sort(function(style1, style2) { + if (dest[style1] === '') { + return 1; + } else { + return -1; + } + }); + let i = keys.length; + while (i--) { + const key = keys[i]; + const val = dest[key]; + if (val) { + src[key] = val; + } else { + if ((val === '' || val === undefined) && src[key]) { + return; + } + src[key] = val; } - src[key] = val; } } } @@ -924,14 +925,13 @@ class Element extends Node { if (this._event && this._event['detached']) { this.fireEvent('detached', {}); } - this._attr = null; - this._style = null; + this._attr = {}; + this._style = {}; this._classStyle = {}; - this._event = null; - this._idStyle = null; - this._tagStyle = null; + this._event = {}; + this._idStyle = {}; + this._tagStyle = {}; this._classList.length = 0; - this._classList = null; if (this.destroyHook) { this.destroyHook(); @@ -942,11 +942,9 @@ class Element extends Node { child.destroy(); }); this._children.length = 0; - this._children = null; } if (this._pureChildren) { this._pureChildren.length = 0; - this._pureChildren = null; } super.destroy(); }