jellyfin-web/dashboard-ui/thirdparty/jquerymobile-1.4.5/jqm.panel.js

531 lines
19 KiB
JavaScript
Raw Normal View History

2015-12-14 08:43:03 -07:00
define(['jqmwidget'], function () {
(function ($, undefined) {
var props = {
"animation": {},
"transition": {}
2015-09-05 11:05:29 -07:00
},
2015-12-14 08:43:03 -07:00
testElement = document.createElement("a"),
vendorPrefixes = ["", "webkit-", "moz-", "o-"];
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
$.each(["animation", "transition"], function (i, test) {
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
// Get correct name for test
var testName = (i === 0) ? test + "-" + "name" : test;
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
$.each(vendorPrefixes, function (j, prefix) {
if (testElement.style[$.camelCase(prefix + testName)] !== undefined) {
props[test]["prefix"] = prefix;
return false;
}
});
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
// Set event and duration names for later use
props[test]["duration"] =
$.camelCase(props[test]["prefix"] + test + "-" + "duration");
props[test]["event"] =
$.camelCase(props[test]["prefix"] + test + "-" + "end");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
// All lower case if not a vendor prop
if (props[test]["prefix"] === "") {
props[test]["event"] = props[test]["event"].toLowerCase();
}
});
// Remove the testElement
$(testElement).remove();
// Animation complete callback
$.fn.animationComplete = function (callback, type, fallbackTime) {
var timer, duration,
that = this,
eventBinding = function () {
// Clear the timer so we don't call callback twice
clearTimeout(timer);
callback.apply(this, arguments);
},
animationType = (!type || type === "animation") ? "animation" : "transition";
// If a fallback time was not passed set one
if (fallbackTime === undefined) {
// Make sure the was not bound to document before checking .css
if ($(this).context !== document) {
// Parse the durration since its in second multiple by 1000 for milliseconds
// Multiply by 3 to make sure we give the animation plenty of time.
duration = parseFloat(
$(this).css(props[animationType].duration)
) * 3000;
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
// If we could not read a duration use the default
if (duration === 0 || duration === undefined || isNaN(duration)) {
duration = $.fn.animationComplete.defaultDuration;
}
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
// Sets up the fallback if event never comes
timer = setTimeout(function () {
$(that).off(props[animationType].event, eventBinding);
callback.apply(that);
}, duration);
// Bind the event
return $(this).one(props[animationType].event, eventBinding);
};
// Allow default callback to be configured on mobileInit
$.fn.animationComplete.defaultDuration = 1000;
})(jQuery);
(function ($, undefined) {
$.widget("mobile.panel", {
options: {
animate: true,
theme: null,
position: "left",
dismissible: true,
display: "overlay", //accepts reveal, push, overlay
swipeClose: true,
positionFixed: true
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_parentPage: null,
_page: null,
_modal: null,
_panelInner: null,
_wrapper: null,
_create: function () {
var el = this.element,
parentPage = el.closest(".ui-page, [data-role='page']");
// expose some private props to other methods
$.extend(this, {
_parentPage: (parentPage.length > 0) ? parentPage : false,
_openedPage: null,
_page: this._getPage,
_panelInner: this._getPanelInner()
});
if (this.options.display !== "overlay") {
this._getWrapper();
}
this._addPanelClasses();
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
// if animating, add the class to do so
if (!!this.options.animate) {
this.element.addClass("ui-panel-animate");
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
this._bindUpdateLayout();
this._bindCloseEvents();
this._bindLinkListeners();
this._bindPageEvents();
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (!!this.options.dismissible) {
this._createModal();
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
this._bindSwipeEvents();
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_getPanelInner: function () {
var panelInner = this.element[0].querySelector("." + "ui-panel-inner");
if (!panelInner) {
panelInner = this.element.children().wrapAll("<div class='" + "ui-panel-inner" + "' />").parent();
} else {
panelInner = $(panelInner);
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
return panelInner;
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_createModal: function () {
var self = this,
target = self._parentPage ? self._parentPage.parent() : self.element.parent();
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self._modal = $("<div class='" + "ui-panel-dismiss" + "'></div>")
.on("mousedown", function () {
self.close();
})
.appendTo(target);
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_getPage: function () {
var page = this._openedPage || this._parentPage || $(".ui-page-active");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
return page;
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_getWrapper: function () {
var wrapper = this._page().find("." + "ui-panel-wrapper");
if (wrapper.length === 0) {
wrapper = this._page().children(".ui-header:not(.ui-header-fixed), .ui-content:not(.ui-popup), .ui-footer:not(.ui-footer-fixed)")
.wrapAll("<div class='" + "ui-panel-wrapper" + "'></div>")
.parent();
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
this._wrapper = wrapper;
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_getPosDisplayClasses: function (prefix) {
return prefix + "-position-right " + prefix + "-display-" + this.options.display;
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_getPanelClasses: function () {
var panelClasses = "ui-panel" +
" " + this._getPosDisplayClasses("ui-panel") +
" " + "ui-panel-closed" +
" " + "ui-body-" + (this.options.theme ? this.options.theme : "inherit");
if (!!this.options.positionFixed) {
panelClasses += " " + "ui-panel-fixed";
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
return panelClasses;
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_addPanelClasses: function () {
this.element.addClass(this._getPanelClasses());
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_handleCloseClick: function (event) {
if (!event.isDefaultPrevented()) {
this.close();
}
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_bindCloseEvents: function () {
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_positionPanel: function (scrollToTop) {
var self = this,
panelInnerHeight = self._panelInner.outerHeight(),
expand = panelInnerHeight > (window.innerHeight || $(window).height());
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (expand || !self.options.positionFixed) {
if (expand) {
self._unfixPanel();
}
if (scrollToTop) {
this.window[0].scrollTo(0, $.mobile.defaultHomeScroll);
}
} else {
self._fixPanel();
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_bindFixListener: function () {
this._on($(window), { "resize": "_positionPanel" });
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_unbindFixListener: function () {
this._off($(window), "resize");
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_unfixPanel: function () {
if (!!this.options.positionFixed) {
this.element.removeClass("ui-panel-fixed");
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_fixPanel: function () {
if (!!this.options.positionFixed) {
this.element.addClass("ui-panel-fixed");
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_bindUpdateLayout: function () {
var self = this;
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self.element.on("updatelayout", function (/* e */) {
2015-09-05 11:05:29 -07:00
if (self._open) {
2015-12-14 08:43:03 -07:00
self._positionPanel();
2015-09-05 11:05:29 -07:00
}
});
2015-12-14 08:43:03 -07:00
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_bindLinkListeners: function () {
this._on("body", {
"click a": "_handleClick"
});
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_handleClick: function (e) {
var link,
panelId = this.element.attr("id");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (e.currentTarget.href.split("#")[1] === panelId && panelId !== undefined) {
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
e.preventDefault();
link = $(e.target);
if (link.hasClass("ui-btn")) {
link.addClass($.mobile.activeBtnClass);
this.element.one("panelopen panelclose", function () {
link.removeClass($.mobile.activeBtnClass);
});
}
this.toggle();
}
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_bindSwipeEvents: function () {
var self = this,
area = self._modal ? self.element.add(self._modal) : self.element;
// on swipe, close the panel
if (!!self.options.swipeClose) {
if (self.options.position === "left") {
area.on("swipeleft.panel", function (/* e */) {
self.close();
});
} else {
area.on("swiperight.panel", function (/* e */) {
self.close();
});
}
}
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_bindPageEvents: function () {
var self = this;
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
this.document
// Close the panel if another panel on the page opens
.on("panelbeforeopen", function (e) {
if (self._open && e.target !== self.element[0]) {
self.close();
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
})
// On escape, close? might need to have a target check too...
.on("keyup.panel", function (e) {
if (e.keyCode === 27 && self._open) {
self.close();
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
});
if (!this._parentPage && this.options.display !== "overlay") {
this._on(this.document, {
"pageshow": function () {
this._openedPage = null;
this._getWrapper();
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
});
}
// Clean up open panels after page hide
if (self._parentPage) {
this.document.on("pagehide", "[data-role='page']", function () {
if (self._open) {
self.close(true);
2015-09-05 11:05:29 -07:00
}
});
} else {
2015-12-14 08:43:03 -07:00
this.document.on("pagebeforehide", function () {
if (self._open) {
self.close(true);
}
});
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
// state storage of open or closed
_open: false,
_pageContentOpenClasses: null,
_modalOpenClasses: null,
open: function (immediate) {
if (!this._open) {
var self = this,
o = self.options,
_openPanel = function () {
self._off(self.document, "panelclose");
self._page().data("panel", "open");
if (!!o.animate && o.display !== "overlay") {
self._wrapper.addClass("ui-panel-animate");
}
if (!immediate && !!o.animate) {
(self._wrapper || self.element)
.animationComplete(complete, "transition");
} else {
setTimeout(complete, 0);
}
if (o.theme && o.display !== "overlay") {
self._page().parent()
.addClass("ui-panel-page-container" + "-themed " + "ui-panel-page-container" + "-" + o.theme);
}
self.element
.removeClass("ui-panel-closed")
.addClass("ui-panel-open");
self._positionPanel(true);
self._pageContentOpenClasses = self._getPosDisplayClasses("ui-panel-page-content");
if (o.display !== "overlay") {
self._page().parent().addClass("ui-panel-page-container");
self._wrapper.addClass(self._pageContentOpenClasses);
}
self._modalOpenClasses = self._getPosDisplayClasses("ui-panel-dismiss") + " " + "ui-panel-dismiss-open";
if (self._modal) {
self._modal
.addClass(self._modalOpenClasses)
.height(Math.max(self._modal.height(), self.document.height()));
}
},
complete = function () {
// Bail if the panel was closed before the opening animation has completed
if (!self._open) {
return;
}
if (o.display !== "overlay") {
self._wrapper.addClass("ui-panel-page-content" + "-open");
}
self._bindFixListener();
self._trigger("open");
self._openedPage = self._page();
};
self._trigger("beforeopen");
if (self._page().data("panel") === "open") {
self._on(self.document, {
"panelclose": _openPanel
});
} else {
_openPanel();
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self._open = true;
}
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
close: function (immediate) {
if (this._open) {
var self = this,
o = this.options,
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_closePanel = function () {
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self.element.removeClass("ui-panel-open");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (o.display !== "overlay") {
self._wrapper.removeClass(self._pageContentOpenClasses);
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (!immediate && !!o.animate) {
(self._wrapper || self.element)
.animationComplete(complete, "transition");
} else {
setTimeout(complete, 0);
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (self._modal) {
self._modal
.removeClass(self._modalOpenClasses)
.height("");
}
},
complete = function () {
if (o.theme && o.display !== "overlay") {
self._page().parent().removeClass("ui-panel-page-container" + "-themed " + "ui-panel-page-container" + "-" + o.theme);
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self.element.addClass("ui-panel-closed");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (o.display !== "overlay") {
self._page().parent().removeClass("ui-panel-page-container");
self._wrapper.removeClass("ui-panel-page-content" + "-open");
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (!!o.animate && o.display !== "overlay") {
self._wrapper.removeClass("ui-panel-animate");
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self._fixPanel();
self._unbindFixListener();
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self._page().removeData("panel");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self._trigger("close");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self._openedPage = null;
};
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self._trigger("beforeclose");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_closePanel();
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
self._open = false;
}
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
toggle: function () {
this[this._open ? "close" : "open"]();
},
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
_destroy: function () {
var otherPanels,
o = this.options,
multiplePanels = ($("body > :mobile-panel").length + $.mobile.activePage.find(":mobile-panel").length) > 1;
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (o.display !== "overlay") {
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
// remove the wrapper if not in use by another panel
otherPanels = $("body > :mobile-panel").add($.mobile.activePage.find(":mobile-panel"));
if (otherPanels.not(".ui-panel-display-overlay").not(this.element).length === 0) {
this._wrapper.children().unwrap();
}
if (this._open) {
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
this._page().parent().removeClass("ui-panel-page-container");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (o.theme) {
this._page().parent().removeClass("ui-panel-page-container" + "-themed " + "ui-panel-page-container" + "-" + o.theme);
}
2015-09-05 11:05:29 -07:00
}
}
2015-12-14 08:43:03 -07:00
if (!multiplePanels) {
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
this.document.off("panelopen panelclose");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (this._open) {
this._page().removeData("panel");
}
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
this._panelInner.children().unwrap();
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
this.element
.removeClass([this._getPanelClasses(), "ui-panel-open", "ui-panel-animate"].join(" "))
.off("swipeleft.panel swiperight.panel")
.off("panelbeforeopen")
.off("panelhide")
.off("keyup.panel")
.off("updatelayout");
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
if (this._modal) {
this._modal.remove();
}
2015-09-05 11:05:29 -07:00
}
2015-12-14 08:43:03 -07:00
});
})(jQuery);
2015-09-05 11:05:29 -07:00
2015-12-14 08:43:03 -07:00
});