UNPKG

7.54 kBJavaScriptView Raw
1/*
2Copyright 2013-2015 ASIAL CORPORATION
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15
16*/
17
18import onsElements from '../ons/elements.js';
19import util from '../ons/util.js';
20import autoStyle from '../ons/autostyle.js';
21import ModifierUtil from '../ons/internal/modifier-util.js';
22import BaseElement from './base/base-element.js';
23import contentReady from '../ons/content-ready.js';
24
25const defaultClassName = 'back-button';
26
27const scheme = {
28 '': 'back-button--*',
29 '.back-button__icon': 'back-button--*__icon',
30 '.back-button__label': 'back-button--*__label'
31};
32
33// original image file at misc/images/ios-back-button-icon.svg
34const iosBackButtonIcon = `
35 <?xml version="1.0" encoding="UTF-8"?>
36 <svg width="13px" height="21px" viewBox="0 0 13 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
37 <title>ios-back-button-icon</title>
38 <desc>Created with Sketch.</desc>
39 <defs></defs>
40 <g id="toolbar-back-button" stroke="none" stroke-width="1" fill-rule="evenodd">
41 <g id="ios" transform="translate(-34.000000, -30.000000)">
42 <polygon id="ios-back-button-icon" points="34 40.5 44.5 30 46.5 32 38 40.5 46.5 49 44.5 51"></polygon>
43 </g>
44 </g>
45 </svg>
46`;
47
48// original image file at misc/images/md-back-button-icon.svg
49const mdBackButtonIcon = `
50 <?xml version="1.0" encoding="UTF-8"?>
51 <svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
52 <title>md-back-button-icon</title>
53 <desc>Created with Sketch.</desc>
54 <defs></defs>
55 <g id="toolbar-back-button" stroke="none" stroke-width="1" fill-rule="evenodd">
56 <g id="android" transform="translate(-32.000000, -32.000000)" fill-rule="nonzero">
57 <polygon id="md-back-button-icon" points="48 39 35.83 39 41.42 33.41 40 32 32 40 40 48 41.41 46.59 35.83 41 48 41"></polygon>
58 </g>
59 </g>
60 </svg>
61`;
62
63/**
64 * @element ons-back-button
65 * @category navigation
66 * @description
67 * [en]
68 * Back button component for `<ons-toolbar>`. Put it in the left part of the `<ons-toolbar>`.
69 *
70 * It will find the parent `<ons-navigator>` element and pop a page when clicked. This behavior can be overriden by specifying the `onClick` property and calling event.preventDefault in its callback.
71 * [/en]
72 * [ja][/ja]
73 * @codepen aHmGL
74 * @tutorial vanilla/Reference/back-button
75 * @modifier material
76 * [en]Material Design style[/en]
77 * [ja][/ja]
78 * @seealso ons-toolbar
79 * [en]ons-toolbar component[/en]
80 * [ja]ons-toolbarコンポーネント[/ja]
81 * @seealso ons-navigator
82 * [en]ons-navigator component[/en]
83 * [ja]ons-navigatorコンポーネント[/ja]
84 * @example
85 * <ons-toolbar>
86 * <div class="left">
87 * <ons-back-button>Back</ons-back-button>
88 * </div>
89 * <div class="center">
90 * Title
91 * <div>
92 * </ons-toolbar>
93 */
94
95export default class BackButtonElement extends BaseElement {
96 /**
97 * @attribute modifier
98 * @type {String}
99 * @description
100 * [en]The appearance of the back button.[/en]
101 * [ja]バックボタンの見た目を指定します。[/ja]
102 */
103
104 constructor() {
105 super();
106
107 contentReady(this, () => {
108 this._compile();
109 });
110
111 this._options = {};
112 this._boundOnClick = this._onClick.bind(this);
113
114 const {onConnected, onDisconnected} = util.defineListenerProperty(this, 'click');
115 this._connectOnClick = onConnected;
116 this._disconnectOnClick = onDisconnected;
117 }
118
119 _updateIcon(icon = util.findChild(this, '.back-button__icon')) {
120 icon.innerHTML = autoStyle.getPlatform(this) === 'android' || util.hasModifier(this, 'material') ? mdBackButtonIcon : iosBackButtonIcon;
121 }
122
123 _compile() {
124 autoStyle.prepare(this);
125
126 this.classList.add(defaultClassName);
127
128 if (!util.findChild(this, '.back-button__label')) {
129 const label = util.create('span.back-button__label');
130
131 while (this.childNodes[0]) {
132 label.appendChild(this.childNodes[0]);
133 }
134 this.appendChild(label);
135 }
136
137 if (!util.findChild(this, '.back-button__icon')) {
138 const icon = util.create('span.back-button__icon');
139 this._updateIcon(icon);
140
141 this.insertBefore(icon, this.children[0]);
142 }
143
144 util.updateRipple(this, undefined, {center: '', 'size': 'contain', 'background': 'transparent'});
145
146 ModifierUtil.initModifier(this, scheme);
147 }
148
149 /**
150 * @property options
151 * @type {Object}
152 * @description
153 * [en]Options object.[/en]
154 * [ja]オプションを指定するオブジェクト。[/ja]
155 */
156
157 /**
158 * @property options.animation
159 * @type {String}
160 * @description
161 * [en]Animation name. Available animations are "slide", "lift", "fade" and "none".
162 * These are platform based animations. For fixed animations, add "-ios" or "-md"
163 * suffix to the animation name. E.g. "lift-ios", "lift-md". Defaults values are "slide-ios" and "fade-md".
164 * [/en]
165 * [ja][/ja]
166 */
167
168 /**
169 * @property options.animationOptions
170 * @type {String}
171 * @description
172 * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/en]
173 * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
174 */
175
176 /**
177 * @property options.callback
178 * @type {String}
179 * @description
180 * [en]Function that is called when the transition has ended.[/en]
181 * [ja]このメソッドによる画面遷移が終了した際に呼び出される関数オブジェクトを指定します。[/ja]
182 */
183
184 get options() {
185 return this._options;
186 }
187
188 set options(object) {
189 this._options = object;
190 }
191
192 /**
193 * @property onClick
194 * @type {Function}
195 * @description
196 * [en]Used to override the default back button behavior.[/en]
197 * [ja][/ja]
198 */
199
200 _onClick(event) {
201 setTimeout(() => {
202 if (!event.defaultPrevented) {
203 const navigator = util.findParent(this, 'ons-navigator');
204 if (navigator) {
205 navigator.popPage({...this.options, onsBackButton: true});
206 }
207 }
208 });
209 }
210
211 connectedCallback() {
212 this.addEventListener('click', this._boundOnClick, false);
213 this._connectOnClick();
214 }
215
216 static get observedAttributes() {
217 return ['modifier', 'class'];
218 }
219
220 attributeChangedCallback(name, last, current) {
221 switch (name) {
222 case 'class':
223 util.restoreClass(this, defaultClassName, scheme);
224 break;
225
226 case 'modifier': {
227 ModifierUtil.onModifierChanged(last, current, this, scheme) && this._updateIcon();
228 break;
229 }
230 }
231 }
232
233 disconnectedCallback() {
234 this.removeEventListener('click', this._boundOnClick, false);
235 this._disconnectOnClick();
236 }
237
238 show() {
239 this.style.display = 'inline-block';
240 }
241
242 hide() {
243 this.style.display = 'none';
244 }
245}
246
247onsElements.BackButton = BackButtonElement;
248customElements.define('ons-back-button', BackButtonElement);