-
Notifications
You must be signed in to change notification settings - Fork 131
/
page.js
113 lines (95 loc) · 3.59 KB
/
page.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import map from 'just-map-object'
import { $initial, $log } from '../../mixins'
import { pick, without, values, fromPairs } from '../../utils/functions'
import { prependHooks, linkProperties, initializeData } from '../../utils/helpers'
import * as wxOptionsGenerator from '../../utils/wx-options-generator'
import globals from '../../utils/globals'
import SigmundDataAdapter from '../../adapters/data/sigmund'
import Unit from './unit'
const MINA_PAGE_OPTIONS = ['data', 'onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll', 'onTabItemTap']
const MINA_PAGE_HOOKS = ['onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll', 'onTabItemTap']
const MINA_PAGE_METHODS = ['setData']
const MINA_PAGE_ATTRIBUTES = ['data', 'route']
const ADDON_BEFORE_HOOKS = {
'onLoad': 'beforeLoad',
}
const ADDON_OPTIONS = ['mixins', 'compute', 'methods', 'beforeLoad']
const OVERWRITED_OPTIONS = ['data', ...MINA_PAGE_HOOKS]
const OVERWRITED_METHODS = ['setData']
const OVERWRITED_ATTRIBUTES = ['data']
const PAGE_HOOKS = [...MINA_PAGE_HOOKS, ...values(ADDON_BEFORE_HOOKS)]
const PAGE_INITIAL_OPTIONS = {
mixins: [],
data: {},
compute () {},
// hooks: return { beforeLoad: [], ...... }
...fromPairs(PAGE_HOOKS.map((name) => [name, []])),
methods: {},
adapters: {
data: SigmundDataAdapter,
},
}
const BUILTIN_MIXINS = [$log, $initial]
class Page extends Unit {
static _mixins = []
static define (options = {}) {
// use mixins
options = this.mix(PAGE_INITIAL_OPTIONS, [...BUILTIN_MIXINS, ...this._mixins, ...(options.mixins || []), options])
// initilize data
options.data = initializeData(options.adapters.data, options.data)
// create wx-Page options
let page = {
data: options.adapters.data.toPlainObject(options.data()),
...wxOptionsGenerator.methods(options.methods),
...wxOptionsGenerator.lifecycles(MINA_PAGE_HOOKS.filter((name) => options[name].length > 0), (name) => ADDON_BEFORE_HOOKS[name]),
}
// creating Tina-Page on **wx-Page** loaded.
// !important: this hook is added to wx-Page directly, but not Tina-Page
page = prependHooks(page, {
onLoad () {
let instance = new Page({ options, $source: this })
// create bi-direction links
this.__tina_instance__ = instance
instance.$source = this
},
})
// apply wx-Page options
new globals.Page({
...pick(options, without(MINA_PAGE_OPTIONS, OVERWRITED_OPTIONS)),
...page,
})
}
constructor ({ options = {}, $source }) {
super()
// creating Tina-Page members
let members = {
data: options.data(),
compute: options.compute || function () {
return {}
},
...options.methods,
// hooks
...map(pick(options, PAGE_HOOKS), (name, handlers) => function (...args) {
return handlers.reduce((memory, handler) => handler.apply(this, args.concat(memory)), void 0)
}),
adapters: options.adapters,
}
// apply members into instance
for (let name in members) {
this[name] = members[name]
}
return this
}
}
// link the rest of wx-Component attributes and methods to Tina-Component
linkProperties({
TargetClass: Page,
getSourceInstance (context) {
return context.$source
},
properties: [...without(MINA_PAGE_ATTRIBUTES, OVERWRITED_ATTRIBUTES), ...without(MINA_PAGE_METHODS, OVERWRITED_METHODS)],
})
export default Page
export function getCurrentPages () {
return globals.getCurrentPages().map((page) => page.__tina_instance__)
}