1
0
mirror of https://github.com/owncloudarchive/contacts.git synced 2024-11-29 11:24:11 +01:00

Merge branch 'master' into filesystem

This commit is contained in:
Robin Appelman 2012-12-25 14:29:56 +01:00
commit 3f9e124ddf
28 changed files with 2380 additions and 489 deletions

View File

@ -31,10 +31,10 @@
}
#content textarea { font-family: inherit; }
#content input:-moz-placeholder { color: #aaa; }
#content input::-webkit-input-placeholder { color: #aaa; }
#content input:-ms-input-placeholder { color: #aaa; }
#content input:placeholder { color: #aaa; }
#content input:-moz-placeholder #content ::-moz-placeholder, #content input[placeholder], #content input:placeholder, #content input:-ms-input-placeholder, #content input::-webkit-input-placeholder, #content input:-moz-placeholder {
color: #aaa;
text-overflow: ellipsis;
}
#content input:not([type="checkbox"]), #content select:not(.button), #content textarea {
background-color: #fefefe; border: 1px solid #fff !important;
@ -62,7 +62,7 @@
/* Left content */
#leftcontent { top: 3.5em !important; padding: 0; margin: 0; }
#leftcontent { position: absolute; top: 4em; padding: 0; margin: 0; }
#leftcontent a { display: inline-block; padding: 0; margin: 0; }
#leftcontent h3 {
cursor: pointer;
@ -95,7 +95,16 @@
margin: auto 0 auto .3em;
}
#groupactions { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; height: 4em; border-bottom: 1px solid #DDDDDD; }
#groupsheader {
-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;
position: fixed;
padding: 0; margin:0;
top:3.5em; left: 12.5em;
height: 4em; width: 20em;
border-bottom: 1px solid #DDDDDD;
border-right: 1px solid #DDDDDD;
background: none repeat scroll 0 0 #F8F8F8;
}
/*#groupactions > button, .addcontact, .import-upload-button, .doImport {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
@ -162,8 +171,9 @@ dl.form { display: block; width: auto; margin: 0; padding: 0; cursor: normal; }
.no-svg .mail { background-image:url('%webroot%/core/img/actions/mail.png'); }
.no-svg .import, .no-svg .upload { background-image:url('%webroot%/core/img/actions/upload.png'); }
.no-svg .export, .no-svg .download { background-image:url('%webroot%/core/img/actions/download.png'); }
.no-svg .cloud:not { background-image:url('%webroot%/core/img/places/picture.png'); }
.no-svg .globe:not { background-image:url('%webroot%/core/img/actions/public.png'); }
.no-svg .cloud { background-image:url('%webroot%/core/img/places/picture.png'); }
.no-svg .globe { background-image:url('%webroot%/core/img/actions/public.png'); }
.no-svg .settings { background-image:url('%webroot%/core/img/actions/settings.svg'); }
.no-svg .starred { background-image:url('%appswebroot%/contacts/img/starred.png'); background-size: contain; }
.no-svg .checked { background-image:url('%appswebroot%/contacts/img/checkmark-green.png'); }
.no-svg .checked.disabled { background-image:url('%appswebroot%/contacts/img/checkmark-gray.png'); cursor: default; }
@ -186,6 +196,7 @@ dl.form { display: block; width: auto; margin: 0; padding: 0; cursor: normal; }
.svg .export,.svg .download { background-image:url('%webroot%/core/img/actions/download.svg'); }
.svg .cloud { background-image:url('%webroot%/core/img/places/picture.svg'); }
.svg .globe { background-image:url('%webroot%/core/img/actions/public.svg'); }
.svg .settings { background-image:url('%webroot%/core/img/actions/settings.svg'); }
.svg .starred { background-image:url('%appswebroot%/contacts/img/starred.svg'); background-size: contain; }
.svg .checked { background-image:url('%appswebroot%/contacts/img/checkmark-green.svg'); }
.svg .checked.disabled { background-image:url('%appswebroot%/contacts/img/checkmark-gray.svg'); cursor: default; }
@ -307,10 +318,18 @@ ul.propertylist { width: 450px; }
.addressbooks-settings td.active, .addressbooks-settings td.action { width: 20px; }
#contacts-settings .settings {
width: 20px; height: 20px;
float: left;
/*width: 20px; height: 20px;
float: left;*/
color: transparent;
background-repeat: no-repeat;
background-position: left center;
background-origin: content-box;
background-image:url('%webroot%/core/img/actions/settings.svg');
}
#contacts-settings .settings:hover {
font-weight: normal;
color: #666666;
}
#contacts-settings.open {
height: auto;
}
@ -331,7 +350,7 @@ ul.propertylist { width: 450px; }
z-index: 2;
}
#contacts-settings li,#contacts-settings li:hover { background-color: transparent; white-space: nowrap; }
#contacts-settings a.action { width: 20px; height: 20px; }
#contacts-settings a.action:not(.settings) { width: 16px; height: 16px; }
#contacts-settings .actions { float: right; }
.multiselectoptions label { display: block; }
@ -433,7 +452,7 @@ input[type="checkbox"].propertytype { width: 10px; }
/* Right content layout */
#rightcontent, .rightcontent { position:fixed; top: 7.5em; left: 32.5em; overflow-x:hidden; overflow-y: auto; }
#rightcontent, .rightcontent { position:absolute; top: 4em; left: 20em; overflow-x:hidden; overflow-y: auto; }
/* Contact layout */

View File

