aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2023-04-20 14:28:22 -0400
committerB. Stack <bgstack15@gmail.com>2023-04-20 14:28:22 -0400
commitd5bc9bfd4f6a45e766b2371cc97108f31d4ff09e (patch)
treed8ade8b1b3a6618ece230a9f1417b23829f9f808
parentadd cal keyboard hotkeys (diff)
downloadradicaleinfcloud-d5bc9bfd4f6a45e766b2371cc97108f31d4ff09e.tar.gz
radicaleinfcloud-d5bc9bfd4f6a45e766b2371cc97108f31d4ff09e.tar.bz2
radicaleinfcloud-d5bc9bfd4f6a45e766b2371cc97108f31d4ff09e.zip
merge: add buttons for help and about
-rw-r--r--radicale_infcloud/web/css/default_integration.css37
-rw-r--r--radicale_infcloud/web/images/banner_about.svg61
-rw-r--r--radicale_infcloud/web/images/banner_help.svg61
-rw-r--r--radicale_infcloud/web/index.html26
-rw-r--r--radicale_infcloud/web/lib/jquery-ui-1.11.4.custom.js1257
-rw-r--r--radicale_infcloud/web/main.js22
6 files changed, 1462 insertions, 2 deletions
diff --git a/radicale_infcloud/web/css/default_integration.css b/radicale_infcloud/web/css/default_integration.css
index 35aa3c5..cdcba42 100644
--- a/radicale_infcloud/web/css/default_integration.css
+++ b/radicale_infcloud/web/css/default_integration.css
@@ -68,6 +68,43 @@
background: url(../images/banner_refresh.svg) no-repeat center;
}
+/* begin stackrpms */
+#intHelp
+{
+ background: url(../images/banner_help.svg) no-repeat center;
+}
+#intAbout
+{
+ background: url(../images/banner_about.svg) no-repeat center;
+}
+#helpDialog, #aboutDialog {
+ /* 25 is the main calendar */
+ z-index: 26;
+ display: none;
+ position: absolute;
+ top: -10rem;
+ min-width: 22rem;
+}
+#helpCloseButton, #aboutCloseButton {
+ position: absolute;
+ right: 0;
+ border: 1px solid #585858;
+ cursor: pointer;
+}
+/* reference https://helplogger.blogspot.com/2013/10/css-keyboard-keys-on-blogger.html */
+#helpDialog td, #aboutDialog td { padding: 5px 8px; }
+#helpDialog td kbd, #aboutDialog td kbd{
+ border:1px solid gray;
+ /*font-size:1.2em;*/
+ box-shadow:1px 0 1px 0 #eee, 0 2px 0 2px #ccc, 0 2px 0 3px #444;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ border-radius:3px;
+ margin:2px 3px;
+ padding:3px 5px;
+}
+/* end stackrpms */
+
#intLogout
{
background: url(../images/banner_logout.svg) no-repeat center;
diff --git a/radicale_infcloud/web/images/banner_about.svg b/radicale_infcloud/web/images/banner_about.svg
new file mode 100644
index 0000000..05384d4
--- /dev/null
+++ b/radicale_infcloud/web/images/banner_about.svg
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
+
+<svg
+ version="1.1"
+ x="0px"
+ y="0px"
+ width="36"
+ height="36"
+ viewBox="0 0 36 36"
+ overflow="visible"
+ enable-background="new 0 0 16 16"
+ xml:space="preserve"
+ id="svg2"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ sodipodi:docname="banner_about.svg"
+ style=""
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
+ id="metadata10"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1042"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="10.429825"
+ inkscape:cx="9.204373"
+ inkscape:cy="2.492851"
+ inkscape:window-x="1920"
+ inkscape:window-y="18"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" /><defs
+ id="defs4" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#585858"
+ d="M 33,36 3,36 C 1.3,36 0,34.7 0,33 L 0,5 C 0,3.3 1.3,2 3,2 l 30,0 c 1.7,0 3,1.3 3,3 l 0,28 c 0,1.7 -1.3,3 -3,3 z M 3,4 C 2.4,4 2,4.4 2,5 l 0,28 c 0,0.6 0.4,1 1,1 l 30,0 c 0.6,0 1,-0.4 1,-1 L 34,5 C 34,4.4 33.6,4 33,4 L 3,4 Z"
+ id="path5" /><text
+ xml:space="preserve"
+ style="font-size:29.3333px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';fill:#585858;fill-opacity:1;stroke-width:14.7817"
+ x="13.917974"
+ y="29.885405"
+ id="text897"><tspan
+ sodipodi:role="line"
+ id="tspan895"
+ x="13.917974"
+ y="29.885405"
+ style="font-size:29.3333px;fill:#585858;fill-opacity:1">i</tspan></text></svg>
diff --git a/radicale_infcloud/web/images/banner_help.svg b/radicale_infcloud/web/images/banner_help.svg
new file mode 100644
index 0000000..b339fa7
--- /dev/null
+++ b/radicale_infcloud/web/images/banner_help.svg
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
+
+<svg
+ version="1.1"
+ x="0px"
+ y="0px"
+ width="36"
+ height="36"
+ viewBox="0 0 36 36"
+ overflow="visible"
+ enable-background="new 0 0 16 16"
+ xml:space="preserve"
+ id="svg2"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ sodipodi:docname="banner_help.svg"
+ style=""
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
+ id="metadata10"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1042"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="10.429825"
+ inkscape:cx="9.1084942"
+ inkscape:cy="2.5407905"
+ inkscape:window-x="1920"
+ inkscape:window-y="18"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" /><defs
+ id="defs4" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#585858"
+ d="M 33,36 3,36 C 1.3,36 0,34.7 0,33 L 0,5 C 0,3.3 1.3,2 3,2 l 30,0 c 1.7,0 3,1.3 3,3 l 0,28 c 0,1.7 -1.3,3 -3,3 z M 3,4 C 2.4,4 2,4.4 2,5 l 0,28 c 0,0.6 0.4,1 1,1 l 30,0 c 0.6,0 1,-0.4 1,-1 L 34,5 C 34,4.4 33.6,4 33,4 L 3,4 Z"
+ id="path5" /><text
+ xml:space="preserve"
+ style="font-size:29.3333px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';fill:#585858;fill-opacity:1;stroke-width:14.7817"
+ x="10.186858"
+ y="29.885405"
+ id="text897"><tspan
+ sodipodi:role="line"
+ id="tspan895"
+ x="10.186858"
+ y="29.885405"
+ style="font-size:29.3333px;fill:#585858;fill-opacity:1">?</tspan></text></svg>
diff --git a/radicale_infcloud/web/index.html b/radicale_infcloud/web/index.html
index 7f36475..a0c8fd6 100644
--- a/radicale_infcloud/web/index.html
+++ b/radicale_infcloud/web/index.html
@@ -7,6 +7,7 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!--
+vim: set noet:
InfCloud - the open source CalDAV/CardDAV Web Client
Copyright (C) 2011-2015
Jan Mate <jan.mate@inf-it.com>
@@ -123,8 +124,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</div>
<div class="intBlank"></div>
<div id="intRefresh" title="refresh" onclick="reloadResources();"></div>
- <div class="intBlank"></div>
+ <div id="intHelp" title="Help" onclick="toggleHelpModal();"></div>
+ <div id="intAbout" title="About" onclick="toggleAboutModal();"></div>
<div id="intLogout" title="logout" onclick="logout();"></div>
+ <div id="helpDialog" title="Help dialog">
+ <div id="helpCloseButton">x</div>
+ <h2>Keyboard shortcuts</h2>
+ <table>
+ <tr><td><kbd>Ctrl</kbd><kbd>Enter</kbd></td><td>Save event dialog</td></tr>
+ <tr><td><kbd>Esc</kbd></td><td>Cancel/close event dialog</td></tr>
+ <tr><td><kbd>[</kbd>left square bracket</td><td>Toggle left panel</td></tr>
+ <tr><td><kbd>t</kbd> or <kbd>Home</kbd></td><td>Jump to today</td></tr>
+ <tr><td><kbd>PageUp</kbd></td><td>Previous page</td></tr>
+ <tr><td><kbd>Shift</kbd><kbd>PageUp</kbd></td><td>Go back 4 pages</td></tr>
+ <tr><td><kbd>Shift</kbd><kbd>PageDown</kbd></td><td>Go forward 4 pages</td></tr>
+ <tr><td><kbd>Ctrl</kbd><kbd>1</kbd></td><td>Month view</td></tr>
+ <tr><td><kbd>Ctrl</kbd><kbd>2</kbd></td><td>Multi-week view</td></tr>
+ <tr><td><kbd>Ctrl</kbd><kbd>3</kbd></td><td>Week view</td></tr>
+ <tr><td><kbd>Ctrl</kbd><kbd>4</kbd></td><td>Day view</td></tr>
+ </table>
+ </div>
+ <div id="aboutDialog" title="About dialog">
+ <div id="aboutCloseButton">x</div>
+ <h2>About infcloud</h2>
+ <div id="aboutContent">boilerplate</div>
+ </div>
</div>
<div class="System" id="SystemCalDavZAP">
<div id="CalDavZAPPopup">
diff --git a/radicale_infcloud/web/lib/jquery-ui-1.11.4.custom.js b/radicale_infcloud/web/lib/jquery-ui-1.11.4.custom.js
index fa650d7..8114968 100644
--- a/radicale_infcloud/web/lib/jquery-ui-1.11.4.custom.js
+++ b/radicale_infcloud/web/lib/jquery-ui-1.11.4.custom.js
@@ -1,6 +1,7 @@
/*! jQuery UI - v1.11.4 - 2015-03-15
* http://jqueryui.com
* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, autocomplete.js, datepicker.js, menu.js, slider.js
+* added back in button.js, dialog.js
* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
(function( factory ) {
@@ -5444,6 +5445,403 @@ var autocomplete = $.ui.autocomplete;
/*!
+ * jQuery UI Button 1.11.4
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/button/
+ */
+
+
+var lastActive,
+ baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
+ typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
+ formResetHandler = function() {
+ var form = $( this );
+ setTimeout(function() {
+ form.find( ":ui-button" ).button( "refresh" );
+ }, 1 );
+ },
+ radioGroup = function( radio ) {
+ var name = radio.name,
+ form = radio.form,
+ radios = $( [] );
+ if ( name ) {
+ name = name.replace( /'/g, "\\'" );
+ if ( form ) {
+ radios = $( form ).find( "[name='" + name + "'][type=radio]" );
+ } else {
+ radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
+ .filter(function() {
+ return !this.form;
+ });
+ }
+ }
+ return radios;
+ };
+
+$.widget( "ui.button", {
+ version: "1.11.4",
+ defaultElement: "<button>",
+ options: {
+ disabled: null,
+ text: true,
+ label: null,
+ icons: {
+ primary: null,
+ secondary: null
+ }
+ },
+ _create: function() {
+ this.element.closest( "form" )
+ .unbind( "reset" + this.eventNamespace )
+ .bind( "reset" + this.eventNamespace, formResetHandler );
+
+ if ( typeof this.options.disabled !== "boolean" ) {
+ this.options.disabled = !!this.element.prop( "disabled" );
+ } else {
+ this.element.prop( "disabled", this.options.disabled );
+ }
+
+ this._determineButtonType();
+ this.hasTitle = !!this.buttonElement.attr( "title" );
+
+ var that = this,
+ options = this.options,
+ toggleButton = this.type === "checkbox" || this.type === "radio",
+ activeClass = !toggleButton ? "ui-state-active" : "";
+
+ if ( options.label === null ) {
+ options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
+ }
+
+ this._hoverable( this.buttonElement );
+
+ this.buttonElement
+ .addClass( baseClasses )
+ .attr( "role", "button" )
+ .bind( "mouseenter" + this.eventNamespace, function() {
+ if ( options.disabled ) {
+ return;
+ }
+ if ( this === lastActive ) {
+ $( this ).addClass( "ui-state-active" );
+ }
+ })
+ .bind( "mouseleave" + this.eventNamespace, function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).removeClass( activeClass );
+ })
+ .bind( "click" + this.eventNamespace, function( event ) {
+ if ( options.disabled ) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+ });
+
+ // Can't use _focusable() because the element that receives focus
+ // and the element that gets the ui-state-focus class are different
+ this._on({
+ focus: function() {
+ this.buttonElement.addClass( "ui-state-focus" );
+ },
+ blur: function() {
+ this.buttonElement.removeClass( "ui-state-focus" );
+ }
+ });
+
+ if ( toggleButton ) {
+ this.element.bind( "change" + this.eventNamespace, function() {
+ that.refresh();
+ });
+ }
+
+ if ( this.type === "checkbox" ) {
+ this.buttonElement.bind( "click" + this.eventNamespace, function() {
+ if ( options.disabled ) {
+ return false;
+ }
+ });
+ } else if ( this.type === "radio" ) {
+ this.buttonElement.bind( "click" + this.eventNamespace, function() {
+ if ( options.disabled ) {
+ return false;
+ }
+ $( this ).addClass( "ui-state-active" );
+ that.buttonElement.attr( "aria-pressed", "true" );
+
+ var radio = that.element[ 0 ];
+ radioGroup( radio )
+ .not( radio )
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ });
+ } else {
+ this.buttonElement
+ .bind( "mousedown" + this.eventNamespace, function() {
+ if ( options.disabled ) {
+ return false;
+ }
+ $( this ).addClass( "ui-state-active" );
+ lastActive = this;
+ that.document.one( "mouseup", function() {
+ lastActive = null;
+ });
+ })
+ .bind( "mouseup" + this.eventNamespace, function() {
+ if ( options.disabled ) {
+ return false;
+ }
+ $( this ).removeClass( "ui-state-active" );
+ })
+ .bind( "keydown" + this.eventNamespace, function(event) {
+ if ( options.disabled ) {
+ return false;
+ }
+ if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
+ $( this ).addClass( "ui-state-active" );
+ }
+ })
+ // see #8559, we bind to blur here in case the button element loses
+ // focus between keydown and keyup, it would be left in an "active" state
+ .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
+ $( this ).removeClass( "ui-state-active" );
+ });
+
+ if ( this.buttonElement.is("a") ) {
+ this.buttonElement.keyup(function(event) {
+ if ( event.keyCode === $.ui.keyCode.SPACE ) {
+ // TODO pass through original event correctly (just as 2nd argument doesn't work)
+ $( this ).click();
+ }
+ });
+ }
+ }
+
+ this._setOption( "disabled", options.disabled );
+ this._resetButton();
+ },
+
+ _determineButtonType: function() {
+ var ancestor, labelSelector, checked;
+
+ if ( this.element.is("[type=checkbox]") ) {
+ this.type = "checkbox";
+ } else if ( this.element.is("[type=radio]") ) {
+ this.type = "radio";
+ } else if ( this.element.is("input") ) {
+ this.type = "input";
+ } else {
+ this.type = "button";
+ }
+
+ if ( this.type === "checkbox" || this.type === "radio" ) {
+ // we don't search against the document in case the element
+ // is disconnected from the DOM
+ ancestor = this.element.parents().last();
+ labelSelector = "label[for='" + this.element.attr("id") + "']";
+ this.buttonElement = ancestor.find( labelSelector );
+ if ( !this.buttonElement.length ) {
+ ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
+ this.buttonElement = ancestor.filter( labelSelector );
+ if ( !this.buttonElement.length ) {
+ this.buttonElement = ancestor.find( labelSelector );
+ }
+ }
+ this.element.addClass( "ui-helper-hidden-accessible" );
+
+ checked = this.element.is( ":checked" );
+ if ( checked ) {
+ this.buttonElement.addClass( "ui-state-active" );
+ }
+ this.buttonElement.prop( "aria-pressed", checked );
+ } else {
+ this.buttonElement = this.element;
+ }
+ },
+
+ widget: function() {
+ return this.buttonElement;
+ },
+
+ _destroy: function() {
+ this.element
+ .removeClass( "ui-helper-hidden-accessible" );
+ this.buttonElement
+ .removeClass( baseClasses + " ui-state-active " + typeClasses )
+ .removeAttr( "role" )
+ .removeAttr( "aria-pressed" )
+ .html( this.buttonElement.find(".ui-button-text").html() );
+
+ if ( !this.hasTitle ) {
+ this.buttonElement.removeAttr( "title" );
+ }
+ },
+
+ _setOption: function( key, value ) {
+ this._super( key, value );
+ if ( key === "disabled" ) {
+ this.widget().toggleClass( "ui-state-disabled", !!value );
+ this.element.prop( "disabled", !!value );
+ if ( value ) {
+ if ( this.type === "checkbox" || this.type === "radio" ) {
+ this.buttonElement.removeClass( "ui-state-focus" );
+ } else {
+ this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
+ }
+ }
+ return;
+ }
+ this._resetButton();
+ },
+
+ refresh: function() {
+ //See #8237 & #8828
+ var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
+
+ if ( isDisabled !== this.options.disabled ) {
+ this._setOption( "disabled", isDisabled );
+ }
+ if ( this.type === "radio" ) {
+ radioGroup( this.element[0] ).each(function() {
+ if ( $( this ).is( ":checked" ) ) {
+ $( this ).button( "widget" )
+ .addClass( "ui-state-active" )
+ .attr( "aria-pressed", "true" );
+ } else {
+ $( this ).button( "widget" )
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ }
+ });
+ } else if ( this.type === "checkbox" ) {
+ if ( this.element.is( ":checked" ) ) {
+ this.buttonElement
+ .addClass( "ui-state-active" )
+ .attr( "aria-pressed", "true" );
+ } else {
+ this.buttonElement
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ }
+ }
+ },
+
+ _resetButton: function() {
+ if ( this.type === "input" ) {
+ if ( this.options.label ) {
+ this.element.val( this.options.label );
+ }
+ return;
+ }
+ var buttonElement = this.buttonElement.removeClass( typeClasses ),
+ buttonText = $( "<span></span>", this.document[0] )
+ .addClass( "ui-button-text" )
+ .html( this.options.label )
+ .appendTo( buttonElement.empty() )
+ .text(),
+ icons = this.options.icons,
+ multipleIcons = icons.primary && icons.secondary,
+ buttonClasses = [];
+
+ if ( icons.primary || icons.secondary ) {
+ if ( this.options.text ) {
+ buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
+ }
+
+ if ( icons.primary ) {
+ buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
+ }
+
+ if ( icons.secondary ) {
+ buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
+ }
+
+ if ( !this.options.text ) {
+ buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
+
+ if ( !this.hasTitle ) {
+ buttonElement.attr( "title", $.trim( buttonText ) );
+ }
+ }
+ } else {
+ buttonClasses.push( "ui-button-text-only" );
+ }
+ buttonElement.addClass( buttonClasses.join( " " ) );
+ }
+});
+
+$.widget( "ui.buttonset", {
+ version: "1.11.4",
+ options: {
+ items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
+ },
+
+ _create: function() {
+ this.element.addClass( "ui-buttonset" );
+ },
+
+ _init: function() {
+ this.refresh();
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "disabled" ) {
+ this.buttons.button( "option", key, value );
+ }
+
+ this._super( key, value );
+ },
+
+ refresh: function() {
+ var rtl = this.element.css( "direction" ) === "rtl",
+ allButtons = this.element.find( this.options.items ),
+ existingButtons = allButtons.filter( ":ui-button" );
+
+ // Initialize new buttons
+ allButtons.not( ":ui-button" ).button();
+
+ // Refresh existing buttons
+ existingButtons.button( "refresh" );
+
+ this.buttons = allButtons
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
+ .filter( ":first" )
+ .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
+ .end()
+ .filter( ":last" )
+ .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
+ .end()
+ .end();
+ },
+
+ _destroy: function() {
+ this.element.removeClass( "ui-buttonset" );
+ this.buttons
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-corner-left ui-corner-right" )
+ .end()
+ .button( "destroy" );
+ }
+});
+
+var button = $.ui.button;
+
+
+/*!
* jQuery UI Datepicker 1.11.4
* http://jqueryui.com
*
@@ -7521,6 +7919,863 @@ var datepicker = $.datepicker;
/*!
+ * jQuery UI Dialog 1.11.4
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/dialog/
+ */
+
+
+var dialog = $.widget( "ui.dialog", {
+ version: "1.11.4",
+ options: {
+ appendTo: "body",
+ autoOpen: true,
+ buttons: [],
+ closeOnEscape: true,
+ closeText: "Close",
+ dialogClass: "",
+ draggable: true,
+ hide: null,
+ height: "auto",
+ maxHeight: null,
+ maxWidth: null,
+ minHeight: 150,
+ minWidth: 150,
+ modal: false,
+ position: {
+ my: "center",
+ at: "center",
+ of: window,
+ collision: "fit",
+ // Ensure the titlebar is always visible
+ using: function( pos ) {
+ var topOffset = $( this ).css( pos ).offset().top;
+ if ( topOffset < 0 ) {
+ $( this ).css( "top", pos.top - topOffset );
+ }
+ }
+ },
+ resizable: true,
+ show: null,
+ title: null,
+ width: 300,
+
+ // callbacks
+ beforeClose: null,
+ close: null,
+ drag: null,
+ dragStart: null,
+ dragStop: null,
+ focus: null,
+ open: null,
+ resize: null,
+ resizeStart: null,
+ resizeStop: null
+ },
+
+ sizeRelatedOptions: {
+ buttons: true,
+ height: true,
+ maxHeight: true,
+ maxWidth: true,
+ minHeight: true,
+ minWidth: true,
+ width: true
+ },
+
+ resizableRelatedOptions: {
+ maxHeight: true,
+ maxWidth: true,
+ minHeight: true,
+ minWidth: true
+ },
+
+ _create: function() {
+ this.originalCss = {
+ display: this.element[ 0 ].style.display,
+ width: this.element[ 0 ].style.width,
+ minHeight: this.element[ 0 ].style.minHeight,
+ maxHeight: this.element[ 0 ].style.maxHeight,
+ height: this.element[ 0 ].style.height
+ };
+ this.originalPosition = {
+ parent: this.element.parent(),
+ index: this.element.parent().children().index( this.element )
+ };
+ this.originalTitle = this.element.attr( "title" );
+ this.options.title = this.options.title || this.originalTitle;
+
+ this._createWrapper();
+
+ this.element
+ .show()
+ .removeAttr( "title" )
+ .addClass( "ui-dialog-content ui-widget-content" )
+ .appendTo( this.uiDialog );
+
+ this._createTitlebar();
+ this._createButtonPane();
+
+ if ( this.options.draggable && $.fn.draggable ) {
+ this._makeDraggable();
+ }
+ if ( this.options.resizable && $.fn.resizable ) {
+ this._makeResizable();
+ }
+
+ this._isOpen = false;
+
+ this._trackFocus();
+ },
+
+ _init: function() {
+ if ( this.options.autoOpen ) {
+ this.open();
+ }
+ },
+
+ _appendTo: function() {
+ var element = this.options.appendTo;
+ if ( element && (element.jquery || element.nodeType) ) {
+ return $( element );
+ }
+ return this.document.find( element || "body" ).eq( 0 );
+ },
+
+ _destroy: function() {
+ var next,
+ originalPosition = this.originalPosition;
+
+ this._untrackInstance();
+ this._destroyOverlay();
+
+ this.element
+ .removeUniqueId()
+ .removeClass( "ui-dialog-content ui-widget-content" )
+ .css( this.originalCss )
+ // Without detaching first, the following becomes really slow
+ .detach();
+
+ this.uiDialog.stop( true, true ).remove();
+
+ if ( this.originalTitle ) {
+ this.element.attr( "title", this.originalTitle );
+ }
+
+ next = originalPosition.parent.children().eq( originalPosition.index );
+ // Don't try to place the dialog next to itself (#8613)
+ if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
+ next.before( this.element );
+ } else {
+ originalPosition.parent.append( this.element );
+ }
+ },
+
+ widget: function() {
+ return this.uiDialog;
+ },
+
+ disable: $.noop,
+ enable: $.noop,
+
+ close: function( event ) {
+ var activeElement,
+ that = this;
+
+ if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
+ return;
+ }
+
+ this._isOpen = false;
+ this._focusedElement = null;
+ this._destroyOverlay();
+ this._untrackInstance();
+
+ if ( !this.opener.filter( ":focusable" ).focus().length ) {
+
+ // support: IE9
+ // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
+ try {
+ activeElement = this.document[ 0 ].activeElement;
+
+ // Support: IE9, IE10
+ // If the <body> is blurred, IE will switch windows, see #4520
+ if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
+
+ // Hiding a focused element doesn't trigger blur in WebKit
+ // so in case we have nothing to focus on, explicitly blur the active element
+ // https://bugs.webkit.org/show_bug.cgi?id=47182
+ $( activeElement ).blur();
+ }
+ } catch ( error ) {}
+ }
+
+ this._hide( this.uiDialog, this.options.hide, function() {
+ that._trigger( "close", event );
+ });
+ },
+
+ isOpen: function() {
+ return this._isOpen;
+ },
+
+ moveToTop: function() {
+ this._moveToTop();
+ },
+
+ _moveToTop: function( event, silent ) {
+ var moved = false,
+ zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
+ return +$( this ).css( "z-index" );
+ }).get(),
+ zIndexMax = Math.max.apply( null, zIndices );
+
+ if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
+ this.uiDialog.css( "z-index", zIndexMax + 1 );
+ moved = true;
+ }
+
+ if ( moved && !silent ) {
+ this._trigger( "focus", event );
+ }
+ return moved;
+ },
+
+ open: function() {
+ var that = this;
+ if ( this._isOpen ) {
+ if ( this._moveToTop() ) {
+ this._focusTabbable();
+ }
+ return;
+ }
+
+ this._isOpen = true;
+ this.opener = $( this.document[ 0 ].activeElement );
+
+ this._size();
+ this._position();
+ this._createOverlay();
+ this._moveToTop( null, true );
+
+ // Ensure the overlay is moved to the top with the dialog, but only when
+ // opening. The overlay shouldn't move after the dialog is open so that
+ // modeless dialogs opened after the modal dialog stack properly.
+ if ( this.overlay ) {
+ this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
+ }
+
+ this._show( this.uiDialog, this.options.show, function() {
+ that._focusTabbable();
+ that._trigger( "focus" );
+ });
+
+ // Track the dialog immediately upon openening in case a focus event
+ // somehow occurs outside of the dialog before an element inside the
+ // dialog is focused (#10152)
+ this._makeFocusTarget();
+
+ this._trigger( "open" );
+ },
+
+ _focusTabbable: function() {
+ // Set focus to the first match:
+ // 1. An element that was focused previously
+ // 2. First element inside the dialog matching [autofocus]
+ // 3. Tabbable element inside the content element
+ // 4. Tabbable element inside the buttonpane
+ // 5. The close button
+ // 6. The dialog itself
+ var hasFocus = this._focusedElement;
+ if ( !hasFocus ) {
+ hasFocus = this.element.find( "[autofocus]" );
+ }
+ if ( !hasFocus.length ) {
+ hasFocus = this.element.find( ":tabbable" );
+ }
+ if ( !hasFocus.length ) {
+ hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
+ }
+ if ( !hasFocus.length ) {
+ hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
+ }
+ if ( !hasFocus.length ) {
+ hasFocus = this.uiDialog;
+ }
+ hasFocus.eq( 0 ).focus();
+ },
+
+ _keepFocus: function( event ) {
+ function checkFocus() {
+ var activeElement = this.document[0].activeElement,
+ isActive = this.uiDialog[0] === activeElement ||
+ $.contains( this.uiDialog[0], activeElement );
+ if ( !isActive ) {
+ this._focusTabbable();
+ }
+ }
+ event.preventDefault();
+ checkFocus.call( this );
+ // support: IE
+ // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
+ // so we check again later
+ this._delay( checkFocus );
+ },
+
+ _createWrapper: function() {
+ this.uiDialog = $("<div>")
+ .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
+ this.options.dialogClass )
+ .hide()
+ .attr({
+ // Setting tabIndex makes the div focusable
+ tabIndex: -1,
+ role: "dialog"
+ })
+ .appendTo( this._appendTo() );
+
+ this._on( this.uiDialog, {
+ keydown: function( event ) {
+ if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
+ event.keyCode === $.ui.keyCode.ESCAPE ) {
+ event.preventDefault();
+ this.close( event );
+ return;
+ }
+
+ // prevent tabbing out of dialogs
+ if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
+ return;
+ }
+ var tabbables = this.uiDialog.find( ":tabbable" ),
+ first = tabbables.filter( ":first" ),
+ last = tabbables.filter( ":last" );
+
+ if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
+ this._delay(function() {
+ first.focus();
+ });
+ event.preventDefault();
+ } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
+ this._delay(function() {
+ last.focus();
+ });
+ event.preventDefault();
+ }
+ },
+ mousedown: function( event ) {
+ if ( this._moveToTop( event ) ) {
+ this._focusTabbable();
+ }
+ }
+ });
+
+ // We assume that any existing aria-describedby attribute means
+ // that the dialog content is marked up properly
+ // otherwise we brute force the content as the description
+ if ( !this.element.find( "[aria-describedby]" ).length ) {
+ this.uiDialog.attr({
+ "aria-describedby": this.element.uniqueId().attr( "id" )
+ });
+ }
+ },
+
+ _createTitlebar: function() {
+ var uiDialogTitle;
+
+ this.uiDialogTitlebar = $( "<div>" )
+ .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
+ .prependTo( this.uiDialog );
+ this._on( this.uiDialogTitlebar, {
+ mousedown: function( event ) {
+ // Don't prevent click on close button (#8838)
+ // Focusing a dialog that is partially scrolled out of view
+ // causes the browser to scroll it into view, preventing the click event
+ if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
+ // Dialog isn't getting focus when dragging (#8063)
+ this.uiDialog.focus();
+ }
+ }
+ });
+
+ // support: IE
+ // Use type="button" to prevent enter keypresses in textboxes from closing the
+ // dialog in IE (#9312)
+ this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
+ .button({
+ label: this.options.closeText,
+ icons: {
+ primary: "ui-icon-closethick"
+ },
+ text: false
+ })
+ .addClass( "ui-dialog-titlebar-close" )
+ .appendTo( this.uiDialogTitlebar );
+ this._on( this.uiDialogTitlebarClose, {
+ click: function( event ) {
+ event.preventDefault();
+ this.close( event );
+ }
+ });
+
+ uiDialogTitle = $( "<span>" )
+ .uniqueId()
+ .addClass( "ui-dialog-title" )
+ .prependTo( this.uiDialogTitlebar );
+ this._title( uiDialogTitle );
+
+ this.uiDialog.attr({
+ "aria-labelledby": uiDialogTitle.attr( "id" )
+ });
+ },
+
+ _title: function( title ) {
+ if ( !this.options.title ) {
+ title.html( "&#160;" );
+ }
+ title.text( this.options.title );
+ },
+
+ _createButtonPane: function() {
+ this.uiDialogButtonPane = $( "<div>" )
+ .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
+
+ this.uiButtonSet = $( "<div>" )
+ .addClass( "ui-dialog-buttonset" )
+ .appendTo( this.uiDialogButtonPane );
+
+ this._createButtons();
+ },
+
+ _createButtons: function() {
+ var that = this,
+ buttons = this.options.buttons;
+
+ // if we already have a button pane, remove it
+ this.uiDialogButtonPane.remove();
+ this.uiButtonSet.empty();
+
+ if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
+ this.uiDialog.removeClass( "ui-dialog-buttons" );
+ return;
+ }
+
+ $.each( buttons, function( name, props ) {
+ var click, buttonOptions;
+ props = $.isFunction( props ) ?
+ { click: props, text: name } :
+ props;
+ // Default to a non-submitting button
+ props = $.extend( { type: "button" }, props );
+ // Change the context for the click callback to be the main element
+ click = props.click;
+ props.click = function() {
+ click.apply( that.element[ 0 ], arguments );
+ };
+ buttonOptions = {
+ icons: props.icons,
+ text: props.showText
+ };
+ delete props.icons;
+ delete props.showText;
+ $( "<button></button>", props )
+ .button( buttonOptions )
+ .appendTo( that.uiButtonSet );
+ });
+ this.uiDialog.addClass( "ui-dialog-buttons" );
+ this.uiDialogButtonPane.appendTo( this.uiDialog );
+ },
+
+ _makeDraggable: function() {
+ var that = this,
+ options = this.options;
+
+ function filteredUi( ui ) {
+ return {
+ position: ui.position,
+ offset: ui.offset
+ };
+ }
+
+ this.uiDialog.draggable({
+ cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
+ handle: ".ui-dialog-titlebar",
+ containment: "document",
+ start: function( event, ui ) {
+ $( this ).addClass( "ui-dialog-dragging" );
+ that._blockFrames();
+ that._trigger( "dragStart", event, filteredUi( ui ) );
+ },
+ drag: function( event, ui ) {
+ that._trigger( "drag", event, filteredUi( ui ) );
+ },
+ stop: function( event, ui ) {
+ var left = ui.offset.left - that.document.scrollLeft(),
+ top = ui.offset.top - that.document.scrollTop();
+
+ options.position = {
+ my: "left top",
+ at: "left" + (left >= 0 ? "+" : "") + left + " " +
+ "top" + (top >= 0 ? "+" : "") + top,
+ of: that.window
+ };
+ $( this ).removeClass( "ui-dialog-dragging" );
+ that._unblockFrames();
+ that._trigger( "dragStop", event, filteredUi( ui ) );
+ }
+ });
+ },
+
+ _makeResizable: function() {
+ var that = this,
+ options = this.options,
+ handles = options.resizable,
+ // .ui-resizable has position: relative defined in the stylesheet
+ // but dialogs have to use absolute or fixed positioning
+ position = this.uiDialog.css("position"),
+ resizeHandles = typeof handles === "string" ?
+ handles :
+ "n,e,s,w,se,sw,ne,nw";
+
+ function filteredUi( ui ) {
+ return {
+ originalPosition: ui.originalPosition,
+ originalSize: ui.originalSize,
+ position: ui.position,
+ size: ui.size
+ };
+ }
+
+ this.uiDialog.resizable({
+ cancel: ".ui-dialog-content",
+ containment: "document",
+ alsoResize: this.element,
+ maxWidth: options.maxWidth,
+ maxHeight: options.maxHeight,
+ minWidth: options.minWidth,
+ minHeight: this._minHeight(),
+ handles: resizeHandles,
+ start: function( event, ui ) {
+ $( this ).addClass( "ui-dialog-resizing" );
+ that._blockFrames();
+ that._trigger( "resizeStart", event, filteredUi( ui ) );
+ },
+ resize: function( event, ui ) {
+ that._trigger( "resize", event, filteredUi( ui ) );
+ },
+ stop: function( event, ui ) {
+ var offset = that.uiDialog.offset(),
+ left = offset.left - that.document.scrollLeft(),
+ top = offset.top - that.document.scrollTop();
+
+ options.height = that.uiDialog.height();
+ options.width = that.uiDialog.width();
+ options.position = {
+ my: "left top",
+ at: "left" + (left >= 0 ? "+" : "") + left + " " +
+ "top" + (top >= 0 ? "+" : "") + top,
+ of: that.window
+ };
+ $( this ).removeClass( "ui-dialog-resizing" );
+ that._unblockFrames();
+ that._trigger( "resizeStop", event, filteredUi( ui ) );
+ }
+ })
+ .css( "position", position );
+ },
+
+ _trackFocus: function() {
+ this._on( this.widget(), {
+ focusin: function( event ) {
+ this._makeFocusTarget();
+ this._focusedElement = $( event.target );
+ }
+ });
+ },
+
+ _makeFocusTarget: function() {
+ this._untrackInstance();
+ this._trackingInstances().unshift( this );
+ },
+
+ _untrackInstance: function() {
+ var instances = this._trackingInstances(),
+ exists = $.inArray( this, instances );
+ if ( exists !== -1 ) {
+ instances.splice( exists, 1 );
+ }
+ },
+
+ _trackingInstances: function() {
+ var instances = this.document.data( "ui-dialog-instances" );
+ if ( !instances ) {
+ instances = [];
+ this.document.data( "ui-dialog-instances", instances );
+ }
+ return instances;
+ },
+
+ _minHeight: function() {
+ var options = this.options;
+
+ return options.height === "auto" ?
+ options.minHeight :
+ Math.min( options.minHeight, options.height );
+ },
+
+ _position: function() {
+ // Need to show the dialog to get the actual offset in the position plugin
+ var isVisible = this.uiDialog.is( ":visible" );
+ if ( !isVisible ) {
+ this.uiDialog.show();
+ }
+ this.uiDialog.position( this.options.position );
+ if ( !isVisible ) {
+ this.uiDialog.hide();
+ }
+ },
+
+ _setOptions: function( options ) {
+ var that = this,
+ resize = false,
+ resizableOptions = {};
+
+ $.each( options, function( key, value ) {
+ that._setOption( key, value );
+
+ if ( key in that.sizeRelatedOptions ) {
+ resize = true;
+ }
+ if ( key in that.resizableRelatedOptions ) {
+ resizableOptions[ key ] = value;
+ }
+ });
+
+ if ( resize ) {
+ this._size();
+ this._position();
+ }
+ if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
+ this.uiDialog.resizable( "option", resizableOptions );
+ }
+ },
+
+ _setOption: function( key, value ) {
+ var isDraggable, isResizable,
+ uiDialog = this.uiDialog;
+
+ if ( key === "dialogClass" ) {
+ uiDialog
+ .removeClass( this.options.dialogClass )
+ .addClass( value );
+ }
+
+ if ( key === "disabled" ) {
+ return;
+ }
+
+ this._super( key, value );
+
+ if ( key === "appendTo" ) {
+ this.uiDialog.appendTo( this._appendTo() );
+ }
+
+ if ( key === "buttons" ) {
+ this._createButtons();
+ }
+
+ if ( key === "closeText" ) {
+ this.uiDialogTitlebarClose.button({
+ // Ensure that we always pass a string
+ label: "" + value
+ });
+ }
+
+ if ( key === "draggable" ) {
+ isDraggable = uiDialog.is( ":data(ui-draggable)" );
+ if ( isDraggable && !value ) {
+ uiDialog.draggable( "destroy" );
+ }
+
+ if ( !isDraggable && value ) {
+ this._makeDraggable();
+ }
+ }
+
+ if ( key === "position" ) {
+ this._position();
+ }
+
+ if ( key === "resizable" ) {
+ // currently resizable, becoming non-resizable
+ isResizable = uiDialog.is( ":data(ui-resizable)" );
+ if ( isResizable && !value ) {
+ uiDialog.resizable( "destroy" );
+ }
+
+ // currently resizable, changing handles
+ if ( isResizable && typeof value === "string" ) {
+ uiDialog.resizable( "option", "handles", value );
+ }
+
+ // currently non-resizable, becoming resizable
+ if ( !isResizable && value !== false ) {
+ this._makeResizable();
+ }
+ }
+
+ if ( key === "title" ) {
+ this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
+ }
+ },
+
+ _size: function() {
+ // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+ // divs will both have width and height set, so we need to reset them
+ var nonContentHeight, minContentHeight, maxContentHeight,
+ options = this.options;
+
+ // Reset content sizing
+ this.element.show().css({
+ width: "auto",
+ minHeight: 0,
+ maxHeight: "none",
+ height: 0
+ });
+
+ if ( options.minWidth > options.width ) {
+ options.width = options.minWidth;
+ }
+
+ // reset wrapper sizing
+ // determine the height of all the non-content elements
+ nonContentHeight = this.uiDialog.css({
+ height: "auto",
+ width: options.width
+ })
+ .outerHeight();
+ minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
+ maxContentHeight = typeof options.maxHeight === "number" ?
+ Math.max( 0, options.maxHeight - nonContentHeight ) :
+ "none";
+
+ if ( options.height === "auto" ) {
+ this.element.css({
+ minHeight: minContentHeight,
+ maxHeight: maxContentHeight,
+ height: "auto"
+ });
+ } else {
+ this.element.height( Math.max( 0, options.height - nonContentHeight ) );
+ }
+
+ if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
+ this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
+ }
+ },
+
+ _blockFrames: function() {
+ this.iframeBlocks = this.document.find( "iframe" ).map(function() {
+ var iframe = $( this );
+
+ return $( "<div>" )
+ .css({
+ position: "absolute",
+ width: iframe.outerWidth(),
+ height: iframe.outerHeight()
+ })
+ .appendTo( iframe.parent() )
+ .offset( iframe.offset() )[0];
+ });
+ },
+
+ _unblockFrames: function() {
+ if ( this.iframeBlocks ) {
+ this.iframeBlocks.remove();
+ delete this.iframeBlocks;
+ }
+ },
+
+ _allowInteraction: function( event ) {
+ if ( $( event.target ).closest( ".ui-dialog" ).length ) {
+ return true;
+ }
+
+ // TODO: Remove hack when datepicker implements
+ // the .ui-front logic (#8989)
+ return !!$( event.target ).closest( ".ui-datepicker" ).length;
+ },
+
+ _createOverlay: function() {
+ if ( !this.options.modal ) {
+ return;
+ }
+
+ // We use a delay in case the overlay is created from an
+ // event that we're going to be cancelling (#2804)
+ var isOpening = true;
+ this._delay(function() {
+ isOpening = false;
+ });
+
+ if ( !this.document.data( "ui-dialog-overlays" ) ) {
+
+ // Prevent use of anchors and inputs
+ // Using _on() for an event handler shared across many instances is
+ // safe because the dialogs stack and must be closed in reverse order
+ this._on( this.document, {
+ focusin: function( event ) {
+ if ( isOpening ) {
+ return;
+ }
+
+ if ( !this._allowInteraction( event ) ) {
+ event.preventDefault();
+ this._trackingInstances()[ 0 ]._focusTabbable();
+ }
+ }
+ });
+ }
+
+ this.overlay = $( "<div>" )
+ .addClass( "ui-widget-overlay ui-front" )
+ .appendTo( this._appendTo() );
+ this._on( this.overlay, {
+ mousedown: "_keepFocus"
+ });
+ this.document.data( "ui-dialog-overlays",
+ (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
+ },
+
+ _destroyOverlay: function() {
+ if ( !this.options.modal ) {
+ return;
+ }
+
+ if ( this.overlay ) {
+ var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
+
+ if ( !overlays ) {
+ this.document
+ .unbind( "focusin" )
+ .removeData( "ui-dialog-overlays" );
+ } else {
+ this.document.data( "ui-dialog-overlays", overlays );
+ }
+
+ this.overlay.remove();
+ this.overlay = null;
+ }
+ }
+});
+
+
+/*!
* jQuery UI Slider 1.11.4
* http://jqueryui.com
*
@@ -8223,4 +9478,4 @@ var slider = $.widget( "ui.slider", $.ui.mouse, {
-})); \ No newline at end of file
+}));
diff --git a/radicale_infcloud/web/main.js b/radicale_infcloud/web/main.js
index a84afb5..c23b463 100644
--- a/radicale_infcloud/web/main.js
+++ b/radicale_infcloud/web/main.js
@@ -606,6 +606,16 @@ function login()
});
}
+/* begin stackrpms Help modal */
+function toggleHelpModal() {
+ console.log("toggleHelpModal was run!");
+ $("#helpDialog").css('display', 'block');
+}
+function toggleAboutModal() {
+ $("#aboutDialog").css('display', 'block');
+}
+/* end stackrpms Help modal */
+
function logout(forceLogout)
{
if((typeof forceLogout=='undefined' || forceLogout==null ) && (
@@ -799,6 +809,18 @@ function loadConfig()
// Automatically detect crossDomain settings
var detectedHref=location.protocol+'//'+location.hostname+(location.port ? ':'+location.port : '');
+ /* begin stackrpms help and about buttons */
+ $("#helpDialog").dialog({autoOpen:false,modal:true});
+ $("#intHelp").on("click",function() { $("#helpDialog").dialog("open"); });
+ $("#helpCloseButton").on("click",function() { $("#helpDialog").dialog("close"); });
+ $('#intHelp').prev().addBack().css('display', 'block');
+ $("#aboutDialog").dialog({autoOpen:false,modal:true});
+ $("#intAbout").on("click",function() { $("#aboutDialog").dialog("open"); });
+ $("#aboutCloseButton").on("click",function() { $("#aboutDialog").dialog("close"); });
+ $('#intAbout').prev().addBack().css('display', 'block');
+ $('#aboutContent').html(globalVersion);
+ /* end stackrpms */
+
// check username and password against the server and create config from globalNetworkCheckSettings
if(typeof globalNetworkCheckSettings!='undefined' && globalNetworkCheckSettings!=null)
{
bgstack15