Geen omschrijving

ons-splitter-side.js 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. import _Promise from 'babel-runtime/core-js/promise';
  2. import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
  3. import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
  4. import _inherits from 'babel-runtime/helpers/inherits';
  5. import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
  6. import _createClass from 'babel-runtime/helpers/createClass';
  7. import _setImmediate from 'babel-runtime/core-js/set-immediate';
  8. /*
  9. Copyright 2013-2015 ASIAL CORPORATION
  10. Licensed under the Apache License, Version 2.0 (the "License");
  11. you may not use this file except in compliance with the License.
  12. You may obtain a copy of the License at
  13. http://www.apache.org/licenses/LICENSE-2.0
  14. Unless required by applicable law or agreed to in writing, software
  15. distributed under the License is distributed on an "AS IS" BASIS,
  16. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. See the License for the specific language governing permissions and
  18. limitations under the License.
  19. */
  20. import onsElements from '../ons/elements';
  21. import util from '../ons/util';
  22. import AnimatorFactory from '../ons/internal/animator-factory';
  23. import orientation from '../ons/orientation';
  24. import internal from '../ons/internal';
  25. import ModifierUtil from '../ons/internal/modifier-util';
  26. import BaseElement from './base/base-element';
  27. import SplitterAnimator from './ons-splitter/animator';
  28. import SwipeReveal from '../ons/internal/swipe-reveal';
  29. import DoorLock from '../ons/doorlock';
  30. import contentReady from '../ons/content-ready';
  31. import { PageLoader, defaultPageLoader } from '../ons/page-loader';
  32. import SplitterElement from './ons-splitter';
  33. var SPLIT_MODE = 'split';
  34. var COLLAPSE_MODE = 'collapse';
  35. var CLOSED_STATE = 'closed';
  36. var OPEN_STATE = 'open';
  37. var CHANGING_STATE = 'changing';
  38. var rewritables = {
  39. /**
  40. * @param {Element} splitterSideElement
  41. * @param {Function} callback
  42. */
  43. ready: function ready(splitterSideElement, callback) {
  44. _setImmediate(callback);
  45. }
  46. };
  47. var CollapseDetection = function () {
  48. function CollapseDetection(element, target) {
  49. _classCallCheck(this, CollapseDetection);
  50. this._element = element;
  51. this._onChange = this._onChange.bind(this);
  52. target && this.changeTarget(target);
  53. }
  54. _createClass(CollapseDetection, [{
  55. key: 'changeTarget',
  56. value: function changeTarget(target) {
  57. this.disable();
  58. this._target = target;
  59. if (target) {
  60. this._orientation = ['portrait', 'landscape'].indexOf(target) !== -1;
  61. this.activate();
  62. }
  63. }
  64. }, {
  65. key: '_match',
  66. value: function _match(value) {
  67. if (this._orientation) {
  68. return this._target === (value.isPortrait ? 'portrait' : 'landscape');
  69. }
  70. return value.matches;
  71. }
  72. }, {
  73. key: '_onChange',
  74. value: function _onChange(value) {
  75. this._element._updateMode(this._match(value) ? COLLAPSE_MODE : SPLIT_MODE);
  76. }
  77. }, {
  78. key: 'activate',
  79. value: function activate() {
  80. if (this._orientation) {
  81. orientation.on('change', this._onChange);
  82. this._onChange({ isPortrait: orientation.isPortrait() });
  83. } else {
  84. this._queryResult = window.matchMedia(this._target);
  85. this._queryResult.addListener(this._onChange);
  86. this._onChange(this._queryResult);
  87. }
  88. }
  89. }, {
  90. key: 'disable',
  91. value: function disable() {
  92. if (this._orientation) {
  93. orientation.off('change', this._onChange);
  94. } else if (this._queryResult) {
  95. this._queryResult.removeListener(this._onChange);
  96. this._queryResult = null;
  97. }
  98. }
  99. }]);
  100. return CollapseDetection;
  101. }();
  102. var widthToPx = function widthToPx(width, parent) {
  103. var _ref = [parseInt(width, 10), /px/.test(width)],
  104. value = _ref[0],
  105. px = _ref[1];
  106. return px ? value : Math.round(parent.offsetWidth * value / 100);
  107. };
  108. /**
  109. * @element ons-splitter-side
  110. * @category menu
  111. * @description
  112. * [en]
  113. * The `<ons-splitter-side>` element is used as a child element of `<ons-splitter>`.
  114. *
  115. * It will be displayed on either the left or right side of the `<ons-splitter-content>` element.
  116. *
  117. * It supports two modes: collapsed and split. When it's in collapsed mode it will be hidden from view and can be displayed when the user swipes the screen or taps a button. In split mode the element is always shown. It can be configured to automatically switch between the two modes depending on the screen size.
  118. * [/en]
  119. * [ja]ons-splitter-side要素は、ons-splitter要素の子要素として利用します。[/ja]
  120. * @codepen rOQOML
  121. * @tutorial vanilla/Reference/splitter
  122. * @guide fundamentals.html#managing-pages
  123. * [en]Managing multiple pages.[/en]
  124. * [ja]複数のページを管理する[/ja]
  125. * @seealso ons-splitter
  126. * [en]The `<ons-splitter>` is the parent component.[/en]
  127. * [ja]ons-splitterコンポーネント[/ja]
  128. * @seealso ons-splitter-content
  129. * [en]The `<ons-splitter-content>` component contains the main content of the page.[/en]
  130. * [ja]ons-splitter-contentコンポーネント[/ja]
  131. * @example
  132. * <ons-splitter>
  133. * <ons-splitter-content>
  134. * ...
  135. * </ons-splitter-content>
  136. *
  137. * <ons-splitter-side side="left" width="80%" collapse>
  138. * ...
  139. * </ons-splitter-side>
  140. * </ons-splitter>
  141. */
  142. var SplitterSideElement = function (_BaseElement) {
  143. _inherits(SplitterSideElement, _BaseElement);
  144. /**
  145. * @event modechange
  146. * @description
  147. * [en]Fired just after the component's mode changes.[/en]
  148. * [ja]この要素のモードが変化した際に発火します。[/ja]
  149. * @param {Object} event
  150. * [en]Event object.[/en]
  151. * [ja]イベントオブジェクトです。[/ja]
  152. * @param {Object} event.side
  153. * [en]Component object.[/en]
  154. * [ja]コンポーネントのオブジェクト。[/ja]
  155. * @param {String} event.mode
  156. * [en]Returns the current mode. Can be either `"collapse"` or `"split"`.[/en]
  157. * [ja]現在のモードを返します。[/ja]
  158. */
  159. /**
  160. * @event preopen
  161. * @description
  162. * [en]Fired just before the sliding menu is opened.[/en]
  163. * [ja]スライディングメニューが開く前に発火します。[/ja]
  164. * @param {Object} event
  165. * [en]Event object.[/en]
  166. * [ja]イベントオブジェクトです。[/ja]
  167. * @param {Function} event.cancel
  168. * [en]Call to cancel opening sliding menu.[/en]
  169. * [ja]スライディングメニューが開くのをキャンセルします。[/ja]
  170. * @param {Object} event.side
  171. * [en]Component object.[/en]
  172. * [ja]コンポーネントのオブジェクト。[/ja]
  173. */
  174. /**
  175. * @event postopen
  176. * @description
  177. * [en]Fired just after the sliding menu is opened.[/en]
  178. * [ja]スライディングメニューが開いた後に発火します。[/ja]
  179. * @param {Object} event
  180. * [en]Event object.[/en]
  181. * [ja]イベントオブジェクトです。[/ja]
  182. * @param {Object} event.side
  183. * [en]Component object.[/en]
  184. * [ja]コンポーネントのオブジェクト。[/ja]
  185. */
  186. /**
  187. * @event preclose
  188. * @description
  189. * [en]Fired just before the sliding menu is closed.[/en]
  190. * [ja]スライディングメニューが閉じる前に発火します。[/ja]
  191. * @param {Object} event
  192. * [en]Event object.[/en]
  193. * [ja]イベントオブジェクトです。[/ja]
  194. * @param {Object} event.side
  195. * [en]Component object.[/en]
  196. * [ja]コンポーネントのオブジェクト。[/ja]
  197. * @param {Function} event.cancel
  198. * [en]Call to cancel opening sliding-menu.[/en]
  199. * [ja]スライディングメニューが閉じるのをキャンセルします。[/ja]
  200. */
  201. /**
  202. * @event postclose
  203. * @description
  204. * [en]Fired just after the sliding menu is closed.[/en]
  205. * [ja]スライディングメニューが閉じた後に発火します。[/ja]
  206. * @param {Object} event
  207. * [en]Event object.[/en]
  208. * [ja]イベントオブジェクトです。[/ja]
  209. * @param {Object} event.side
  210. * [en]Component object.[/en]
  211. * [ja]コンポーネントのオブジェクト。[/ja]
  212. */
  213. /**
  214. * @attribute animation
  215. * @type {String}
  216. * @default default
  217. * @description
  218. * [en]Specify the animation. Use one of `overlay`, `push`, `reveal` or `default`.[/en]
  219. * [ja]アニメーションを指定します。"overlay", "push", "reveal", "default"のいずれかを指定できます。[/ja]
  220. */
  221. /**
  222. * @attribute animation-options
  223. * @type {Expression}
  224. * @description
  225. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  226. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. {duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
  227. */
  228. /**
  229. * @attribute open-threshold
  230. * @type {Number}
  231. * @default 0.3
  232. * @description
  233. * [en]Specify how much the menu needs to be swiped before opening. A value between `0` and `1`.[/en]
  234. * [ja]どのくらいスワイプすればスライディングメニューを開くかどうかの割合を指定します。0から1の間の数値を指定します。スワイプの距離がここで指定した数値掛けるこの要素の幅よりも大きければ、スワイプが終わった時にこの要素を開きます。デフォルトは0.3です。[/ja]
  235. */
  236. /**
  237. * @attribute collapse
  238. * @type {String}
  239. * @description
  240. * [en]
  241. * Specify the collapse behavior. Valid values are `"portrait"`, `"landscape"` or a media query.
  242. * The strings `"portrait"` and `"landscape"` means the view will collapse when device is in landscape or portrait orientation.
  243. * If the value is a media query, the view will collapse when the media query resolves to `true`.
  244. * If the value is not defined, the view always be in `"collapse"` mode.
  245. * [/en]
  246. * [ja]
  247. * 左側のページを非表示にする条件を指定します。portrait, landscape、width #pxもしくはメディアクエリの指定が可能です。
  248. * portraitもしくはlandscapeを指定すると、デバイスの画面が縦向きもしくは横向きになった時に適用されます。
  249. * メディアクエリを指定すると、指定したクエリに適合している場合に適用されます。
  250. * 値に何も指定しない場合には、常にcollapseモードになります。
  251. * [/ja]
  252. */
  253. /**
  254. * @attribute swipe-target-width
  255. * @type {String}
  256. * @description
  257. * [en]The width of swipeable area calculated from the edge (in pixels). Use this to enable swipe only when the finger touch on the screen edge.[/en]
  258. * [ja]スワイプの判定領域をピクセル単位で指定します。画面の端から指定した距離に達するとページが表示されます。[/ja]
  259. */
  260. /**
  261. * @attribute width
  262. * @type {String}
  263. * @description
  264. * [en]Can be specified in either pixels or as a percentage, e.g. `90%` or `200px`.[/en]
  265. * [ja]この要素の横幅を指定します。pxと%での指定が可能です。eg. 90%, 200px[/ja]
  266. */
  267. /**
  268. * @attribute side
  269. * @type {String}
  270. * @default left
  271. * @description
  272. * [en]Specify which side of the screen the `<ons-splitter-side>` element is located. Possible values are `"left"` and `"right"`.[/en]
  273. * [ja]この要素が左か右かを指定します。指定できる値は"left"か"right"のみです。[/ja]
  274. */
  275. /**
  276. * @attribute mode
  277. * @type {String}
  278. * @description
  279. * [en]Current mode. Possible values are `"collapse"` or `"split"`. This attribute is read only.[/en]
  280. * [ja]現在のモードが設定されます。"collapse"もしくは"split"が指定されます。この属性は読み込み専用です。[/ja]
  281. */
  282. /**
  283. * @attribute page
  284. * @initonly
  285. * @type {String}
  286. * @description
  287. * [en]The URL of the menu page.[/en]
  288. * [ja]ons-splitter-side要素に表示するページのURLを指定します。[/ja]
  289. */
  290. /**
  291. * @attribute swipeable
  292. * @type {Boolean}
  293. * @description
  294. * [en]Whether to enable swipe interaction on collapse mode.[/en]
  295. * [ja]collapseモード時にスワイプ操作を有効にする場合に指定します。[/ja]
  296. */
  297. function SplitterSideElement() {
  298. _classCallCheck(this, SplitterSideElement);
  299. var _this = _possibleConstructorReturn(this, (SplitterSideElement.__proto__ || _Object$getPrototypeOf(SplitterSideElement)).call(this));
  300. _this._page = null;
  301. _this._state = CLOSED_STATE;
  302. _this._lock = new DoorLock();
  303. _this._pageLoader = defaultPageLoader;
  304. _this._collapseDetection = new CollapseDetection(_this);
  305. _this._animatorFactory = new AnimatorFactory({
  306. animators: SplitterElement.animators,
  307. baseClass: SplitterAnimator,
  308. baseClassName: 'SplitterAnimator',
  309. defaultAnimation: _this.getAttribute('animation')
  310. });
  311. contentReady(_this, function () {
  312. // These attributes are used early by the parent element
  313. _this.attributeChangedCallback('width');
  314. if (!_this.hasAttribute('side')) {
  315. _this.setAttribute('side', 'left');
  316. }
  317. rewritables.ready(_this, function () {
  318. var page = _this._page || _this.getAttribute('page');
  319. page && _this.load(page);
  320. });
  321. });
  322. return _this;
  323. }
  324. _createClass(SplitterSideElement, [{
  325. key: 'connectedCallback',
  326. value: function connectedCallback() {
  327. var _this2 = this;
  328. if (!util.match(this.parentNode, 'ons-splitter')) {
  329. util.throw('Parent must be an ons-splitter element');
  330. }
  331. this._swipe = new SwipeReveal({
  332. element: this,
  333. elementHandler: this.parentElement,
  334. swipeMax: function swipeMax() {
  335. _this2._onSwipe && _this2._onSwipe(1, _this2._animationOpt);
  336. _this2.open();
  337. },
  338. swipeMid: function swipeMid(distance, width) {
  339. _this2._onSwipe && _this2._onSwipe(distance / width);
  340. _this2._animator.translate(distance);
  341. },
  342. swipeMin: function swipeMin() {
  343. _this2._onSwipe && _this2._onSwipe(0, _this2._animationOpt);
  344. _this2.close();
  345. },
  346. getThreshold: function getThreshold() {
  347. return Math.max(0, Math.min(1, parseFloat(_this2.getAttribute('open-threshold')) || 0.3));
  348. },
  349. getSide: function getSide() {
  350. return _this2.side;
  351. },
  352. isInitialState: function isInitialState() {
  353. var closed = _this2._state === CLOSED_STATE;
  354. _this2._state = CHANGING_STATE;
  355. return closed;
  356. },
  357. ignoreSwipe: function ignoreSwipe(event, distance) {
  358. var isOpen = _this2.isOpen;
  359. var validDrag = function validDrag(d) {
  360. return _this2.side === 'left' ? d === 'left' && isOpen || d === 'right' && !isOpen : d === 'left' && !isOpen || d === 'right' && isOpen;
  361. };
  362. var area = Math.max(0, parseInt(_this2.getAttribute('swipe-target-width'), 10) || 0);
  363. return _this2._mode === SPLIT_MODE || _this2._lock.isLocked() || _this2._isOtherSideOpen() || !validDrag(event.gesture.direction) || !isOpen && area !== 0 && distance > area;
  364. }
  365. });
  366. this.attributeChangedCallback('swipeable');
  367. contentReady(this, function () {
  368. _this2.constructor.observedAttributes.forEach(function (attr) {
  369. return _this2.attributeChangedCallback(attr, null, _this2.getAttribute(attr));
  370. });
  371. });
  372. }
  373. }, {
  374. key: 'disconnectedCallback',
  375. value: function disconnectedCallback() {
  376. this._swipe && this._swipe.dispose();
  377. this._animator = this._animationOpt = this._swipe = null;
  378. }
  379. }, {
  380. key: 'attributeChangedCallback',
  381. value: function attributeChangedCallback(name, last, current) {
  382. switch (name) {
  383. case 'swipeable':
  384. this._swipe && this._swipe.update();
  385. break;
  386. case 'width':
  387. current = this.getAttribute('width'); // Sometimes undefined. CE bug?
  388. this.style.width = /^\d+(px|%)$/.test(current) ? current : '80%';
  389. break;
  390. default:
  391. this[util.camelize('_update-' + name)](current);
  392. }
  393. }
  394. }, {
  395. key: '_emitEvent',
  396. value: function _emitEvent(name) {
  397. if (name.slice(0, 3) !== 'pre') {
  398. return util.triggerElementEvent(this, name, { side: this });
  399. }
  400. var isCanceled = false;
  401. util.triggerElementEvent(this, name, {
  402. side: this,
  403. cancel: function cancel() {
  404. return isCanceled = true;
  405. }
  406. });
  407. return isCanceled;
  408. }
  409. }, {
  410. key: '_isOtherSideOpen',
  411. value: function _isOtherSideOpen() {
  412. var _this3 = this;
  413. return !!util.findChild(this.parentElement, function (el) {
  414. return el instanceof _this3.constructor && el !== _this3 && el._mode === COLLAPSE_MODE && el.isOpen;
  415. });
  416. }
  417. }, {
  418. key: '_updateCollapse',
  419. value: function _updateCollapse() {
  420. var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('collapse');
  421. if (value === null || value === 'split') {
  422. this._collapseDetection.disable();
  423. return this._updateMode(SPLIT_MODE);
  424. }
  425. if (value === '' || value === 'collapse') {
  426. this._collapseDetection.disable();
  427. return this._updateMode(COLLAPSE_MODE);
  428. }
  429. this._collapseDetection.changeTarget(value);
  430. }
  431. }, {
  432. key: '_updateMode',
  433. value: function _updateMode(mode) {
  434. if (mode !== this._mode) {
  435. this._mode = mode;
  436. this.setAttribute('mode', mode); // readonly attribute for the users
  437. if (mode === SPLIT_MODE) {
  438. this._animator && this._animator.deactivate();
  439. this._state = CLOSED_STATE;
  440. } else {
  441. this._animator && this._animator.activate(this);
  442. this._state === OPEN_STATE && this._animator.open();
  443. }
  444. util.triggerElementEvent(this, 'modechange', { side: this, mode: mode });
  445. }
  446. }
  447. }, {
  448. key: '_updateAnimation',
  449. value: function _updateAnimation() {
  450. var animation = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('animation');
  451. if (this.parentNode) {
  452. this._animator && this._animator.deactivate();
  453. this._animator = this._animatorFactory.newAnimator({ animation: animation });
  454. this._animator.activate(this);
  455. this._animationOpt = {
  456. timing: this._animator.duration,
  457. duration: this._animator.duration
  458. };
  459. }
  460. }
  461. }, {
  462. key: '_updateAnimationOptions',
  463. value: function _updateAnimationOptions() {
  464. var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('animation-options');
  465. this._animator.updateOptions(AnimatorFactory.parseAnimationOptionsString(value));
  466. }
  467. /**
  468. * @property page
  469. * @type {*}
  470. * @description
  471. * [en]Page location to load in the splitter side.[/en]
  472. * [ja]この要素内に表示するページを指定します。[/ja]
  473. */
  474. }, {
  475. key: 'open',
  476. /**
  477. * @method open
  478. * @signature open([options])
  479. * @param {Object} [options]
  480. * [en]Parameter object.[/en]
  481. * [ja]オプションを指定するオブジェクト。[/ja]
  482. * @param {Function} [options.callback]
  483. * [en]This function will be called after the menu has been opened.[/en]
  484. * [ja]メニューが開いた後に呼び出される関数オブジェクトを指定します。[/ja]
  485. * @description
  486. * [en]Open menu in collapse mode.[/en]
  487. * [ja]collapseモードになっているons-splitter-side要素を開きます。[/ja]
  488. * @return {Promise}
  489. * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
  490. * [ja][/ja]
  491. */
  492. value: function open(options) {
  493. return this.toggle(options, true);
  494. }
  495. /**
  496. * @method close
  497. * @signature close([options])
  498. * @param {Object} [options]
  499. * [en]Parameter object.[/en]
  500. * [ja]オプションを指定するオブジェクト。[/ja]
  501. * @param {Function} [options.callback]
  502. * [en]This function will be called after the menu has been closed.[/en]
  503. * [ja]メニューが閉じた後に呼び出される関数オブジェクトを指定します。[/ja]
  504. * @description
  505. * [en]Close menu in collapse mode.[/en]
  506. * [ja]collapseモードになっているons-splitter-side要素を閉じます。[/ja]
  507. * @return {Promise}
  508. * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
  509. * [ja][/ja]
  510. */
  511. }, {
  512. key: 'close',
  513. value: function close(options) {
  514. return this.toggle(options, false);
  515. }
  516. /**
  517. * @method toggle
  518. * @signature toggle([options])
  519. * @param {Object} [options]
  520. * @description
  521. * [en]Opens if it's closed. Closes if it's open.[/en]
  522. * [ja]開けている場合は要素を閉じますそして開けている場合は要素を開きます。[/ja]
  523. * @return {Promise}
  524. * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
  525. * [ja][/ja]
  526. */
  527. }, {
  528. key: 'toggle',
  529. value: function toggle() {
  530. var _this4 = this;
  531. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  532. var force = arguments[1];
  533. var shouldOpen = typeof force === 'boolean' ? force : !this.isOpen;
  534. var action = shouldOpen ? 'open' : 'close';
  535. var FINAL_STATE = shouldOpen ? OPEN_STATE : CLOSED_STATE;
  536. if (this._mode === SPLIT_MODE) {
  537. return _Promise.resolve(false);
  538. }
  539. if (this._state === FINAL_STATE) {
  540. return _Promise.resolve(this);
  541. }
  542. if (this._lock.isLocked()) {
  543. return _Promise.reject('Another splitter-side action is already running.');
  544. }
  545. if (shouldOpen && this._isOtherSideOpen()) {
  546. return _Promise.reject('Another menu is already open.');
  547. }
  548. if (this._emitEvent('pre' + action)) {
  549. return _Promise.reject('Canceled in pre' + action + ' event.');
  550. }
  551. var unlock = this._lock.lock();
  552. this._state = CHANGING_STATE;
  553. if (options.animation) {
  554. this._updateAnimation(options.animation);
  555. }
  556. return new _Promise(function (resolve) {
  557. _this4._animator[action](function () {
  558. util.iosPageScrollFix(shouldOpen);
  559. _this4._state = FINAL_STATE;
  560. unlock();
  561. _this4._emitEvent('post' + action);
  562. options.callback instanceof Function && options.callback(_this4);
  563. resolve(_this4);
  564. });
  565. });
  566. }
  567. /**
  568. * @method load
  569. * @signature load(page, [options])
  570. * @param {String} page
  571. * [en]Page URL. Can be either an HTML document or a `<template>`.[/en]
  572. * [ja]pageのURLか、`<template>`で宣言したテンプレートのid属性の値を指定します。[/ja]
  573. * @param {Object} [options]
  574. * @param {Function} [options.callback]
  575. * @description
  576. * [en]Show the page specified in pageUrl in the right section[/en]
  577. * [ja]指定したURLをメインページを読み込みます。[/ja]
  578. * @return {Promise}
  579. * [en]Resolves to the new page element[/en]
  580. * [ja][/ja]
  581. */
  582. }, {
  583. key: 'load',
  584. value: function load(page) {
  585. var _this5 = this;
  586. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  587. this._page = page;
  588. var callback = options.callback || function () {};
  589. return new _Promise(function (resolve) {
  590. var oldContent = _this5._content || null;
  591. _this5._pageLoader.load({ page: page, parent: _this5 }, function (pageElement) {
  592. if (oldContent) {
  593. _this5._pageLoader.unload(oldContent);
  594. oldContent = null;
  595. }
  596. _setImmediate(function () {
  597. return _this5._show();
  598. });
  599. callback(pageElement);
  600. resolve(pageElement);
  601. });
  602. });
  603. }
  604. }, {
  605. key: '_show',
  606. value: function _show() {
  607. if (this._content) {
  608. this._content._show();
  609. }
  610. }
  611. }, {
  612. key: '_hide',
  613. value: function _hide() {
  614. if (this._content) {
  615. this._content._hide();
  616. }
  617. }
  618. }, {
  619. key: '_destroy',
  620. value: function _destroy() {
  621. if (this._content) {
  622. this._pageLoader.unload(this._content);
  623. }
  624. this.remove();
  625. }
  626. }, {
  627. key: 'side',
  628. get: function get() {
  629. return this.getAttribute('side') === 'right' ? 'right' : 'left';
  630. }
  631. }, {
  632. key: 'page',
  633. get: function get() {
  634. return this._page;
  635. }
  636. /**
  637. * @param {*} page
  638. */
  639. ,
  640. set: function set(page) {
  641. this._page = page;
  642. }
  643. }, {
  644. key: '_content',
  645. get: function get() {
  646. return this.children[0];
  647. }
  648. /**
  649. * @property pageLoader
  650. * @description
  651. * [en][/en]
  652. * [ja][/ja]
  653. */
  654. }, {
  655. key: 'pageLoader',
  656. get: function get() {
  657. return this._pageLoader;
  658. },
  659. set: function set(loader) {
  660. if (!(loader instanceof PageLoader)) {
  661. util.throwPageLoader();
  662. }
  663. this._pageLoader = loader;
  664. }
  665. /**
  666. * @property mode
  667. * @readonly
  668. * @type {String}
  669. * @description
  670. * [en]Current mode. Possible values are "split", "collapse", "closed", "open" or "changing".[/en]
  671. * [ja][/ja]
  672. */
  673. }, {
  674. key: 'mode',
  675. get: function get() {
  676. return this._mode;
  677. }
  678. /**
  679. * @property onSwipe
  680. * @type {Function}
  681. * @description
  682. * [en]Hook called whenever the user slides the splitter. It gets a decimal ratio (0-1) and an animationOptions object as arguments.[/en]
  683. * [ja][/ja]
  684. */
  685. }, {
  686. key: 'onSwipe',
  687. get: function get() {
  688. return this._onSwipe;
  689. },
  690. set: function set(value) {
  691. if (value && !(value instanceof Function)) {
  692. util.throw('"onSwipe" must be a function');
  693. }
  694. this._onSwipe = value;
  695. }
  696. /**
  697. * @property isOpen
  698. * @type {Boolean}
  699. * @readonly
  700. * @description
  701. * [en]This value is `true` when the menu is open.[/en]
  702. * [ja][/ja]
  703. */
  704. }, {
  705. key: 'isOpen',
  706. get: function get() {
  707. return this._mode === COLLAPSE_MODE && this._state !== CLOSED_STATE;
  708. }
  709. }], [{
  710. key: 'observedAttributes',
  711. get: function get() {
  712. return ['animation', 'width', 'collapse', 'swipeable', 'animation-options'];
  713. }
  714. }, {
  715. key: 'events',
  716. get: function get() {
  717. return ['preopen', 'postopen', 'preclose', 'postclose', 'modechange'];
  718. }
  719. }, {
  720. key: 'rewritables',
  721. get: function get() {
  722. return rewritables;
  723. }
  724. }]);
  725. return SplitterSideElement;
  726. }(BaseElement);
  727. export default SplitterSideElement;
  728. onsElements.SplitterSide = SplitterSideElement;
  729. customElements.define('ons-splitter-side', SplitterSideElement);