UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

872 lines (710 loc) 30.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); require('./kendo.core.js'); require('./kendo.licensing.js'); require('@progress/kendo-licensing'); const __meta__ = { id: "popup", name: "Pop-up", category: "framework", depends: [ "core" ], advanced: true }; (function($, undefined$1) { var kendo = window.kendo, ui = kendo.ui, Widget = ui.Widget, Class = kendo.Class, support = kendo.support, getOffset = kendo.getOffset, outerWidth = kendo._outerWidth, outerHeight = kendo._outerHeight, OPEN = "open", CLOSE = "close", DEACTIVATE = "deactivate", ACTIVATE = "activate", CENTER = "center", LEFT = "left", RIGHT = "right", TOP = "top", BOTTOM = "bottom", ABSOLUTE = "absolute", HIDDEN = "hidden", BODY = "body", LOCATION = "location", POSITION = "position", VISIBLE = "visible", EFFECTS = "effects", ACTIVE = "k-active", ACTIVECHILDREN = ".k-picker-wrap, .k-dropdown-wrap, .k-link", MOUSEDOWN = "down", DOCUMENT_ELEMENT = $(document.documentElement), WINDOW = $(window), SCROLL = "scroll", TRANSFORM = "transform", extend = $.extend, NS = ".kendoPopup", styles = ["font-size", "font-family", "font-stretch", "font-style", "font-weight", "line-height"]; function contains(container, target) { if (!container || !target) { return false; } return container === target || $.contains(container, target); } var Popup = Widget.extend({ init: function(element, options) { var that = this, parentPopup; options = options || {}; if (options.isRtl) { options.origin = options.origin || BOTTOM + " " + RIGHT; options.position = options.position || TOP + " " + RIGHT; } Widget.fn.init.call(that, element, options); element = that.element; options = that.options; that.collisions = options.collision ? options.collision.split(" ") : []; that.downEvent = kendo.applyEventMap(MOUSEDOWN, kendo.guid()); if (that.collisions.length === 1) { that.collisions.push(that.collisions[0]); } parentPopup = $(that.options.anchor).closest(".k-popup,.k-group,.k-menu-group").filter(":not([class^=km-])"); // When popup is in another popup, make it relative. options.appendTo = $($(options.appendTo)[0] || parentPopup[0] || document.body); that.element.hide() .addClass("k-popup") .toggleClass("k-rtl", !!options.isRtl) .appendTo(options.appendTo) .attr("aria-hidden", true) .on("mouseenter" + NS, function() { that._hovered = true; }) .on("wheel" + NS, function(e) { var list = $(e.target).find(".k-list"); var scrollArea = list.parent(); if (list.length && list.is(":visible") && ((scrollArea.scrollTop() === 0 && e.originalEvent.deltaY < 0) || (scrollArea.scrollTop() === scrollArea.prop('scrollHeight') - scrollArea.prop('offsetHeight') && e.originalEvent.deltaY > 0))) { e.preventDefault(); } }) .on("mouseleave" + NS, function() { that._hovered = false; }); that.wrapper = $(); if (options.animation === false) { options.animation = { open: { effects: {} }, close: { hide: true, effects: {} } }; } extend(options.animation.open, { complete: function() { that.wrapper.addClass("k-animation-container-shown"); // Forcing refresh causes flickering in mobile. that.wrapper.css("overflow",""); that._activated = true; that._trigger(ACTIVATE); } }); extend(options.animation.close, { complete: function() { that._animationClose(); } }); that._mousedownProxy = function(e) { that._mousedown(e); }; if (support.mobileOS.android) { that._resizeProxy = function(e) { setTimeout(function() { that._resize(e); }, 600); //Logic from kendo.onResize }; } else { that._resizeProxy = function(e) { that._resize(e); }; } if (options.toggleTarget) { $(options.toggleTarget).on(options.toggleEvent + NS, that.toggle.bind(that)); } }, events: [ OPEN, ACTIVATE, CLOSE, DEACTIVATE ], options: { name: "Popup", toggleEvent: "click", origin: BOTTOM + " " + LEFT, position: TOP + " " + LEFT, anchor: BODY, appendTo: null, collision: "flip fit", viewport: window, copyAnchorStyles: true, autosize: false, autowidth: false, modal: false, adjustSize: { width: 0, height: 0 }, animation: { open: { effects: "slideIn:down", transition: true, duration: 200 }, close: { // if close animation effects are defined, they will be used instead of open.reverse duration: 100, hide: true } }, omitOriginOffsets: false }, _animationClose: function() { var that = this; var location = that.wrapper.data(LOCATION); that.wrapper.hide(); if (location) { that.wrapper.css(location); } if (that.options.anchor != BODY) { that._hideActiveClass(); } that._closing = false; that._trigger(DEACTIVATE); }, destroy: function() { var that = this, options = that.options, element = that.element.off(NS), parent; Widget.fn.destroy.call(that); if (options.toggleTarget) { $(options.toggleTarget).off(NS); } if (!options.modal) { DOCUMENT_ELEMENT.off(that.downEvent, that._mousedownProxy); that._toggleResize(false); } kendo.destroy(that.element.children()); element.removeData(); if (options.appendTo[0] === document.body) { parent = element.closest(".k-animation-container"); if (parent[0]) { parent.remove(); } else { element.remove(); } } }, open: function(x, y) { var that = this, fixed = { isFixed: !isNaN(parseInt(y,10)), x: x, y: y }, shouldCorrectWidth = that._shouldCorrectWidth, element = that.element, options = that.options, animation, wrapper, anchor = $(options.anchor), mobile = element[0] && element.hasClass("km-widget"), listbox = element.find("[role='listbox']"), parent; if (!that.visible()) { if (options.copyAnchorStyles) { if (mobile && styles[0] == "font-size") { styles.shift(); } element.css(kendo.getComputedStyles(anchor[0], styles)); } if (that.element.parent().data("animating") || that._trigger(OPEN)) { return; } that._activated = false; if (!options.modal) { DOCUMENT_ELEMENT.off(that.downEvent, that._mousedownProxy) .on(that.downEvent, that._mousedownProxy); // this binding hangs iOS in editor // all elements in IE7/8 fire resize event, causing mayhem that._toggleResize(false); that._toggleResize(true); } that.wrapper = wrapper = kendo.wrap(element, options.autosize, options._resizeOnWrap, shouldCorrectWidth, options.autowidth) .css({ overflow: HIDDEN, display: "block", position: ABSOLUTE }) .attr("aria-hidden", false); parent = element.parent(); if (listbox.attr("aria-label")) { wrapper.attr("aria-label", listbox.attr("aria-label")); } else if (listbox.attr("aria-labelledby")) { wrapper.attr("aria-labelledby", listbox.attr("aria-labelledby")); } if (support.mobileOS.android) { parent.css(TRANSFORM, "translatez(0)"); // Android is VERY slow otherwise. Should be tested in other droids as well since it may cause blur. } wrapper.css(POSITION); if ($(options.appendTo)[0] == document.body) { wrapper.css(TOP, "-10000px"); } that.flipped = that._position(fixed); animation = that._openAnimation(); if (options.anchor != BODY && !that.element.hasClass("k-tooltip")) { that._addActiveClass(); } parent.hide(); element.show(); that.wrapper.show(); parent.data(EFFECTS, animation.effects) .kendoStop(true) .kendoAnimate(animation); element.attr("aria-hidden", false); } }, _updateDimensions: function() { const that = this; const shouldCorrectWidth = that._shouldCorrectWidth; const element = that.element; const options = that.options; that.wrapper = kendo.wrap(element, options.autosize, options._resizeOnWrap, shouldCorrectWidth, options.autowidth) .css({ overflow: HIDDEN, display: "block", position: ABSOLUTE }) .attr("aria-hidden", false); }, _location: function(isFixed) { var that = this, element = that.element, options = that.options, wrapper, anchor = $(options.anchor), mobile = element[0] && element.hasClass("km-widget"); if (options.copyAnchorStyles) { if (mobile && styles[0] == "font-size") { styles.shift(); } element.css(kendo.getComputedStyles(anchor[0], styles)); } that.wrapper = wrapper = kendo.wrap(element, options.autosize) .css({ overflow: HIDDEN, display: "block", position: ABSOLUTE }); if (support.mobileOS.android) { wrapper.css(TRANSFORM, "translatez(0)"); // Android is VERY slow otherwise. Should be tested in other droids as well since it may cause blur. } wrapper.css(POSITION); if ($(options.appendTo)[0] == document.body) { wrapper.css(TOP, "-10000px"); } that._position(isFixed || {}); var offset = wrapper.offset(); return { width: kendo._outerWidth(wrapper), height: kendo._outerHeight(wrapper), left: offset.left, top: offset.top }; }, _openAnimation: function() { var animation = extend(true, {}, this.options.animation.open); animation.effects = kendo.parseEffects(animation.effects, this.flipped); return animation; }, _hideActiveClass: function() { var anchor = $(this.options.anchor); anchor .children(ACTIVECHILDREN) .removeClass(ACTIVE); }, _addActiveClass: function() { $(this.options.anchor) .children(ACTIVECHILDREN) .addClass(ACTIVE); }, position: function() { if (this.visible()) { this._updateDimensions(); this.flipped = this._position(); } }, toggle: function() { var that = this; that[that.visible() ? CLOSE : OPEN](); }, visible: function() { return this.wrapper.is(":" + VISIBLE) && this.element.is(":" + VISIBLE); }, close: function(skipEffects) { var that = this, parent = that.element.parent(), options = that.options, wrap, animation, openEffects, closeEffects; if (that.visible()) { wrap = (that.wrapper[0] ? that.wrapper : kendo.wrap(that.element).hide()); that._toggleResize(false); if (that._closing || that._trigger(CLOSE)) { that._toggleResize(true); return; } that.wrapper.removeClass("k-animation-container-shown"); // Close all inclusive popups. that.element.find(".k-popup").each(function() { var that = $(this), popup = that.data("kendoPopup"); if (popup) { popup.close(skipEffects); } }); DOCUMENT_ELEMENT.off(that.downEvent, that._mousedownProxy); if (skipEffects) { animation = { hide: true, effects: {} }; } else { animation = extend(true, {}, options.animation.close); openEffects = parent.data(EFFECTS); closeEffects = animation.effects; if (!closeEffects && !kendo.size(closeEffects) && openEffects && kendo.size(openEffects)) { animation.effects = openEffects; animation.reverse = true; } that._closing = true; } parent.kendoStop(true); that.element.attr("aria-hidden", true); wrap .css({ overflow: HIDDEN }) // stop callback will remove hidden overflow .attr("aria-hidden", true); parent.kendoAnimate(animation); if (skipEffects) { that._animationClose(); } } }, _trigger: function(ev) { return this.trigger(ev, { type: ev }); }, _resize: function(e) { var that = this; if (support.resize.indexOf(e.type) !== -1) { clearTimeout(that._resizeTimeout); that._resizeTimeout = setTimeout(function() { that._position(); that._resizeTimeout = null; }, 50); } else { if (!that._hovered || (that._activated && that.element.find(".k-list").length > 0)) { that.close(); } } }, _toggleResize: function(toggle) { var method = toggle ? "on" : "off"; var eventNames = support.resize; if (!(support.mobileOS.ios || support.mobileOS.android || support.browser.safari)) { eventNames += " " + SCROLL; } if (toggle && !this.scrollableParents) { this.scrollableParents = this._scrollableParents(); } if (this.scrollableParents && this.scrollableParents.length) { this.scrollableParents[method](SCROLL, this._resizeProxy); } WINDOW[method](eventNames, this._resizeProxy); }, _mousedown: function(e) { var that = this, container = that.element[0], options = that.options, anchor = $(options.anchor)[0], toggleTarget = options.toggleTarget, target = kendo.eventTarget(e), popup = $(target).closest(".k-popup"), mobile = popup.parent().parent(".km-shim").length; popup = popup[0]; if (!mobile && popup && popup !== that.element[0]) { return; } // This MAY result in popup not closing in certain cases. if ($(e.target).closest("a").data("rel") === "popover") { return; } if (!contains(container, target) && !contains(anchor, target) && !(toggleTarget && contains($(toggleTarget)[0], target))) { that.close(); } }, _fit: function(position, size, viewPortSize) { var output = 0; if (position + size > viewPortSize) { output = viewPortSize - (position + size); } if (position < 0) { output = -position; } return output; }, _flip: function(offset, size, anchorSize, viewPortSize, origin, position, boxSize) { var output = 0; boxSize = boxSize || size; if (position !== origin && position !== CENTER && origin !== CENTER) { if (offset + boxSize > viewPortSize) { output += -(anchorSize + size); } if (offset + output < 0) { output += anchorSize + size; } } return output; }, _scrollableParents: function() { return $(this.options.anchor) .parentsUntil("body") .filter(function(index, element) { return kendo.isScrollable(element); }); }, _position: function(fixed) { var that = this, //element = that.element.css(POSITION, ""), /* fixes telerik/kendo-ui-core#790, comes from telerik/kendo#615 */ element = that.element, wrapper = that.wrapper, options = that.options, viewport = $(options.viewport), zoomLevel = support.zoomLevel(), isWindow = !!((viewport[0] == window) && window.innerWidth && (zoomLevel <= 1.02)), anchor = $(options.anchor), origins = options.origin.toLowerCase().split(" "), positions = options.position.toLowerCase().split(" "), collisions = that.collisions, siblingContainer, parents, parentZIndex, zIndex = 10002, idx = 0, docEl = document.documentElement, length, viewportOffset, viewportWidth, viewportHeight; if (options.viewport === window) { viewportOffset = { top: (window.pageYOffset || document.documentElement.scrollTop || 0), left: (window.pageXOffset || document.documentElement.scrollLeft || 0) }; } else { viewportOffset = viewport.offset(); } if (isWindow) { viewportWidth = window.innerWidth; viewportHeight = window.innerHeight; } else { viewportWidth = viewport.width(); viewportHeight = viewport.height(); } if (isWindow && docEl.scrollHeight - docEl.clientHeight > 0) { var sign = options.isRtl ? -1 : 1; viewportWidth -= sign * kendo.support.scrollbar(); } siblingContainer = anchor.parents().filter(wrapper.siblings()); if (siblingContainer[0]) { parentZIndex = Math.max(Number(siblingContainer.css("zIndex")), 0); // set z-index to be more than that of the container/sibling // compensate with more units for window z-stack if (parentZIndex) { zIndex = parentZIndex + 10; } else { parents = anchor.parentsUntil(siblingContainer); for (length = parents.length; idx < length; idx++) { parentZIndex = Number($(parents[idx]).css("zIndex")); if (parentZIndex && zIndex < parentZIndex) { zIndex = parentZIndex + 10; } } } } wrapper.css("zIndex", zIndex); if (fixed && fixed.isFixed) { wrapper.css({ left: fixed.x, top: fixed.y }); } else { wrapper.css(that._align(origins, positions)); } var pos = getOffset(wrapper, POSITION, anchor[0] === wrapper.offsetParent()[0]), offset = getOffset(wrapper), anchorParent = anchor.offsetParent().parent(".k-animation-container,.k-popup,.k-group,.k-menu-group"); // If the parent is positioned, get the current positions if (anchorParent.length) { pos = getOffset(wrapper, POSITION, true); offset = getOffset(wrapper); } offset.top -= viewportOffset.top; offset.left -= viewportOffset.left; if (!that.wrapper.data(LOCATION)) { // Needed to reset the popup location after every closure - fixes the resize bugs. wrapper.data(LOCATION, extend({}, pos)); } var offsets = extend({}, offset), location = extend({}, pos), adjustSize = options.adjustSize; if (collisions[0] === "fit") { location.top += that._fit(offsets.top, outerHeight(wrapper) + adjustSize.height, viewportHeight / zoomLevel); } if (collisions[1] === "fit") { location.left += that._fit(offsets.left, outerWidth(wrapper) + adjustSize.width, viewportWidth / zoomLevel); } var flipPos = extend({}, location); var elementHeight = outerHeight(element); var wrapperHeight = outerHeight(wrapper); if (!wrapper.height() && elementHeight) { wrapperHeight = wrapperHeight + elementHeight; } if (collisions[0] === "flip") { location.top += that._flip(offsets.top, elementHeight, outerHeight(anchor), viewportHeight / zoomLevel, origins[0], positions[0], wrapperHeight); } if (collisions[1] === "flip") { location.left += that._flip(offsets.left, outerWidth(element), outerWidth(anchor), viewportWidth / zoomLevel, origins[1], positions[1], outerWidth(wrapper)); } wrapper.css(location); return (location.left != flipPos.left || location.top != flipPos.top); }, _align: function(origin, position) { var that = this, element = that.wrapper, anchor = $(that.options.anchor), verticalOrigin = origin[0], horizontalOrigin = origin[1], verticalPosition = position[0], horizontalPosition = position[1], anchorOffset = getOffset(anchor), appendTo = $(that.options.appendTo), appendToOffset, width = outerWidth(element) || outerWidth(element.find(".k-child-animation-container").children().first()), height = outerHeight(element) || outerHeight(element.find(".k-child-animation-container").children().first()), anchorWidth = outerWidth(anchor), anchorHeight = outerHeight(anchor), top = that.options.omitOriginOffsets ? 0 : anchorOffset.top, left = that.options.omitOriginOffsets ? 0 : anchorOffset.left, round = Math.round; if (appendTo[0] != document.body) { appendToOffset = getOffset(appendTo); top -= appendToOffset.top; left -= appendToOffset.left; } if (verticalOrigin === BOTTOM) { top += anchorHeight; } if (verticalOrigin === CENTER) { top += round(anchorHeight / 2); } if (verticalPosition === BOTTOM) { top -= height; } if (verticalPosition === CENTER) { top -= round(height / 2); } if (horizontalOrigin === RIGHT) { left += anchorWidth; } if (horizontalOrigin === CENTER) { left += round(anchorWidth / 2); } if (horizontalPosition === RIGHT) { left -= width; } if (horizontalPosition === CENTER) { left -= round(width / 2); } return { top: top, left: left }; } }); ui.plugin(Popup); var stableSort = kendo.support.stableSort; var tabKeyTrapNS = "kendoTabKeyTrap"; var focusableNodesSelector = "a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex], *[contenteditable]"; var TabKeyTrap = Class.extend({ init: function(element, options) { this.element = $(element); this.element.autoApplyNS(tabKeyTrapNS); }, trap: function() { this.element.on("keydown", this._keepInTrap.bind(this)); }, removeTrap: function() { this.element.kendoDestroy(tabKeyTrapNS); }, destroy: function() { this.element.kendoDestroy(tabKeyTrapNS); this.element = undefined$1; }, shouldTrap: function() { return true; }, _keepInTrap: function(e) { if (e.which !== 9 || !this.shouldTrap() || e.isDefaultPrevented()) { return; } var elements = this._focusableElements(); var sortedElements = this._sortFocusableElements(elements); var next = this._nextFocusable(e, sortedElements); if (next) { this._focus(next); } e.preventDefault(); }, _focusableElements: function() { var elements = this.element.find(focusableNodesSelector).filter(function(i, item) { return item.tabIndex >= 0 && $(item).is(':visible') && !$(item).is('[disabled]'); }); if (this.element.is("[tabindex]")) { [].push.call(elements, this.element[0]); } return elements; }, _sortFocusableElements: function(elements) { var sortedElements; if (stableSort) { sortedElements = [].sort.call(elements, function(prev, next) { return prev.tabIndex - next.tabIndex; }); } else { var attrName = "__k_index"; elements.each(function(i, item) { item.setAttribute(attrName, i); }); sortedElements = [].sort.call(elements, function(prev, next) { return prev.tabIndex === next.tabIndex ? parseInt(prev.getAttribute(attrName), 10) - parseInt(next.getAttribute(attrName), 10) : prev.tabIndex - next.tabIndex; }); elements.removeAttr(attrName); } return sortedElements; }, _nextFocusable: function(e, elements) { var count = elements.length; var current = elements.index(e.target); return elements.get((current + (e.shiftKey ? -1 : 1)) % count); }, _focus: function(element) { if (element.nodeName == "IFRAME") { element.contentWindow.document.body.focus(); return; } element.focus(); if (element.nodeName == "INPUT" && element.setSelectionRange && this._haveSelectionRange(element)) { element.setSelectionRange(0, element.value.length); } }, _haveSelectionRange: function(element) { var elementType = element.type.toLowerCase(); return elementType === "text" || elementType === "search" || elementType === "url" || elementType === "tel" || elementType === "password"; } }); ui.Popup.TabKeyTrap = TabKeyTrap; })(window.kendo.jQuery); var kendo$1 = kendo; exports.__meta__ = __meta__; exports.default = kendo$1;