');
- // append tooltip (jsPanel) to the wrapper div
- jsP.parentElmt.parent().append(jsP);
- if (jsP.option.paneltype.mode === 'semisticky') {
- jsP.hover(
- function () {
- $.noop();
- },
- function () {
- jsPanel.close(jsP);
- }
- );
- } else if (jsP.option.paneltype.mode === 'sticky') {
- $.noop();
- } else {
- jsP.option.controls.buttons = 'none';
- // tooltip will be removed whenever mouse leaves trigger
- jsP.parentElmt.off('mouseout'); // to prevent mouseout from firing several times
- jsP.parentElmt.mouseout(function () {
- jsPanel.close(jsP);
- });
- }
- }
- // corners
- jsP.css('overflow', 'visible');
- if (jsP.option.paneltype.cornerBG) {
- var corner = $("
"),
- cornerLoc = "jsPanel-corner-" + jsP.option.paneltype.position,
- cornerPos,
- cornerOX = parseInt(jsP.option.paneltype.cornerOX) || 0,
- cornerOY = parseInt(jsP.option.paneltype.cornerOY) || 0,
- cornerBG = jsP.option.paneltype.cornerBG;
- if (jsP.option.paneltype.position !== "bottom") {
- corner.addClass("jsPanel-corner " + cornerLoc).appendTo(jsP);
- } else {
- corner.addClass("jsPanel-corner " + cornerLoc).prependTo(jsP);
- }
- if (jsP.option.paneltype.position === "top") {
- cornerPos = parseInt(jsP.option.size.width) / 2 - 12 + (cornerOX) + "px";
- corner.css({ borderTopColor: cornerBG, left: cornerPos });
- } else if (jsP.option.paneltype.position === "right") {
- cornerPos = parseInt(jsP.option.size.height) / 2 - 12 + (cornerOY) + "px";
- corner.css({ borderRightColor: cornerBG, left: "-22px", top: cornerPos });
- } else if (jsP.option.paneltype.position === "bottom") {
- cornerPos = parseInt(jsP.option.size.width) / 2 - 12 + (cornerOX) + "px";
- corner.css({ borderBottomColor: cornerBG, left: cornerPos, top: "-22px" });
- } else if (jsP.option.paneltype.position === "left") {
- cornerPos = parseInt(jsP.option.size.height) / 2 - 12 + (cornerOY) + "px";
- corner.css({ borderLeftColor: cornerBG, left: jsP.option.size.width, top: cornerPos });
- }
- }
- } else if (jsP.option.paneltype.type === 'hint') {
- jsPanel.setHintDefaults(jsP);
- // bind callback for close button
- $('.jsPanel-hint-close', jsP).on('click', jsP, function (event) {
- event.data.close(jsP);
- });
- // set option.position for hints using 'top left', 'top center' or 'top right'
- if (jsP.option.position.top === '0' && jsP.option.position.left === 'center') {
- jsP.addClass("jsPanel-hint-tc");
- if ($(".jsPanel-hint-tc").length > 0) {
- jsP.option.position = jsPanel.hintTop("jsPanel-hint-tc");
- }
- } else if (jsP.option.position.top === '0' && jsP.option.position.left === '0') {
- jsP.addClass("jsPanel-hint-tl");
- if ($(".jsPanel-hint-tl").length > 0) {
- jsP.option.position = jsPanel.hintTop("jsPanel-hint-tl");
- }
- } else if (jsP.option.position.top === '0' && jsP.option.position.right === '0') {
- jsP.addClass("jsPanel-hint-tr");
- if ($(".jsPanel-hint-tr").length > 0) {
- jsP.option.position = jsPanel.hintTop("jsPanel-hint-tr");
- }
- }
- }
-
- /* option.selector - append jsPanel only to the first object in selector ------------------------------------ */
- jsP.data("selector", jsP.option.selector); // needed for exportPanels()
- if (jsP.option.paneltype.type !== 'tooltip') {
- jsP.appendTo(jsP.parentElmt);
- }
- if (jsP.option.paneltype.type === 'modal') {
- jsP.css('zIndex', 10001);
- if (jsP.option.paneltype.mode === 'extended') {
- $('.jsPanel-backdrop').css('z-index', '9998');
- }
- } else {
- if (!jsP.hasClass("jsPanel-modal")) {
- jsP.css('z-index', jsPanel.setZi(jsP));
- }
- }
-
- /* option.bootstrap & option.theme -------------------------------------------------------------------------- */
- if (jsP.option.bootstrap) {
- // check whether a bootstrap compatible theme is used and set option.theme accordingly
- jsP.option.theme = jsPanel.isBootstrapTheme(jsP.option.bootstrap);
- jsP.option.controls.iconfont = 'bootstrap';
- jsP.alterClass('jsPanel-theme-*', 'panel panel-' + jsP.option.theme);
- jsP.header.alterClass('jsPanel-theme-*', 'panel-heading');
- jsP.header.title.addClass('panel-title');
- jsP.content.alterClass('jsPanel-theme-*', 'panel-body');
- jsP.footer.addClass('panel-footer');
- // fix css problems for panels nested in other bootstrap panels
- jsP.header.title.css('color', function () {
- return jsP.header.css('color');
- });
- jsP.content.css('border-top-color', function () {
- return jsP.header.css('border-top-color');
- });
- } else {
- // activate normal non bootstrap themes
- var components = [jsP, jsP.header, jsP.content, jsP.footer];
- components.forEach(function (elmt) {
- $(elmt).alterClass('jsPanel-theme-*', 'jsPanel-theme-' + jsP.option.theme);
- });
- }
-
- /* option.removeHeader; option.controls (buttons in header right) ------------------------------------------- */
- if (jsP.option.removeHeader) {
- jsP.header.remove();
- } else {
- jsPanel.configControls(jsP);
- }
-
- /* insert iconfonts if option.iconfont set (default is "jsglyph") */
- if (jsP.option.controls.iconfont) {
- jsPanel.configIconfont(jsP);
- } else {
- // if option.controls.iconfont === false restore old icon sprite
- $('.jsPanel-btn-close, .jsPanel-btn-max, .jsPanel-btn-norm, .jsPanel-btn-min, .jsPanel-btn-small, .jsPanel-btn-smallrev', jsP.header.controls).empty();
- }
-
- /* option.toolbarHeader | default: false -------------------------------------------------------------------- */
- if (jsP.option.toolbarHeader && jsP.option.removeHeader === false) {
- if (typeof jsP.option.toolbarHeader === 'string') {
- jsP.header.toolbar.append(jsP.option.toolbarHeader);
- } else if ($.isFunction(jsP.option.toolbarHeader)) {
- jsP.header.toolbar.append(jsP.option.toolbarHeader(jsP.header));
- } else if ($.isArray(jsP.option.toolbarHeader)) {
- jsPanel.configToolbar(jsP.option.toolbarHeader, jsP.header.toolbar, jsP);
- }
- // give toolbar the same font-family as title
- jsP.header.toolbar.css("font-family", jsP.header.title.css("font-family"));
- }
-
- /* option.toolbarFooter | default: false -------------------------------------------------------------------- */
- if (jsP.option.toolbarFooter) {
- jsP.footer.css({
- display: 'block'
- });
- if (typeof jsP.option.toolbarFooter === 'string') {
- jsP.footer.append(jsP.option.toolbarFooter);
- } else if ($.isFunction(jsP.option.toolbarFooter)) {
- jsP.footer.append(jsP.option.toolbarFooter(jsP.footer));
- } else if ($.isArray(jsP.option.toolbarFooter)) {
- jsPanel.configToolbar(jsP.option.toolbarFooter, jsP.footer, jsP);
- }
- // give toolbar the same font-family as title
- jsP.footer.css("font-family", jsP.header.title.css("font-family"));
- }
-
- /* option.rtl | default: false ------------------------------------------------------------------------------ */
- if (jsP.option.rtl.rtl === true) {
- jsPanel.setRTL(jsP, jsP.option.rtl.lang);
- }
-
- /* option.overflow | default: 'hidden' --------------------------------------------------------------------- */
- if (typeof jsP.option.overflow === 'string') {
- jsP.content.css('overflow', jsP.option.overflow);
- } else if ($.isPlainObject(jsP.option.overflow)) {
- jsP.content.css({
- 'overflow-y': jsP.option.overflow.vertical,
- 'overflow-x': jsP.option.overflow.horizontal
- });
- }
-
- /* option.draggable ----------------------------------------------------------------------------------------- */
- if ($.isPlainObject(jsP.option.draggable)) {
- // if jsPanel is childpanel
- if (jsP.parent().hasClass('jsPanel-content')) {
- jsP.option.draggable.containment = 'parent';
- }
- // merge draggable settings and apply
- jsP.option.customdraggable = $.extend(true, {}, $.jsPanel.defaults.draggable, jsP.option.draggable);
- jsP.draggable(jsP.option.customdraggable);
- } else if (jsP.option.draggable === 'disabled') {
- // reset cursor, draggable deactivated
- $('.jsPanel-title, .jsPanel-ftr', jsP).css('cursor', 'inherit');
- // jquery ui draggable initialize disabled to allow to query status
- jsP.draggable({ disabled: true });
- }
-
- /* option.resizable ----------------------------------------------------------------------------------------- */
- if ($.isPlainObject(jsP.option.resizable)) {
- jsP.option.customresizable = $.extend(true, {}, $.jsPanel.defaults.resizable, jsP.option.resizable);
- jsP.resizable(jsP.option.customresizable);
- } else if (jsP.option.resizable === 'disabled') {
- // jquery ui resizable initialize disabled to allow to query status
- jsP.resizable({ disabled: true });
- $('.ui-icon-gripsmall-diagonal-se', jsP).css({ 'background-image': 'none', 'text-indent': -9999 });
- $('.ui-resizable-handle', jsP).css({ 'cursor': 'inherit' });
- }
-
- /* option.content ------------------------------------------------------------------------------------------- */
- // option.content can be any valid argument for jQuery.append()
- if (jsP.option.content) {
- jsP.content.append(jsP.option.content);
- jsP.data("content", jsP.option.content);
- }
-
- /* option.load ---------------------------------------------------------------------------------------------- */
- if ($.isPlainObject(jsP.option.load) && jsP.option.load.url) {
- jsPanel.load(jsP);
- }
-
- /* option.ajax ---------------------------------------------------------------------------------------------- */
- if ($.isPlainObject(jsP.option.ajax) && jsP.option.ajax.url) {
- jsPanel.ajax(jsP);
- }
-
- /* option.size ---------------------------------------------------------------------------------------------- */
- jsP.content.css({
- width: jsP.option.size.width || 'auto',
- height: jsP.option.size.height || 'auto'
- });
-
- // Important! limit title width; final adjustment follows later; otherwise title might be longer than panel width
- jsP.header.title.css('width', jsP.content.width() - 90);
-
- /* option.iframe -------------------------------------------------------------------------------------------- */
- // implemented after option.size because option.size.width/height are either "auto" or pixel values already
- if ($.isPlainObject(jsP.option.iframe) && (jsP.option.iframe.src || jsP.option.iframe.srcdoc)) {
- jsPanel.iframe(jsP);
- }
-
- /* option.position ------------------------------------------------------------------------------------------ */
- if (jsP.option.paneltype.type !== 'tooltip') {
- // value "center" not allowed for option.position.bottom & option.position.right -> use top and/or left
- // finally calculate & position the jsPanel
- jsPanel.calcPanelposition(jsP);
- }
-
- /* option.addClass ------------------------------------------------------------------------------------------ */
- if (typeof jsP.option.addClass.header === 'string') {
- jsP.header.addClass(jsP.option.addClass.header);
- }
- if (typeof jsP.option.addClass.content === 'string') {
- jsP.content.addClass(jsP.option.addClass.content);
- }
- if (typeof jsP.option.addClass.footer === 'string') {
- jsP.footer.addClass(jsP.option.addClass.footer);
- }
-
- // handlers for doubleclicks -----------------------------------------------------------------------------------
- // dblclicks disabled for normal modals, hints and tooltips
- if (jsP.option.paneltype.mode !== "default") {
- if (jsP.option.dblclicks) {
- if (jsP.option.dblclicks.title) {
- jsP.header.title.on('dblclick', function (e) {
- e.preventDefault();
- jsPanel.dblclickhelper(jsP.option.dblclicks.title, jsP);
- });
- }
- if (jsP.option.dblclicks.content) {
- jsP.content.on('dblclick', function (e) {
- e.preventDefault();
- jsPanel.dblclickhelper(jsP.option.dblclicks.content, jsP);
- });
- }
- if (jsP.option.dblclicks.footer) {
- jsP.footer.on('dblclick', function (e) {
- e.preventDefault();
- jsPanel.dblclickhelper(jsP.option.dblclicks.footer, jsP);
- });
- }
- }
- }
-
- /* option.show ---------------------------------------------------------------------------------------------- */
- if (!jsP.option.show) {
- jsP.css({
- display: 'block',
- opacity: 1
- });
- $(jsP).trigger('jspanelloaded', jsP.attr('id'));
- $(jsP).trigger('jspanelstatechange', jsP.attr('id'));
- jsP.option.size = {
- width: jsP.outerWidth(),
- height: jsP.outerHeight()
- };
- } else if (jsP.option.show.indexOf(" ") === -1) {
- // if no space is found in "jsP.option.show" -> function anwenden
- jsP[jsP.option.show]({
- done: function () {
- // trigger custom event
- $(jsP).trigger('jspanelloaded', jsP.attr('id'));
- $(jsP).trigger('jspanelstatechange', jsP.attr('id'));
- jsP.option.size = {
- width: jsP.outerWidth(),
- height: jsP.outerHeight()
- };
- }
- });
- } else {
- // does not work with certain combinations of type of animation and positioning
- jsP.css({
- display: 'block',
- opacity: 1
- });
- $(jsP).addClass(jsP.option.show);
- $(jsP).trigger('jspanelloaded', jsP.attr('id'));
- $(jsP).trigger('jspanelstatechange', jsP.attr('id'));
- jsP.option.size = {
- width: jsP.outerWidth(),
- height: jsP.outerHeight()
- };
- }
-
- /* needed if a maximized panel in body is normalized again -------------------------------------------------- */
- // don't put this under $('body').on('jspanelloaded', function () { ... }
- jsP.verticalOffset = jsPanel.calcVerticalOffset(jsP) || 0;
-
- /* replace bottom/right values with corresponding top/left values if necessary ------------------------------ */
- jsPanel.replaceCSSBottomRight(jsP);
-
- /* option.title | needs to be late in the file! ------------------------------------------------------------- */
- jsP.header.title.empty().prepend(jsP.option.title);
- jsPanel.resizeTitle(jsP);
-
- /* reposition hints while scrolling window, must be after normalization of position ------------------------- */
- if (jsP.option.paneltype.type === 'hint') {
- jsPanel.reposHintsScroll(jsP);
- }
-
- /* reposition jsPanel appended to body while scrolling window ----------------------------------------------- */
- if (jsP.parentElmtTagname === 'body' && (jsP.option.paneltype.type !== 'tooltip' || jsP.option.paneltype.type !== 'hint')) {
- jsPanel.fixPosition(jsP);
- }
-
- /* resizestart & resizestop & dragstop callbacks ------------------------------------------------------------ */
- if (!jsP.option.paneltype || jsP.option.paneltype.mode !== 'default') {
- // not needed for modals, hints and tooltips
- $(jsP).on("resizestart", function () {
- $("iframe", jsP.content).css("display", "none"); // on test
- });
-
- $(jsP).on("resize", function () {
- // debugger;
- // jquery ui resize event is also fired when panel is maximized or normalized (on request of Gareth Bult)
- jsPanel.resizeContent(jsP);
- jsPanel.resizeTitle(jsP);
- });
-
- $(jsP).on("resizestop", function () {
-
- //alert('resized')
- jsP.option.size = {
- width: jsP.outerWidth(),
- height: jsP.outerHeight()
- };
- if ($('.tools').length> 0) {
- //nikita
- if ($('#canvasDiv') != null) {
- if (jsP.outerHeight() >= 435 && jsP.outerWidth() >= 650) {
- // alert('resizestop')
- $('#canvasDiv').css('height', jsP.outerHeight() - 85)
- $('#canvasDiv').css('width', jsP.outerWidth() - 95)
- $('#canvasDiv').css('overflow', 'scroll')
- }
- else {
- $('#canvasDiv').css('height', jsP.outerHeight() - 110)
- $('#canvasDiv').css('width', jsP.outerWidth() - 85)
- $('#canvasDiv').css('overflow', 'scroll')
- }
- }
- }
- //nikita
- // $('#leftToolBar').css('height', jsP.outerWidth())
-
- jsPanel.updateStateProps(jsP, "normalized");
- $(jsP).trigger('jspanelnormalized', jsP.attr('id'));
- $(jsP).trigger('jspanelstatechange', jsP.attr('id'));
- // controls und title zurücksetzen
- jsPanel.hideControls(".jsPanel-btn-norm, .jsPanel-btn-smallrev", jsP);
- $("iframe", jsP.content).css("display", "block"); // on test
- });
-
- $(jsP).on("dragstart", function () {
- // alert("dragstart")
- // debugger;
- // remove window.scroll handler, is added again on dragstop
- $(window).off('scroll', jsP.jsPanelfixPos);
- if (jsP.option.paneltype.mode === 'extended') {
- jsP.css('z-index', '1');
- }
- });
-
- $(jsP).on("dragstop", function () {
- // alert("dragstop")
- // debugger;
- jsP.option.position = {
- top: jsP.css('top'),
- left: jsP.css('left')
- };
- jsP.verticalOffset = jsPanel.calcVerticalOffset(jsP) || 0;
- if (jsP.parentElmtTagname === 'body') {
- jsPanel.fixPosition(jsP);
- }
- });
-
- $(jsP).on("jspanelminimized", function () {
- jsPanel.hideControls(".jsPanel-btn-min, .jsPanel-btn-small, .jsPanel-btn-smallrev, .jsPanel-btn-hide", jsP);
- jsPanel.updateStateProps(jsP, "minimized");
- $(window).off('scroll', jsP.jsPanelfixPos);
- });
-
- $(jsP).on("jspanelmaximized", function () {
- // debugger;
- jsPanel.resizeContent(jsP);
- jsPanel.resizeTitle(jsP);
- jsPanel.hideControls(".jsPanel-btn-max, .jsPanel-btn-smallrev", jsP);
- jsPanel.updateStateProps(jsP, "maximized");
- // additionally trigger the jQuery UI resize event (on request of Gareth Bult)
- jsP.trigger("resize");
- });
-
- $(jsP).on("jspanelnormalized", function () {
- jsPanel.hideControls(".jsPanel-btn-norm, .jsPanel-btn-smallrev", jsP);
- jsPanel.resizeTitle(jsP);
- jsPanel.resizeContent(jsP);
- jsPanel.updateStateProps(jsP, "normalized");
- // additionally trigger the jQuery UI resize event (on request of Gareth Bult)
- jsP.trigger("resize");
- });
-
- }
-
- /* option.autoclose | default: false --------------------------------------- */
- if (typeof jsP.option.autoclose === 'number' && jsP.option.autoclose > 0) {
- jsPanel.autoclose(jsP);
- }
-
- /* tooltip corrections ----------------------------------------------------- */
- if (jsP.option.paneltype.type === "tooltip" && (jsP.option.paneltype.position === "top" || jsP.option.paneltype.position === "bottom")) {
- jsPanel.shiftTooltipHorizontal(jsP, jsP.option.paneltype.shiftwithin);
- } else if (jsP.option.paneltype.position === "left" || jsP.option.paneltype.position === "right") {
- jsPanel.shiftTooltipVertical(jsP, jsP.option.paneltype.shiftwithin);
- }
-
- /* option.panelstatus --------------------------------------------------------------------------------------- */
- if (jsP.option.panelstatus) {
- switch (jsP.option.panelstatus) {
- case "minimized":
- jsPanel.minimize(jsP);
- break;
- case "maximized":
- jsPanel.maximize(jsP);
- break;
- case ("smallified"):
- jsPanel.smallify(jsP);
- break;
- case ("smallifiedMax"):
- jsPanel.maximize(jsP);
- jsPanel.smallify(jsP);
- break;
- }
- } else {
- jsPanel.updateStateProps(jsP, "normalized");
- }
-
- /* jsP.option.callback --------------------------------------------------------- */
- if ($.isFunction(jsP.option.callback)) {
- jsP.option.callback.call(jsP, jsP);
- } else if ($.isArray(jsP.option.callback)) {
- jsP.option.callback.forEach(function (item) {
- if ($.isFunction(item)) {
- item.call(jsP, jsP);
- }
- });
- }
-
-
- return jsP;
- };
-
- /* jsPanel.defaults */
- $.jsPanel.defaults = {
- "addClass": {
- header: false,
- content: false,
- footer: false
- },
- "ajax": {
- autoload: true
- },
- "autoclose": false,
- "bootstrap": false,
- "callback": undefined,
- "content": false,
- "controls": {
- buttons: true,
- iconfont: 'jsglyph',
- close: false,
- confirmClose: false,
- maximize: false,
- minimize: false,
- normalize: false,
- smallify: false,
- maxtoScreen: false
- },
- "custom": false,
- "dblclicks": false,
- "draggable": {
- handle: 'div.jsPanel-hdr, div.jsPanel-ftr',
- stack: '.jsPanel',
- opacity: 0.7
- },
- "id": function () {
- jsPanel.ID += 1;
- return 'jsPanel-' + jsPanel.ID;
- },
- "iframe": false,
- "load": false,
- "maximizedMargin": {
- top: 5,
- right: 5,
- bottom: 5,
- left: 5
- },
- "offset": {
- top: 0,
- left: 0
- },
- "onbeforeclose": false,
- "onbeforemaximize": false,
- "onbeforeminimize": false,
- "onbeforenormalize": false,
- "onclosed": false,
- "oncmaximized": false,
- "onminimized": false,
- "onnormalized": false,
- "overflow": 'hidden',
- "panelstatus": false,
- "paneltype": false,
- "position": 'auto',
- "removeHeader": false,
- "resizable": {
- handles: 'n, e, s, w, ne, se, sw, nw',
- autoHide: false,
- minWidth: 150,
- minHeight: 93
- },
- "rtl": false,
- "selector": 'body',
- "show": 'fadeIn',
- "size": {
- width: '400px',
- height: '222px'
- },
- "template": false,
- "theme": 'default',
- "title": 'jsPanel',
- "toolbarFooter": false,
- "toolbarHeader": false,
- "currentController": '',
- "parentSlug": ''
-
- };
-
-
- /*
- * jQuery alterClass plugin
- * Remove element classes with wildcard matching. Optionally add classes:
- * $( '#foo' ).alterClass( 'foo-* bar-*', 'foobar' )
- * Copyright (c) 2011 Pete Boere (the-echoplex.net)
- * Free under terms of the MIT license: http://www.opensource.org/licenses/mit-license.php
- */
- $.fn.alterClass = function (removals, additions) {
-
- var self = this,
- patt;
- if (removals.indexOf('*') === -1) {
- // Use native jQuery methods if there is no wildcard matching
- self.removeClass(removals);
- return !additions ? self : self.addClass(additions);
- }
- patt = new RegExp('\\s' +
- removals.replace(/\*/g, '[A-Za-z0-9-_]+').split(' ').join('\\s|\\s') +
- '\\s', 'g');
- self.each(function (i, it) {
- var cn = ' ' + it.className + ' ';
- while (patt.test(cn)) {
- cn = cn.replace(patt, ' ');
- }
- it.className = $.trim(cn);
- });
- return !additions ? self : self.addClass(additions);
- };
-
- /* body click handler: remove all tooltips on click in body except click is inside tooltip */
- $('body').click(function (e) {
- var pID,
- isTT = $(e.target).closest('.jsPanel-tt').length;
- if (isTT < 1) {
- $('.jsPanel-tt').each(function () {
- pID = $(this).attr('id');
- // if present remove tooltip wrapper and than remove tooltip
- $('#' + pID).unwrap().remove();
- $('body').trigger('jspanelclosed', pID);
- });
- }
- });
-
-
-
-
-}(jQuery));
-
-/*
- :: Number.isInteger() polyfill ::
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
-*/
-if (!Number.isInteger) {
- Number.isInteger = function isInteger(nVal) {
- "use strict";
- return typeof nVal === 'number' && isFinite(nVal) && nVal > -9007199254740992 && nVal < 9007199254740992 && Math.floor(nVal) === nVal;
- };
+///
+///
+///
+/* global console, MobileDetect, jQuery */
+/* jQuery Plugin jsPanel
+ Dependencies:
+ jQuery library ( > 1.9.1 incl. 2.1.3 )
+ jQuery.UI library ( > 1.9.2 ) - (at least UI Core, Mouse, Widget, Draggable, Resizable)
+ HTML5/CSS3 compatible browser
+
+ Copyright (c) 2014-15 Stefan Sträßer,
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+
.
+
+ CHANGES IN 2.6.0:
+ + new options onbeforeclose, onclosed
+ + new options onbeforemaximize, onmaximized
+ + new options onbeforeminimize, onminimized
+ + new options onbefornormalize, onnormalized
+ */
+
+"use strict";
+// check for jQuery and jQuery UI components
+if (!$.fn.jquery || !$.fn.uniqueId || !$.widget || !$.ui.mouse || !$.ui.draggable || !$.ui.resizable) {
+ console.log("Error: jQuery or at least one jQuery UI component is not loaded! You need at least jQuery 1.9.1 and jQuery UI 1.9.2 (modules Core, Mouse, Widget, Draggable and Resizable).");
+} else {
+ console.log("Loaded: jQuery " + $.fn.jquery + ", jQuery UI " + $.ui.version +
+ "\nUI core: " + $.isFunction($.fn.uniqueId) + ", UI widget: " + $.isFunction($.widget) + ", UI mouse: " + $.isFunction($.ui.mouse) +
+ ", UI draggable: " + $.isFunction($.ui.draggable) + ", UI resizable: " + $.isFunction($.ui.resizable));
+}
+
+var jsPanel = {
+
+ version: '2.6.0 2015-12-04 14:15',
+ device: (function () {
+ try {
+ var imported = document.createElement('script');
+ //imported.src = '//vendor/mobile-detect.js';
+ imported.src = '~/../libs/jquery/jquery_plugin/jsPanel/vendor/mobile-detect.js';
+ document.head.appendChild(imported);
+
+ // requires "mobile-detect.js" to be loaded
+ var md = new MobileDetect(window.navigator.userAgent),
+ mobile = md.mobile(),
+ phone = md.phone(),
+ tablet = md.tablet(),
+ os = md.os(),
+ userAgent = md.userAgent();
+ return { mobile: mobile, tablet: tablet, phone: phone, os: os, userAgent: userAgent };
+ } catch (e) {
+ console.log(e + "; Seems like mobile-detect.js is not loaded");
+ return { mobile: undefined, tablet: undefined, phone: undefined, os: undefined, userAgent: undefined };
+ }
+ })(),
+ ID: 0, // kind of a counter to add to automatically generated id attribute
+ widthForMinimized: 180, // default width of minimized panels
+ template: '' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+
+ //'
' +
+ //'
' +
+ //'
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
',
+
+ // add toolbar
+ addToolbar: function (panel, place, items) {
+ if (place === 'header') {
+ this.configToolbar(items, panel.header.toolbar, panel);
+ } else if (place === 'footer') {
+ panel.footer.css({ display: 'block' });
+ this.configToolbar(items, panel.footer, panel);
+ }
+ // give toolbar the same font-family as title
+ panel.header.toolbar.css("font-family", panel.header.title.css("font-family"));
+ return panel;
+ },
+
+ // loads content using jQuery.ajax();
+ ajax: function (panel) {
+ var oAjax = panel.option.ajax,
+ pc = panel.content;
+ $.ajax(oAjax)
+ .done(function (data, textStatus, jqXHR) {
+ if (oAjax.autoload && oAjax.url) {
+ pc.empty().append(data);
+ }
+ if ($.isFunction(oAjax.done)) {
+ oAjax.done.call(pc, data, textStatus, jqXHR, panel);
+ }
+ })
+ .fail(function (jqXHR, textStatus, errorThrown) {
+ if ($.isFunction(oAjax.fail)) {
+ oAjax.fail.call(pc, jqXHR, textStatus, errorThrown, panel);
+ }
+ })
+ .always(function (arg1, textStatus, arg3) {
+ //In response to a successful request, the function's arguments are the same as those of .done(): data(hier: arg1), textStatus, and the jqXHR object(hier: arg3)
+ //For failed requests the arguments are the same as those of .fail(): the jqXHR object(hier: arg1), textStatus, and errorThrown(hier: arg3)
+ // fix for a bug in jQuery-UI draggable? that causes the jsPanel to reduce width when dragged beyond boundary of containing element and option.size.width is 'auto'
+ pc.css('width', function () {
+ return pc.outerWidth();
+ });
+ if ($.isFunction(oAjax.always)) {
+ oAjax.always.call(pc, arg1, textStatus, arg3, panel);
+ }
+ // title h3 might be to small: load() is async!
+ jsPanel.resizeTitle(panel);
+ // update option.size (content might come delayed)
+ jsPanel.updateOptionSize(panel, panel.option.size);
+ })
+ .then(function (data, textStatus, jqXHR) {
+ if (oAjax.then && $.isArray(oAjax.then)) {
+ if ($.isFunction(oAjax.then[0])) {
+ oAjax.then[0].call(pc, data, textStatus, jqXHR, panel);
+ }
+ // title h3 might be to small: load() is async!
+ jsPanel.resizeTitle(panel);
+ // update option.size (content might come delayed)
+ jsPanel.updateOptionSize(panel, panel.option.size);
+ }
+ }, function (jqXHR, textStatus, errorThrown) {
+ if (oAjax.then && $.isArray(oAjax.then)) {
+ if ($.isFunction(oAjax.then[1])) {
+ oAjax.then[1].call(pc, jqXHR, textStatus, errorThrown, panel);
+ }
+ // title h3 might be to small: load() is async!
+ jsPanel.resizeTitle(panel);
+ }
+ }
+ );
+ panel.data("ajaxURL", oAjax.url); // needed for exportPanels()
+ },
+
+ // used in option.autoclose and checks prior use of .close() whether the panel is still there
+ autoclose: function (panel) {
+ window.setTimeout(function () {
+ if (panel) {
+ panel.fadeOut('slow', function () {
+ panel.close();
+ });
+ }
+ }, panel.option.autoclose);
+ },
+
+ calcPanelposition: function (jsP) {
+ // when using option.size = 'auto' and option.position = 'center' consider use of option.ajax with
+ // async: false -> size will be known when position is calculated
+ // value "center" not allowed for option.position.bottom & option.position.right -> use top and/or left
+ var panelpos = {};
+ // get px values for panel size in case option.size is 'auto' - results will be incorrect whenever content
+ // is not loaded yet ( e.g. option.load, option.ajax ) -> centering can't work correctly
+ jsP.option.size.width = $(jsP).outerWidth();
+ jsP.option.size.height = $(jsP).innerHeight();
+ // delete option.position.top and/or left if option.position.bottom and/or right (top & left values come from defaults object)
+ if (jsP.option.position.bottom) {
+ delete jsP.option.position.top;
+ }
+ if (jsP.option.position.right) {
+ delete jsP.option.position.left;
+ }
+ // calculate top | bottom values != center
+ // if not checked for 0 as well code would not be executed!
+ if (jsP.option.position.bottom || jsP.option.position.bottom === 0) {
+ this.calcPos('bottom', jsP);
+ } else if (jsP.option.position.top || jsP.option.position.top === 0) {
+ if (jsP.option.position.top === 'center') {
+ jsP.option.position.top = this.calcPosCenter(jsP.option).top;
+ } else {
+ panelpos.top = this.calcPos('top', jsP); // change in 2.5.4
+ }
+ }
+ // calculate left | right values != center
+ if (jsP.option.position.right || jsP.option.position.right === 0) {
+ this.calcPos('right', jsP);
+ } else if (jsP.option.position.left || jsP.option.position.left === 0) {
+ if (jsP.option.position.left === 'center') {
+ jsP.option.position.left = this.calcPosCenter(jsP.option).left;
+ } else {
+ panelpos.left = this.calcPos('left', jsP); // change in 2.5.4
+ }
+ }
+ if (jsP.option.position.top) {
+ panelpos.top = parseInt(jsP.option.position.top, 10) + jsP.option.offset.top;
+ } else {
+ panelpos.bottom = parseInt(jsP.option.position.bottom, 10) + jsP.option.offset.top;
+ }
+ if (jsP.option.position.left) {
+ panelpos.left = parseInt(jsP.option.position.left, 10) + jsP.option.offset.left;
+ } else {
+ panelpos.right = parseInt(jsP.option.position.right, 10) + jsP.option.offset.left;
+ }
+ jsP.css(panelpos);
+ jsP.option.position = {
+ top: jsP.css('top'),
+ left: jsP.css('left')
+ };
+ },
+
+ // used in calcPanelposition
+ calcPos: function (prop, panel) {
+ var optPosition = panel.option.position;
+ if (optPosition[prop] === 'auto') {
+ panel.option.position[prop] = panel.count * 30;
+ } else if ($.isFunction(optPosition[prop])) {
+ panel.option.position[prop] = optPosition[prop](panel);
+ } else if (optPosition[prop] === 0) {
+ panel.option.position[prop] = '0';
+ } else {
+ panel.option.position[prop] = parseInt(optPosition[prop], 10);
+ }
+ // corrections if jsPanel is appended to the body element
+ if (panel.option.selector === 'body') {
+ if (prop === 'top') {
+ panel.option.position.top = parseInt(optPosition.top, 10) + $(window).scrollTop();
+ } else if (prop === 'bottom') {
+ panel.option.position.bottom = parseInt(optPosition.bottom, 10) - $(window).scrollTop();
+ } else if (prop === 'left') {
+ panel.option.position.left = parseInt(optPosition.left, 10) + $(window).scrollLeft();
+ } else if (prop === 'right') {
+ panel.option.position.right = parseInt(optPosition.right, 10) - $(window).scrollLeft();
+ }
+ }
+ return panel.option.position[prop];
+ },
+
+ // calculate position center for option.position == 'center'
+ calcPosCenter: function (option) {
+ var optSelector = option.selector,
+ optSize = option.size,
+ posL = ($(optSelector).outerWidth() / 2) - ((parseInt(optSize.width, 10) / 2)),
+ posT;
+ if (optSelector === 'body') {
+ posT = ($(window).outerHeight() / 2) - ((parseInt(optSize.height, 10) / 2) - $(window).scrollTop());
+ } else {
+ posT = ($(optSelector).outerHeight() / 2) - ((parseInt(optSize.height, 10) / 2));
+ }
+ return { top: posT, left: posL };
+ },
+
+ // calculate position for maximized panels using option.controls.maxtoScreen (for devmondo)
+ calcPosmaxtoScreen: function (panel) {
+ var offset = panel.offset();
+ return {
+ top: parseInt(panel.css('top')) - (offset.top - $(document).scrollTop()) + 5,
+ left: parseInt(panel.css('left')) - (offset.left - $(document).scrollLeft()) + 5
+ };
+ },
+
+ // calculates css left for tooltips
+ calcPosTooltipLeft: function (jsPparent, option) {
+ // width of element serving as trigger for the tooltip
+ var parW = jsPparent.outerWidth(),
+ // check possible margins of trigger
+ mL = parseInt(jsPparent.css('margin-left')),
+ // check whether offset is set
+ oX = option.offset.left || 0,
+ optptPosition = option.paneltype.position;
+ if (optptPosition === 'top' || optptPosition === 'bottom') {
+ return (parW - option.size.width) / 2 + mL + oX;
+ } else if (optptPosition === 'left') {
+ return -(option.size.width) + mL + oX;
+ } else if (optptPosition === 'right') {
+ return parW + mL + oX;
+ }
+ return false;
+ },
+
+ // calculates css top for tooltips
+ calcPosTooltipTop: function (jsPparent, option) {
+ var parH = jsPparent.innerHeight(),
+ mT = parseInt(jsPparent.css('margin-top')),
+ oY = option.offset.top || 0,
+ optptPosition = option.paneltype.position;
+ if (optptPosition === 'left' || optptPosition === 'right') {
+ return -(option.size.height / 2) + (parH / 2) + mT + oY;
+ } else if (optptPosition === 'top') {
+ return -(option.size.height + oY) + mT;
+ } else if (optptPosition === 'bottom') {
+ return parH + mT + oY;
+ }
+ return false;
+ },
+
+ // calculate final tooltip position
+ calcToooltipPosition: function (jsPparent, option) {
+ return {
+ top: this.calcPosTooltipTop(jsPparent, option),
+ left: this.calcPosTooltipLeft(jsPparent, option)
+ };
+ },
+
+ calcVerticalOffset: function (panel) {
+ return Math.floor(panel.offset().top - $(window).scrollTop());
+ },
+
+ // closes a jsPanel and removes it from the DOM
+ close: function (panel) {
+ // alert('jspanel closed')
+ // get parent-element of jsPanel
+ var context = panel.parent(),
+ panelID = panel.attr('id');
+ panel.trigger('jspanelbeforeclose', panelID);
+ if ($.isFunction(panel.option.onbeforeclose)) {
+ var close = panel.option.onbeforeclose.call(panel, panel);
+ if (close === false) {
+ return panel;
+ }
+ }
+ // delete childpanels ...
+ this.closeChildpanels(panel);
+ // if present remove tooltip wrapper
+ if (context.hasClass('jsPanel-tooltip-wrapper')) {
+ panel.unwrap();
+ }
+ // remove the jsPanel itself
+ panel.remove();
+ $('body').trigger('jspanelclosed', panelID);
+ // remove backdrop only when modal jsPanel is closed
+ if (panel.option.paneltype.type === 'modal') {
+ $('.jsPanel-backdrop').remove();
+ }
+ // reposition minimized panels
+ this.reposMinimized(this.widthForMinimized);
+ // reposition hints
+ if (panel.option.paneltype.type === 'hint') {
+ if (panel.hasClass("jsPanel-hint-tl")) {
+ jsPanel.reposHints("jsPanel-hint-tl", panel.parentElmtTagname);
+ } else if (panel.hasClass("jsPanel-hint-tc")) {
+ jsPanel.reposHints("jsPanel-hint-tc", panel.parentElmtTagname);
+ } else if (panel.hasClass("jsPanel-hint-tr")) {
+ jsPanel.reposHints("jsPanel-hint-tr", panel.parentElmtTagname);
+ }
+ }
+ if ($.isFunction(panel.option.onclosed)) {
+ panel.option.onclosed.call(panel, panel);
+ }
+ return context;
+ },
+
+ // close all tooltips
+ closeallTooltips: function () {
+ $('.jsPanel-tt').each(function () {
+ // remove tooltip wrapper and than remove tooltip
+ $(this).unwrap().remove();
+ $('body').trigger('jspanelclosed', $(this).attr('id'));
+ });
+ },
+
+ // closes/removes all childpanels within the parent jsPanel
+ closeChildpanels: function (panel) {
+ $('.jsPanel', panel).each(function () {
+ panel.trigger('jspanelbeforeclose', $(this).attr('id'));
+ $(this).remove();
+ $('body').trigger('jspanelclosed', $(this).attr('id'));
+ });
+ return panel;
+ },
+
+ // configure controls
+ configControls: function (panel) {
+ var controls = ["close", "maximize", "minimize", "normalize", "smallify"];
+ if (panel.option.controls.buttons === 'closeonly') {
+ $("div:not('.jsPanel-btn-close')", panel.header.controls).remove(); // change in 2.5.3
+ panel.header.title.css("width", "calc(100% - 30px)");
+ } else if (panel.option.controls.buttons === 'none') {
+ $('*', panel.header.controls).remove();
+ panel.header.title.css("width", "100%");
+ }
+ // disable controls individually
+ controls.forEach(function (ctrl) {
+ if (panel.option.controls[ctrl]) { panel.control('disable', ctrl); }
+ });
+ },
+
+ // configure iconfonts
+ configIconfont: function (panel) {
+ var controlsArray = ["close", "max", "norm", "min", "small", "smallrev"],
+ bootstrapArray = ["remove", "fullscreen", "resize-full", "minus", "chevron-up", "chevron-down"],
+ fontawesomeArray = ["times", "arrows-alt", "expand", "minus", "chevron-up", "chevron-down"],
+ optIconfont = panel.option.controls.iconfont,
+ controls = panel.header.controls;
+ // remove icon sprites
+ $('*', controls).css('background-image', 'none');
+ // set icons
+ if (optIconfont === 'bootstrap') {
+ controlsArray.forEach(function (item, i) {
+ $('.jsPanel-btn-' + item, controls).empty().append('');
+ });
+ } else if (optIconfont === 'font-awesome') {
+ controlsArray.forEach(function (item, i) {
+ $('.jsPanel-btn-' + item, controls).empty().append('');
+ });
+ }
+ },
+
+ // builds toolbar
+ configToolbar: function (toolbaritems, toolbarplace, panel) {
+ var el;
+ toolbaritems.forEach(function (item) {
+ if (typeof item === "object") {
+ el = $(item.item);
+ // add text to button
+ if (typeof item.btntext === 'string') {
+ el.append(item.btntext);
+ }
+ // add class to button
+ if (typeof item.btnclass === 'string') {
+ el.addClass(item.btnclass);
+ }
+ toolbarplace.append(el);
+ // bind handler to the item
+ if ($.isFunction(item.callback)) {
+ el.on(item.event, panel, item.callback);
+ // jsP is accessible in the handler as "event.data"
+ }
+ }
+ });
+ },
+
+ // disable/enable individual controls
+ control: function (panel, action, btn) {
+ var controls = panel.header.controls,
+ controlbtn;
+ if (arguments.length === 3) {
+ if (arguments[1] === 'disable') {
+ if (btn === 'close') {
+ controlbtn = $('.jsPanel-btn-close', controls);
+ } else if (btn === 'maximize') {
+ controlbtn = $('.jsPanel-btn-max', controls);
+ } else if (btn === 'minimize') {
+ controlbtn = $('.jsPanel-btn-min', controls);
+ } else if (btn === 'normalize') {
+ controlbtn = $('.jsPanel-btn-norm', controls);
+ } else if (btn === 'smallify') {
+ controlbtn = $('.jsPanel-btn-small', controls);
+ }
+ // unbind handler and set styles
+ controlbtn.off().css({ opacity: 0.5, cursor: 'default' });
+ } else if (arguments[1] === 'enable') {
+ if (btn === 'close') {
+ controlbtn = $('.jsPanel-btn-close', controls);
+ } else if (btn === 'maximize') {
+ controlbtn = $('.jsPanel-btn-max', controls);
+ } else if (btn === 'minimize') {
+ controlbtn = $('.jsPanel-btn-min', controls);
+ } else if (btn === 'normalize') {
+ controlbtn = $('.jsPanel-btn-norm', controls);
+ } else if (btn === 'smallify') {
+ controlbtn = $('.jsPanel-btn-small', controls);
+ }
+ // enable control and reset styles
+ controlbtn.on('click', function (e) {
+ e.preventDefault();
+ panel[btn]();
+ }).css({ opacity: 1, cursor: 'pointer' });
+ }
+ }
+ return panel;
+ },
+
+ // helper function for the doubleclick handlers (title, content, footer)
+ dblclickhelper: function (odcs, panel) {
+ if (typeof odcs === 'string') {
+ if (odcs === "maximize" || odcs === "normalize") {
+ if (panel.status === "normalized" || panel.option.panelstatus === "normalized") {
+ panel.maximize();
+ } else {
+ panel.normalize();
+ }
+ } else if (odcs === "minimize" || odcs === "smallify" || odcs === "close") {
+ panel[odcs]();
+ }
+ }
+ },
+
+ // export a panel layout to localStorage and returns array with an object for each panel
+ exportPanels: function () {
+ var elmtOffset, elmtPosition, elmtTop, elmtLeft, elmtWidth, elmtHeight, elmtStatus, panelParent,
+ panelArr = [], exportedPanel,
+ panels = $(".jsPanel").not(".jsPanel-tt, .jsPanel-hint, .jsPanel-modal");
+ panels.each(function (index, elmt) {
+ exportedPanel = {
+ panelstatus: $(elmt).data("panelstatus"),
+ id: $(elmt).prop("id"),
+ title: $(".jsPanel-title", elmt).html(),
+ custom: $(elmt).data("custom"),
+ offset: { top: 0, left: 0 },
+ content: $(elmt).data("content")
+ };
+ // normalize minimized/maximized panels before export
+ // status to restore is saved in exportedPanel.panelstatus
+ if ($(elmt).data("panelstatus") !== "normalized") {
+ $(".jsPanel-btn-norm", elmt).trigger("click");
+ }
+ panelParent = $(elmt).data("selector");
+ elmtOffset = $(elmt).offset();
+ elmtPosition = $(elmt).position();
+ if (elmtStatus === "minimized") {
+ if (panelParent.toLowerCase() === "body") {
+ elmtTop = $(elmt).data("paneltop") - $(window).scrollTop() + "px";
+ elmtLeft = $(elmt).data("panelleft") - $(window).scrollLeft() + "px";
+ } else {
+ elmtTop = $(elmt).data("paneltop") + "px";
+ elmtLeft = $(elmt).data("panelleft") + "px";
+ }
+ elmtWidth = $(elmt).data("panelwidth") + "px";
+ elmtHeight = $(elmt).data("panelheight") + "px";
+ } else {
+ if (panelParent.toLowerCase() === "body") {
+ elmtTop = Math.floor(elmtOffset.top - $(window).scrollTop()) + "px";
+ elmtLeft = Math.floor(elmtOffset.left - $(window).scrollLeft()) + "px";
+ } else {
+ elmtTop = Math.floor(elmtPosition.top) + "px";
+ elmtLeft = Math.floor(elmtPosition.left) + "px";
+ }
+ elmtWidth = $(elmt).css("width");
+ elmtHeight = $(".jsPanel-content", elmt).css("height");
+ }
+ exportedPanel.size = {
+ width: elmtWidth,
+ height: elmtHeight
+ };
+ exportedPanel.position = {
+ top: elmtTop,
+ left: elmtLeft
+ };
+ if ($(elmt).data("loadURL")) {
+ exportedPanel.load = {};
+ exportedPanel.load.url = $(elmt).data("loadURL");
+ }
+ if ($(elmt).data("ajaxURL")) {
+ exportedPanel.ajax = {};
+ exportedPanel.ajax.url = $(elmt).data("ajaxURL");
+ }
+ if ($(elmt).data("iframeDOC") || $(elmt).data("iframeSRC")) {
+ exportedPanel.iframe = {};
+ if ($(elmt).data("iframeDOC")) {
+ exportedPanel.iframe.srcdoc = $(elmt).data("iframeDOC");
+ }
+ if ($(elmt).data("iframeSRC")) {
+ exportedPanel.iframe.src = $(elmt).data("iframeSRC");
+ }
+ }
+ panelArr.push(exportedPanel);
+ // restore status that is saved
+ switch (exportedPanel.panelstatus) {
+ case "minimized":
+ $(".jsPanel-btn-min", elmt).trigger("click");
+ break;
+ case "maximized":
+ $(".jsPanel-btn-max", elmt).trigger("click");
+ break;
+ case "smallified":
+ $(".jsPanel-btn-small", elmt).trigger("click");
+ break;
+ case "smallifiedMax":
+ $(".jsPanel-btn-small", elmt).trigger("click");
+ break;
+ }
+ });
+ //window.localStorage.setItem("jspanels", panelArr);
+ window.localStorage.setItem("jspanels", JSON.stringify(panelArr));
+ return panelArr;
+ },
+
+ // imports panel layout from localStorage.jspanels and restores panels
+ importPanels: function (predefinedConfigs) {
+ /* panelConfig needs to be an object with predefined configs.
+ * A config named "default" will be applied to ALL panels
+ *
+ * panelConfig = { default: { } [, config1 [, config2 [, configN ]]] };
+ */
+ var savedPanels, restoredConfig, defaultConfig;
+ savedPanels = JSON.parse(localStorage.jspanels) || {};
+ defaultConfig = predefinedConfigs["default"] || {};
+ savedPanels.forEach(function (savedconfig) {
+ // safedconfig represents one item in safedPanels
+ if (typeof savedconfig.custom.config === "string") {
+ restoredConfig = $.extend(true, {}, defaultConfig, predefinedConfigs[savedconfig.custom.config], savedconfig);
+ } else {
+ restoredConfig = $.extend(true, {}, defaultConfig, savedconfig);
+ }
+ // restore panel
+ $.jsPanel(restoredConfig);
+ });
+ },
+
+ // maintains panel position relative to window on scroll of page
+ fixPosition: function (panel) {
+ var jspaneldiff = panel.offset().top - $(window).scrollTop();
+ panel.jsPanelfixPos = function () {
+ panel.css('top', $(window).scrollTop() + jspaneldiff);
+ };
+ $(window).on('scroll', panel.jsPanelfixPos);
+ },
+
+ // calculate panel margins
+ getMargins: function (panel) {
+ var off, elmtOff, mR, mL, mB, mT,
+ selector = panel.option.paneltype.shiftwithin,
+ winWidth = $(window).outerWidth(),
+ winHeight = $(window).outerHeight(),
+ panelWidth = panel.outerWidth(),
+ panelHeight = panel.outerHeight();
+ if (!selector || selector === "body") {
+ // panel margins relative to browser viewport
+ off = panel.offset();
+ mR = winWidth - off.left - panelWidth + $(window).scrollLeft();
+ mL = winWidth - panelWidth - mR;
+ mB = winHeight - off.top - panelHeight + $(window).scrollTop();
+ mT = winHeight - panelHeight - mB;
+ } else {
+ // panel margins relative to element matching selector "selector"
+ elmtOff = $(selector).offset();
+ off = panel.offset();
+ mR = $(selector).outerWidth() - parseInt(panel.css('width')) - (off.left - elmtOff.left);
+ mL = off.left - elmtOff.left;
+ mB = $(selector).outerHeight() - (off.top - elmtOff.top) - parseInt(panel.css('height'));
+ mT = off.top - elmtOff.top;
+ }
+ return { marginTop: parseInt(mT), marginRight: parseInt(mR), marginBottom: parseInt(mB), marginLeft: parseInt(mL) };
+ },
+
+ // return max value of an array with numbers
+ getMaxOfArray: function (numArray) {
+ return Math.max.apply(null, numArray);
+ },
+
+ // calculate max horizontal and vertical tooltip shift
+ getMaxpanelshift: function (panel) {
+ var panelWidth = panel.outerWidth(),
+ panelHeight = panel.outerHeight(),
+ horiz = parseInt(panelWidth / 2) + parseInt(panel.parent().outerWidth() / 2) - 20,
+ vert = parseInt(panelHeight / 2) + parseInt(panel.parent().outerHeight() / 2) - 20,
+ cornerHoriz = parseInt(panelWidth / 2) - 16,
+ cornerVert = parseInt(panelHeight / 2) - 16;
+ return { maxshiftH: horiz, maxshiftV: vert, maxCornerH: cornerHoriz, maxCornerV: cornerVert };
+ },
+
+ // hide controls specified by param "sel" of the jsPanel "panel"
+ hideControls: function (sel, panel) {
+ var controls = panel.header.controls;
+ $("*", controls).css('display', 'block');
+ $('#minSpan').css({ 'display': '' });
+
+ $(sel, controls).css('display', 'none');
+ },
+
+ // calculates option.position for hints using 'top left', 'top center' or 'top right'
+ hintTop: function (hintGroup) {
+ var hintH = 0;
+ $("." + hintGroup).each(function () {
+ hintH += $(this).outerHeight(true);
+ });
+ if (hintGroup === "jsPanel-hint-tr") {
+ return { top: hintH, right: 0 };
+ } else if (hintGroup === "jsPanel-hint-tl") {
+ return { top: hintH, left: 0 };
+ } else if (hintGroup === "jsPanel-hint-tc") {
+ return { top: hintH, left: 'center' };
+ }
+ return { top: 0, left: 0 };
+ },
+
+ // loads content in an iFrame
+ iframe: function (panel) {
+ var iFrame = $("");
+ // iframe content
+ if (panel.option.iframe.srcdoc) {
+ iFrame.prop("srcdoc", panel.option.iframe.srcdoc);
+ panel.data("iframeDOC", panel.option.iframe.srcdoc); // needed for exportPanels()
+ }
+ if (panel.option.iframe.src) {
+ iFrame.prop("src", panel.option.iframe.src);
+ panel.data("iframeSRC", panel.option.iframe.src); // needed for exportPanels()
+ }
+ //iframe size
+ if (panel.option.size.width !== "auto" && !panel.option.iframe.width) {
+ iFrame.prop("width", "100%");
+ } else if (typeof panel.option.iframe.width === 'string' && panel.option.iframe.width.slice(-1) === '%') {
+ iFrame.prop("width", panel.option.iframe.width);
+ } else {
+ iFrame.prop("width", parseInt(panel.option.iframe.width) + 'px');
+ }
+ if (panel.option.size.height !== "auto" && !panel.option.iframe.height) {
+ iFrame.prop("height", "100%");
+ } else if (typeof panel.option.iframe.height === 'string' && panel.option.iframe.height.slice(-1) === '%') {
+ iFrame.prop("height", panel.option.iframe.height);
+ } else {
+ iFrame.prop("height", parseInt(panel.option.iframe.height) + 'px');
+ }
+ //iframe name
+ if (typeof panel.option.iframe.name === 'string') {
+ iFrame.prop("name", panel.option.iframe.name);
+ }
+ //iframe id
+ if (typeof panel.option.iframe.id === 'string') {
+ iFrame.prop("id", panel.option.iframe.id);
+ }
+ //iframe seamless (not yet supported by any browser)
+ if (panel.option.iframe.seamless) {
+ iFrame.prop("seamless", "seamless");
+ }
+ //iframe sandbox
+ if (typeof panel.option.iframe.sandbox === 'string') {
+ iFrame.prop("sandox", panel.option.iframe.sandbox);
+ }
+ //iframe style
+ if ($.isPlainObject(panel.option.iframe.style)) {
+ iFrame.css(panel.option.iframe.style);
+ }
+ //iframe css classes
+ if (typeof panel.option.iframe.classname === 'string') {
+ iFrame.addClass(panel.option.iframe.classname);
+ } else if ($.isFunction(panel.option.iframe.classname)) {
+ iFrame.addClass(panel.option.iframe.classname());
+ }
+ panel.content.empty().append(iFrame);
+ },
+
+ // append modal backdrop
+ insertModalBackdrop: function () {
+ var backdrop = '';
+ $('body').append(backdrop);
+ /*$(document).on("keydown", ".jsPanel-backdrop", function(e){
+ e.preventDefault();
+ return false;
+ });*/
+ },
+
+ // check whether a bootstrap compatible theme is used
+ isBootstrapTheme: function (optionBootstrap) {
+ if ($.inArray(optionBootstrap, ["default", "primary", "info", "success", "warning", "danger"]) > -1) {
+ return optionBootstrap;
+ }
+ return "default";
+ },
+
+ // loads content using jQuery.load()
+ load: function (panel) {
+ // alert('pppp')
+ panel.content.load(panel.option.load.url, panel.option.load.data || undefined, function (responseText, textStatus, jqXHR) {
+ if ($.isFunction(panel.option.load.complete)) {
+ panel.option.load.complete.call(panel.content, responseText, textStatus, jqXHR, panel);
+ }
+ // title h3 might be to small: load() is async!
+ jsPanel.resizeTitle(panel);
+ // update option.size (content might come delayed)
+ jsPanel.updateOptionSize(panel, panel.option.size);
+ // fix for a bug in jQuery-UI draggable? that causes the jsPanel to reduce width when dragged beyond boundary of containing element and option.size.width is 'auto'
+ panel.content.css('width', function () {
+ return panel.content.outerWidth();
+ });
+ });
+ panel.data("loadURL", panel.option.load.url); // needed for exportPanels()
+
+
+
+ },
+
+ // maximizes a panel within the body element
+ maxWithinBody: function (panel) {
+ var newPos, newTop, newLeft, newRight;
+ if ((panel.status !== "maximized" || panel.option.panelstatus !== "maximized") && panel.option.paneltype.mode !== 'default') {
+ // remove window.scroll handler, is added again later in this function
+ $(window).off('scroll', panel.jsPanelfixPos);
+ // restore minimized panel to initial container if necessary
+ if (panel.status === "minimized" || panel.option.panelstatus === "minimized") {
+ this.restoreFromMinimized(panel);
+ }
+ // test to enable fullscreen maximize for panels in a parent other than body
+ if (panel.option.controls.maxtoScreen === true) {
+ newPos = this.calcPosmaxtoScreen(panel);
+ newTop = newPos.top + parseInt(panel.option.maximizedMargin.top);
+ newLeft = newPos.left + parseInt(panel.option.maximizedMargin.left);
+ } else {
+ //nikita
+ //newTop = $(window).scrollTop() + parseInt(panel.option.maximizedMargin.top);
+ //newLeft = $(window).scrollLeft() + parseInt(panel.option.maximizedMargin.left);
+ newTop = 70;
+ newLeft = 0;
+ //nikita
+ newRight = 15;
+ }
+ panel.css({
+ top: newTop,
+ left: newLeft,
+ //nikita
+ right: newRight,
+ width: $(window).outerWidth() - 10, height: $(window).outerHeight() - 90
+
+ //width: $(window).outerWidth() - parseInt(panel.option.maximizedMargin.left) - parseInt(panel.option.maximizedMargin.right),
+ //height: $(window).outerHeight() - parseInt(panel.option.maximizedMargin.top) - parseInt(panel.option.maximizedMargin.bottom)
+ });
+ if ($('.tools') != null) {
+ //nikita
+ if ($('#canvasDiv') != null) {
+ if (panel.outerHeight() >= 435 && panel.outerWidth() >= 650) {
+ // alert('if')
+ $('#canvasDiv').css('height', panel.outerHeight() - 75)
+ $('#canvasDiv').css('width', panel.outerWidth() - 100)
+ $('#canvasDiv').css('overflow', 'scroll')
+ }
+ else {
+ // alert('else')
+ $('#canvasDiv').css('height', panel.outerHeight() - 110)
+ $('#canvasDiv').css('width', panel.outerWidth() - 90)
+ $('#canvasDiv').css('overflow', 'scroll')
+ }
+ }
+ }
+ //nikita
+ if (!panel.option.controls.maxtoScreen || (panel.option.controls.maxtoScreen && panel.option.selector === 'body')) {
+ // test to enable fullscreen maximize for panels in a parent other than body
+ this.fixPosition(panel);
+ }
+ }
+ },
+
+ // maximizes a panel within an element other than body
+ maxWithinElement: function (panel) {
+ // debugger;
+ if ((panel.status !== "maximized" || panel.option.panelstatus !== "maximized") && panel.option.paneltype.mode !== 'default') {
+ // restore minimized panel to initial container if necessary
+ if (panel.status === "minimized" || panel.option.panelstatus === "minimized") {
+ this.restoreFromMinimized(panel);
+ }
+ panel.css({
+ top: parseInt(70),//panel.option.maximizedMargin.top),
+ left: parseInt(panel.option.maximizedMargin.left),
+ width: parseInt(panel.parent().outerWidth(), 10) - parseInt(panel.option.maximizedMargin.left) - parseInt(panel.option.maximizedMargin.right),
+ height: parseInt(panel.parent().outerHeight()) - parseInt(panel.option.maximizedMargin.top) - parseInt(panel.option.maximizedMargin.bottom) - 65
+ });
+ }
+ if ($('.tools').length> 0) {
+ //nikita
+ if ($('#canvasDiv') != null) {
+ if (panel.outerHeight() >= 435 && panel.outerWidth() >= 650) {
+ //alert('if')
+ // debugger;
+ $('#canvasDiv').css('height', panel.outerHeight() - 85)
+ $('#canvasDiv').css('width', panel.outerWidth() - 90)
+ $('#canvasDiv').css('overflow', 'scroll')
+ }
+ else {
+ // alert('else')
+ $('#canvasDiv').css('height', panel.outerHeight() - 105)
+ $('#canvasDiv').css('width', panel.outerWidth() - 80)
+ $('#canvasDiv').css('overflow', 'scroll')
+
+ }
+ }
+ }
+ //nikita
+ // debugger;
+ // $(".fa-minus").removeClass('display');
+ $('#minSpan').css({ 'display': '' });
+ },
+
+ // calls functions to maximize a jsPanel
+ maximize: function (panel) {
+ // debugger;
+ panel.trigger('jspanelbeforemaximize', panel.attr('id'));
+ if ($.isFunction(panel.option.onbeforemaximize)) {
+ var maximize = panel.option.onbeforemaximize.call(panel, panel);
+ if (maximize === false) {
+ return panel;
+ }
+ }
+ if (panel.parentElmtTagname === 'body' || panel.option.controls.maxtoScreen === true) {
+ this.maxWithinBody(panel);
+ } else {
+ this.maxWithinElement(panel);
+ }
+ panel.trigger('jspanelmaximized', panel.attr('id'));
+ panel.trigger('jspanelstatechange', panel.attr('id'));
+ if ($.isFunction(panel.option.onmaximized)) {
+ panel.option.onmaximized.call(panel, panel);
+ }
+ return panel;
+ },
+
+ // minimizes a jsPanel to the lower left corner of the browser viewport
+ minimize: function (panel) {
+ panel.trigger('jspanelbeforeminimize', panel.attr('id'));
+ if ($.isFunction(panel.option.onbeforeminimize)) {
+ var minimize = panel.option.onbeforeminimize.call(panel, panel);
+ if (minimize === false) {
+ return panel;
+ }
+ }
+ panel.data({ // needed for method exportPanels()
+ "paneltop": parseInt(panel.option.position.top),
+ "panelleft": parseInt(panel.option.position.left),
+ "panelwidth": parseInt(panel.option.size.width),
+ "panelheight": parseInt($(".jsPanel-content", panel).css("height"))
+ });
+ // update panel size to have correct values when normalizing again
+ if (panel.status === "normalized" || panel.option.panelstatus === "normalized") {
+ panel.option.size.width = panel.outerWidth();
+ panel.option.size.height = panel.outerHeight();
+ }
+ panel.animate({
+ opacity: 0
+ }, {
+ duration: 400, // fade out speed when minimizing
+ complete: function () {
+ panel.animate({
+ width: jsPanel.widthForMinimized + "px",
+ height: '28px'
+ }, {
+ duration: 100,
+ complete: function () {
+ jsPanel.movetoMinified(panel);
+ jsPanel.resizeTitle(panel);
+ panel.css('opacity', 1);
+ }
+ });
+ }
+ });
+ if ($.isFunction(panel.option.onminimized)) {
+ panel.option.onminimized.call(panel, panel);
+ }
+ return panel;
+ },
+
+ // moves a panel to the minimized container
+ movetoMinified: function (panel) {
+ // wenn der Container für die minimierten jsPanels noch nicht existiert -> erstellen
+ if ($('#jsPanel-min-container').length === 0) {
+ $('body').append('');
+ }
+ if (panel.status !== "minimized" || panel.option.panelstatus !== "minimized") {
+ // jsPanel in vorgesehenen Container verschieben
+ panel.css({
+ left: ($('.jsPanel', '#jsPanel-min-container').length * jsPanel.widthForMinimized),
+ top: 0,
+ opacity: 1
+ })
+ .appendTo('#jsPanel-min-container')
+ .resizable({ disabled: true })
+ .draggable({ disabled: true });
+ panel.trigger('jspanelminimized', panel.attr('id'));
+ panel.trigger('jspanelstatechange', panel.attr('id'));
+ }
+ },
+
+ // restores a panel to its "normalized" (not minimized, maximized or smallified) position & size
+ normalize: function (panel) {
+ // debugger;
+ var panelTop,
+ interactions = ["resizable", "draggable"];
+ panel.trigger('jspanelbeforenormalize', panel.attr('id'));
+ if ($.isFunction(panel.option.onbeforenormalize)) {
+ var normalize = panel.option.onbeforenormalize.call(panel, panel);
+ if (normalize === false) {
+ return panel;
+ }
+ }
+ // remove window.scroll handler, is added again later in this function
+ $(window).off('scroll', panel.jsPanelfixPos);
+ // restore minimized panel to initial container if necessary
+ if (panel.status === "minimized" || panel.option.panelstatus === "minimized") {
+ this.restoreFromMinimized(panel);
+ }
+ // correction for panels maximized in body after page was scrolled
+ if (panel.parentElmtTagname === 'body') {
+ panelTop = $(window).scrollTop() + panel.verticalOffset;
+ } else {
+ panelTop = panel.option.position.top;
+ }
+ panel.css({
+ width: panel.option.size.width,
+ height: panel.option.size.height + 10,
+ top: panelTop,
+ left: panel.option.position.left
+ });
+ interactions.forEach(function (action) {
+ if (panel.option[action] !== "disabled") {
+ panel[action]("enable");
+ // get resizer and cursor for resizable back
+ $('.ui-icon-gripsmall-diagonal-se', panel).css({ 'background-image': 'none', 'text-indent': 0 });
+ $('.ui-resizable-handle', panel).css({ 'cursor': '' });
+ }
+ });
+ panel.trigger('jspanelnormalized', panel.attr('id'));
+ panel.trigger('jspanelstatechange', panel.attr('id'));
+ if (panel.parentElmtTagname === 'body') {
+ this.fixPosition(panel);
+ }
+ if ($.isFunction(panel.option.onnormalized)) {
+ panel.option.onnormalized.call(panel, panel);
+ }
+ return panel;
+ },
+
+ // replace bottom/right values with corresponding top/left values if necessary and update option.position
+ replaceCSSBottomRight: function (panel) {
+ var panelPosition = panel.position();
+ if (panel.css('bottom')) {
+ panel.css({
+ 'top': parseInt(panelPosition.top, 10),
+ 'bottom': ''
+ });
+ panel.option.position.top = parseInt(panelPosition.top, 10);
+ }
+ if (panel.css('right')) {
+ panel.css({
+ 'left': parseInt(panelPosition.left, 10),
+ 'right': ''
+ });
+ panel.option.position.left = parseInt(panelPosition.left, 10);
+ }
+ },
+
+ // reposition hint upon closing
+ reposHints: function (hintGroup, jsPtagname) {
+ var hintH;
+ if (jsPtagname === 'body') {
+ hintH = $(window).scrollTop();
+ } else {
+ hintH = 0;
+ }
+ $("." + hintGroup).each(function () {
+ $(this).animate({
+ top: hintH
+ });
+ hintH += $(this).outerHeight(true);
+ });
+ },
+
+ // reposition hints on window scroll
+ reposHintsScroll: function (panel) {
+ var dif = panel.offset().top - $(window).scrollTop();
+ // with window.onscroll only the last added hint would stay in position
+ $(window).scroll(function () {
+ panel.css('top', $(window).scrollTop() + dif);
+ });
+ },
+
+ // repositions a panel and optionally moves it to another container
+ reposition: function (panel, position, selector) {
+ //alert('reposition')
+ if (selector && typeof selector === "string") {
+ panel.option.selector = selector;
+ panel.appendTo(selector);
+ panel.parentElmt = $(selector).first();
+ panel.parentElmtTagname = panel.parentElmt[0].tagName.toLowerCase();
+ }
+ if (panel.option.paneltype.type !== 'tooltip' && panel.option.paneltype.type !== 'hint') {
+ // rewrite passed position to be a proper object
+ panel.option.position = jsPanel.rewriteOPosition(position);
+ // delete element styles concerning position, otherwise you might end up with left &right and/or top & bottom values
+ panel.css({ top: "", right: "", bottom: "", left: "" });
+ this.calcPanelposition(panel);
+ panel.verticalOffset = jsPanel.calcVerticalOffset(panel) || 0;
+ this.replaceCSSBottomRight(panel);
+ if (panel.parentElmtTagname === "body") {
+ this.fixPosition(panel);
+ } else {
+ $(window).off('scroll', panel.jsPanelfixPos);
+ }
+ this.updateOptionPosition(panel);
+ }
+ return panel;
+ },
+
+ // repositions minimized jsPanels
+ reposMinimized: function () {
+ $('.jsPanel', '#jsPanel-min-container').each(function (index, elmt) {
+ $(elmt).animate({
+ left: (index * jsPanel.widthForMinimized)
+ });
+ });
+ },
+
+ // resize exsisting jsPanel; resizes the full panel (not content section only)
+ resize: function (panel, width, height) {
+ // debugger;
+ if (panel.option.panelstatus !== "minimized") { // v2.4.1 don't call resize() on minimized panels
+ if (width && width !== null) {
+ panel.css("width", width);
+ } else {
+ panel.css("width", panel.content.css("width"));
+ }
+ if (height && height !== null) {
+ panel.css("height", height);
+ }
+ this.resizeContent(panel);
+ this.resizeTitle(panel);
+ }
+
+ if ($('#canvasDiv') != null) {
+ $('#canvasDiv').css('height', $(window).outerHeight() - 120)
+ $('#leftToolBar').css('height', $(window).outerHeight() - 120)
+
+ }
+ },
+
+ // reset dimensions of content section after resize and so on
+ resizeContent: function (panel) {
+ var hdrftr;
+ if (panel.footer.css('display') === 'none') {
+ hdrftr = panel.header.outerHeight();
+ } else {
+ hdrftr = panel.header.outerHeight() + panel.footer.outerHeight();
+ }
+ panel.content.css({
+ height: (panel.outerHeight() - hdrftr),
+ //nikita
+ width: panel.outerWidth()
+ });
+ return panel;
+ },
+
+ // resize the title h3 to use full width minus controls width (and prevent being longer than panel)
+ resizeTitle: function (panel) {
+ var titleWidth = (panel.outerWidth() - $(panel.header.controls).outerWidth() - 15);
+ panel.header.title.css('width', titleWidth);
+ },
+
+ // restores minimized panels to their initial container, reenables resizable and draggable, repositions minimized panels
+ restoreFromMinimized: function (panel) {
+ var interactions = ["resizable", "draggable"];
+ // restore minimized panel to initial container
+ if (panel.status === "minimized" || panel.option.panelstatus === "minimized") {
+ panel.appendTo(panel.option.selector);
+ }
+ interactions.forEach(function (action) {
+ if (panel.option[action] !== "disabled") {
+ panel[action]("enable");
+ // get resizer and cursor for resizable back
+ $('.ui-icon-gripsmall-diagonal-se', panel).css({ 'background-image': 'none', 'text-indent': 0 });
+ $('.ui-resizable-handle', panel).css({ 'cursor': '' });
+ }
+ });
+ // reposition minimized panels
+ this.reposMinimized(jsPanel.widthForMinimized);
+ },
+
+ // rewrite option.paneltype strings to objects and set defaults for option.paneltype
+ rewriteOPaneltype: function (optionPaneltype) {
+ var op = optionPaneltype;
+ if (op === 'modal') {
+ return { type: 'modal', mode: 'default' };
+ } else if (op === 'tooltip') {
+ return { type: 'tooltip', position: 'top' };
+ } else if (op === 'hint') {
+ return { type: 'hint' };
+ } else if (op.type === 'modal') {
+ return { type: 'modal', mode: op.mode || 'default' };
+ } else if (op.type === 'tooltip') {
+ return {
+ type: 'tooltip',
+ mode: op.mode || false,
+ position: op.position || false,
+ shiftwithin: op.shiftwithin || "body",
+ solo: op.solo || false,
+ cornerBG: op.cornerBG || false,
+ cornerOX: op.cornerOX || false,
+ cornerOY: op.cornerOY || false
+ };
+ } else {
+ return { paneltype: false };
+ }
+ },
+
+ // converts option.position string to object
+ rewriteOPosition: function (optionPosition) {
+ var op = optionPosition;
+ if (op === 'center') {
+ return { top: 'center', left: 'center' };
+ } else if (op === 'auto') {
+ return { top: 'auto', left: 'auto' };
+ } else if (op === 'top left') {
+ return { top: '0', left: '0' };
+ } else if (op === 'top center') {
+ return { top: '0', left: 'center' };
+ } else if (op === 'top right') {
+ return { top: '0', right: '0' };
+ } else if (op === 'center right') {
+ return { top: 'center', right: '0' };
+ } else if (op === 'bottom right') {
+ return { bottom: '0', right: '0' };
+ } else if (op === 'bottom center') {
+ return { bottom: '0', left: 'center' };
+ } else if (op === 'bottom left') {
+ return { bottom: '0', left: '0' };
+ } else if (op === 'center left') {
+ return { top: 'center', left: '0' };
+ }
+ // if bottom and/or right is set to "center" change that to top and/or left set to "center"
+ if (op.bottom === "center") {
+ delete op.bottom;
+ op.top = "center";
+ }
+ if (op.right === "center") {
+ delete op.right;
+ op.left = "center";
+ }
+ return optionPosition;
+ },
+
+ // converts option.size string to object
+ rewriteOSize: function (optionSize) {
+ var oSize = optionSize;
+ if (typeof oSize === 'string' && oSize === 'auto') {
+ oSize = {
+ width: 'auto',
+ height: 'auto'
+ };
+ }
+ return oSize;
+ },
+
+ // set default options for hints and add necessary classes
+ setHintDefaults: function (panel) {
+ panel.option.resizable = false;
+ panel.option.draggable = false;
+ panel.option.removeHeader = true;
+ panel.option.toolbarFooter = false;
+ panel.option.show = 'fadeIn';
+ panel.addClass('jsPanel-hint');
+ panel.content.addClass('jsPanel-hint-content');
+ // autoclose default 8 sec | or -1 to deactivate
+ if (!panel.option.autoclose) {
+ panel.option.autoclose = 8000;
+ } else if (panel.option.autoclose < 0) {
+ panel.option.autoclose = false;
+ }
+ // add class according option.theme to color the hint background
+ panel.content.addClass('jsPanel-hint-' + panel.option.theme);
+ panel.content.append('');
+ },
+
+ // set default options for standard modal
+ setModalDefaults: function (panel) {
+ panel.option.selector = 'body';
+ panel.option.show = 'fadeIn';
+ panel.addClass('jsPanel-modal');
+ if (panel.option.paneltype.mode === 'default') {
+ panel.option.resizable = false;
+ panel.option.draggable = false;
+ panel.option.removeHeader = false;
+ panel.option.position = { top: 'center', left: 'center' };
+ panel.option.offset = { top: 0, left: 0 };
+ panel.option.controls.buttons = 'closeonly'; //do not delete else "modal" with no close button possible
+ $(".jsPanel-btn-min, .jsPanel-btn-norm, .jsPanel-btn-max, .jsPanel-btn-small, .jsPanel-btn-smallrev", panel).remove();
+ $(panel.header, panel.header.title, panel.footer).css('cursor', 'default');
+ $('.jsPanel-title', panel).css('cursor', 'inherit');
+ }
+ },
+
+ // set right-to-left text direction and language; set styles and reoorder controls for rtl
+ setRTL: function (panel) {
+ var elmts = [panel.header.title, panel.content, panel.header.toolbar, panel.footer];
+ elmts.forEach(function (item) {
+ item.prop('dir', 'rtl');
+ if (panel.option.rtl.lang) {
+ item.prop('lang', panel.option.rtl.lang);
+ }
+ });
+ panel.header.title.css('text-align', 'right');
+ $('.jsPanel-btn-close', panel.header.controls).insertAfter($('.jsPanel-btn-min', panel.header.controls));
+ $('.jsPanel-btn-max', panel.header.controls).insertAfter($('.jsPanel-btn-min', panel.header.controls));
+ $('.jsPanel-btn-small', panel.header.controls).insertBefore($('.jsPanel-btn-min', panel.header.controls));
+ $('.jsPanel-btn-smallrev', panel.header.controls).insertBefore($('.jsPanel-btn-min', panel.header.controls));
+ $('.jsPanel-hdr-r', panel).css({ left: '0px', right: '', position: 'relative', 'float': 'left' });
+ $('.jsPanel-hint-close', panel).css('float', 'left');
+ $('.jsPanel-title', panel).css('float', 'right');
+ $('.jsPanel-ftr', panel).append('');
+ $('button', panel.footer).css('float', 'left');
+ },
+
+ // set default options for tooltips
+ setTooltipDefaults: function (panel) {
+ panel.option.position = {};
+ panel.option.resizable = false;
+ panel.option.draggable = false;
+ panel.option.show = 'fadeIn';
+ panel.option.controls.buttons = 'closeonly';
+ panel.header.title.css('cursor', 'inherit');
+ panel.footer.css('cursor', 'inherit');
+ panel.addClass('jsPanel-tt');
+ },
+
+ // returns a z-index value for a panel in order to have it on top
+ setZi: function (panel) {
+ var jspanel, allZi = [], maxZi;
+ if (typeof panel === "string") {
+ jspanel = $(panel);
+ } else {
+ jspanel = panel;
+ }
+ // build array with all z-index values
+ $(".jsPanel:not('.jsPanel-modal, .jsPanel-nofront')").each(function (i, elmt) {
+ if (jspanel.attr("id") !== $(elmt).attr("id")) {
+ allZi.push($(elmt).css("z-index"));
+ }
+ });
+ //allZi.sort(function(a, b) {return a - b}); // sort array ascending
+ //console.log(allZi);
+ maxZi = this.getMaxOfArray(allZi);
+ return maxZi + 1;
+ },
+
+ // shift tooltip left/right if it overflows window; when using horizontal offsets of panel and/or corner result might be not as expected
+ shiftTooltipHorizontal: function (panel) {
+ var margins = this.getMargins(panel),
+ leftShiftRequired,
+ maxShift = this.getMaxpanelshift(panel),
+ maxLeftShift = maxShift.maxshiftH,
+ shift,
+ maxCornerLeft = maxShift.maxCornerH,
+ cornerShift,
+ newPanelLeft = 0,
+ newCornerLeft = 0;
+ if (margins.marginLeft < 0 && margins.marginRight > 0) {
+ // if panel overflows left window border
+ leftShiftRequired = Math.abs(margins.marginLeft) + 5 || 0;
+ shift = Math.min(leftShiftRequired, maxLeftShift) || 0;
+ cornerShift = Math.min(maxCornerLeft, shift) || 0;
+ newPanelLeft = parseInt(panel.css('left')) + shift + "px";
+ newCornerLeft = parseInt($('.jsPanel-corner', panel).css('left')) - cornerShift + "px";
+ } else if (margins.marginRight < 0 && margins.marginLeft > 0) {
+ // if panel overflows right window border
+ leftShiftRequired = Math.abs(margins.marginRight) + 5 || 0;
+ shift = Math.min(leftShiftRequired, maxLeftShift) || 0;
+ cornerShift = Math.min(maxCornerLeft, shift) || 0;
+ newPanelLeft = parseInt(panel.css('left')) - shift + "px";
+ newCornerLeft = parseInt($('.jsPanel-corner', panel).css('left')) + cornerShift + "px";
+ }
+ if ((margins.marginLeft < 0 && margins.marginRight > 0) || (margins.marginRight < 0 && margins.marginLeft > 0)) {
+ // shift panel
+ panel.animate({
+ "left": newPanelLeft
+ }, { queue: false /* to have both animation run simultaneously */ });
+
+ // shift corner if present
+ if ($('.jsPanel-corner', panel)) {
+ $('.jsPanel-corner', panel).animate({
+ "left": newCornerLeft
+ }, { queue: false /* to have both animation run simultaneously */ });
+ }
+ }
+ },
+
+ // shift tooltip up/down if it overflows window; when using vertical offsets of panel and/or corner result might be not as expected
+ shiftTooltipVertical: function (panel) {
+ //console.log( parseInt($('*:first-child', panel.parent()).css('margin-left')) );
+ var margins = this.getMargins(panel),
+ topShiftRequired,
+ maxShift = this.getMaxpanelshift(panel),
+ maxTopShift = maxShift.maxshiftV,
+ shift,
+ maxCornerTop = maxShift.maxCornerV,
+ cornerShift,
+ newPanelTop = 0,
+ newCornerTop = 0;
+ if (margins.marginTop < 0 && margins.marginBottom > 0) {
+ // if panel overflows top window border
+ topShiftRequired = Math.abs(margins.marginTop) + 5 || 0;
+ shift = Math.min(topShiftRequired, maxTopShift) || 0;
+ cornerShift = Math.min(maxCornerTop, shift) || 0;
+ newPanelTop = parseInt(panel.css('top')) + shift + "px";
+ newCornerTop = parseInt($('.jsPanel-corner', panel).css('top')) - cornerShift + "px";
+ } else if (margins.marginBottom < 0 && margins.marginTop > 0) {
+ // if panel overflows bottom window border
+ topShiftRequired = Math.abs(margins.marginBottom) + 5 || 0;
+ shift = Math.min(topShiftRequired, maxTopShift) || 0;
+ cornerShift = Math.min(maxCornerTop, shift) || 0;
+ newPanelTop = parseInt(panel.css('top')) - shift + "px";
+ newCornerTop = parseInt($('.jsPanel-corner', panel).css('top')) + cornerShift + "px";
+ }
+ if ((margins.marginTop < 0 && margins.marginBottom > 0) || (margins.marginBottom < 0 && margins.marginTop > 0)) {
+ // shift panel
+ panel.animate({
+ "top": newPanelTop
+ }, { queue: false /* to have both animation run simultaneously */ });
+
+ // shift corner if present
+ if ($('.jsPanel-corner', panel)) {
+ $('.jsPanel-corner', panel).animate({
+ "top": newCornerTop
+ }, { queue: false /* to have both animation run simultaneously */ });
+ }
+ }
+ },
+
+ smallify: function (panel) {
+ var statusNew;
+ if ((panel.status !== "smallified" || panel.option.panelstatus !== "smallified") && (panel.status !== "smallifiedMax" || panel.option.panelstatus !== "smallifiedMax")) {
+ if (panel.status === "maximized" || panel.option.panelstatus === "maximized") {
+ statusNew = "smallifiedMax";
+ } else {
+ statusNew = "smallified";
+ }
+ // store panel height in function property
+ panel.smallify.height = panel.outerHeight();
+ panel.panelheaderheight = panel.header.outerHeight() - 2;
+ panel.panelfooterheight = panel.footer.outerHeight();
+ panel.panelcontentheight = panel.content.outerHeight();
+ panel.animate({
+ height: panel.panelheaderheight
+ },
+ {
+ done: function () {
+ if (panel.status === 'maximized' || panel.option.panelstatus === 'maximized') {
+ jsPanel.hideControls(".jsPanel-btn-max, .jsPanel-btn-small", panel);
+ } else {
+ jsPanel.hideControls(".jsPanel-btn-norm, .jsPanel-btn-small", panel);
+ }
+ jsPanel.updateStateProps(panel, statusNew);
+ panel.trigger('jspanel' + statusNew, panel.attr('id'));
+ panel.trigger('jspanelstatechange', panel.attr('id'));
+ }
+ });
+ }
+ },
+
+ unsmallify: function (panel) {
+ panel.animate({
+ height: panel.smallify.height
+ },
+ {
+ done: function () {
+ if (panel.status === 'smallified' || panel.option.panelstatus === 'smallified') {
+ jsPanel.hideControls(".jsPanel-btn-norm, .jsPanel-btn-smallrev", panel);
+ jsPanel.updateStateProps(panel, "normalized");
+ panel.trigger('jspanelnormalized', panel.attr('id'));
+ panel.trigger('jspanelstatechange', panel.attr('id'));
+ } else {
+ jsPanel.hideControls(".jsPanel-btn-max, .jsPanel-btn-smallrev", panel);
+ jsPanel.updateStateProps(panel, "maximized");
+ panel.trigger('jspanelmaximized', panel.attr('id'));
+ panel.trigger('jspanelstatechange', panel.attr('id'));
+ }
+ }
+ }
+ );
+ },
+
+ // updates option.position to hold actual values
+ updateOptionPosition: function (panel) {
+ panel.option.position.top = panel.css('top');
+ panel.option.position.left = panel.css('left');
+ },
+
+ // updates option.size to hold actual values
+ updateOptionSize: function (panel) {
+ panel.option.size.width = panel.css('width');
+ panel.option.size.height = $(".jsPanel-content", panel).css("height");
+ },
+
+ updateCustomData: function (panel, key, val) {
+ var custom = panel.data("custom");
+ custom[key] = val;
+ panel.data("custom", custom);
+ },
+
+ updateStateProps: function (panel, status) {
+ panel.status = status;
+ panel.option.panelstatus = status;
+ panel.data("panelstatus", status);
+ panel.alterClass("jsPanel-state-*", "jsPanel-state-" + status);
+ },
+
+ getScope: function (ctrlName) {
+ var sel = 'div[ng-controller="' + ctrlName + '"]';
+ return angular.element(sel).scope();
+ },
+
+ getRootScope: function (controllerName) {
+ var $body = angular.element(document.body); // 1
+ return $body.scope().$root;
+
+ }
+};
+
+console.log("jsPanel version: " + jsPanel.version);
+
+(function ($) {
+ $.jsPanel = function (config) {
+
+
+ var jsP, template, id,
+ panelconfig = config || {},
+ optConfig = panelconfig.config || {};
+
+ // use custom jsPanel template if present else standard template
+ template = panelconfig.template || jsPanel.template;
+ jsP = $(template);
+
+ // Extend our default config with those provided. Note that the first arg to extend is an empty object - this is to keep from overriding our "defaults" object.
+ jsP.option = $.extend(true, {}, $.jsPanel.defaults, optConfig, panelconfig);
+
+ // option.id ---------------------------------------------------------------------------------------------------
+ if (typeof jsP.option.id === "string") {
+ id = jsP.option.id;
+ } else if ($.isFunction(jsP.option.id)) {
+ id = jsP.option.id();
+ } else {
+ jsPanel.ID += 1;
+ id = jsPanel.ID;
+ }
+ if ($("#" + id).length > 0) {
+ alert("jsPanel Error: No jsPanel created - id attribute passed with option.id already exists in document");
+ return false;
+ } else {
+ jsP.attr("id", id);
+ }
+
+ jsP.data("custom", jsP.option.custom);
+
+ jsP.verticalOffset = 0; // always use 0 ... not "0" !
+
+ try {
+ jsP.parentElmt = $(jsP.option.selector).first();
+ jsP.parentElmtTagname = jsP.parentElmt[0].tagName.toLowerCase();
+ jsP.count = jsP.parentElmt.children('.jsPanel').length;
+ } catch (e) {
+ alert(e + "\n\nThe element you want to append the jsPanel to does not exist!\n\n The jsPanel will be appended to the body element instead.");
+ jsP.option.selector = 'body';
+ jsP.parentElmt = $('body');
+ jsP.parentElmtTagname = 'body';
+ jsP.count = jsP.parentElmt.children('.jsPanel').length;
+ }
+
+ jsP.status = "initialized";
+
+ jsP.header = $('.jsPanel-hdr', jsP);
+
+ jsP.header.title = $('.jsPanel-title', jsP.header);
+
+ jsP.header.controls = $('.jsPanel-hdr-r', jsP.header);
+
+ jsP.header.toolbar = $('.jsPanel-hdr-toolbar', jsP.header);
+
+ jsP.content = $('.jsPanel-content', jsP);
+
+ jsP.footer = $('.jsPanel-ftr', jsP);
+
+ jsP.normalize = function () {
+ jsPanel.normalize(jsP);
+ return jsP;
+ };
+
+ jsP.close = function () {
+ // alert('1')
+ jsPanel.close(jsP);
+ // no need to return something
+ };
+
+ jsP.closeChildpanels = function () {
+ jsPanel.closeChildpanels(jsP);
+ return jsP;
+ };
+
+ jsP.minimize = function () {
+ jsPanel.minimize(jsP);
+ return jsP;
+ };
+
+ jsP.maximize = function () {
+ jsPanel.maximize(jsP);
+ return jsP;
+ };
+
+ jsP.smallify = function () {
+ if ((jsP.status === "normalized" || jsP.option.panelstatus === "normalized") || (jsP.status === "maximized" || jsP.option.panelstatus === "maximized")) {
+ jsPanel.smallify(jsP);
+ } else if ((jsP.status !== "minimized" || jsP.option.panelstatus !== "minimized")) {
+ jsPanel.unsmallify(jsP);
+ }
+ return jsP;
+ };
+
+ jsP.front = function () {
+ jsP.css('z-index', jsPanel.setZi(jsP));
+ return jsP;
+ };
+
+ jsP.title = function (text) {
+ if (text && typeof text === "string") {
+ jsP.header.title.html(text);
+ return jsP;
+ } else if (arguments.length === 0) {
+ return jsP.header.title.html();
+ }
+ };
+
+ jsP.addToolbar = function (place, items) {
+ jsPanel.addToolbar(jsP, place, items);
+ return jsP;
+ };
+
+ jsP.control = function (action, btn) {
+ jsPanel.control(jsP, action, btn);
+ return jsP;
+ };
+
+ jsP.resize = function (width, height) {
+ // alert('jsP.resize')
+ // method resizes the full panel (not content section only)
+ jsPanel.resize(jsP, width, height);
+ return jsP;
+ };
+
+ jsP.reposition = function (position, selector) {
+ jsPanel.reposition(jsP, position, selector);
+ return jsP;
+ };
+
+ jsP.reloadContent = function () {
+ if (jsP.option.content) {
+ jsP.content.empty().append(jsP.option.content);
+ } else if (jsP.option.load) {
+ jsP.content.empty();
+ jsPanel.load(jsP);
+ } else if (jsP.option.ajax) {
+ jsPanel.ajax(jsP);
+ } else if (jsP.option.iframe) {
+ jsPanel.iframe(jsP);
+ }
+ };
+
+ // handler to move panel to foreground on click
+ jsP.on('click', function (e) {
+ //alert('1')
+ // use of e.preventDefault(); would prevent events from inside a panel from firing properly
+ if (!$(e.target).is("a[href], button, .jsPanel-nofront, .jsPanel-nofront *")) {
+ if (!jsP.hasClass("jsPanel-modal")) {
+ jsP.css('z-index', jsPanel.setZi(jsP));
+ }
+ }
+ });
+
+ // jsPanel close
+ $('.jsPanel-btn-close', jsP).on('click', function (e) {
+ // alert('2')
+ e.preventDefault();
+ //if (!jsP.option.controls.confirmClose) {
+ // jsPanel.close(jsP, jsP.parentElmtTagname);
+ //} else {
+ // if (window.confirm(jsP.option.controls.confirmClose) === true) {
+ // jsPanel.close(jsP, jsP.parentElmtTagname);
+ // }
+ //}
+
+ //if ($('#jsPanel-1').length > 0) {
+ // $('.jsPanel-btn-norm').attr('style', 'display: block');
+ // $('.jsPanel-btn-max').attr('style', 'display: block');
+ //}
+
+ var $scope = jsPanel.getRootScope('HomeController');
+ $scope.openParent(jsP.option.parentSlug);
+ $scope.$apply();
+ });
+
+
+
+
+ // jsPanel minimize
+ $('.jsPanel-btn-min', jsP).on('click', function (e) {
+ // alert('minimized')
+
+ e.preventDefault();
+ jsPanel.minimize(jsP);
+ // debugger;
+ var headerTitle = $('.jsPanel-title');
+ var title = headerTitle[0].innerHTML;
+
+ var $rootscope = jsPanel.getRootScope('HomeController');
+ //$rootscope.openParent(jsP.option.parentSlug);
+ $rootscope.setState('min', title);
+ $rootscope.$apply();
+
+ var currentController = jsP.option.currentController;
+ if (currentController == 'DAController') {
+ var $scope = jsPanel.getScope(currentController);
+ var canvasDiv = document.getElementById('canvasDiv');
+ $scope.imageVerticalScrollPosition = canvasDiv.scrollTop;
+ $scope.imageHorizontlScrollPosition = canvasDiv.scrollLeft;
+ $scope.$apply();
+ }
+ });
+
+ // jsPanel maximize
+ $('.jsPanel-btn-max', jsP).on('click', function (e) {
+ // debugger;
+ e.preventDefault();
+ jsPanel.maximize(jsP);
+
+ $('.jsPanel-btn-min').css('display', 'initial');
+ $('.fa fa-minus').css('display', 'initial');
+ var headerTitle = $('.jsPanel-title');
+ var title = headerTitle[0].innerHTML;
+ var $rootscope = jsPanel.getRootScope('HomeController');
+ //$rootscope.setState('max', title);
+ $rootscope.$apply();
+ });
+
+ // jsPanel normalize
+ $('.jsPanel-btn-norm', jsP).on('click', function (e) {
+ // debugger;
+ e.preventDefault();
+ jsPanel.normalize(jsP);
+
+ var currentController = jsP.option.currentController;
+ if (currentController == 'DAController') {
+ var $scope = jsPanel.getScope(currentController);
+
+
+ $('#canvasDiv').scrollLeft($scope.imageHorizontlScrollPosition)
+ $('#canvasDiv').scrollTop($scope.imageVerticalScrollPosition)
+
+ $scope.$apply();
+ }
+ });
+
+ // jsPanel smallify
+ $('.jsPanel-btn-small', jsP).on('click', function (e) {
+ e.preventDefault();
+ jsPanel.smallify(jsP);
+ });
+
+ // jsPanel unsmallify
+ $('.jsPanel-btn-smallrev', jsP).on('click', function (e) {
+ e.preventDefault();
+ jsPanel.unsmallify(jsP);
+ });
+
+ // rewrite option.paneltype strings to objects and set defaults for option.paneltype
+ jsP.option.paneltype = jsPanel.rewriteOPaneltype(jsP.option.paneltype);
+
+ // converts option.position string to object
+ jsP.option.position = jsPanel.rewriteOPosition(jsP.option.position);
+
+ // converts option.size string to object
+ jsP.option.size = jsPanel.rewriteOSize(jsP.option.size);
+
+ /* option.paneltype - override or set various settings depending on option.paneltype ------------------------ */
+ if (jsP.option.paneltype.type === 'modal') {
+ // set defaults for standard modal
+ jsPanel.setModalDefaults(jsP);
+ // insert backdrop
+ if ($('.jsPanel-backdrop').length < 1) {
+ jsPanel.insertModalBackdrop();
+ }
+ } else if (jsP.option.paneltype.type === 'tooltip') {
+ jsPanel.setTooltipDefaults(jsP);
+ // optionally remove all other tooltips
+ if (jsP.option.paneltype.solo) {
+ jsPanel.closeallTooltips();
+ }
+ // calc top & left for the various tooltip positions
+ jsP.option.position = jsPanel.calcToooltipPosition(jsP.parentElmt, jsP.option);
+ // position the tooltip & add tooltip class
+ jsP.css({
+ top: jsP.option.position.top,
+ left: jsP.option.position.left
+ });
+ if (!jsP.parentElmt.parent().hasClass('jsPanel-tooltip-wrapper')) {
+ // wrap element serving as trigger in a div - will take the tooltip
+ jsP.parentElmt.wrap('');
+ // append tooltip (jsPanel) to the wrapper div
+ jsP.parentElmt.parent().append(jsP);
+ if (jsP.option.paneltype.mode === 'semisticky') {
+ jsP.hover(
+ function () {
+ $.noop();
+ },
+ function () {
+ jsPanel.close(jsP);
+ }
+ );
+ } else if (jsP.option.paneltype.mode === 'sticky') {
+ $.noop();
+ } else {
+ jsP.option.controls.buttons = 'none';
+ // tooltip will be removed whenever mouse leaves trigger
+ jsP.parentElmt.off('mouseout'); // to prevent mouseout from firing several times
+ jsP.parentElmt.mouseout(function () {
+ jsPanel.close(jsP);
+ });
+ }
+ }
+ // corners
+ jsP.css('overflow', 'visible');
+ if (jsP.option.paneltype.cornerBG) {
+ var corner = $("
"),
+ cornerLoc = "jsPanel-corner-" + jsP.option.paneltype.position,
+ cornerPos,
+ cornerOX = parseInt(jsP.option.paneltype.cornerOX) || 0,
+ cornerOY = parseInt(jsP.option.paneltype.cornerOY) || 0,
+ cornerBG = jsP.option.paneltype.cornerBG;
+ if (jsP.option.paneltype.position !== "bottom") {
+ corner.addClass("jsPanel-corner " + cornerLoc).appendTo(jsP);
+ } else {
+ corner.addClass("jsPanel-corner " + cornerLoc).prependTo(jsP);
+ }
+ if (jsP.option.paneltype.position === "top") {
+ cornerPos = parseInt(jsP.option.size.width) / 2 - 12 + (cornerOX) + "px";
+ corner.css({ borderTopColor: cornerBG, left: cornerPos });
+ } else if (jsP.option.paneltype.position === "right") {
+ cornerPos = parseInt(jsP.option.size.height) / 2 - 12 + (cornerOY) + "px";
+ corner.css({ borderRightColor: cornerBG, left: "-22px", top: cornerPos });
+ } else if (jsP.option.paneltype.position === "bottom") {
+ cornerPos = parseInt(jsP.option.size.width) / 2 - 12 + (cornerOX) + "px";
+ corner.css({ borderBottomColor: cornerBG, left: cornerPos, top: "-22px" });
+ } else if (jsP.option.paneltype.position === "left") {
+ cornerPos = parseInt(jsP.option.size.height) / 2 - 12 + (cornerOY) + "px";
+ corner.css({ borderLeftColor: cornerBG, left: jsP.option.size.width, top: cornerPos });
+ }
+ }
+ } else if (jsP.option.paneltype.type === 'hint') {
+ jsPanel.setHintDefaults(jsP);
+ // bind callback for close button
+ $('.jsPanel-hint-close', jsP).on('click', jsP, function (event) {
+ event.data.close(jsP);
+ });
+ // set option.position for hints using 'top left', 'top center' or 'top right'
+ if (jsP.option.position.top === '0' && jsP.option.position.left === 'center') {
+ jsP.addClass("jsPanel-hint-tc");
+ if ($(".jsPanel-hint-tc").length > 0) {
+ jsP.option.position = jsPanel.hintTop("jsPanel-hint-tc");
+ }
+ } else if (jsP.option.position.top === '0' && jsP.option.position.left === '0') {
+ jsP.addClass("jsPanel-hint-tl");
+ if ($(".jsPanel-hint-tl").length > 0) {
+ jsP.option.position = jsPanel.hintTop("jsPanel-hint-tl");
+ }
+ } else if (jsP.option.position.top === '0' && jsP.option.position.right === '0') {
+ jsP.addClass("jsPanel-hint-tr");
+ if ($(".jsPanel-hint-tr").length > 0) {
+ jsP.option.position = jsPanel.hintTop("jsPanel-hint-tr");
+ }
+ }
+ }
+
+ /* option.selector - append jsPanel only to the first object in selector ------------------------------------ */
+ jsP.data("selector", jsP.option.selector); // needed for exportPanels()
+ if (jsP.option.paneltype.type !== 'tooltip') {
+ jsP.appendTo(jsP.parentElmt);
+ }
+ if (jsP.option.paneltype.type === 'modal') {
+ jsP.css('zIndex', 10001);
+ if (jsP.option.paneltype.mode === 'extended') {
+ $('.jsPanel-backdrop').css('z-index', '9998');
+ }
+ } else {
+ if (!jsP.hasClass("jsPanel-modal")) {
+ jsP.css('z-index', jsPanel.setZi(jsP));
+ }
+ }
+
+ /* option.bootstrap & option.theme -------------------------------------------------------------------------- */
+ if (jsP.option.bootstrap) {
+ // check whether a bootstrap compatible theme is used and set option.theme accordingly
+ jsP.option.theme = jsPanel.isBootstrapTheme(jsP.option.bootstrap);
+ jsP.option.controls.iconfont = 'bootstrap';
+ jsP.alterClass('jsPanel-theme-*', 'panel panel-' + jsP.option.theme);
+ jsP.header.alterClass('jsPanel-theme-*', 'panel-heading');
+ jsP.header.title.addClass('panel-title');
+ jsP.content.alterClass('jsPanel-theme-*', 'panel-body');
+ jsP.footer.addClass('panel-footer');
+ // fix css problems for panels nested in other bootstrap panels
+ jsP.header.title.css('color', function () {
+ return jsP.header.css('color');
+ });
+ jsP.content.css('border-top-color', function () {
+ return jsP.header.css('border-top-color');
+ });
+ } else {
+ // activate normal non bootstrap themes
+ var components = [jsP, jsP.header, jsP.content, jsP.footer];
+ components.forEach(function (elmt) {
+ $(elmt).alterClass('jsPanel-theme-*', 'jsPanel-theme-' + jsP.option.theme);
+ });
+ }
+
+ /* option.removeHeader; option.controls (buttons in header right) ------------------------------------------- */
+ if (jsP.option.removeHeader) {
+ jsP.header.remove();
+ } else {
+ jsPanel.configControls(jsP);
+ }
+
+ /* insert iconfonts if option.iconfont set (default is "jsglyph") */
+ if (jsP.option.controls.iconfont) {
+ jsPanel.configIconfont(jsP);
+ } else {
+ // if option.controls.iconfont === false restore old icon sprite
+ $('.jsPanel-btn-close, .jsPanel-btn-max, .jsPanel-btn-norm, .jsPanel-btn-min, .jsPanel-btn-small, .jsPanel-btn-smallrev', jsP.header.controls).empty();
+ }
+
+ /* option.toolbarHeader | default: false -------------------------------------------------------------------- */
+ if (jsP.option.toolbarHeader && jsP.option.removeHeader === false) {
+ if (typeof jsP.option.toolbarHeader === 'string') {
+ jsP.header.toolbar.append(jsP.option.toolbarHeader);
+ } else if ($.isFunction(jsP.option.toolbarHeader)) {
+ jsP.header.toolbar.append(jsP.option.toolbarHeader(jsP.header));
+ } else if ($.isArray(jsP.option.toolbarHeader)) {
+ jsPanel.configToolbar(jsP.option.toolbarHeader, jsP.header.toolbar, jsP);
+ }
+ // give toolbar the same font-family as title
+ jsP.header.toolbar.css("font-family", jsP.header.title.css("font-family"));
+ }
+
+ /* option.toolbarFooter | default: false -------------------------------------------------------------------- */
+ if (jsP.option.toolbarFooter) {
+ jsP.footer.css({
+ display: 'block'
+ });
+ if (typeof jsP.option.toolbarFooter === 'string') {
+ jsP.footer.append(jsP.option.toolbarFooter);
+ } else if ($.isFunction(jsP.option.toolbarFooter)) {
+ jsP.footer.append(jsP.option.toolbarFooter(jsP.footer));
+ } else if ($.isArray(jsP.option.toolbarFooter)) {
+ jsPanel.configToolbar(jsP.option.toolbarFooter, jsP.footer, jsP);
+ }
+ // give toolbar the same font-family as title
+ jsP.footer.css("font-family", jsP.header.title.css("font-family"));
+ }
+
+ /* option.rtl | default: false ------------------------------------------------------------------------------ */
+ if (jsP.option.rtl.rtl === true) {
+ jsPanel.setRTL(jsP, jsP.option.rtl.lang);
+ }
+
+ /* option.overflow | default: 'hidden' --------------------------------------------------------------------- */
+ if (typeof jsP.option.overflow === 'string') {
+ jsP.content.css('overflow', jsP.option.overflow);
+ } else if ($.isPlainObject(jsP.option.overflow)) {
+ jsP.content.css({
+ 'overflow-y': jsP.option.overflow.vertical,
+ 'overflow-x': jsP.option.overflow.horizontal
+ });
+ }
+
+ /* option.draggable ----------------------------------------------------------------------------------------- */
+ if ($.isPlainObject(jsP.option.draggable)) {
+ // if jsPanel is childpanel
+ if (jsP.parent().hasClass('jsPanel-content')) {
+ jsP.option.draggable.containment = 'parent';
+ }
+ // merge draggable settings and apply
+ jsP.option.customdraggable = $.extend(true, {}, $.jsPanel.defaults.draggable, jsP.option.draggable);
+ jsP.draggable(jsP.option.customdraggable);
+ } else if (jsP.option.draggable === 'disabled') {
+ // reset cursor, draggable deactivated
+ $('.jsPanel-title, .jsPanel-ftr', jsP).css('cursor', 'inherit');
+ // jquery ui draggable initialize disabled to allow to query status
+ jsP.draggable({ disabled: true });
+ }
+
+ /* option.resizable ----------------------------------------------------------------------------------------- */
+ if ($.isPlainObject(jsP.option.resizable)) {
+ jsP.option.customresizable = $.extend(true, {}, $.jsPanel.defaults.resizable, jsP.option.resizable);
+ jsP.resizable(jsP.option.customresizable);
+ } else if (jsP.option.resizable === 'disabled') {
+ // jquery ui resizable initialize disabled to allow to query status
+ jsP.resizable({ disabled: true });
+ $('.ui-icon-gripsmall-diagonal-se', jsP).css({ 'background-image': 'none', 'text-indent': -9999 });
+ $('.ui-resizable-handle', jsP).css({ 'cursor': 'inherit' });
+ }
+
+ /* option.content ------------------------------------------------------------------------------------------- */
+ // option.content can be any valid argument for jQuery.append()
+ if (jsP.option.content) {
+ jsP.content.append(jsP.option.content);
+ jsP.data("content", jsP.option.content);
+ }
+
+ /* option.load ---------------------------------------------------------------------------------------------- */
+ if ($.isPlainObject(jsP.option.load) && jsP.option.load.url) {
+ jsPanel.load(jsP);
+ }
+
+ /* option.ajax ---------------------------------------------------------------------------------------------- */
+ if ($.isPlainObject(jsP.option.ajax) && jsP.option.ajax.url) {
+ jsPanel.ajax(jsP);
+ }
+
+ /* option.size ---------------------------------------------------------------------------------------------- */
+ jsP.content.css({
+ width: jsP.option.size.width || 'auto',
+ height: jsP.option.size.height || 'auto'
+ });
+
+ // Important! limit title width; final adjustment follows later; otherwise title might be longer than panel width
+ jsP.header.title.css('width', jsP.content.width() - 90);
+
+ /* option.iframe -------------------------------------------------------------------------------------------- */
+ // implemented after option.size because option.size.width/height are either "auto" or pixel values already
+ if ($.isPlainObject(jsP.option.iframe) && (jsP.option.iframe.src || jsP.option.iframe.srcdoc)) {
+ jsPanel.iframe(jsP);
+ }
+
+ /* option.position ------------------------------------------------------------------------------------------ */
+ if (jsP.option.paneltype.type !== 'tooltip') {
+ // value "center" not allowed for option.position.bottom & option.position.right -> use top and/or left
+ // finally calculate & position the jsPanel
+ jsPanel.calcPanelposition(jsP);
+ }
+
+ /* option.addClass ------------------------------------------------------------------------------------------ */
+ if (typeof jsP.option.addClass.header === 'string') {
+ jsP.header.addClass(jsP.option.addClass.header);
+ }
+ if (typeof jsP.option.addClass.content === 'string') {
+ jsP.content.addClass(jsP.option.addClass.content);
+ }
+ if (typeof jsP.option.addClass.footer === 'string') {
+ jsP.footer.addClass(jsP.option.addClass.footer);
+ }
+
+ // handlers for doubleclicks -----------------------------------------------------------------------------------
+ // dblclicks disabled for normal modals, hints and tooltips
+ if (jsP.option.paneltype.mode !== "default") {
+ if (jsP.option.dblclicks) {
+ if (jsP.option.dblclicks.title) {
+ jsP.header.title.on('dblclick', function (e) {
+ e.preventDefault();
+ jsPanel.dblclickhelper(jsP.option.dblclicks.title, jsP);
+ });
+ }
+ if (jsP.option.dblclicks.content) {
+ jsP.content.on('dblclick', function (e) {
+ e.preventDefault();
+ jsPanel.dblclickhelper(jsP.option.dblclicks.content, jsP);
+ });
+ }
+ if (jsP.option.dblclicks.footer) {
+ jsP.footer.on('dblclick', function (e) {
+ e.preventDefault();
+ jsPanel.dblclickhelper(jsP.option.dblclicks.footer, jsP);
+ });
+ }
+ }
+ }
+
+ /* option.show ---------------------------------------------------------------------------------------------- */
+ if (!jsP.option.show) {
+ jsP.css({
+ display: 'block',
+ opacity: 1
+ });
+ $(jsP).trigger('jspanelloaded', jsP.attr('id'));
+ $(jsP).trigger('jspanelstatechange', jsP.attr('id'));
+ jsP.option.size = {
+ width: jsP.outerWidth(),
+ height: jsP.outerHeight()
+ };
+ } else if (jsP.option.show.indexOf(" ") === -1) {
+ // if no space is found in "jsP.option.show" -> function anwenden
+ jsP[jsP.option.show]({
+ done: function () {
+ // trigger custom event
+ $(jsP).trigger('jspanelloaded', jsP.attr('id'));
+ $(jsP).trigger('jspanelstatechange', jsP.attr('id'));
+ jsP.option.size = {
+ width: jsP.outerWidth(),
+ height: jsP.outerHeight()
+ };
+ }
+ });
+ } else {
+ // does not work with certain combinations of type of animation and positioning
+ jsP.css({
+ display: 'block',
+ opacity: 1
+ });
+ $(jsP).addClass(jsP.option.show);
+ $(jsP).trigger('jspanelloaded', jsP.attr('id'));
+ $(jsP).trigger('jspanelstatechange', jsP.attr('id'));
+ jsP.option.size = {
+ width: jsP.outerWidth(),
+ height: jsP.outerHeight()
+ };
+ }
+
+ /* needed if a maximized panel in body is normalized again -------------------------------------------------- */
+ // don't put this under $('body').on('jspanelloaded', function () { ... }
+ jsP.verticalOffset = jsPanel.calcVerticalOffset(jsP) || 0;
+
+ /* replace bottom/right values with corresponding top/left values if necessary ------------------------------ */
+ jsPanel.replaceCSSBottomRight(jsP);
+
+ /* option.title | needs to be late in the file! ------------------------------------------------------------- */
+ jsP.header.title.empty().prepend(jsP.option.title);
+ jsPanel.resizeTitle(jsP);
+
+ /* reposition hints while scrolling window, must be after normalization of position ------------------------- */
+ if (jsP.option.paneltype.type === 'hint') {
+ jsPanel.reposHintsScroll(jsP);
+ }
+
+ /* reposition jsPanel appended to body while scrolling window ----------------------------------------------- */
+ if (jsP.parentElmtTagname === 'body' && (jsP.option.paneltype.type !== 'tooltip' || jsP.option.paneltype.type !== 'hint')) {
+ jsPanel.fixPosition(jsP);
+ }
+
+ /* resizestart & resizestop & dragstop callbacks ------------------------------------------------------------ */
+ if (!jsP.option.paneltype || jsP.option.paneltype.mode !== 'default') {
+ // not needed for modals, hints and tooltips
+ $(jsP).on("resizestart", function () {
+ $("iframe", jsP.content).css("display", "none"); // on test
+ });
+
+ $(jsP).on("resize", function () {
+ // debugger;
+ // jquery ui resize event is also fired when panel is maximized or normalized (on request of Gareth Bult)
+ jsPanel.resizeContent(jsP);
+ jsPanel.resizeTitle(jsP);
+ });
+
+ $(jsP).on("resizestop", function () {
+
+ //alert('resized')
+ jsP.option.size = {
+ width: jsP.outerWidth(),
+ height: jsP.outerHeight()
+ };
+ if ($('.tools').length> 0) {
+ //nikita
+ if ($('#canvasDiv') != null) {
+ if (jsP.outerHeight() >= 435 && jsP.outerWidth() >= 650) {
+ // alert('resizestop')
+ $('#canvasDiv').css('height', jsP.outerHeight() - 85)
+ $('#canvasDiv').css('width', jsP.outerWidth() - 95)
+ $('#canvasDiv').css('overflow', 'scroll')
+ }
+ else {
+ $('#canvasDiv').css('height', jsP.outerHeight() - 110)
+ $('#canvasDiv').css('width', jsP.outerWidth() - 85)
+ $('#canvasDiv').css('overflow', 'scroll')
+ }
+ }
+ }
+ //nikita
+ // $('#leftToolBar').css('height', jsP.outerWidth())
+
+ jsPanel.updateStateProps(jsP, "normalized");
+ $(jsP).trigger('jspanelnormalized', jsP.attr('id'));
+ $(jsP).trigger('jspanelstatechange', jsP.attr('id'));
+ // controls und title zurücksetzen
+ jsPanel.hideControls(".jsPanel-btn-norm, .jsPanel-btn-smallrev", jsP);
+ $("iframe", jsP.content).css("display", "block"); // on test
+ });
+
+ $(jsP).on("dragstart", function () {
+ // alert("dragstart")
+ // debugger;
+ // remove window.scroll handler, is added again on dragstop
+ $(window).off('scroll', jsP.jsPanelfixPos);
+ if (jsP.option.paneltype.mode === 'extended') {
+ jsP.css('z-index', '1');
+ }
+ });
+
+ $(jsP).on("dragstop", function () {
+ // alert("dragstop")
+ // debugger;
+ jsP.option.position = {
+ top: jsP.css('top'),
+ left: jsP.css('left')
+ };
+ jsP.verticalOffset = jsPanel.calcVerticalOffset(jsP) || 0;
+ if (jsP.parentElmtTagname === 'body') {
+ jsPanel.fixPosition(jsP);
+ }
+ });
+
+ $(jsP).on("jspanelminimized", function () {
+ jsPanel.hideControls(".jsPanel-btn-min, .jsPanel-btn-small, .jsPanel-btn-smallrev, .jsPanel-btn-hide", jsP);
+ jsPanel.updateStateProps(jsP, "minimized");
+ $(window).off('scroll', jsP.jsPanelfixPos);
+ });
+
+ $(jsP).on("jspanelmaximized", function () {
+ // debugger;
+ jsPanel.resizeContent(jsP);
+ jsPanel.resizeTitle(jsP);
+ jsPanel.hideControls(".jsPanel-btn-max, .jsPanel-btn-smallrev", jsP);
+ jsPanel.updateStateProps(jsP, "maximized");
+ // additionally trigger the jQuery UI resize event (on request of Gareth Bult)
+ jsP.trigger("resize");
+ });
+
+ $(jsP).on("jspanelnormalized", function () {
+ jsPanel.hideControls(".jsPanel-btn-norm, .jsPanel-btn-smallrev", jsP);
+ jsPanel.resizeTitle(jsP);
+ jsPanel.resizeContent(jsP);
+ jsPanel.updateStateProps(jsP, "normalized");
+ // additionally trigger the jQuery UI resize event (on request of Gareth Bult)
+ jsP.trigger("resize");
+ });
+
+ }
+
+ /* option.autoclose | default: false --------------------------------------- */
+ if (typeof jsP.option.autoclose === 'number' && jsP.option.autoclose > 0) {
+ jsPanel.autoclose(jsP);
+ }
+
+ /* tooltip corrections ----------------------------------------------------- */
+ if (jsP.option.paneltype.type === "tooltip" && (jsP.option.paneltype.position === "top" || jsP.option.paneltype.position === "bottom")) {
+ jsPanel.shiftTooltipHorizontal(jsP, jsP.option.paneltype.shiftwithin);
+ } else if (jsP.option.paneltype.position === "left" || jsP.option.paneltype.position === "right") {
+ jsPanel.shiftTooltipVertical(jsP, jsP.option.paneltype.shiftwithin);
+ }
+
+ /* option.panelstatus --------------------------------------------------------------------------------------- */
+ if (jsP.option.panelstatus) {
+ switch (jsP.option.panelstatus) {
+ case "minimized":
+ jsPanel.minimize(jsP);
+ break;
+ case "maximized":
+ jsPanel.maximize(jsP);
+ break;
+ case ("smallified"):
+ jsPanel.smallify(jsP);
+ break;
+ case ("smallifiedMax"):
+ jsPanel.maximize(jsP);
+ jsPanel.smallify(jsP);
+ break;
+ }
+ } else {
+ jsPanel.updateStateProps(jsP, "normalized");
+ }
+
+ /* jsP.option.callback --------------------------------------------------------- */
+ if ($.isFunction(jsP.option.callback)) {
+ jsP.option.callback.call(jsP, jsP);
+ } else if ($.isArray(jsP.option.callback)) {
+ jsP.option.callback.forEach(function (item) {
+ if ($.isFunction(item)) {
+ item.call(jsP, jsP);
+ }
+ });
+ }
+
+
+ return jsP;
+ };
+
+ /* jsPanel.defaults */
+ $.jsPanel.defaults = {
+ "addClass": {
+ header: false,
+ content: false,
+ footer: false
+ },
+ "ajax": {
+ autoload: true
+ },
+ "autoclose": false,
+ "bootstrap": false,
+ "callback": undefined,
+ "content": false,
+ "controls": {
+ buttons: true,
+ iconfont: 'jsglyph',
+ close: false,
+ confirmClose: false,
+ maximize: false,
+ minimize: false,
+ normalize: false,
+ smallify: false,
+ maxtoScreen: false
+ },
+ "custom": false,
+ "dblclicks": false,
+ "draggable": {
+ handle: 'div.jsPanel-hdr, div.jsPanel-ftr',
+ stack: '.jsPanel',
+ opacity: 0.7
+ },
+ "id": function () {
+ jsPanel.ID += 1;
+ return 'jsPanel-' + jsPanel.ID;
+ },
+ "iframe": false,
+ "load": false,
+ "maximizedMargin": {
+ top: 5,
+ right: 5,
+ bottom: 5,
+ left: 5
+ },
+ "offset": {
+ top: 0,
+ left: 0
+ },
+ "onbeforeclose": false,
+ "onbeforemaximize": false,
+ "onbeforeminimize": false,
+ "onbeforenormalize": false,
+ "onclosed": false,
+ "oncmaximized": false,
+ "onminimized": false,
+ "onnormalized": false,
+ "overflow": 'hidden',
+ "panelstatus": false,
+ "paneltype": false,
+ "position": 'auto',
+ "removeHeader": false,
+ "resizable": {
+ handles: 'n, e, s, w, ne, se, sw, nw',
+ autoHide: false,
+ minWidth: 150,
+ minHeight: 93
+ },
+ "rtl": false,
+ "selector": 'body',
+ "show": 'fadeIn',
+ "size": {
+ width: '400px',
+ height: '222px'
+ },
+ "template": false,
+ "theme": 'default',
+ "title": 'jsPanel',
+ "toolbarFooter": false,
+ "toolbarHeader": false,
+ "currentController": '',
+ "parentSlug": ''
+
+ };
+
+
+ /*
+ * jQuery alterClass plugin
+ * Remove element classes with wildcard matching. Optionally add classes:
+ * $( '#foo' ).alterClass( 'foo-* bar-*', 'foobar' )
+ * Copyright (c) 2011 Pete Boere (the-echoplex.net)
+ * Free under terms of the MIT license: http://www.opensource.org/licenses/mit-license.php
+ */
+ $.fn.alterClass = function (removals, additions) {
+
+ var self = this,
+ patt;
+ if (removals.indexOf('*') === -1) {
+ // Use native jQuery methods if there is no wildcard matching
+ self.removeClass(removals);
+ return !additions ? self : self.addClass(additions);
+ }
+ patt = new RegExp('\\s' +
+ removals.replace(/\*/g, '[A-Za-z0-9-_]+').split(' ').join('\\s|\\s') +
+ '\\s', 'g');
+ self.each(function (i, it) {
+ var cn = ' ' + it.className + ' ';
+ while (patt.test(cn)) {
+ cn = cn.replace(patt, ' ');
+ }
+ it.className = $.trim(cn);
+ });
+ return !additions ? self : self.addClass(additions);
+ };
+
+ /* body click handler: remove all tooltips on click in body except click is inside tooltip */
+ $('body').click(function (e) {
+ var pID,
+ isTT = $(e.target).closest('.jsPanel-tt').length;
+ if (isTT < 1) {
+ $('.jsPanel-tt').each(function () {
+ pID = $(this).attr('id');
+ // if present remove tooltip wrapper and than remove tooltip
+ $('#' + pID).unwrap().remove();
+ $('body').trigger('jspanelclosed', pID);
+ });
+ }
+ });
+
+
+
+
+}(jQuery));
+
+/*
+ :: Number.isInteger() polyfill ::
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
+*/
+if (!Number.isInteger) {
+ Number.isInteger = function isInteger(nVal) {
+ "use strict";
+ return typeof nVal === 'number' && isFinite(nVal) && nVal > -9007199254740992 && nVal < 9007199254740992 && Math.floor(nVal) === nVal;
+ };
}
\ No newline at end of file