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