diff --git a/.babelrc b/.babelrc index a1d01353..b10762ed 100644 --- a/.babelrc +++ b/.babelrc @@ -1,8 +1,8 @@ { - "presets": ["env"], + "presets": ["@babel/preset-env"], "env": { "test": { - "presets": ["env"], + "presets": ["@babel/preset-env"], "plugins": ["transform-flow-strip-types"] } } diff --git a/build/build.js b/build/build.js index 844b2ec0..c851eb68 100644 --- a/build/build.js +++ b/build/build.js @@ -37,11 +37,10 @@ function build(builds) { function buildEntry(config) { const output = config.output const { file } = output - return rollup.rollup(config) .then(bundle => bundle.generate(output)) - .then(({ code }) => { - return write(file, code) + .then((res) => { + return write(file, res.output[0].code) }) } diff --git a/build/config.js b/build/config.js index 69e1aeb9..c9debc9b 100644 --- a/build/config.js +++ b/build/config.js @@ -17,6 +17,12 @@ const banner = (name, version) => ` * Released under the MIT license. */ ` +const intro = ` +if (!global.process) { + global.process = process = {env:{}} +} +` + const resolveVue = p => { return path.resolve(process.cwd(), 'node_modules', 'vue/src/', p) + '/' } @@ -36,6 +42,7 @@ const builds = { entry: './platform/nativescript/framework.js', dest: './dist/index.js', moduleName: 'NativeScript-Vue', + intro: intro, banner: banner('NativeScript-Vue'), external(id) { return id.startsWith('tns-core-modules') || id.startsWith('weex') @@ -57,6 +64,7 @@ const genConfig = (name) => { input: opts.entry, external: opts.external, output: { + intro: opts.intro, file: opts.dest, format: opts.format || 'cjs', banner: opts.banner, @@ -72,10 +80,9 @@ const genConfig = (name) => { replace({ __WEEX__: false, __VERSION__: VueVersion, - 'process.env.NODE_ENV': "'development'", 'let _isServer': 'let _isServer = false', - 'process.env.VUE_VERSION': `'${VueVersion}'`, - 'process.env.NS_VUE_VERSION': `'${NSVueVersion}'` + 'process.env.VUE_VERSION': `process.env.VUE_VERSION || '${VueVersion}'`, + 'process.env.NS_VUE_VERSION': `process.env.NS_VUE_VERSION || '${NSVueVersion}'` }), flow(), buble(), diff --git a/package.json b/package.json index 18d8e5e0..ee917951 100644 --- a/package.json +++ b/package.json @@ -51,35 +51,35 @@ }, "dependencies": {}, "devDependencies": { - "@commitlint/cli": "^6.1.0", - "@commitlint/config-conventional": "^6.1.0", - "babel-jest": "^22.1.0", + "@babel/preset-env": "7.3.4", + "@commitlint/cli": "^7.5.2", + "@commitlint/config-conventional": "^7.5.0", + "babel-jest": "^24.1.0", "babel-plugin-transform-flow-strip-types": "^6.22.0", - "babel-preset-env": "^1.6.1", - "chalk": "^2.3.0", - "commitizen": "^2.10.1", - "conventional-changelog-cli": "^1.3.14", + "chalk": "^2.4.2", + "commitizen": "^3.0.7", + "conventional-changelog-cli": "^2.0.12", "cz-conventional-changelog": "^2.1.0", - "husky": "^0.15.0-rc.3", - "inquirer": "^5.0.1", - "jest": "^23.6.0", - "jest-junit": "^3.5.0", - "lint-staged": "^6.1.0", - "prettier": "^1.10.2", - "rollup": "^0.62.0", - "rollup-plugin-alias": "^1.4.0", - "rollup-plugin-buble": "^0.19.2", - "rollup-plugin-commonjs": "^9.1.3", + "husky": "^1.3.1", + "inquirer": "^6.2.2", + "jest": "^24.1.0", + "jest-junit": "^6.3.0", + "lint-staged": "^8.1.4", + "prettier": "^1.16.4", + "rollup": "^1.3.1", + "rollup-plugin-alias": "^1.5.1", + "rollup-plugin-buble": "^0.19.6", + "rollup-plugin-commonjs": "^9.2.1", "rollup-plugin-flow-no-whitespace": "^1.0.0", - "rollup-plugin-node-resolve": "^3.3.0", - "rollup-plugin-replace": "^2.0.0", + "rollup-plugin-node-resolve": "^4.0.1", + "rollup-plugin-replace": "^2.1.0", "rollup-plugin-resolve-aliases": "^0.2.0", "rollup-watch": "^4.3.1", - "semver": "^5.5.0", - "set-value": "^2.0.0", - "tns-core-modules": "4.2.0", + "semver": "^5.6.0", + "set-value": "^3.0.0", + "tns-core-modules": "5.2.1", "util-inspect": "^0.1.8", - "vue": "^2.5.17" + "vue": "^2.6.10" }, "jest": { "verbose": true, diff --git a/platform/nativescript/compiler.js b/platform/nativescript/compiler.js index a5b605c8..5bbda91a 100644 --- a/platform/nativescript/compiler.js +++ b/platform/nativescript/compiler.js @@ -1,3 +1,4 @@ export { parseComponent } from './compiler/sfc/parser' export { compile, compileToFunctions } from './compiler/index' -export { registerElement } from './element-registry' +// register all components +export { registerElement } from './compiler/element-registry' diff --git a/platform/nativescript/compiler/directives/model.js b/platform/nativescript/compiler/directives/model.js index 8e6dd1e3..185ed347 100644 --- a/platform/nativescript/compiler/directives/model.js +++ b/platform/nativescript/compiler/directives/model.js @@ -1,5 +1,5 @@ import { genComponentModel, genAssignmentCode } from 'compiler/directives/model' -import { isKnownView, getViewMeta } from '../../element-registry' +import { isKnownView, getViewMeta } from '../../element-register' import { addHandler, addAttr } from 'compiler/helpers' export default function model(el, dir) { diff --git a/platform/nativescript/compiler/element-registry.js b/platform/nativescript/compiler/element-registry.js new file mode 100644 index 00000000..9cc537fa --- /dev/null +++ b/platform/nativescript/compiler/element-registry.js @@ -0,0 +1,211 @@ +import { registerElement } from '../element-register' +export { registerElement } + +registerElement( + 'AbsoluteLayout', + () => require('tns-core-modules/ui/layouts/absolute-layout').AbsoluteLayout +) +registerElement( + 'ActivityIndicator', + () => require('tns-core-modules/ui/activity-indicator').ActivityIndicator +) +registerElement('Border', () => require('tns-core-modules/ui/border').Border) +registerElement('Button', () => require('tns-core-modules/ui/button').Button) +registerElement( + 'ContentView', + () => require('tns-core-modules/ui/content-view').ContentView +) +registerElement( + 'DatePicker', + () => require('tns-core-modules/ui/date-picker').DatePicker, + { + model: { + prop: 'date', + event: 'dateChange' + } + } +) +registerElement( + 'DockLayout', + () => require('tns-core-modules/ui/layouts/dock-layout').DockLayout +) +registerElement( + 'GridLayout', + () => require('tns-core-modules/ui/layouts/grid-layout').GridLayout +) +registerElement( + 'HtmlView', + () => require('tns-core-modules/ui/html-view').HtmlView +) +registerElement('Image', () => require('tns-core-modules/ui/image').Image) +registerElement('img', () => require('tns-core-modules/ui/image').Image) +registerElement('Label', () => require('tns-core-modules/ui/label').Label) +registerElement( + 'ListPicker', + () => require('tns-core-modules/ui/list-picker').ListPicker, + { + model: { + prop: 'selectedIndex', + event: 'selectedIndexChange' + } + } +) +registerElement( + 'NativeActionBar', + () => require('tns-core-modules/ui/action-bar').ActionBar +) +registerElement( + 'NativeActionItem', + () => require('tns-core-modules/ui/action-bar').ActionItem +) +registerElement( + 'NativeListView', + () => require('tns-core-modules/ui/list-view').ListView +) +registerElement( + 'NativeNavigationButton', + () => require('tns-core-modules/ui/action-bar').NavigationButton +) +registerElement('Page', () => require('tns-core-modules/ui/page').Page, { + skipAddToDom: true +}) +registerElement( + 'Placeholder', + () => require('tns-core-modules/ui/placeholder').Placeholder +) +registerElement( + 'Progress', + () => require('tns-core-modules/ui/progress').Progress +) +registerElement( + 'ProxyViewContainer', + () => require('tns-core-modules/ui/proxy-view-container').ProxyViewContainer +) +registerElement( + 'Repeater', + () => require('tns-core-modules/ui/repeater').Repeater +) +registerElement( + 'ScrollView', + () => require('tns-core-modules/ui/scroll-view').ScrollView +) +registerElement( + 'SearchBar', + () => require('tns-core-modules/ui/search-bar').SearchBar, + { + model: { + prop: 'text', + event: 'textChange' + } + } +) +registerElement( + 'SegmentedBar', + () => require('tns-core-modules/ui/segmented-bar').SegmentedBar, + { + model: { + prop: 'selectedIndex', + event: 'selectedIndexChange' + } + } +) +registerElement( + 'SegmentedBarItem', + () => require('tns-core-modules/ui/segmented-bar').SegmentedBarItem +) +registerElement('Slider', () => require('tns-core-modules/ui/slider').Slider, { + model: { + prop: 'value', + event: 'valueChange' + } +}) +registerElement( + 'StackLayout', + () => require('tns-core-modules/ui/layouts/stack-layout').StackLayout +) +registerElement( + 'FlexboxLayout', + () => require('tns-core-modules/ui/layouts/flexbox-layout').FlexboxLayout +) +registerElement('Switch', () => require('tns-core-modules/ui/switch').Switch, { + model: { + prop: 'checked', + event: 'checkedChange' + } +}) + +registerElement( + 'NativeTabView', + () => require('tns-core-modules/ui/tab-view').TabView, + { + model: { + prop: 'selectedIndex', + event: 'selectedIndexChange' + } + } +) +registerElement( + 'NativeTabViewItem', + () => require('tns-core-modules/ui/tab-view').TabViewItem, + { + skipAddToDom: true + } +) + +registerElement( + 'TextField', + () => require('tns-core-modules/ui/text-field').TextField +) +registerElement( + 'TextView', + () => require('tns-core-modules/ui/text-view').TextView +) +registerElement( + 'TimePicker', + () => require('tns-core-modules/ui/time-picker').TimePicker, + { + model: { + prop: 'time', + event: 'timeChange' + } + } +) +registerElement( + 'WebView', + () => require('tns-core-modules/ui/web-view').WebView +) +registerElement( + 'WrapLayout', + () => require('tns-core-modules/ui/layouts/wrap-layout').WrapLayout +) +registerElement( + 'FormattedString', + () => require('text/formatted-string').FormattedString +) +registerElement('Span', () => require('text/span').Span) + +registerElement( + 'DetachedContainer', + () => require('tns-core-modules/ui/proxy-view-container').ProxyViewContainer, + { + skipAddToDom: true + } +) +registerElement( + 'DetachedText', + () => require('tns-core-modules/ui/placeholder').Placeholder, + { + skipAddToDom: true + } +) +registerElement( + 'Comment', + () => require('tns-core-modules/ui/placeholder').Placeholder +) +registerElement( + 'Document', + () => require('tns-core-modules/ui/proxy-view-container').ProxyViewContainer, + { + skipAddToDom: true + } +) diff --git a/platform/nativescript/compiler/index.js b/platform/nativescript/compiler/index.js index 447f26e4..dcef6b3a 100644 --- a/platform/nativescript/compiler/index.js +++ b/platform/nativescript/compiler/index.js @@ -1,6 +1,6 @@ import { createCompiler } from 'compiler/index' import { genStaticKeys } from 'shared/util' - +import { registerElement } from '../element-register' import modules from './modules/index' import directives from './directives/index' @@ -25,4 +25,4 @@ export const baseOptions = { } const { compile, compileToFunctions } = createCompiler(baseOptions) -export { compile, compileToFunctions } +export { compile, compileToFunctions, registerElement } diff --git a/platform/nativescript/compiler/modules/for.js b/platform/nativescript/compiler/modules/for.js index 0e6b8294..546b901b 100644 --- a/platform/nativescript/compiler/modules/for.js +++ b/platform/nativescript/compiler/modules/for.js @@ -1,5 +1,5 @@ import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers' -import { normalizeElementName } from '../../element-registry' +import { normalizeElementName } from '../../element-register' import { parseFor } from 'compiler/parser/index' import { warn } from 'core/util/debug' diff --git a/platform/nativescript/compiler/modules/router.js b/platform/nativescript/compiler/modules/router.js index fcf9f414..17f635e7 100644 --- a/platform/nativescript/compiler/modules/router.js +++ b/platform/nativescript/compiler/modules/router.js @@ -1,4 +1,4 @@ -import { normalizeElementName } from '../../element-registry' +import { normalizeElementName } from '../../element-register' import { addAttr } from 'compiler/helpers' function preTransformNode(el) { diff --git a/platform/nativescript/compiler/modules/view.js b/platform/nativescript/compiler/modules/view.js index 26095321..fd67130b 100644 --- a/platform/nativescript/compiler/modules/view.js +++ b/platform/nativescript/compiler/modules/view.js @@ -11,8 +11,8 @@ function transformNode(el) { mods[mod] = true return mods }, {}) - getAndRemoveAttr(el, attr) - addDirective(el, 'view', `v-view:${attrName}`, '', arg, modifiers) + getAndRemoveAttr(el, attr, true) + addDirective(el, 'view', `v-view:${attrName}`, '', arg, false, modifiers) } } diff --git a/platform/nativescript/constants.js b/platform/nativescript/constants.js new file mode 100644 index 00000000..8fd865ec --- /dev/null +++ b/platform/nativescript/constants.js @@ -0,0 +1 @@ +export const VUE_VM_REF = '__vue_vm_ref__' diff --git a/platform/nativescript/element-register.js b/platform/nativescript/element-register.js new file mode 100644 index 00000000..77bc6534 --- /dev/null +++ b/platform/nativescript/element-register.js @@ -0,0 +1,85 @@ + +const elementMap = {} +const nativeRegExp = /Native/gi +const dashRegExp = /-/g + +const defaultViewMeta = { + skipAddToDom: false, + isUnaryTag: false, + tagNamespace: '', + canBeLeftOpenTag: false, + model: null, + component: null +} + +export function normalizeElementName(elementName) { + return `native${elementName + .replace(nativeRegExp, '') + .replace(dashRegExp, '') + .toLowerCase()}` +} + +export function registerElement(elementName, resolver, meta) { + const normalizedName = normalizeElementName(elementName) + + meta = Object.assign({}, defaultViewMeta, meta) + + if (elementMap[normalizedName]) { + throw new Error(`Element for ${elementName} already registered.`) + } + + if (!meta.component) { + // if no Vue component is passed, wrap the simpler vue component + // which bind the events and attributes to the NS one + meta.component = { + functional: true, + model: meta.model, + render: (h, { data, children }) => { + return h(normalizedName, data, children) + } + } + } + meta.component.name = elementName + + const entry = { + resolver: resolver, + meta: meta + } + elementMap[normalizedName] = entry +} + +export function getElementMap() { + return elementMap +} + +export function getViewClass(elementName) { + const normalizedName = normalizeElementName(elementName) + const entry = elementMap[normalizedName] + + if (!entry) { + throw new TypeError(`No known component for element ${elementName}.`) + } + + try { + return entry.resolver() + } catch (e) { + throw new TypeError(`Could not load view for: ${elementName}. ${e}`) + } +} + +export function getViewMeta(elementName) { + const normalizedName = normalizeElementName(elementName) + + let meta = defaultViewMeta + const entry = elementMap[normalizedName] + + if (entry && entry.meta) { + meta = entry.meta + } + + return meta +} + +export function isKnownView(elementName) { + return elementMap[normalizeElementName(elementName)] +} diff --git a/platform/nativescript/element-registry.js b/platform/nativescript/element-registry.js index 9a506b8b..16eb4094 100644 --- a/platform/nativescript/element-registry.js +++ b/platform/nativescript/element-registry.js @@ -1,89 +1,6 @@ import * as builtInComponents from './runtime/components' - -const elementMap = {} -const nativeRegExp = /Native/gi -const dashRegExp = /-/g - -const defaultViewMeta = { - skipAddToDom: false, - isUnaryTag: false, - tagNamespace: '', - canBeLeftOpenTag: false, - model: null, - component: null -} - -export function normalizeElementName(elementName) { - return `native${elementName - .replace(nativeRegExp, '') - .replace(dashRegExp, '') - .toLowerCase()}` -} - -export function registerElement(elementName, resolver, meta) { - const normalizedName = normalizeElementName(elementName) - - meta = Object.assign({}, defaultViewMeta, meta) - - if (elementMap[normalizedName]) { - throw new Error(`Element for ${elementName} already registered.`) - } - - if (!meta.component) { - // if no Vue component is passed, wrap the simpler vue component - // which bind the events and attributes to the NS one - meta.component = { - functional: true, - model: meta.model, - render: (h, { data, children }) => { - return h(normalizedName, data, children) - } - } - } - meta.component.name = elementName - - const entry = { - resolver: resolver, - meta: meta - } - elementMap[normalizedName] = entry -} - -export function getElementMap() { - return elementMap -} - -export function getViewClass(elementName) { - const normalizedName = normalizeElementName(elementName) - const entry = elementMap[normalizedName] - - if (!entry) { - throw new TypeError(`No known component for element ${elementName}.`) - } - - try { - return entry.resolver() - } catch (e) { - throw new TypeError(`Could not load view for: ${elementName}. ${e}`) - } -} - -export function getViewMeta(elementName) { - const normalizedName = normalizeElementName(elementName) - - let meta = defaultViewMeta - const entry = elementMap[normalizedName] - - if (entry && entry.meta) { - meta = entry.meta - } - - return meta -} - -export function isKnownView(elementName) { - return elementMap[normalizeElementName(elementName)] -} +import { registerElement } from './element-register' +export { registerElement } registerElement( 'ActionBar', diff --git a/platform/nativescript/framework.js b/platform/nativescript/framework.js index a1b2d3f8..74cf920d 100644 --- a/platform/nativescript/framework.js +++ b/platform/nativescript/framework.js @@ -1,9 +1,3 @@ -// This is required because some of the third party plugins rely on this -// and cause errors since there is no process variable in {N}. -global.process = global.process || {} -global.process.env = global.process.env || {} - -import inspect from 'util-inspect' import { topmost } from 'tns-core-modules/ui/frame' import application from 'tns-core-modules/application' import Vue from './runtime/index' @@ -19,27 +13,6 @@ setVue(Vue) Vue.use(ModalPlugin) Vue.use(NavigatorPlugin) -const newLineRegExp = /\\n/g - -console.log = (function(log, inspect, Vue) { - return function(...args) { - return log.call( - this, - ...Array.prototype.map.call(args, function(arg) { - return inspect(arg, { - depth: 2, - colors: Vue.config.debug, - showHidden: true - }).replace(newLineRegExp, '\n') - }) - ) - } -})(console.log, inspect, Vue) - -console.keys = function(object) { - console.log(Object.keys(object)) -} - // this fixes the issue of resuming the application // however this might not be the desired functionality // Todo: figure out if there is a better way to fix application resume. diff --git a/platform/nativescript/renderer/ElementNode.js b/platform/nativescript/renderer/ElementNode.js index a4d4126f..ba3f26f6 100644 --- a/platform/nativescript/renderer/ElementNode.js +++ b/platform/nativescript/renderer/ElementNode.js @@ -1,4 +1,4 @@ -import { getViewClass } from '../element-registry' +import { getViewClass } from '../element-register' import ViewNode from './ViewNode' export const VUE_ELEMENT_REF = '__vue_element_ref__' diff --git a/platform/nativescript/renderer/ViewNode.js b/platform/nativescript/renderer/ViewNode.js index 32578a69..80a65c1c 100644 --- a/platform/nativescript/renderer/ViewNode.js +++ b/platform/nativescript/renderer/ViewNode.js @@ -1,6 +1,6 @@ import set from 'set-value' -import { getViewMeta, normalizeElementName } from '../element-registry' +import { getViewMeta, normalizeElementName } from '../element-register' import * as viewUtil from './utils' import { isAndroid, isIOS } from 'tns-core-modules/platform' import * as types from 'tns-core-modules/utils/types' diff --git a/platform/nativescript/runtime/components/v-template.js b/platform/nativescript/runtime/components/v-template.js index 56c3298c..694688f7 100644 --- a/platform/nativescript/runtime/components/v-template.js +++ b/platform/nativescript/runtime/components/v-template.js @@ -69,7 +69,14 @@ export class TemplateBag { } patchTemplate(name, context, oldVnode) { - const vnode = this._templateMap.get(name).scopedFn(context) + let vnode = this._templateMap.get(name).scopedFn(context) + // in 2.6 scopedFn returns an array! + if (Array.isArray(vnode)) { + vnode = vnode[0] + } + if (Array.isArray(oldVnode)) { + oldVnode = oldVnode[0]; + } const nativeView = patch(oldVnode, vnode).nativeView nativeView[VUE_VIEW] = vnode diff --git a/platform/nativescript/runtime/directives/view.js b/platform/nativescript/runtime/directives/view.js index 77260236..4757ddb5 100644 --- a/platform/nativescript/runtime/directives/view.js +++ b/platform/nativescript/runtime/directives/view.js @@ -1,7 +1,8 @@ export default { - inserted(el, { arg, modifiers }) { + inserted(el, binding, vnode, oldNode) { const parent = el.parentNode.nativeView - + const arg = binding.arg; + const modifiers = binding.modifiers; if (parent) { if (modifiers.array) { parent[arg] = (parent[arg] || []).push(el.nativeView) diff --git a/platform/nativescript/runtime/index.js b/platform/nativescript/runtime/index.js index b858f902..a2dc2386 100644 --- a/platform/nativescript/runtime/index.js +++ b/platform/nativescript/runtime/index.js @@ -3,7 +3,8 @@ import { warn } from 'core/util/index' import { patch } from './patch' import { mountComponent } from 'core/instance/lifecycle' import { compileToFunctions } from '../compiler/index' -import { registerElement, getElementMap } from '../element-registry' +import { getElementMap } from '../element-register' +import { registerElement } from '../element-registry' import { makeMap } from 'shared/util' import Vue from 'core/index' @@ -12,8 +13,6 @@ import platformDirectives from './directives/index' import { mustUseProp, isReservedTag, isUnknownElement } from '../util/index' -export const VUE_VM_REF = '__vue_vm_ref__' - Vue.config.mustUseProp = mustUseProp Vue.config.isReservedTag = isReservedTag Vue.config.isUnknownElement = isUnknownElement diff --git a/platform/nativescript/util/index.js b/platform/nativescript/util/index.js index 5f34a84f..9232d6bb 100644 --- a/platform/nativescript/util/index.js +++ b/platform/nativescript/util/index.js @@ -1,6 +1,6 @@ -import { isKnownView, getViewMeta, getViewClass } from '../element-registry' +import { isKnownView, getViewMeta, getViewClass } from '../element-register' import { makeMap, once } from 'shared/util' -import { VUE_VM_REF } from '../runtime' +import { VUE_VM_REF } from '../constants' export const isReservedTag = makeMap('template', true)