- *
- */
+var _util2 = _interopRequireDefault(_util);
-var BackButtonElement = function (_BaseElement) {
- _inherits(BackButtonElement, _BaseElement);
+var _internal = __webpack_require__(7);
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the back button.[/en]
- * [ja]バックボタンの見た目を指定します。[/ja]
- */
+var _internal2 = _interopRequireDefault(_internal);
- function BackButtonElement() {
- _classCallCheck(this, BackButtonElement);
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
- var _this = _possibleConstructorReturn(this, (BackButtonElement.__proto__ || Object.getPrototypeOf(BackButtonElement)).call(this));
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- (0, _contentReady2.default)(_this, function () {
- _this._compile();
- });
+var AnimatorFactory = function () {
- _this._options = {};
- _this._boundOnClick = _this._onClick.bind(_this);
- return _this;
- }
+ /**
+ * @param {Object} opts
+ * @param {Object} opts.animators The dictionary for animator classes
+ * @param {Function} opts.baseClass The base class of animators
+ * @param {String} [opts.baseClassName] The name of the base class of animators
+ * @param {String} [opts.defaultAnimation] The default animation name
+ * @param {Object} [opts.defaultAnimationOptions] The default animation options
+ */
+ function AnimatorFactory(opts) {
+ _classCallCheck(this, AnimatorFactory);
- _createClass(BackButtonElement, [{
- key: '_updateIcon',
- value: function _updateIcon() {
- var icon = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _util2.default.findChild(this, '.back-button__icon');
+ this._animators = opts.animators;
+ this._baseClass = opts.baseClass;
+ this._baseClassName = opts.baseClassName || opts.baseClass.name;
+ this._animation = opts.defaultAnimation || 'default';
+ this._animationOptions = opts.defaultAnimationOptions || {};
- icon.innerHTML = _autostyle2.default.getPlatform(this) === 'android' || _util2.default.hasModifier(this, 'material') ? _mdBackButtonIcon2.default : _iosBackButtonIcon2.default;
+ if (!this._animators[this._animation]) {
+ throw new Error('No such animation: ' + this._animation);
}
- }, {
- key: '_compile',
- value: function _compile() {
- _autostyle2.default.prepare(this);
-
- this.classList.add(defaultClassName);
-
- if (!_util2.default.findChild(this, '.back-button__label')) {
- var label = _util2.default.create('span.back-button__label');
-
- while (this.childNodes[0]) {
- label.appendChild(this.childNodes[0]);
- }
- this.appendChild(label);
- }
+ }
- if (!_util2.default.findChild(this, '.back-button__icon')) {
- var icon = _util2.default.create('span.back-button__icon');
- this._updateIcon(icon);
+ /**
+ * @param {String} jsonString
+ * @return {Object/null}
+ */
- this.insertBefore(icon, this.children[0]);
- }
- _util2.default.updateRipple(this, undefined, { center: '', 'size': 'contain', 'background': 'transparent' });
+ _createClass(AnimatorFactory, [{
+ key: 'setAnimationOptions',
- _modifierUtil2.default.initModifier(this, scheme);
- }
/**
- * @property options
- * @type {Object}
- * @description
- * [en]Options object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
+ * @param {Object} options
*/
+ value: function setAnimationOptions(options) {
+ this._animationOptions = options;
+ }
/**
- * @property options.animation
- * @type {String}
- * @description
- * [en]Animation name. Available animations are "slide", "lift", "fade" and "none".
- * These are platform based animations. For fixed animations, add "-ios" or "-md"
- * suffix to the animation name. E.g. "lift-ios", "lift-md". Defaults values are "slide-ios" and "fade-md".
- * [/en]
- * [ja][/ja]
+ * @param {Object} options
+ * @param {String} [options.animation] The animation name
+ * @param {Object} [options.animationOptions] The animation options
+ * @param {Object} defaultAnimator The default animator instance
+ * @return {Object} An animator instance
*/
- /**
- * @property options.animationOptions
- * @type {String}
- * @description
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
- */
+ }, {
+ key: 'newAnimator',
+ value: function newAnimator() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var defaultAnimator = arguments[1];
- /**
- * @property options.callback
- * @type {String}
- * @description
- * [en]Function that is called when the transition has ended.[/en]
- * [ja]このメソッドによる画面遷移が終了した際に呼び出される関数オブジェクトを指定します。[/ja]
- */
- /**
- * @property options.refresh
- * @description
- * [en]The previous page will be refreshed (destroyed and created again) before popPage action.[/en]
- * [ja]popPageする前に、前にあるページを生成しなおして更新する場合にtrueを指定します。[/ja]
- */
+ var animator = null;
- }, {
- key: '_onClick',
+ if (options.animation instanceof this._baseClass) {
+ return options.animation;
+ }
+ var Animator = null;
- /**
- * @property onClick
- * @type {Function}
- * @description
- * [en]Used to override the default back button behavior.[/en]
- * [ja][/ja]
- */
- value: function _onClick() {
- if (this.onClick) {
- this.onClick.apply(this);
+ if (typeof options.animation === 'string') {
+ Animator = this._animators[options.animation];
+ }
+
+ if (!Animator && defaultAnimator) {
+ animator = defaultAnimator;
} else {
- var navigator = _util2.default.findParent(this, 'ons-navigator');
- if (navigator) {
- navigator.popPage(this.options);
+ Animator = Animator || this._animators[this._animation];
+
+ var animationOpts = _util2.default.extend({}, this._animationOptions, options.animationOptions || {}, _internal2.default.config.animationsDisabled ? { duration: 0, delay: 0 } : {});
+
+ animator = new Animator(animationOpts);
+
+ if (typeof animator === 'function') {
+ animator = new animator(animationOpts); // eslint-disable-line new-cap
}
}
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- this.addEventListener('click', this._boundOnClick, false);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- if (!this.classList.contains(defaultClassName)) {
- this.className = defaultClassName + ' ' + current;
- }
- break;
- case 'modifier':
- {
- _modifierUtil2.default.onModifierChanged(last, current, this, scheme) && this._updateIcon();
- break;
- }
+ if (!(animator instanceof this._baseClass)) {
+ throw new Error('"animator" is not an instance of ' + this._baseClassName + '.');
}
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this.removeEventListener('click', this._boundOnClick, false);
- }
- }, {
- key: 'show',
- value: function show() {
- this.style.display = 'inline-block';
- }
- }, {
- key: 'hide',
- value: function hide() {
- this.style.display = 'none';
- }
- }, {
- key: 'options',
- get: function get() {
- return this._options;
- },
- set: function set(object) {
- this._options = object;
+
+ return animator;
}
}], [{
- key: 'observedAttributes',
- get: function get() {
- return ['modifier', 'class'];
+ key: 'parseAnimationOptionsString',
+ value: function parseAnimationOptionsString(jsonString) {
+ try {
+ if (typeof jsonString === 'string') {
+ var result = _util2.default.animationOptionsParse(jsonString);
+ if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) === 'object' && result !== null) {
+ return result;
+ } else {
+ console.error('"animation-options" attribute must be a JSON object string: ' + jsonString);
+ }
+ }
+ return {};
+ } catch (e) {
+ console.error('"animation-options" attribute must be a JSON object string: ' + jsonString);
+ return {};
+ }
}
}]);
- return BackButtonElement;
-}(_baseElement2.default);
+ return AnimatorFactory;
+}();
-exports.default = BackButtonElement;
+exports.default = AnimatorFactory;
+module.exports = exports['default'];
+
+/***/ }),
+/* 9 */
+/***/ (function(module, exports, __webpack_require__) {
+"use strict";
-customElements.define('ons-back-button', BackButtonElement);
-module.exports = exports['default'];
+
+var store = __webpack_require__(73)('wks'),
+ uid = __webpack_require__(38),
+ _Symbol = __webpack_require__(12).Symbol,
+ USE_SYMBOL = typeof _Symbol == 'function';
+
+var $exports = module.exports = function (name) {
+ return store[name] || (store[name] = USE_SYMBOL && _Symbol[name] || (USE_SYMBOL ? _Symbol : uid)('Symbol.' + name));
+};
+
+$exports.store = store;
/***/ }),
-/* 84 */
+/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -59264,328 +72325,489 @@ Object.defineProperty(exports, "__esModule", {
value: true
});
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
+ 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.
+
+ */
var _util = __webpack_require__(0);
var _util2 = _interopRequireDefault(_util);
-var _autostyle = __webpack_require__(4);
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-var _autostyle2 = _interopRequireDefault(_autostyle);
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-var _modifierUtil = __webpack_require__(3);
+var BaseAnimator = function () {
-var _modifierUtil2 = _interopRequireDefault(_modifierUtil);
+ /**
+ * @param {Object} options
+ * @param {String} options.timing
+ * @param {Number} options.duration
+ * @param {Number} options.delay
+ */
+ function BaseAnimator() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-var _baseElement = __webpack_require__(1);
+ _classCallCheck(this, BaseAnimator);
-var _baseElement2 = _interopRequireDefault(_baseElement);
+ this.timing = options.timing || 'linear';
+ this.duration = options.duration || 0;
+ this.delay = options.delay || 0;
+ }
+
+ _createClass(BaseAnimator, null, [{
+ key: 'extend',
+ value: function extend() {
+ var properties = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ var extendedAnimator = this;
+ var newAnimator = function newAnimator() {
+ extendedAnimator.apply(this, arguments);
+ _util2.default.extend(this, properties);
+ };
+
+ newAnimator.prototype = this.prototype;
+ return newAnimator;
+ }
+ }]);
+
+ return BaseAnimator;
+}();
+
+exports.default = BaseAnimator;
+module.exports = exports['default'];
+
+/***/ }),
+/* 11 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Utilities = __webpack_require__(15);
+
+var Utilities = _interopRequireWildcard(_Utilities);
+
+var _CustomElementState = __webpack_require__(42);
+
+var _CustomElementState2 = _interopRequireDefault(_CustomElementState);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+var CustomElementInternals = function () {
+ function CustomElementInternals() {
+ _classCallCheck(this, CustomElementInternals);
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
- 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.
-
- */
+ /** @type {!Map
} */
+ this._localNameToDefinition = new Map();
-var defaultClassName = 'bottom-bar';
-var scheme = { '': 'bottom-bar--*' };
+ /** @type {!Map} */
+ this._constructorToDefinition = new Map();
-/**
- * @element ons-bottom-toolbar
- * @category page
- * @description
- * [en]Toolbar component that is positioned at the bottom of the page.[/en]
- * [ja]ページ下部に配置されるツールバー用コンポーネントです。[/ja]
- * @modifier transparent
- * [en]Make the toolbar transparent.[/en]
- * [ja]ツールバーの背景を透明にして表示します。[/ja]
- * @seealso ons-toolbar [en]ons-toolbar component[/en][ja]ons-toolbarコンポーネント[/ja]
- * @example
- *
- * Content
- *
- */
+ /** @type {!Array} */
+ this._patches = [];
-var BottomToolbarElement = function (_BaseElement) {
- _inherits(BottomToolbarElement, _BaseElement);
+ /** @type {boolean} */
+ this._hasPatches = false;
+ }
/**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the toolbar.[/en]
- * [ja]ツールバーの見た目の表現を指定します。[/ja]
+ * @param {string} localName
+ * @param {!CustomElementDefinition} definition
*/
- function BottomToolbarElement() {
- _classCallCheck(this, BottomToolbarElement);
- var _this = _possibleConstructorReturn(this, (BottomToolbarElement.__proto__ || Object.getPrototypeOf(BottomToolbarElement)).call(this));
+ _createClass(CustomElementInternals, [{
+ key: 'setDefinition',
+ value: function setDefinition(localName, definition) {
+ this._localNameToDefinition.set(localName, definition);
+ this._constructorToDefinition.set(definition.constructor, definition);
+ }
- _this.classList.add(defaultClassName);
- _modifierUtil2.default.initModifier(_this, scheme);
- return _this;
- }
+ /**
+ * @param {string} localName
+ * @return {!CustomElementDefinition|undefined}
+ */
- _createClass(BottomToolbarElement, [{
- key: 'connectedCallback',
- value: function connectedCallback() {
- if (_util2.default.match(this.parentNode, 'ons-page')) {
- this.parentNode.classList.add('page-with-bottom-toolbar');
- }
- }
}, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- if (!this.classList.contains(defaultClassName)) {
- this.className = defaultClassName + ' ' + current;
- }
- break;
- case 'modifier':
- _modifierUtil2.default.onModifierChanged(last, current, this, scheme);
- break;
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get() {
- return ['modifier', 'class'];
+ key: 'localNameToDefinition',
+ value: function localNameToDefinition(localName) {
+ return this._localNameToDefinition.get(localName);
}
- }]);
- return BottomToolbarElement;
-}(_baseElement2.default);
+ /**
+ * @param {!Function} constructor
+ * @return {!CustomElementDefinition|undefined}
+ */
-exports.default = BottomToolbarElement;
+ }, {
+ key: 'constructorToDefinition',
+ value: function constructorToDefinition(constructor) {
+ return this._constructorToDefinition.get(constructor);
+ }
+ /**
+ * @param {!function(!Node)} listener
+ */
-customElements.define('ons-bottom-toolbar', BottomToolbarElement);
-module.exports = exports['default'];
+ }, {
+ key: 'addPatch',
+ value: function addPatch(listener) {
+ this._hasPatches = true;
+ this._patches.push(listener);
+ }
-/***/ }),
-/* 85 */
-/***/ (function(module, exports, __webpack_require__) {
+ /**
+ * @param {!Node} node
+ */
-"use strict";
+ }, {
+ key: 'patchTree',
+ value: function patchTree(node) {
+ var _this = this;
+ if (!this._hasPatches) return;
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
+ Utilities.walkDeepDescendantElements(node, function (element) {
+ return _this.patch(element);
+ });
+ }
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+ /**
+ * @param {!Node} node
+ */
-var _util = __webpack_require__(0);
+ }, {
+ key: 'patch',
+ value: function patch(node) {
+ if (!this._hasPatches) return;
-var _util2 = _interopRequireDefault(_util);
+ if (node.__CE_patched) return;
+ node.__CE_patched = true;
-var _autostyle = __webpack_require__(4);
+ for (var i = 0; i < this._patches.length; i++) {
+ this._patches[i](node);
+ }
+ }
-var _autostyle2 = _interopRequireDefault(_autostyle);
+ /**
+ * @param {!Node} root
+ */
-var _modifierUtil = __webpack_require__(3);
+ }, {
+ key: 'connectTree',
+ value: function connectTree(root) {
+ var elements = [];
-var _modifierUtil2 = _interopRequireDefault(_modifierUtil);
+ Utilities.walkDeepDescendantElements(root, function (element) {
+ return elements.push(element);
+ });
-var _baseElement = __webpack_require__(1);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ if (element.__CE_state === _CustomElementState2.default.custom) {
+ if (Utilities.isConnected(element)) {
+ this.connectedCallback(element);
+ }
+ } else {
+ this.upgradeElement(element);
+ }
+ }
+ }
-var _baseElement2 = _interopRequireDefault(_baseElement);
+ /**
+ * @param {!Node} root
+ */
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+ }, {
+ key: 'disconnectTree',
+ value: function disconnectTree(root) {
+ var elements = [];
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+ Utilities.walkDeepDescendantElements(root, function (element) {
+ return elements.push(element);
+ });
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ if (element.__CE_state === _CustomElementState2.default.custom) {
+ this.disconnectedCallback(element);
+ }
+ }
+ }
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
- 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.
-
- */
+ /**
+ * Upgrades all uncustomized custom elements at and below a root node for
+ * which there is a definition. When custom element reaction callbacks are
+ * assumed to be called synchronously (which, by the current DOM / HTML spec
+ * definitions, they are *not*), callbacks for both elements customized
+ * synchronously by the parser and elements being upgraded occur in the same
+ * relative order.
+ *
+ * NOTE: This function, when used to simulate the construction of a tree that
+ * is already created but not customized (i.e. by the parser), does *not*
+ * prevent the element from reading the 'final' (true) state of the tree. For
+ * example, the element, during truly synchronous parsing / construction would
+ * see that it contains no children as they have not yet been inserted.
+ * However, this function does not modify the tree, the element will
+ * (incorrectly) have children. Additionally, self-modification restrictions
+ * for custom element constructors imposed by the DOM spec are *not* enforced.
+ *
+ *
+ * The following nested list shows the steps extending down from the HTML
+ * spec's parsing section that cause elements to be synchronously created and
+ * upgraded:
+ *
+ * The "in body" insertion mode:
+ * https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
+ * - Switch on token:
+ * .. other cases ..
+ * -> Any other start tag
+ * - [Insert an HTML element](below) for the token.
+ *
+ * Insert an HTML element:
+ * https://html.spec.whatwg.org/multipage/syntax.html#insert-an-html-element
+ * - Insert a foreign element for the token in the HTML namespace:
+ * https://html.spec.whatwg.org/multipage/syntax.html#insert-a-foreign-element
+ * - Create an element for a token:
+ * https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token
+ * - Will execute script flag is true?
+ * - (Element queue pushed to the custom element reactions stack.)
+ * - Create an element:
+ * https://dom.spec.whatwg.org/#concept-create-element
+ * - Sync CE flag is true?
+ * - Constructor called.
+ * - Self-modification restrictions enforced.
+ * - Sync CE flag is false?
+ * - (Upgrade reaction enqueued.)
+ * - Attributes appended to element.
+ * (`attributeChangedCallback` reactions enqueued.)
+ * - Will execute script flag is true?
+ * - (Element queue popped from the custom element reactions stack.
+ * Reactions in the popped stack are invoked.)
+ * - (Element queue pushed to the custom element reactions stack.)
+ * - Insert the element:
+ * https://dom.spec.whatwg.org/#concept-node-insert
+ * - Shadow-including descendants are connected. During parsing
+ * construction, there are no shadow-*excluding* descendants.
+ * However, the constructor may have validly attached a shadow
+ * tree to itself and added descendants to that shadow tree.
+ * (`connectedCallback` reactions enqueued.)
+ * - (Element queue popped from the custom element reactions stack.
+ * Reactions in the popped stack are invoked.)
+ *
+ * @param {!Node} root
+ * @param {!Set=} visitedImports
+ */
-var scheme = { '': 'button--*' };
+ }, {
+ key: 'patchAndUpgradeTree',
+ value: function patchAndUpgradeTree(root) {
+ var _this2 = this;
-var defaultClassName = 'button';
+ var visitedImports = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
-/**
- * @element ons-button
- * @category form
- * @modifier outline
- * [en]Button with outline and transparent background[/en]
- * [ja]アウトラインを持ったボタンを表示します。[/ja]
- * @modifier light
- * [en]Button that doesn't stand out.[/en]
- * [ja]目立たないボタンを表示します。[/ja]
- * @modifier quiet
- * [en]Button with no outline and or background..[/en]
- * [ja]枠線や背景が無い文字だけのボタンを表示します。[/ja]
- * @modifier cta
- * [en]Button that really stands out.[/en]
- * [ja]目立つボタンを表示します。[/ja]
- * @modifier large
- * [en]Large button that covers the width of the screen.[/en]
- * [ja]横いっぱいに広がる大きなボタンを表示します。[/ja]
- * @modifier large--quiet
- * [en]Large quiet button.[/en]
- * [ja]横いっぱいに広がるquietボタンを表示します。[/ja]
- * @modifier large--cta
- * [en]Large call to action button.[/en]
- * [ja]横いっぱいに広がるctaボタンを表示します。[/ja]
- * @modifier material
- * [en]Material Design button[/en]
- * [ja]マテリアルデザインのボタン[/ja]
- * @modifier material--flat
- * [en]Material Design flat button[/en]
- * [ja]マテリアルデザインのフラットボタン[/ja]
- * @description
- * [en]
- * Button component. If you want to place a button in a toolbar, use `` or `` instead.
- *
- * Will automatically display as a Material Design button with a ripple effect on Android.
- * [/en]
- * [ja]ボタン用コンポーネント。ツールバーにボタンを設置する場合は、ons-toolbar-buttonもしくはons-back-buttonコンポーネントを使用します。[/ja]
- * @codepen hLayx
- * @tutorial vanilla/Reference/button
- * @guide using-modifier [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @guide cross-platform-styling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
- * @example
- *
- * Tap Me
- *
- */
+ var elements = [];
-var ButtonElement = function (_BaseElement) {
- _inherits(ButtonElement, _BaseElement);
+ var gatherElements = function gatherElements(element) {
+ if (element.localName === 'link' && element.getAttribute('rel') === 'import') {
+ // The HTML Imports polyfill sets a descendant element of the link to
+ // the `import` property, specifically this is *not* a Document.
+ var importNode = /** @type {?Node} */element.import;
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the button.[/en]
- * [ja]ボタンの表現を指定します。[/ja]
- */
+ if (importNode instanceof Node && importNode.readyState === 'complete') {
+ importNode.__CE_isImportDocument = true;
- /**
- * @attribute ripple
- * @description
- * [en]If this attribute is defined, the button will have a ripple effect.[/en]
- * [ja][/ja]
- */
+ // Connected links are associated with the registry.
+ importNode.__CE_hasRegistry = true;
+ } else {
+ // If this link's import root is not available, its contents can't be
+ // walked. Wait for 'load' and walk it when it's ready.
+ element.addEventListener('load', function () {
+ var importNode = /** @type {!Node} */element.import;
- /**
- * @attribute disabled
- * @description
- * [en]Specify if button should be disabled.[/en]
- * [ja]ボタンを無効化する場合は指定します。[/ja]
- */
+ if (importNode.__CE_documentLoadHandled) return;
+ importNode.__CE_documentLoadHandled = true;
- function ButtonElement() {
- _classCallCheck(this, ButtonElement);
+ importNode.__CE_isImportDocument = true;
- var _this = _possibleConstructorReturn(this, (ButtonElement.__proto__ || Object.getPrototypeOf(ButtonElement)).call(this));
+ // Connected links are associated with the registry.
+ importNode.__CE_hasRegistry = true;
- _this._compile();
- return _this;
- }
+ // Clone the `visitedImports` set that was populated sync during
+ // the `patchAndUpgradeTree` call that caused this 'load' handler to
+ // be added. Then, remove *this* link's import node so that we can
+ // walk that import again, even if it was partially walked later
+ // during the same `patchAndUpgradeTree` call.
+ var clonedVisitedImports = new Set(visitedImports);
+ visitedImports.delete(importNode);
- _createClass(ButtonElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- if (!this.classList.contains(defaultClassName)) {
- this.className = defaultClassName + ' ' + current;
+ _this2.patchAndUpgradeTree(importNode, visitedImports);
+ });
}
- break;
- case 'modifier':
- _modifierUtil2.default.onModifierChanged(last, current, this, scheme);
- break;
- case 'ripple':
- this._updateRipple();
+ } else {
+ elements.push(element);
+ }
+ };
+
+ // `walkDeepDescendantElements` populates (and internally checks against)
+ // `visitedImports` when traversing a loaded import.
+ Utilities.walkDeepDescendantElements(root, gatherElements, visitedImports);
+
+ if (this._hasPatches) {
+ for (var i = 0; i < elements.length; i++) {
+ this.patch(elements[i]);
+ }
+ }
+
+ for (var _i = 0; _i < elements.length; _i++) {
+ this.upgradeElement(elements[_i]);
}
}
/**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the button is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
+ * @param {!Element} element
*/
}, {
- key: '_compile',
- value: function _compile() {
- _autostyle2.default.prepare(this);
+ key: 'upgradeElement',
+ value: function upgradeElement(element) {
+ var currentState = element.__CE_state;
+ if (currentState !== undefined) return;
- this.classList.add(defaultClassName);
+ var definition = this.localNameToDefinition(element.localName);
+ if (!definition) return;
- this._updateRipple();
+ definition.constructionStack.push(element);
- _modifierUtil2.default.initModifier(this, scheme);
+ var constructor = definition.constructor;
+ try {
+ try {
+ var result = new constructor();
+ if (result !== element) {
+ throw new Error('The custom element constructor did not produce the element being upgraded.');
+ }
+ } finally {
+ definition.constructionStack.pop();
+ }
+ } catch (e) {
+ element.__CE_state = _CustomElementState2.default.failed;
+ throw e;
+ }
+
+ element.__CE_state = _CustomElementState2.default.custom;
+ element.__CE_definition = definition;
+
+ if (definition.attributeChangedCallback) {
+ var observedAttributes = definition.observedAttributes;
+ for (var i = 0; i < observedAttributes.length; i++) {
+ var name = observedAttributes[i];
+ var value = element.getAttribute(name);
+ if (value !== null) {
+ this.attributeChangedCallback(element, name, null, value, null);
+ }
+ }
+ }
+
+ if (Utilities.isConnected(element)) {
+ this.connectedCallback(element);
+ }
}
+
+ /**
+ * @param {!Element} element
+ */
+
}, {
- key: '_updateRipple',
- value: function _updateRipple() {
- _util2.default.updateRipple(this);
+ key: 'connectedCallback',
+ value: function connectedCallback(element) {
+ var definition = element.__CE_definition;
+ if (definition.connectedCallback) {
+ definition.connectedCallback.call(element);
+ }
+
+ element.__CE_isConnectedCallbackCalled = true;
}
+
+ /**
+ * @param {!Element} element
+ */
+
}, {
- key: 'disabled',
- set: function set(value) {
- return _util2.default.toggleAttribute(this, 'disabled', value);
- },
- get: function get() {
- return this.hasAttribute('disabled');
+ key: 'disconnectedCallback',
+ value: function disconnectedCallback(element) {
+ if (!element.__CE_isConnectedCallbackCalled) {
+ this.connectedCallback(element);
+ }
+
+ var definition = element.__CE_definition;
+ if (definition.disconnectedCallback) {
+ definition.disconnectedCallback.call(element);
+ }
+
+ element.__CE_isConnectedCallbackCalled = undefined;
}
- }], [{
- key: 'observedAttributes',
- get: function get() {
- return ['modifier', 'ripple', 'class'];
+
+ /**
+ * @param {!Element} element
+ * @param {string} name
+ * @param {?string} oldValue
+ * @param {?string} newValue
+ * @param {?string} namespace
+ */
+
+ }, {
+ key: 'attributeChangedCallback',
+ value: function attributeChangedCallback(element, name, oldValue, newValue, namespace) {
+ var definition = element.__CE_definition;
+ if (definition.attributeChangedCallback && definition.observedAttributes.indexOf(name) > -1) {
+ definition.attributeChangedCallback.call(element, name, oldValue, newValue, namespace);
+ }
}
}]);
- return ButtonElement;
-}(_baseElement2.default);
+ return CustomElementInternals;
+}();
-exports.default = ButtonElement;
+exports.default = CustomElementInternals;
+module.exports = exports['default'];
+/***/ }),
+/* 12 */
+/***/ (function(module, exports, __webpack_require__) {
-customElements.define('ons-button', ButtonElement);
-module.exports = exports['default'];
+"use strict";
+
+
+// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
+var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
+if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
/***/ }),
-/* 86 */
+/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -59597,21 +72819,13 @@ Object.defineProperty(exports, "__esModule", {
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-var _autostyle = __webpack_require__(4);
-
-var _autostyle2 = _interopRequireDefault(_autostyle);
-
-var _modifierUtil = __webpack_require__(3);
-
-var _modifierUtil2 = _interopRequireDefault(_modifierUtil);
-
-var _baseElement = __webpack_require__(1);
+var _util = __webpack_require__(0);
-var _baseElement2 = _interopRequireDefault(_baseElement);
+var _util2 = _interopRequireDefault(_util);
-var _contentReady = __webpack_require__(2);
+var _baseAnimator = __webpack_require__(10);
-var _contentReady2 = _interopRequireDefault(_contentReady);
+var _baseAnimator2 = _interopRequireDefault(_baseAnimator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -59636,2200 +72850,2273 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
*/
-var defaultClassName = 'card';
-var scheme = {
- '': 'card--*',
- '.card__title': 'card--*__title',
- '.card__content': 'card--*__content'
-};
-
-/**
- * @element ons-card
- * @category visual
- * @modifier material
- * [en]A card with material design.[/en]
- * [ja]リストの上下のボーダーが無いリストを表示します。[/ja]
- * @description
- * [en]
- * Component to create a card that displays some information.
- *
- * The card may be composed by divs with specially prepared classes `title` and/or `content`. You can also add your own content as you please.[/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/card
- * @example
- *
- * Some content
- *
- */
-
-var CardElement = function (_BaseElement) {
- _inherits(CardElement, _BaseElement);
+var NavigatorTransitionAnimator = function (_BaseAnimator) {
+ _inherits(NavigatorTransitionAnimator, _BaseAnimator);
/**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the card.[/en]
- * [ja]リストの表現を指定します。[/ja]
+ * @param {Object} options
+ * @param {String} options.timing
+ * @param {Number} options.duration
+ * @param {Number} options.delay
*/
+ function NavigatorTransitionAnimator(options) {
+ _classCallCheck(this, NavigatorTransitionAnimator);
- function CardElement() {
- _classCallCheck(this, CardElement);
+ options = _util2.default.extend({
+ timing: 'linear',
+ duration: '0.4',
+ delay: '0'
+ }, options || {});
- var _this = _possibleConstructorReturn(this, (CardElement.__proto__ || Object.getPrototypeOf(CardElement)).call(this));
-
- (0, _contentReady2.default)(_this, function () {
- _this._compile();
- });
- return _this;
+ return _possibleConstructorReturn(this, (NavigatorTransitionAnimator.__proto__ || Object.getPrototypeOf(NavigatorTransitionAnimator)).call(this, options));
}
- _createClass(CardElement, [{
- key: '_compile',
- value: function _compile() {
- var title = void 0,
- content = void 0;
-
- for (var i = 0; i < this.children.length; i++) {
- var el = this.children[i];
-
- if (el.classList.contains('title')) {
- el.classList.add('card__title');
- title = el;
- } else if (el.classList.contains('content')) {
- el.classList.add('card__content');
- content = el;
- }
- }
-
- _autostyle2.default.prepare(this);
- this.classList.add(defaultClassName);
- _modifierUtil2.default.initModifier(this, scheme);
+ _createClass(NavigatorTransitionAnimator, [{
+ key: 'push',
+ value: function push(enterPage, leavePage, callback) {
+ callback();
}
}, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- if (!this.classList.contains(defaultClassName)) {
- this.className = defaultClassName + ' ' + current;
- }
- break;
- case 'modifier':
- _modifierUtil2.default.onModifierChanged(last, current, this, scheme);
- break;
- }
+ key: 'pop',
+ value: function pop(enterPage, leavePage, callback) {
+ callback();
}
- }], [{
- key: 'observedAttributes',
- get: function get() {
- return ['modifier', 'class'];
+ }, {
+ key: 'block',
+ value: function block(page) {
+ var blocker = _util2.default.createElement('\n \n ');
+ page.parentNode.appendChild(blocker);
+ return function () {
+ return blocker.remove();
+ };
}
}]);
- return CardElement;
-}(_baseElement2.default);
-
-exports.default = CardElement;
-
+ return NavigatorTransitionAnimator;
+}(_baseAnimator2.default);
-customElements.define('ons-card', CardElement);
+exports.default = NavigatorTransitionAnimator;
module.exports = exports['default'];
/***/ }),
-/* 87 */
+/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
+/*
+ * Gesture detector library that forked from github.com/EightMedia/hammer.js.
+ */
+
Object.defineProperty(exports, "__esModule", {
value: true
});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _util = __webpack_require__(0);
-
-var _util2 = _interopRequireDefault(_util);
-
-var _baseElement = __webpack_require__(1);
-
-var _baseElement2 = _interopRequireDefault(_baseElement);
-
-var _modifierUtil = __webpack_require__(3);
-
-var _modifierUtil2 = _interopRequireDefault(_modifierUtil);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
- 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.
-
- */
-
-var scheme = { '': 'carousel-item--*' };
+var Event, Utils, Detection, PointerEvent;
/**
- * @element ons-carousel-item
- * @category carousel
+ * @object ons.GestureDetector
+ * @category gesture
* @description
- * [en]
- * Carousel item component. Used as a child of the `` element.
- * [/en]
- * [ja][/ja]
- * @codepen xbbzOQ
- * @tutorial vanilla/Reference/carousel
- * @seealso ons-carousel
- * [en]`` components[/en]
- * [ja]コンポーネント[/ja]
- * @example
- *
- *
- * ...
- *
- *
- * ...
- *
- *
+ * [en]Utility class for gesture detection.[/en]
+ * [ja]ジェスチャを検知するためのユーティリティクラスです。[/ja]
*/
-var CarouselItemElement = function (_BaseElement) {
- _inherits(CarouselItemElement, _BaseElement);
-
- function CarouselItemElement() {
- _classCallCheck(this, CarouselItemElement);
-
- var _this = _possibleConstructorReturn(this, (CarouselItemElement.__proto__ || Object.getPrototypeOf(CarouselItemElement)).call(this));
+/**
+ * @method constructor
+ * @signature constructor(element[, options])
+ * @description
+ * [en]Create a new GestureDetector instance.[/en]
+ * [ja]GestureDetectorのインスタンスを生成します。[/ja]
+ * @param {Element} element
+ * [en]Name of the event.[/en]
+ * [ja]ジェスチャを検知するDOM要素を指定します。[/ja]
+ * @param {Object} [options]
+ * [en]Options object.[/en]
+ * [ja]オプションを指定します。[/ja]
+ * @return {ons.GestureDetector.Instance}
+ */
+var GestureDetector = function GestureDetector(element, options) {
+ return new GestureDetector.Instance(element, options || {});
+};
- _this.style.width = '100%';
- _modifierUtil2.default.initModifier(_this, scheme);
- return _this;
+/**
+ * default settings.
+ * more settings are defined per gesture at `/gestures`. Each gesture can be disabled/enabled
+ * by setting it's name (like `swipe`) to false.
+ * You can set the defaults for all instances by changing this object before creating an instance.
+ * @example
+ * ````
+ * GestureDetector.defaults.drag = false;
+ * GestureDetector.defaults.behavior.touchAction = 'pan-y';
+ * delete GestureDetector.defaults.behavior.userSelect;
+ * ````
+ * @property defaults
+ * @type {Object}
+ */
+GestureDetector.defaults = {
+ behavior: {
+ // userSelect: 'none', // Also disables selection in `input` children
+ touchAction: 'pan-y',
+ touchCallout: 'none',
+ contentZooming: 'none',
+ userDrag: 'none',
+ tapHighlightColor: 'rgba(0,0,0,0)'
}
+};
- _createClass(CarouselItemElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'modifier') {
- return _modifierUtil2.default.onModifierChanged(last, current, this, scheme);
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get() {
- return ['modifier'];
- }
- }]);
-
- return CarouselItemElement;
-}(_baseElement2.default);
-
-exports.default = CarouselItemElement;
-
-
-customElements.define('ons-carousel-item', CarouselItemElement);
-module.exports = exports['default'];
-
-/***/ }),
-/* 88 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+/**
+ * GestureDetector document where the base events are added at
+ * @property DOCUMENT
+ * @type {HTMLElement}
+ * @default window.document
+ */
+GestureDetector.DOCUMENT = document;
-var _util = __webpack_require__(0);
+/**
+ * detect support for pointer events
+ * @property HAS_POINTEREVENTS
+ * @type {Boolean}
+ */
+GestureDetector.HAS_POINTEREVENTS = navigator.pointerEnabled || navigator.msPointerEnabled;
-var _util2 = _interopRequireDefault(_util);
+/**
+ * detect support for touch events
+ * @property HAS_TOUCHEVENTS
+ * @type {Boolean}
+ */
+GestureDetector.HAS_TOUCHEVENTS = 'ontouchstart' in window;
-var _baseElement = __webpack_require__(1);
+/**
+ * detect mobile browsers
+ * @property IS_MOBILE
+ * @type {Boolean}
+ */
+GestureDetector.IS_MOBILE = /mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent);
-var _baseElement2 = _interopRequireDefault(_baseElement);
+/**
+ * detect if we want to support mouseevents at all
+ * @property NO_MOUSEEVENTS
+ * @type {Boolean}
+ */
+GestureDetector.NO_MOUSEEVENTS = GestureDetector.HAS_TOUCHEVENTS && GestureDetector.IS_MOBILE || GestureDetector.HAS_POINTEREVENTS;
-var _gestureDetector = __webpack_require__(14);
+/**
+ * interval in which GestureDetector recalculates current velocity/direction/angle in ms
+ * @property CALCULATE_INTERVAL
+ * @type {Number}
+ * @default 25
+ */
+GestureDetector.CALCULATE_INTERVAL = 25;
-var _gestureDetector2 = _interopRequireDefault(_gestureDetector);
+/**
+ * eventtypes per touchevent (start, move, end) are filled by `Event.determineEventTypes` on `setup`
+ * the object contains the DOM event names per type (`EVENT_START`, `EVENT_MOVE`, `EVENT_END`)
+ * @property EVENT_TYPES
+ * @private
+ * @writeOnce
+ * @type {Object}
+ */
+var EVENT_TYPES = {};
-var _doorlock = __webpack_require__(32);
+/**
+ * direction strings, for safe comparisons
+ * @property DIRECTION_DOWN|LEFT|UP|RIGHT
+ * @final
+ * @type {String}
+ * @default 'down' 'left' 'up' 'right'
+ */
+var DIRECTION_DOWN = GestureDetector.DIRECTION_DOWN = 'down';
+var DIRECTION_LEFT = GestureDetector.DIRECTION_LEFT = 'left';
+var DIRECTION_UP = GestureDetector.DIRECTION_UP = 'up';
+var DIRECTION_RIGHT = GestureDetector.DIRECTION_RIGHT = 'right';
-var _doorlock2 = _interopRequireDefault(_doorlock);
+/**
+ * pointertype strings, for safe comparisons
+ * @property POINTER_MOUSE|TOUCH|PEN
+ * @final
+ * @type {String}
+ * @default 'mouse' 'touch' 'pen'
+ */
+var POINTER_MOUSE = GestureDetector.POINTER_MOUSE = 'mouse';
+var POINTER_TOUCH = GestureDetector.POINTER_TOUCH = 'touch';
+var POINTER_PEN = GestureDetector.POINTER_PEN = 'pen';
-var _animit = __webpack_require__(5);
+/**
+ * eventtypes
+ * @property EVENT_START|MOVE|END|RELEASE|TOUCH
+ * @final
+ * @type {String}
+ * @default 'start' 'change' 'move' 'end' 'release' 'touch'
+ */
+var EVENT_START = GestureDetector.EVENT_START = 'start';
+var EVENT_MOVE = GestureDetector.EVENT_MOVE = 'move';
+var EVENT_END = GestureDetector.EVENT_END = 'end';
+var EVENT_RELEASE = GestureDetector.EVENT_RELEASE = 'release';
+var EVENT_TOUCH = GestureDetector.EVENT_TOUCH = 'touch';
-var _animit2 = _interopRequireDefault(_animit);
+/**
+ * if the window events are set...
+ * @property READY
+ * @writeOnce
+ * @type {Boolean}
+ * @default false
+ */
+GestureDetector.READY = false;
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+/**
+ * plugins namespace
+ * @property plugins
+ * @type {Object}
+ */
+GestureDetector.plugins = GestureDetector.plugins || {};
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+/**
+ * gestures namespace
+ * see `/gestures` for the definitions
+ * @property gestures
+ * @type {Object}
+ */
+GestureDetector.gestures = GestureDetector.gestures || {};
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+/**
+ * setup events to detect gestures on the document
+ * this function is called when creating an new instance
+ * @private
+ */
+function setup() {
+ if (GestureDetector.READY) {
+ return;
+ }
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
- 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.
-
- */
+ // find what eventtypes we add listeners to
+ Event.determineEventTypes();
-var VerticalModeTrait = {
+ // Register all gestures inside GestureDetector.gestures
+ Utils.each(GestureDetector.gestures, function (gesture) {
+ Detection.register(gesture);
+ });
- _getScrollDelta: function _getScrollDelta(event) {
- return event.gesture.deltaY;
- },
+ // Add touch events on the document
+ Event.onTouch(GestureDetector.DOCUMENT, EVENT_MOVE, Detection.detect);
+ Event.onTouch(GestureDetector.DOCUMENT, EVENT_END, Detection.detect);
- _getScrollVelocity: function _getScrollVelocity(event) {
- return event.gesture.velocityY;
- },
+ // GestureDetector is ready...!
+ GestureDetector.READY = true;
+}
- _getElementSize: function _getElementSize() {
- if (!this._currentElementSize) {
- var styling = window.getComputedStyle(this, null);
- this._currentElementSize = this.getBoundingClientRect().height - parseInt(styling.getPropertyValue('border-top-width')) - parseInt(styling.getPropertyValue('border-bottom-width'));
+/**
+ * @module GestureDetector
+ *
+ * @class Utils
+ * @static
+ */
+Utils = GestureDetector.utils = {
+ /**
+ * extend method, could also be used for cloning when `dest` is an empty object.
+ * changes the dest object
+ * @param {Object} dest
+ * @param {Object} src
+ * @param {Boolean} [merge=false] do a merge
+ * @return {Object} dest
+ */
+ extend: function extend(dest, src, merge) {
+ for (var key in src) {
+ if (src.hasOwnProperty(key) && (dest[key] === undefined || !merge)) {
+ dest[key] = src[key];
+ }
}
-
- return this._currentElementSize;
- },
-
- _generateScrollTransform: function _generateScrollTransform(scroll) {
- return 'translate3d(0px, ' + -scroll + 'px, 0px)';
+ return dest;
},
- _updateDimensionData: function _updateDimensionData() {
- this._style = window.getComputedStyle(this);
- this._dimensions = this.getBoundingClientRect();
+ /**
+ * simple addEventListener wrapper
+ * @param {HTMLElement} element
+ * @param {String} type
+ * @param {Function} handler
+ */
+ on: function on(element, type, handler) {
+ element.addEventListener(type, handler, false);
},
- _updateOffset: function _updateOffset() {
- if (this.centered) {
- var height = (this._dimensions.height || 0) - parseInt(this._style.paddingTop, 10) - parseInt(this._style.paddingBottom, 10);
- this._offset = -(height - this._getCarouselItemSize()) / 2;
- }
+ /**
+ * simple removeEventListener wrapper
+ * @param {HTMLElement} element
+ * @param {String} type
+ * @param {Function} handler
+ */
+ off: function off(element, type, handler) {
+ element.removeEventListener(type, handler, false);
},
- _layoutCarouselItems: function _layoutCarouselItems() {
- var children = this._getCarouselItemElements();
-
- var sizeAttr = this._getCarouselItemSizeAttr();
- var sizeInfo = this._decomposeSizeString(sizeAttr);
+ /**
+ * forEach over arrays and objects
+ * @param {Object|Array} obj
+ * @param {Function} iterator
+ * @param {any} iterator.item
+ * @param {Number} iterator.index
+ * @param {Object|Array} iterator.obj the source object
+ * @param {Object} context value to use as `this` in the iterator
+ */
+ each: function each(obj, iterator, context) {
+ var i, len;
- for (var i = 0; i < children.length; i++) {
- children[i].style.position = 'absolute';
- children[i].style.height = sizeAttr;
- children[i].style.visibility = 'visible';
- children[i].style.top = i * sizeInfo.number + sizeInfo.unit;
+ // native forEach on arrays
+ if ('forEach' in obj) {
+ obj.forEach(iterator, context);
+ // arrays
+ } else if (obj.length !== undefined) {
+ for (i = 0, len = obj.length; i < len; i++) {
+ if (iterator.call(context, obj[i], i, obj) === false) {
+ return;
+ }
+ }
+ // objects
+ } else {
+ for (i in obj) {
+ if (obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj) === false) {
+ return;
+ }
+ }
}
},
- _setup: function _setup() {
- this._updateDimensionData();
- this._updateOffset();
- this._layoutCarouselItems();
- }
-};
-
-var HorizontalModeTrait = {
-
- _getScrollDelta: function _getScrollDelta(event) {
- return event.gesture.deltaX;
- },
-
- _getScrollVelocity: function _getScrollVelocity(event) {
- return event.gesture.velocityX;
+ /**
+ * find if a string contains the string using indexOf
+ * @param {String} src
+ * @param {String} find
+ * @return {Boolean} found
+ */
+ inStr: function inStr(src, find) {
+ return src.indexOf(find) > -1;
},
- _getElementSize: function _getElementSize() {
- if (!this._currentElementSize) {
- var styling = window.getComputedStyle(this, null);
- this._currentElementSize = this.getBoundingClientRect().width - parseInt(styling.getPropertyValue('border-right-width')) - parseInt(styling.getPropertyValue('border-left-width'));
+ /**
+ * find if a array contains the object using indexOf or a simple polyfill
+ * @param {String} src
+ * @param {String} find
+ * @return {Boolean|Number} false when not found, or the index
+ */
+ inArray: function inArray(src, find) {
+ if (src.indexOf) {
+ var index = src.indexOf(find);
+ return index === -1 ? false : index;
+ } else {
+ for (var i = 0, len = src.length; i < len; i++) {
+ if (src[i] === find) {
+ return i;
+ }
+ }
+ return false;
}
-
- return this._currentElementSize;
- },
-
- _generateScrollTransform: function _generateScrollTransform(scroll) {
- return 'translate3d(' + -scroll + 'px, 0px, 0px)';
},
- _updateDimensionData: function _updateDimensionData() {
- this._style = window.getComputedStyle(this);
- this._dimensions = this.getBoundingClientRect();
+ /**
+ * convert an array-like object (`arguments`, `touchlist`) to an array
+ * @param {Object} obj
+ * @return {Array}
+ */
+ toArray: function toArray(obj) {
+ return Array.prototype.slice.call(obj, 0);
},
- _updateOffset: function _updateOffset() {
- if (this.centered) {
- var width = (this._dimensions.width || 0) - parseInt(this._style.paddingLeft, 10) - parseInt(this._style.paddingRight, 10);
- this._offset = -(width - this._getCarouselItemSize()) / 2;
+ /**
+ * find if a node is in the given parent
+ * @param {HTMLElement} node
+ * @param {HTMLElement} parent
+ * @return {Boolean} found
+ */
+ hasParent: function hasParent(node, parent) {
+ while (node) {
+ if (node == parent) {
+ return true;
+ }
+ node = node.parentNode;
}
+ return false;
},
- _layoutCarouselItems: function _layoutCarouselItems() {
- var children = this._getCarouselItemElements();
-
- var sizeAttr = this._getCarouselItemSizeAttr();
- var sizeInfo = this._decomposeSizeString(sizeAttr);
+ /**
+ * get the center of all the touches
+ * @param {Array} touches
+ * @return {Object} center contains `pageX`, `pageY`, `clientX` and `clientY` properties
+ */
+ getCenter: function getCenter(touches) {
+ var pageX = [],
+ pageY = [],
+ clientX = [],
+ clientY = [],
+ min = Math.min,
+ max = Math.max;
- for (var i = 0; i < children.length; i++) {
- children[i].style.position = 'absolute';
- children[i].style.width = sizeAttr;
- children[i].style.visibility = 'visible';
- children[i].style.left = i * sizeInfo.number + sizeInfo.unit;
+ // no need to loop when only one touch
+ if (touches.length === 1) {
+ return {
+ pageX: touches[0].pageX,
+ pageY: touches[0].pageY,
+ clientX: touches[0].clientX,
+ clientY: touches[0].clientY
+ };
}
- },
-
- _setup: function _setup() {
- this._updateDimensionData();
- this._updateOffset();
- this._layoutCarouselItems();
- }
-};
-/**
- * @element ons-carousel
- * @category carousel
- * @description
- * [en]
- * Carousel component. A carousel can be used to display several items in the same space.
- *
- * The component supports displaying content both horizontally and vertically. The user can scroll through the items by dragging and it can also be controller programmatically.
- * [/en]
- * [ja][/ja]
- * @codepen xbbzOQ
- * @tutorial vanilla/Reference/carousel
- * @seealso ons-carousel-item
- * [en]`` component[/en]
- * [ja]ons-carousel-itemコンポーネント[/ja]
- * @example
- *
- *
- * ...
- *
- *
- * ...
- *
- *
- */
+ Utils.each(touches, function (touch) {
+ pageX.push(touch.pageX);
+ pageY.push(touch.pageY);
+ clientX.push(touch.clientX);
+ clientY.push(touch.clientY);
+ });
-var CarouselElement = function (_BaseElement) {
- _inherits(CarouselElement, _BaseElement);
+ return {
+ pageX: (min.apply(Math, pageX) + max.apply(Math, pageX)) / 2,
+ pageY: (min.apply(Math, pageY) + max.apply(Math, pageY)) / 2,
+ clientX: (min.apply(Math, clientX) + max.apply(Math, clientX)) / 2,
+ clientY: (min.apply(Math, clientY) + max.apply(Math, clientY)) / 2
+ };
+ },
/**
- * @event postchange
- * @description
- * [en]Fired just after the current carousel item has changed.[/en]
- * [ja]現在表示しているカルーセルの要素が変わった時に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.carousel
- * [en]Carousel object.[/en]
- * [ja]イベントが発火したCarouselオブジェクトです。[/ja]
- * @param {Number} event.activeIndex
- * [en]Current active index.[/en]
- * [ja]現在アクティブになっている要素のインデックス。[/ja]
- * @param {Number} event.lastActiveIndex
- * [en]Previous active index.[/en]
- * [ja]以前アクティブだった要素のインデックス。[/ja]
+ * calculate the velocity between two points. unit is in px per ms.
+ * @param {Number} deltaTime
+ * @param {Number} deltaX
+ * @param {Number} deltaY
+ * @return {Object} velocity `x` and `y`
*/
+ getVelocity: function getVelocity(deltaTime, deltaX, deltaY) {
+ return {
+ x: Math.abs(deltaX / deltaTime) || 0,
+ y: Math.abs(deltaY / deltaTime) || 0
+ };
+ },
/**
- * @event refresh
- * @description
- * [en]Fired when the carousel has been refreshed.[/en]
- * [ja]カルーセルが更新された時に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.carousel
- * [en]Carousel object.[/en]
- * [ja]イベントが発火したCarouselオブジェクトです。[/ja]
+ * calculate the angle between two coordinates
+ * @param {Touch} touch1
+ * @param {Touch} touch2
+ * @return {Number} angle
*/
+ getAngle: function getAngle(touch1, touch2) {
+ var x = touch2.clientX - touch1.clientX,
+ y = touch2.clientY - touch1.clientY;
- /**
- * @event overscroll
- * @description
- * [en]Fired when the carousel has been overscrolled.[/en]
- * [ja]カルーセルがオーバースクロールした時に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.carousel
- * [en]Fired when the carousel has been refreshed.[/en]
- * [ja]カルーセルが更新された時に発火します。[/ja]
- * @param {Number} event.activeIndex
- * [en]Current active index.[/en]
- * [ja]現在アクティブになっている要素のインデックス。[/ja]
- * @param {String} event.direction
- * [en]Can be one of either "up", "down", "left" or "right".[/en]
- * [ja]オーバースクロールされた方向が得られます。"up", "down", "left", "right"のいずれかの方向が渡されます。[/ja]
- * @param {Function} event.waitToReturn
- * [en]Takes a Promise
object as an argument. The carousel will not scroll back until the promise has been resolved or rejected.[/en]
- * [ja]この関数はPromiseオブジェクトを引数として受け取ります。渡したPromiseオブジェクトがresolveされるかrejectされるまで、カルーセルはスクロールバックしません。[/ja]
- */
+ return Math.atan2(y, x) * 180 / Math.PI;
+ },
/**
- * @attribute direction
- * @type {String}
- * @description
- * [en]The direction of the carousel. Can be either "horizontal" or "vertical". Default is "horizontal".[/en]
- * [ja]カルーセルの方向を指定します。"horizontal"か"vertical"を指定できます。"horizontal"がデフォルト値です。[/ja]
+ * do a small comparison to get the direction between two touches.
+ * @param {Touch} touch1
+ * @param {Touch} touch2
+ * @return {String} direction matches `DIRECTION_LEFT|RIGHT|UP|DOWN`
*/
+ getDirection: function getDirection(touch1, touch2) {
+ var x = Math.abs(touch1.clientX - touch2.clientX),
+ y = Math.abs(touch1.clientY - touch2.clientY);
+
+ if (x >= y) {
+ return touch1.clientX - touch2.clientX > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
+ }
+ return touch1.clientY - touch2.clientY > 0 ? DIRECTION_UP : DIRECTION_DOWN;
+ },
/**
- * @attribute fullscreen
- * @description
- * [en]If this attribute is set the carousel will cover the whole screen.[/en]
- * [ja]この属性があると、absoluteポジションを使ってカルーセルが自動的に画面いっぱいに広がります。[/ja]
+ * calculate the distance between two touches
+ * @param {Touch}touch1
+ * @param {Touch} touch2
+ * @return {Number} distance
*/
+ getDistance: function getDistance(touch1, touch2) {
+ var x = touch2.clientX - touch1.clientX,
+ y = touch2.clientY - touch1.clientY;
+
+ return Math.sqrt(x * x + y * y);
+ },
/**
- * @attribute overscrollable
- * @description
- * [en]If this attribute is set the carousel will be scrollable over the edge. It will bounce back when released.[/en]
- * [ja]この属性がある時、タッチやドラッグで端までスクロールした時に、バウンドするような効果が当たります。[/ja]
+ * calculate the scale factor between two touchLists
+ * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
+ * @param {Array} start array of touches
+ * @param {Array} end array of touches
+ * @return {Number} scale
*/
+ getScale: function getScale(start, end) {
+ // need two fingers...
+ if (start.length >= 2 && end.length >= 2) {
+ return this.getDistance(end[0], end[1]) / this.getDistance(start[0], start[1]);
+ }
+ return 1;
+ },
/**
- * @attribute centered
- * @description
- * [en]If this attribute is set the carousel then the selected item will be in the center of the carousel instead of the beginning. Useful only when the items are smaller than the carousel. [/en]
- * [ja]この属性がある時、選んでいるons-carousel-itemはカルーセルの真ん中へ行きます。項目がカルーセルよりも小さい場合にのみ、これは便利です。[/ja]
+ * calculate the rotation degrees between two touchLists
+ * @param {Array} start array of touches
+ * @param {Array} end array of touches
+ * @return {Number} rotation
*/
+ getRotation: function getRotation(start, end) {
+ // need two fingers
+ if (start.length >= 2 && end.length >= 2) {
+ return this.getAngle(end[1], end[0]) - this.getAngle(start[1], start[0]);
+ }
+ return 0;
+ },
/**
- * @attribute item-width
- * @type {String}
- * @description
- * [en]ons-carousel-item's width. Only works when the direction is set to "horizontal".[/en]
- * [ja]ons-carousel-itemの幅を指定します。この属性は、direction属性に"horizontal"を指定した時のみ有効になります。[/ja]
+ * find out if the direction is vertical *
+ * @param {String} direction matches `DIRECTION_UP|DOWN`
+ * @return {Boolean} is_vertical
*/
+ isVertical: function isVertical(direction) {
+ return direction == DIRECTION_UP || direction == DIRECTION_DOWN;
+ },
/**
- * @attribute item-height
- * @type {String}
- * @description
- * [en]ons-carousel-item's height. Only works when the direction is set to "vertical".[/en]
- * [ja]ons-carousel-itemの高さを指定します。この属性は、direction属性に"vertical"を指定した時のみ有効になります。[/ja]
+ * set css properties with their prefixes
+ * @param {HTMLElement} element
+ * @param {String} prop
+ * @param {String} value
+ * @param {Boolean} [toggle=true]
+ * @return {Boolean}
*/
+ setPrefixedCss: function setPrefixedCss(element, prop, value, toggle) {
+ var prefixes = ['', 'Webkit', 'Moz', 'O', 'ms'];
+ prop = Utils.toCamelCase(prop);
+
+ for (var i = 0; i < prefixes.length; i++) {
+ var p = prop;
+ // prefixes
+ if (prefixes[i]) {
+ p = prefixes[i] + p.slice(0, 1).toUpperCase() + p.slice(1);
+ }
+
+ // test the style
+ if (p in element.style) {
+ element.style[p] = (toggle === null || toggle) && value || '';
+ break;
+ }
+ }
+ },
/**
- * @attribute auto-scroll
- * @description
- * [en]If this attribute is set the carousel will be automatically scrolled to the closest item border when released.[/en]
- * [ja]この属性がある時、一番近いcarousel-itemの境界まで自動的にスクロールするようになります。[/ja]
+ * toggle browser default behavior by setting css properties.
+ * `userSelect='none'` also sets `element.onselectstart` to false
+ * `userDrag='none'` also sets `element.ondragstart` to false
+ *
+ * @param {HtmlElement} element
+ * @param {Object} props
+ * @param {Boolean} [toggle=true]
*/
+ toggleBehavior: function toggleBehavior(element, props, toggle) {
+ if (!props || !element || !element.style) {
+ return;
+ }
+
+ // set the css properties
+ Utils.each(props, function (value, prop) {
+ Utils.setPrefixedCss(element, prop, value, toggle);
+ });
+
+ var falseFn = toggle && function () {
+ return false;
+ };
+
+ // also the disable onselectstart
+ if (props.userSelect == 'none') {
+ element.onselectstart = falseFn;
+ }
+ // and disable ondragstart
+ if (props.userDrag == 'none') {
+ element.ondragstart = falseFn;
+ }
+ },
/**
- * @attribute auto-scroll-ratio
- * @type {Number}
- * @description
- * [en]A number between 0.0 and 1.0 that specifies how much the user must drag the carousel in order for it to auto scroll to the next item.[/en]
- * [ja]0.0から1.0までの値を指定します。カルーセルの要素をどれぐらいの割合までドラッグすると次の要素に自動的にスクロールするかを指定します。[/ja]
+ * convert a string with underscores to camelCase
+ * so prevent_default becomes preventDefault
+ * @param {String} str
+ * @return {String} camelCaseStr
*/
+ toCamelCase: function toCamelCase(str) {
+ return str.replace(/[_-]([a-z])/g, function (s) {
+ return s[1].toUpperCase();
+ });
+ }
+};
+/**
+ * @module GestureDetector
+ */
+/**
+ * @class Event
+ * @static
+ */
+Event = GestureDetector.event = {
/**
- * @attribute swipeable
- * @description
- * [en]If this attribute is set the carousel can be scrolled by drag or swipe.[/en]
- * [ja]この属性がある時、カルーセルをスワイプやドラッグで移動できるようになります。[/ja]
+ * when touch events have been fired, this is true
+ * this is used to stop mouse events
+ * @property prevent_mouseevents
+ * @private
+ * @type {Boolean}
*/
+ preventMouseEvents: false,
/**
- * @attribute disabled
- * @description
- * [en]If this attribute is set the carousel is disabled.[/en]
- * [ja]この属性がある時、dragやtouchやswipeを受け付けなくなります。[/ja]
+ * if EVENT_START has been fired
+ * @property started
+ * @private
+ * @type {Boolean}
*/
+ started: false,
/**
- * @attribute initial-index
- * @initonly
- * @type {Number}
- * @description
- * [en]Specify the index of the ons-carousel-item to show initially. Default is 0.[/en]
- * [ja]最初に表示するons-carousel-itemを0始まりのインデックスで指定します。デフォルト値は 0 です。[/ja]
+ * when the mouse is hold down, this is true
+ * @property should_detect
+ * @private
+ * @type {Boolean}
*/
+ shouldDetect: false,
/**
- * @attribute auto-refresh
- * @description
- * [en]When this attribute is set the carousel will automatically refresh when the number of child nodes change.[/en]
- * [ja]この属性がある時、子要素の数が変わるとカルーセルは自動的に更新されるようになります。[/ja]
+ * simple event binder with a hook and support for multiple types
+ * @param {HTMLElement} element
+ * @param {String} type
+ * @param {Function} handler
+ * @param {Function} [hook]
+ * @param {Object} hook.type
*/
+ on: function on(element, type, handler, hook) {
+ var types = type.split(' ');
+ Utils.each(types, function (type) {
+ Utils.on(element, type, handler);
+ hook && hook(type);
+ });
+ },
/**
- * @attribute animation
- * @type {String}
- * @description
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
+ * simple event unbinder with a hook and support for multiple types
+ * @param {HTMLElement} element
+ * @param {String} type
+ * @param {Function} handler
+ * @param {Function} [hook]
+ * @param {Object} hook.type
*/
+ off: function off(element, type, handler, hook) {
+ var types = type.split(' ');
+ Utils.each(types, function (type) {
+ Utils.off(element, type, handler);
+ hook && hook(type);
+ });
+ },
/**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。例:{duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
+ * the core touch event handler.
+ * this finds out if we should to detect gestures
+ * @param {HTMLElement} element
+ * @param {String} eventType matches `EVENT_START|MOVE|END`
+ * @param {Function} handler
+ * @return onTouchHandler {Function} the core event handler
*/
+ onTouch: function onTouch(element, eventType, handler) {
+ var self = this;
- function CarouselElement() {
- _classCallCheck(this, CarouselElement);
-
- var _this = _possibleConstructorReturn(this, (CarouselElement.__proto__ || Object.getPrototypeOf(CarouselElement)).call(this));
+ var onTouchHandler = function onTouchHandler(ev) {
+ var srcType = ev.type.toLowerCase(),
+ isPointer = GestureDetector.HAS_POINTEREVENTS,
+ isMouse = Utils.inStr(srcType, 'mouse'),
+ triggerType;
- _this._doorLock = new _doorlock2.default();
- _this._scroll = 0;
- _this._offset = 0;
- _this._lastActiveIndex = 0;
+ // if we are in a mouseevent, but there has been a touchevent triggered in this session
+ // we want to do nothing. simply break out of the event.
+ if (isMouse && self.preventMouseEvents) {
+ return;
- _this._boundOnDragStart = _this._onDragStart.bind(_this);
- _this._boundOnDrag = _this._onDrag.bind(_this);
- _this._boundOnDragEnd = _this._onDragEnd.bind(_this);
- _this._boundOnResize = _this._onResize.bind(_this);
+ // mousebutton must be down
+ } else if (isMouse && eventType == EVENT_START && ev.button === 0) {
+ self.preventMouseEvents = false;
+ self.shouldDetect = true;
+ } else if (isPointer && eventType == EVENT_START) {
+ self.shouldDetect = ev.buttons === 1 || PointerEvent.matchType(POINTER_TOUCH, ev);
+ // just a valid start event, but no mouse
+ } else if (!isMouse && eventType == EVENT_START) {
+ self.preventMouseEvents = true;
+ self.shouldDetect = true;
+ }
- _this._mixin(_this._isVertical() ? VerticalModeTrait : HorizontalModeTrait);
- return _this;
- }
+ // update the pointer event before entering the detection
+ if (isPointer && eventType != EVENT_END) {
+ PointerEvent.updatePointer(eventType, ev);
+ }
- _createClass(CarouselElement, [{
- key: '_onResize',
- value: function _onResize() {
- var i = this._scroll / this._currentElementSize;
- delete this._currentElementSize;
- this.setActiveIndex(i);
+ // we are in a touch/down state, so allowed detection of gestures
+ if (self.shouldDetect) {
+ triggerType = self.doDetect.call(self, ev, eventType, element, handler);
+ }
- this.refresh();
- }
- }, {
- key: '_onDirectionChange',
- value: function _onDirectionChange() {
- if (this._isVertical()) {
- this.style.overflowX = 'auto';
- this.style.overflowY = '';
- } else {
- this.style.overflowX = '';
- this.style.overflowY = 'auto';
+ // ...and we are done with the detection
+ // so reset everything to start each detection totally fresh
+ if (triggerType == EVENT_END) {
+ self.preventMouseEvents = false;
+ self.shouldDetect = false;
+ PointerEvent.reset();
+ // update the pointerevent object after the detection
}
- this.refresh();
- }
- }, {
- key: '_saveLastState',
- value: function _saveLastState() {
- this._lastState = {
- elementSize: this._getCarouselItemSize(),
- carouselElementCount: this.itemCount,
- width: this._getCarouselItemSize() * this.itemCount
- };
- }
+ if (isPointer && eventType == EVENT_END) {
+ PointerEvent.updatePointer(eventType, ev);
+ }
+ };
- /**
- * @return {Number}
- */
+ this.on(element, EVENT_TYPES[eventType], onTouchHandler);
+ return onTouchHandler;
+ },
- }, {
- key: '_getCarouselItemSize',
- value: function _getCarouselItemSize() {
- var sizeAttr = this._getCarouselItemSizeAttr();
- var sizeInfo = this._decomposeSizeString(sizeAttr);
- var elementSize = this._getElementSize();
-
- if (sizeInfo.unit === '%') {
- return Math.round(sizeInfo.number / 100 * elementSize);
- } else if (sizeInfo.unit === 'px') {
- return sizeInfo.number;
- } else {
- throw new Error('Invalid state');
- }
- }
+ /**
+ * the core detection method
+ * this finds out what GestureDetector-touch-events to trigger
+ * @param {Object} ev
+ * @param {String} eventType matches `EVENT_START|MOVE|END`
+ * @param {HTMLElement} element
+ * @param {Function} handler
+ * @return {String} triggerType matches `EVENT_START|MOVE|END`
+ */
+ doDetect: function doDetect(ev, eventType, element, handler) {
+ var touchList = this.getTouchList(ev, eventType);
+ var touchListLength = touchList.length;
+ var triggerType = eventType;
+ var triggerChange = touchList.trigger; // used by fakeMultitouch plugin
+ var changedLength = touchListLength;
- /**
- * @return {Number}
- */
+ // at each touchstart-like event we want also want to trigger a TOUCH event...
+ if (eventType == EVENT_START) {
+ triggerChange = EVENT_TOUCH;
+ // ...the same for a touchend-like event
+ } else if (eventType == EVENT_END) {
+ triggerChange = EVENT_RELEASE;
- }, {
- key: '_getInitialIndex',
- value: function _getInitialIndex() {
- var index = parseInt(this.getAttribute('initial-index'), 10);
+ // keep track of how many touches have been removed
+ changedLength = touchList.length - (ev.changedTouches ? ev.changedTouches.length : 1);
+ }
- if (typeof index === 'number' && !isNaN(index)) {
- return Math.max(Math.min(index, this.itemCount - 1), 0);
- } else {
- return 0;
- }
+ // after there are still touches on the screen,
+ // we just want to trigger a MOVE event. so change the START or END to a MOVE
+ // but only after detection has been started, the first time we actually want a START
+ if (changedLength > 0 && this.started) {
+ triggerType = EVENT_MOVE;
}
- /**
- * @return {String}
- */
+ // detection has been started, we keep track of this, see above
+ this.started = true;
- }, {
- key: '_getCarouselItemSizeAttr',
- value: function _getCarouselItemSizeAttr() {
- var attrName = 'item-' + (this._isVertical() ? 'height' : 'width');
- var itemSizeAttr = ('' + this.getAttribute(attrName)).trim();
+ // generate some event data, some basic information
+ var evData = this.collectEventData(element, triggerType, touchList, ev);
- return itemSizeAttr.match(/^\d+(px|%)$/) ? itemSizeAttr : '100%';
+ // trigger the triggerType event before the change (TOUCH, RELEASE) events
+ // but the END event should be at last
+ if (eventType != EVENT_END) {
+ handler.call(Detection, evData);
}
- /**
- * @return {Object}
- */
+ // trigger a change (TOUCH, RELEASE) event, this means the length of the touches changed
+ if (triggerChange) {
+ evData.changedLength = changedLength;
+ evData.eventType = triggerChange;
- }, {
- key: '_decomposeSizeString',
- value: function _decomposeSizeString(size) {
- var matches = size.match(/^(\d+)(px|%)/);
+ handler.call(Detection, evData);
- return {
- number: parseInt(matches[1], 10),
- unit: matches[2]
- };
- }
- }, {
- key: '_setupInitialIndex',
- value: function _setupInitialIndex() {
- this._scroll = (this._offset || 0) + this._getCarouselItemSize() * this._getInitialIndex();
- this._lastActiveIndex = this._getInitialIndex();
- this._scrollTo(this._scroll);
+ evData.eventType = triggerType;
+ delete evData.changedLength;
}
- /**
- * @method setActiveIndex
- * @signature setActiveIndex(index, [options])
- * @param {Number} index
- * [en]The index that the carousel should be set to.[/en]
- * [ja]carousel要素のインデックスを指定します。[/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be called after the animation is finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @description
- * [en]Specify the index of the `` to show.[/en]
- * [ja]表示するons-carousel-itemをindexで指定します。[/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element.[/en]
- * [ja][/ja]
- */
+ // trigger the END event
+ if (triggerType == EVENT_END) {
+ handler.call(Detection, evData);
- }, {
- key: 'setActiveIndex',
- value: function setActiveIndex(index) {
- var _this2 = this;
+ // ...and we are done with the detection
+ // so reset everything to start each detection totally fresh
+ this.started = false;
+ }
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ return triggerType;
+ },
- if (options && (typeof options === 'undefined' ? 'undefined' : _typeof(options)) != 'object') {
- throw new Error('options must be an object. You supplied ' + options);
+ /**
+ * we have different events for each device/browser
+ * determine what we need and set them in the EVENT_TYPES constant
+ * the `onTouch` method is bind to these properties.
+ * @return {Object} events
+ */
+ determineEventTypes: function determineEventTypes() {
+ var types;
+ if (GestureDetector.HAS_POINTEREVENTS) {
+ if (window.PointerEvent) {
+ types = ['pointerdown', 'pointermove', 'pointerup pointercancel lostpointercapture'];
+ } else {
+ types = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp MSPointerCancel MSLostPointerCapture'];
}
-
- options.animation = options.animation || this.getAttribute('animation');
- options.animationOptions = _util2.default.extend({ duration: 0.3, timing: 'cubic-bezier(.1, .7, .1, 1)' }, options.animationOptions || {}, this.hasAttribute('animation-options') ? _util2.default.animationOptionsParse(this.getAttribute('animation-options')) : {});
-
- index = Math.max(0, Math.min(index, this.itemCount - 1));
- var scroll = (this._offset || 0) + this._getCarouselItemSize() * index;
- var max = this._calculateMaxScroll();
-
- this._scroll = Math.max(0, Math.min(max, scroll));
- return this._scrollTo(this._scroll, options).then(function () {
- _this2._tryFirePostChangeEvent();
- return _this2;
- });
+ } else if (GestureDetector.NO_MOUSEEVENTS) {
+ types = ['touchstart', 'touchmove', 'touchend touchcancel'];
+ } else {
+ types = ['touchstart mousedown', 'touchmove mousemove', 'touchend touchcancel mouseup'];
}
- /**
- * @method getActiveIndex
- * @signature getActiveIndex()
- * @return {Number}
- * [en]The current carousel item index.[/en]
- * [ja]現在表示しているカルーセル要素のインデックスが返されます。[/ja]
- * @description
- * [en]Returns the index of the currently visible ``.[/en]
- * [ja]現在表示されているons-carousel-item要素のインデックスを返します。[/ja]
- */
+ EVENT_TYPES[EVENT_START] = types[0];
+ EVENT_TYPES[EVENT_MOVE] = types[1];
+ EVENT_TYPES[EVENT_END] = types[2];
+ return EVENT_TYPES;
+ },
- }, {
- key: 'getActiveIndex',
- value: function getActiveIndex() {
- var scroll = this._scroll - (this._offset || 0);
- var count = this.itemCount;
- var size = this._getCarouselItemSize();
+ /**
+ * create touchList depending on the event
+ * @param {Object} ev
+ * @param {String} eventType
+ * @return {Array} touches
+ */
+ getTouchList: function getTouchList(ev, eventType) {
+ // get the fake pointerEvent touchlist
+ if (GestureDetector.HAS_POINTEREVENTS) {
+ return PointerEvent.getTouchList();
+ }
- if (scroll < 0) {
- return 0;
+ // get the touchlist
+ if (ev.touches) {
+ if (eventType == EVENT_MOVE) {
+ return ev.touches;
}
- var i = void 0;
- for (i = 0; i < count; i++) {
- if (size * i <= scroll && size * (i + 1) > scroll) {
- return i;
+ var identifiers = [];
+ var concat = [].concat(Utils.toArray(ev.touches), Utils.toArray(ev.changedTouches));
+ var touchList = [];
+
+ Utils.each(concat, function (touch) {
+ if (Utils.inArray(identifiers, touch.identifier) === false) {
+ touchList.push(touch);
}
- }
+ identifiers.push(touch.identifier);
+ });
- // max carousel index
- return i;
+ return touchList;
}
- /**
- * @method next
- * @signature next([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be executed after the animation has finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element[/en]
- * [ja][/ja]
- * @description
- * [en]Show next ``.[/en]
- * [ja]次のons-carousel-itemを表示します。[/ja]
- */
+ // make fake touchList from mouse position
+ ev.identifier = 1;
+ return [ev];
+ },
- }, {
- key: 'next',
- value: function next(options) {
- return this.setActiveIndex(this.getActiveIndex() + 1, options);
+ /**
+ * collect basic event data
+ * @param {HTMLElement} element
+ * @param {String} eventType matches `EVENT_START|MOVE|END`
+ * @param {Array} touches
+ * @param {Object} ev
+ * @return {Object} ev
+ */
+ collectEventData: function collectEventData(element, eventType, touches, ev) {
+ // find out pointerType
+ var pointerType = POINTER_TOUCH;
+ if (Utils.inStr(ev.type, 'mouse') || PointerEvent.matchType(POINTER_MOUSE, ev)) {
+ pointerType = POINTER_MOUSE;
+ } else if (PointerEvent.matchType(POINTER_PEN, ev)) {
+ pointerType = POINTER_PEN;
}
- /**
- * @method prev
- * @signature prev([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be executed after the animation has finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element[/en]
- * [ja][/ja]
- * @description
- * [en]Show previous ``.[/en]
- * [ja]前のons-carousel-itemを表示します。[/ja]
- */
+ return {
+ center: Utils.getCenter(touches),
+ timeStamp: Date.now(),
+ target: ev.target,
+ touches: touches,
+ eventType: eventType,
+ pointerType: pointerType,
+ srcEvent: ev,
- }, {
- key: 'prev',
- value: function prev(options) {
- return this.setActiveIndex(this.getActiveIndex() - 1, options);
- }
+ /**
+ * prevent the browser default actions
+ * mostly used to disable scrolling of the browser
+ */
+ preventDefault: function preventDefault() {
+ var srcEvent = this.srcEvent;
+ srcEvent.preventManipulation && srcEvent.preventManipulation();
+ srcEvent.preventDefault && srcEvent.preventDefault();
+ },
- /**
- * @return {Boolean}
- */
+ /**
+ * stop bubbling the event up to its parents
+ */
+ stopPropagation: function stopPropagation() {
+ this.srcEvent.stopPropagation();
+ },
- }, {
- key: '_isEnabledChangeEvent',
- value: function _isEnabledChangeEvent() {
- var elementSize = this._getElementSize();
- var carouselItemSize = this._getCarouselItemSize();
+ /**
+ * immediately stop gesture detection
+ * might be useful after a swipe was detected
+ * @return {*}
+ */
+ stopDetect: function stopDetect() {
+ return Detection.stopDetect();
+ }
+ };
+ }
+};
- return this.autoScroll && Math.abs(elementSize - carouselItemSize) < 0.5;
- }
+/**
+ * @module GestureDetector
+ *
+ * @class PointerEvent
+ * @static
+ */
+PointerEvent = GestureDetector.PointerEvent = {
+ /**
+ * holds all pointers, by `identifier`
+ * @property pointers
+ * @type {Object}
+ */
+ pointers: {},
- /**
- * @return {Boolean}
- */
+ /**
+ * get the pointers as an array
+ * @return {Array} touchlist
+ */
+ getTouchList: function getTouchList() {
+ var touchlist = [];
+ // we can use forEach since pointerEvents only is in IE10
+ Utils.each(this.pointers, function (pointer) {
+ touchlist.push(pointer);
+ });
+ return touchlist;
+ },
- }, {
- key: '_isVertical',
- value: function _isVertical() {
- return this.getAttribute('direction') === 'vertical';
+ /**
+ * update the position of a pointer
+ * @param {String} eventType matches `EVENT_START|MOVE|END`
+ * @param {Object} pointerEvent
+ */
+ updatePointer: function updatePointer(eventType, pointerEvent) {
+ if (eventType == EVENT_END || eventType != EVENT_END && pointerEvent.buttons !== 1) {
+ delete this.pointers[pointerEvent.pointerId];
+ } else {
+ pointerEvent.identifier = pointerEvent.pointerId;
+ this.pointers[pointerEvent.pointerId] = pointerEvent;
}
- }, {
- key: '_show',
- value: function _show() {
- window.addEventListener('resize', this._boundOnResize, true);
+ },
+
+ /**
+ * check if ev matches pointertype
+ * @param {String} pointerType matches `POINTER_MOUSE|TOUCH|PEN`
+ * @param {PointerEvent} ev
+ */
+ matchType: function matchType(pointerType, ev) {
+ if (!ev.pointerType) {
+ return false;
}
- }, {
- key: '_prepareEventListeners',
- value: function _prepareEventListeners() {
- var _this3 = this;
- this._gestureDetector = new _gestureDetector2.default(this, {
- dragMinDistance: 1,
- dragLockToAxis: true
- });
- this._mutationObserver = new MutationObserver(function () {
- return _this3.refresh();
- });
+ var pt = ev.pointerType,
+ types = {};
- this._updateSwipeable();
- this._updateAutoRefresh();
+ types[POINTER_MOUSE] = pt === (ev.MSPOINTER_TYPE_MOUSE || POINTER_MOUSE);
+ types[POINTER_TOUCH] = pt === (ev.MSPOINTER_TYPE_TOUCH || POINTER_TOUCH);
+ types[POINTER_PEN] = pt === (ev.MSPOINTER_TYPE_PEN || POINTER_PEN);
+ return types[pointerType];
+ },
- window.addEventListener('resize', this._boundOnResize, true);
- }
- }, {
- key: '_hide',
- value: function _hide() {
- window.removeEventListener('resize', this._boundOnResize, true);
- }
- }, {
- key: '_removeEventListeners',
- value: function _removeEventListeners() {
- this._gestureDetector.dispose();
- this._gestureDetector = null;
+ /**
+ * reset the stored pointers
+ */
+ reset: function resetList() {
+ this.pointers = {};
+ }
+};
- this._mutationObserver.disconnect();
- this._mutationObserver = null;
+/**
+ * @module GestureDetector
+ *
+ * @class Detection
+ * @static
+ */
+Detection = GestureDetector.detection = {
+ // contains all registered GestureDetector.gestures in the correct order
+ gestures: [],
- window.removeEventListener('resize', this._boundOnResize, true);
- }
- }, {
- key: '_updateSwipeable',
- value: function _updateSwipeable() {
- if (this._gestureDetector) {
- var action = this.swipeable ? 'on' : 'off';
- this._gestureDetector[action]('drag', this._boundOnDrag);
- this._gestureDetector[action]('dragstart', this._boundOnDragStart);
- this._gestureDetector[action]('dragend', this._boundOnDragEnd);
- }
- }
- }, {
- key: '_updateAutoRefresh',
- value: function _updateAutoRefresh() {
- if (this._mutationObserver) {
- if (this.hasAttribute('auto-refresh')) {
- this._mutationObserver.observe(this, { childList: true });
- } else {
- this._mutationObserver.disconnect();
- }
- }
- }
- }, {
- key: '_tryFirePostChangeEvent',
- value: function _tryFirePostChangeEvent() {
- var currentIndex = this.getActiveIndex();
+ // data of the current GestureDetector.gesture detection session
+ current: null,
- if (this._lastActiveIndex !== currentIndex) {
- var lastActiveIndex = this._lastActiveIndex;
- this._lastActiveIndex = currentIndex;
+ // the previous GestureDetector.gesture session data
+ // is a full clone of the previous gesture.current object
+ previous: null,
- _util2.default.triggerElementEvent(this, 'postchange', {
- carousel: this,
- activeIndex: currentIndex,
- lastActiveIndex: lastActiveIndex
- });
- }
- }
- }, {
- key: '_canConsumeGesture',
- value: function _canConsumeGesture(gesture) {
- var d = gesture.direction;
- var isFirst = this._scroll === 0 && !this.overscrollable;
- var isLast = this._scroll === this._calculateMaxScroll() && !this.overscrollable;
+ // when this becomes true, no gestures are fired
+ stopped: false,
- return this._isVertical() ? d === 'down' && !isFirst || d === 'up' && !isLast : d === 'right' && !isFirst || d === 'left' && !isLast;
+ /**
+ * start GestureDetector.gesture detection
+ * @param {GestureDetector.Instance} inst
+ * @param {Object} eventData
+ */
+ startDetect: function startDetect(inst, eventData) {
+ // already busy with a GestureDetector.gesture detection on an element
+ if (this.current) {
+ return;
}
- }, {
- key: '_onDragStart',
- value: function _onDragStart(event) {
- var _this4 = this;
- this._ignoreDrag = event.consumed;
+ this.stopped = false;
- if (event.gesture && !this._ignoreDrag) {
- var consume = event.consume;
- event.consume = function () {
- consume && consume();_this4._ignoreDrag = true;
- };
- if (this._canConsumeGesture(event.gesture)) {
- consume && consume();
- event.consumed = true;
- this._started = true; // Avoid starting drag from outside
- }
- }
- }
- }, {
- key: '_onDrag',
- value: function _onDrag(event) {
- if (!event.gesture || this._ignoreDrag || !this._canConsumeGesture(event.gesture) || !this._started) {
- return;
- }
+ // holds current session
+ this.current = {
+ inst: inst, // reference to GestureDetectorInstance we're working for
+ startEvent: Utils.extend({}, eventData), // start eventData for distances, timing etc
+ lastEvent: false, // last eventData
+ lastCalcEvent: false, // last eventData for calculations.
+ futureCalcEvent: false, // last eventData for calculations.
+ lastCalcData: {}, // last lastCalcData
+ name: '' // current gesture we're in/detected, can be 'tap', 'hold' etc
+ };
- event.stopPropagation();
+ this.detect(eventData);
+ },
- this._lastDragEvent = event;
+ /**
+ * GestureDetector.gesture detection
+ * @param {Object} eventData
+ * @return {any}
+ */
+ detect: function detect(eventData) {
+ if (!this.current || this.stopped) {
+ return;
+ }
- var scroll = this._scroll - this._getScrollDelta(event);
- this._scrollTo(scroll);
- event.gesture.preventDefault();
+ // extend event data with calculations about scale, distance etc
+ eventData = this.extendEventData(eventData);
- this._tryFirePostChangeEvent();
- }
- }, {
- key: '_onDragEnd',
- value: function _onDragEnd(event) {
- var _this5 = this;
+ // GestureDetector instance and instance options
+ var inst = this.current.inst,
+ instOptions = inst.options;
- this._started = false;
- if (!event.gesture || !this._lastDragEvent || this._ignoreDrag) {
- return;
+ // call GestureDetector.gesture handlers
+ Utils.each(this.gestures, function triggerGesture(gesture) {
+ // only when the instance options have enabled this gesture
+ if (!this.stopped && inst.enabled && instOptions[gesture.name]) {
+ gesture.handler.call(gesture, eventData, inst);
}
+ }, this);
- event.stopPropagation();
+ // store as previous event event
+ if (this.current) {
+ this.current.lastEvent = eventData;
+ }
- this._currentElementSize = undefined;
- this._scroll = this._scroll - this._getScrollDelta(event);
+ if (eventData.eventType == EVENT_END) {
+ this.stopDetect();
+ }
- if (this._isOverScroll(this._scroll)) {
- var waitForAction = false;
- _util2.default.triggerElementEvent(this, 'overscroll', {
- carousel: this,
- activeIndex: this.getActiveIndex(),
- direction: this._getOverScrollDirection(),
- waitToReturn: function waitToReturn(promise) {
- waitForAction = true;
- promise.then(function () {
- return _this5._scrollToKillOverScroll();
- });
- }
- });
+ return eventData; // eslint-disable-line consistent-return
+ },
- if (!waitForAction) {
- this._scrollToKillOverScroll();
- }
- } else {
- this._startMomentumScroll();
- }
- this._lastDragEvent = null;
+ /**
+ * clear the GestureDetector.gesture vars
+ * this is called on endDetect, but can also be used when a final GestureDetector.gesture has been detected
+ * to stop other GestureDetector.gestures from being fired
+ */
+ stopDetect: function stopDetect() {
+ // clone current data to the store as the previous gesture
+ // used for the double tap gesture, since this is an other gesture detect session
+ this.previous = Utils.extend({}, this.current);
- event.gesture.preventDefault();
- }
+ // reset the current
+ this.current = null;
+ this.stopped = true;
+ },
- /**
- * @param {Object} trait
- */
+ /**
+ * calculate velocity, angle and direction
+ * @param {Object} ev
+ * @param {Object} center
+ * @param {Number} deltaTime
+ * @param {Number} deltaX
+ * @param {Number} deltaY
+ */
+ getCalculatedData: function getCalculatedData(ev, center, deltaTime, deltaX, deltaY) {
+ var cur = this.current,
+ recalc = false,
+ calcEv = cur.lastCalcEvent,
+ calcData = cur.lastCalcData;
- }, {
- key: '_mixin',
- value: function _mixin(trait) {
- Object.keys(trait).forEach(function (key) {
- this[key] = trait[key];
- }.bind(this));
+ if (calcEv && ev.timeStamp - calcEv.timeStamp > GestureDetector.CALCULATE_INTERVAL) {
+ center = calcEv.center;
+ deltaTime = ev.timeStamp - calcEv.timeStamp;
+ deltaX = ev.center.clientX - calcEv.center.clientX;
+ deltaY = ev.center.clientY - calcEv.center.clientY;
+ recalc = true;
}
- }, {
- key: '_startMomentumScroll',
- value: function _startMomentumScroll() {
- if (this._lastDragEvent) {
- var velocity = this._getScrollVelocity(this._lastDragEvent);
- var duration = 0.3;
- var scrollDelta = duration * 100 * velocity;
- var scroll = this._normalizeScrollPosition(this._scroll + (this._getScrollDelta(this._lastDragEvent) > 0 ? -scrollDelta : scrollDelta));
-
- this._scroll = scroll;
- (0, _animit2.default)(this._getCarouselItemElements()).queue({
- transform: this._generateScrollTransform(this._scroll)
- }, {
- duration: duration,
- timing: 'cubic-bezier(.1, .7, .1, 1)'
- }).queue(function (done) {
- done();
- this._tryFirePostChangeEvent();
- }.bind(this)).play();
- }
+ if (ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) {
+ cur.futureCalcEvent = ev;
}
- }, {
- key: '_normalizeScrollPosition',
- value: function _normalizeScrollPosition(scroll) {
- var max = this._calculateMaxScroll();
- if (!this.autoScroll) {
- return Math.max(0, Math.min(max, scroll));
- }
- var arr = [];
- var size = this._getCarouselItemSize();
- var nbrOfItems = this.itemCount;
+ if (!cur.lastCalcEvent || recalc) {
+ calcData.velocity = Utils.getVelocity(deltaTime, deltaX, deltaY);
+ calcData.angle = Utils.getAngle(center, ev.center);
+ calcData.direction = Utils.getDirection(center, ev.center);
- for (var i = 0; i < nbrOfItems; i++) {
- if (i * size + this._offset < max) {
- arr.push(i * size + this._offset);
- }
- }
- arr.push(max);
+ cur.lastCalcEvent = cur.futureCalcEvent || ev;
+ cur.futureCalcEvent = ev;
+ }
- arr.sort(function (left, right) {
- left = Math.abs(left - scroll);
- right = Math.abs(right - scroll);
+ ev.velocityX = calcData.velocity.x;
+ ev.velocityY = calcData.velocity.y;
+ ev.interimAngle = calcData.angle;
+ ev.interimDirection = calcData.direction;
+ },
- return left - right;
- });
+ /**
+ * extend eventData for GestureDetector.gestures
+ * @param {Object} ev
+ * @return {Object} ev
+ */
+ extendEventData: function extendEventData(ev) {
+ var cur = this.current,
+ startEv = cur.startEvent,
+ lastEv = cur.lastEvent || startEv;
- arr = arr.filter(function (item, pos) {
- return !pos || item != arr[pos - 1];
+ // update the start touchlist to calculate the scale/rotation
+ if (ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) {
+ startEv.touches = [];
+ Utils.each(ev.touches, function (touch) {
+ startEv.touches.push({
+ clientX: touch.clientX,
+ clientY: touch.clientY
+ });
});
-
- var lastScroll = this._lastActiveIndex * size + this._offset;
- var scrollRatio = Math.abs(scroll - lastScroll) / size;
- var result = arr[0];
-
- if (scrollRatio <= this.autoScrollRatio) {
- result = lastScroll;
- } else if (scrollRatio < 1.0) {
- if (arr[0] === lastScroll && arr.length > 1) {
- result = arr[1];
- }
- }
-
- return Math.max(0, Math.min(max, result));
}
- /**
- * @return {Array}
- */
+ var deltaTime = ev.timeStamp - startEv.timeStamp,
+ deltaX = ev.center.clientX - startEv.center.clientX,
+ deltaY = ev.center.clientY - startEv.center.clientY;
- }, {
- key: '_getCarouselItemElements',
- value: function _getCarouselItemElements() {
- return _util2.default.arrayFrom(this.children).filter(function (child) {
- return child.nodeName.toLowerCase() === 'ons-carousel-item';
- });
- }
+ this.getCalculatedData(ev, lastEv.center, deltaTime, deltaX, deltaY);
- /**
- * @param {Number} scroll
- * @param {Object} [options]
- * @return {Promise} Resolves to the carousel element
- */
+ Utils.extend(ev, {
+ startEvent: startEv,
- }, {
- key: '_scrollTo',
- value: function _scrollTo(scroll) {
- var _this6 = this;
+ deltaTime: deltaTime,
+ deltaX: deltaX,
+ deltaY: deltaY,
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ distance: Utils.getDistance(startEv.center, ev.center),
+ angle: Utils.getAngle(startEv.center, ev.center),
+ direction: Utils.getDirection(startEv.center, ev.center),
+ scale: Utils.getScale(startEv.touches, ev.touches),
+ rotation: Utils.getRotation(startEv.touches, ev.touches)
+ });
- var isOverscrollable = this.overscrollable;
+ return ev;
+ },
- var normalizeScroll = function normalizeScroll(scroll) {
- var ratio = 0.35;
+ /**
+ * register new gesture
+ * @param {Object} gesture object, see `gestures/` for documentation
+ * @return {Array} gestures
+ */
+ register: function register(gesture) {
+ // add an enable gesture options if there is no given
+ var options = gesture.defaults || {};
+ if (options[gesture.name] === undefined) {
+ options[gesture.name] = true;
+ }
- if (scroll < 0) {
- return isOverscrollable ? Math.round(scroll * ratio) : 0;
- }
+ // extend GestureDetector default options with the GestureDetector.gesture options
+ Utils.extend(GestureDetector.defaults, options, true);
- var maxScroll = _this6._calculateMaxScroll();
- if (maxScroll < scroll) {
- return isOverscrollable ? maxScroll + Math.round((scroll - maxScroll) * ratio) : maxScroll;
- }
+ // set its index
+ gesture.index = gesture.index || 1000;
- return scroll;
- };
+ // add GestureDetector.gesture to the list
+ this.gestures.push(gesture);
- return new Promise(function (resolve) {
- (0, _animit2.default)(_this6._getCarouselItemElements()).queue({
- transform: _this6._generateScrollTransform(normalizeScroll(scroll))
- }, options.animation !== 'none' ? options.animationOptions : {}).play(function () {
- if (options.callback instanceof Function) {
- options.callback();
- }
- resolve();
- });
- });
- }
- }, {
- key: '_calculateMaxScroll',
- value: function _calculateMaxScroll() {
- var max = this.itemCount * this._getCarouselItemSize() - this._getElementSize();
- return Math.ceil(max < 0 ? 0 : max); // Need to return an integer value.
- }
- }, {
- key: '_isOverScroll',
- value: function _isOverScroll(scroll) {
- if (scroll < 0 || scroll > this._calculateMaxScroll()) {
- return true;
- }
- return false;
- }
- }, {
- key: '_getOverScrollDirection',
- value: function _getOverScrollDirection() {
- if (this._isVertical()) {
- return this._scroll <= 0 ? 'up' : 'down';
- } else {
- return this._scroll <= 0 ? 'left' : 'right';
+ // sort the list by index
+ this.gestures.sort(function (a, b) {
+ if (a.index < b.index) {
+ return -1;
}
- }
- }, {
- key: '_scrollToKillOverScroll',
- value: function _scrollToKillOverScroll() {
- var duration = 0.4;
-
- if (this._scroll < 0) {
- (0, _animit2.default)(this._getCarouselItemElements()).queue({
- transform: this._generateScrollTransform(0)
- }, {
- duration: duration,
- timing: 'cubic-bezier(.1, .4, .1, 1)'
- }).queue(function (done) {
- done();
- this._tryFirePostChangeEvent();
- }.bind(this)).play();
- this._scroll = 0;
- return;
+ if (a.index > b.index) {
+ return 1;
}
+ return 0;
+ });
- var maxScroll = this._calculateMaxScroll();
+ return this.gestures;
+ }
+};
- if (maxScroll < this._scroll) {
- (0, _animit2.default)(this._getCarouselItemElements()).queue({
- transform: this._generateScrollTransform(maxScroll)
- }, {
- duration: duration,
- timing: 'cubic-bezier(.1, .4, .1, 1)'
- }).queue(function (done) {
- done();
- this._tryFirePostChangeEvent();
- }.bind(this)).play();
- this._scroll = maxScroll;
- return;
- }
+/**
+ * @module GestureDetector
+ */
- return;
- }
+/**
+ * create new GestureDetector instance
+ * all methods should return the instance itself, so it is chainable.
+ *
+ * @class Instance
+ * @constructor
+ * @param {HTMLElement} element
+ * @param {Object} [options={}] options are merged with `GestureDetector.defaults`
+ * @return {GestureDetector.Instance}
+ */
+GestureDetector.Instance = function (element, options) {
+ var self = this;
- /**
- * @property itemCount
- * @readonly
- * @type {Number}
- * @description
- * [en]The number of carousel items.[/en]
- * [ja]カルーセル要素の数です。[/ja]
- */
+ // setup GestureDetectorJS window events and register all gestures
+ // this also sets up the default options
+ setup();
- }, {
- key: 'refresh',
+ /**
+ * @property element
+ * @type {HTMLElement}
+ */
+ this.element = element;
+ /**
+ * @property enabled
+ * @type {Boolean}
+ * @protected
+ */
+ this.enabled = true;
- /**
- * @method refresh
- * @signature refresh()
- * @description
- * [en]Update the layout of the carousel. Used when adding `` dynamically or to automatically adjust the size.[/en]
- * [ja]レイアウトや内部の状態を最新のものに更新します。ons-carousel-itemを動的に増やしたり、ons-carouselの大きさを動的に変える際に利用します。[/ja]
- */
- value: function refresh() {
- // Bug fix
- if (this._getCarouselItemSize() === 0) {
- return;
- }
+ /**
+ * options, merged with the defaults
+ * options with an _ are converted to camelCase
+ * @property options
+ * @type {Object}
+ */
+ Utils.each(options, function (value, name) {
+ delete options[name];
+ options[Utils.toCamelCase(name)] = value;
+ });
- this._mixin(this._isVertical() ? VerticalModeTrait : HorizontalModeTrait);
- this._setup();
+ this.options = Utils.extend(Utils.extend({}, GestureDetector.defaults), options || {});
- if (this._lastState && this._lastState.width > 0) {
- var scroll = this._scroll; // - this._offset;
+ // add some css to the element to prevent the browser from doing its native behavior
+ if (this.options.behavior) {
+ Utils.toggleBehavior(this.element, this.options.behavior, true);
+ }
- if (this._isOverScroll(scroll)) {
- this._scrollToKillOverScroll();
- } else {
- if (this.autoScroll) {
- scroll = this._normalizeScrollPosition(scroll);
- }
+ /**
+ * event start handler on the element to start the detection
+ * @property eventStartHandler
+ * @type {Object}
+ */
+ this.eventStartHandler = Event.onTouch(element, EVENT_START, function (ev) {
+ if (self.enabled && ev.eventType == EVENT_START) {
+ Detection.startDetect(self, ev);
+ } else if (ev.eventType == EVENT_TOUCH) {
+ Detection.detect(ev);
+ }
+ });
- this._scrollTo(scroll);
- }
- }
+ /**
+ * keep a list of user event handlers which needs to be removed when calling 'dispose'
+ * @property eventHandlers
+ * @type {Array}
+ */
+ this.eventHandlers = [];
+};
- this._saveLastState();
+GestureDetector.Instance.prototype = {
+ /**
+ * @method on
+ * @signature on(gestures, handler)
+ * @description
+ * [en]Adds an event handler for a gesture. Available gestures are: drag, dragleft, dragright, dragup, dragdown, hold, release, swipe, swipeleft, swiperight, swipeup, swipedown, tap, doubletap, touch, transform, pinch, pinchin, pinchout and rotate. [/en]
+ * [ja]ジェスチャに対するイベントハンドラを追加します。指定できるジェスチャ名は、drag dragleft dragright dragup dragdown hold release swipe swipeleft swiperight swipeup swipedown tap doubletap touch transform pinch pinchin pinchout rotate です。[/ja]
+ * @param {String} gestures
+ * [en]A space separated list of gestures.[/en]
+ * [ja]検知するジェスチャ名を指定します。スペースで複数指定することができます。[/ja]
+ * @param {Function} handler
+ * [en]An event handling function.[/en]
+ * [ja]イベントハンドラとなる関数オブジェクトを指定します。[/ja]
+ */
+ on: function onEvent(gestures, handler) {
+ var self = this;
+ Event.on(self.element, gestures, handler, function (type) {
+ self.eventHandlers.push({ gesture: type, handler: handler });
+ });
+ return self;
+ },
- _util2.default.triggerElementEvent(this, 'refresh', { carousel: this });
- }
+ /**
+ * @method off
+ * @signature off(gestures, handler)
+ * @description
+ * [en]Remove an event listener.[/en]
+ * [ja]イベントリスナーを削除します。[/ja]
+ * @param {String} gestures
+ * [en]A space separated list of gestures.[/en]
+ * [ja]ジェスチャ名を指定します。スペースで複数指定することができます。[/ja]
+ * @param {Function} handler
+ * [en]An event handling function.[/en]
+ * [ja]イベントハンドラとなる関数オブジェクトを指定します。[/ja]
+ */
+ off: function offEvent(gestures, handler) {
+ var self = this;
- /**
- * @method first
- * @signature first()
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be executed after the animation has finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this is set to `"none"`, the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element[/en]
- * [ja][/ja]
- * @description
- * [en]Show first ``.[/en]
- * [ja]最初のons-carousel-itemを表示します。[/ja]
- */
+ Event.off(self.element, gestures, handler, function (type) {
+ var index = Utils.inArray({ gesture: type, handler: handler });
+ if (index !== false) {
+ self.eventHandlers.splice(index, 1);
+ }
+ });
+ return self;
+ },
- }, {
- key: 'first',
- value: function first(options) {
- return this.setActiveIndex(0, options);
+ /**
+ * trigger gesture event
+ * @method trigger
+ * @signature trigger(gesture, eventData)
+ * @param {String} gesture
+ * @param {Object} [eventData]
+ */
+ trigger: function triggerEvent(gesture, eventData) {
+ // optional
+ if (!eventData) {
+ eventData = {};
}
- /**
- * @method last
- * @signature last()
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be executed after the animation has finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element[/en]
- * [ja]Resolves to the carousel element[/ja]
- * @description
- * [en]Show last ons-carousel item.[/en]
- * [ja]最後のons-carousel-itemを表示します。[/ja]
- */
+ // create DOM event
+ var event = GestureDetector.DOCUMENT.createEvent('Event');
+ event.initEvent(gesture, true, true);
+ event.gesture = eventData;
- }, {
- key: 'last',
- value: function last(options) {
- this.setActiveIndex(Math.max(this.itemCount - 1, 0), options);
+ // trigger on the target if it is in the instance element,
+ // this is for event delegation tricks
+ var element = this.element;
+ if (Utils.hasParent(eventData.target, element)) {
+ element = eventData.target;
}
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this7 = this;
-
- this._prepareEventListeners();
- this._setup();
- this._setupInitialIndex();
+ element.dispatchEvent(event);
+ return this;
+ },
- this._saveLastState();
+ /**
+ * @method enable
+ * @signature enable(state)
+ * @description
+ * [en]Enable or disable gesture detection.[/en]
+ * [ja]ジェスチャ検知を有効化/無効化します。[/ja]
+ * @param {Boolean} state
+ * [en]Specify if it should be enabled or not.[/en]
+ * [ja]有効にするかどうかを指定します。[/ja]
+ */
+ enable: function enable(state) {
+ this.enabled = state;
+ return this;
+ },
- // Fix rendering glitch on Android 4.1
- if (this.offsetHeight === 0) {
- setImmediate(function () {
- return _this7.refresh();
- });
- }
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'swipeable':
- this._updateSwipeable();
- break;
- case 'auto-refresh':
- this._updateAutoRefresh();
- break;
- case 'direction':
- this._onDirectionChange();
- }
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this._removeEventListeners();
- }
+ /**
+ * @method dispose
+ * @signature dispose()
+ * @description
+ * [en]Remove and destroy all event handlers for this instance.[/en]
+ * [ja]このインスタンスでのジェスチャの検知や、イベントハンドラを全て解除して廃棄します。[/ja]
+ */
+ dispose: function dispose() {
+ var i, eh;
- /**
- * @property autoScrollRatio
- * @type {Number}
- * @description
- * [en]The current auto scroll ratio. [/en]
- * [ja]現在のオートスクロールのratio値。[/ja]
- */
+ // undo all changes made by stop_browser_behavior
+ Utils.toggleBehavior(this.element, this.options.behavior, false);
- }, {
- key: 'itemCount',
- get: function get() {
- return this._getCarouselItemElements().length;
+ // unbind all custom event handlers
+ for (i = -1; eh = this.eventHandlers[++i];) {
+ // eslint-disable-line no-cond-assign
+ Utils.off(this.element, eh.gesture, eh.handler);
}
- }, {
- key: 'autoScrollRatio',
- get: function get() {
- var attr = this.getAttribute('auto-scroll-ratio');
-
- if (!attr) {
- return 0.5;
- }
- var scrollRatio = parseFloat(attr);
- if (scrollRatio < 0.0 || scrollRatio > 1.0) {
- throw new Error('Invalid ratio.');
- }
+ this.eventHandlers = [];
- return isNaN(scrollRatio) ? 0.5 : scrollRatio;
- },
- set: function set(ratio) {
- if (ratio < 0.0 || ratio > 1.0) {
- throw new Error('Invalid ratio.');
- }
+ // unbind the start event listener
+ Event.off(this.element, EVENT_TYPES[EVENT_START], this.eventStartHandler);
- this.setAttribute('auto-scroll-ratio', ratio);
- }
+ return null;
+ }
+};
- /**
- * @property swipeable
- * @type {Boolean}
- * @description
- * [en]true if the carousel is swipeable.[/en]
- * [ja]swipeableであればtrueを返します。[/ja]
- */
+/**
+ * @module gestures
+ */
+/**
+ * Move with x fingers (default 1) around on the page.
+ * Preventing the default browser behavior is a good way to improve feel and working.
+ * ````
+ * GestureDetectortime.on("drag", function(ev) {
+ * console.log(ev);
+ * ev.gesture.preventDefault();
+ * });
+ * ````
+ *
+ * @class Drag
+ * @static
+ */
+/**
+ * @event drag
+ * @param {Object} ev
+ */
+/**
+ * @event dragstart
+ * @param {Object} ev
+ */
+/**
+ * @event dragend
+ * @param {Object} ev
+ */
+/**
+ * @event drapleft
+ * @param {Object} ev
+ */
+/**
+ * @event dragright
+ * @param {Object} ev
+ */
+/**
+ * @event dragup
+ * @param {Object} ev
+ */
+/**
+ * @event dragdown
+ * @param {Object} ev
+ */
- }, {
- key: 'swipeable',
- get: function get() {
- return this.hasAttribute('swipeable');
- },
- set: function set(value) {
- return _util2.default.toggleAttribute(this, 'swipeable', value);
- }
+/**
+ * @param {String} name
+ */
+(function (name) {
+ var triggered = false;
- /**
- * @property autoScroll
- * @type {Boolean}
- * @description
- * [en]true if auto scroll is enabled.[/en]
- * [ja]オートスクロールが有効であればtrueを返します。[/ja]
- */
+ function dragGesture(ev, inst) {
+ var cur = Detection.current;
- }, {
- key: 'autoScroll',
- get: function get() {
- return this.hasAttribute('auto-scroll');
- },
- set: function set(value) {
- return _util2.default.toggleAttribute(this, 'auto-scroll', value);
+ // max touches
+ if (inst.options.dragMaxTouches > 0 && ev.touches.length > inst.options.dragMaxTouches) {
+ return;
}
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the carousel is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }, {
- key: 'disabled',
- get: function get() {
- return this.hasAttribute('disabled');
- },
- set: function set(value) {
- return _util2.default.toggleAttribute(this, 'disabled', value);
- }
+ switch (ev.eventType) {
+ case EVENT_START:
+ triggered = false;
+ break;
- /**
- * @property overscrollable
- * @type {Boolean}
- * @description
- * [en]Whether the carousel is overscrollable or not.[/en]
- * [ja]overscrollできればtrueを返します。[/ja]
- */
+ case EVENT_MOVE:
+ // when the distance we moved is too small we skip this gesture
+ // or we can be already in dragging
+ if (ev.distance < inst.options.dragMinDistance && cur.name != name) {
+ return;
+ }
- }, {
- key: 'overscrollable',
- get: function get() {
- return this.hasAttribute('overscrollable');
- },
- set: function set(value) {
- return _util2.default.toggleAttribute(this, 'overscrollable', value);
- }
+ var startCenter = cur.startEvent.center;
- /**
- * @property centered
- * @type {Boolean}
- * @description
- * [en]Whether the carousel is centered or not.[/en]
- * [ja]centered状態になっていればtrueを返します。[/ja]
- */
+ // we are dragging!
+ if (cur.name != name) {
+ cur.name = name;
+ if (inst.options.dragDistanceCorrection && ev.distance > 0) {
+ // When a drag is triggered, set the event center to dragMinDistance pixels from the original event center.
+ // Without this correction, the dragged distance would jumpstart at dragMinDistance pixels instead of at 0.
+ // It might be useful to save the original start point somewhere
+ var factor = Math.abs(inst.options.dragMinDistance / ev.distance);
+ startCenter.pageX += ev.deltaX * factor;
+ startCenter.pageY += ev.deltaY * factor;
+ startCenter.clientX += ev.deltaX * factor;
+ startCenter.clientY += ev.deltaY * factor;
- }, {
- key: 'centered',
- get: function get() {
- return this.hasAttribute('centered');
- },
- set: function set(value) {
- return _util2.default.toggleAttribute(this, 'centered', value);
- }
- }], [{
- key: 'observedAttributes',
- get: function get() {
- return ['swipeable', 'auto-refresh', 'direction'];
- }
- }, {
- key: 'events',
- get: function get() {
- return ['postchange', 'refresh', 'overscroll'];
- }
- }]);
+ // recalculate event data using new start point
+ ev = Detection.extendEventData(ev);
+ }
+ }
- return CarouselElement;
-}(_baseElement2.default);
+ // lock drag to axis?
+ if (cur.lastEvent.dragLockToAxis || inst.options.dragLockToAxis && inst.options.dragLockMinDistance <= ev.distance) {
+ ev.dragLockToAxis = true;
+ }
-exports.default = CarouselElement;
+ // keep direction on the axis that the drag gesture started on
+ var lastDirection = cur.lastEvent.direction;
+ if (ev.dragLockToAxis && lastDirection !== ev.direction) {
+ if (Utils.isVertical(lastDirection)) {
+ ev.direction = ev.deltaY < 0 ? DIRECTION_UP : DIRECTION_DOWN;
+ } else {
+ ev.direction = ev.deltaX < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
+ }
+ }
+ // first time, trigger dragstart event
+ if (!triggered) {
+ inst.trigger(name + 'start', ev);
+ triggered = true;
+ }
-customElements.define('ons-carousel', CarouselElement);
-module.exports = exports['default'];
+ // trigger events
+ inst.trigger(name, ev);
+ inst.trigger(name + ev.direction, ev);
-/***/ }),
-/* 89 */
-/***/ (function(module, exports, __webpack_require__) {
+ var isVertical = Utils.isVertical(ev.direction);
-"use strict";
+ // block the browser events
+ if (inst.options.dragBlockVertical && isVertical || inst.options.dragBlockHorizontal && !isVertical) {
+ ev.preventDefault();
+ }
+ break;
+ case EVENT_RELEASE:
+ if (triggered && ev.changedLength <= inst.options.dragMaxTouches) {
+ inst.trigger(name + 'end', ev);
+ triggered = false;
+ }
+ break;
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
+ case EVENT_END:
+ triggered = false;
+ break;
+ }
+ }
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+ GestureDetector.gestures.Drag = {
+ name: name,
+ index: 50,
+ handler: dragGesture,
+ defaults: {
+ /**
+ * minimal movement that have to be made before the drag event gets triggered
+ * @property dragMinDistance
+ * @type {Number}
+ * @default 10
+ */
+ dragMinDistance: 10,
-var _baseCheckbox = __webpack_require__(39);
+ /**
+ * Set dragDistanceCorrection to true to make the starting point of the drag
+ * be calculated from where the drag was triggered, not from where the touch started.
+ * Useful to avoid a jerk-starting drag, which can make fine-adjustments
+ * through dragging difficult, and be visually unappealing.
+ * @property dragDistanceCorrection
+ * @type {Boolean}
+ * @default true
+ */
+ dragDistanceCorrection: true,
-var _baseCheckbox2 = _interopRequireDefault(_baseCheckbox);
+ /**
+ * set 0 for unlimited, but this can conflict with transform
+ * @property dragMaxTouches
+ * @type {Number}
+ * @default 1
+ */
+ dragMaxTouches: 1,
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+ /**
+ * prevent default browser behavior when dragging occurs
+ * be careful with it, it makes the element a blocking element
+ * when you are using the drag gesture, it is a good practice to set this true
+ * @property dragBlockHorizontal
+ * @type {Boolean}
+ * @default false
+ */
+ dragBlockHorizontal: false,
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+ /**
+ * same as `dragBlockHorizontal`, but for vertical movement
+ * @property dragBlockVertical
+ * @type {Boolean}
+ * @default false
+ */
+ dragBlockVertical: false,
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+ /**
+ * dragLockToAxis keeps the drag gesture on the axis that it started on,
+ * It disallows vertical directions if the initial direction was horizontal, and vice versa.
+ * @property dragLockToAxis
+ * @type {Boolean}
+ * @default false
+ */
+ dragLockToAxis: false,
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
- 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.
- */
+ /**
+ * drag lock only kicks in when distance > dragLockMinDistance
+ * This way, locking occurs only when the distance has become large enough to reliably determine the direction
+ * @property dragLockMinDistance
+ * @type {Number}
+ * @default 25
+ */
+ dragLockMinDistance: 25
+ }
+ };
+})('drag');
-var scheme = {
- '.checkbox': 'checkbox--*',
- '.checkbox__input': 'checkbox--*__input',
- '.checkbox__checkmark': 'checkbox--*__checkmark'
+/**
+ * @module gestures
+ */
+/**
+ * trigger a simple gesture event, so you can do anything in your handler.
+ * only usable if you know what your doing...
+ *
+ * @class Gesture
+ * @static
+ */
+/**
+ * @event gesture
+ * @param {Object} ev
+ */
+GestureDetector.gestures.Gesture = {
+ name: 'gesture',
+ index: 1337,
+ handler: function releaseGesture(ev, inst) {
+ inst.trigger(this.name, ev);
+ }
};
/**
- * @element ons-checkbox
- * @category form
- * @modifier material
- * [en]Displays a Material Design checkbox.[/en]
- * [ja][/ja]
- * @modifier noborder
- * [en]iOS borderless checkbox.[/en]
- * [ja][/ja]
- * @description
- * [en]
- * A checkbox element. The component will automatically render as a Material Design checkbox on Android devices.
+ * @module gestures
+ */
+/**
+ * Touch stays at the same place for x time
*
- * Most attributes that can be used for a normal `` element can also be used on the `` element.
- * [/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/input
- * @seealso ons-switch
- * [en]The `` element is used to display a draggable toggle switch.[/en]
- * [ja][/ja]
- * @seealso ons-radio
- * [en]The `` element is used to display a radio button.[/en]
- * [ja][/ja]
- * @seealso ons-input
- * [en]The `` element is used to display a text input.[/en]
- * [ja][/ja]
- * @seealso ons-search-input
- * [en]The `` element is used to display a search input.[/en]
- * [ja][/ja]
- * @seealso ons-range
- * [en]The `` element is used to display a range slider.[/en]
- * [ja][/ja]
- * @seealso ons-select
- * [en]The `` element is used to display a select box.[/en]
- * [ja][/ja]
- * @guide adding-page-content
- * [en]Using form components[/en]
- * [ja]フォームを使う[/ja]
- * @guide using-modifier [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @example
- *
+ * @class Hold
+ * @static
+ */
+/**
+ * @event hold
+ * @param {Object} ev
*/
-var CheckboxElement = function (_BaseCheckboxElement) {
- _inherits(CheckboxElement, _BaseCheckboxElement);
+/**
+ * @param {String} name
+ */
+(function (name) {
+ var timer;
- function CheckboxElement() {
- _classCallCheck(this, CheckboxElement);
+ function holdGesture(ev, inst) {
+ var options = inst.options,
+ current = Detection.current;
- return _possibleConstructorReturn(this, (CheckboxElement.__proto__ || Object.getPrototypeOf(CheckboxElement)).apply(this, arguments));
- }
+ switch (ev.eventType) {
+ case EVENT_START:
+ clearTimeout(timer);
- _createClass(CheckboxElement, [{
- key: '_scheme',
- get: function get() {
- return scheme;
- }
- }, {
- key: '_defaultElementClass',
- get: function get() {
- return 'checkbox';
+ // set the gesture so we can check in the timeout if it still is
+ current.name = name;
+
+ // set timer and if after the timeout it still is hold,
+ // we trigger the hold event
+ timer = setTimeout(function () {
+ if (current && current.name == name) {
+ inst.trigger(name, ev);
+ }
+ }, options.holdTimeout);
+ break;
+
+ case EVENT_MOVE:
+ if (ev.distance > options.holdThreshold) {
+ clearTimeout(timer);
+ }
+ break;
+
+ case EVENT_RELEASE:
+ clearTimeout(timer);
+ break;
}
- }, {
- key: 'type',
- get: function get() {
- return 'checkbox';
+ }
+
+ GestureDetector.gestures.Hold = {
+ name: name,
+ index: 10,
+ defaults: {
+ /**
+ * @property holdTimeout
+ * @type {Number}
+ * @default 500
+ */
+ holdTimeout: 500,
+
+ /**
+ * movement allowed while holding
+ * @property holdThreshold
+ * @type {Number}
+ * @default 2
+ */
+ holdThreshold: 2
+ },
+ handler: holdGesture
+ };
+})('hold');
+
+/**
+ * @module gestures
+ */
+/**
+ * when a touch is being released from the page
+ *
+ * @class Release
+ * @static
+ */
+/**
+ * @event release
+ * @param {Object} ev
+ */
+GestureDetector.gestures.Release = {
+ name: 'release',
+ index: Infinity,
+ handler: function releaseGesture(ev, inst) {
+ if (ev.eventType == EVENT_RELEASE) {
+ inst.trigger(this.name, ev);
}
+ }
+};
+/**
+ * @module gestures
+ */
+/**
+ * triggers swipe events when the end velocity is above the threshold
+ * for best usage, set `preventDefault` (on the drag gesture) to `true`
+ * ````
+ * GestureDetectortime.on("dragleft swipeleft", function(ev) {
+ * console.log(ev);
+ * ev.gesture.preventDefault();
+ * });
+ * ````
+ *
+ * @class Swipe
+ * @static
+ */
+/**
+ * @event swipe
+ * @param {Object} ev
+ */
+/**
+ * @event swipeleft
+ * @param {Object} ev
+ */
+/**
+ * @event swiperight
+ * @param {Object} ev
+ */
+/**
+ * @event swipeup
+ * @param {Object} ev
+ */
+/**
+ * @event swipedown
+ * @param {Object} ev
+ */
+GestureDetector.gestures.Swipe = {
+ name: 'swipe',
+ index: 40,
+ defaults: {
/**
- * @attribute input-id
- * @type {String}
- * @description
- * [en]Specify the "id" attribute of the inner `` element. This is useful when using `