glib-web 4.24.1 → 4.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/action.js +8 -5
- package/actions/sheets/close.js +10 -0
- package/actions/sheets/open.js +35 -0
- package/actions/sheets/show.js +14 -0
- package/app.vue +47 -15
- package/components/_chip.vue +0 -5
- package/components/_icon.vue +1 -6
- package/components/_internal_button.vue +0 -5
- package/components/composable/form.js +2 -2
- package/components/fields/_buttonDate.vue +1 -0
- package/components/fields/_patternText.vue +1 -0
- package/components/fields/_select.vue +4 -8
- package/components/fields/multiUpload.vue +1 -2
- package/components/fields/sign.vue +2 -2
- package/components/mixins/events.js +10 -1
- package/components/mixins/tooltip.js +7 -1
- package/components/popover.vue +2 -2
- package/cypress/downloads/downloads.html +0 -0
- package/cypress/downloads/downloads.html.crdownload +0 -0
- package/cypress/e2e/glib-web/lifecycle.cy.ts +28 -0
- package/cypress/e2e/glib-web/multiupload.cy.ts +2 -0
- package/cypress/e2e/glib-web/selectable.cy.ts +1 -1
- package/package.json +1 -1
- package/store.js +8 -3
- package/utils/history.js +5 -1
- package/utils/http.js +2 -1
package/action.js
CHANGED
|
@@ -22,6 +22,9 @@ import ActionsSnackbarsAlert from "./actions/snackbars/alert";
|
|
|
22
22
|
import ActionsSnackbarsSelect from "./actions/snackbars/select";
|
|
23
23
|
|
|
24
24
|
import ActionsSheetsSelect from "./actions/sheets/select";
|
|
25
|
+
import ActionsSheetsOpen from "./actions/sheets/open";
|
|
26
|
+
import ActionsSheetsShow from "./actions/sheets/show";
|
|
27
|
+
import ActionsSheetsClose from "./actions/sheets/close";
|
|
25
28
|
|
|
26
29
|
import ActionsWindowsClose from "./actions/windows/close";
|
|
27
30
|
import ActionsWindowsCloseAll from "./actions/windows/closeAll";
|
|
@@ -80,8 +83,6 @@ import ActionListsAppend from "./actions/lists/append";
|
|
|
80
83
|
|
|
81
84
|
import ActionBottomBannersOpen from "./actions/bottom_banners/open";
|
|
82
85
|
import ActionBottomBannersClose from "./actions/bottom_banners/close";
|
|
83
|
-
import ActionRightBannersOpen from "./actions/right_banners/open";
|
|
84
|
-
import ActionRightBannersClose from "./actions/right_banners/close";
|
|
85
86
|
|
|
86
87
|
import ActionGlobalStatesWatch from "./actions/global_states/watch";
|
|
87
88
|
import ActionGlobalStatesSet from "./actions/global_states/set";
|
|
@@ -124,6 +125,9 @@ const actions = {
|
|
|
124
125
|
"snackbars/select": ActionsSnackbarsSelect,
|
|
125
126
|
|
|
126
127
|
"sheets/select": ActionsSheetsSelect,
|
|
128
|
+
"sheets/open": ActionsSheetsOpen,
|
|
129
|
+
"sheets/show": ActionsSheetsShow,
|
|
130
|
+
"sheets/close": ActionsSheetsClose,
|
|
127
131
|
|
|
128
132
|
"windows/close": ActionsWindowsClose,
|
|
129
133
|
"windows/closeAll": ActionsWindowsCloseAll,
|
|
@@ -179,12 +183,10 @@ const actions = {
|
|
|
179
183
|
|
|
180
184
|
"lists/append": ActionListsAppend,
|
|
181
185
|
|
|
186
|
+
// deprecated
|
|
182
187
|
"bottomBanners/open": ActionBottomBannersOpen,
|
|
183
188
|
"bottomBanners/close": ActionBottomBannersClose,
|
|
184
189
|
|
|
185
|
-
"rightBanners/open": ActionRightBannersOpen,
|
|
186
|
-
"rightBanners/close": ActionRightBannersClose,
|
|
187
|
-
|
|
188
190
|
"globalStates/watch": ActionGlobalStatesWatch,
|
|
189
191
|
"globalStates/set": ActionGlobalStatesSet,
|
|
190
192
|
|
|
@@ -327,6 +329,7 @@ export default class Action {
|
|
|
327
329
|
dialog.updateContent(response);
|
|
328
330
|
} else {
|
|
329
331
|
jsonView.page = response;
|
|
332
|
+
jsonView.source = 'server';
|
|
330
333
|
}
|
|
331
334
|
});
|
|
332
335
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { vueApp } from "../../store";
|
|
2
|
+
import http from "../../utils/http";
|
|
3
|
+
|
|
4
|
+
export default class {
|
|
5
|
+
execute(spec, component) {
|
|
6
|
+
|
|
7
|
+
const { placement } = spec;
|
|
8
|
+
|
|
9
|
+
http.execute(
|
|
10
|
+
spec,
|
|
11
|
+
'GET',
|
|
12
|
+
component,
|
|
13
|
+
(response) => {
|
|
14
|
+
vueApp.sheet = {
|
|
15
|
+
spec: response.body,
|
|
16
|
+
show: true,
|
|
17
|
+
placement
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
() => {
|
|
21
|
+
vueApp.sheet = {
|
|
22
|
+
spec: {
|
|
23
|
+
childViews: [
|
|
24
|
+
{ view: 'p', text: 'Failed to load' },
|
|
25
|
+
{ view: 'spacer', height: 8 },
|
|
26
|
+
{ view: 'button', text: 'close', onClick: { action: 'sheets/close' } }
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
show: true,
|
|
30
|
+
placement
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
package/app.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-app :class="page.styleClasses" ref="appRef">
|
|
3
3
|
<component :is="containerComponent" :spec="formSpec" :style="'height: 100%;'">
|
|
4
|
-
<nav-layout ref="navBar" @mounted="updateMainHeight()" :page="page" />
|
|
4
|
+
<nav-layout ref="navBar" @mounted="updateMainHeight()" :page="page" :key="`navBar-${page.key}`" />
|
|
5
5
|
|
|
6
6
|
<v-progress-linear color="primary" v-if="vueApp.indicator" :indeterminate="true" height="5"
|
|
7
7
|
style="position: fixed; z-index: 4">
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<v-main :style="`height: ${mainHeight}px;`">
|
|
11
11
|
<v-container :fluid="page.template == 'fullWidth'" :class="containerClasses">
|
|
12
|
-
<div class="pages-header">
|
|
12
|
+
<div class="pages-header" :key="`page-header-${page.key}`">
|
|
13
13
|
<panels-responsive :spec="header" />
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<panels-responsive :key="`footer-${page.key}`" class="body-footer" :spec="bodyFooter" />
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
|
-
<div class="pages-footer">
|
|
22
|
+
<div class="pages-footer" :key="`page-footer-${page.key}`">
|
|
23
23
|
<panels-responsive :spec="footer" />
|
|
24
24
|
</div>
|
|
25
25
|
</v-container>
|
|
@@ -30,9 +30,8 @@
|
|
|
30
30
|
<panels-responsive :spec="vueApp.tooltipSpec"></panels-responsive>
|
|
31
31
|
</div>
|
|
32
32
|
<Transition name="slide-fade">
|
|
33
|
-
<v-sheet v-if="vueApp.
|
|
34
|
-
|
|
35
|
-
<glib-component v-for="(rbSpec, index) in vueApp.rightBanners.spec.childViews" :spec="rbSpec"
|
|
33
|
+
<v-sheet v-if="vueApp.sheet.show" position="fixed" :class="`views-sheet ${vueApp.sheet.placement}`">
|
|
34
|
+
<glib-component v-for="(rbSpec, index) in vueApp.sheet.spec.childViews" :spec="rbSpec"
|
|
36
35
|
:key="index"></glib-component>
|
|
37
36
|
</v-sheet>
|
|
38
37
|
</Transition>
|
|
@@ -49,7 +48,7 @@ import Utils from "./utils/helper";
|
|
|
49
48
|
// import phoenixSocketMixin from "./components/mixins/ws/phoenixSocket.js";
|
|
50
49
|
// import actionCableMixin from "./components/mixins/ws/actionCable.js";
|
|
51
50
|
import FormPanel from "./components/panels/form.vue";
|
|
52
|
-
import { vueApp } from "./store";
|
|
51
|
+
import { isRerender, vueApp } from "./store";
|
|
53
52
|
import { useSocket } from "./components/composable/socket";
|
|
54
53
|
import { usePasteable } from "./components/composable/pasteable";
|
|
55
54
|
import { computed, onMounted, provide, ref } from "vue";
|
|
@@ -141,7 +140,11 @@ export default {
|
|
|
141
140
|
`Version: ${Utils.settings.appVersion} (${Utils.settings.env})`
|
|
142
141
|
);
|
|
143
142
|
Utils.history.saveInitialContent(this.page);
|
|
144
|
-
Utils.history.restoreOnBackOrForward(
|
|
143
|
+
Utils.history.restoreOnBackOrForward({
|
|
144
|
+
onAfterBack: () => {
|
|
145
|
+
if (isRerender) GLib.action.execute(this.page.onRerender, this);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
145
148
|
watchGlibEvent();
|
|
146
149
|
},
|
|
147
150
|
methods: {
|
|
@@ -167,6 +170,12 @@ export default {
|
|
|
167
170
|
},
|
|
168
171
|
true
|
|
169
172
|
);
|
|
173
|
+
|
|
174
|
+
if (isRerender()) {
|
|
175
|
+
GLib.action.execute(this.page.onRerender, this);
|
|
176
|
+
} else {
|
|
177
|
+
GLib.action.execute(this.page.onLoad, this);
|
|
178
|
+
}
|
|
170
179
|
},
|
|
171
180
|
$ready() {
|
|
172
181
|
this.$type.ifString(this.page.title, (title) => {
|
|
@@ -195,10 +204,6 @@ export default {
|
|
|
195
204
|
GLib.action.execute(this.page.onRefocus, this);
|
|
196
205
|
GLib.action.execute(this.page.replayGetResponse, this);
|
|
197
206
|
});
|
|
198
|
-
} else {
|
|
199
|
-
setTimeout(() => {
|
|
200
|
-
GLib.action.execute(this.page.onLoad, this);
|
|
201
|
-
});
|
|
202
207
|
}
|
|
203
208
|
|
|
204
209
|
// Use nextTick() to allow time for the navBar to complete initialization.
|
|
@@ -396,11 +401,38 @@ body,
|
|
|
396
401
|
z-index: 99;
|
|
397
402
|
}
|
|
398
403
|
|
|
399
|
-
.
|
|
400
|
-
z-index:
|
|
401
|
-
right: 0;
|
|
404
|
+
.views-sheet {
|
|
405
|
+
z-index: 1007;
|
|
402
406
|
box-shadow: 0px 4px 12px 0px #0000001A;
|
|
403
407
|
overflow-y: auto;
|
|
408
|
+
|
|
409
|
+
&.top {
|
|
410
|
+
top: 0;
|
|
411
|
+
height: 100%;
|
|
412
|
+
max-height: 160px;
|
|
413
|
+
width: 100%;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
&.right {
|
|
417
|
+
right: 0;
|
|
418
|
+
height: 100%;
|
|
419
|
+
width: 100%;
|
|
420
|
+
max-width: 684px;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
&.bottom {
|
|
424
|
+
bottom: 0;
|
|
425
|
+
height: 100%;
|
|
426
|
+
max-height: 160px;
|
|
427
|
+
width: 100%;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
&.left {
|
|
431
|
+
left: 0;
|
|
432
|
+
height: 100%;
|
|
433
|
+
width: 100%;
|
|
434
|
+
max-width: 684px;
|
|
435
|
+
}
|
|
404
436
|
}
|
|
405
437
|
|
|
406
438
|
.slide-fade-enter-active {
|
package/components/_chip.vue
CHANGED
package/components/_icon.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-icon class="aligner" :style="$styles()" :class="cssClasses" :size="icon.size" :color="color">{{
|
|
3
3
|
icon.name
|
|
4
|
-
|
|
4
|
+
}}</v-icon>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script>
|
|
@@ -48,11 +48,6 @@ export default {
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
methods: {
|
|
51
|
-
$ready() {
|
|
52
|
-
nextTick(() => { // Make sure the component has been initialized and registered.
|
|
53
|
-
GLib.action.execute(this.spec.onLoad, this);
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
51
|
|
|
57
52
|
// $ready() {
|
|
58
53
|
// // this.badge = this.spec.badge || {};
|
|
@@ -42,11 +42,6 @@ export default {
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
methods: {
|
|
45
|
-
$ready() {
|
|
46
|
-
nextTick(() => { // Make sure the component has been initialized and registered.
|
|
47
|
-
GLib.action.execute(this.spec.onLoad, this);
|
|
48
|
-
});
|
|
49
|
-
},
|
|
50
45
|
// $ready() {
|
|
51
46
|
// this.$type.ifArray(this.spec.styleClasses, val => {
|
|
52
47
|
// this.linkStyling = val.includes("link");
|
|
@@ -89,7 +89,7 @@ function useGlibForm({ formRef }) {
|
|
|
89
89
|
return { updateDirtyState };
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
function useGlibInput({ props }) {
|
|
92
|
+
function useGlibInput({ props, cacheValue = true }) {
|
|
93
93
|
// setup dirty state
|
|
94
94
|
const registeredInputs = inject('registeredInputs', null);
|
|
95
95
|
const ignoredDirtyCheckFields = inject('ignoredDirtyCheckFields', null);
|
|
@@ -106,7 +106,7 @@ function useGlibInput({ props }) {
|
|
|
106
106
|
|
|
107
107
|
// save fieldModel to spec so data still intact even if component unmounted
|
|
108
108
|
onBeforeUpdate(() => {
|
|
109
|
-
if (!instance.ctx.spec) return;
|
|
109
|
+
if (!instance.ctx.spec || !cacheValue) return;
|
|
110
110
|
instance.ctx.spec.value = instance.ctx.fieldModel;
|
|
111
111
|
});
|
|
112
112
|
|
|
@@ -75,7 +75,7 @@ export default {
|
|
|
75
75
|
setup(props) {
|
|
76
76
|
useGlibInput({ props });
|
|
77
77
|
|
|
78
|
-
const fieldModel = ref(props.
|
|
78
|
+
const fieldModel = ref(props.spec.value || props.defaultValue);
|
|
79
79
|
const options = ref(props.spec.options);
|
|
80
80
|
const append = props.spec.append || {};
|
|
81
81
|
|
|
@@ -139,13 +139,9 @@ export default {
|
|
|
139
139
|
}
|
|
140
140
|
},
|
|
141
141
|
methods: {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// return;
|
|
146
|
-
// }
|
|
147
|
-
// this.fieldModel = this.spec.value;
|
|
148
|
-
// },
|
|
142
|
+
_linkFieldModels(valueChanged) {
|
|
143
|
+
this.fieldModel = this.spec.value || this.defaultValue;
|
|
144
|
+
},
|
|
149
145
|
onChange() {
|
|
150
146
|
this.$executeOnChange();
|
|
151
147
|
const containerEl = this.$refs.container;
|
|
@@ -49,11 +49,11 @@ import * as uploader from "../composable/upload";
|
|
|
49
49
|
import { useFileUtils } from "../composable/file";
|
|
50
50
|
import { useGlibInput } from "../composable/form";
|
|
51
51
|
|
|
52
|
-
useGlibInput({ props });
|
|
53
|
-
|
|
54
52
|
const { makeKey, Item } = useFileUtils();
|
|
55
53
|
const props = defineProps(['spec']);
|
|
56
54
|
|
|
55
|
+
useGlibInput({ props });
|
|
56
|
+
|
|
57
57
|
const canvas = ref(null);
|
|
58
58
|
const context = computed(() => {
|
|
59
59
|
if (!canvas.value) return;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Action from "../../action";
|
|
2
2
|
import UrlUtils from "../../utils/url";
|
|
3
3
|
import * as TypeUtils from "../../utils/type";
|
|
4
|
-
import { vueApp } from "../../store";
|
|
4
|
+
import { isRerender, vueApp } from "../../store";
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
data() {
|
|
@@ -41,6 +41,15 @@ export default {
|
|
|
41
41
|
if (this.spec && this.spec.onChangeAndLoad && this.$registryEnabled()) {
|
|
42
42
|
this.$executeOnChange();
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
if (this.spec && this.$registryEnabled()) {
|
|
46
|
+
if (isRerender()) {
|
|
47
|
+
GLib.action.execute(this.spec.onRerender, this);
|
|
48
|
+
} else {
|
|
49
|
+
GLib.action.execute(this.spec.onLoad, this);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
44
53
|
},
|
|
45
54
|
beforeUpdate() {
|
|
46
55
|
if (vueApp.isStale) {
|
|
@@ -24,7 +24,13 @@ export default defineComponent({
|
|
|
24
24
|
const key = Math.random().toString(36).slice(2, 7);
|
|
25
25
|
|
|
26
26
|
const handleMouseEnter = () => {
|
|
27
|
-
|
|
27
|
+
const properties = {
|
|
28
|
+
body: { childViews: [this.properties] },
|
|
29
|
+
key: key,
|
|
30
|
+
placement: this.spec.tooltip.placement || 'top',
|
|
31
|
+
styleClass: 'views-tooltip'
|
|
32
|
+
};
|
|
33
|
+
launch.popover.open(properties, this);
|
|
28
34
|
};
|
|
29
35
|
const handleMouseLeave = () => {
|
|
30
36
|
launch.popover.close({ key: key });
|
package/components/popover.vue
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
| 'left-end'
|
|
15
15
|
-->
|
|
16
16
|
|
|
17
|
-
<common-responsive v-if="toggle" ref="container" :spec="spec.body" />
|
|
17
|
+
<common-responsive :class="`views-popovers ${spec.styleClass}`" v-if="toggle" ref="container" :spec="spec.body" />
|
|
18
18
|
|
|
19
19
|
</template>
|
|
20
20
|
|
|
@@ -25,7 +25,7 @@ import { driver } from "driver.js";
|
|
|
25
25
|
import 'driver.js/dist/driver.css';
|
|
26
26
|
|
|
27
27
|
export default {
|
|
28
|
-
props: ['spec', 'reference', 'placeholder'],
|
|
28
|
+
props: ['spec', 'reference', 'placeholder', 'styleClass'],
|
|
29
29
|
data() {
|
|
30
30
|
const allowClose = this.spec.overlay ? this.spec.overlay.closeOnFocus : true;
|
|
31
31
|
return {
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
const url = testPageUrl('lifecycle')
|
|
3
|
+
|
|
4
|
+
describe('glib lifecycle hooks', () => {
|
|
5
|
+
it('execute onLoad and onRerender', () => {
|
|
6
|
+
cy.visit(url)
|
|
7
|
+
|
|
8
|
+
cy.contains('page.onLoad').should('be.exist')
|
|
9
|
+
|
|
10
|
+
// check if onLoad executed
|
|
11
|
+
cy.get('#button').should('have.text', 'onLoad')
|
|
12
|
+
cy.get('#chip').trigger('mouseenter')
|
|
13
|
+
cy.get('.views-tooltip p').should('have.text', 'onLoad')
|
|
14
|
+
cy.get('#icon').should('contain.text', 'home')
|
|
15
|
+
|
|
16
|
+
// navigate to other page and close it
|
|
17
|
+
cy.contains('navigate to other page').click()
|
|
18
|
+
cy.contains('windows/close').click()
|
|
19
|
+
|
|
20
|
+
// check if onRerender executed
|
|
21
|
+
cy.contains('page.onRerender').should('be.exist')
|
|
22
|
+
|
|
23
|
+
cy.get('#button').should('have.text', 'onRerender')
|
|
24
|
+
cy.get('#chip').trigger('mouseenter')
|
|
25
|
+
cy.get('.views-tooltip p').should('have.text', 'onRerender')
|
|
26
|
+
cy.get('#icon').should('contain.text', 'person')
|
|
27
|
+
})
|
|
28
|
+
})
|
|
@@ -6,7 +6,9 @@ describe('multiUpload', () => {
|
|
|
6
6
|
cy.visit(url)
|
|
7
7
|
|
|
8
8
|
cy.contains('clear files').click()
|
|
9
|
+
cy.contains('File (Example)').should('not.exist')
|
|
9
10
|
cy.contains('populate files').click()
|
|
11
|
+
cy.contains('File (Example)').should('exist')
|
|
10
12
|
|
|
11
13
|
cy.contains('submit').click()
|
|
12
14
|
|
|
@@ -35,6 +35,6 @@ describe("selectable", () => {
|
|
|
35
35
|
it('can detect timezone', () => {
|
|
36
36
|
cy.visit(url)
|
|
37
37
|
cy.get('input[name="user[timezone]"]').should('have.value', 'Asia/Shanghai')
|
|
38
|
-
cy.get('input[name="user[timezone_with_current_local]"]').should('not.have.value',
|
|
38
|
+
cy.get('input[name="user[timezone_with_current_local]"]').should('not.have.value', '')
|
|
39
39
|
})
|
|
40
40
|
})
|
package/package.json
CHANGED
package/store.js
CHANGED
|
@@ -17,13 +17,13 @@ export const vueApp = reactive({
|
|
|
17
17
|
lastNavigationCount: null,
|
|
18
18
|
tooltipSpec: {},
|
|
19
19
|
bottomBanners: {},
|
|
20
|
-
|
|
20
|
+
sheet: { show: false, placement: 'right', spec: {} },
|
|
21
21
|
uploader: {},
|
|
22
22
|
confirmationDialog: {},
|
|
23
23
|
mobile: undefined
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
export const jsonView = reactive({ page: window.__page });
|
|
26
|
+
export const jsonView = reactive({ page: window.__page, source: 'server' }); // source can be 'server' or 'history'
|
|
27
27
|
export const jsonSettings = reactive(window.__settings);
|
|
28
28
|
|
|
29
29
|
export const dialogs = ref([]);
|
|
@@ -39,7 +39,8 @@ export const closeAllDialog = () => {
|
|
|
39
39
|
export const closeAllPopover = () => {
|
|
40
40
|
popovers.value.forEach((popover) => popover.close());
|
|
41
41
|
popovers.value = [];
|
|
42
|
-
vueApp.
|
|
42
|
+
vueApp.sheet.show = false;
|
|
43
|
+
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
export const glibevent = reactive({
|
|
@@ -99,4 +100,8 @@ export function executeGlibEvent(name) {
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
return glibevent[name]();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function isRerender() {
|
|
106
|
+
return jsonView.source == 'history';
|
|
102
107
|
}
|
package/utils/history.js
CHANGED
|
@@ -44,7 +44,7 @@ export default class {
|
|
|
44
44
|
this._pageBody.scrollTop = 0;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
static restoreOnBackOrForward() {
|
|
47
|
+
static restoreOnBackOrForward({ onAfterBack }) {
|
|
48
48
|
const vm = this;
|
|
49
49
|
let skipOnce = false;
|
|
50
50
|
window.onpopstate = event => {
|
|
@@ -75,12 +75,16 @@ export default class {
|
|
|
75
75
|
data.content.__poppedState = true;
|
|
76
76
|
|
|
77
77
|
jsonView.page = data.content;
|
|
78
|
+
jsonView.source = 'history';
|
|
79
|
+
|
|
78
80
|
vueApp.lastNavigationCount = data.navigationCount;
|
|
79
81
|
vm.navigationCount = data.navigationCount;
|
|
80
82
|
|
|
81
83
|
nextTick(() => {
|
|
82
84
|
const scrollTop = this.bodyScrollTops[this.navigationCount];
|
|
83
85
|
this._pageBody.scrollTop = scrollTop;
|
|
86
|
+
|
|
87
|
+
if (onAfterBack) { onAfterBack(); }
|
|
84
88
|
});
|
|
85
89
|
};
|
|
86
90
|
}
|
package/utils/http.js
CHANGED
|
@@ -4,7 +4,7 @@ import { nextTick } from 'vue';
|
|
|
4
4
|
import { ctx, dialogs, jsonView, vueApp } from "../store";
|
|
5
5
|
import Hash from "./hash";
|
|
6
6
|
|
|
7
|
-
const strandom = () => (Math.random() + 1).toString(36).substring(7);
|
|
7
|
+
const strandom = () => (Math.random() + 1).toString(36).substring(7) + Date.now().toString();
|
|
8
8
|
|
|
9
9
|
let loading = false;
|
|
10
10
|
|
|
@@ -183,6 +183,7 @@ export default class {
|
|
|
183
183
|
Utils.http.forceComponentUpdate(() => {
|
|
184
184
|
page.key = strandom();
|
|
185
185
|
jsonView.page = page;
|
|
186
|
+
jsonView.source = 'server';
|
|
186
187
|
const redirectUrl = Utils.url.htmlUrl(response.url);
|
|
187
188
|
Utils.history.updatePage(jsonView.page, redirectUrl);
|
|
188
189
|
|