Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

index.js 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. import _setImmediate from 'babel-runtime/core-js/set-immediate';
  2. import _Promise from 'babel-runtime/core-js/promise';
  3. import _extends from 'babel-runtime/helpers/extends';
  4. import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
  5. import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
  6. import _createClass from 'babel-runtime/helpers/createClass';
  7. import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
  8. import _inherits from 'babel-runtime/helpers/inherits';
  9. /*
  10. Copyright 2013-2015 ASIAL CORPORATION
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. */
  21. import onsElements from '../../ons/elements';
  22. import util from '../../ons/util';
  23. import internal from '../../ons/internal';
  24. import autoStyle from '../../ons/autostyle';
  25. import Swiper from '../../ons/internal/swiper';
  26. import ModifierUtil from '../../ons/internal/modifier-util';
  27. import BaseElement from '../base/base-element';
  28. import contentReady from '../../ons/content-ready';
  29. var scheme = {
  30. '.tabbar__content': 'tabbar--*__content',
  31. '.tabbar__border': 'tabbar--*__border',
  32. '.tabbar': 'tabbar--*'
  33. };
  34. var rewritables = {
  35. /**
  36. * @param {Element} tabbarElement
  37. * @param {Function} callback
  38. */
  39. ready: function ready(tabbarElement, callback) {
  40. callback();
  41. }
  42. };
  43. var nullPage = internal.nullElement;
  44. var lerp = function lerp(x0, x1, t) {
  45. return (1 - t) * x0 + t * x1;
  46. };
  47. /**
  48. * @element ons-tabbar
  49. * @category tabbar
  50. * @description
  51. * [en]A component to display a tab bar on the bottom of a page. Used with `<ons-tab>` to manage pages using tabs.[/en]
  52. * [ja]タブバーをページ下部に表示するためのコンポーネントです。ons-tabと組み合わせて使うことで、ページを管理できます。[/ja]
  53. * @codepen pGuDL
  54. * @tutorial vanilla/Reference/tabbar
  55. * @modifier material
  56. * [en]A tabbar in Material Design.[/en]
  57. * [ja][/ja]
  58. * @modifier autogrow
  59. * [en]Tabs automatically grow depending on their content instead of having a fixed width.[/en]
  60. * [ja][/ja]
  61. * @modifier top-border
  62. * [en]Shows a static border-bottom in tabs for iOS top tabbars.[/en]
  63. * [ja][/ja]
  64. * @guide fundamentals.html#managing-pages
  65. * [en]Managing multiple pages.[/en]
  66. * [ja]複数のページを管理する[/ja]
  67. * @seealso ons-tab
  68. * [en]The `<ons-tab>` component.[/en]
  69. * [ja]ons-tabコンポーネント[/ja]
  70. * @seealso ons-page
  71. * [en]The `<ons-page>` component.[/en]
  72. * [ja]ons-pageコンポーネント[/ja]
  73. * @example
  74. * <ons-tabbar>
  75. * <ons-tab
  76. * page="home.html"
  77. * label="Home"
  78. * active>
  79. * </ons-tab>
  80. * <ons-tab
  81. * page="settings.html"
  82. * label="Settings"
  83. * active>
  84. * </ons-tab>
  85. * </ons-tabbar>
  86. *
  87. * <template id="home.html">
  88. * ...
  89. * </template>
  90. *
  91. * <template id="settings.html">
  92. * ...
  93. * </template>
  94. */
  95. var TabbarElement = function (_BaseElement) {
  96. _inherits(TabbarElement, _BaseElement);
  97. /**
  98. * @event prechange
  99. * @description
  100. * [en]Fires just before the tab is changed.[/en]
  101. * [ja]アクティブなタブが変わる前に発火します。[/ja]
  102. * @param {Object} event
  103. * [en]Event object.[/en]
  104. * [ja]イベントオブジェクト。[/ja]
  105. * @param {Number} event.index
  106. * [en]Current index.[/en]
  107. * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
  108. * @param {Object} event.tabItem
  109. * [en]Tab item object.[/en]
  110. * [ja]tabItemオブジェクト。[/ja]
  111. * @param {Function} event.cancel
  112. * [en]Call this function to cancel the change event.[/en]
  113. * [ja]この関数を呼び出すと、アクティブなタブの変更がキャンセルされます。[/ja]
  114. */
  115. /**
  116. * @event postchange
  117. * @description
  118. * [en]Fires just after the tab is changed.[/en]
  119. * [ja]アクティブなタブが変わった後に発火します。[/ja]
  120. * @param {Object} event
  121. * [en]Event object.[/en]
  122. * [ja]イベントオブジェクト。[/ja]
  123. * @param {Number} event.index
  124. * [en]Current index.[/en]
  125. * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
  126. * @param {Object} event.tabItem
  127. * [en]Tab item object.[/en]
  128. * [ja]tabItemオブジェクト。[/ja]
  129. */
  130. /**
  131. * @event reactive
  132. * @description
  133. * [en]Fires if the already open tab is tapped again.[/en]
  134. * [ja]すでにアクティブになっているタブがもう一度タップやクリックされた場合に発火します。[/ja]
  135. * @param {Object} event
  136. * [en]Event object.[/en]
  137. * [ja]イベントオブジェクト。[/ja]
  138. * @param {Number} event.index
  139. * [en]Current index.[/en]
  140. * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
  141. * @param {Object} event.tabItem
  142. * [en]Tab item object.[/en]
  143. * [ja]tabItemオブジェクト。[/ja]
  144. */
  145. /**
  146. * @attribute animation
  147. * @type {String}
  148. * @default none
  149. * @description
  150. * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
  151. * [ja][/ja]
  152. */
  153. /**
  154. * @attribute animation-options
  155. * @type {Expression}
  156. * @description
  157. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  158. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. {duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
  159. */
  160. /**
  161. * @attribute position
  162. * @initonly
  163. * @type {String}
  164. * @default bottom
  165. * @description
  166. * [en]Tabbar's position. Available values are `"bottom"` and `"top"`. Use `"auto"` to choose position depending on platform (bottom for iOS flat design, top for Material Design).[/en]
  167. * [ja]タブバーの位置を指定します。"bottom"もしくは"top"を選択できます。デフォルトは"bottom"です。[/ja]
  168. */
  169. /**
  170. * @attribute swipeable
  171. * @description
  172. * [en]If this attribute is set the tab bar can be scrolled by drag or swipe.[/en]
  173. * [ja]この属性がある時、タブバーをスワイプやドラッグで移動できるようになります。[/ja]
  174. */
  175. /**
  176. * @attribute ignore-edge-width
  177. * @type {Number}
  178. * @default 20
  179. * @description
  180. * [en]Distance in pixels from both edges. Swiping on these areas will prioritize parent components such as `ons-splitter` or `ons-navigator`.[/en]
  181. * [ja][/ja]
  182. */
  183. /**
  184. * @attribute hide-tabs
  185. * @description
  186. * [en]Whether to hide the tabs.[/en]
  187. * [ja]タブを非表示にする場合に指定します。[/ja]
  188. */
  189. /**
  190. * @attribute tab-border
  191. * @description
  192. * [en]If this attribute is set the tabs show a dynamic bottom border. Only works for iOS flat design since the border is always visible in Material Design.[/en]
  193. * [ja][/ja]
  194. */
  195. /**
  196. * @attribute modifier
  197. * @type {String}
  198. * @description
  199. * [en]The appearance of the tabbar.[/en]
  200. * [ja]タブバーの表現を指定します。[/ja]
  201. */
  202. function TabbarElement() {
  203. _classCallCheck(this, TabbarElement);
  204. var _this = _possibleConstructorReturn(this, (TabbarElement.__proto__ || _Object$getPrototypeOf(TabbarElement)).call(this));
  205. _this._loadInactive = util.defer(); // Improves #2324
  206. contentReady(_this, function () {
  207. return _this._compile();
  208. });
  209. return _this;
  210. }
  211. _createClass(TabbarElement, [{
  212. key: 'connectedCallback',
  213. value: function connectedCallback() {
  214. var _this2 = this;
  215. if (!this._swiper) {
  216. this._swiper = new Swiper({
  217. getElement: function getElement() {
  218. return _this2._contentElement;
  219. },
  220. getInitialIndex: function getInitialIndex() {
  221. return _this2.getAttribute('activeIndex') || _this2.getAttribute('active-index');
  222. },
  223. getAutoScrollRatio: this._getAutoScrollRatio.bind(this),
  224. getBubbleWidth: function getBubbleWidth() {
  225. return parseInt(_this2.getAttribute('ignore-edge-width') || 25, 10);
  226. },
  227. isAutoScrollable: function isAutoScrollable() {
  228. return true;
  229. },
  230. preChangeHook: this._onPreChange.bind(this),
  231. postChangeHook: this._onPostChange.bind(this),
  232. refreshHook: this._onRefresh.bind(this),
  233. scrollHook: this._onScroll.bind(this)
  234. });
  235. contentReady(this, function () {
  236. _this2._tabbarBorder = util.findChild(_this2._tabbarElement, '.tabbar__border');
  237. _this2._swiper.init({ swipeable: _this2.hasAttribute('swipeable') });
  238. });
  239. }
  240. contentReady(this, function () {
  241. _this2._updatePosition();
  242. if (!util.findParent(_this2, 'ons-page', function (p) {
  243. return p === document.body;
  244. })) {
  245. _this2._show(); // This tabbar is the top component
  246. }
  247. });
  248. }
  249. }, {
  250. key: 'disconnectedCallback',
  251. value: function disconnectedCallback() {
  252. if (this._swiper && this._swiper.initialized) {
  253. this._swiper.dispose();
  254. this._swiper = null;
  255. this._tabbarBorder = null;
  256. this._tabsRect = null;
  257. }
  258. }
  259. }, {
  260. key: '_normalizeEvent',
  261. value: function _normalizeEvent(event) {
  262. return _extends({}, event, { index: event.activeIndex, tabItem: this.tabs[event.activeIndex] });
  263. }
  264. }, {
  265. key: '_onPostChange',
  266. value: function _onPostChange(event) {
  267. event = this._normalizeEvent(event);
  268. util.triggerElementEvent(this, 'postchange', event);
  269. var page = event.tabItem.pageElement;
  270. page && page._show();
  271. }
  272. }, {
  273. key: '_onPreChange',
  274. value: function _onPreChange(event) {
  275. event = this._normalizeEvent(event);
  276. event.cancel = function () {
  277. return event.canceled = true;
  278. };
  279. util.triggerElementEvent(this, 'prechange', event);
  280. if (!event.canceled) {
  281. var _event = event,
  282. activeIndex = _event.activeIndex,
  283. lastActiveIndex = _event.lastActiveIndex;
  284. var tabs = this.tabs;
  285. tabs[activeIndex].setActive(true);
  286. if (lastActiveIndex >= 0) {
  287. var prevTab = tabs[lastActiveIndex];
  288. prevTab.setActive(false);
  289. prevTab.pageElement && prevTab.pageElement._hide();
  290. }
  291. }
  292. return event.canceled;
  293. }
  294. }, {
  295. key: '_onScroll',
  296. value: function _onScroll(index) {
  297. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  298. if (this._tabbarBorder) {
  299. this._tabbarBorder.style.transition = 'all ' + (options.duration || 0) + 's ' + (options.timing || '');
  300. if (this._autogrow && this._tabsRect.length > 0) {
  301. var a = Math.floor(index),
  302. b = Math.ceil(index),
  303. r = index % 1;
  304. this._tabbarBorder.style.width = lerp(this._tabsRect[a].width, this._tabsRect[b].width, r) + 'px';
  305. this._tabbarBorder.style.transform = 'translate3d(' + lerp(this._tabsRect[a].left, this._tabsRect[b].left, r) + 'px, 0, 0)';
  306. } else {
  307. this._tabbarBorder.style.transform = 'translate3d(' + index * 100 + '%, 0, 0)';
  308. }
  309. }
  310. this._onSwipe && this._onSwipe(index, options);
  311. }
  312. }, {
  313. key: '_onRefresh',
  314. value: function _onRefresh() {
  315. this._autogrow = util.hasModifier(this, 'autogrow');
  316. this._tabsRect = this.tabs.map(function (tab) {
  317. return tab.getBoundingClientRect();
  318. });
  319. if (this._tabbarBorder) {
  320. this._tabbarBorder.style.display = this.hasAttribute('tab-border') || util.hasModifier(this, 'material') ? 'block' : 'none';
  321. var index = this.getActiveTabIndex();
  322. if (this._tabsRect.length > 0 && index >= 0) {
  323. this._tabbarBorder.style.width = this._tabsRect[index].width + 'px';
  324. }
  325. }
  326. }
  327. }, {
  328. key: '_getAutoScrollRatio',
  329. value: function _getAutoScrollRatio(matches, velocity, size) {
  330. var ratio = .6; // Base ratio
  331. var modifier = size / 300 * (matches ? -1 : 1); // Based on screen size
  332. return Math.min(1, Math.max(0, ratio + velocity * modifier));
  333. }
  334. }, {
  335. key: '_compile',
  336. value: function _compile() {
  337. autoStyle.prepare(this);
  338. var content = this._contentElement || util.create('.tabbar__content');
  339. content.classList.add('ons-tabbar__content');
  340. var tabbar = this._tabbarElement || util.create('.tabbar');
  341. tabbar.classList.add('ons-tabbar__footer');
  342. if (!tabbar.parentNode) {
  343. while (this.firstChild) {
  344. tabbar.appendChild(this.firstChild);
  345. }
  346. }
  347. var activeIndex = Number(this.getAttribute('activeIndex')); // 0 by default
  348. if (tabbar.children.length > activeIndex && !util.findChild(tabbar, '[active]')) {
  349. tabbar.children[activeIndex].setAttribute('active', '');
  350. }
  351. this._tabbarBorder = util.findChild(tabbar, '.tabbar__border') || util.create('.tabbar__border');
  352. tabbar.appendChild(this._tabbarBorder);
  353. tabbar.classList.add('ons-swiper-tabbar'); // Hides material border
  354. !content.children[0] && content.appendChild(document.createElement('div'));
  355. !content.children[1] && content.appendChild(document.createElement('div'));
  356. content.appendChild = content.appendChild.bind(content.children[0]);
  357. content.insertBefore = content.insertBefore.bind(content.children[0]);
  358. this.appendChild(content);
  359. this.appendChild(tabbar); // Triggers ons-tab connectedCallback
  360. ModifierUtil.initModifier(this, scheme);
  361. }
  362. }, {
  363. key: '_updatePosition',
  364. value: function _updatePosition() {
  365. var _this3 = this;
  366. var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('position');
  367. var top = this._top = position === 'top' || position === 'auto' && util.hasModifier(this, 'material');
  368. var action = top ? util.addModifier : util.removeModifier;
  369. action(this, 'top');
  370. var page = util.findParent(this, 'ons-page');
  371. if (page) {
  372. contentReady(page, function () {
  373. var p = 0;
  374. if (page.children[0] && util.match(page.children[0], 'ons-toolbar')) {
  375. action(page.children[0], 'noshadow');
  376. p = 1; // Visual fix for some devices
  377. }
  378. var content = page._getContentElement();
  379. var cs = window.getComputedStyle(page._getContentElement(), null);
  380. _this3.style.top = top ? parseInt(cs.getPropertyValue('padding-top'), 10) - p + 'px' : '';
  381. // Refresh content top - Fix for iOS 8
  382. content.style.top = cs.top;
  383. content.style.top = '';
  384. });
  385. }
  386. internal.autoStatusBarFill(function () {
  387. var filled = util.findParent(_this3, function (e) {
  388. return e.hasAttribute('status-bar-fill');
  389. });
  390. util.toggleAttribute(_this3, 'status-bar-fill', top && !filled);
  391. });
  392. }
  393. }, {
  394. key: 'setActiveTab',
  395. /**
  396. * @method setActiveTab
  397. * @signature setActiveTab(index, [options])
  398. * @param {Number} index
  399. * [en]Tab index.[/en]
  400. * [ja]タブのインデックスを指定します。[/ja]
  401. * @param {Object} [options]
  402. * [en]Parameter object.[/en]
  403. * [ja]オプションを指定するオブジェクト。[/ja]
  404. * @param {Function} [options.callback]
  405. * [en]Function that runs when the new page has loaded.[/en]
  406. * [ja][/ja]
  407. * @param {String} [options.animation]
  408. * [en]If this option is "none", the transition won't slide.[/en]
  409. * [ja][/ja]
  410. * @param {String} [options.animationOptions]
  411. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  412. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  413. * @description
  414. * [en]Show specified tab page. Animations and their options can be specified by the second parameter.[/en]
  415. * [ja]指定したインデックスのタブを表示します。アニメーションなどのオプションを指定できます。[/ja]
  416. * @return {Promise}
  417. * [en]A promise that resolves to the new page element.[/en]
  418. * [ja][/ja]
  419. */
  420. value: function setActiveTab(nextIndex) {
  421. var _this4 = this;
  422. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  423. var prevIndex = this.getActiveTabIndex();
  424. var prevTab = this.tabs[prevIndex],
  425. nextTab = this.tabs[nextIndex];
  426. if (!nextTab) {
  427. return _Promise.reject('Specified index does not match any tab.');
  428. }
  429. if (nextIndex === prevIndex) {
  430. util.triggerElementEvent(this, 'reactive', { index: nextIndex, activeIndex: nextIndex, tabItem: nextTab });
  431. return _Promise.resolve(nextTab.pageElement);
  432. }
  433. // FIXME: nextTab.loaded is broken in Zone.js promises (Angular2)
  434. var nextPage = nextTab.pageElement;
  435. return (nextPage ? _Promise.resolve(nextPage) : nextTab.loaded).then(function (nextPage) {
  436. return _this4._swiper.setActiveIndex(nextIndex, _extends({
  437. reject: true
  438. }, options, {
  439. animation: prevTab && nextPage ? options.animation || _this4.getAttribute('animation') : 'none',
  440. animationOptions: util.extend({ duration: .3, timing: 'cubic-bezier(.4, .7, .5, 1)' }, _this4.hasAttribute('animation-options') ? util.animationOptionsParse(_this4.getAttribute('animation-options')) : {}, options.animationOptions || {})
  441. })).then(function () {
  442. options.callback instanceof Function && options.callback(nextPage);
  443. return nextPage;
  444. });
  445. });
  446. }
  447. /**
  448. * @method setTabbarVisibility
  449. * @signature setTabbarVisibility(visible)
  450. * @param {Boolean} visible
  451. * @description
  452. * [en]Used to hide or show the tab bar.[/en]
  453. * [ja][/ja]
  454. */
  455. }, {
  456. key: 'setTabbarVisibility',
  457. value: function setTabbarVisibility(visible) {
  458. var _this5 = this;
  459. contentReady(this, function () {
  460. _this5._contentElement.style[_this5._top ? 'top' : 'bottom'] = visible ? '' : '0px';
  461. _this5._tabbarElement.style.display = visible ? '' : 'none';
  462. visible && _this5._onRefresh();
  463. });
  464. }
  465. }, {
  466. key: 'show',
  467. value: function show() {
  468. this.setTabbarVisibility(true);
  469. }
  470. }, {
  471. key: 'hide',
  472. value: function hide() {
  473. this.setTabbarVisibility(false);
  474. }
  475. /**
  476. * @property visible
  477. * @readonly
  478. * @type {Boolean}
  479. * @description
  480. * [en]Whether the tabbar is visible or not.[/en]
  481. * [ja]タブバーが見える場合に`true`。[/ja]
  482. */
  483. }, {
  484. key: 'getActiveTabIndex',
  485. /**
  486. * @method getActiveTabIndex
  487. * @signature getActiveTabIndex()
  488. * @return {Number}
  489. * [en]The index of the currently active tab.[/en]
  490. * [ja]現在アクティブになっているタブのインデックスを返します。[/ja]
  491. * @description
  492. * [en]Returns tab index on current active tab. If active tab is not found, returns -1.[/en]
  493. * [ja]現在アクティブになっているタブのインデックスを返します。現在アクティブなタブがない場合には-1を返します。[/ja]
  494. */
  495. value: function getActiveTabIndex() {
  496. var tabs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.tabs;
  497. for (var i = 0; i < tabs.length; i++) {
  498. if (tabs[i] && tabs[i].tagName === 'ONS-TAB' && tabs[i].isActive()) {
  499. return i;
  500. }
  501. }
  502. return -1;
  503. }
  504. }, {
  505. key: '_show',
  506. value: function _show() {
  507. var _this6 = this;
  508. this._swiper.show();
  509. _setImmediate(function () {
  510. var tabs = _this6.tabs;
  511. var activeIndex = _this6.getActiveTabIndex(tabs);
  512. _this6._loadInactive.resolve();
  513. if (tabs.length > 0 && activeIndex >= 0) {
  514. tabs[activeIndex].loaded.then(function (el) {
  515. return el && _setImmediate(function () {
  516. return el._show();
  517. });
  518. });
  519. }
  520. });
  521. }
  522. }, {
  523. key: '_hide',
  524. value: function _hide() {
  525. this._swiper.hide();
  526. var topPage = this.topPage;
  527. topPage && topPage._hide();
  528. }
  529. }, {
  530. key: '_destroy',
  531. value: function _destroy() {
  532. this.tabs.forEach(function (tab) {
  533. return tab.remove();
  534. });
  535. this.remove();
  536. }
  537. }, {
  538. key: 'attributeChangedCallback',
  539. value: function attributeChangedCallback(name, last, current) {
  540. if (name === 'modifier') {
  541. ModifierUtil.onModifierChanged(last, current, this, scheme);
  542. var isTop = function isTop(m) {
  543. return (/(^|\s+)top($|\s+)/i.test(m)
  544. );
  545. };
  546. isTop(last) !== isTop(current) && this._updatePosition();
  547. } else if (name === 'position') {
  548. util.isAttached(this) && this._updatePosition();
  549. } else if (name === 'swipeable') {
  550. this._swiper && this._swiper.updateSwipeable(this.hasAttribute('swipeable'));
  551. } else if (name === 'hide-tabs') {
  552. this.setTabbarVisibility(!this.hasAttribute('hide-tabs') || current === 'false');
  553. }
  554. }
  555. }, {
  556. key: '_tabbarElement',
  557. get: function get() {
  558. return util.findChild(this, '.tabbar');
  559. }
  560. }, {
  561. key: '_contentElement',
  562. get: function get() {
  563. return util.findChild(this, '.tabbar__content');
  564. }
  565. }, {
  566. key: '_targetElement',
  567. get: function get() {
  568. var content = this._contentElement;
  569. return content && content.children[0] || null;
  570. }
  571. }, {
  572. key: 'topPage',
  573. get: function get() {
  574. var tabs = this.tabs,
  575. index = this.getActiveTabIndex();
  576. return tabs[index] ? tabs[index].pageElement || this.pages[0] || null : null;
  577. }
  578. }, {
  579. key: 'pages',
  580. get: function get() {
  581. return util.arrayFrom(this._targetElement.children);
  582. }
  583. }, {
  584. key: 'tabs',
  585. get: function get() {
  586. return Array.prototype.filter.call(this._tabbarElement.children, function (e) {
  587. return e.tagName === 'ONS-TAB';
  588. });
  589. }
  590. }, {
  591. key: 'visible',
  592. get: function get() {
  593. return this._tabbarElement.style.display !== 'none';
  594. }
  595. /**
  596. * @property swipeable
  597. * @type {Boolean}
  598. * @description
  599. * [en]Enable swipe interaction.[/en]
  600. * [ja]swipeableであればtrueを返します。[/ja]
  601. */
  602. }, {
  603. key: 'swipeable',
  604. get: function get() {
  605. return this.hasAttribute('swipeable');
  606. },
  607. set: function set(value) {
  608. return util.toggleAttribute(this, 'swipeable', value);
  609. }
  610. /**
  611. * @property onSwipe
  612. * @type {Function}
  613. * @description
  614. * [en]Hook called whenever the user slides the tabbar. It gets a decimal index and an animationOptions object as arguments.[/en]
  615. * [ja][/ja]
  616. */
  617. }, {
  618. key: 'onSwipe',
  619. get: function get() {
  620. return this._onSwipe;
  621. },
  622. set: function set(value) {
  623. if (value && !(value instanceof Function)) {
  624. util.throw('"onSwipe" must be a function');
  625. }
  626. this._onSwipe = value;
  627. }
  628. }], [{
  629. key: 'observedAttributes',
  630. get: function get() {
  631. return ['modifier', 'position', 'swipeable', 'tab-border', 'hide-tabs'];
  632. }
  633. }, {
  634. key: 'rewritables',
  635. get: function get() {
  636. return rewritables;
  637. }
  638. }, {
  639. key: 'events',
  640. get: function get() {
  641. return ['prechange', 'postchange', 'reactive'];
  642. }
  643. }]);
  644. return TabbarElement;
  645. }(BaseElement);
  646. export default TabbarElement;
  647. onsElements.Tabbar = TabbarElement;
  648. customElements.define('ons-tabbar', TabbarElement);