1 | import { writeTask, Build } from '@stencil/core/internal/client';
|
2 | import { c as componentOnReady } from './helpers.js';
|
3 |
|
4 | const LIFECYCLE_WILL_ENTER = 'ionViewWillEnter';
|
5 | const LIFECYCLE_DID_ENTER = 'ionViewDidEnter';
|
6 | const LIFECYCLE_WILL_LEAVE = 'ionViewWillLeave';
|
7 | const LIFECYCLE_DID_LEAVE = 'ionViewDidLeave';
|
8 | const LIFECYCLE_WILL_UNLOAD = 'ionViewWillUnload';
|
9 |
|
10 | const iosTransitionAnimation = () => import('./ios.transition.js');
|
11 | const mdTransitionAnimation = () => import('./md.transition.js');
|
12 | const transition = (opts) => {
|
13 | return new Promise((resolve, reject) => {
|
14 | writeTask(() => {
|
15 | beforeTransition(opts);
|
16 | runTransition(opts).then(result => {
|
17 | if (result.animation) {
|
18 | result.animation.destroy();
|
19 | }
|
20 | afterTransition(opts);
|
21 | resolve(result);
|
22 | }, error => {
|
23 | afterTransition(opts);
|
24 | reject(error);
|
25 | });
|
26 | });
|
27 | });
|
28 | };
|
29 | const beforeTransition = (opts) => {
|
30 | const enteringEl = opts.enteringEl;
|
31 | const leavingEl = opts.leavingEl;
|
32 | setZIndex(enteringEl, leavingEl, opts.direction);
|
33 | if (opts.showGoBack) {
|
34 | enteringEl.classList.add('can-go-back');
|
35 | }
|
36 | else {
|
37 | enteringEl.classList.remove('can-go-back');
|
38 | }
|
39 | setPageHidden(enteringEl, false);
|
40 | |
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | enteringEl.style.setProperty('pointer-events', 'none');
|
47 | if (leavingEl) {
|
48 | setPageHidden(leavingEl, false);
|
49 | leavingEl.style.setProperty('pointer-events', 'none');
|
50 | }
|
51 | };
|
52 | const runTransition = async (opts) => {
|
53 | const animationBuilder = await getAnimationBuilder(opts);
|
54 | const ani = (animationBuilder && Build.isBrowser)
|
55 | ? animation(animationBuilder, opts)
|
56 | : noAnimation(opts);
|
57 | return ani;
|
58 | };
|
59 | const afterTransition = (opts) => {
|
60 | const enteringEl = opts.enteringEl;
|
61 | const leavingEl = opts.leavingEl;
|
62 | enteringEl.classList.remove('ion-page-invisible');
|
63 | enteringEl.style.removeProperty('pointer-events');
|
64 | if (leavingEl !== undefined) {
|
65 | leavingEl.classList.remove('ion-page-invisible');
|
66 | leavingEl.style.removeProperty('pointer-events');
|
67 | }
|
68 | };
|
69 | const getAnimationBuilder = async (opts) => {
|
70 | if (!opts.leavingEl || !opts.animated || opts.duration === 0) {
|
71 | return undefined;
|
72 | }
|
73 | if (opts.animationBuilder) {
|
74 | return opts.animationBuilder;
|
75 | }
|
76 | const getAnimation = (opts.mode === 'ios')
|
77 | ? (await iosTransitionAnimation()).iosTransitionAnimation
|
78 | : (await mdTransitionAnimation()).mdTransitionAnimation;
|
79 | return getAnimation;
|
80 | };
|
81 | const animation = async (animationBuilder, opts) => {
|
82 | await waitForReady(opts, true);
|
83 | const trans = animationBuilder(opts.baseEl, opts);
|
84 | fireWillEvents(opts.enteringEl, opts.leavingEl);
|
85 | const didComplete = await playTransition(trans, opts);
|
86 | if (opts.progressCallback) {
|
87 | opts.progressCallback(undefined);
|
88 | }
|
89 | if (didComplete) {
|
90 | fireDidEvents(opts.enteringEl, opts.leavingEl);
|
91 | }
|
92 | return {
|
93 | hasCompleted: didComplete,
|
94 | animation: trans
|
95 | };
|
96 | };
|
97 | const noAnimation = async (opts) => {
|
98 | const enteringEl = opts.enteringEl;
|
99 | const leavingEl = opts.leavingEl;
|
100 | await waitForReady(opts, false);
|
101 | fireWillEvents(enteringEl, leavingEl);
|
102 | fireDidEvents(enteringEl, leavingEl);
|
103 | return {
|
104 | hasCompleted: true
|
105 | };
|
106 | };
|
107 | const waitForReady = async (opts, defaultDeep) => {
|
108 | const deep = opts.deepWait !== undefined ? opts.deepWait : defaultDeep;
|
109 | const promises = deep ? [
|
110 | deepReady(opts.enteringEl),
|
111 | deepReady(opts.leavingEl),
|
112 | ] : [
|
113 | shallowReady(opts.enteringEl),
|
114 | shallowReady(opts.leavingEl),
|
115 | ];
|
116 | await Promise.all(promises);
|
117 | await notifyViewReady(opts.viewIsReady, opts.enteringEl);
|
118 | };
|
119 | const notifyViewReady = async (viewIsReady, enteringEl) => {
|
120 | if (viewIsReady) {
|
121 | await viewIsReady(enteringEl);
|
122 | }
|
123 | };
|
124 | const playTransition = (trans, opts) => {
|
125 | const progressCallback = opts.progressCallback;
|
126 | const promise = new Promise(resolve => {
|
127 | trans.onFinish((currentStep) => resolve(currentStep === 1));
|
128 | });
|
129 |
|
130 | if (progressCallback) {
|
131 |
|
132 |
|
133 | trans.progressStart(true);
|
134 | progressCallback(trans);
|
135 | }
|
136 | else {
|
137 |
|
138 |
|
139 |
|
140 | trans.play();
|
141 | }
|
142 |
|
143 | return promise;
|
144 | };
|
145 | const fireWillEvents = (enteringEl, leavingEl) => {
|
146 | lifecycle(leavingEl, LIFECYCLE_WILL_LEAVE);
|
147 | lifecycle(enteringEl, LIFECYCLE_WILL_ENTER);
|
148 | };
|
149 | const fireDidEvents = (enteringEl, leavingEl) => {
|
150 | lifecycle(enteringEl, LIFECYCLE_DID_ENTER);
|
151 | lifecycle(leavingEl, LIFECYCLE_DID_LEAVE);
|
152 | };
|
153 | const lifecycle = (el, eventName) => {
|
154 | if (el) {
|
155 | const ev = new CustomEvent(eventName, {
|
156 | bubbles: false,
|
157 | cancelable: false,
|
158 | });
|
159 | el.dispatchEvent(ev);
|
160 | }
|
161 | };
|
162 | const shallowReady = (el) => {
|
163 | if (el) {
|
164 | return new Promise(resolve => componentOnReady(el, resolve));
|
165 | }
|
166 | return Promise.resolve();
|
167 | };
|
168 | const deepReady = async (el) => {
|
169 | const element = el;
|
170 | if (element) {
|
171 | if (element.componentOnReady != null) {
|
172 | const stencilEl = await element.componentOnReady();
|
173 | if (stencilEl != null) {
|
174 | return;
|
175 | }
|
176 | }
|
177 | await Promise.all(Array.from(element.children).map(deepReady));
|
178 | }
|
179 | };
|
180 | const setPageHidden = (el, hidden) => {
|
181 | if (hidden) {
|
182 | el.setAttribute('aria-hidden', 'true');
|
183 | el.classList.add('ion-page-hidden');
|
184 | }
|
185 | else {
|
186 | el.hidden = false;
|
187 | el.removeAttribute('aria-hidden');
|
188 | el.classList.remove('ion-page-hidden');
|
189 | }
|
190 | };
|
191 | const setZIndex = (enteringEl, leavingEl, direction) => {
|
192 | if (enteringEl !== undefined) {
|
193 | enteringEl.style.zIndex = (direction === 'back')
|
194 | ? '99'
|
195 | : '101';
|
196 | }
|
197 | if (leavingEl !== undefined) {
|
198 | leavingEl.style.zIndex = '100';
|
199 | }
|
200 | };
|
201 | const getIonPageElement = (element) => {
|
202 | if (element.classList.contains('ion-page')) {
|
203 | return element;
|
204 | }
|
205 | const ionPage = element.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs');
|
206 | if (ionPage) {
|
207 | return ionPage;
|
208 | }
|
209 |
|
210 | return element;
|
211 | };
|
212 |
|
213 | export { LIFECYCLE_WILL_ENTER as L, LIFECYCLE_DID_ENTER as a, LIFECYCLE_WILL_LEAVE as b, LIFECYCLE_DID_LEAVE as c, LIFECYCLE_WILL_UNLOAD as d, deepReady as e, getIonPageElement as g, lifecycle as l, setPageHidden as s, transition as t };
|