123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- import _Object$defineProperty from 'babel-runtime/core-js/object/define-property';
- 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 internal from '../ons/internal';
- import autoStyle from '../ons/autostyle';
- import ModifierUtil from '../ons/internal/modifier-util';
- import BaseElement from './base/base-element';
- import deviceBackButtonDispatcher from '../ons/internal/device-back-button-dispatcher';
- import contentReady from '../ons/content-ready';
-
- import './ons-toolbar'; // ensures that 'ons-toolbar' element is registered
-
- var defaultClassName = 'page';
- var scheme = {
- '': 'page--*',
- '.page__content': 'page--*__content',
- '.page__background': 'page--*__background'
- };
-
- /**
- * @element ons-page
- * @category page
- * @modifier material
- * [en]Material Design style[/en]
- * [ja][/ja]
- * @description
- * [en]
- * This component defines the root of each page. If the content is large it will become scrollable.
- *
- * A navigation bar can be added to the top of the page using the `<ons-toolbar>` element.
- * [/en]
- * [ja]ページ定義のためのコンポーネントです。このコンポーネントの内容はスクロールが許可されます。[/ja]
- * @tutorial vanilla/Reference/page
- * @guide lifecycle.html#events
- * [en]Overview of page events[/en]
- * [ja]Overview of page events[/ja]
- * @guide fundamentals.html#managing-pages
- * [en]Managing multiple pages[/en]
- * [ja]複数のページを管理する[/ja]
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @seealso ons-toolbar
- * [en]Use the `<ons-toolbar>` element to add a navigation bar to the top of the page.[/en]
- * [ja][/ja]
- * @example
- * <ons-page>
- * <ons-toolbar>
- * <div class="left">
- * <ons-back-button>Back</ons-back-button>
- * </div>
- * <div class="center">Title</div>
- * <div class="right">
- * <ons-toolbar-button>
- * <ons-icon icon="md-menu"></ons-icon>
- * </ons-toolbar-button>
- * </div>
- * </ons-toolbar>
- *
- * <p>Page content</p>
- * </ons-page>
- *
- * @example
- * <script>
- * myApp.handler = function(done) {
- * loadMore().then(done);
- * }
- * </script>
- *
- * <ons-page on-infinite-scroll="myApp.handler">
- * <ons-toolbar>
- * <div class="center">List</div>
- * </ons-toolbar>
- *
- * <ons-list>
- * <ons-list-item>#1</ons-list-item>
- * <ons-list-item>#2</ons-list-item>
- * <ons-list-item>#3</ons-list-item>
- * ...
- * </ons-list>
- * </ons-page>
- */
-
- var PageElement = function (_BaseElement) {
- _inherits(PageElement, _BaseElement);
-
- /**
- * @event init
- * @description
- * [en]Fired right after the page is attached.[/en]
- * [ja]ページがアタッチされた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- */
-
- /**
- * @event show
- * @description
- * [en]Fired right after the page is shown.[/en]
- * [ja]ページが表示された後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- */
-
- /**
- * @event hide
- * @description
- * [en]Fired right after the page is hidden.[/en]
- * [ja]ページが隠れた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- */
-
- /**
- * @event destroy
- * @description
- * [en]Fired right before the page is destroyed.[/en]
- * [ja]ページが破棄される前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]Specify modifier name to specify custom styles.[/en]
- * [ja]スタイル定義をカスタマイズするための名前を指定します。[/ja]
- */
-
- /**
- * @attribute on-infinite-scroll
- * @type {String}
- * @description
- * [en]Path of the function to be executed on infinite scrolling. Example: `app.loadData`. The function receives a done callback that must be called when it's finished.[/en]
- * [ja][/ja]
- */
-
- function PageElement() {
- _classCallCheck(this, PageElement);
-
- var _this = _possibleConstructorReturn(this, (PageElement.__proto__ || _Object$getPrototypeOf(PageElement)).call(this));
-
- _this._deriveHooks();
-
- _this._defaultClassName = defaultClassName;
- _this.classList.add(defaultClassName);
-
- _this._initialized = false;
-
- contentReady(_this, function () {
- _this._compile();
-
- _this._isShown = false;
- _this._contentElement = _this._getContentElement();
- _this._backgroundElement = _this._getBackgroundElement();
- });
- return _this;
- }
-
- _createClass(PageElement, [{
- key: '_compile',
- value: function _compile() {
- var _this2 = this;
-
- autoStyle.prepare(this);
-
- var toolbar = util.findChild(this, 'ons-toolbar');
-
- var background = util.findChild(this, '.page__background') || util.findChild(this, '.background') || document.createElement('div');
- background.classList.add('page__background');
- this.insertBefore(background, !toolbar && this.firstChild || toolbar && toolbar.nextSibling);
-
- var content = util.findChild(this, '.page__content') || util.findChild(this, '.content') || document.createElement('div');
- content.classList.add('page__content');
- if (!content.parentElement) {
- util.arrayFrom(this.childNodes).forEach(function (node) {
- if (node.nodeType !== 1 || _this2._elementShouldBeMoved(node)) {
- content.appendChild(node); // Can trigger detached connectedCallbacks
- }
- });
- }
-
- this._tryToFillStatusBar(content); // Must run before child pages try to fill status bar.
- this.insertBefore(content, background.nextSibling); // Can trigger attached connectedCallbacks
-
- if ((!toolbar || !util.hasModifier(toolbar, 'transparent')) && content.children.length === 1 && util.isPageControl(content.children[0])) {
- this._defaultClassName += ' page--wrapper';
- this.attributeChangedCallback('class');
- }
-
- var bottomToolbar = util.findChild(this, 'ons-bottom-toolbar');
- if (bottomToolbar) {
- this._defaultClassName += ' page-with-bottom-toolbar';
- this.attributeChangedCallback('class');
- }
-
- ModifierUtil.initModifier(this, scheme);
- }
- }, {
- key: '_elementShouldBeMoved',
- value: function _elementShouldBeMoved(el) {
- if (el.classList.contains('page__background')) {
- return false;
- }
- var tagName = el.tagName.toLowerCase();
- if (tagName === 'ons-fab') {
- return !el.hasAttribute('position');
- }
- var fixedElements = ['script', 'ons-toolbar', 'ons-bottom-toolbar', 'ons-modal', 'ons-speed-dial', 'ons-dialog', 'ons-alert-dialog', 'ons-popover', 'ons-action-sheet'];
- return el.hasAttribute('inline') || fixedElements.indexOf(tagName) === -1;
- }
- }, {
- key: '_tryToFillStatusBar',
- value: function _tryToFillStatusBar() {
- var _this3 = this;
-
- var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._contentElement;
-
- internal.autoStatusBarFill(function () {
- util.toggleAttribute(_this3, 'status-bar-fill', !util.findParent(_this3, function (e) {
- return e.hasAttribute('status-bar-fill');
- }) // Not already filled
- && (_this3._canAnimateToolbar(content) || !util.findChild(content, util.isPageControl)) // Has toolbar or cannot delegate
- );
- });
- }
- }, {
- key: '_canAnimateToolbar',
- value: function _canAnimateToolbar() {
- var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._contentElement;
-
- if (util.findChild(this, 'ons-toolbar')) {
- return true;
- }
-
- return !!util.findChild(content, function (el) {
- return util.match(el, 'ons-toolbar') && !el.hasAttribute('inline');
- });
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this4 = this;
-
- if (!util.isAttached(this)) {
- // Avoid detached calls
- return;
- }
-
- contentReady(this, function () {
- _this4._tryToFillStatusBar(); // Ensure status bar when the element was compiled before connected
-
- if (_this4.hasAttribute('on-infinite-scroll')) {
- _this4.attributeChangedCallback('on-infinite-scroll', null, _this4.getAttribute('on-infinite-scroll'));
- }
-
- if (!_this4._initialized) {
- _this4._initialized = true;
-
- _setImmediate(function () {
- _this4.onInit && _this4.onInit();
- util.triggerElementEvent(_this4, 'init');
- });
-
- if (!util.hasAnyComponentAsParent(_this4)) {
- _setImmediate(function () {
- return _this4._show();
- });
- }
- }
- });
- }
- }, {
- key: 'updateBackButton',
- value: function updateBackButton(show) {
- if (this.backButton) {
- show ? this.backButton.show() : this.backButton.hide();
- }
- }
- }, {
- key: '_onScroll',
- value: function _onScroll() {
- var _this5 = this;
-
- var c = this._contentElement,
- overLimit = (c.scrollTop + c.clientHeight) / c.scrollHeight >= this._infiniteScrollLimit;
-
- if (this._onInfiniteScroll && !this._loadingContent && overLimit) {
- this._loadingContent = true;
- this._onInfiniteScroll(function () {
- return _this5._loadingContent = false;
- });
- }
- }
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- }, {
- key: '_getContentElement',
- value: function _getContentElement() {
- var result = util.findChild(this, '.page__content');
- if (result) {
- return result;
- }
- util.throw('Fail to get ".page__content" element');
- }
- }, {
- key: '_getBackgroundElement',
- value: function _getBackgroundElement() {
- var result = util.findChild(this, '.page__background');
- if (result) {
- return result;
- }
- util.throw('Fail to get ".page__background" element');
- }
- }, {
- key: '_getBottomToolbarElement',
- value: function _getBottomToolbarElement() {
- return util.findChild(this, 'ons-bottom-toolbar') || internal.nullElement;
- }
- }, {
- key: '_getToolbarElement',
- value: function _getToolbarElement() {
- return util.findChild(this, 'ons-toolbar') || document.createElement('ons-toolbar');
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- var _this6 = this;
-
- switch (name) {
- case 'class':
- util.restoreClass(this, this._defaultClassName, scheme);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme);
- break;
- case 'on-infinite-scroll':
- if (current === null) {
- this.onInfiniteScroll = null;
- } else {
- this.onInfiniteScroll = function (done) {
- var f = util.findFromPath(current);
- _this6.onInfiniteScroll = f;
- f(done);
- };
- }
- break;
- }
- }
- }, {
- key: '_show',
- value: function _show() {
- if (!this._isShown && util.isAttached(this)) {
- this._isShown = true;
- this.setAttribute('shown', '');
- this.onShow && this.onShow();
- util.triggerElementEvent(this, 'show');
- util.propagateAction(this, '_show');
- }
- }
- }, {
- key: '_hide',
- value: function _hide() {
- if (this._isShown) {
- this._isShown = false;
- this.removeAttribute('shown');
- this.onHide && this.onHide();
- util.triggerElementEvent(this, 'hide');
- util.propagateAction(this, '_hide');
- }
- }
- }, {
- key: '_destroy',
- value: function _destroy() {
- this._hide();
-
- this.onDestroy && this.onDestroy();
- util.triggerElementEvent(this, 'destroy');
-
- if (this.onDeviceBackButton) {
- this.onDeviceBackButton.destroy();
- }
-
- util.propagateAction(this, '_destroy');
-
- this.remove();
- }
- }, {
- key: '_deriveHooks',
- value: function _deriveHooks() {
- var _this7 = this;
-
- this.constructor.events.forEach(function (event) {
- var key = 'on' + event.charAt(0).toUpperCase() + event.slice(1);
- _Object$defineProperty(_this7, key, {
- configurable: true,
- enumerable: true,
- get: function get() {
- return _this7['_' + key];
- },
- set: function set(value) {
- if (!(value instanceof Function)) {
- util.throw('"' + key + '" hook must be a function');
- }
- _this7['_' + key] = value.bind(_this7);
- }
- });
- });
- }
- }, {
- key: 'name',
- set: function set(str) {
- this.setAttribute('name', str);
- },
- get: function get() {
- return this.getAttribute('name');
- }
- }, {
- key: 'backButton',
- get: function get() {
- return this.querySelector('ons-back-button');
- }
-
- /**
- * @property onInfiniteScroll
- * @description
- * [en]Function to be executed when scrolling to the bottom of the page. The function receives a done callback as an argument that must be called when it's finished.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'onInfiniteScroll',
- set: function set(value) {
- var _this8 = this;
-
- if (value && !(value instanceof Function)) {
- util.throw('"onInfiniteScroll" must be function or null');
- }
-
- contentReady(this, function () {
- if (!value) {
- _this8._contentElement.removeEventListener('scroll', _this8._boundOnScroll);
- } else if (!_this8._onInfiniteScroll) {
- _this8._infiniteScrollLimit = 0.9;
- _this8._boundOnScroll = _this8._onScroll.bind(_this8);
- _setImmediate(function () {
- return _this8._contentElement.addEventListener('scroll', _this8._boundOnScroll);
- });
- }
- _this8._onInfiniteScroll = value;
- });
- },
- get: function get() {
- return this._onInfiniteScroll;
- }
- }, {
- key: 'onDeviceBackButton',
- get: function get() {
- return this._backButtonHandler;
- },
- set: function set(callback) {
- if (this._backButtonHandler) {
- this._backButtonHandler.destroy();
- }
-
- this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
- }
- }, {
- key: 'scrollTop',
- get: function get() {
- return this._contentElement.scrollTop;
- },
- set: function set(newValue) {
- this._contentElement.scrollTop = newValue;
- }
- }], [{
- key: 'observedAttributes',
- get: function get() {
- return ['modifier', 'on-infinite-scroll', 'class'];
- }
- }, {
- key: 'events',
- get: function get() {
- return ['init', 'show', 'hide', 'destroy'];
- }
-
- /**
- * @property data
- * @type {*}
- * @description
- * [en]User's custom data passed to `pushPage()`-like methods.[/en]
- * [ja][/ja]
- */
-
- }]);
-
- return PageElement;
- }(BaseElement);
-
- export default PageElement;
-
-
- onsElements.Page = PageElement;
- customElements.define('ons-page', PageElement);
|