440 lines
13 KiB
JavaScript
440 lines
13 KiB
JavaScript
import _Promise from 'babel-runtime/core-js/promise';
|
|
import _setImmediate from 'babel-runtime/core-js/set-immediate';
|
|
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
|
|
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
|
import _createClass from 'babel-runtime/helpers/createClass';
|
|
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
|
import _inherits from 'babel-runtime/helpers/inherits';
|
|
/*
|
|
Copyright 2013-2015 ASIAL CORPORATION
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
import onsElements from '../ons/elements';
|
|
import util from '../ons/util';
|
|
import autoStyle from '../ons/autostyle';
|
|
import ModifierUtil from '../ons/internal/modifier-util';
|
|
import BaseElement from './base/base-element';
|
|
import TabbarElement from './ons-tabbar';
|
|
import contentReady from '../ons/content-ready';
|
|
import { PageLoader, defaultPageLoader } from '../ons/page-loader';
|
|
|
|
var defaultClassName = 'tabbar__item';
|
|
|
|
var scheme = {
|
|
'': 'tabbar--*__item',
|
|
'.tabbar__button': 'tabbar--*__button'
|
|
};
|
|
|
|
/**
|
|
* @element ons-tab
|
|
* @category tabbar
|
|
* @description
|
|
* [en]Represents a tab inside tab bar. Each `<ons-tab>` represents a page.[/en]
|
|
* [ja]
|
|
* タブバーに配置される各アイテムのコンポーネントです。それぞれのons-tabはページを表します。
|
|
* ons-tab要素の中には、タブに表示されるコンテンツを直接記述することが出来ます。
|
|
* [/ja]
|
|
* @codepen pGuDL
|
|
* @tutorial vanilla/Reference/tabbar
|
|
* @guide fundamentals.html#managing-pages
|
|
* [en]Managing multiple pages.[/en]
|
|
* [ja]複数のページを管理する[/ja]]
|
|
* @guide appsize.html#removing-icon-packs [en]Removing icon packs.[/en][ja][/ja]
|
|
* @guide faq.html#how-can-i-use-custom-icon-packs [en]Adding custom icon packs.[/en][ja][/ja]
|
|
* @seealso ons-tabbar
|
|
* [en]ons-tabbar component[/en]
|
|
* [ja]ons-tabbarコンポーネント[/ja]
|
|
* @seealso ons-page
|
|
* [en]ons-page component[/en]
|
|
* [ja]ons-pageコンポーネント[/ja]
|
|
* @seealso ons-icon
|
|
* [en]ons-icon component[/en]
|
|
* [ja]ons-iconコンポーネント[/ja]
|
|
* @example
|
|
* <ons-tabbar>
|
|
* <ons-tab
|
|
* page="home.html"
|
|
* label="Home"
|
|
* active>
|
|
* </ons-tab>
|
|
* <ons-tab
|
|
* page="settings.html"
|
|
* label="Settings"
|
|
* active>
|
|
* </ons-tab>
|
|
* </ons-tabbar>
|
|
*
|
|
* <template id="home.html">
|
|
* ...
|
|
* </template>
|
|
*
|
|
* <template id="settings.html">
|
|
* ...
|
|
* </template>
|
|
|
|
*/
|
|
|
|
var TabElement = function (_BaseElement) {
|
|
_inherits(TabElement, _BaseElement);
|
|
|
|
/**
|
|
* @attribute page
|
|
* @initonly
|
|
* @type {String}
|
|
* @description
|
|
* [en]The page that is displayed when the tab is tapped.[/en]
|
|
* [ja]ons-tabが参照するページへのURLを指定します。[/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute icon
|
|
* @type {String}
|
|
* @description
|
|
* [en]
|
|
* The icon name for the tab. Can specify the same icon name as `<ons-icon>`. Check [See also](#seealso) section for more information.
|
|
* [/en]
|
|
* [ja]
|
|
* アイコン名を指定します。ons-iconと同じアイコン名を指定できます。
|
|
* 個別にアイコンをカスタマイズする場合は、background-imageなどのCSSスタイルを用いて指定できます。
|
|
* [/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute active-icon
|
|
* @type {String}
|
|
* @description
|
|
* [en]The name of the icon when the tab is active.[/en]
|
|
* [ja]アクティブの際のアイコン名を指定します。[/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute label
|
|
* @type {String}
|
|
* @description
|
|
* [en]The label of the tab item.[/en]
|
|
* [ja]アイコン下に表示されるラベルを指定します。[/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute badge
|
|
* @type {String}
|
|
* @description
|
|
* [en]Display a notification badge on top of the tab.[/en]
|
|
* [ja]バッジに表示する内容を指定します。[/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute active
|
|
* @description
|
|
* [en]This attribute should be set to the tab that is active by default.[/en]
|
|
* [ja][/ja]
|
|
*/
|
|
|
|
function TabElement() {
|
|
_classCallCheck(this, TabElement);
|
|
|
|
var _this = _possibleConstructorReturn(this, (TabElement.__proto__ || _Object$getPrototypeOf(TabElement)).call(this));
|
|
|
|
if (['label', 'icon', 'badge'].some(_this.hasAttribute.bind(_this))) {
|
|
_this._compile();
|
|
} else {
|
|
contentReady(_this, function () {
|
|
return _this._compile();
|
|
});
|
|
}
|
|
|
|
_this._pageLoader = defaultPageLoader;
|
|
_this._onClick = _this._onClick.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(TabElement, [{
|
|
key: '_compile',
|
|
value: function _compile() {
|
|
autoStyle.prepare(this);
|
|
this.classList.add(defaultClassName);
|
|
|
|
if (this._button) {
|
|
return;
|
|
}
|
|
|
|
var button = util.create('button.tabbar__button');
|
|
while (this.childNodes[0]) {
|
|
button.appendChild(this.childNodes[0]);
|
|
}
|
|
|
|
var input = util.create('input', { display: 'none' });
|
|
input.type = 'radio';
|
|
|
|
this.appendChild(input);
|
|
this.appendChild(button);
|
|
|
|
this._updateButtonContent();
|
|
ModifierUtil.initModifier(this, scheme);
|
|
this._updateRipple();
|
|
}
|
|
}, {
|
|
key: '_updateRipple',
|
|
value: function _updateRipple() {
|
|
this._button && util.updateRipple(this._button, this.hasAttribute('ripple'));
|
|
}
|
|
}, {
|
|
key: '_updateButtonContent',
|
|
value: function _updateButtonContent() {
|
|
var _this2 = this;
|
|
|
|
var button = this._button;
|
|
|
|
var iconWrapper = this._icon;
|
|
if (this.hasAttribute('icon')) {
|
|
iconWrapper = iconWrapper || util.createElement('<div class="tabbar__icon"><ons-icon></ons-icon></div>');
|
|
var icon = iconWrapper.children[0];
|
|
var fix = function (last) {
|
|
return function () {
|
|
return icon.attributeChangedCallback('icon', last, _this2.getAttribute('icon'));
|
|
};
|
|
}(icon.getAttribute('icon'));
|
|
icon.setAttribute('icon', this.getAttribute(this.isActive() ? 'active-icon' : 'icon'));
|
|
iconWrapper.parentElement !== button && button.insertBefore(iconWrapper, button.firstChild);
|
|
|
|
// dirty fix for https://github.com/OnsenUI/OnsenUI/issues/1654
|
|
icon.attributeChangedCallback instanceof Function ? fix() : _setImmediate(function () {
|
|
return icon.attributeChangedCallback instanceof Function && fix();
|
|
});
|
|
} else {
|
|
iconWrapper && iconWrapper.remove();
|
|
}
|
|
|
|
['label', 'badge'].forEach(function (attr, index) {
|
|
var prop = _this2.querySelector('.tabbar__' + attr);
|
|
if (_this2.hasAttribute(attr)) {
|
|
prop = prop || util.create('.tabbar__' + attr + (attr === 'badge' ? ' notification' : ''));
|
|
prop.textContent = _this2.getAttribute(attr);
|
|
prop.parentElement !== button && button.appendChild(prop);
|
|
} else {
|
|
prop && prop.remove();
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: '_onClick',
|
|
value: function _onClick() {
|
|
if (this.onClick instanceof Function) {
|
|
this.onClick();
|
|
} else {
|
|
this._tabbar.setActiveTab(this.index, { reject: false });
|
|
}
|
|
}
|
|
}, {
|
|
key: 'setActive',
|
|
value: function setActive() {
|
|
var active = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
|
|
this._input.checked = active;
|
|
this.classList.toggle('active', active);
|
|
util.toggleAttribute(this, 'active', active);
|
|
|
|
if (this.hasAttribute('icon') && this.hasAttribute('active-icon')) {
|
|
this._icon.children[0].setAttribute('icon', this.getAttribute(active ? 'active-icon' : 'icon'));
|
|
}
|
|
}
|
|
}, {
|
|
key: '_loadPageElement',
|
|
value: function _loadPageElement(parent, page) {
|
|
var _this3 = this;
|
|
|
|
this._hasLoaded = true;
|
|
|
|
return new _Promise(function (resolve) {
|
|
_this3._pageLoader.load({ parent: parent, page: page }, function (pageElement) {
|
|
parent.replaceChild(pageElement, parent.children[_this3.index]); // Ensure position
|
|
_this3._loadedPage = pageElement;
|
|
resolve(pageElement);
|
|
});
|
|
});
|
|
}
|
|
}, {
|
|
key: 'isActive',
|
|
|
|
|
|
/**
|
|
* @return {Boolean}
|
|
*/
|
|
value: function isActive() {
|
|
return this.classList.contains('active');
|
|
}
|
|
}, {
|
|
key: 'disconnectedCallback',
|
|
value: function disconnectedCallback() {
|
|
this.removeEventListener('click', this._onClick, false);
|
|
if (this._loadedPage) {
|
|
this._hasLoaded = false;
|
|
this.loaded = null;
|
|
}
|
|
}
|
|
}, {
|
|
key: 'connectedCallback',
|
|
value: function connectedCallback() {
|
|
var _this4 = this;
|
|
|
|
this.addEventListener('click', this._onClick, false);
|
|
|
|
if (!util.isAttached(this) || this.loaded) {
|
|
return; // ons-tabbar compilation may trigger this
|
|
}
|
|
|
|
var deferred = util.defer();
|
|
this.loaded = deferred.promise;
|
|
|
|
contentReady(this, function () {
|
|
var index = _this4.index;
|
|
var tabbar = _this4._tabbar;
|
|
if (!tabbar) {
|
|
util.throw('Tab elements must be children of Tabbar');
|
|
}
|
|
|
|
if (tabbar.hasAttribute('modifier')) {
|
|
util.addModifier(_this4, tabbar.getAttribute('modifier'));
|
|
}
|
|
|
|
if (!_this4._hasLoaded) {
|
|
if (_this4.hasAttribute('active')) {
|
|
_this4.setActive(true);
|
|
tabbar.setAttribute('activeIndex', index);
|
|
}
|
|
|
|
if (index === tabbar.tabs.length - 1) {
|
|
tabbar._onRefresh();
|
|
_setImmediate(function () {
|
|
return tabbar._onRefresh();
|
|
});
|
|
}
|
|
|
|
TabbarElement.rewritables.ready(tabbar, function () {
|
|
var pageTarget = _this4.page || _this4.getAttribute('page');
|
|
if (!_this4.pageElement && pageTarget) {
|
|
var parentTarget = tabbar._targetElement;
|
|
var dummyPage = util.create('div', { height: '100%', width: '100%', visibility: 'hidden' });
|
|
parentTarget.insertBefore(dummyPage, parentTarget.children[index]); // Ensure position
|
|
|
|
var load = function load() {
|
|
return _this4._loadPageElement(parentTarget, pageTarget).then(deferred.resolve);
|
|
};
|
|
return _this4.isActive() ? load() : tabbar._loadInactive.promise.then(load);
|
|
}
|
|
|
|
return deferred.resolve(_this4.pageElement);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: 'attributeChangedCallback',
|
|
value: function attributeChangedCallback(name, last, current) {
|
|
var _this5 = this;
|
|
|
|
switch (name) {
|
|
case 'class':
|
|
util.restoreClass(this, defaultClassName, scheme);
|
|
break;
|
|
case 'modifier':
|
|
contentReady(this, function () {
|
|
return ModifierUtil.onModifierChanged(last, current, _this5, scheme);
|
|
});
|
|
break;
|
|
case 'ripple':
|
|
contentReady(this, function () {
|
|
return _this5._updateRipple();
|
|
});
|
|
break;
|
|
case 'icon':
|
|
case 'label':
|
|
case 'badge':
|
|
contentReady(this, function () {
|
|
return _this5._updateButtonContent();
|
|
});
|
|
break;
|
|
case 'page':
|
|
this.page = current || '';
|
|
break;
|
|
}
|
|
}
|
|
}, {
|
|
key: 'pageLoader',
|
|
set: function set(loader) {
|
|
if (!(loader instanceof PageLoader)) {
|
|
util.throwPageLoader();
|
|
}
|
|
this._pageLoader = loader;
|
|
},
|
|
get: function get() {
|
|
return this._pageLoader;
|
|
}
|
|
}, {
|
|
key: '_input',
|
|
get: function get() {
|
|
return util.findChild(this, 'input');
|
|
}
|
|
}, {
|
|
key: '_button',
|
|
get: function get() {
|
|
return util.findChild(this, '.tabbar__button');
|
|
}
|
|
}, {
|
|
key: '_icon',
|
|
get: function get() {
|
|
return this.querySelector('.tabbar__icon');
|
|
}
|
|
}, {
|
|
key: '_tabbar',
|
|
get: function get() {
|
|
return util.findParent(this, 'ons-tabbar');
|
|
}
|
|
}, {
|
|
key: 'index',
|
|
get: function get() {
|
|
return Array.prototype.indexOf.call(this.parentElement.children, this);
|
|
}
|
|
}, {
|
|
key: 'pageElement',
|
|
get: function get() {
|
|
// It has been loaded by ons-tab
|
|
if (this._loadedPage) {
|
|
return this._loadedPage;
|
|
}
|
|
// Manually attached to DOM, 1 per tab
|
|
var tabbar = this._tabbar;
|
|
if (tabbar.pages.length === tabbar.tabs.length) {
|
|
return tabbar.pages[this.index];
|
|
}
|
|
// Loaded in another way
|
|
return null;
|
|
}
|
|
}], [{
|
|
key: 'observedAttributes',
|
|
get: function get() {
|
|
return ['modifier', 'ripple', 'icon', 'label', 'page', 'badge', 'class'];
|
|
}
|
|
}]);
|
|
|
|
return TabElement;
|
|
}(BaseElement);
|
|
|
|
export default TabElement;
|
|
|
|
|
|
onsElements.Tab = TabElement;
|
|
customElements.define('ons-tab', TabElement); |