@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
JavaScript
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;
;