Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>pull/13881/head
parent
2682d672d8
commit
3ced9cd83d
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,127 +0,0 @@ |
||||
/* |
||||
* @name Show Password |
||||
* @description |
||||
* @version 1.3 |
||||
* @requires Jquery 1.5 |
||||
* |
||||
* @author Jan Jarfalk |
||||
* @author-email jan.jarfalk@unwrongest.com |
||||
* @author-website http://www.unwrongest.com
|
||||
* |
||||
* @special-thanks Michel Gratton |
||||
* |
||||
* @licens MIT License - http://www.opensource.org/licenses/mit-license.php
|
||||
*/ |
||||
(function($){ |
||||
$.fn.extend({ |
||||
showPassword: function(c) {
|
||||
|
||||
// Setup callback object
|
||||
var callback = {'fn':null,'args':{}}; |
||||
callback.fn = c; |
||||
|
||||
// Clones passwords and turn the clones into text inputs
|
||||
var cloneElement = function( element ) { |
||||
|
||||
var $element = $(element); |
||||
|
||||
var $clone = $("<input />"); |
||||
|
||||
// Name added for JQuery Validation compatibility
|
||||
// Element name is required to avoid script warning.
|
||||
$clone.attr({ |
||||
'type' : 'text', |
||||
'class' : $element.attr('class'), |
||||
'style' : $element.attr('style'), |
||||
'size' : $element.attr('size'), |
||||
'name' : $element.attr('name')+'-clone', |
||||
'tabindex' : $element.attr('tabindex'), |
||||
'autocomplete' : 'off' |
||||
}); |
||||
|
||||
if($element.attr('placeholder') !== undefined) { |
||||
$clone.attr('placeholder', $element.attr('placeholder')); |
||||
} |
||||
|
||||
return $clone; |
||||
|
||||
}; |
||||
|
||||
// Transfers values between two elements
|
||||
var update = function(a,b){ |
||||
b.val(a.val()); |
||||
}; |
||||
|
||||
// Shows a or b depending on checkbox
|
||||
var setState = function( checkbox, a, b ){ |
||||
|
||||
if(checkbox.is(':checked')){ |
||||
update(a,b); |
||||
b.show(); |
||||
a.hide(); |
||||
} else { |
||||
update(b,a); |
||||
b.hide(); |
||||
a.show(); |
||||
} |
||||
|
||||
}; |
||||
|
||||
return this.each(function() { |
||||
|
||||
var $input = $(this), |
||||
$checkbox = $($input.data('typetoggle')); |
||||
|
||||
// Create clone
|
||||
var $clone = cloneElement($input); |
||||
$clone.insertAfter($input); |
||||
|
||||
// Set callback arguments
|
||||
if(callback.fn){
|
||||
callback.args.input = $input; |
||||
callback.args.checkbox = $checkbox; |
||||
callback.args.clone = $clone; |
||||
} |
||||
|
||||
|
||||
|
||||
$checkbox.bind('click', function() { |
||||
setState( $checkbox, $input, $clone ); |
||||
}); |
||||
|
||||
$input.bind('keyup', function() { |
||||
update( $input, $clone ); |
||||
}); |
||||
|
||||
$clone.bind('keyup', function(){
|
||||
update( $clone, $input ); |
||||
|
||||
// Added for JQuery Validation compatibility
|
||||
// This will trigger validation if it's ON for keyup event
|
||||
$input.trigger('keyup'); |
||||
|
||||
}); |
||||
|
||||
// Added for JQuery Validation compatibility
|
||||
// This will trigger validation if it's ON for blur event
|
||||
$clone.bind('blur', function() { $input.trigger('focusout'); }); |
||||
|
||||
setState( $checkbox, $input, $clone ); |
||||
|
||||
// set type of password field clone (type=text) to password right on submit
|
||||
// to prevent browser save the value of this field
|
||||
$clone.closest('form').submit(function(e) { |
||||
// .prop has to be used, because .attr throws
|
||||
// an error while changing a type of an input
|
||||
// element
|
||||
$clone.prop('type', 'password'); |
||||
}); |
||||
|
||||
if( callback.fn ){ |
||||
callback.fn( callback.args ); |
||||
} |
||||
|
||||
}); |
||||
} |
||||
}); |
||||
})(jQuery); |
||||
@ -1,146 +0,0 @@ |
||||
/** |
||||
* Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it> |
||||
* This file is licensed under the Affero General Public License version 3 or |
||||
* later. |
||||
* See the COPYING-README file. |
||||
*/ |
||||
|
||||
/** |
||||
* This plugin inserts the right avatar for the user, depending on, whether a |
||||
* custom avatar is uploaded - which it uses then - or not, and display a |
||||
* placeholder with the first letter of the users name instead. |
||||
* For this it queries the core_avatar_get route, thus this plugin is fit very |
||||
* tightly for owncloud, and it may not work anywhere else. |
||||
* |
||||
* You may use this on any <div></div> |
||||
* Here I'm using <div class="avatardiv"></div> as an example. |
||||
* |
||||
* There are 5 ways to call this: |
||||
* |
||||
* 1. $('.avatardiv').avatar('jdoe', 128); |
||||
* This will make the div to jdoe's fitting avatar, with a size of 128px. |
||||
* |
||||
* 2. $('.avatardiv').avatar('jdoe'); |
||||
* This will make the div to jdoe's fitting avatar. If the div already has a |
||||
* height, it will be used for the avatars size. Otherwise this plugin will |
||||
* search for 'size' DOM data, to use for avatar size. If neither are available |
||||
* it will default to 64px. |
||||
* |
||||
* 3. $('.avatardiv').avatar(); |
||||
* This will search the DOM for 'user' data, to use as the username. If there |
||||
* is no username available it will default to a placeholder with the value of |
||||
* "?". The size will be determined the same way, as the second example. |
||||
* |
||||
* 4. $('.avatardiv').avatar('jdoe', 128, true); |
||||
* This will behave like the first example, except it will also append random |
||||
* hashes to the custom avatar images, to force image reloading in IE8. |
||||
* |
||||
* 5. $('.avatardiv').avatar('jdoe', 128, undefined, true); |
||||
* This will behave like the first example, but it will hide the avatardiv, if |
||||
* it will display the default placeholder. undefined is the ie8fix from |
||||
* example 4 and can be either true, or false/undefined, to be ignored. |
||||
* |
||||
* 6. $('.avatardiv').avatar('jdoe', 128, undefined, true, callback); |
||||
* This will behave like the above example, but it will call the function |
||||
* defined in callback after the avatar is placed into the DOM. |
||||
* |
||||
*/ |
||||
|
||||
(function ($) { |
||||
$.fn.avatar = function(user, size, ie8fix, hidedefault, callback, displayname) { |
||||
var setAvatarForUnknownUser = function(target) { |
||||
target.imageplaceholder('?'); |
||||
target.css('background-color', '#b9b9b9'); |
||||
}; |
||||
|
||||
if (typeof(user) !== 'undefined') { |
||||
user = String(user); |
||||
} |
||||
if (typeof(displayname) !== 'undefined') { |
||||
displayname = String(displayname); |
||||
} |
||||
|
||||
if (typeof(size) === 'undefined') { |
||||
if (this.height() > 0) { |
||||
size = this.height(); |
||||
} else if (this.data('size') > 0) { |
||||
size = this.data('size'); |
||||
} else { |
||||
size = 64; |
||||
} |
||||
} |
||||
|
||||
this.height(size); |
||||
this.width(size); |
||||
|
||||
if (typeof(user) === 'undefined') { |
||||
if (typeof(this.data('user')) !== 'undefined') { |
||||
user = this.data('user'); |
||||
} else { |
||||
setAvatarForUnknownUser(this); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
// sanitize
|
||||
user = String(user).replace(/\//g,''); |
||||
|
||||
var $div = this; |
||||
var url; |
||||
|
||||
// If this is our own avatar we have to use the version attribute
|
||||
if (user === OC.getCurrentUser().uid) { |
||||
url = OC.generateUrl( |
||||
'/avatar/{user}/{size}?v={version}', |
||||
{ |
||||
user: user, |
||||
size: Math.ceil(size * window.devicePixelRatio), |
||||
version: oc_userconfig.avatar.version |
||||
}); |
||||
} else { |
||||
url = OC.generateUrl( |
||||
'/avatar/{user}/{size}', |
||||
{ |
||||
user: user, |
||||
size: Math.ceil(size * window.devicePixelRatio) |
||||
}); |
||||
} |
||||
|
||||
var img = new Image(); |
||||
|
||||
// If the new image loads successfully set it.
|
||||
img.onload = function() { |
||||
$div.clearimageplaceholder(); |
||||
$div.append(img); |
||||
|
||||
if(typeof callback === 'function') { |
||||
callback(); |
||||
} |
||||
}; |
||||
// Fallback when avatar loading fails:
|
||||
// Use old placeholder when a displayname attribute is defined,
|
||||
// otherwise show the unknown user placeholder.
|
||||
img.onerror = function () { |
||||
$div.clearimageplaceholder(); |
||||
if (typeof(displayname) !== 'undefined') { |
||||
$div.imageplaceholder(user, displayname); |
||||
} else { |
||||
setAvatarForUnknownUser($div); |
||||
} |
||||
|
||||
if(typeof callback === 'function') { |
||||
callback(); |
||||
} |
||||
}; |
||||
|
||||
if (size < 32) { |
||||
$div.addClass('icon-loading-small'); |
||||
} else { |
||||
$div.addClass('icon-loading'); |
||||
} |
||||
img.width = size; |
||||
img.height = size; |
||||
img.src = url; |
||||
img.alt = ''; |
||||
}; |
||||
}(jQuery)); |
||||
@ -1,110 +0,0 @@ |
||||
/** |
||||
* Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
||||
* This file is licensed under the Affero General Public License version 3 or |
||||
* later. |
||||
* See the COPYING-README file. |
||||
*/ |
||||
|
||||
(function ($) { |
||||
|
||||
var LIST = '' |
||||
+ '<div class="menu popovermenu menu-left hidden contactsmenu-popover">' |
||||
+ ' <ul>' |
||||
+ ' <li>' |
||||
+ ' <a>' |
||||
+ ' <span class="icon-loading-small"></span>' |
||||
+ ' </a>' |
||||
+ ' </li>' |
||||
+ ' </ul>' |
||||
+ '</div>'; |
||||
|
||||
$.fn.contactsMenu = function(shareWith, shareType, appendTo) { |
||||
// 0 - user, 4 - email, 6 - remote
|
||||
var allowedTypes = [0, 4, 6]; |
||||
if (allowedTypes.indexOf(shareType) === -1) { |
||||
return; |
||||
} |
||||
|
||||
var $div = this; |
||||
appendTo.append(LIST); |
||||
var $list = appendTo.find('div.contactsmenu-popover'); |
||||
|
||||
$div.click(function() { |
||||
if (!$list.hasClass('hidden')) { |
||||
$list.addClass('hidden'); |
||||
$list.hide(); |
||||
return; |
||||
} |
||||
|
||||
$list.removeClass('hidden'); |
||||
$list.show(); |
||||
|
||||
if ($list.hasClass('loaded')) { |
||||
return; |
||||
} |
||||
|
||||
$list.addClass('loaded'); |
||||
$.ajax(OC.generateUrl('/contactsmenu/findOne'), { |
||||
method: 'POST', |
||||
data: { |
||||
shareType: shareType, |
||||
shareWith: shareWith |
||||
} |
||||
}).then(function(data) { |
||||
$list.find('ul').find('li').addClass('hidden'); |
||||
|
||||
var actions; |
||||
if (!data.topAction) { |
||||
actions = [{ |
||||
hyperlink: '#', |
||||
title: t('core', 'No action available') |
||||
}]; |
||||
} else { |
||||
actions = [data.topAction].concat(data.actions); |
||||
} |
||||
|
||||
actions.forEach(function(action) { |
||||
var template = OC.ContactsMenu.Templates['jquery_entry']; |
||||
$list.find('ul').append(template(action)); |
||||
}); |
||||
|
||||
if (actions.length === 0) { |
||||
|
||||
} |
||||
}, function(jqXHR) { |
||||
$list.find('ul').find('li').addClass('hidden'); |
||||
|
||||
var title; |
||||
if (jqXHR.status === 404) { |
||||
title = t('core', 'No action available'); |
||||
} else { |
||||
title = t('core', 'Error fetching contact actions'); |
||||
} |
||||
|
||||
var template = OC.ContactsMenu.Templates['jquery_entry']; |
||||
$list.find('ul').append(template({ |
||||
hyperlink: '#', |
||||
title: title |
||||
})); |
||||
}); |
||||
}); |
||||
|
||||
$(document).click(function(event) { |
||||
var clickedList = ($list.has(event.target).length > 0); |
||||
var clickedTarget = ($div.has(event.target).length > 0); |
||||
|
||||
$div.each(function() { |
||||
if ($(this).is(event.target)) { |
||||
clickedTarget = true; |
||||
} |
||||
}); |
||||
|
||||
if (clickedList || clickedTarget) { |
||||
return; |
||||
} |
||||
|
||||
$list.addClass('hidden'); |
||||
$list.hide(); |
||||
}); |
||||
}; |
||||
}(jQuery)); |
||||
@ -1,249 +0,0 @@ |
||||
(function($) { |
||||
$.widget('oc.ocdialog', { |
||||
options: { |
||||
width: 'auto', |
||||
height: 'auto', |
||||
closeButton: true, |
||||
closeOnEscape: true, |
||||
modal: false |
||||
}, |
||||
_create: function() { |
||||
var self = this; |
||||
|
||||
this.originalCss = { |
||||
display: this.element[0].style.display, |
||||
width: this.element[0].style.width, |
||||
height: this.element[0].style.height |
||||
}; |
||||
|
||||
this.originalTitle = this.element.attr('title'); |
||||
this.options.title = this.options.title || this.originalTitle; |
||||
|
||||
this.$dialog = $('<div class="oc-dialog" />') |
||||
.attr({ |
||||
// Setting tabIndex makes the div focusable
|
||||
tabIndex: -1, |
||||
role: 'dialog' |
||||
}) |
||||
.insertBefore(this.element); |
||||
this.$dialog.append(this.element.detach()); |
||||
this.element.removeAttr('title').addClass('oc-dialog-content').appendTo(this.$dialog); |
||||
|
||||
this.$dialog.css({ |
||||
display: 'inline-block', |
||||
position: 'fixed' |
||||
}); |
||||
|
||||
this.enterCallback = null; |
||||
|
||||
$(document).on('keydown keyup', function(event) { |
||||
if ( |
||||
event.target !== self.$dialog.get(0) && |
||||
self.$dialog.find($(event.target)).length === 0 |
||||
) { |
||||
return; |
||||
} |
||||
// Escape
|
||||
if ( |
||||
event.keyCode === 27 && |
||||
event.type === 'keydown' && |
||||
self.options.closeOnEscape |
||||
) { |
||||
event.stopImmediatePropagation(); |
||||
self.close(); |
||||
return false; |
||||
} |
||||
// Enter
|
||||
if(event.keyCode === 13) { |
||||
event.stopImmediatePropagation(); |
||||
if (self.enterCallback !== null) { |
||||
self.enterCallback(); |
||||
event.preventDefault(); |
||||
return false; |
||||
} |
||||
if(event.type === 'keyup') { |
||||
event.preventDefault(); |
||||
return false; |
||||
} |
||||
// If no button is selected we trigger the primary
|
||||
if ( |
||||
self.$buttonrow && |
||||
self.$buttonrow.find($(event.target)).length === 0 |
||||
) { |
||||
var $button = self.$buttonrow.find('button.primary'); |
||||
if($button && !$button.prop('disabled')) { |
||||
$button.trigger('click'); |
||||
} |
||||
} else if(self.$buttonrow) { |
||||
$(event.target).trigger('click'); |
||||
} |
||||
return false; |
||||
} |
||||
}); |
||||
|
||||
this._setOptions(this.options); |
||||
this._createOverlay(); |
||||
}, |
||||
_init: function() { |
||||
this.$dialog.focus(); |
||||
this._trigger('open'); |
||||
}, |
||||
_setOption: function(key, value) { |
||||
var self = this; |
||||
switch(key) { |
||||
case 'title': |
||||
if(this.$title) { |
||||
this.$title.text(value); |
||||
} else { |
||||
var $title = $('<h2 class="oc-dialog-title">' |
||||
+ value |
||||
+ '</h2>'); |
||||
this.$title = $title.prependTo(this.$dialog); |
||||
} |
||||
this._setSizes(); |
||||
break; |
||||
case 'buttons': |
||||
if(this.$buttonrow) { |
||||
this.$buttonrow.empty(); |
||||
} else { |
||||
var $buttonrow = $('<div class="oc-dialog-buttonrow" />'); |
||||
this.$buttonrow = $buttonrow.appendTo(this.$dialog); |
||||
} |
||||
if (value.length === 1) { |
||||
this.$buttonrow.addClass('onebutton'); |
||||
} else if (value.length === 2) { |
||||
this.$buttonrow.addClass('twobuttons'); |
||||
} else if (value.length === 3) { |
||||
this.$buttonrow.addClass('threebuttons'); |
||||
} |
||||
$.each(value, function(idx, val) { |
||||
var $button = $('<button>').text(val.text); |
||||
if (val.classes) { |
||||
$button.addClass(val.classes); |
||||
} |
||||
if(val.defaultButton) { |
||||
$button.addClass('primary'); |
||||
self.$defaultButton = $button; |
||||
} |
||||
self.$buttonrow.append($button); |
||||
$button.click(function() { |
||||
val.click.apply(self.element[0], arguments); |
||||
}); |
||||
}); |
||||
this.$buttonrow.find('button') |
||||
.on('focus', function(event) { |
||||
self.$buttonrow.find('button').removeClass('primary'); |
||||
$(this).addClass('primary'); |
||||
}); |
||||
this._setSizes(); |
||||
break; |
||||
case 'style': |
||||
if (value.buttons !== undefined) { |
||||
this.$buttonrow.addClass(value.buttons); |
||||
} |
||||
break; |
||||
case 'closeButton': |
||||
if(value) { |
||||
var $closeButton = $('<a class="oc-dialog-close"></a>'); |
||||
this.$dialog.prepend($closeButton); |
||||
$closeButton.on('click', function() { |
||||
self.close(); |
||||
}); |
||||
} else { |
||||
this.$dialog.find('.oc-dialog-close').remove(); |
||||
} |
||||
break; |
||||
case 'width': |
||||
this.$dialog.css('width', value); |
||||
break; |
||||
case 'height': |
||||
this.$dialog.css('height', value); |
||||
break; |
||||
case 'close': |
||||
this.closeCB = value; |
||||
break; |
||||
} |
||||
//this._super(key, value);
|
||||
$.Widget.prototype._setOption.apply(this, arguments ); |
||||
}, |
||||
_setOptions: function(options) { |
||||
//this._super(options);
|
||||
$.Widget.prototype._setOptions.apply(this, arguments); |
||||
}, |
||||
_setSizes: function() { |
||||
var lessHeight = 0; |
||||
if(this.$title) { |
||||
lessHeight += this.$title.outerHeight(true); |
||||
} |
||||
if(this.$buttonrow) { |
||||
lessHeight += this.$buttonrow.outerHeight(true); |
||||
} |
||||
this.element.css({ |
||||
'height': 'calc(100% - ' + lessHeight + 'px)' |
||||
}); |
||||
}, |
||||
_createOverlay: function() { |
||||
if(!this.options.modal) { |
||||
return; |
||||
} |
||||
|
||||
var self = this; |
||||
this.overlay = $('<div>') |
||||
.addClass('oc-dialog-dim') |
||||
.appendTo($('#content')); |
||||
this.overlay.on('click keydown keyup', function(event) { |
||||
if(event.target !== self.$dialog.get(0) && self.$dialog.find($(event.target)).length === 0) { |
||||
event.preventDefault(); |
||||
event.stopPropagation(); |
||||
return; |
||||
} |
||||
}); |
||||
}, |
||||
_destroyOverlay: function() { |
||||
if (!this.options.modal) { |
||||
return; |
||||
} |
||||
|
||||
if (this.overlay) { |
||||
this.overlay.off('click keydown keyup'); |
||||
this.overlay.remove(); |
||||
this.overlay = null; |
||||
} |
||||
}, |
||||
widget: function() { |
||||
return this.$dialog; |
||||
}, |
||||
setEnterCallback: function(callback) { |
||||
this.enterCallback = callback; |
||||
}, |
||||
unsetEnterCallback: function() { |
||||
this.enterCallback = null; |
||||
}, |
||||
close: function() { |
||||
this._destroyOverlay(); |
||||
var self = this; |
||||
// Ugly hack to catch remaining keyup events.
|
||||
setTimeout(function() { |
||||
self._trigger('close', self); |
||||
}, 200); |
||||
|
||||
self.$dialog.remove(); |
||||
this.destroy(); |
||||
}, |
||||
destroy: function() { |
||||
if(this.$title) { |
||||
this.$title.remove(); |
||||
} |
||||
if(this.$buttonrow) { |
||||
this.$buttonrow.remove(); |
||||
} |
||||
|
||||
if(this.originalTitle) { |
||||
this.element.attr('title', this.originalTitle); |
||||
} |
||||
this.element.removeClass('oc-dialog-content') |
||||
.css(this.originalCss).detach().insertBefore(this.$dialog); |
||||
this.$dialog.remove(); |
||||
} |
||||
}); |
||||
}(jQuery)); |
||||
@ -1,16 +1,11 @@ |
||||
[ |
||||
"jquery.ocdialog.js", |
||||
"oc-dialogs.js", |
||||
"js.js", |
||||
"octemplate.js", |
||||
"public/appconfig.js", |
||||
"public/comments.js", |
||||
"public/whatsnew.js", |
||||
"oc-requesttoken.js", |
||||
"mimetype.js", |
||||
"mimetypelist.js", |
||||
"select2-toggleselect.js", |
||||
"placeholder.js", |
||||
"jquery.avatar.js", |
||||
"jquery.contactsmenu.js" |
||||
"select2-toggleselect.js" |
||||
] |
||||
|
||||
@ -1,105 +0,0 @@ |
||||
/** |
||||
* jQuery plugin for micro templates |
||||
* |
||||
* Strings are automatically escaped, but that can be disabled by setting |
||||
* escapeFunction to null. |
||||
* |
||||
* Usage examples: |
||||
* |
||||
* var htmlStr = '<p>Bake, uncovered, until the {greasystuff} is melted and the {pasta} is heated through, about {min} minutes.</p>' |
||||
* $(htmlStr).octemplate({greasystuff: 'cheese', pasta: 'macaroni', min: 10}); |
||||
* |
||||
* var htmlStr = '<p>Welcome back {user}</p>'; |
||||
* $(htmlStr).octemplate({user: 'John Q. Public'}, {escapeFunction: null}); |
||||
* |
||||
* Be aware that the target string must be wrapped in an HTML element for the |
||||
* plugin to work. The following won't work: |
||||
*
|
||||
* var textStr = 'Welcome back {user}'; |
||||
* $(textStr).octemplate({user: 'John Q. Public'}); |
||||
* |
||||
* For anything larger than one-liners, you can use a simple $.get() ajax |
||||
* request to get the template, or you can embed them it the page using the |
||||
* text/template type: |
||||
* |
||||
* <script id="contactListItemTemplate" type="text/template"> |
||||
* <tr class="contact" data-id="{id}"> |
||||
* <td class="name"> |
||||
* <input type="checkbox" name="id" value="{id}" /><span class="nametext">{name}</span> |
||||
* </td> |
||||
* <td class="email"> |
||||
* <a href="mailto:{email}">{email}</a> |
||||
* </td> |
||||
* <td class="phone">{phone}</td> |
||||
* </tr> |
||||
* </script> |
||||
* |
||||
* var $tmpl = $('#contactListItemTemplate'); |
||||
* var contacts = // fetched in some ajax call
|
||||
* |
||||
* $.each(contacts, function(idx, contact) { |
||||
* $contactList.append( |
||||
* $tmpl.octemplate({ |
||||
* id: contact.getId(), |
||||
* name: contact.getDisplayName(), |
||||
* email: contact.getPreferredEmail(), |
||||
* phone: contact.getPreferredPhone(), |
||||
* }); |
||||
* ); |
||||
* }); |
||||
*/ |
||||
(function( $ ) { |
||||
/** |
||||
* Object Template |
||||
* Inspired by micro templating done by e.g. underscore.js |
||||
*/ |
||||
var Template = { |
||||
init: function(vars, options, elem) { |
||||
// Mix in the passed in options with the default options
|
||||
this.vars = vars; |
||||
this.options = $.extend({},this.options,options); |
||||
|
||||
this.elem = elem; |
||||
var self = this; |
||||
|
||||
if(typeof this.options.escapeFunction === 'function') { |
||||
var keys = Object.keys(this.vars); |
||||
for (var key = 0; key < keys.length; key++) { |
||||
if(typeof this.vars[keys[key]] === 'string') { |
||||
this.vars[keys[key]] = self.options.escapeFunction(this.vars[keys[key]]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
var _html = this._build(this.vars); |
||||
return $(_html); |
||||
}, |
||||
// From stackoverflow.com/questions/1408289/best-way-to-do-variable-interpolation-in-javascript
|
||||
_build: function(o){ |
||||
var data = this.elem.attr('type') === 'text/template' ? this.elem.html() : this.elem.get(0).outerHTML; |
||||
try { |
||||
return data.replace(/{([^{}]*)}/g, |
||||
function (a, b) { |
||||
var r = o[b]; |
||||
return typeof r === 'string' || typeof r === 'number' ? r : a; |
||||
} |
||||
); |
||||
} catch(e) { |
||||
console.error(e, 'data:', data); |
||||
} |
||||
}, |
||||
options: { |
||||
escapeFunction: escapeHTML |
||||
} |
||||
}; |
||||
|
||||
$.fn.octemplate = function(vars, options) { |
||||
vars = vars || {}; |
||||
if(this.length) { |
||||
var _template = Object.create(Template); |
||||
return _template.init(vars, options, this); |
||||
} |
||||
}; |
||||
|
||||
})( jQuery ); |
||||
|
||||
@ -0,0 +1,36 @@ |
||||
/* |
||||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
/** |
||||
* Sanitizes a HTML string by replacing all potential dangerous characters with HTML entities |
||||
* @param {string} s String to sanitize |
||||
* @return {string} Sanitized string |
||||
*/ |
||||
export default function escapeHTML (s) { |
||||
return s.toString() |
||||
.split('&') |
||||
.join('&') |
||||
.split('<') |
||||
.join('<').split('>') |
||||
.join('>').split('"') |
||||
.join('"').split('\'') |
||||
.join('''); |
||||
} |
||||
@ -0,0 +1,162 @@ |
||||
/* |
||||
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import $ from 'jquery' |
||||
|
||||
import OC from '../OC' |
||||
|
||||
/** |
||||
* This plugin inserts the right avatar for the user, depending on, whether a |
||||
* custom avatar is uploaded - which it uses then - or not, and display a |
||||
* placeholder with the first letter of the users name instead. |
||||
* For this it queries the core_avatar_get route, thus this plugin is fit very |
||||
* tightly for owncloud, and it may not work anywhere else. |
||||
* |
||||
* You may use this on any <div></div> |
||||
* Here I'm using <div class="avatardiv"></div> as an example. |
||||
* |
||||
* There are 5 ways to call this: |
||||
* |
||||
* 1. $('.avatardiv').avatar('jdoe', 128); |
||||
* This will make the div to jdoe's fitting avatar, with a size of 128px. |
||||
* |
||||
* 2. $('.avatardiv').avatar('jdoe'); |
||||
* This will make the div to jdoe's fitting avatar. If the div already has a |
||||
* height, it will be used for the avatars size. Otherwise this plugin will |
||||
* search for 'size' DOM data, to use for avatar size. If neither are available |
||||
* it will default to 64px. |
||||
* |
||||
* 3. $('.avatardiv').avatar(); |
||||
* This will search the DOM for 'user' data, to use as the username. If there |
||||
* is no username available it will default to a placeholder with the value of |
||||
* "?". The size will be determined the same way, as the second example. |
||||
* |
||||
* 4. $('.avatardiv').avatar('jdoe', 128, true); |
||||
* This will behave like the first example, except it will also append random |
||||
* hashes to the custom avatar images, to force image reloading in IE8. |
||||
* |
||||
* 5. $('.avatardiv').avatar('jdoe', 128, undefined, true); |
||||
* This will behave like the first example, but it will hide the avatardiv, if |
||||
* it will display the default placeholder. undefined is the ie8fix from |
||||
* example 4 and can be either true, or false/undefined, to be ignored. |
||||
* |
||||
* 6. $('.avatardiv').avatar('jdoe', 128, undefined, true, callback); |
||||
* This will behave like the above example, but it will call the function |
||||
* defined in callback after the avatar is placed into the DOM. |
||||
* |
||||
*/ |
||||
|
||||
$.fn.avatar = function (user, size, ie8fix, hidedefault, callback, displayname) { |
||||
var setAvatarForUnknownUser = function (target) { |
||||
target.imageplaceholder('?'); |
||||
target.css('background-color', '#b9b9b9'); |
||||
}; |
||||
|
||||
if (typeof (user) !== 'undefined') { |
||||
user = String(user); |
||||
} |
||||
if (typeof (displayname) !== 'undefined') { |
||||
displayname = String(displayname); |
||||
} |
||||
|
||||
if (typeof (size) === 'undefined') { |
||||
if (this.height() > 0) { |
||||
size = this.height(); |
||||
} else if (this.data('size') > 0) { |
||||
size = this.data('size'); |
||||
} else { |
||||
size = 64; |
||||
} |
||||
} |
||||
|
||||
this.height(size); |
||||
this.width(size); |
||||
|
||||
if (typeof (user) === 'undefined') { |
||||
if (typeof (this.data('user')) !== 'undefined') { |
||||
user = this.data('user'); |
||||
} else { |
||||
setAvatarForUnknownUser(this); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
// sanitize
|
||||
user = String(user).replace(/\//g, ''); |
||||
|
||||
var $div = this; |
||||
var url; |
||||
|
||||
// If this is our own avatar we have to use the version attribute
|
||||
if (user === OC.getCurrentUser().uid) { |
||||
url = OC.generateUrl( |
||||
'/avatar/{user}/{size}?v={version}', |
||||
{ |
||||
user: user, |
||||
size: Math.ceil(size * window.devicePixelRatio), |
||||
version: oc_userconfig.avatar.version |
||||
}); |
||||
} else { |
||||
url = OC.generateUrl( |
||||
'/avatar/{user}/{size}', |
||||
{ |
||||
user: user, |
||||
size: Math.ceil(size * window.devicePixelRatio) |
||||
}); |
||||
} |
||||
|
||||
var img = new Image(); |
||||
|
||||
// If the new image loads successfully set it.
|
||||
img.onload = function () { |
||||
$div.clearimageplaceholder(); |
||||
$div.append(img); |
||||
|
||||
if (typeof callback === 'function') { |
||||
callback(); |
||||
} |
||||
}; |
||||
// Fallback when avatar loading fails:
|
||||
// Use old placeholder when a displayname attribute is defined,
|
||||
// otherwise show the unknown user placeholder.
|
||||
img.onerror = function () { |
||||
$div.clearimageplaceholder(); |
||||
if (typeof (displayname) !== 'undefined') { |
||||
$div.imageplaceholder(user, displayname); |
||||
} else { |
||||
setAvatarForUnknownUser($div); |
||||
} |
||||
|
||||
if (typeof callback === 'function') { |
||||
callback(); |
||||
} |
||||
}; |
||||
|
||||
if (size < 32) { |
||||
$div.addClass('icon-loading-small'); |
||||
} else { |
||||
$div.addClass('icon-loading'); |
||||
} |
||||
img.width = size; |
||||
img.height = size; |
||||
img.src = url; |
||||
img.alt = ''; |
||||
}; |
||||
@ -0,0 +1,125 @@ |
||||
/* |
||||
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import $ from 'jquery' |
||||
|
||||
import OC from '../OC' |
||||
|
||||
const LIST = '' |
||||
+ '<div class="menu popovermenu menu-left hidden contactsmenu-popover">' |
||||
+ ' <ul>' |
||||
+ ' <li>' |
||||
+ ' <a>' |
||||
+ ' <span class="icon-loading-small"></span>' |
||||
+ ' </a>' |
||||
+ ' </li>' |
||||
+ ' </ul>' |
||||
+ '</div>'; |
||||
|
||||
$.fn.contactsMenu = function (shareWith, shareType, appendTo) { |
||||
// 0 - user, 4 - email, 6 - remote
|
||||
var allowedTypes = [0, 4, 6]; |
||||
if (allowedTypes.indexOf(shareType) === -1) { |
||||
return; |
||||
} |
||||
|
||||
var $div = this; |
||||
appendTo.append(LIST); |
||||
var $list = appendTo.find('div.contactsmenu-popover'); |
||||
|
||||
$div.click(function () { |
||||
if (!$list.hasClass('hidden')) { |
||||
$list.addClass('hidden'); |
||||
$list.hide(); |
||||
return; |
||||
} |
||||
|
||||
$list.removeClass('hidden'); |
||||
$list.show(); |
||||
|
||||
if ($list.hasClass('loaded')) { |
||||
return; |
||||
} |
||||
|
||||
$list.addClass('loaded'); |
||||
$.ajax(OC.generateUrl('/contactsmenu/findOne'), { |
||||
method: 'POST', |
||||
data: { |
||||
shareType: shareType, |
||||
shareWith: shareWith |
||||
} |
||||
}).then(function (data) { |
||||
$list.find('ul').find('li').addClass('hidden'); |
||||
|
||||
var actions; |
||||
if (!data.topAction) { |
||||
actions = [{ |
||||
hyperlink: '#', |
||||
title: t('core', 'No action available') |
||||
}]; |
||||
} else { |
||||
actions = [data.topAction].concat(data.actions); |
||||
} |
||||
|
||||
actions.forEach(function (action) { |
||||
var template = OC.ContactsMenu.Templates['jquery_entry']; |
||||
$list.find('ul').append(template(action)); |
||||
}); |
||||
|
||||
if (actions.length === 0) { |
||||
|
||||
} |
||||
}, function (jqXHR) { |
||||
$list.find('ul').find('li').addClass('hidden'); |
||||
|
||||
var title; |
||||
if (jqXHR.status === 404) { |
||||
title = t('core', 'No action available'); |
||||
} else { |
||||
title = t('core', 'Error fetching contact actions'); |
||||
} |
||||
|
||||
var template = OC.ContactsMenu.Templates['jquery_entry']; |
||||
$list.find('ul').append(template({ |
||||
hyperlink: '#', |
||||
title: title |
||||
})); |
||||
}); |
||||
}); |
||||
|
||||
$(document).click(function (event) { |
||||
var clickedList = ($list.has(event.target).length > 0); |
||||
var clickedTarget = ($div.has(event.target).length > 0); |
||||
|
||||
$div.each(function () { |
||||
if ($(this).is(event.target)) { |
||||
clickedTarget = true; |
||||
} |
||||
}); |
||||
|
||||
if (clickedList || clickedTarget) { |
||||
return; |
||||
} |
||||
|
||||
$list.addClass('hidden'); |
||||
$list.hide(); |
||||
}); |
||||
}; |
||||
@ -0,0 +1,31 @@ |
||||
/* |
||||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import $ from 'jquery' |
||||
|
||||
/** |
||||
* check if an element exists. |
||||
* allows you to write if ($('#myid').exists()) to increase readability |
||||
* @link http://stackoverflow.com/questions/31044/is-there-an-exists-function-for-jquery
|
||||
*/ |
||||
$.fn.exists = function () { |
||||
return this.length > 0; |
||||
}; |
||||
@ -0,0 +1,31 @@ |
||||
/* |
||||
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import $ from 'jquery' |
||||
|
||||
/** |
||||
* Filter jQuery selector by attribute value |
||||
*/ |
||||
$.fn.filterAttr = function (attrName, attrValue) { |
||||
return this.filter(function () { |
||||
return $(this).attr(attrName) === attrValue; |
||||
}); |
||||
}; |
||||
@ -0,0 +1,32 @@ |
||||
/* |
||||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import './avatar' |
||||
import './contactsmenu' |
||||
import './exists' |
||||
import './filterattr' |
||||
import './ocdialog' |
||||
import './octemplate' |
||||
import './placeholder' |
||||
import './selectrange' |
||||
import './showpassword' |
||||
import './tipsy' |
||||
import './ui-fixes' |
||||
@ -0,0 +1,270 @@ |
||||
/* |
||||
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import $ from 'jquery' |
||||
|
||||
$.widget('oc.ocdialog', { |
||||
options: { |
||||
width: 'auto', |
||||
height: 'auto', |
||||
closeButton: true, |
||||
closeOnEscape: true, |
||||
modal: false |
||||
}, |
||||
_create: function () { |
||||
var self = this; |
||||
|
||||
this.originalCss = { |
||||
display: this.element[0].style.display, |
||||
width: this.element[0].style.width, |
||||
height: this.element[0].style.height |
||||
}; |
||||
|
||||
this.originalTitle = this.element.attr('title'); |
||||
this.options.title = this.options.title || this.originalTitle; |
||||
|
||||
this.$dialog = $('<div class="oc-dialog" />') |
||||
.attr({ |
||||
// Setting tabIndex makes the div focusable
|
||||
tabIndex: -1, |
||||
role: 'dialog' |
||||
}) |
||||
.insertBefore(this.element); |
||||
this.$dialog.append(this.element.detach()); |
||||
this.element.removeAttr('title').addClass('oc-dialog-content').appendTo(this.$dialog); |
||||
|
||||
this.$dialog.css({ |
||||
display: 'inline-block', |
||||
position: 'fixed' |
||||
}); |
||||
|
||||
this.enterCallback = null; |
||||
|
||||
$(document).on('keydown keyup', function (event) { |
||||
if ( |
||||
event.target !== self.$dialog.get(0) && |
||||
self.$dialog.find($(event.target)).length === 0 |
||||
) { |
||||
return; |
||||
} |
||||
// Escape
|
||||
if ( |
||||
event.keyCode === 27 && |
||||
event.type === 'keydown' && |
||||
self.options.closeOnEscape |
||||
) { |
||||
event.stopImmediatePropagation(); |
||||
self.close(); |
||||
return false; |
||||
} |
||||
// Enter
|
||||
if (event.keyCode === 13) { |
||||
event.stopImmediatePropagation(); |
||||
if (self.enterCallback !== null) { |
||||
self.enterCallback(); |
||||
event.preventDefault(); |
||||
return false; |
||||
} |
||||
if (event.type === 'keyup') { |
||||
event.preventDefault(); |
||||
return false; |
||||
} |
||||
// If no button is selected we trigger the primary
|
||||
if ( |
||||
self.$buttonrow && |
||||
self.$buttonrow.find($(event.target)).length === 0 |
||||
) { |
||||
var $button = self.$buttonrow.find('button.primary'); |
||||
if ($button && !$button.prop('disabled')) { |
||||
$button.trigger('click'); |
||||
} |
||||
} else if (self.$buttonrow) { |
||||
$(event.target).trigger('click'); |
||||
} |
||||
return false; |
||||
} |
||||
}); |
||||
|
||||
this._setOptions(this.options); |
||||
this._createOverlay(); |
||||
}, |
||||
_init: function () { |
||||
this.$dialog.focus(); |
||||
this._trigger('open'); |
||||
}, |
||||
_setOption: function (key, value) { |
||||
var self = this; |
||||
switch (key) { |
||||
case 'title': |
||||
if (this.$title) { |
||||
this.$title.text(value); |
||||
} else { |
||||
var $title = $('<h2 class="oc-dialog-title">' |
||||
+ value |
||||
+ '</h2>'); |
||||
this.$title = $title.prependTo(this.$dialog); |
||||
} |
||||
this._setSizes(); |
||||
break; |
||||
case 'buttons': |
||||
if (this.$buttonrow) { |
||||
this.$buttonrow.empty(); |
||||
} else { |
||||
var $buttonrow = $('<div class="oc-dialog-buttonrow" />'); |
||||
this.$buttonrow = $buttonrow.appendTo(this.$dialog); |
||||
} |
||||
if (value.length === 1) { |
||||
this.$buttonrow.addClass('onebutton'); |
||||
} else if (value.length === 2) { |
||||
this.$buttonrow.addClass('twobuttons'); |
||||
} else if (value.length === 3) { |
||||
this.$buttonrow.addClass('threebuttons'); |
||||
} |
||||
$.each(value, function (idx, val) { |
||||
var $button = $('<button>').text(val.text); |
||||
if (val.classes) { |
||||
$button.addClass(val.classes); |
||||
} |
||||
if (val.defaultButton) { |
||||
$button.addClass('primary'); |
||||
self.$defaultButton = $button; |
||||
} |
||||
self.$buttonrow.append($button); |
||||
$button.click(function () { |
||||
val.click.apply(self.element[0], arguments); |
||||
}); |
||||
}); |
||||
this.$buttonrow.find('button') |
||||
.on('focus', function (event) { |
||||
self.$buttonrow.find('button').removeClass('primary'); |
||||
$(this).addClass('primary'); |
||||
}); |
||||
this._setSizes(); |
||||
break; |
||||
case 'style': |
||||
if (value.buttons !== undefined) { |
||||
this.$buttonrow.addClass(value.buttons); |
||||
} |
||||
break; |
||||
case 'closeButton': |
||||
if (value) { |
||||
var $closeButton = $('<a class="oc-dialog-close"></a>'); |
||||
this.$dialog.prepend($closeButton); |
||||
$closeButton.on('click', function () { |
||||
self.close(); |
||||
}); |
||||
} else { |
||||
this.$dialog.find('.oc-dialog-close').remove(); |
||||
} |
||||
break; |
||||
case 'width': |
||||
this.$dialog.css('width', value); |
||||
break; |
||||
case 'height': |
||||
this.$dialog.css('height', value); |
||||
break; |
||||
case 'close': |
||||
this.closeCB = value; |
||||
break; |
||||
} |
||||
//this._super(key, value);
|
||||
$.Widget.prototype._setOption.apply(this, arguments); |
||||
}, |
||||
_setOptions: function (options) { |
||||
//this._super(options);
|
||||
$.Widget.prototype._setOptions.apply(this, arguments); |
||||
}, |
||||
_setSizes: function () { |
||||
var lessHeight = 0; |
||||
if (this.$title) { |
||||
lessHeight += this.$title.outerHeight(true); |
||||
} |
||||
if (this.$buttonrow) { |
||||
lessHeight += this.$buttonrow.outerHeight(true); |
||||
} |
||||
this.element.css({ |
||||
'height': 'calc(100% - ' + lessHeight + 'px)' |
||||
}); |
||||
}, |
||||
_createOverlay: function () { |
||||
if (!this.options.modal) { |
||||
return; |
||||
} |
||||
|
||||
var self = this; |
||||
this.overlay = $('<div>') |
||||
.addClass('oc-dialog-dim') |
||||
.appendTo($('#content')); |
||||
this.overlay.on('click keydown keyup', function (event) { |
||||
if (event.target !== self.$dialog.get(0) && self.$dialog.find($(event.target)).length === 0) { |
||||
event.preventDefault(); |
||||
event.stopPropagation(); |
||||
return; |
||||
} |
||||
}); |
||||
}, |
||||
_destroyOverlay: function () { |
||||
if (!this.options.modal) { |
||||
return; |
||||
} |
||||
|
||||
if (this.overlay) { |
||||
this.overlay.off('click keydown keyup'); |
||||
this.overlay.remove(); |
||||
this.overlay = null; |
||||
} |
||||
}, |
||||
widget: function () { |
||||
return this.$dialog; |
||||
}, |
||||
setEnterCallback: function (callback) { |
||||
this.enterCallback = callback; |
||||
}, |
||||
unsetEnterCallback: function () { |
||||
this.enterCallback = null; |
||||
}, |
||||
close: function () { |
||||
this._destroyOverlay(); |
||||
var self = this; |
||||
// Ugly hack to catch remaining keyup events.
|
||||
setTimeout(function () { |
||||
self._trigger('close', self); |
||||
}, 200); |
||||
|
||||
self.$dialog.remove(); |
||||
this.destroy(); |
||||
}, |
||||
destroy: function () { |
||||
if (this.$title) { |
||||
this.$title.remove(); |
||||
} |
||||
if (this.$buttonrow) { |
||||
this.$buttonrow.remove(); |
||||
} |
||||
|
||||
if (this.originalTitle) { |
||||
this.element.attr('title', this.originalTitle); |
||||
} |
||||
this.element.removeClass('oc-dialog-content') |
||||
.css(this.originalCss).detach().insertBefore(this.$dialog); |
||||
this.$dialog.remove(); |
||||
} |
||||
}); |
||||
@ -0,0 +1,104 @@ |
||||
import $ from 'jquery' |
||||
import escapeHTML from '../Util/escapeHTML' |
||||
|
||||
/** |
||||
* jQuery plugin for micro templates |
||||
* |
||||
* Strings are automatically escaped, but that can be disabled by setting |
||||
* escapeFunction to null. |
||||
* |
||||
* Usage examples: |
||||
* |
||||
* var htmlStr = '<p>Bake, uncovered, until the {greasystuff} is melted and the {pasta} is heated through, about {min} minutes.</p>' |
||||
* $(htmlStr).octemplate({greasystuff: 'cheese', pasta: 'macaroni', min: 10}); |
||||
* |
||||
* var htmlStr = '<p>Welcome back {user}</p>'; |
||||
* $(htmlStr).octemplate({user: 'John Q. Public'}, {escapeFunction: null}); |
||||
* |
||||
* Be aware that the target string must be wrapped in an HTML element for the |
||||
* plugin to work. The following won't work: |
||||
* |
||||
* var textStr = 'Welcome back {user}'; |
||||
* $(textStr).octemplate({user: 'John Q. Public'}); |
||||
* |
||||
* For anything larger than one-liners, you can use a simple $.get() ajax |
||||
* request to get the template, or you can embed them it the page using the |
||||
* text/template type: |
||||
* |
||||
* <script id="contactListItemTemplate" type="text/template"> |
||||
* <tr class="contact" data-id="{id}"> |
||||
* <td class="name"> |
||||
* <input type="checkbox" name="id" value="{id}" /><span class="nametext">{name}</span> |
||||
* </td> |
||||
* <td class="email"> |
||||
* <a href="mailto:{email}">{email}</a> |
||||
* </td> |
||||
* <td class="phone">{phone}</td> |
||||
* </tr> |
||||
* </script> |
||||
* |
||||
* var $tmpl = $('#contactListItemTemplate'); |
||||
* var contacts = // fetched in some ajax call
|
||||
* |
||||
* $.each(contacts, function(idx, contact) { |
||||
* $contactList.append( |
||||
* $tmpl.octemplate({ |
||||
* id: contact.getId(), |
||||
* name: contact.getDisplayName(), |
||||
* email: contact.getPreferredEmail(), |
||||
* phone: contact.getPreferredPhone(), |
||||
* }); |
||||
* ); |
||||
* }); |
||||
*/ |
||||
/** |
||||
* Object Template |
||||
* Inspired by micro templating done by e.g. underscore.js |
||||
*/ |
||||
const Template = { |
||||
init: function (vars, options, elem) { |
||||
// Mix in the passed in options with the default options
|
||||
this.vars = vars; |
||||
this.options = $.extend({}, this.options, options); |
||||
|
||||
this.elem = elem; |
||||
var self = this; |
||||
|
||||
if (typeof this.options.escapeFunction === 'function') { |
||||
var keys = Object.keys(this.vars); |
||||
for (var key = 0; key < keys.length; key++) { |
||||
if (typeof this.vars[keys[key]] === 'string') { |
||||
this.vars[keys[key]] = self.options.escapeFunction(this.vars[keys[key]]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
var _html = this._build(this.vars); |
||||
return $(_html); |
||||
}, |
||||
// From stackoverflow.com/questions/1408289/best-way-to-do-variable-interpolation-in-javascript
|
||||
_build: function (o) { |
||||
var data = this.elem.attr('type') === 'text/template' ? this.elem.html() : this.elem.get(0).outerHTML; |
||||
try { |
||||
return data.replace(/{([^{}]*)}/g, |
||||
function (a, b) { |
||||
var r = o[b]; |
||||
return typeof r === 'string' || typeof r === 'number' ? r : a; |
||||
} |
||||
); |
||||
} catch (e) { |
||||
console.error(e, 'data:', data); |
||||
} |
||||
}, |
||||
options: { |
||||
escapeFunction: escapeHTML |
||||
} |
||||
}; |
||||
|
||||
$.fn.octemplate = function (vars, options) { |
||||
vars = vars || {}; |
||||
if (this.length) { |
||||
var _template = Object.create(Template); |
||||
return _template.init(vars, options, this); |
||||
} |
||||
}; |
||||
@ -0,0 +1,43 @@ |
||||
/* |
||||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import $ from 'jquery' |
||||
|
||||
/** |
||||
* select a range in an input field |
||||
* @link http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area
|
||||
* @param {type} start |
||||
* @param {type} end |
||||
*/ |
||||
$.fn.selectRange = function (start, end) { |
||||
return this.each(function () { |
||||
if (this.setSelectionRange) { |
||||
this.focus(); |
||||
this.setSelectionRange(start, end); |
||||
} else if (this.createTextRange) { |
||||
var range = this.createTextRange(); |
||||
range.collapse(true); |
||||
range.moveEnd('character', end); |
||||
range.moveStart('character', start); |
||||
range.select(); |
||||
} |
||||
}); |
||||
}; |
||||
@ -0,0 +1,149 @@ |
||||
/* |
||||
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2018 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import $ from 'jquery' |
||||
|
||||
/* |
||||
* @name Show Password |
||||
* @description |
||||
* @version 1.3 |
||||
* @requires Jquery 1.5 |
||||
* |
||||
* @author Jan Jarfalk |
||||
* @author-email jan.jarfalk@unwrongest.com |
||||
* @author-website http://www.unwrongest.com
|
||||
* |
||||
* @special-thanks Michel Gratton |
||||
* |
||||
* @licens MIT License - http://www.opensource.org/licenses/mit-license.php
|
||||
*/ |
||||
$.fn.extend({ |
||||
showPassword: function (c) { |
||||
|
||||
// Setup callback object
|
||||
var callback = {'fn': null, 'args': {}}; |
||||
callback.fn = c; |
||||
|
||||
// Clones passwords and turn the clones into text inputs
|
||||
var cloneElement = function (element) { |
||||
|
||||
var $element = $(element); |
||||
|
||||
var $clone = $("<input />"); |
||||
|
||||
// Name added for JQuery Validation compatibility
|
||||
// Element name is required to avoid script warning.
|
||||
$clone.attr({ |
||||
'type': 'text', |
||||
'class': $element.attr('class'), |
||||
'style': $element.attr('style'), |
||||
'size': $element.attr('size'), |
||||
'name': $element.attr('name') + '-clone', |
||||
'tabindex': $element.attr('tabindex'), |
||||
'autocomplete': 'off' |
||||
}); |
||||
|
||||
if ($element.attr('placeholder') !== undefined) { |
||||
$clone.attr('placeholder', $element.attr('placeholder')); |
||||
} |
||||
|
||||
return $clone; |
||||
|
||||
}; |
||||
|
||||
// Transfers values between two elements
|
||||
var update = function (a, b) { |
||||
b.val(a.val()); |
||||
}; |
||||
|
||||
// Shows a or b depending on checkbox
|
||||
var setState = function (checkbox, a, b) { |
||||
|
||||
if (checkbox.is(':checked')) { |
||||
update(a, b); |
||||
b.show(); |
||||
a.hide(); |
||||
} else { |
||||
update(b, a); |
||||
b.hide(); |
||||
a.show(); |
||||
} |
||||
|
||||
}; |
||||
|
||||
return this.each(function () { |
||||
|
||||
var $input = $(this), |
||||
$checkbox = $($input.data('typetoggle')); |
||||
|
||||
// Create clone
|
||||
var $clone = cloneElement($input); |
||||
$clone.insertAfter($input); |
||||
|
||||
// Set callback arguments
|
||||
if (callback.fn) { |
||||
callback.args.input = $input; |
||||
callback.args.checkbox = $checkbox; |
||||
callback.args.clone = $clone; |
||||
} |
||||
|
||||
|
||||
$checkbox.bind('click', function () { |
||||
setState($checkbox, $input, $clone); |
||||
}); |
||||
|
||||
$input.bind('keyup', function () { |
||||
update($input, $clone); |
||||
}); |
||||
|
||||
$clone.bind('keyup', function () { |
||||
update($clone, $input); |
||||
|
||||
// Added for JQuery Validation compatibility
|
||||
// This will trigger validation if it's ON for keyup event
|
||||
$input.trigger('keyup'); |
||||
|
||||
}); |
||||
|
||||
// Added for JQuery Validation compatibility
|
||||
// This will trigger validation if it's ON for blur event
|
||||
$clone.bind('blur', function () { |
||||
$input.trigger('focusout'); |
||||
}); |
||||
|
||||
setState($checkbox, $input, $clone); |
||||
|
||||
// set type of password field clone (type=text) to password right on submit
|
||||
// to prevent browser save the value of this field
|
||||
$clone.closest('form').submit(function (e) { |
||||
// .prop has to be used, because .attr throws
|
||||
// an error while changing a type of an input
|
||||
// element
|
||||
$clone.prop('type', 'password'); |
||||
}); |
||||
|
||||
if (callback.fn) { |
||||
callback.fn(callback.args); |
||||
} |
||||
|
||||
}); |
||||
} |
||||
}); |
||||
@ -0,0 +1,83 @@ |
||||
/* |
||||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
import $ from 'jquery' |
||||
|
||||
/** |
||||
* $ tipsy shim for the bootstrap tooltip |
||||
* @deprecated |
||||
*/ |
||||
$.fn.tipsy = function (argument) { |
||||
console.warn('Deprecation warning: tipsy is deprecated. Use tooltip instead.'); |
||||
if (typeof argument === 'object' && argument !== null) { |
||||
|
||||
// tipsy defaults
|
||||
var options = { |
||||
placement: 'bottom', |
||||
delay: {'show': 0, 'hide': 0}, |
||||
trigger: 'hover', |
||||
html: false, |
||||
container: 'body' |
||||
}; |
||||
if (argument.gravity) { |
||||
switch (argument.gravity) { |
||||
case 'n': |
||||
case 'nw': |
||||
case 'ne': |
||||
options.placement = 'bottom'; |
||||
break; |
||||
case 's': |
||||
case 'sw': |
||||
case 'se': |
||||
options.placement = 'top'; |
||||
break; |
||||
case 'w': |
||||
options.placement = 'right'; |
||||
break; |
||||
case 'e': |
||||
options.placement = 'left'; |
||||
break; |
||||
} |
||||
} |
||||
if (argument.trigger) { |
||||
options.trigger = argument.trigger; |
||||
} |
||||
if (argument.delayIn) { |
||||
options.delay.show = argument.delayIn; |
||||
} |
||||
if (argument.delayOut) { |
||||
options.delay.hide = argument.delayOut; |
||||
} |
||||
if (argument.html) { |
||||
options.html = true; |
||||
} |
||||
if (argument.fallback) { |
||||
options.title = argument.fallback; |
||||
} |
||||
// destroy old tooltip in case the title has changed
|
||||
$.fn.tooltip.call(this, 'destroy'); |
||||
$.fn.tooltip.call(this, options); |
||||
} else { |
||||
this.tooltip(argument); |
||||
$.fn.tooltip.call(this, argument); |
||||
} |
||||
return this; |
||||
}; |
||||
@ -1,8 +1,8 @@ |
||||
// Various jquery fixes
|
||||
import $ from 'jquery' |
||||
|
||||
// Set autocomplete width the same as the related input
|
||||
// See http://stackoverflow.com/a/11845718
|
||||
jQuery.ui.autocomplete.prototype._resizeMenu = function () { |
||||
$.ui.autocomplete.prototype._resizeMenu = function () { |
||||
var ul = this.menu.element; |
||||
ul.outerWidth(this.element.outerWidth()); |
||||
}; |
||||
Loading…
Reference in new issue