@ -0,0 +1,32 @@
span.placeholder{
position:absolute;
font-size:75%;
color:#999;
font-family:sans-serif;
padding:4px 3px;
z-index:1;
cursor:text;
}
span.placeholder-hide-except-screenreader {
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
padding:0 !important;
border:0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
span.placeholder-hide{
display:none;
}
/* overwrite for the HTML5 Boilerplate way to hide labels */
label.visuallyhidden-with-placeholder{
/*clip: auto !important;*/
height:auto !important;
overflow: visible !important;
position:absolute !important;
left:-999em;
}

8
css/placeholder_polyfill.min.css vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Html5 Placeholder Polyfill - v2.0.3 - 2012-08-21
* web: * http://blog.ginader.de/dev/jquery/HTML5-placeholder-polyfill/
* issues: * https://github.com/ginader/HTML5-placeholder-polyfill/issues
* Copyright (c) 2012 Dirk Ginader; Licensed MIT, GPL
*/
label span.placeholder{position:absolute;font-size:75%;color:#999;font-family:sans-serif;padding:4px 3px;z-index:1;cursor:text}label span.placeholder-hide-except-screenreader{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}
label span.placeholder-hide{display:none}label.visuallyhidden-with-placeholder{height:auto!important;overflow:visible!important;position:absolute!important;left:-999em}

View File

@ -49,16 +49,13 @@ $maxUploadFilesize = min($maxUploadFilesize, $freeSpace);
OCP\Util::addscript('contacts', 'multiselect');
OCP\Util::addscript('', 'oc-vcategories');
OCP\Util::addscript('contacts', 'modernizr.custom');
OCP\Util::addscript('contacts', 'app');
OCP\Util::addscript('contacts', 'contacts');
OCP\Util::addscript('contacts', 'modernizr');
OCP\Util::addscript('contacts', 'placeholder.polyfill.jquery');
OCP\Util::addscript('contacts', 'expanding');
OCP\Util::addscript('contacts', 'jquery.combobox');
OCP\Util::addscript('files', 'jquery.fileupload');
//OCP\Util::addscript('core', 'jquery.inview');
OCP\Util::addscript('contacts', 'jquery.Jcrop');
OCP\Util::addscript('contacts', 'jquery.multi-autocomplete');
OCP\Util::addStyle('contacts', 'multiselect');
OCP\Util::addStyle('contacts', 'jquery.combobox');
OCP\Util::addStyle('contacts', 'jquery.Jcrop');

224
js/app.js
View File

@ -1,3 +1,11 @@
Modernizr.load({
test: Modernizr.input.placeholder,
nope: [
OC.filePath('contacts', 'css', 'placeholder_polyfill.min.css'),
OC.filePath('contacts', 'js', 'placeholder_polyfill.jquery.min.combo.js')
]
});
var utils = {};
/**
@ -22,11 +30,11 @@ utils.isArray = function(obj) {
utils.isInt = function(s) {
return typeof s === 'number' && (s.toString().search(/^-?[0-9]+$/) === 0);
}
};
utils.isUInt = function(s) {
return typeof s === 'number' && (s.toString().search(/^[0-9]+$/) === 0);
}
};
/**
* utils.type
@ -50,7 +58,7 @@ utils.moveCursorToEnd = function(el) {
range.collapse(false);
range.select();
}
}
};
if (typeof Object.create !== 'function') {
Object.create = function (o) {
@ -77,8 +85,9 @@ Array.prototype.clean = function(deleteValue) {
// Keep it DRY ;)
var wrongKey = function(event) {
return (event.type === 'keydown' && (event.keyCode !== 32 && event.keyCode !== 13));
}
return ((event.type === 'keydown' || event.type === 'keypress')
&& (event.keyCode !== 32 && event.keyCode !== 13));
};
/**
* Simply notifier
@ -140,7 +149,7 @@ OC.notify = function(params) {
self.notifier.removeData(dataid);
});
}
}
};
var GroupList = function(groupList, listItemTmpl) {
this.$groupList = groupList;
@ -158,7 +167,7 @@ var GroupList = function(groupList, listItemTmpl) {
if(response.status !== 'success') {
OC.notify({message:response.data.message});
}
})
});
} else {
self.selectGroup({element:$(this)});
}
@ -166,19 +175,19 @@ var GroupList = function(groupList, listItemTmpl) {
this.$groupListItemTemplate = listItemTmpl;
this.categories = [];
}
};
GroupList.prototype.nameById = function(id) {
return this.findById(id).contents().filter(function(){ return(this.nodeType == 3); }).text().trim()
}
return this.findById(id).contents().filter(function(){ return(this.nodeType == 3); }).text().trim();
};
GroupList.prototype.findById = function(id) {
return this.$groupList.find('h3[data-id="' + id + '"]');
}
};
GroupList.prototype.isFavorite = function(contactid) {
return this.inGroup(contactid, 'fav');
}
};
GroupList.prototype.selectGroup = function(params) {
var id, $elem;
@ -203,15 +212,15 @@ GroupList.prototype.selectGroup = function(params) {
$(document).trigger('status.group.selected', {
id: this.lastgroup,
type: $elem.data('type'),
contacts: $elem.data('contacts'),
contacts: $elem.data('contacts')
});
}
};
GroupList.prototype.inGroup = function(contactid, groupid) {
var $groupelem = this.findById(groupid);
var contacts = $groupelem.data('contacts');
return (contacts.indexOf(contactid) !== -1);
}
};
GroupList.prototype.setAsFavorite = function(contactid, state, cb) {
contactid = parseInt(contactid);
@ -251,7 +260,7 @@ GroupList.prototype.setAsFavorite = function(contactid, state, cb) {
}
});
}
}
};
/**
* Add one or more contact ids to a group
@ -315,7 +324,7 @@ GroupList.prototype.addTo = function(contactid, groupid, cb) {
$(document).trigger('status.group.contactadded', {
contactid: contactid,
groupid: groupid,
groupname: self.nameById(groupid),
groupname: self.nameById(groupid)
});
}
} else {
@ -325,14 +334,14 @@ GroupList.prototype.addTo = function(contactid, groupid, cb) {
}
});
}
}
};
GroupList.prototype.removeFrom = function(contactid, groupid, cb) {
console.log('GroupList.removeFrom', contactid, groupid);
var $groupelem = this.findById(groupid);
var contacts = $groupelem.data('contacts');
var ids = [];
// If it's the 'all' group simply decrement the number
if(groupid === 'all') {
var $numelem = $groupelem.find('.numcontacts');
@ -405,7 +414,7 @@ GroupList.prototype.removeFrom = function(contactid, groupid, cb) {
}
});
}
}
};
GroupList.prototype.removeFromAll = function(contactid, alsospecial) {
var self = this;
@ -413,11 +422,11 @@ GroupList.prototype.removeFromAll = function(contactid, alsospecial) {
$.each(this.$groupList.find(selector), function(i, group) {
self.removeFrom(contactid, $(this).data('id'));
});
}
};
GroupList.prototype.categoriesChanged = function(newcategories) {
console.log('GroupList.categoriesChanged, I should do something');
}
};
GroupList.prototype.contactDropped = function(event, ui) {
var dragitem = ui.draggable, droptarget = $(this);
@ -430,7 +439,7 @@ GroupList.prototype.contactDropped = function(event, ui) {
$(this).data('obj').addTo(dragitem.data('id'), $(this).data('id'));
}
}
}
};
GroupList.prototype.deleteGroup = function(groupid, cb) {
var $elem = this.findById(groupid);
@ -445,7 +454,7 @@ GroupList.prototype.deleteGroup = function(groupid, cb) {
groupid: groupid,
newgroupid: parseInt($newelem.data('id')),
groupname: self.nameById(groupid),
contacts: contacts,
contacts: contacts
});
$elem.remove();
self.selectGroup({element:$newelem});
@ -456,7 +465,7 @@ GroupList.prototype.deleteGroup = function(groupid, cb) {
cb(jsondata);
}
});
}
};
GroupList.prototype.editGroup = function(id) {
var self = this;
@ -476,16 +485,16 @@ GroupList.prototype.editGroup = function(id) {
self.addGroup({name:name, element:$elem}, function(response) {
if(response.status === 'success') {
$elem.prepend(name).removeClass('editing').attr('data-id', response.id);
$input.next('.checked').remove()
$input.remove()
$input.next('.checked').remove();
$input.remove();
self.$editelem = null;
} else {
$input.prop('disabled', false);
OC.notify({message:response.message});
}
});
}
};
if(typeof id === 'undefined') {
// Add new group
var tmpl = this.$groupListItemTemplate;
@ -493,7 +502,7 @@ GroupList.prototype.editGroup = function(id) {
id: 'new',
type: 'category',
num: 0,
name: '',
name: ''
});
var $input = $('<input type="text" class="active" /><a class="action checked disabled" />');
self.$editelem.prepend($input).addClass('editing');
@ -533,11 +542,11 @@ GroupList.prototype.editGroup = function(id) {
var $input = $('<input type="text" class="active" value="' + name + '" /><a class="action checked disabled />');
$elem.prepend($input).addClass('editing');
$input.focus();
} else {
throw { name: 'WrongParameterType', message: 'GroupList.editGroup only accept integers.'}
throw { name: 'WrongParameterType', message: 'GroupList.editGroup only accept integers.'};
}
}
};
GroupList.prototype.addGroup = function(params, cb) {
console.log('GroupList.addGroup', params.name);
@ -565,8 +574,8 @@ GroupList.prototype.addGroup = function(params, cb) {
id: jsondata.data.id,
type: 'category',
num: contacts.length,
name: name,
})
name: name
});
self.categories.push({id: jsondata.data.id, name: name});
$elem.data('obj', self);
$elem.data('contacts', contacts);
@ -595,7 +604,7 @@ GroupList.prototype.addGroup = function(params, cb) {
}
}
});
}
};
GroupList.prototype.loadGroups = function(numcontacts, cb) {
var self = this;
@ -608,11 +617,11 @@ GroupList.prototype.loadGroups = function(numcontacts, cb) {
if (jsondata && jsondata.status == 'success') {
self.lastgroup = jsondata.data.lastgroup;
self.sortorder = jsondata.data.sortorder.length > 0
? $.map(jsondata.data.sortorder.split(','), function(c) {return parseInt(c)})
? $.map(jsondata.data.sortorder.split(','), function(c) {return parseInt(c);})
: [];
console.log('sortorder', self.sortorder);
// Favorites
var contacts = $.map(jsondata.data.favorites, function(c) {return parseInt(c)});
var contacts = $.map(jsondata.data.favorites, function(c) {return parseInt(c);});
var $elem = tmpl.octemplate({
id: 'fav',
type: 'fav',
@ -633,12 +642,12 @@ GroupList.prototype.loadGroups = function(numcontacts, cb) {
console.log('favorites', $elem.data('contacts'));
// Normal groups
$.each(jsondata.data.categories, function(c, category) {
var contacts = $.map(category.contacts, function(c) {return parseInt(c)});
var contacts = $.map(category.contacts, function(c) {return parseInt(c);});
var $elem = (tmpl).octemplate({
id: category.id,
type: 'category',
num: contacts.length,
name: category.name,
name: category.name
});
self.categories.push({id: category.id, name: category.name});
$elem.data('obj', self);
@ -666,12 +675,12 @@ GroupList.prototype.loadGroups = function(numcontacts, cb) {
// Shared addressbook
$.each(jsondata.data.shared, function(c, shared) {
var sharedindicator = '<img class="shared svg" src="' + OC.imagePath('core', 'actions/shared') + '"'
+ 'title="' + t('contacts', 'Shared by {owner}', {owner:shared.userid}) + '" />'
+ 'title="' + t('contacts', 'Shared by {owner}', {owner:shared.userid}) + '" />';
var $elem = (tmpl).octemplate({
id: shared.id,
type: 'shared',
num: '', //jsondata.data.shared.length,
name: shared.displayname,
name: shared.displayname
});
$elem.find('.numcontacts').after(sharedindicator);
$elem.data('obj', self);
@ -685,27 +694,27 @@ GroupList.prototype.loadGroups = function(numcontacts, cb) {
console.log('stop sorting', $(this));
var ids = [];
$.each($(this).children('h3[data-type="category"]'), function(i, elem) {
ids.push($(elem).data('id'))
})
ids.push($(elem).data('id'));
});
self.sortorder = ids;
$(document).trigger('status.groups.sorted', {
sortorder: self.sortorder.join(','),
sortorder: self.sortorder.join(',')
});
},
}
});
var $elem = self.findById(self.lastgroup);
$elem.addClass('active');
$(document).trigger('status.group.selected', {
id: self.lastgroup,
type: $elem.data('type'),
contacts: $elem.data('contacts'),
contacts: $elem.data('contacts')
});
} // TODO: else
if(typeof cb === 'function') {
cb();
}
});
}
};
OC.Contacts = OC.Contacts || {
init:function(id) {
@ -713,7 +722,7 @@ OC.Contacts = OC.Contacts || {
$(document).ajaxError(function(e, xhr, settings, exception) {
// Don't try to get translation because it's likely a network error.
OC.notify({
message: 'error in: ' + settings.url + ', '+'error: ' + xhr.responseText,
message: 'error in: ' + settings.url + ', '+'error: ' + xhr.responseText
});
});
}
@ -777,9 +786,10 @@ OC.Contacts = OC.Contacts || {
// The weird double loading is because jquery apparently doesn't
// create a searchable object from a script element.
$.each($($('#contactDetailsTemplate').html()), function(idx, node) {
if(node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'DIV') {
var $node = $(node);
if($node.is('div')) {
var $tmpl = $(node.innerHTML);
self.detailTemplates[$tmpl.data('element')] = $(node);
self.detailTemplates[$tmpl.data('element')] = $node;
}
});
this.$groupListItemTemplate = $('#groupListItemTemplate');
@ -853,7 +863,7 @@ OC.Contacts = OC.Contacts || {
var id = parseInt(data.id);
console.log('contact', data.id, 'deleted');
// update counts on group lists
self.groups.removeFromAll(data.id, true)
self.groups.removeFromAll(data.id, true);
});
$(document).bind('status.contact.added', function(e, data) {
@ -867,7 +877,7 @@ OC.Contacts = OC.Contacts || {
});
$(document).bind('status.contact.enabled', function(e, enabled) {
console.log('status.contact.enabled', enabled)
console.log('status.contact.enabled', enabled);
/*if(enabled) {
self.showActions(['back', 'download', 'delete', 'groups']);
} else {
@ -906,7 +916,7 @@ OC.Contacts = OC.Contacts || {
self.dontScroll = false;
}, 100);
}
self.currentlistid = result.id
self.currentlistid = result.id;
});
$(document).bind('status.nomorecontacts', function(e, result) {
@ -931,7 +941,7 @@ OC.Contacts = OC.Contacts || {
console.log('waiting for contacts to load');
setTimeout(function() {
$(document).trigger('request.loadcontact', {
id: result.id,
id: result.id
});
}, 1000);
}
@ -1008,7 +1018,7 @@ OC.Contacts = OC.Contacts || {
$.each(result.contacts, function(idx, contactid) {
var contact = self.contacts.findById(contactid);
console.log('contactid', contactid, contact);
self.contacts.findById(contactid).removeFromGroup(result.groupname);
});
});
@ -1083,7 +1093,7 @@ OC.Contacts = OC.Contacts || {
if(self.$settings.find($(e.target)).length == 0) {
self.$settings.switchClass('open', '');
}
}
};
if(self.$settings.hasClass('open')) {
self.$settings.switchClass('open', '');
$('body').unbind('click', bodyListener);
@ -1096,7 +1106,7 @@ OC.Contacts = OC.Contacts || {
self.uploadPhoto(this.files);
});
$('#groupactions > .addgroup').on('click keydown',function(event) {
$('#groupsheader > .addgroup').on('click keydown',function(event) {
if(wrongKey(event)) {
return;
}
@ -1145,8 +1155,8 @@ OC.Contacts = OC.Contacts || {
// If a contact is open the action is only applied to that,
// otherwise on all selected items.
if(self.currentid) {
ids = [self.currentid,];
buildnow = true
ids = [self.currentid];
buildnow = true;
} else {
ids = self.contacts.getSelectedContacts();
}
@ -1156,7 +1166,7 @@ OC.Contacts = OC.Contacts || {
if(!self.currentid) {
self.showActions(['add']);
}
if($opt.val() === 'add') { // Add new group
action = 'add';
console.log('add group...');
@ -1179,7 +1189,7 @@ OC.Contacts = OC.Contacts || {
$(document).trigger('status.contact.addedtogroup', {
contactid: id,
groupid: groupId,
groupname: groupName,
groupname: groupName
});
}, 1000);
});
@ -1194,7 +1204,7 @@ OC.Contacts = OC.Contacts || {
});
return;
}
groupName = $opt.text(), groupId = $opt.val();
console.log('trut', groupName, groupId);
@ -1215,7 +1225,7 @@ OC.Contacts = OC.Contacts || {
$(document).trigger('status.contact.addedtogroup', {
contactid: id,
groupid: groupId,
groupname: groupName,
groupname: groupName
});
}, 1000);
});
@ -1241,7 +1251,7 @@ OC.Contacts = OC.Contacts || {
$(document).trigger('status.contact.removedfromgroup', {
contactid: id,
groupid: groupId,
groupname: groupName,
groupname: groupName
});
});
} else {
@ -1281,7 +1291,7 @@ OC.Contacts = OC.Contacts || {
}
self.openContact($(this).data('id'));
});
this.$settings.find('h3').on('click keydown', function(event) {
if(wrongKey(event)) {
return;
@ -1294,7 +1304,7 @@ OC.Contacts = OC.Contacts || {
var $list = $(this).next('ul');
if($(this).data('id') === 'addressbooks') {
console.log('addressbooks');
if(!self.$addressbookTmpl) {
self.$addressbookTmpl = $('#addressbookTemplate');
}
@ -1302,9 +1312,9 @@ OC.Contacts = OC.Contacts || {
$list.empty();
$.each(self.contacts.addressbooks, function(id, book) {
var $li = self.$addressbookTmpl.octemplate({
id: id,
id: id,
permissions: book.permissions,
displayname: book.displayname,
displayname: book.displayname
});
$list.append($li);
@ -1317,7 +1327,7 @@ OC.Contacts = OC.Contacts || {
var $li = $(this).parents('li').first();
$.ajax({
type:'POST',
url:OC.filePath('contacts', 'ajax', 'addressbook/delete.php'),
url:OC.filePath('contacts', 'ajax', 'addressbook/delete.php'),
data:{ id: id },
success:function(jsondata) {
console.log(jsondata);
@ -1343,7 +1353,7 @@ OC.Contacts = OC.Contacts || {
error:function(jqXHR, textStatus, errorThrown) {
OC.notify({message:textStatus + ': ' + errorThrown});
id = false;
},
}
});
});
$list.find('a.action.globe').on('click keypress', function() {
@ -1376,13 +1386,13 @@ OC.Contacts = OC.Contacts || {
$.ajax({
type:'POST',
async:false,
url:OC.filePath('contacts', 'ajax', 'addressbook/add.php'),
url:OC.filePath('contacts', 'ajax', 'addressbook/add.php'),
data:{ name: name },
success:function(jsondata) {
console.log(jsondata);
if(jsondata.status == 'success') {
self.contacts.setAddressbook(jsondata.data.addressbook);
id = jsondata.data.addressbook.id
id = jsondata.data.addressbook.id;
} else {
OC.notify({message:jsondata.data.message});
}
@ -1390,10 +1400,10 @@ OC.Contacts = OC.Contacts || {
error:function(jqXHR, textStatus, errorThrown) {
OC.notify({message:textStatus + ': ' + errorThrown});
id = false;
},
}
});
return id;
}
};
self.$importIntoSelect.empty();
$.each(self.contacts.addressbooks, function(id, book) {
@ -1403,7 +1413,7 @@ OC.Contacts = OC.Contacts || {
createCallback:addAddressbookCallback,
singleSelect: true,
createText:String(t('contacts', 'Add address book')),
minWidth: 120,
minWidth: 120
});
}
@ -1420,11 +1430,11 @@ OC.Contacts = OC.Contacts || {
$(this).hide();
self.currentid = 'new';
// Properties that the contact doesn't know
console.log('addContact, groupid', self.currentgroup)
console.log('addContact, groupid', self.currentgroup);
var groupprops = {
favorite: false,
groups: self.groups.categories,
currentgroup: {id:self.currentgroup, name:self.groups.nameById(self.currentgroup)},
currentgroup: {id:self.currentgroup, name:self.groups.nameById(self.currentgroup)}
};
self.tmpcontact = self.contacts.addContact(groupprops);
self.$rightContent.prepend(self.tmpcontact);
@ -1450,7 +1460,7 @@ OC.Contacts = OC.Contacts || {
return;
}
console.log('download');
document.location.href = OC.linkTo('contacts', 'export.php')
document.location.href = OC.linkTo('contacts', 'export.php')
+ '?selectedids=' + self.contacts.getSelectedContacts().join(',');
});
@ -1558,14 +1568,14 @@ OC.Contacts = OC.Contacts || {
$status.text(t('contacts', 'Importing from {filename}...', {filename:fileName})).fadeIn();
doImport(fileName, aid, function(response) {
if(response.status === 'success') {
$status.text(t('contacts', '{success} imported, {failed} failed.',
$status.text(t('contacts', '{success} imported, {failed} failed.',
{success:response.data.imported, failed:response.data.failed})).fadeIn();
}
delete uploadingFiles[fileName];
numfiles -= 1; uploadedfiles -= 1;
$progressbar.progressbar('value',50+(50/(todo-uploadedfiles)));
});
})
});
//$status.text(t('contacts', 'Importing...')).fadeIn();
waitForImport();
};
@ -1605,7 +1615,7 @@ OC.Contacts = OC.Contacts || {
$.each(files, function(i, file) {
var fileName = file.name;
console.log('file.name', file.name);
var jqXHR = $('#import_fileupload').fileupload('send',
var jqXHR = $('#import_fileupload').fileupload('send',
{
files: file,
formData: function(form) {
@ -1624,7 +1634,7 @@ OC.Contacts = OC.Contacts || {
})
.error(function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
OC.notify({message:errorThrown + ': ' + textStatus,});
OC.notify({message:errorThrown + ': ' + textStatus});
});
uploadingFiles[fileName] = jqXHR;
});
@ -1673,9 +1683,9 @@ OC.Contacts = OC.Contacts || {
$('#upload input.stop').hide();
}
}
})
});
});
$(document).on('keypress', function(event) {
if(!$(event.target).is('body')) {
return;
@ -1731,7 +1741,7 @@ OC.Contacts = OC.Contacts || {
break;
case 34: // PageDown
case 78: // n
console.log('page down')
console.log('page down');
break;
case 79: // o
console.log('open contact?');
@ -1757,7 +1767,7 @@ OC.Contacts = OC.Contacts || {
});
// find all with a title attribute and tipsy them
// find all with a title attribute and tipsy them
$('.tooltipped.downwards:not(.onfocus)').tipsy({gravity: 'n'});
$('.tooltipped.upwards:not(.onfocus)').tipsy({gravity: 's'});
$('.tooltipped.rightwards:not(.onfocus)').tipsy({gravity: 'w'});
@ -1792,8 +1802,8 @@ OC.Contacts = OC.Contacts || {
});
$(this).dialog('close');
},
'Cancel':function() {
$(this).dialog('close');
'Cancel':function() {
$(this).dialog('close');
return false;
}
},
@ -1803,12 +1813,12 @@ OC.Contacts = OC.Contacts || {
},
open: function(event, ui) {
$dlg.find('input').focus();
},
}
});
},
setAllChecked: function(checked) {
var selector = checked ? 'input:checkbox:visible:not(checked)' : 'input:checkbox:visible:checked';
$.each(self.$contactList.find(selector), function() {
$.each(this.$contactList.find(selector), function() {
$(this).prop('checked', checked);
});
},
@ -1847,7 +1857,7 @@ OC.Contacts = OC.Contacts || {
var groupprops = {
favorite: this.groups.isFavorite(this.currentid),
groups: this.groups.categories,
currentgroup: {id:this.currentgroup, name:this.groups.nameById(this.currentgroup)},
currentgroup: {id:this.currentgroup, name:this.groups.nameById(this.currentgroup)}
};
var $contactelem = this.contacts.showContact(this.currentid, groupprops);
var self = this;
@ -1879,7 +1889,7 @@ OC.Contacts = OC.Contacts || {
OC.notify({
message:t(
'contacts',
'The file you are trying to upload exceed the maximum size for file uploads on this server.'),
'The file you are trying to upload exceed the maximum size for file uploads on this server.')
});
return;
} else {
@ -1898,12 +1908,12 @@ OC.Contacts = OC.Contacts || {
},
cloudPhotoSelected:function(id, path) {
var self = this;
console.log('cloudPhotoSelected, id', id)
console.log('cloudPhotoSelected, id', id);
$.getJSON(OC.filePath('contacts', 'ajax', 'oc_photo.php'),
{path: path, id: id},function(jsondata) {
if(jsondata.status == 'success') {
//alert(jsondata.data.page);
self.editPhoto(jsondata.data.id, jsondata.data.tmp)
self.editPhoto(jsondata.data.id, jsondata.data.tmp);
$('#edit_photo_dialog_img').html(jsondata.data.page);
}
else{
@ -1917,7 +1927,7 @@ OC.Contacts = OC.Contacts || {
{id: id}, function(jsondata) {
if(jsondata.status == 'success') {
//alert(jsondata.data.page);
self.editPhoto(jsondata.data.id, jsondata.data.tmp)
self.editPhoto(jsondata.data.id, jsondata.data.tmp);
$('#edit_photo_dialog_img').html(jsondata.data.page);
}
else{
@ -1926,7 +1936,7 @@ OC.Contacts = OC.Contacts || {
});
},
editPhoto:function(id, tmpkey) {
console.log('editPhoto', id, tmpkey)
console.log('editPhoto', id, tmpkey);
$('.tipsy').remove();
// Simple event handler, called from onChange and onSelect
// event handlers, as per the Jcrop invocation above
@ -1961,7 +1971,7 @@ OC.Contacts = OC.Contacts || {
maxSize: [399, 399],
bgColor: 'black',
bgOpacity: .4,
boxWidth: 400,
boxWidth: 400,
boxHeight: 400,
setSelect: [ 100, 130, 50, 50 ]//,
//aspectRatio: 0.8
@ -2000,7 +2010,7 @@ OC.Contacts = OC.Contacts || {
if(jsondata && jsondata.status === 'success') {
// load cropped photo.
$(document).trigger('status.contact.photoupdated', {
id: jsondata.data.id,
id: jsondata.data.id
});
} else {
if(!jsondata) {
@ -2016,14 +2026,14 @@ OC.Contacts = OC.Contacts || {
$.ajax({
type:'POST',
async:false,
url:OC.filePath('contacts', 'ajax', 'addressbook/add.php'),
url:OC.filePath('contacts', 'ajax', 'addressbook/add.php'),
data:{ name: data.name, description: data.description },
success:function(jsondata) {
if(jsondata.status == 'success') {
if(typeof cb === 'function') {
cb({
status:'success',
addressbook: jsondata.data.addressbook,
addressbook: jsondata.data.addressbook
});
}
} else {
@ -2040,7 +2050,7 @@ OC.Contacts = OC.Contacts || {
$('body').append('<div id="addressbook_dialog"></div>');
var $dlg = $('#addressbook_dialog').html(data).octemplate({
nameplaceholder: t('contacts', 'Enter name'),
descplaceholder: t('contacts', 'Enter description'),
descplaceholder: t('contacts', 'Enter description')
}).dialog({
modal: true, height: 'auto', width: 'auto',
title: t('contacts', 'Select addressbook'),
@ -2062,7 +2072,7 @@ OC.Contacts = OC.Contacts || {
if(data.status === 'success') {
cb({
status:'success',
addressbook:data.addressbook,
addressbook:data.addressbook
});
} else {
cb({status:'error'});
@ -2075,7 +2085,7 @@ OC.Contacts = OC.Contacts || {
if(typeof cb === 'function') {
cb({
status:'success',
addressbook:self.contacts.addressbooks[parseInt(aid)],
addressbook:self.contacts.addressbooks[parseInt(aid)]
});
}
$(this).dialog('close');
@ -2100,7 +2110,7 @@ OC.Contacts = OC.Contacts || {
|| book.permissions & OC.PERMISSION_DELETE)) {
var row = '<tr><td><input id="book_{id}" name="book" type="radio" value="{id}"</td>'
+ '<td><label for="book_{id}">{displayname}</label></td>'
+ '<td>{description}</td></tr>'
+ '<td>{description}</td></tr>';
var $row = $(row).octemplate({
id:book.id,
displayname:book.displayname,
@ -2113,12 +2123,12 @@ OC.Contacts = OC.Contacts || {
$lastrow.find('input.name,input.desc').on('focus', function(e) {
$lastrow.find('input[type="radio"]').prop('checked', true);
});
},
}
});
}).error(function() {
OC.notify({message: t('contacts', 'Network or server error. Please inform administrator.')});
});
},
}
};
(function( $ ) {

View File

@ -23,15 +23,16 @@ OC.Contacts = OC.Contacts || {};
this.$fullTemplate = fulltemplate;
this.detailTemplates = detailtemplates;
this.undoQueue = [];
this.multi_properties = ['EMAIL', 'TEL', 'IMPP', 'ADR', 'URL'];
}
};
Contact.prototype.showActions = function(act) {
this.$footer.children().hide();
if(act && act.length > 0) {
this.$footer.children('.'+act.join(',.')).show();
}
}
};
Contact.prototype.setAsSaving = function(obj, state) {
if(!obj) {
@ -44,10 +45,35 @@ OC.Contacts = OC.Contacts || {};
} else {
$(obj).removeClass('loading');
}*/
}
};
Contact.prototype.pushToUndo = function(params) {
// Check if the same property has been changed before
// and update it's checksum if so.
if(typeof params.oldchecksum !== 'undefined') {
$.each(this.undoQueue, function(idx, item) {
if(item.checksum === params.oldchecksum) {
item.checksum = params.newchecksum;
if(params.action === 'delete') {
item.action = 'delete';
}
return false; // Break loop
}
});
}
this.undoQueue.push({
action:params.action,
name: params.name,
checksum: params.newchecksum,
newvalue: params.newvalue,
oldvalue: params.oldvalue
});
console.log('undoQueue', this.undoQueue);
}
Contact.prototype.addProperty = function($option, name) {
console.log('Contact.addProperty', name)
var $elem;
switch(name) {
case 'NICKNAME':
case 'TITLE':
@ -82,7 +108,15 @@ OC.Contacts = OC.Contacts || {};
$elem.find('input.value').addClass('new');
break;
}
}
if($elem) {
$elem.find('select.type[name="parameters[TYPE][]"]')
.combobox({
singleclick: true,
classes: ['propertytype', 'float', 'label'],
});
}
};
Contact.prototype.deleteProperty = function(params) {
var obj = params.obj;
@ -109,7 +143,7 @@ OC.Contacts = OC.Contacts || {};
if(!jsondata) {
$(document).trigger('status.contact.error', {
status: 'error',
message: t('contacts', 'Network or server error. Please inform administrator.'),
message: t('contacts', 'Network or server error. Please inform administrator.')
});
self.setAsSaving(obj, false);
return false;
@ -119,6 +153,12 @@ OC.Contacts = OC.Contacts || {};
if(self.multi_properties.indexOf(element) !== -1) {
// First find out if an existing element by looking for checksum
var checksum = self.checksumFor(obj);
self.pushToUndo({
action:'delete',
name: element,
oldchecksum: self.checksumFor(obj),
newvalue: self.valueFor(obj)
});
if(checksum) {
for(var i in self.data[element]) {
if(self.data[element][i].checksum === checksum) {
@ -130,22 +170,31 @@ OC.Contacts = OC.Contacts || {};
}
$container.remove();
} else {
self.pushToUndo({
action:'delete',
name: element,
newvalue: $container.find('input.value').val()
});
self.setAsSaving(obj, false);
self.$fullelem.find('[data-element="' + element.toLowerCase() + '"]').hide();
$container.find('input.value').val('');
self.$addMenu.find('option[value="' + element.toUpperCase() + '"]').prop('disabled', false);
}
$(document).trigger('status.contact.updated', {
property: element,
contact: self
});
return true;
} else {
$(document).trigger('status.contact.error', {
status: 'error',
message: jsondata.data.message,
message: jsondata.data.message
});
self.setAsSaving(obj, false);
return false;
}
},'json');
}
};
/**
* @brief Act on change of a property.
@ -192,7 +241,7 @@ OC.Contacts = OC.Contacts || {};
if(!jsondata) {
$(document).trigger('status.contact.error', {
status: 'error',
message: t('contacts', 'Network or server error. Please inform administrator.'),
message: t('contacts', 'Network or server error. Please inform administrator.')
});
$(obj).addClass('error');
self.setAsSaving(obj, false);
@ -205,24 +254,40 @@ OC.Contacts = OC.Contacts || {};
if(self.multi_properties.indexOf(element) !== -1) {
// First find out if an existing element by looking for checksum
var checksum = self.checksumFor(obj);
if(checksum) {
for(var i in self.data[element]) {
if(self.data[element][i].checksum === checksum) {
var value = self.valueFor(obj);
var parameters = self.parametersFor(obj);
if(checksum && checksum !== 'new') {
self.pushToUndo({
action:'save',
name: element,
newchecksum: jsondata.data.checksum,
oldchecksum: checksum,
newvalue: value,
oldvalue: obj.defaultValue
});
$.each(self.data[element], function(i, el) {
if(el.checksum === checksum) {
self.data[element][i] = {
name: element,
value: self.valueFor(obj),
parameters: self.parametersFor(obj),
checksum: jsondata.data.checksum,
}
break;
value: value,
parameters: parameters,
checksum: jsondata.data.checksum
};
return false;
}
}
});
} else {
$(obj).removeClass('new');
self.pushToUndo({
action:'add',
name: element,
newchecksum: jsondata.data.checksum,
newvalue: value,
});
self.data[element].push({
name: element,
value: self.valueFor(obj),
parameters: self.parametersFor(obj),
value: value,
parameters: parameters,
checksum: jsondata.data.checksum,
});
}
@ -230,17 +295,20 @@ OC.Contacts = OC.Contacts || {};
} else {
// Save value and parameters internally
var value = obj ? self.valueFor(obj) : params.value;
self.pushToUndo({
action: ((obj && obj.defaultValue) || self.data[element].length) ? 'save' : 'add', // FIXME
name: element,
newvalue: value,
});
switch(element) {
case 'CATEGORIES':
// We deal with this in addToGroup()
break;
case 'FN':
if(!self.data.FN || !self.data.FN.length) {
self.data.FN = [{name:'FN', value:'', parameters:[]}]
self.data.FN = [{name:'FN', value:'', parameters:[]}];
}
self.data.FN[0]['value'] = value;
// Update the list element
self.$listelem.find('.nametext').text(value);
var nempty = true;
if(!self.data.N) {
// TODO: Maybe add a method for constructing new elements?
@ -272,10 +340,6 @@ OC.Contacts = OC.Contacts || {};
}
, 500);
}
$(document).trigger('status.contact.renamed', {
id: self.id,
contact: self,
});
break;
case 'N':
if(!utils.isArray(value)) {
@ -295,7 +359,7 @@ OC.Contacts = OC.Contacts || {};
name: element,
value: value,
parameters: self.parametersFor(obj),
checksum: jsondata.data.checksum,
checksum: jsondata.data.checksum
};
break;
default:
@ -303,25 +367,29 @@ OC.Contacts = OC.Contacts || {};
}
}
self.setAsSaving(obj, false);
$(document).trigger('status.contact.updated', {
property: element,
contact: self
});
return true;
} else {
$(document).trigger('status.contact.error', {
status: 'error',
message: jsondata.data.message,
message: jsondata.data.message
});
self.setAsSaving(obj, false);
return false;
}
},'json');
}
};
/**
* Hide contact list element.
*/
Contact.prototype.hide = function() {
this.getListItemElement().hide();
}
};
/**
* Remove any open contact from the DOM.
*/
@ -333,7 +401,7 @@ OC.Contacts = OC.Contacts || {};
} else {
return false;
}
}
};
/**
* Remove any open contact from the DOM and detach it's list
@ -348,7 +416,7 @@ OC.Contacts = OC.Contacts || {};
this.$listelem.detach();
return this;
}
}
};
/**
* Set a contacts list element as (un)checked
@ -359,7 +427,7 @@ OC.Contacts = OC.Contacts || {};
this.$listelem.find('input:checkbox').prop('checked', checked);
return this;
}
}
};
/**
* Set a contact to en/disabled depending on its permissions.
@ -376,13 +444,13 @@ OC.Contacts = OC.Contacts || {};
$(this).prop('disabled', !enabled);
});
$(document).trigger('status.contact.enabled', enabled);
}
};
/**
* Add a contact from data store and remove it from the DOM
* @params params. An object which can contain the optional properties:
* aid: The id of the addressbook to add the contact to. Per default it will be added to the first.
* fn: The formatted name of the contact.
* aid: The id of the addressbook to add the contact to. Per default it will be added to the first.
* fn: The formatted name of the contact.
* @param cb Optional callback function which
* @returns The callback gets an object as argument with a variable 'status' of either 'success'
* or 'error'. On success the 'data' property of that object contains the contact id as 'id', the
@ -395,7 +463,7 @@ OC.Contacts = OC.Contacts || {};
if(!jsondata) {
$(document).trigger('status.contact.error', {
status: 'error',
message: t('contacts', 'Network or server error. Please inform administrator.'),
message: t('contacts', 'Network or server error. Please inform administrator.')
});
return false;
}
@ -404,7 +472,7 @@ OC.Contacts = OC.Contacts || {};
self.access.id = parseInt(jsondata.data.aid);
self.data = jsondata.data.details;
// Add contact to current group
if(self.groupprops && self.groupprops.currentgroup.name !== 'all'
if(self.groupprops && self.groupprops.currentgroup.name !== 'all'
&& self.groupprops.currentgroup.name !== 'fav') {
if(!self.data.CATEGORIES) {
self.data.CATEGORIES = [{value:[self.groupprops.currentgroup.name], parameters:[]}];
@ -413,25 +481,25 @@ OC.Contacts = OC.Contacts || {};
// Tell OC.Contacts to save in backend
$(document).trigger('request.contact.addtogroup', {
id: self.id,
groupid: self.groupprops.currentgroup.id,
groupid: self.groupprops.currentgroup.id
});
}
}
$(document).trigger('status.contact.added', {
id: self.id,
contact: self,
contact: self
});
}
if(typeof cb == 'function') {
cb(jsondata);
}
});
}
};
/**
* Delete contact from data store and remove it from the DOM
* @param cb Optional callback function which
* @returns An object with a variable 'status' of either success
* or 'error'
* or 'error'
*/
Contact.prototype.destroy = function(cb) {
var self = this;
@ -460,7 +528,7 @@ OC.Contacts = OC.Contacts || {};
cb(retval);
}
});
}
};
Contact.prototype.queryStringFor = function(obj) {
var q = 'id=' + this.id;
@ -483,23 +551,23 @@ OC.Contacts = OC.Contacts || {};
}
}
return q;
}
};
Contact.prototype.propertyContainerFor = function(obj) {
return $(obj).hasClass('propertycontainer')
? $(obj)
: $(obj).parents('.propertycontainer').first();
}
};
Contact.prototype.checksumFor = function(obj) {
return this.propertyContainerFor(obj).data('checksum');
}
};
Contact.prototype.valueFor = function(obj) {
var $container = this.propertyContainerFor(obj);
console.assert($container.length > 0, 'Couldn\'t find container for ' + $(obj))
return $container.is('input')
? $container.val()
console.assert($container.length > 0, 'Couldn\'t find container for ' + $(obj));
return $container.is('input')
? $container.val()
: (function() {
var $elem = $container.find('textarea.value,input.value:not(:checkbox)');
console.assert($elem.length > 0, 'Couldn\'t find value for ' + $container.data('element'));
@ -513,7 +581,7 @@ OC.Contacts = OC.Contacts || {};
return retval;
}
})();
}
};
Contact.prototype.parametersFor = function(obj, asText) {
var parameters = [];
@ -536,12 +604,12 @@ OC.Contacts = OC.Contacts || {};
parameters[paramname].push(val);
});
return parameters;
}
};
Contact.prototype.propertyTypeFor = function(obj) {
var ptype = this.propertyContainerFor(obj).data('element');
return ptype ? ptype.toUpperCase() : null;
}
};
/**
* Render the list item
@ -555,7 +623,7 @@ OC.Contacts = OC.Contacts || {};
tel: this.getPreferredValue('TEL', ''),
adr: this.getPreferredValue('ADR', []).clean('').join(', '),
categories: this.getPreferredValue('CATEGORIES', [])
.clean('').join(' / '),
.clean('').join(' / ')
});
if(this.access.owner !== OC.currentUser
&& !(this.access.permissions & OC.PERMISSION_UPDATE
@ -563,7 +631,7 @@ OC.Contacts = OC.Contacts || {};
this.$listelem.find('input:checkbox').prop('disabled', true).css('opacity', '0');
}
return this.$listelem;
}
};
/**
* Render the full contact
@ -588,13 +656,13 @@ OC.Contacts = OC.Contacts || {};
$.datepicker.parseDate('yy-mm-dd',
this.getPreferredValue('BDAY', '').substring(0, 10)))
: '',
note: this.getPreferredValue('NOTE', ''),
note: this.getPreferredValue('NOTE', '')
}
: {id:'', favorite:'', name:'', nickname:'', title:'', org:'', bday:'', note:'', n0:'', n1:'', n2:'', n3:'', n4:''};
this.$fullelem = this.$fullTemplate.octemplate(values).data('contactobject', this);
this.$footer = this.$fullelem.find('footer');
this.$fullelem.find('.tooltipped.rightwards.onfocus').tipsy({trigger: 'focus', gravity: 'w'});
this.$fullelem.on('submit', function() {
return false;
@ -625,12 +693,12 @@ OC.Contacts = OC.Contacts || {};
$editor.toggle('blind');
$('body').unbind('click', bodyListener);
}
}
};
$editor.toggle('blind', function() {
$('body').bind('click', bodyListener);
});
});
this.$fullelem.on('click keydown', '.delete', function(event) {
$('.tipsy').remove();
if(wrongKey(event)) {
@ -646,32 +714,36 @@ OC.Contacts = OC.Contacts || {};
}
if($(this).is('.close') || $(this).is('.cancel')) {
$(document).trigger('request.contact.close', {
id: self.id,
id: self.id
});
} else if($(this).is('.export')) {
$(document).trigger('request.contact.export', {
id: self.id,
id: self.id
});
} else if($(this).is('.delete')) {
$(document).trigger('request.contact.delete', {
id: self.id,
id: self.id
});
}
return false;
});
this.$fullelem.on('keypress', '.value,.parameter', function(event) {
if(event.keyCode === 13 && $(this).is('input')) {
console.log('Enter');
$(this).trigger('change');
// Prevent a second save on blur.
this.defaultValue = this.value;
return false;
} else if(event.keyCode === 27) {
$(document).trigger('request.contact.close', {
id: self.id,
id: self.id
});
}
});
this.$fullelem.on('change', '.value,.parameter', function(event) {
if(this.value === this.defaultValue) {
return;
}
self.saveProperty({obj:event.target});
});
@ -681,7 +753,7 @@ OC.Contacts = OC.Contacts || {};
});
this.$fullelem.find('.favorite').on('click', function () {
var state = $(this).hasClass('active');
if(!this.data) {
if(!self.data) {
return;
}
if(state) {
@ -691,7 +763,7 @@ OC.Contacts = OC.Contacts || {};
}
$(document).trigger('request.contact.setasfavorite', {
id: self.id,
state: !state,
state: !state
});
});
this.loadPhoto();
@ -757,7 +829,7 @@ OC.Contacts = OC.Contacts || {};
//console.log('param', param);
if(param.toUpperCase() == 'PREF') {
var $cb = $property.find('input[type="checkbox"]');
$cb.attr('checked', 'checked')
$cb.attr('checked', 'checked');
meta.push($cb.attr('title'));
}
else if(param.toUpperCase() == 'TYPE') {
@ -798,7 +870,7 @@ OC.Contacts = OC.Contacts || {};
$property.find('select.type[name="parameters[TYPE][]"]')
.combobox({
singleclick: true,
classes: ['propertytype', 'float', 'label'],
classes: ['propertytype', 'float', 'label']
});
}
$list.append($property);
@ -810,19 +882,19 @@ OC.Contacts = OC.Contacts || {};
&& !(this.access.permissions & OC.PERMISSION_UPDATE
|| this.access.permissions & OC.PERMISSION_DELETE)) {
this.setEnabled(false);
this.showActions(['close']);
this.showActions(['close', 'export']);
} else {
this.setEnabled(true);
this.showActions(['close', 'add', 'export', 'delete']);
}
return this.$fullelem;
}
};
Contact.prototype.isEditable = function() {
return ((this.access.owner === OC.currentUser)
|| (this.access.permissions & OC.PERMISSION_UPDATE
|| this.access.permissions & OC.PERMISSION_DELETE));
}
};
/**
* Render a simple property. Used for EMAIL and TEL.
@ -837,7 +909,7 @@ OC.Contacts = OC.Contacts || {};
? { value: property.value, checksum: property.checksum }
: { value: '', checksum: 'new' };
return this.detailTemplates[name].octemplate(values);
}
};
/**
* Render an ADR (address) property.
@ -865,7 +937,7 @@ OC.Contacts = OC.Contacts || {};
adr4: property.value[4] || '',
adr5: property.value[5] || '',
adr6: property.value[6] || '',
idx: idx,
idx: idx
}
: {value:'', checksum:'new', adr0:'', adr1:'', adr2:'', adr3:'', adr4:'', adr5:'', adr6:'', idx: idx};
var $elem = this.detailTemplates['adr'].octemplate(values);
@ -889,7 +961,7 @@ OC.Contacts = OC.Contacts || {};
$('body').unbind('click', bodyListener);
});
}
}
};
$viewer.slideUp();
$editor.toggle('blind', function() {
$('body').bind('click', bodyListener);
@ -914,7 +986,7 @@ OC.Contacts = OC.Contacts || {};
label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
value: item.name,
country: item.countryName
}
};
}));
}
});
@ -924,7 +996,7 @@ OC.Contacts = OC.Contacts || {};
if(ui.item && $elem.find('.value.country').val().trim().length == 0) {
$elem.find('.value.country').val(ui.item.country);
}
},
}
});
$elem.find('.value.country')
.autocomplete({
@ -946,15 +1018,15 @@ OC.Contacts = OC.Contacts || {};
return {
label: item.name,
value: item.name
}
};
}));
}
});
},
minLength: 2,
minLength: 2
});
return $elem;
}
};
/**
* Render an IMPP (Instant Messaging) property.
@ -967,10 +1039,10 @@ OC.Contacts = OC.Contacts || {};
}
var values = property ? {
value: property.value,
checksum: property.checksum,
checksum: property.checksum
} : {value: '', checksum: 'new'};
return this.detailTemplates['impp'].octemplate(values);
}
};
/**
* Render the PHOTO property.
@ -983,7 +1055,7 @@ OC.Contacts = OC.Contacts || {};
this.$photowrapper.addClass('loading').addClass('wait');
var $phototools = this.$fullelem.find('#phototools');
delete this.photo;
$('img.contactphoto').remove()
$('img.contactphoto').remove();
this.photo = new Image();
$(this.photo).load(function () {
$(this).addClass('contactphoto');
@ -1012,17 +1084,17 @@ OC.Contacts = OC.Contacts || {};
$phototools.find('.edit').on('click', function() {
$(document).trigger('request.edit.contactphoto', {
id: self.id,
id: self.id
});
});
$phototools.find('.cloud').on('click', function() {
$(document).trigger('request.select.contactphoto.fromcloud', {
id: self.id,
id: self.id
});
});
$phototools.find('.upload').on('click', function() {
$(document).trigger('request.select.contactphoto.fromlocal', {
id: self.id,
id: self.id
});
});
if(this.data && this.data.PHOTO) {
@ -1039,7 +1111,7 @@ OC.Contacts = OC.Contacts || {};
.css('background', 'url(' + OC.filePath('', '', 'remote.php')+'/contactthumbnail?id='+self.id+refreshstr + ')');
});
}
}
};
/**
* Get the jquery element associated with this object
@ -1049,7 +1121,7 @@ OC.Contacts = OC.Contacts || {};
this.renderListItem();
}
return this.$listelem;
}
};
/**
* Get the preferred value for a property.
@ -1079,7 +1151,7 @@ OC.Contacts = OC.Contacts || {};
});
}
return pref;
}
};
/**
* Returns true/false depending on the contact being in the
@ -1097,9 +1169,9 @@ OC.Contacts = OC.Contacts || {};
if(typeof categories[i] === 'string' && (name.toLowerCase() === categories[i].toLowerCase())) {
return true;
}
};
}
return false;
}
};
/**
* Add this contact to a group
@ -1108,7 +1180,7 @@ OC.Contacts = OC.Contacts || {};
Contact.prototype.addToGroup = function(name) {
console.log('addToGroup', name);
if(!this.data.CATEGORIES) {
this.data.CATEGORIES = [{value:[name]},];
this.data.CATEGORIES = [{value:[name]}];
} else {
if(this.inGroup(name)) {
return;
@ -1120,7 +1192,7 @@ OC.Contacts = OC.Contacts || {};
}
}
this.saveProperty({name:'CATEGORIES', value:this.data.CATEGORIES[0].value.join(',') });
}
};
/**
* Remove this contact to a group
@ -1151,7 +1223,7 @@ OC.Contacts = OC.Contacts || {};
}
}
this.saveProperty({name:'CATEGORIES', value:this.data.CATEGORIES[0].value.join(',') });
}
};
Contact.prototype.setCurrent = function(on) {
if(on) {
@ -1162,9 +1234,9 @@ OC.Contacts = OC.Contacts || {};
$(document).trigger('status.contact.currentlistitem', {
id: this.id,
pos: Math.round(this.$listelem.position().top),
height: Math.round(this.$listelem.height()),
height: Math.round(this.$listelem.height())
});
}
};
Contact.prototype.next = function() {
var $next = this.$listelem.next('tr');
@ -1174,10 +1246,10 @@ OC.Contacts = OC.Contacts || {};
$(document).trigger('status.contact.currentlistitem', {
id: parseInt($next.data('id')),
pos: Math.round($next.position().top),
height: Math.round($next.height()),
height: Math.round($next.height())
});
}
}
};
Contact.prototype.prev = function() {
var $prev = this.$listelem.prev('tr');
@ -1187,10 +1259,10 @@ OC.Contacts = OC.Contacts || {};
$(document).trigger('status.contact.currentlistitem', {
id: parseInt($prev.data('id')),
pos: Math.round($prev.position().top),
height: Math.round($prev.height()),
height: Math.round($prev.height())
});
}
}
};
var ContactList = function(contactlist, contactlistitemtemplate, contactfulltemplate, contactdetailtemplates) {
//console.log('ContactList', contactlist, contactlistitemtemplate, contactfulltemplate, contactdetailtemplates);
@ -1209,10 +1281,13 @@ OC.Contacts = OC.Contacts || {};
self.insertContact(data.contact.renderListItem());
});
$(document).bind('status.contact.renamed', function(e, data) {
self.insertContact(data.contact.getListItemElement().detach());
$(document).bind('status.contact.updated', function(e, data) {
if(['FN', 'EMAIL', 'TEL', 'ADR', 'CATEGORIES'].indexOf(data.property) !== -1) {
data.contact.getListItemElement().remove();
self.insertContact(self.contacts[parseInt(data.contact.id)].renderListItem());
}
});
}
};
/**
* Show/hide contacts belonging to an addressbook.
@ -1230,7 +1305,7 @@ OC.Contacts = OC.Contacts || {};
this.contacts[contact].getListItemElement().hide();
}
}
}
};
/**
* Show/hide contacts belonging to shared addressbooks.
@ -1247,7 +1322,7 @@ OC.Contacts = OC.Contacts || {};
}
}
}
}
};
/**
* Show contacts in list
@ -1272,7 +1347,7 @@ OC.Contacts = OC.Contacts || {};
this.contacts[contact].getListItemElement().show();
}
}
}
};
ContactList.prototype.contactPos = function(id) {
if(!id) {
@ -1282,15 +1357,15 @@ OC.Contacts = OC.Contacts || {};
var $elem = this.contacts[parseInt(id)].getListItemElement();
var pos = $elem.offset().top - this.$contactList.offset().top + this.$contactList.scrollTop();
return pos;
}
};
ContactList.prototype.hideContact = function(id) {
this.contacts[parseInt(id)].hide();
}
};
ContactList.prototype.closeContact = function(id) {
this.contacts[parseInt(id)].close();
}
};
/**
* Returns a Contact object by searching for its id
@ -1312,7 +1387,7 @@ OC.Contacts = OC.Contacts || {};
} else if(utils.isArray(id)) {
$.extend(this.deletionQueue, id);
} else {
throw { name: 'WrongParameterType', message: 'ContactList.delayedDelete only accept integers or arrays.'}
throw { name: 'WrongParameterType', message: 'ContactList.delayedDelete only accept integers or arrays.'};
}
$.each(this.deletionQueue, function(idx, id) {
self.contacts[id].detach().setChecked(false);
@ -1326,7 +1401,7 @@ OC.Contacts = OC.Contacts || {};
e.returnValue = String(warn);
}
return warn;
}
};
}
if(this.$contactList.find('tr:visible').length === 0) {
$(document).trigger('status.visiblecontacts');
@ -1350,7 +1425,7 @@ OC.Contacts = OC.Contacts || {};
window.onbeforeunload = null;
}
});
}
};
/**
* Delete a contact with this id
@ -1379,7 +1454,7 @@ OC.Contacts = OC.Contacts || {};
if(response.status === 'success') {
delete self.contacts[id];
$(document).trigger('status.contact.deleted', {
id: id,
id: id
});
self.length -= 1;
if(self.length === 0) {
@ -1389,7 +1464,7 @@ OC.Contacts = OC.Contacts || {};
OC.notify({message:response.message});
}
});
}
};
/**
* Opens the contact with this id in edit mode
@ -1399,7 +1474,7 @@ OC.Contacts = OC.Contacts || {};
ContactList.prototype.showContact = function(id, props) {
console.assert(typeof id === 'number', 'ContactList.showContact called with a non-number');
this.currentContact = id;
console.log('Contacts.showContact', id, this.contacts[this.currentContact], this.contacts)
console.log('Contacts.showContact', id, this.contacts[this.currentContact], this.contacts);
return this.contacts[this.currentContact].renderContact(props);
};
@ -1413,10 +1488,10 @@ OC.Contacts = OC.Contacts || {};
revert: 'invalid',
//containment: '#content',
opacity: 0.8, helper: 'clone',
zIndex: 1000,
zIndex: 1000
});
var name = $contact.find('.nametext').text().toLowerCase();
var added = false
var added = false;
this.$contactList.find('tr').each(function() {
if ($(this).find('.nametext').text().toLowerCase().localeCompare(name) > 0) {
$(this).before($contact);
@ -1429,7 +1504,7 @@ OC.Contacts = OC.Contacts || {};
}
$contact.show();
return $contact;
}
};
/**
* Add contact
@ -1450,7 +1525,7 @@ OC.Contacts = OC.Contacts || {};
this.contacts[this.currentContact].close();
}
return contact.renderContact(props);
}
};
/**
* Get contacts selected in list
@ -1464,17 +1539,17 @@ OC.Contacts = OC.Contacts || {};
contacts.push(parseInt($(b).parents('tr').first().data('id')));
});
return contacts;
}
};
ContactList.prototype.setCurrent = function(id, deselect_other) {
self = this;
var self = this;
if(deselect_other === true) {
$.each(this.contacts, function(contact) {
self.contacts[contact].setCurrent(false);
});
}
this.contacts[parseInt(id)].setCurrent(true);
}
};
// Should only be neccesary with progressive loading, but it's damn fast, so... ;)
ContactList.prototype.doSort = function() {
@ -1485,10 +1560,18 @@ OC.Contacts = OC.Contacts || {};
return $(a).find('td.name').text().toUpperCase().localeCompare($(b).find('td.name').text().toUpperCase());
});
var items = [];
$.each(rows, function(index, row) {
self.$contactList.append(row);
items.push(row);
if(items.length === 100) {
self.$contactList.append(items);
items = [];
}
});
}
if(items.length > 0) {
self.$contactList.append(items);
}
};
/**
* Save addressbook data
@ -1496,8 +1579,8 @@ OC.Contacts = OC.Contacts || {};
*/
ContactList.prototype.unsetAddressbook = function(id) {
delete this.addressbooks[id];
}
};
/**
* Save addressbook data
* @param object book
@ -1510,9 +1593,9 @@ OC.Contacts = OC.Contacts || {};
id: parseInt(book.id),
displayname: book.displayname,
description: book.description,
active: Boolean(parseInt(book.active)),
active: Boolean(parseInt(book.active))
};
}
};
/**
* Load contacts
* @param int offset
@ -1527,6 +1610,7 @@ OC.Contacts = OC.Contacts || {};
$.each(jsondata.data.addressbooks, function(i, book) {
self.setAddressbook(book);
});
var items = [];
$.each(jsondata.data.contacts, function(c, contact) {
self.contacts[parseInt(contact.id)]
= new Contact(
@ -1540,6 +1624,7 @@ OC.Contacts = OC.Contacts || {};
);
self.length +=1;
var $item = self.contacts[parseInt(contact.id)].renderListItem();
items.push($item.get(0));
$item.draggable({
distance: 10,
revert: 'invalid',
@ -1547,10 +1632,18 @@ OC.Contacts = OC.Contacts || {};
opacity: 0.8, helper: 'clone',
zIndex: 1000,
});
self.$contactList.append($item);
//self.insertContact(item);
if(items.length === 100) {
self.$contactList.append(items);
items = [];
}
});
self.doSort();
if(items.length > 0) {
self.$contactList.append(items);
}
setTimeout(function() {
self.doSort();
}
, 2000);
$(document).trigger('status.contacts.loaded', {
status: true,
numcontacts: jsondata.data.contacts.length

View File

@ -75,7 +75,7 @@ Contacts_Import={
}
});
}
}
};
var openContact = function(id) {
if(typeof OC.Contacts !== 'undefined') {
@ -83,7 +83,7 @@ var openContact = function(id) {
} else {
window.location.href = OC.linkTo('contacts', 'index.php') + '?id=' + id;
}
}
};
$(document).ready(function(){
if(typeof FileActions !== 'undefined'){
@ -91,5 +91,5 @@ $(document).ready(function(){
FileActions.setDefault('text/vcard','importaddressbook');
FileActions.register('text/x-vcard','importaddressbook', OC.PERMISSION_READ, '', Contacts_Import.importdialog);
FileActions.setDefault('text/x-vcard','importaddressbook');
};
}
});

814
js/modernizr.custom.js Normal file
View File

@ -0,0 +1,814 @@
/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
* Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-flexboxlegacy-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-canvas-draganddrop-audio-video-input-inputtypes-localstorage-sessionstorage-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-elem_track-load
*/
;
window.Modernizr = (function( window, document, undefined ) {
var version = '2.6.2',
Modernizr = {},
enableClasses = true,
docElement = document.documentElement,
mod = 'modernizr',
modElem = document.createElement(mod),
mStyle = modElem.style,
inputElem = document.createElement('input') ,
smile = ':)',
toString = {}.toString,
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
omPrefixes = 'Webkit Moz O ms',
cssomPrefixes = omPrefixes.split(' '),
domPrefixes = omPrefixes.toLowerCase().split(' '),
ns = {'svg': 'http://www.w3.org/2000/svg'},
tests = {},
inputs = {},
attrs = {},
classes = [],
slice = classes.slice,
featureName,
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
var style, ret, node, docOverflow,
div = document.createElement('div'),
body = document.body,
fakeBody = body || document.createElement('body');
if ( parseInt(nodes, 10) ) {
while ( nodes-- ) {
node = document.createElement('div');
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
div.appendChild(node);
}
}
style = ['&#173;','<style id="s', mod, '">', rule, '</style>'].join('');
div.id = mod;
(body ? div : fakeBody).innerHTML += style;
fakeBody.appendChild(div);
if ( !body ) {
fakeBody.style.background = '';
fakeBody.style.overflow = 'hidden';
docOverflow = docElement.style.overflow;
docElement.style.overflow = 'hidden';
docElement.appendChild(fakeBody);
}
ret = callback(div, rule);
if ( !body ) {
fakeBody.parentNode.removeChild(fakeBody);
docElement.style.overflow = docOverflow;
} else {
div.parentNode.removeChild(div);
}
return !!ret;
},
testMediaQuery = function( mq ) {
var matchMedia = window.matchMedia || window.msMatchMedia;
if ( matchMedia ) {
return matchMedia(mq).matches;
}
var bool;
injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
bool = (window.getComputedStyle ?
getComputedStyle(node, null) :
node.currentStyle)['position'] == 'absolute';
});
return bool;
},
isEventSupported = (function() {
var TAGNAMES = {
'select': 'input', 'change': 'input',
'submit': 'form', 'reset': 'form',
'error': 'img', 'load': 'img', 'abort': 'img'
};
function isEventSupported( eventName, element ) {
element = element || document.createElement(TAGNAMES[eventName] || 'div');
eventName = 'on' + eventName;
var isSupported = eventName in element;
if ( !isSupported ) {
if ( !element.setAttribute ) {
element = document.createElement('div');
}
if ( element.setAttribute && element.removeAttribute ) {
element.setAttribute(eventName, '');
isSupported = is(element[eventName], 'function');
if ( !is(element[eventName], 'undefined') ) {
element[eventName] = undefined;
}
element.removeAttribute(eventName);
}
}
element = null;
return isSupported;
}
return isEventSupported;
})(),
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
hasOwnProp = function (object, property) {
return _hasOwnProperty.call(object, property);
};
}
else {
hasOwnProp = function (object, property) {
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
};
}
if (!Function.prototype.bind) {
Function.prototype.bind = function bind(that) {
var target = this;
if (typeof target != "function") {
throw new TypeError();
}
var args = slice.call(arguments, 1),
bound = function () {
if (this instanceof bound) {
var F = function(){};
F.prototype = target.prototype;
var self = new F();
var result = target.apply(
self,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return self;
} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);
}
};
return bound;
};
}
function setCss( str ) {
mStyle.cssText = str;
}
function setCssAll( str1, str2 ) {
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
}
function is( obj, type ) {
return typeof obj === type;
}
function contains( str, substr ) {
return !!~('' + str).indexOf(substr);
}
function testProps( props, prefixed ) {
for ( var i in props ) {
var prop = props[i];
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
return prefixed == 'pfx' ? prop : true;
}
}
return false;
}
function testDOMProps( props, obj, elem ) {
for ( var i in props ) {
var item = obj[props[i]];
if ( item !== undefined) {
if (elem === false) return props[i];
if (is(item, 'function')){
return item.bind(elem || obj);
}
return item;
}
}
return false;
}
function testPropsAll( prop, prefixed, elem ) {
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
if(is(prefixed, "string") || is(prefixed, "undefined")) {
return testProps(props, prefixed);
} else {
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
return testDOMProps(props, prefixed, elem);
}
} tests['flexbox'] = function() {
return testPropsAll('flexWrap');
};
tests['flexboxlegacy'] = function() {
return testPropsAll('boxDirection');
};
tests['canvas'] = function() {
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
}; tests['webgl'] = function() {
return !!window.WebGLRenderingContext;
};
tests['touch'] = function() {
var bool;
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
} else {
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
bool = node.offsetTop === 9;
});
}
return bool;
};
tests['geolocation'] = function() {
return 'geolocation' in navigator;
};
tests['draganddrop'] = function() {
var div = document.createElement('div');
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
};
tests['rgba'] = function() {
setCss('background-color:rgba(150,255,150,.5)');
return contains(mStyle.backgroundColor, 'rgba');
};
tests['hsla'] = function() {
setCss('background-color:hsla(120,40%,100%,.5)');
return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
};
tests['multiplebgs'] = function() {
setCss('background:url(https://),url(https://),red url(https://)');
return (/(url\s*\(.*?){3}/).test(mStyle.background);
}; tests['backgroundsize'] = function() {
return testPropsAll('backgroundSize');
};
tests['borderimage'] = function() {
return testPropsAll('borderImage');
};
tests['borderradius'] = function() {
return testPropsAll('borderRadius');
};
tests['boxshadow'] = function() {
return testPropsAll('boxShadow');
};
tests['textshadow'] = function() {
return document.createElement('div').style.textShadow === '';
};
tests['opacity'] = function() {
setCssAll('opacity:.55');
return (/^0.55$/).test(mStyle.opacity);
};
tests['cssanimations'] = function() {
return testPropsAll('animationName');
};
tests['csscolumns'] = function() {
return testPropsAll('columnCount');
};
tests['cssgradients'] = function() {
var str1 = 'background-image:',
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
str3 = 'linear-gradient(left top,#9f9, white);';
setCss(
(str1 + '-webkit- '.split(' ').join(str2 + str1) +
prefixes.join(str3 + str1)).slice(0, -str1.length)
);
return contains(mStyle.backgroundImage, 'gradient');
};
tests['cssreflections'] = function() {
return testPropsAll('boxReflect');
};
tests['csstransforms'] = function() {
return !!testPropsAll('transform');
};
tests['csstransforms3d'] = function() {
var ret = !!testPropsAll('perspective');
if ( ret && 'webkitPerspective' in docElement.style ) {
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
});
}
return ret;
};
tests['csstransitions'] = function() {
return testPropsAll('transition');
};
tests['fontface'] = function() {
var bool;
injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) {
var style = document.getElementById('smodernizr'),
sheet = style.sheet || style.styleSheet,
cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
});
return bool;
};
tests['generatedcontent'] = function() {
var bool;
injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) {
bool = node.offsetHeight >= 3;
});
return bool;
};
tests['video'] = function() {
var elem = document.createElement('video'),
bool = false;
try {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
}
} catch(e) { }
return bool;
};
tests['audio'] = function() {
var elem = document.createElement('audio'),
bool = false;
try {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
}
} catch(e) { }
return bool;
};
tests['localstorage'] = function() {
try {
localStorage.setItem(mod, mod);
localStorage.removeItem(mod);
return true;
} catch(e) {
return false;
}
};
tests['sessionstorage'] = function() {
try {
sessionStorage.setItem(mod, mod);
sessionStorage.removeItem(mod);
return true;
} catch(e) {
return false;
}
};
tests['svg'] = function() {
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
};
tests['inlinesvg'] = function() {
var div = document.createElement('div');
div.innerHTML = '<svg/>';
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
};
tests['smil'] = function() {
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
};
tests['svgclippaths'] = function() {
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
};
function webforms() {
Modernizr['input'] = (function( props ) {
for ( var i = 0, len = props.length; i < len; i++ ) {
attrs[ props[i] ] = !!(props[i] in inputElem);
}
if (attrs.list){
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
}
return attrs;
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
Modernizr['inputtypes'] = (function(props) {
for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
inputElem.setAttribute('type', inputElemType = props[i]);
bool = inputElem.type !== 'text';
if ( bool ) {
inputElem.value = smile;
inputElem.style.cssText = 'position:absolute;visibility:hidden;';
if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
docElement.appendChild(inputElem);
defaultView = document.defaultView;
bool = defaultView.getComputedStyle &&
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
(inputElem.offsetHeight !== 0);
docElement.removeChild(inputElem);
} else if ( /^(search|tel)$/.test(inputElemType) ){
} else if ( /^(url|email)$/.test(inputElemType) ) {
bool = inputElem.checkValidity && inputElem.checkValidity() === false;
} else {
bool = inputElem.value != smile;
}
}
inputs[ props[i] ] = !!bool;
}
return inputs;
})('search tel url email datetime date month week time datetime-local number range color'.split(' '));
}
for ( var feature in tests ) {
if ( hasOwnProp(tests, feature) ) {
featureName = feature.toLowerCase();
Modernizr[featureName] = tests[feature]();
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
}
}
Modernizr.input || webforms();
Modernizr.addTest = function ( feature, test ) {
if ( typeof feature == 'object' ) {
for ( var key in feature ) {
if ( hasOwnProp( feature, key ) ) {
Modernizr.addTest( key, feature[ key ] );
}
}
} else {
feature = feature.toLowerCase();
if ( Modernizr[feature] !== undefined ) {
return Modernizr;
}
test = typeof test == 'function' ? test() : test;
if (typeof enableClasses !== "undefined" && enableClasses) {
docElement.className += ' ' + (test ? '' : 'no-') + feature;
}
Modernizr[feature] = test;
}
return Modernizr;
};
setCss('');
modElem = inputElem = null;
;(function(window, document) {
var options = window.html5 || {};
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
var supportsHtml5Styles;
var expando = '_html5shiv';
var expanID = 0;
var expandoData = {};
var supportsUnknownElements;
(function() {
try {
var a = document.createElement('a');
a.innerHTML = '<xyz></xyz>';
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
(document.createElement)('a');
var frag = document.createDocumentFragment();
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
);
}());
} catch(e) {
supportsHtml5Styles = true;
supportsUnknownElements = true;
}
}()); function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x<style>' + cssText + '</style>';
return parent.insertBefore(p.lastChild, parent.firstChild);
}
function getElements() {
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
if (!data) {
data = {};
expanID++;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
}
return data;
}
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
}
if (!data) {
data = getExpandoData(ownerDocument);
}
var node;
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
node = data.createElem(nodeName);
}
return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
}
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
}
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
i = 0,
elems = getElements(),
l = elems.length;
for(;i<l;i++){
clone.createElement(elems[i]);
}
return clone;
}
function shivMethods(ownerDocument, data) {
if (!data.cache) {
data.cache = {};
data.createElem = ownerDocument.createElement;
data.createFrag = ownerDocument.createDocumentFragment;
data.frag = data.createFrag();
}
ownerDocument.createElement = function(nodeName) {
if (!html5.shivMethods) {
return data.createElem(nodeName);
}
return createElement(nodeName, ownerDocument, data);
};
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
'var n=f.cloneNode(),c=n.createElement;' +
'h.shivMethods&&(' +
getElements().join().replace(/\w+/g, function(nodeName) {
data.createElem(nodeName);
data.frag.createElement(nodeName);
return 'c("' + nodeName + '")';
}) +
');return n}'
)(html5, data.frag);
} function shivDocument(ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
}
var data = getExpandoData(ownerDocument);
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
data.hasCSS = !!addStyleSheet(ownerDocument,
'article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}' +
'mark{background:#FF0;color:#000}'
);
}
if (!supportsUnknownElements) {
shivMethods(ownerDocument, data);
}
return ownerDocument;
} var html5 = {
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video',
'shivCSS': (options.shivCSS !== false),
'supportsUnknownElements': supportsUnknownElements,
'shivMethods': (options.shivMethods !== false),
'type': 'default',
'shivDocument': shivDocument,
createElement: createElement,
createDocumentFragment: createDocumentFragment
}; window.html5 = html5;
shivDocument(document);
}(this, document));
Modernizr._version = version;
Modernizr._prefixes = prefixes;
Modernizr._domPrefixes = domPrefixes;
Modernizr._cssomPrefixes = cssomPrefixes;
Modernizr.mq = testMediaQuery;
Modernizr.hasEvent = isEventSupported;
Modernizr.testProp = function(prop){
return testProps([prop]);
};
Modernizr.testAllProps = testPropsAll;
Modernizr.testStyles = injectElementWithStyles;
Modernizr.prefixed = function(prop, obj, elem){
if(!obj) {
return testPropsAll(prop, 'pfx');
} else {
return testPropsAll(prop, obj, elem);
}
};
docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
(enableClasses ? ' js ' + classes.join(' ') : '');
return Modernizr;
})(this, this.document);
/*yepnope1.5.4|WTFPL*/
(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.
loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(
e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){
b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document);
Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0));};
// Track element + Timed Text Track API
// http://www.w3.org/TR/html5/video.html#the-track-element
// http://www.w3.org/TR/html5/media-elements.html#text-track-api
//
// While IE10 has implemented the track element, IE10 does not expose the underlying APIs to create timed text tracks by JS (really sad)
// By Addy Osmani
Modernizr.addTest({
texttrackapi: (typeof (document.createElement('video').addTextTrack) === 'function'),
// a more strict test for track including UI support: document.createElement('track').kind === 'subtitles'
track: ('kind' in document.createElement('track'))
});
;

