Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>tags/v16.0.0alpha1
@@ -1,12 +1,7 @@ | |||
{ | |||
"libraries": [ | |||
"jquery-showpassword.js", | |||
"jquery.avatar.js", | |||
"jquery.contactsmenu.js", | |||
"placeholder.js" | |||
], | |||
"modules": [ | |||
"jquery.ocdialog.js", | |||
"oc-dialogs.js", | |||
"js.js", | |||
"share.js", | |||
@@ -18,7 +13,6 @@ | |||
"sharedialoglinkshareview.js", | |||
"sharedialogresharerinfoview.js", | |||
"sharedialogshareelistview.js", | |||
"octemplate.js", | |||
"contactsmenu_templates.js", | |||
"public/appconfig.js", | |||
"public/comments.js", |
@@ -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)); |
@@ -29,15 +29,6 @@ if (typeof console === "undefined" || typeof console.log === "undefined") { | |||
} | |||
} | |||
/** | |||
* Sanitizes a HTML string by replacing all potential dangerous characters with HTML entities | |||
* @param {string} s String to sanitize | |||
* @return {string} Sanitized string | |||
*/ | |||
function escapeHTML(s) { | |||
return s.toString().split('&').join('&').split('<').join('<').split('>').join('>').split('"').join('"').split('\'').join('''); | |||
} | |||
/** @namespace OCP */ | |||
var OCP = Object.assign({}, window.OCP); | |||
@@ -1832,13 +1823,6 @@ OC.PasswordConfirmation = { | |||
$(document).ready(initCore); | |||
/** | |||
* Filter Jquery selector by attribute value | |||
*/ | |||
$.fn.filterAttr = function(attr_name, attr_value) { | |||
return this.filter(function() { return $(this).attr(attr_name) === attr_value; }); | |||
}; | |||
/** | |||
* Returns a human readable file size | |||
* @param {number} size Size in bytes | |||
@@ -2338,93 +2322,3 @@ OC.set=function(name, value) { | |||
document.getElementsByTagName("head")[0].appendChild(msViewportStyle); | |||
} | |||
})(); | |||
/** | |||
* 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 | |||
*/ | |||
jQuery.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(); | |||
} | |||
}); | |||
}; | |||
/** | |||
* 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 | |||
*/ | |||
jQuery.fn.exists = function(){ | |||
return this.length > 0; | |||
}; | |||
/** | |||
* jQuery tipsy shim for the bootstrap tooltip | |||
*/ | |||
jQuery.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 | |||
jQuery.fn.tooltip.call(this, 'destroy'); | |||
jQuery.fn.tooltip.call(this, options); | |||
} else { | |||
this.tooltip(argument); | |||
jQuery.fn.tooltip.call(this, argument); | |||
} | |||
return this; | |||
}; |
@@ -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 ); | |||
@@ -1,174 +0,0 @@ | |||
/** | |||
* ownCloud | |||
* | |||
* @author John Molakvoæ | |||
* @copyright 2016-2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* @author Morris Jobke | |||
* @copyright 2013 Morris Jobke <morris.jobke@gmail.com> | |||
* | |||
* This library is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or any later version. | |||
* | |||
* This library 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 library. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
/* | |||
* Adds a background color to the element called on and adds the first character | |||
* of the passed in string. This string is also the seed for the generation of | |||
* the background color. | |||
* | |||
* You have following HTML: | |||
* | |||
* <div id="albumart"></div> | |||
* | |||
* And call this from Javascript: | |||
* | |||
* $('#albumart').imageplaceholder('The Album Title'); | |||
* | |||
* Which will result in: | |||
* | |||
* <div id="albumart" style="background-color: rgb(121, 90, 171); ... ">T</div> | |||
* | |||
* You may also call it like this, to have a different background, than the seed: | |||
* | |||
* $('#albumart').imageplaceholder('The Album Title', 'Album Title'); | |||
* | |||
* Resulting in: | |||
* | |||
* <div id="albumart" style="background-color: rgb(121, 90, 171); ... ">A</div> | |||
* | |||
*/ | |||
/* | |||
* Alternatively, you can use the prototype function to convert your string to rgb colors: | |||
* | |||
* "a6741a86aded5611a8e46ce16f2ad646".toRgb() | |||
* | |||
* Will return the rgb parameters within the following object: | |||
* | |||
* Color {r: 208, g: 158, b: 109} | |||
* | |||
*/ | |||
(function ($) { | |||
String.prototype.toRgb = function() { | |||
// Normalize hash | |||
var hash = this.toLowerCase(); | |||
// Already a md5 hash? | |||
if( hash.match(/^([0-9a-f]{4}-?){8}$/) === null ) { | |||
hash = md5(hash); | |||
} | |||
hash = hash.replace(/[^0-9a-f]/g, ''); | |||
function Color(r,g,b) { | |||
this.r = r; | |||
this.g = g; | |||
this.b = b; | |||
} | |||
function stepCalc(steps, ends) { | |||
var step = new Array(3); | |||
step[0] = (ends[1].r - ends[0].r) / steps; | |||
step[1] = (ends[1].g - ends[0].g) / steps; | |||
step[2] = (ends[1].b - ends[0].b) / steps; | |||
return step; | |||
} | |||
function mixPalette(steps, color1, color2) { | |||
var count = steps + 1; | |||
var palette = new Array(); | |||
palette.push(color1); | |||
var step = stepCalc(steps, [color1, color2]) | |||
for (var i = 1; i < steps; i++) { | |||
var r = parseInt(color1.r + (step[0] * i)); | |||
var g = parseInt(color1.g + (step[1] * i)); | |||
var b = parseInt(color1.b + (step[2] * i)); | |||
palette.push(new Color(r,g,b)); | |||
} | |||
return palette; | |||
} | |||
var red = new Color(182, 70, 157); | |||
var yellow = new Color(221, 203, 85); | |||
var blue = new Color(0, 130, 201); // Nextcloud blue | |||
// Number of steps to go from a color to another | |||
// 3 colors * 6 will result in 18 generated colors | |||
var steps = 6; | |||
var palette1 = mixPalette(steps, red, yellow); | |||
var palette2 = mixPalette(steps, yellow, blue); | |||
var palette3 = mixPalette(steps, blue, red); | |||
var finalPalette = palette1.concat(palette2).concat(palette3); | |||
// Convert a string to an integer evenly | |||
function hashToInt(hash, maximum) { | |||
var finalInt = 0; | |||
var result = Array(); | |||
// Splitting evenly the string | |||
for (var i=0; i<hash.length; i++) { | |||
// chars in md5 goes up to f, hex:16 | |||
result.push(parseInt(hash.charAt(i), 16) % 16); | |||
} | |||
// Adds up all results | |||
for (var j in result) { | |||
finalInt += result[j]; | |||
} | |||
// chars in md5 goes up to f, hex:16 | |||
// make sure we're always using int in our operation | |||
return parseInt(parseInt(finalInt) % maximum); | |||
} | |||
return finalPalette[hashToInt(hash, steps * 3 )]; | |||
}; | |||
$.fn.imageplaceholder = function(seed, text, size) { | |||
text = text || seed; | |||
// Compute the hash | |||
var rgb = seed.toRgb(); | |||
this.css('background-color', 'rgb('+rgb.r+', '+rgb.g+', '+rgb.b+')'); | |||
// Placeholders are square | |||
var height = this.height() || size || 32; | |||
this.height(height); | |||
this.width(height); | |||
// CSS rules | |||
this.css('color', '#fff'); | |||
this.css('font-weight', 'normal'); | |||
this.css('text-align', 'center'); | |||
// calculate the height | |||
this.css('line-height', height + 'px'); | |||
this.css('font-size', (height * 0.55) + 'px'); | |||
if(seed !== null && seed.length) { | |||
this.html(text[0].toUpperCase()); | |||
} | |||
}; | |||
$.fn.clearimageplaceholder = function() { | |||
this.css('background-color', ''); | |||
this.css('color', ''); | |||
this.css('font-weight', ''); | |||
this.css('text-align', ''); | |||
this.css('line-height', ''); | |||
this.css('font-size', ''); | |||
this.html(''); | |||
this.removeClass('icon-loading'); | |||
this.removeClass('icon-loading-small'); | |||
}; | |||
}(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('''); | |||
} |
@@ -51,6 +51,7 @@ import 'strengthify/strengthify.css' | |||
import OC from './OC/index' | |||
import OCP from './OCP/index' | |||
import OCA from './OCA/index' | |||
import escapeHTML from './Util/escapeHTML' | |||
window['_'] = _ | |||
window['$'] = $ | |||
@@ -72,6 +73,7 @@ window['moment'] = moment | |||
window['OC'] = OC | |||
window['OCP'] = OCP | |||
window['OCA'] = OCA | |||
window['escapeHTML'] = escapeHTML | |||
/** | |||
* translate a string |
@@ -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,174 @@ | |||
/** | |||
* ownCloud | |||
* | |||
* @author John Molakvoæ | |||
* @copyright 2016-2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* @author Morris Jobke | |||
* @copyright 2013 Morris Jobke <morris.jobke@gmail.com> | |||
* | |||
* This library is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or any later version. | |||
* | |||
* This library 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 library. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
import $ from 'jquery' | |||
/* | |||
* Adds a background color to the element called on and adds the first character | |||
* of the passed in string. This string is also the seed for the generation of | |||
* the background color. | |||
* | |||
* You have following HTML: | |||
* | |||
* <div id="albumart"></div> | |||
* | |||
* And call this from Javascript: | |||
* | |||
* $('#albumart').imageplaceholder('The Album Title'); | |||
* | |||
* Which will result in: | |||
* | |||
* <div id="albumart" style="background-color: rgb(121, 90, 171); ... ">T</div> | |||
* | |||
* You may also call it like this, to have a different background, than the seed: | |||
* | |||
* $('#albumart').imageplaceholder('The Album Title', 'Album Title'); | |||
* | |||
* Resulting in: | |||
* | |||
* <div id="albumart" style="background-color: rgb(121, 90, 171); ... ">A</div> | |||
* | |||
*/ | |||
/* | |||
* Alternatively, you can use the prototype function to convert your string to rgb colors: | |||
* | |||
* "a6741a86aded5611a8e46ce16f2ad646".toRgb() | |||
* | |||
* Will return the rgb parameters within the following object: | |||
* | |||
* Color {r: 208, g: 158, b: 109} | |||
* | |||
*/ | |||
String.prototype.toRgb = function () { | |||
// Normalize hash | |||
var hash = this.toLowerCase(); | |||
// Already a md5 hash? | |||
if (hash.match(/^([0-9a-f]{4}-?){8}$/) === null) { | |||
hash = md5(hash); | |||
} | |||
hash = hash.replace(/[^0-9a-f]/g, ''); | |||
function Color (r, g, b) { | |||
this.r = r; | |||
this.g = g; | |||
this.b = b; | |||
} | |||
function stepCalc (steps, ends) { | |||
var step = new Array(3); | |||
step[0] = (ends[1].r - ends[0].r) / steps; | |||
step[1] = (ends[1].g - ends[0].g) / steps; | |||
step[2] = (ends[1].b - ends[0].b) / steps; | |||
return step; | |||
} | |||
function mixPalette (steps, color1, color2) { | |||
var count = steps + 1; | |||
var palette = new Array(); | |||
palette.push(color1); | |||
var step = stepCalc(steps, [color1, color2]) | |||
for (var i = 1; i < steps; i++) { | |||
var r = parseInt(color1.r + (step[0] * i)); | |||
var g = parseInt(color1.g + (step[1] * i)); | |||
var b = parseInt(color1.b + (step[2] * i)); | |||
palette.push(new Color(r, g, b)); | |||
} | |||
return palette; | |||
} | |||
var red = new Color(182, 70, 157); | |||
var yellow = new Color(221, 203, 85); | |||
var blue = new Color(0, 130, 201); // Nextcloud blue | |||
// Number of steps to go from a color to another | |||
// 3 colors * 6 will result in 18 generated colors | |||
var steps = 6; | |||
var palette1 = mixPalette(steps, red, yellow); | |||
var palette2 = mixPalette(steps, yellow, blue); | |||
var palette3 = mixPalette(steps, blue, red); | |||
var finalPalette = palette1.concat(palette2).concat(palette3); | |||
// Convert a string to an integer evenly | |||
function hashToInt (hash, maximum) { | |||
var finalInt = 0; | |||
var result = Array(); | |||
// Splitting evenly the string | |||
for (var i = 0; i < hash.length; i++) { | |||
// chars in md5 goes up to f, hex:16 | |||
result.push(parseInt(hash.charAt(i), 16) % 16); | |||
} | |||
// Adds up all results | |||
for (var j in result) { | |||
finalInt += result[j]; | |||
} | |||
// chars in md5 goes up to f, hex:16 | |||
// make sure we're always using int in our operation | |||
return parseInt(parseInt(finalInt) % maximum); | |||
} | |||
return finalPalette[hashToInt(hash, steps * 3)]; | |||
}; | |||
$.fn.imageplaceholder = function (seed, text, size) { | |||
text = text || seed; | |||
// Compute the hash | |||
var rgb = seed.toRgb(); | |||
this.css('background-color', 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')'); | |||
// Placeholders are square | |||
var height = this.height() || size || 32; | |||
this.height(height); | |||
this.width(height); | |||
// CSS rules | |||
this.css('color', '#fff'); | |||
this.css('font-weight', 'normal'); | |||
this.css('text-align', 'center'); | |||
// calculate the height | |||
this.css('line-height', height + 'px'); | |||
this.css('font-size', (height * 0.55) + 'px'); | |||
if (seed !== null && seed.length) { | |||
this.html(text[0].toUpperCase()); | |||
} | |||
}; | |||
$.fn.clearimageplaceholder = function () { | |||
this.css('background-color', ''); | |||
this.css('color', ''); | |||
this.css('font-weight', ''); | |||
this.css('text-align', ''); | |||
this.css('line-height', ''); | |||
this.css('font-size', ''); | |||
this.html(''); | |||
this.removeClass('icon-loading'); | |||
this.removeClass('icon-loading-small'); | |||
}; |
@@ -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()); | |||
}; |
@@ -23,6 +23,7 @@ import '@babel/polyfill' | |||
import './globals' | |||
import $ from 'jquery' | |||
import './jquery/index' | |||
import {registerAppsSlideToggle} from './OC/apps' | |||
$(document).ready(function () { |