1 | /*
|
2 | Copyright 2013-2015 ASIAL CORPORATION
|
3 |
|
4 | Licensed under the Apache License, Version 2.0 (the "License");
|
5 | you may not use this file except in compliance with the License.
|
6 | You may obtain a copy of the License at
|
7 |
|
8 | http://www.apache.org/licenses/LICENSE-2.0
|
9 |
|
10 | Unless required by applicable law or agreed to in writing, software
|
11 | distributed under the License is distributed on an "AS IS" BASIS,
|
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 | See the License for the specific language governing permissions and
|
14 | limitations under the License.
|
15 |
|
16 | */
|
17 |
|
18 | import onsElements from '../ons/elements.js';
|
19 | import util from '../ons/util.js';
|
20 | import autoStyle from '../ons/autostyle.js';
|
21 | import ModifierUtil from '../ons/internal/modifier-util.js';
|
22 | import AnimatorFactory from '../ons/internal/animator-factory.js';
|
23 | import ToastAnimator from './ons-toast/animator.js';
|
24 | import FadeToastAnimator from './ons-toast/fade-animator.js';
|
25 | import AscendToastAnimator from './ons-toast/ascend-animator.js';
|
26 | import LiftToastAnimator from './ons-toast/lift-animator.js';
|
27 | import FallToastAnimator from './ons-toast/fall-animator.js';
|
28 | import platform from '../ons/platform.js';
|
29 | import BaseDialogElement from './base/base-dialog.js';
|
30 | import contentReady from '../ons/content-ready.js';
|
31 |
|
32 | const scheme = {
|
33 | '.toast': 'toast--*',
|
34 | '.toast__message': 'toast--*__message',
|
35 | '.toast__button': 'toast--*__button'
|
36 | };
|
37 |
|
38 | const defaultClassName = 'toast';
|
39 |
|
40 | const _animatorDict = {
|
41 | 'default': platform.isAndroid() ? AscendToastAnimator : LiftToastAnimator,
|
42 | 'fade': FadeToastAnimator,
|
43 | 'ascend': AscendToastAnimator,
|
44 | 'lift': LiftToastAnimator,
|
45 | 'fall': FallToastAnimator,
|
46 | 'none': ToastAnimator
|
47 | };
|
48 |
|
49 | /**
|
50 | * @element ons-toast
|
51 | * @category dialog
|
52 | * @description
|
53 | * [en]
|
54 | * The Toast or Snackbar component is useful for displaying dismissable information or simple actions at (normally) the bottom of the page.
|
55 | *
|
56 | * This component does not block user input, allowing the app to continue its flow. For simple toasts, consider `ons.notification.toast` instead.
|
57 | * [/en]
|
58 | * [ja][/ja]
|
59 | * @tutorial vanilla/Reference/toast
|
60 | * @seealso ons-alert-dialog
|
61 | * [en]The `<ons-alert-dialog>` component is preferred for displaying undismissable information.[/en]
|
62 | * [ja][/ja]
|
63 | */
|
64 | export default class ToastElement extends BaseDialogElement {
|
65 |
|
66 | /**
|
67 | * @event preshow
|
68 | * @description
|
69 | * [en]Fired just before the toast is displayed.[/en]
|
70 | * [ja]ダイアログが表示される直前に発火します。[/ja]
|
71 | * @param {Object} event [en]Event object.[/en]
|
72 | * @param {Object} event.toast
|
73 | * [en]Toast object.[/en]
|
74 | * [ja]ダイアログのオブジェクト。[/ja]
|
75 | * @param {Function} event.cancel
|
76 | * [en]Execute to stop the toast from showing.[/en]
|
77 | * [ja]この関数を実行すると、ダイアログの表示を止めます。[/ja]
|
78 | */
|
79 |
|
80 | /**
|
81 | * @event postshow
|
82 | * @description
|
83 | * [en]Fired just after the toast is displayed.[/en]
|
84 | * [ja]ダイアログが表示された直後に発火します。[/ja]
|
85 | * @param {Object} event [en]Event object.[/en]
|
86 | * @param {Object} event.toast
|
87 | * [en]Toast object.[/en]
|
88 | * [ja]ダイアログのオブジェクト。[/ja]
|
89 | */
|
90 |
|
91 | /**
|
92 | * @event prehide
|
93 | * @description
|
94 | * [en]Fired just before the toast is hidden.[/en]
|
95 | * [ja]ダイアログが隠れる直前に発火します。[/ja]
|
96 | * @param {Object} event [en]Event object.[/en]
|
97 | * @param {Object} event.toast
|
98 | * [en]Toast object.[/en]
|
99 | * [ja]ダイアログのオブジェクト。[/ja]
|
100 | * @param {Function} event.cancel
|
101 | * [en]Execute to stop the toast from hiding.[/en]
|
102 | * [ja]この関数を実行すると、ダイアログが閉じようとするのを止めます。[/ja]
|
103 | */
|
104 |
|
105 | /**
|
106 | * @event posthide
|
107 | * @description
|
108 | * [en]Fired just after the toast is hidden.[/en]
|
109 | * [ja]ダイアログが隠れた後に発火します。[/ja]
|
110 | * @param {Object} event [en]Event object.[/en]
|
111 | * @param {Object} event.toast
|
112 | * [en]Toast object.[/en]
|
113 | * [ja]ダイアログのオブジェクト。[/ja]
|
114 | */
|
115 |
|
116 | /**
|
117 | * @attribute animation
|
118 | * @type {String}
|
119 | * @default default
|
120 | * @description
|
121 | * [en]The animation used when showing and hiding the toast. Can be either `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
|
122 | * [ja][/ja]
|
123 | */
|
124 |
|
125 | /**
|
126 | * @attribute animation-options
|
127 | * @type {Expression}
|
128 | * @description
|
129 | * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
|
130 | * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. <code>{duration: 0.2, delay: 1, timing: 'ease-in'}</code>[/ja]
|
131 | */
|
132 |
|
133 | /**
|
134 | * @property animationOptions
|
135 | * @type {Object}
|
136 | * @description
|
137 | * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
|
138 | * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。例:{duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
|
139 | */
|
140 |
|
141 | /**
|
142 | * @attribute visible
|
143 | * @type {Boolean}
|
144 | * @description
|
145 | * [en]Whether the toast is visible or not.[/en]
|
146 | * [ja]要素が見える場合に`true`。[/ja]
|
147 | */
|
148 |
|
149 | constructor() {
|
150 | super();
|
151 |
|
152 | this._defaultDBB = null;
|
153 | contentReady(this, () => this._compile());
|
154 | }
|
155 |
|
156 | get _scheme() {
|
157 | return scheme;
|
158 | }
|
159 |
|
160 | get _toast() {
|
161 | return util.findChild(this, `.${defaultClassName}`);
|
162 | }
|
163 |
|
164 | _updateAnimatorFactory() {
|
165 | // Reset position style
|
166 | this._toast && (this._toast.style.top = this._toast.style.bottom = '');
|
167 |
|
168 | return new AnimatorFactory({
|
169 | animators: _animatorDict,
|
170 | baseClass: ToastAnimator,
|
171 | baseClassName: 'ToastAnimator',
|
172 | defaultAnimation: this.getAttribute('animation')
|
173 | });
|
174 | }
|
175 |
|
176 | /**
|
177 | * @property onDeviceBackButton
|
178 | * @type {Object}
|
179 | * @description
|
180 | * [en]Back-button handler.[/en]
|
181 | * [ja]バックボタンハンドラ。[/ja]
|
182 | */
|
183 |
|
184 | _compile() {
|
185 | autoStyle.prepare(this);
|
186 |
|
187 | this.style.display = 'none';
|
188 | this.style.zIndex = 10000; // Lower than dialogs
|
189 |
|
190 | const messageClassName = 'toast__message';
|
191 | const buttonClassName = 'toast__button';
|
192 |
|
193 | let toast = util.findChild(this, `.${defaultClassName}`);
|
194 | if (!toast) {
|
195 | toast = document.createElement('div');
|
196 | toast.classList.add(defaultClassName);
|
197 | while (this.childNodes[0]) {
|
198 | toast.appendChild(this.childNodes[0]);
|
199 | }
|
200 | }
|
201 |
|
202 | let button = util.findChild(toast, `.${buttonClassName}`);
|
203 | if (!button) {
|
204 | button = util.findChild(toast, e => util.match(e, '.button') || util.match(e, 'button'));
|
205 | if (button) {
|
206 | button.classList.remove('button');
|
207 | button.classList.add(buttonClassName);
|
208 | toast.appendChild(button);
|
209 | }
|
210 | }
|
211 |
|
212 | if (!util.findChild(toast, `.${messageClassName}`)) {
|
213 | let message = util.findChild(toast, '.message');
|
214 | if (!message) {
|
215 | message = document.createElement('div');
|
216 | for (let i = toast.childNodes.length - 1; i >= 0; i--) {
|
217 | if (toast.childNodes[i] !== button) {
|
218 | message.insertBefore(toast.childNodes[i], message.firstChild);
|
219 | }
|
220 | }
|
221 | }
|
222 | message.classList.add(messageClassName);
|
223 |
|
224 | toast.insertBefore(message, toast.firstChild);
|
225 | }
|
226 |
|
227 | if (toast.parentNode !== this) {
|
228 | this.appendChild(toast);
|
229 | }
|
230 |
|
231 | ModifierUtil.initModifier(this, this._scheme);
|
232 | }
|
233 |
|
234 | /**
|
235 | * @property visible
|
236 | * @type {Boolean}
|
237 | * @description
|
238 | * [en]Whether the element is visible or not.[/en]
|
239 | * [ja]要素が見える場合に`true`。[/ja]
|
240 | */
|
241 |
|
242 | /**
|
243 | * @method show
|
244 | * @signature show([options])
|
245 | * @param {Object} [options]
|
246 | * [en]Parameter object.[/en]
|
247 | * [ja]オプションを指定するオブジェクト。[/ja]
|
248 | * @param {String} [options.animation]
|
249 | * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
|
250 | * [ja][/ja]
|
251 | * @param {String} [options.animationOptions]
|
252 | * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
|
253 | * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
|
254 | * @description
|
255 | * [en]Show the element.[/en]
|
256 | * [ja][/ja]
|
257 | * @return {Promise}
|
258 | * [en]Resolves to the displayed element[/en]
|
259 | * [ja][/ja]
|
260 | */
|
261 |
|
262 | /**
|
263 | * @method toggle
|
264 | * @signature toggle([options])
|
265 | * @param {Object} [options]
|
266 | * [en]Parameter object.[/en]
|
267 | * [ja]オプションを指定するオブジェクト。[/ja]
|
268 | * @param {String} [options.animation]
|
269 | * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
|
270 | * [ja][/ja]
|
271 | * @param {String} [options.animationOptions]
|
272 | * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
|
273 | * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
|
274 | * @description
|
275 | * [en]Toggle toast visibility.[/en]
|
276 | * [ja][/ja]
|
277 | */
|
278 |
|
279 | /**
|
280 | * @method hide
|
281 | * @signature hide([options])
|
282 | * @param {Object} [options]
|
283 | * [en]Parameter object.[/en]
|
284 | * [ja]オプションを指定するオブジェクト。[/ja]
|
285 | * @param {String} [options.animation]
|
286 | * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
|
287 | * [ja][/ja]
|
288 | * @param {String} [options.animationOptions]
|
289 | * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
|
290 | * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
|
291 | * @description
|
292 | * [en]Hide toast.[/en]
|
293 | * [ja][/ja]
|
294 | * @return {Promise}
|
295 | * [en]Resolves to the hidden element[/en]
|
296 | * [ja][/ja]
|
297 | */
|
298 |
|
299 | /**
|
300 | * @param {String} name
|
301 | * @param {Function} Animator
|
302 | */
|
303 | static registerAnimator(name, Animator) {
|
304 | if (!(Animator.prototype instanceof ToastAnimator)) {
|
305 | util.throw('"Animator" param must inherit OnsToastElement.ToastAnimator');
|
306 | }
|
307 | _animatorDict[name] = Animator;
|
308 | }
|
309 |
|
310 | static get animators() {
|
311 | return _animatorDict;
|
312 | }
|
313 |
|
314 | static get ToastAnimator() {
|
315 | return ToastAnimator;
|
316 | }
|
317 | }
|
318 |
|
319 | onsElements.Toast = ToastElement;
|
320 | customElements.define('ons-toast', ToastElement);
|