View File

@ -1,14 +1,14 @@
/**
* @param 'createCallback' A function to be called when a new entry is created. Two arguments are supplied to this function:
* The select element used and the value of the option. If the function returns false addition will be cancelled. If it returns
* anything else it will be used as the value of the newly added option.
* anything else it will be used as the value of the newly added option.
* @param 'createText' The placeholder text for the create action.
* @param 'title' The title to show if no options are selected.
* @param 'checked' An array containing values for options that should be checked. Any options which are already selected will be added to this array.
* @param 'labels' The corresponding labels to show for the checked items.
* @param 'oncheck' Callback function which will be called when a checkbox/radiobutton is selected. If the function returns false the input will be unchecked.
* @param 'onuncheck' @see 'oncheck'.
* @param 'singleSelect' If true radiobuttons will be used instead of checkboxes.
* @param 'singleSelect' If true radiobuttons will be used instead of checkboxes.
*/
(function( $ ){
var multiSelectId=-1;
@ -23,7 +23,7 @@
'labels':[],
'oncheck':false,
'onuncheck':false,
'minWidth': 'default;',
'minWidth': 'default;'
};
$(this).attr('data-msid', multiSelectId);
$.extend(settings,options);
@ -62,7 +62,7 @@
var self = this;
self.menuDirection = 'down';
button.click(function(event){
var button=$(this);
if(button.parent().children('ul').length>0) {
if(self.menuDirection === 'down') {
@ -146,7 +146,7 @@
settings.labels.splice(index,1);
}
var oldWidth=button.width();
button.children('span').first().text(settings.labels.length > 0
button.children('span').first().text(settings.labels.length > 0
? settings.labels.join(', ')
: settings.title);
var newOuterWidth=Math.max((button.outerWidth()-2),settings.minOuterWidth)+'px';
@ -193,7 +193,7 @@
return false;
}
var li=$(this).parent();
var val = $(this).val()
var val = $(this).val();
var select=button.parent().next();
if(typeof settings.createCallback === 'function') {
var response = settings.createCallback(select, val);
@ -217,7 +217,7 @@
select.append(option);
li.prev().children('input').prop('checked', true).trigger('change');
button.parent().data('preventHide',false);
button.children('span').first().text(settings.labels.length > 0
button.children('span').first().text(settings.labels.length > 0
? settings.labels.join(', ')
: settings.title);
if(self.menuDirection === 'up') {
@ -276,7 +276,7 @@
}
}
});
return span;
};
})( jQuery );

View File

@ -1,212 +0,0 @@
/**
* HTML5 placeholder polyfill
* @requires jQuery - tested with 1.6.2 but might as well work with older versions
*
* code: https://github.com/ginader/HTML5-placeholder-polyfill
* please report issues at: https://github.com/ginader/HTML5-placeholder-polyfill/issues
*
* Copyright (c) 2012 Dirk Ginader (ginader.de)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Version: 2.0.3
*
* History:
* * 1.0 initial release
* * 1.1 added support for multiline placeholders in textareas
* * 1.2 Allow label to wrap the input element by noah https://github.com/ginader/HTML5-placeholder-polyfill/pull/1
* * 1.3 New option to read placeholder to Screenreaders. Turned on by default
* * 1.4 made placeholder more rubust to allow labels being offscreen + added minified version of the 3rd party libs
* * 1.5 emptying the native placeholder to prevent double rendering in Browsers with partial support
* * 1.6 optional reformat when a textarea is being resized - requires http://benalman.com/projects/jquery-resize-plugin/
* * 1.7 feature detection is now included in the polyfill so you can simply include it without the need for Modernizr
* * 1.8 replacing the HTML5 Boilerplate .visuallyhidden technique with one that still allows the placeholder to be rendered
* * 1.8.1 bugfix for implicit labels
* * 1.9 New option "hideOnFocus" which, if set to false will mimic the behavior of mobile safari and chrome (remove label when typed instead of onfocus)
* * 1.9.1 added reformat event on window resize
* * 1.9.2 more flexible way to "fix" labels that are hidden using clip() thanks to grahambates: https://github.com/ginader/HTML5-placeholder-polyfill/issues/12
* * 2.0 new easier configuration technique and new options forceApply and AutoInit and support for setters and getters
* * 2.0.1 changed check for empty field so a space character is no longer ignored
* * 2.0.2 allow rerun of the placeholder() to cover generated elements - existing polyfilled placeholder will be repositioned. Fixing: https://github.com/ginader/HTML5-placeholder-polyfill/issues/15
* * 2.0.3 turn debugging of for production. fix https://github.com/ginader/HTML5-placeholder-polyfill/issues/18
*/
(function($) {
var debug = false,
animId;
function showPlaceholderIfEmpty(input,options) {
if( input.val() === '' ){
input.data('placeholder').removeClass(options.hideClass);
}else{
input.data('placeholder').addClass(options.hideClass);
}
}
function hidePlaceholder(input,options){
input.data('placeholder').addClass(options.hideClass);
}
function positionPlaceholder(placeholder,input){
var ta = input.is('textarea');
placeholder.css({
width : input.innerWidth()-(ta ? 20 : 4),
height : input.innerHeight()-6,
lineHeight : input.css('line-height'),
whiteSpace : ta ? 'normal' : 'nowrap',
overflow : 'hidden'
}).offset(input.offset());
}
function startFilledCheckChange(input,options){
var input = input,
val = input.val();
(function checkloop(){
animId = requestAnimationFrame(checkloop);
if(input.val() != val){
hidePlaceholder(input,options);
stopCheckChange();
startEmptiedCheckChange(input,options);
}
})();
}
function startEmptiedCheckChange(input,options){
var input = input,
val = input.val();
(function checkloop(){
animId = requestAnimationFrame(checkloop);
showPlaceholderIfEmpty(input,options);
})();
}
function stopCheckChange(){
cancelAnimationFrame(animId);
}
function log(msg){
if(debug && window.console && window.console.log){
window.console.log(msg);
}
}
$.fn.placeHolder = function(config) {
log('init placeHolder');
var o = this;
var l = $(this).length;
this.options = $.extend({
className: 'placeholder', // css class that is used to style the placeholder
visibleToScreenreaders : true, // expose the placeholder text to screenreaders or not
visibleToScreenreadersHideClass : 'placeholder-hide-except-screenreader', // css class is used to visually hide the placeholder
visibleToNoneHideClass : 'placeholder-hide', // css class used to hide the placeholder for all
hideOnFocus : false, // either hide the placeholder on focus or on type
removeLabelClass : 'visuallyhidden', // remove this class from a label (to fix hidden labels)
hiddenOverrideClass : 'visuallyhidden-with-placeholder', // replace the label above with this class
forceHiddenOverride : true, // allow the replace of the removeLabelClass with hiddenOverrideClass or not
forceApply : false, // apply the polyfill even for browser with native support
autoInit : true // init automatically or not
}, config);
this.options.hideClass = this.options.visibleToScreenreaders ? this.options.visibleToScreenreadersHideClass : this.options.visibleToNoneHideClass;
return $(this).each(function(index) {
var input = $(this),
text = input.attr('placeholder'),
id = input.attr('id'),
label,placeholder,titleNeeded,polyfilled;
label = input.closest('label');
input.removeAttr('placeholder');
if(!label.length && !id){
log('the input element with the placeholder needs an id!');
return;
}
label = label.length ? label : $('label[for="'+id+'"]').first();
if(!label.length){
log('the input element with the placeholder needs a label!');
return;
}
polyfilled = $(label).find('.placeholder');
if(polyfilled.length) {
//log('the input element already has a polyfilled placeholder!');
positionPlaceholder(polyfilled,input);
return input;
}
if(label.hasClass(o.options.removeLabelClass)){
label.removeClass(o.options.removeLabelClass)
.addClass(o.options.hiddenOverrideClass);
}
placeholder = $('<span class="'+o.options.className+'">'+text+'</span>').appendTo(label);
titleNeeded = (placeholder.width() > input.width());
if(titleNeeded){
placeholder.attr('title',text);
}
positionPlaceholder(placeholder,input);
input.data('placeholder',placeholder);
placeholder.data('input',placeholder);
placeholder.click(function(){
$(this).data('input').focus();
});
input.focusin(function() {
if(!o.options.hideOnFocus && window.requestAnimationFrame){
startFilledCheckChange(input,o.options);
}else{
hidePlaceholder(input,o.options);
}
});
input.focusout(function(){
showPlaceholderIfEmpty($(this),o.options);
if(!o.options.hideOnFocus && window.cancelAnimationFrame){
stopCheckChange();
}
});
showPlaceholderIfEmpty(input,o.options);
// reformat on window resize and optional reformat on font resize - requires: http://www.tomdeater.com/jquery/onfontresize/
$(document).bind("fontresize resize", function(){
positionPlaceholder(placeholder,input);
});
// optional reformat when a textarea is being resized - requires http://benalman.com/projects/jquery-resize-plugin/
if($.event.special.resize){
$("textarea").bind("resize", function(e){
positionPlaceholder(placeholder,input);
});
}else{
// we simply disable the resizeablilty of textareas when we can't react on them resizing
$("textarea").css('resize','none');
}
if(index >= l-1){
$.attrHooks.placeholder = {
get: function(elem) {
if (elem.nodeName.toLowerCase() == 'input' || elem.nodeName.toLowerCase() == 'textarea') {
if( $(elem).data('placeholder') ){
// has been polyfilled
return $( $(elem).data('placeholder') ).text();
}else{
// native / not yet polyfilled
return $(elem)[0].placeholder;
}
}else{
return undefined;
}
},
set: function(elem, value){
return $( $(elem).data('placeholder') ).text(value);
}
};
}
});
};
$(function(){
var config = window.placeHolderConfig || {};
if(config.autoInit === false){
log('placeholder:abort because autoInit is off');
return
}
if('placeholder' in $('<input>')[0] && !config.forceApply){ // don't run the polyfill when the browser has native support
log('placeholder:abort because browser has native support');
return;
}
$('input[placeholder], textarea[placeholder]').placeHolder(config);
});
})(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,16 @@
/**
* Copyright (c) 2008 Tom Deater (http://www.tomdeater.com)
* Licensed under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*/
jQuery.onFontResize=(function(a){a(document).ready(function(){var c=a("<iframe />").attr("id","frame-onFontResize"+Date.parse(new Date)).addClass("div-onfontresize").css({width:"100em",height:"10px",position:"absolute",borderWidth:0,top:"-5000px",left:"-5000px"}).appendTo("body");
if(a.browser.msie){c.bind("resize",function(){a.onFontResize.trigger(c[0].offsetWidth/100);});}else{var b=c[0].contentWindow||c[0].contentDocument||c[0].document;
b=b.document||b;b.open();b.write('<script>window.onload = function(){var em = parent.jQuery(".div-onfontresize")[0];window.onresize = function(){if(parent.jQuery.onFontResize){parent.jQuery.onFontResize.trigger(em.offsetWidth / 100);}}};<\/script>');
b.close();}});return{trigger:function(b){a(document).trigger("fontresize",[b]);}};})(jQuery);
/**
* Html5 Placeholder Polyfill - v2.0.6 - 2012-11-14
* web: * http://blog.ginader.de/dev/jquery/HTML5-placeholder-polyfill/
* issues: * https://github.com/ginader/HTML5-placeholder-polyfill/issues
* Copyright (c) 2012 Dirk Ginader; Licensed MIT, GPL
*/
(function(a){function d(a,b){a.val()===""?a.data("placeholder").removeClass(b.hideClass):a.data("placeholder").addClass(b.hideClass)}function e(a,b){a.data("placeholder").addClass(b.hideClass)}function f(a,b){var c=b.is("textarea"),d=b.offset();if(b.css("padding")&&b.css("padding")!=="0px"){var e=b.css("padding").split(" ");d.top+=Number(e[0].replace("px","")),d.left+=Number(e[e.length-1].replace("px",""))}else b.css("padding-top")&&b.css("padding-top")!=="0px"&&(d.top+=Number(b.css("padding-top").replace("px",""))),b.css("padding-left")&&b.css("padding-left")!=="0px"&&(d.left+=Number(b.css("padding-left").replace("px","")));a.css({width:b.innerWidth()-(c?20:4),height:b.innerHeight()-6,lineHeight:b.css("line-height"),whiteSpace:c?"normal":"nowrap",overflow:"hidden"}).offset(d)}function g(a,b){var d=a.val();(function f(){c=requestAnimationFrame(f),a.val()!==d&&(e(a,b),i(),h(a,b))})()}function h(a,b){(function e(){c=requestAnimationFrame(e),d(a,b)})()}function i(){cancelAnimationFrame(c)}function j(a){b&&window.console&&window.console.log&&window.console.log(a)}var b=!1,c;a.fn.placeHolder=function(b){j("init placeHolder");var c=this,h=a(this).length;return this.options=a.extend({className:"placeholder",visibleToScreenreaders:!0,visibleToScreenreadersHideClass:"placeholder-hide-except-screenreader",visibleToNoneHideClass:"placeholder-hide",hideOnFocus:!1,removeLabelClass:"visuallyhidden",hiddenOverrideClass:"visuallyhidden-with-placeholder",forceHiddenOverride:!0,forceApply:!1,autoInit:!0},b),this.options.hideClass=this.options.visibleToScreenreaders?this.options.visibleToScreenreadersHideClass:this.options.visibleToNoneHideClass,a(this).each(function(b){var k=a(this),m=k.attr("placeholder"),n=k.attr("id"),p,q,r,s;if(m===""||m===undefined)m=k[0].attributes.placeholder.value;p=k.closest("label"),k.removeAttr("placeholder");if(!p.length&&!n){j("the input element with the placeholder needs an id!");return}p=p.length?p:a('label[for="'+n+'"]').first();if(!p.length){j("the input element with the placeholder needs a label!");return}s=a(p).find(".placeholder");if(s.length)return f(s,k),s.text(m),k;p.hasClass(c.options.removeLabelClass)&&p.removeClass(c.options.removeLabelClass).addClass(c.options.hiddenOverrideClass),q=a("<span>").addClass(c.options.className).text(m).appendTo(p),r=q.width()>k.width(),r&&q.attr("title",m),f(q,k),k.data("placeholder",q),q.data("input",q),q.click(function(){a(this).data("input").focus()}),k.focusin(function(){!c.options.hideOnFocus&&window.requestAnimationFrame?g(k,c.options):e(k,c.options)}),k.focusout(function(){d(a(this),c.options),!c.options.hideOnFocus&&window.cancelAnimationFrame&&i()}),d(k,c.options),a(document).bind("fontresize resize",function(){f(q,k)}),a.event.special.resize?a("textarea").bind("resize",function(a){f(q,k)}):a("textarea").css("resize","none"),b>=h-1&&(a.attrHooks.placeholder={get:function(b){return b.nodeName.toLowerCase()==="input"||b.nodeName.toLowerCase()==="textarea"?a(b).data("placeholder")?a(a(b).data("placeholder")).text():a(b)[0].placeholder:undefined},set:function(b,c){return a(a(b).data("placeholder")).text(c)}})})},a(function(){var b=window.placeHolderConfig||{};if(b.autoInit===!1){j("placeholder:abort because autoInit is off");return}if(("placeholder"in a("<input>")[0]||"placeHolder"in a("<input>")[0])&&!b.forceApply){j("placeholder:abort because browser has native support");return}a("input[placeholder], textarea[placeholder]").placeHolder(b)})})(jQuery);

View File

@ -1,5 +1,6 @@
<?php $TRANSLATIONS = array(
"Error (de)activating addressbook." => "خطء خلال توقيف كتاب العناوين.",
"No categories selected for deletion." => "لم يتم اختيار فئة للحذف",
"Information about vCard is incorrect. Please reload the page." => "المعلومات الموجودة في ال vCard غير صحيحة. الرجاء إعادة تحديث الصفحة.",
"There is no error, the file uploaded with success" => "تم ترفيع الملفات بنجاح.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini" => "حجم الملف الذي تريد ترفيعه أعلى مما upload_max_filesize يسمح به في ملف php.ini",
@ -8,6 +9,7 @@
"No file was uploaded" => "لم يتم ترفيع أي من الملفات",
"Missing a temporary folder" => "المجلد المؤقت غير موجود",
"Contacts" => "المعارف",
"Error" => "خطأ",
"Upload too large" => "حجم الترفيع أعلى من المسموح",
"Download" => "انزال",
"Edit" => "تعديل",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Konnte das temporäre Bild nicht laden:",
"No file was uploaded. Unknown error" => "Keine Datei hochgeladen. Unbekannter Fehler",
"Contacts" => "Kontakte",
"%d_selected_contacts" => "%d_markierte_kontakte",
"Contact is already in this group." => "Kontakt ist bereits in dieser Gruppe.",
"Contacts are already in this group." => "Kontakte sind bereits in dieser Gruppe.",
"Couldn't get contact list." => "Kontaktliste konnte nicht ermittelt werden.",
@ -159,6 +160,7 @@
"OK" => "OK",
"(De-)select all" => "Alle (nicht) auswählen",
"New Contact" => "Neuer Kontakt",
"Download Contact(s)" => "Kontakt(e) herunterladen",
"Groups" => "Gruppen",
"Favorite" => "Favorit",
"Delete Contact" => "Kontakt löschen",
@ -194,6 +196,7 @@
"Enter organization" => "Organisation eingeben",
"Birthday" => "Geburtstag",
"Notes go here..." => "Notizen hier hinein...",
"Export as VCF" => "Als VCF exportieren",
"Add" => "Hinzufügen",
"Phone" => "Telefon",
"Email" => "E-Mail",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Konnte das temporäre Bild nicht laden:",
"No file was uploaded. Unknown error" => "Keine Datei hochgeladen. Unbekannter Fehler",
"Contacts" => "Kontakte",
"%d_selected_contacts" => "%d_markierte_kontakte",
"Contact is already in this group." => "Kontakt ist schon in der Gruppe.",
"Contacts are already in this group." => "Kontakte sind schon in der Gruppe.",
"Couldn't get contact list." => "Kontaktliste konnte nicht ermittelt werden.",
@ -159,7 +160,7 @@
"OK" => "OK",
"(De-)select all" => "Alle (ab-)wählen",
"New Contact" => "Neuer Kontakt",
"Download Contact(s)" => "Kontakte herunterladen",
"Download Contact(s)" => "Kontakt(e) herunterladen",
"Groups" => "Gruppen",
"Favorite" => "Favorit",
"Delete Contact" => "Kontakt löschen",

View File

@ -43,12 +43,18 @@
"Contacts" => "Επαφές",
"Contact is already in this group." => "Η επαφή είναι ήδη σε αυτήν την ομάδα.",
"Contacts are already in this group." => "Οι επαφές είναι ήδη σε αυτήν την ομάδα.",
"Couldn't get contact list." => "Αδυναμία λήψης λίστας επαφών.",
"Contact is not in this group." => "Η επαφή δεν είναι σε αυτή την ομάδα",
"Contacts are not in this group." => "Οι επαφές δεν είναι σε αυτή την ομάδα.",
"A group named {group} already exists" => "Υπάρχει ήδη μια ομάδα με όνομα {group}",
"All" => "Όλες",
"Favorites" => "Αγαπημένες",
"Shared by {owner}" => "Διαμοιράστηκε από τον {owner}",
"Add to..." => "Προσθήκη στο...",
"Remove from..." => "Αφαίρεση από το...",
"Add group..." => "Προσθήκη ομάδας...",
"Select photo" => "Επέλεξε φωτογραφία",
"Network or server error. Please inform administrator." => "Σφάλμα δικτύου ή διακομιστή. Παρακαλώ ενημερώστε το διαχειριστή.",
"Error adding to group." => "Σφάλμα κατά την προσθήκη σε ομάδα.",
"Error removing from group." => "Σφάλμα κατά την αφαίρεση από ομάδα.",
"There was an error opening a mail composer." => "Υπήρχε ένα σφάλμα στο άνοιγμα μίας σύνθεσης μηνύματος.",
@ -69,6 +75,7 @@
"Enter description" => "Εισαγωγή περιγραφής",
"Select addressbook" => "Επιλογή βιβλίου επαφών",
"The address book name cannot be empty." => "Το όνομα του βιβλίου διευθύνσεων δεν πρέπει να είναι κενό.",
"Is this correct?" => "Είναι σωστό;",
"Some contacts are marked for deletion, but not deleted yet. Please wait for them to be deleted." => "Κάποιες επαφές σημειώθηκαν προς διαγραφή,δεν έχουν διαγραφεί ακόμα. Παρακαλώ περιμένετε μέχρι να διαγραφούν.",
"Result: " => "Αποτέλεσμα: ",
" imported, " => " εισάγεται,",
@ -125,9 +132,11 @@
"New Group" => "Νέα Ομάδα",
"Settings" => "Ρυθμίσεις",
"Import" => "Εισαγωγή",
"Select files" => "Επιλογή αρχείων",
"Import into:" => "Εισαγωγή από:",
"OK" => "ΟΚ",
"New Contact" => "Νέα επαφή",
"Download Contact(s)" => "Λήψη Επαφής(-ών)",
"Groups" => "Ομάδες",
"Delete Contact" => "Διαγραφή επαφής",
"Close" => "Κλείσιμο ",
@ -158,6 +167,8 @@
"Title" => "Τίτλος",
"Organization" => "Οργανισμός",
"Birthday" => "Γενέθλια",
"Notes go here..." => "Σημειώσεις...",
"Export as VCF" => "Εξαγωγή ως VCF",
"Add" => "Προσθήκη",
"Phone" => "Τηλέφωνο",
"Email" => "Email",
@ -188,6 +199,7 @@
"Delete IM" => "Διαγραφή IM",
"Share" => "Μοιράσου",
"Export" => "Εξαγωγή",
"CardDAV link" => "Σύνδεσμος CardDAV",
"Add Contact" => "Προσθήκη επαφής",
"Drop photo to upload" => "Ρίξε μια φωτογραφία για ανέβασμα",
"Format custom, Short name, Full name, Reverse or Reverse with comma" => "Format custom, Όνομα, Επώνυμο, Αντίστροφο ή Αντίστροφο με κόμμα",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Fallo no pudo cargara de una imagen temporal",
"No file was uploaded. Unknown error" => "Fallo no se subió el fichero",
"Contacts" => "Contactos",
"%d_selected_contacts" => "%d_contactos_seleccionados",
"Contact is already in this group." => "El contacto ya se encuentra en este grupo.",
"Contacts are already in this group." => "Los contactos ya se encuentran es este grupo.",
"Couldn't get contact list." => "No se pudo obtener la lista de contactos.",
@ -159,6 +160,7 @@
"OK" => "Aceptar",
"(De-)select all" => "Seleccionar todos",
"New Contact" => "Nuevo contacto",
"Download Contact(s)" => "Descargar Contacto(s)",
"Groups" => "Grupos",
"Favorite" => "Favorito",
"Delete Contact" => "Eliminar contacto",

View File

@ -67,9 +67,14 @@
"Error adding to group." => "Erreur lors de l'ajout au groupe.",
"Error removing from group." => "Erreur lors du retrait du groupe.",
"There was an error opening a mail composer." => "Une erreur s'est produite lors de louverture d'un outil de composition email.",
"Deleting done. Click here to cancel reloading." => "Suppression effectuée. Cliquez ici pour annuler le rechargement.",
"Add address book" => "Ajouter un carnet d'adresses",
"Import done. Click here to cancel reloading." => "Import effectué. Cliquez ici pour annuler le rechargement.",
"Not all files uploaded. Retrying..." => "Tous les fichiers n'ont pas pu être téléversés. Nouvel essai…",
"Something went wrong with the upload, please retry." => "Une erreur s'est produite pendant le téléversement, veuillez réessayer.",
"Error" => "Erreur",
"Importing from {filename}..." => "Import en cours depuis {filename} ...",
"{success} imported, {failed} failed." => "{success} importé, {failed} échoué.",
"Importing..." => "Import en cours…",
"Unable to upload your file as it is a directory or has 0 bytes" => "Impossible de téléverser votre fichier dans la mesure où il s'agit d'un répertoire ou d'un fichier de taille nulle",
"Upload Error" => "Erreur lors du téléversement",
@ -145,7 +150,10 @@
"HomePage" => "Page d'Accueil",
"New Group" => "Nouveau Groupe",
"Settings" => "Paramètres",
"Address books" => "Carnets d'adresses",
"Import" => "Importer",
"Select files to import" => "Sélectionnez les fichiers à importer",
"Select files" => "Sélectionnez les fichiers",
"Import into:" => "Importer dans :",
"OK" => "OK",
"(De-)select all" => "(Dé-)sélectionner tout",
@ -180,7 +188,9 @@
"Nickname" => "Surnom",
"Enter nickname" => "Entrer un surnom",
"Title" => "Titre",
"Enter title" => "Saisissez le titre",
"Organization" => "Société",
"Enter organization" => "Saisissez l'organisation",
"Birthday" => "Anniversaire",
"Notes go here..." => "Remarques…",
"Add" => "Ajouter",
@ -209,12 +219,14 @@
"Your city" => "Votre Ville",
"City" => "Ville",
"Some region" => "Une Région",
"State or province" => "Pays ou région",
"Your country" => "Votre Pays",
"Country" => "Pays",
"Instant Messenger" => "Instant Messenger",
"Delete IM" => "Supprimer la messagerie instantanée",
"Share" => "Partager",
"Export" => "Exporter",
"CardDAV link" => "Lien CardDAV",
"Add Contact" => "Ajouter un Contact",
"Drop photo to upload" => "Glisser une photo pour l'envoi",
"Format custom, Short name, Full name, Reverse or Reverse with comma" => "Formatage personnalisé, Nom court, Nom complet, Inversé, Inversé avec virgule",

View File

@ -49,12 +49,14 @@
"Couldn't load temporary image: " => "Kan tijdelijk plaatje niet op laden:",
"No file was uploaded. Unknown error" => "Er was geen bestand geladen. Onbekende fout",
"Contacts" => "Contacten",
"%d_selected_contacts" => "%d_selected_contacts",
"Contact is already in this group." => "De contactpersoon bevindt zich al in deze groep.",
"Contacts are already in this group." => "De contactpersonen bevinden zich al in deze groep.",
"Couldn't get contact list." => "Kan de contactenlijst niet ophalen.",
"Contact is not in this group." => "De contactpersoon bevindt zich niet in deze groep",
"Contacts are not in this group." => "De contactpersonen bevinden zich niet in deze groep",
"A group named {group} already exists" => "Er bestaat al een groep {group}",
"You can drag groups to\narrange them as you like." => "U kunt groepen slepen\nom ze naar wens te rangschikken.",
"All" => "Alle",
"Favorites" => "Favorieten",
"Shared by {owner}" => "Gedeeld door {owner}",
@ -67,15 +69,21 @@
"Error adding to group." => "Fout bij het toevoegen aan de groep.",
"Error removing from group." => "Fout bij het verwijderen uit de groep.",
"There was an error opening a mail composer." => "Er is iets misgegaan tijdens het openen van een email programma.",
"Deleting done. Click here to cancel reloading." => "Verwijderen gereed. Klik hier om herladen te annuleren.",
"Add address book" => "Toevoegen adresboek",
"Import done. Click here to cancel reloading." => "Import gereed. Klik hier om herladen te annuleren.",
"Not all files uploaded. Retrying..." => "Nog niet alle bestanden zijn ge-upload. Nogmaals proberen...",
"Something went wrong with the upload, please retry." => "Er is iets fout gegaan met het uploaden. Probeer het nog eens.",
"Error" => "Fout",
"Importing from {filename}..." => "Importeren van {filename}...",
"{success} imported, {failed} failed." => "{success} geïmporteerd, {failed} mislukt.",
"Importing..." => "Importeren...",
"Unable to upload your file as it is a directory or has 0 bytes" => "Het lukt niet om uw bestand te uploaded, omdat het een folder of 0 bytes is",
"Upload Error" => "Upload fout",
"The file you are trying to upload exceed the maximum size for file uploads on this server." => "Het bestand dat u probeert te uploaden overschrijdt de maximale bestand grootte voor bestand uploads voor deze server.",
"Upload too large" => "Upload is te groot",
"Pending" => "In behandeling",
"Add group" => "Toevoegen groep",
"No files selected for upload." => "Geen bestanden geselecteerd voor upload.",
"Edit profile picture" => "Bewerk profielafbeelding",
"Error loading profile picture." => "Fout profiel plaatje kan niet worden geladen.",
@ -144,11 +152,15 @@
"HomePage" => "HomePage",
"New Group" => "Nieuwe Groep",
"Settings" => "Instellingen",
"Address books" => "Adresboeken",
"Import" => "Importeer",
"Select files to import" => "Selecteer de te importeren bestanden",
"Select files" => "Selecteer bestanden",
"Import into:" => "Importeer naar:",
"OK" => "OK",
"(De-)select all" => "(De-)selecteer alle",
"New Contact" => "Nieuw Contact",
"Download Contact(s)" => "Downloaden Contactperso(o)n(en)",
"Groups" => "Groepen",
"Favorite" => "Favoriet",
"Delete Contact" => "Verwijder Contact",
@ -179,9 +191,12 @@
"Nickname" => "Roepnaam",
"Enter nickname" => "Voer roepnaam in",
"Title" => "Titel",
"Enter title" => "Invoeren titel",
"Organization" => "Organisatie",
"Enter organization" => "Invoeren organisatie",
"Birthday" => "Verjaardag",
"Notes go here..." => "Hier de notities...",
"Export as VCF" => "Exporteren als VCF",
"Add" => "Toevoegen",
"Phone" => "Telefoon",
"Email" => "E-mail",
@ -201,15 +216,21 @@
"Delete URL" => "Verwijder URL",
"View on map" => "Bekijk op een kaart",
"Delete address" => "Verwijder adres",
"1 Main Street" => "Hoofdstraat 1",
"Street address" => "Adres",
"12345" => "12345",
"Postal code" => "Postcode",
"Your city" => "Ons Dorp",
"City" => "Stad",
"Some region" => "Een regio",
"State or province" => "Staat of provincie",
"Your country" => "Uw land",
"Country" => "Land",
"Instant Messenger" => "Instant Messenger",
"Delete IM" => "Verwijder IM",
"Share" => "Deel",
"Export" => "Exporteer",
"CardDAV link" => "CardDAV link",
"Add Contact" => "Contact toevoegen",
"Drop photo to upload" => "Verwijder foto uit upload",
"Format custom, Short name, Full name, Reverse or Reverse with comma" => "Formateer aangepast, Korte naam, Volledige naam, Achteruit of Achteruit met komma",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Nie można wczytać obrazu tymczasowego: ",
"No file was uploaded. Unknown error" => "Plik nie został załadowany. Nieznany błąd",
"Contacts" => "Kontakty",
"%d_selected_contacts" => "%d_wybierz_kontakty",
"Contact is already in this group." => "Kontakt jest już w tej grupie.",
"Contacts are already in this group." => "Kontakty są już w tej grupie.",
"Couldn't get contact list." => "Nie można pobrać listy kontaktów.",
@ -159,6 +160,7 @@
"OK" => "OK",
"(De-)select all" => "Odznacz wszystkie",
"New Contact" => "Nowy kontakt",
"Download Contact(s)" => "Pobierz Kontakt(y)",
"Groups" => "Grupy",
"Favorite" => "Ulubione",
"Delete Contact" => "Usuń kontakt",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Não é possível carregar a imagem temporária: ",
"No file was uploaded. Unknown error" => "Nenhum ficheiro foi carregado. Erro desconhecido",
"Contacts" => "Contactos",
"%d_selected_contacts" => "%d_selected_contacts",
"Contact is already in this group." => "O contacto já está neste grupo.",
"Contacts are already in this group." => "Os contactos já estão neste grupo",
"Couldn't get contact list." => "Não foi possível ler a lista de contactos",
@ -159,6 +160,7 @@
"OK" => "OK",
"(De-)select all" => "(Des)seleccionar todos",
"New Contact" => "Novo Contacto",
"Download Contact(s)" => "Fazer download do(s) contacto(s)",
"Groups" => "Grupos",
"Favorite" => "Favorito",
"Delete Contact" => "Eliminar o Contacto",
@ -189,9 +191,12 @@
"Nickname" => "Alcunha",
"Enter nickname" => "Introduza alcunha",
"Title" => "Titulo ",
"Enter title" => "Título",
"Organization" => "Organização",
"Enter organization" => "Organização",
"Birthday" => "Aniversário",
"Notes go here..." => "As notas ficam aqui:",
"Export as VCF" => "Exportar como VCF",
"Add" => "Adicionar",
"Phone" => "Telefone",
"Email" => "Email",
@ -218,6 +223,7 @@
"Your city" => "Cidade",
"City" => "Cidade",
"Some region" => "Região (Distrito)",
"State or province" => "Distrito",
"Your country" => "País",
"Country" => "País",
"Instant Messenger" => "Mensageiro instantâneo",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Не удалось загрузить временное изображение:",
"No file was uploaded. Unknown error" => "Файл не был загружен. Неизвестная ошибка",
"Contacts" => "Контакты",
"%d_selected_contacts" => "%d_выбранныеонтакты",
"Contact is already in this group." => "Контакт уже находятся в этой группе.",
"Contacts are already in this group." => "Контакты уже находятся в этой группе.",
"Couldn't get contact list." => "Не удалось получить список контактов.",
@ -159,6 +160,7 @@
"OK" => "ОК",
"(De-)select all" => "(Отменить) отметить все",
"New Contact" => "Новый контакт",
"Download Contact(s)" => "Загрузить контакт(ы)",
"Groups" => "Группы",
"Favorite" => "Избранное",
"Delete Contact" => "Удалить контакт",

View File

@ -49,12 +49,14 @@
"Couldn't load temporary image: " => "Не удалось загрузить временное изображение:",
"No file was uploaded. Unknown error" => "Файл не был загружен. Неизвестная ошибка",
"Contacts" => "Контакты",
"%d_selected_contacts" => "%d_выбранныеонтакты",
"Contact is already in this group." => "Контакт уже в этой группе.",
"Contacts are already in this group." => "Контакты уже в этой группе.",
"Couldn't get contact list." => "Не удалось получить лист контактов.",
"Contact is not in this group." => "Контакт не в этой группе.",
"Contacts are not in this group." => "Контакты не в этой группе.",
"A group named {group} already exists" => "Группа, названная {группа} уже существует",
"You can drag groups to\narrange them as you like." => "Вы можете передвигать группы,\nчтобы расположить их как Вам нравится.",
"All" => "Все",
"Favorites" => "Избранные",
"Shared by {owner}" => "Опубликовано {собственник}",
@ -67,9 +69,14 @@
"Error adding to group." => "Ошибка добавления в группу.",
"Error removing from group." => "Ошибка удаления из группы.",
"There was an error opening a mail composer." => "Произошла ошибка при открытии окна составления сообщения.",
"Deleting done. Click here to cancel reloading." => "Удаление выполнено. Нажмите здесь, чтобы отменить перезагрузку.",
"Add address book" => "Добавить адресную книгу",
"Import done. Click here to cancel reloading." => "Импортирование выполнено. Нажмите здесь, чтобы отменить перезагрузку.",
"Not all files uploaded. Retrying..." => "Не все файлы загружены. Попробуйте снова..",
"Something went wrong with the upload, please retry." => "Что-то пошло не так при загрузке, пожалуйста, попробуйте снова.",
"Error" => "Ошибка",
"Importing from {filename}..." => "Импортирование из {имя файла}...",
"{success} imported, {failed} failed." => "{успешно} импортировано, {неудачно} выполнить не удалось .",
"Importing..." => "Импортирование...",
"Unable to upload your file as it is a directory or has 0 bytes" => "Невозможно загрузить Ваш файл, так как он является каталогом или его размер составляет 0 байт.",
"Upload Error" => "Ошибка загрузки",
@ -145,11 +152,15 @@
"HomePage" => "Домашняя страница",
"New Group" => "Новая группа",
"Settings" => "Настройки",
"Address books" => "Адресные книги",
"Import" => "Импортировать",
"Select files to import" => "Выберите файлы для импортирования",
"Select files" => "Выбрать файлы",
"Import into:" => "Импортировать в:",
"OK" => "OK",
"(De-)select all" => "Отметить(снять отметку) все",
"New Contact" => "Новый контакт",
"Download Contact(s)" => "Загруженный контакт(ы)",
"Groups" => "Группы",
"Favorite" => "Избранный",
"Delete Contact" => "Удалить контакт",
@ -180,9 +191,12 @@
"Nickname" => "Имя",
"Enter nickname" => "Введите имя",
"Title" => "Название",
"Enter title" => "Введите название",
"Organization" => "Организация",
"Enter organization" => "Введите организацию",
"Birthday" => "День рождения",
"Notes go here..." => "Заметки перемещаются сюда...",
"Export as VCF" => "Экспортировать как VCF",
"Add" => "Добавить",
"Phone" => "Телефон",
"Email" => "Email",
@ -209,12 +223,14 @@
"Your city" => "Ваш город",
"City" => "Город",
"Some region" => "Регион",
"State or province" => "Область или район",
"Your country" => "Ваша страна",
"Country" => "Страна",
"Instant Messenger" => "Служба обмена мгновенными сообщениями",
"Delete IM" => "Удалить IM",
"Share" => "Сделать общим",
"Export" => "Экспортировать",
"CardDAV link" => "CardDAV ссылка",
"Add Contact" => "Добавить контакт",
"Drop photo to upload" => "Перетащите фотографию для загрузки",
"Format custom, Short name, Full name, Reverse or Reverse with comma" => "Пользовательский формат, сокращенное имя, полное имя, обратный порядок или обратный порядок с запятыми",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Začasne slike ni mogoče naložiti: ",
"No file was uploaded. Unknown error" => "Nobena datoteka ni naložena. Neznana napaka.",
"Contacts" => "Stiki",
"%d_selected_contacts" => "%d_selected_contacts",
"Contact is already in this group." => "Stik je že v tej skupini.",
"Contacts are already in this group." => "Stiki so že v tej skupini.",
"Couldn't get contact list." => "Ne morem dobiti seznama stikov.",
@ -159,6 +160,7 @@
"OK" => "V redu",
"(De-)select all" => "(Od-)izberi vse",
"New Contact" => "Nov stik",
"Download Contact(s)" => "Prenesi stike",
"Groups" => "Skupine",
"Favorite" => "Priljubljen",
"Delete Contact" => "Izbriši stik",
@ -189,9 +191,12 @@
"Nickname" => "Vzdevek",
"Enter nickname" => "Vnos vzdevka",
"Title" => "Ime",
"Enter title" => "Vnesite naziv",
"Organization" => "Ustanova",
"Enter organization" => "Vnesite organizacijo",
"Birthday" => "Rojstni dan",
"Notes go here..." => "Prostor za opombe ...",
"Export as VCF" => "Izvozi kot VCF",
"Add" => "Dodaj",
"Phone" => "Telefon",
"Email" => "Elektronska pošta",
@ -218,6 +223,7 @@
"Your city" => "Vaše mesto",
"City" => "Mesto",
"Some region" => "Neka regija",
"State or province" => "Zvezna država ali provinca",
"Your country" => "Vaša država",
"Country" => "Država",
"Instant Messenger" => "Hipni sporočilnik",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Kunde inte ladda tillfällig bild:",
"No file was uploaded. Unknown error" => "Ingen fil uppladdad. Okänt fel",
"Contacts" => "Kontakter",
"%d_selected_contacts" => "%d_selected_contacts",
"Contact is already in this group." => "Kontakten finns redan i denna grupp.",
"Contacts are already in this group." => "Kontakterna finns redan i denna grupp.",
"Couldn't get contact list." => "Kunde inte hämta kontaktlista.",
@ -159,6 +160,7 @@
"OK" => "OK",
"(De-)select all" => "(Av-)markera alla",
"New Contact" => "Ny kontakt",
"Download Contact(s)" => "Ladda ner kontakt(er)",
"Groups" => "Grupper",
"Favorite" => "Favorit",
"Delete Contact" => "Radera kontakt",
@ -189,9 +191,12 @@
"Nickname" => "Smeknamn",
"Enter nickname" => "Ange smeknamn",
"Title" => "Titel",
"Enter title" => "Ange titel",
"Organization" => "Organisation",
"Enter organization" => "Ange organisation",
"Birthday" => "Födelsedag",
"Notes go here..." => "Noteringar här...",
"Export as VCF" => "Exportera som VCF",
"Add" => "Lägg till",
"Phone" => "Telefon",
"Email" => "E-post",
@ -218,6 +223,7 @@
"Your city" => "Din stad",
"City" => "Stad",
"Some region" => "En region",
"State or province" => "Stat eller provins",
"Your country" => "Ditt land",
"Country" => "Land",
"Instant Messenger" => "Instant Messenger",

View File

@ -49,6 +49,7 @@
"Couldn't load temporary image: " => "Не вдалося завантажити тимчасове зображення: ",
"No file was uploaded. Unknown error" => "Не завантажено жодного файлу. Невідома помилка",
"Contacts" => "Контакти",
"%d_selected_contacts" => "%d_selected_contacts",
"Contact is already in this group." => "Контакт вже у даній групі.",
"Contacts are already in this group." => "Контакти вже у даній групі.",
"Couldn't get contact list." => "Не вдалося отримати список контактів.",
@ -159,6 +160,7 @@
"OK" => "OK",
"(De-)select all" => "(Відміна) виділення усіх",
"New Contact" => "Новий контакт",
"Download Contact(s)" => "Завантажити Контакт(и)",
"Groups" => "Групи",
"Favorite" => "Улюблений",
"Delete Contact" => "Видалити контакт",

View File

@ -49,13 +49,21 @@
"Contact is not in this group." => "联系人不在此分组中。",
"A group named {group} already exists" => "分组{group}已存在。",
"All" => "全部",
"Favorites" => "收藏",
"Shared by {owner}" => "共享人:{owner}",
"Indexing contacts" => "正在索引联系人",
"Add to..." => "添加到……",
"Add group..." => "添加分组……",
"Select photo" => "选择图片",
"Error adding to group." => "添加到组时出错。",
"Error removing from group." => "从组删除时出错。",
"There was an error opening a mail composer." => "打开邮件撰写器时出错。",
"Add address book" => "添加地址簿",
"Import done. Click here to cancel reloading." => "导入完毕。点击此处取消重载。",
"Not all files uploaded. Retrying..." => "仍有文件未上传,重试中",
"Something went wrong with the upload, please retry." => "上传中出现些问题,请重试。",
"Error" => "错误",
"Importing from {filename}..." => "正在导入 {文件名}...",
"Importing..." => "导入中",
"Unable to upload your file as it is a directory or has 0 bytes" => "无法上传您的文件,文件夹或者空文件",
"Upload Error" => "上传错误",
@ -64,10 +72,13 @@
"Pending" => "等待",
"Add group" => "添加分组",
"No files selected for upload." => "没有选择文件以上传",
"Edit profile picture" => "编辑配置图片",
"Error loading profile picture." => "载入档案图片时出错",
"Enter name" => "输入姓名",
"Enter description" => "输入描述",
"Select addressbook" => "选择地址簿",
"The address book name cannot be empty." => "地址簿名称不能为空",
"Is this correct?" => "这正确吗?",
"Some contacts are marked for deletion, but not deleted yet. Please wait for them to be deleted." => "一些联系人已被标注为删除,但是尚未完成,请稍候。",
"Result: " => "结果: ",
" imported, " => " 已导入, ",
@ -124,11 +135,15 @@
"HomePage" => "主页",
"New Group" => "新建分组",
"Settings" => "设置",
"Address books" => "地址簿",
"Import" => "导入",
"Select files to import" => "选择要导入的文件",
"Select files" => "选择文件",
"Import into:" => "导入至:",
"OK" => "OK",
"(De-)select all" => "反选全部",
"New Contact" => "新建联系人",
"Download Contact(s)" => "下载联系人",
"Groups" => "分组",
"Favorite" => "最爱",
"Delete Contact" => "删除联系人",
@ -158,8 +173,11 @@
"Nickname" => "昵称",
"Enter nickname" => "输入昵称",
"Title" => "标题",
"Enter title" => "输入标题",
"Organization" => "组织",
"Enter organization" => "输入组织",
"Birthday" => "生日",
"Export as VCF" => "导出为 VCF",
"Add" => "增加",
"Phone" => "电话",
"Email" => "电子邮件",
@ -179,11 +197,14 @@
"Delete URL" => "删除URL",
"View on map" => "在地图上显示",
"Delete address" => "删除地址",
"1 Main Street" => "1 主街道",
"Street address" => "街道地址",
"12345" => "12345",
"Postal code" => "邮政编码",
"Your city" => "城市",
"City" => "城市",
"Some region" => "部分地区",
"State or province" => "州/省",
"Your country" => "国家",
"Country" => "国家",
"Instant Messenger" => "即时通讯",

View File

@ -14,21 +14,18 @@
<input id="contactphoto_fileupload" type="file" accept="image/*" name="imagefile" />
</form>
<iframe name="file_upload_target" id='file_upload_target' src=""></iframe>
<div id="groupsheader">
<button class="addgroup"><?php echo $l->t('New Group'); ?></button>
</div>
<div id="leftcontent" class="loading">
<div class="hidden" id="statusbar"></div>
<div id="groupactions">
<button class="addgroup"><?php echo $l->t('New Group'); ?></button>
</div>
<nav id="grouplist">
</nav>
<div id="contacts-settings">
<ul>
<li><button class="settings" title="<?php echo $l->t('Settings'); ?>"></button></li>
<li><h3 data-id="addressbooks"><?php echo $l->t('Address books'); ?></h3>
<h3 class="settings action text" tabindex="0" role="button"><?php echo $l->t('Settings'); ?></h3>
<h3 data-id="addressbooks" tabindex="0" role="button"><?php echo $l->t('Address books'); ?></h3>
<ul class="hidden">
</ul>
</li>
<li><h3 data-id="import" role="button"><?php echo $l->t('Import'); ?></h3>
<h3 data-id="import" tabindex="0" role="button"><?php echo $l->t('Import'); ?></h3>
<ul class="hidden">
<li class="import-upload">
<form id="import_upload_form" action="<?php echo OCP\Util::linkTo('contacts', 'ajax/uploadimport.php'); ?>" method="post" enctype="multipart/form-data" target="import_upload_target">
@ -51,8 +48,6 @@
<div id="import-progress"></div>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div id="contactsheader">