forked from GNUsocial/gnu-social
styling for people tag UI
This commit is contained in:
parent
382e4d2cdb
commit
b372ed721d
381
js/jquery.tagInput.js
Normal file
381
js/jquery.tagInput.js
Normal file
@ -0,0 +1,381 @@
|
||||
/*
|
||||
Copyright (c) 2009 Open Lab, http://www.open-lab.com/
|
||||
Written by Roberto Bicchierai http://roberto.open-lab.com.
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/**
|
||||
* options.tags an object array [{tag:"tag1",freq:1},{tag:"tag2",freq:2}, {tag:"tag3",freq:3},{tag:"tag4",freq:4} ].
|
||||
* options.jsonUrl an url returning a json object array in the same format of options.tag. The url will be called with
|
||||
* "search" parameter to be used server side to filter results
|
||||
* option.autoFilter true/false default=true when active show only matching tags, "false" should be used for server-side filtering
|
||||
* option.autoStart true/false default=false when active dropdown will appear entering field, otherwise when typing
|
||||
* options.sortBy "frequency"|"tag"|"none" default="tag"
|
||||
* options.tagSeparator default="," any separator char as space, comma, semicolumn
|
||||
* options.boldify true/false default trrue boldify the matching part of tag in dropdown
|
||||
*
|
||||
* options.suggestedTags callback an object array like ["sugtag1","sugtag2","sugtag3"]
|
||||
* options.suggestedTagsPlaceHolder jquery proxy for suggested tag placeholder. When placeholder is supplied (hence unique), tagField should be applied on a single input
|
||||
* (something like $("#myTagFiled").tagField(...) will works fine: $(":text").tagField(...) probably not!)
|
||||
*/
|
||||
|
||||
if (typeof(String.prototype.trim) == "undefined"){
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
jQuery.fn.tagInput = function(options) {
|
||||
// -------------------------- start default option values --------------------------
|
||||
if (!options.tags && !options.jsonUrl) {
|
||||
options.tags = [ { tag:"tag1", freq:1 }, { tag:"tag2", freq:2 }, { tag:"tag3", freq:3 }, { tag:"tag4", freq:4 } ];
|
||||
}
|
||||
|
||||
if (typeof(options.tagSeparator) == "undefined")
|
||||
options.tagSeparator = ",";
|
||||
|
||||
if (typeof(options.autoFilter) == "undefined")
|
||||
options.autoFilter = true;
|
||||
|
||||
if (typeof(options.autoStart) == "undefined")
|
||||
options.autoStart = false;
|
||||
|
||||
if (typeof(options.boldify) == "undefined")
|
||||
options.boldify = true;
|
||||
|
||||
if (typeof(options.animate) == "undefined")
|
||||
options.animate = true;
|
||||
|
||||
if (typeof(options.animate) != "function") {
|
||||
options._animate = options.animate;
|
||||
options.animate = function(show, el, cb) {
|
||||
var func = (options._animate) ? (show ? 'fadeIn' : 'fadeOut') : (show ? 'show' : 'hide');
|
||||
el[func](cb);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof(options.sortBy) == "undefined")
|
||||
options.sortBy = "tag";
|
||||
|
||||
if (typeof(options.sortBy) == "string") {
|
||||
options._sortBy = options.sortBy;
|
||||
options.sortBy = function(obj) { return obj[options._sortBy]; }
|
||||
}
|
||||
|
||||
if (typeof(options.formatLine) == "undefined")
|
||||
options.formatLine = function (i, obj, search, matches) {
|
||||
var tag = obj.tag;
|
||||
if (options.boldify && matches) {
|
||||
tag = "<b>" + tag.substring(0, search.length) + "</b>" + tag.substring(search.length);
|
||||
}
|
||||
|
||||
var line = $("<div/>");
|
||||
line.append("<div class='tagInputLineTag'>" + tag + "</div>");
|
||||
if (obj.freq)
|
||||
line.append("<div class='tagInputLineFreq'>" + obj.freq + "</div>");
|
||||
return line;
|
||||
}
|
||||
|
||||
if (typeof(options.formatValue == "undefined"))
|
||||
options.formatValue = function (obj, i) {
|
||||
return obj.tag;
|
||||
}
|
||||
// -------------------------- end default option values --------------------------
|
||||
|
||||
|
||||
this.each(function() {
|
||||
|
||||
var theInput = $(this);
|
||||
var theDiv;
|
||||
|
||||
theInput.addClass("tagInput");
|
||||
theInput.tagOptions=options;
|
||||
theInput.attr('autocomplete', 'off');
|
||||
|
||||
var suggestedTagsPlaceHolder=options.suggestedTagsPlaceHolder;
|
||||
//create suggested tags place if the case
|
||||
if (options.suggestedTags){
|
||||
if (!suggestedTagsPlaceHolder){
|
||||
//create a placeholder
|
||||
var stl=$("<div class='tagInputSuggestedTags'><span class='label'>suggested tags: </span><span class='tagInputSuggestedTagList'></span></div>");
|
||||
suggestedTagsPlaceHolder=stl.find(".tagInputSuggestedTagList");
|
||||
theInput.after(stl);
|
||||
}
|
||||
|
||||
//fill with suggestions
|
||||
for (var tag in options.suggestedTags) {
|
||||
suggestedTagsPlaceHolder.append($("<span class='tag'>" + options.suggestedTags[tag] + "</span>"));
|
||||
}
|
||||
|
||||
// bind click on suggestion tags
|
||||
suggestedTagsPlaceHolder.find(".tag").click(function() {
|
||||
var element = $(this);
|
||||
var val = theInput.val();
|
||||
var tag = element.text();
|
||||
|
||||
//check if already present
|
||||
var re = new RegExp(tag + "\\b","g");
|
||||
if (containsTag(val, tag)) {
|
||||
val = val.replace(re, ""); //remove all the tag
|
||||
element.removeClass("tagUsed");
|
||||
} else {
|
||||
val = val + options.tagSeparator + tag;
|
||||
element.addClass("tagUsed");
|
||||
}
|
||||
theInput.val(refurbishTags(val));
|
||||
// selectSuggTagFromInput();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -------------------------- INPUT FOCUS --------------------------
|
||||
var tagInputFocus = function () {
|
||||
theDiv = $("#__tagInputDiv");
|
||||
// check if the result box exists
|
||||
if (theDiv.size() <= 0) {
|
||||
//create the div
|
||||
theDiv = $("<div id='__tagInputDiv' class='tagInputDiv' style='width:" + theInput.get(0).clientWidth + ";display:none; '></div>");
|
||||
theInput.after(theDiv);
|
||||
theDiv.css({left:theInput.position().left});
|
||||
}
|
||||
if (options.autoStart)
|
||||
tagInputRefreshDiv(theInput, theDiv);
|
||||
};
|
||||
|
||||
|
||||
// -------------------------- INPUT BLUR --------------------------
|
||||
var tagInputBlur = function () {
|
||||
// reformat string
|
||||
theDiv = $("#__tagInputDiv");
|
||||
theInput.val(refurbishTags(theInput.val()));
|
||||
|
||||
options.animate(0, theDiv, function() {
|
||||
theDiv.remove();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// -------------------------- INPUT KEYBOARD --------------------------
|
||||
var tagInputKey = function (e) {
|
||||
var rows = theDiv.find("div.tagInputLine");
|
||||
var rowNum = rows.index(theDiv.find("div.tagInputSel"));
|
||||
|
||||
var ret = true;
|
||||
switch (e.which) {
|
||||
case 38: //up arrow
|
||||
rowNum = (rowNum < 1 ? 0 : rowNum - 1 );
|
||||
tagInputHLSCR(rows.eq(rowNum), true);
|
||||
break;
|
||||
|
||||
case 40: //down arrow
|
||||
rowNum = (rowNum < rows.size() - 1 ? rowNum + 1 : rows.size() - 1 );
|
||||
tagInputHLSCR(rows.eq(rowNum), false);
|
||||
break;
|
||||
|
||||
case 9: //tab
|
||||
case 13: //enter
|
||||
if (theDiv.is(":visible")){
|
||||
var theRow = rows.eq(rowNum);
|
||||
tagInputClickRow(theRow);
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 27: //esc
|
||||
options.animate(0, theDiv);
|
||||
break;
|
||||
|
||||
default:
|
||||
$(document).stopTime("tagInputRefresh");
|
||||
$(document).oneTime(400, "tagInputRefresh", function() {
|
||||
tagInputRefreshDiv();
|
||||
});
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------- TAG DIV HIGHLIGHT AND SCROLL --------------------------
|
||||
var tagInputHLSCR = function(theRowJQ, isUp) {
|
||||
if (theRowJQ.size() > 0) {
|
||||
var div = theDiv.get(0);
|
||||
var theRow = theRowJQ.get(0);
|
||||
if (isUp) {
|
||||
if (theDiv.scrollTop() > theRow.offsetTop) {
|
||||
theDiv.scrollTop(theRow.offsetTop);
|
||||
}
|
||||
} else {
|
||||
if ((theRow.offsetTop + theRow.offsetHeight) > (div.scrollTop + div.offsetHeight)) {
|
||||
div.scrollTop = theRow.offsetTop + theRow.offsetHeight - div.offsetHeight;
|
||||
}
|
||||
}
|
||||
theDiv.find("div.tagInputSel").removeClass("tagInputSel");
|
||||
theRowJQ.addClass("tagInputSel");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -------------------------- TAG LINE CLICK --------------------------
|
||||
var tagInputClickRow = function(theRow) {
|
||||
|
||||
var lastComma = theInput.val().lastIndexOf(options.tagSeparator);
|
||||
var sep= lastComma<=0? (""):(options.tagSeparator+ (options.tagSeparator==" "?"":" "));
|
||||
var newVal = (theInput.val().substr(0, lastComma) + sep + theRow.attr('id').replace('val-','')).trim();
|
||||
theInput.val(newVal);
|
||||
theDiv.hide();
|
||||
$().oneTime(200, function() {
|
||||
theInput.focus();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// -------------------------- REFILL TAG BOX --------------------------
|
||||
var tagInputRefreshDiv = function () {
|
||||
|
||||
var lastComma = theInput.val().lastIndexOf(options.tagSeparator);
|
||||
var search = theInput.val().substr(lastComma + 1).trim();
|
||||
|
||||
|
||||
// -------------------------- FILLING THE DIV --------------------------
|
||||
var fillingCallbak = function(tags) {
|
||||
tags = tags.sort(function (a, b) {
|
||||
if (options.sortBy(a) < options.sortBy(b))
|
||||
return 1;
|
||||
if (options.sortBy(a) > options.sortBy(b))
|
||||
return -1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
for (var i in tags) {
|
||||
tags[i]._val = options.formatValue(tags[i], i);
|
||||
var el = tags[i];
|
||||
var matches = el._val.toLocaleLowerCase().indexOf(search.toLocaleLowerCase()) == 0;
|
||||
if (!options.autoFilter || matches) {
|
||||
var line = $(options.formatLine(i, el, search, matches));
|
||||
if (!line.is('.tagInputLine'))
|
||||
line = $("<div class='tagInputLine'></div>").append(line);
|
||||
line.attr('id', 'val-' + el._val);
|
||||
theDiv.append(line);
|
||||
}
|
||||
}
|
||||
if (theDiv.html()!=""){
|
||||
options.animate(true, theDiv);
|
||||
}
|
||||
|
||||
theDiv.find("div:first").addClass("tagInputSel");
|
||||
theDiv.find("div.tagInputLine").bind("click", function() {
|
||||
tagInputClickRow($(this));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
if (search != "" || options.autoStart) {
|
||||
theDiv.html("");
|
||||
|
||||
if (options.tags)
|
||||
fillingCallbak(options.tags);
|
||||
else{
|
||||
var data = {search:search};
|
||||
$.getJSON(options.jsonUrl, data, fillingCallbak );
|
||||
}
|
||||
} else {
|
||||
options.animate(false, theDiv);
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------- CLEAN THE TAG LIST FROM EXTRA SPACES, DOUBLE COMMAS ETC. --------------------------
|
||||
var refurbishTags = function (tagString) {
|
||||
var splitted = tagString.split(options.tagSeparator);
|
||||
var res = "";
|
||||
var first = true;
|
||||
for (var i = 0; i < splitted.length; i++) {
|
||||
if (splitted[i].trim() != "") {
|
||||
if (first) {
|
||||
first = false;
|
||||
res = res + splitted[i].trim();
|
||||
} else {
|
||||
res = res + options.tagSeparator+ (options.tagSeparator==" "?"":" ") + splitted[i].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
return( res);
|
||||
};
|
||||
|
||||
// -------------------------- TEST IF TAG IS PRESENT --------------------------
|
||||
var containsTag=function (tagString,tag){
|
||||
var splitted = tagString.split(options.tagSeparator);
|
||||
var res="";
|
||||
var found=false;
|
||||
tag=tag.trim();
|
||||
for(i = 0; i < splitted.length; i++){
|
||||
var testTag=splitted[i].trim();
|
||||
if (testTag==tag){
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------- SELECT TAGS BASING ON USER INPUT --------------------------
|
||||
var delayedSelectTagFromInput= function(){
|
||||
var element = $(this);
|
||||
$().stopTime("suggTagRefresh");
|
||||
$().oneTime(200, "suggTagRefresh", function() {
|
||||
selectSuggTagFromInput();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var selectSuggTagFromInput = function () {
|
||||
var val = theInput.val();
|
||||
suggestedTagsPlaceHolder.find(".tag").each(function(){
|
||||
var el = $(this);
|
||||
var tag=el.text();
|
||||
|
||||
//check if already present
|
||||
if (containsTag(val,tag)) {
|
||||
el.addClass("tagUsed");
|
||||
} else {
|
||||
el.removeClass("tagUsed");
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------- INPUT BINDINGS --------------------------
|
||||
$(this).bind("focus", tagInputFocus).bind("blur", tagInputBlur).bind("keydown", tagInputKey);
|
||||
if (options.suggestedTags)
|
||||
$(this).bind("keyup",delayedSelectTagFromInput) ;
|
||||
|
||||
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
|
138
js/jquery.timers.js
Normal file
138
js/jquery.timers.js
Normal file
@ -0,0 +1,138 @@
|
||||
/**
|
||||
* jQuery.timers - Timer abstractions for jQuery
|
||||
* Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
|
||||
* Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
|
||||
* Date: 2009/10/16
|
||||
*
|
||||
* @author Blair Mitchelmore
|
||||
* @version 1.2
|
||||
*
|
||||
**/
|
||||
|
||||
jQuery.fn.extend({
|
||||
everyTime: function(interval, label, fn, times) {
|
||||
return this.each(function() {
|
||||
jQuery.timer.add(this, interval, label, fn, times);
|
||||
});
|
||||
},
|
||||
oneTime: function(interval, label, fn) {
|
||||
return this.each(function() {
|
||||
jQuery.timer.add(this, interval, label, fn, 1);
|
||||
});
|
||||
},
|
||||
stopTime: function(label, fn) {
|
||||
return this.each(function() {
|
||||
jQuery.timer.remove(this, label, fn);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
jQuery.extend({
|
||||
timer: {
|
||||
global: [],
|
||||
guid: 1,
|
||||
dataKey: "jQuery.timer",
|
||||
regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
|
||||
powers: {
|
||||
// Yeah this is major overkill...
|
||||
'ms': 1,
|
||||
'cs': 10,
|
||||
'ds': 100,
|
||||
's': 1000,
|
||||
'das': 10000,
|
||||
'hs': 100000,
|
||||
'ks': 1000000
|
||||
},
|
||||
timeParse: function(value) {
|
||||
if (value == undefined || value == null)
|
||||
return null;
|
||||
var result = this.regex.exec(jQuery.trim(value.toString()));
|
||||
if (result[2]) {
|
||||
var num = parseFloat(result[1]);
|
||||
var mult = this.powers[result[2]] || 1;
|
||||
return num * mult;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
},
|
||||
add: function(element, interval, label, fn, times) {
|
||||
var counter = 0;
|
||||
|
||||
if (jQuery.isFunction(label)) {
|
||||
if (!times)
|
||||
times = fn;
|
||||
fn = label;
|
||||
label = interval;
|
||||
}
|
||||
|
||||
interval = jQuery.timer.timeParse(interval);
|
||||
|
||||
if (typeof interval != 'number' || isNaN(interval) || interval < 0)
|
||||
return;
|
||||
|
||||
if (typeof times != 'number' || isNaN(times) || times < 0)
|
||||
times = 0;
|
||||
|
||||
times = times || 0;
|
||||
|
||||
var timers = jQuery.data(element, this.dataKey) || jQuery.data(element, this.dataKey, {});
|
||||
|
||||
if (!timers[label])
|
||||
timers[label] = {};
|
||||
|
||||
fn.timerID = fn.timerID || this.guid++;
|
||||
|
||||
var handler = function() {
|
||||
if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
|
||||
jQuery.timer.remove(element, label, fn);
|
||||
};
|
||||
|
||||
handler.timerID = fn.timerID;
|
||||
|
||||
if (!timers[label][fn.timerID])
|
||||
timers[label][fn.timerID] = window.setInterval(handler,interval);
|
||||
|
||||
this.global.push( element );
|
||||
|
||||
},
|
||||
remove: function(element, label, fn) {
|
||||
var timers = jQuery.data(element, this.dataKey), ret;
|
||||
|
||||
if ( timers ) {
|
||||
|
||||
if (!label) {
|
||||
for ( label in timers )
|
||||
this.remove(element, label, fn);
|
||||
} else if ( timers[label] ) {
|
||||
if ( fn ) {
|
||||
if ( fn.timerID ) {
|
||||
window.clearInterval(timers[label][fn.timerID]);
|
||||
delete timers[label][fn.timerID];
|
||||
}
|
||||
} else {
|
||||
for ( var fn in timers[label] ) {
|
||||
window.clearInterval(timers[label][fn]);
|
||||
delete timers[label][fn];
|
||||
}
|
||||
}
|
||||
|
||||
for ( ret in timers[label] ) break;
|
||||
if ( !ret ) {
|
||||
ret = null;
|
||||
delete timers[label];
|
||||
}
|
||||
}
|
||||
|
||||
for ( ret in timers ) break;
|
||||
if ( !ret )
|
||||
jQuery.removeData(element, this.dataKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(window).bind("unload", function() {
|
||||
jQuery.each(jQuery.timer.global, function(index, item) {
|
||||
jQuery.timer.remove(item);
|
||||
});
|
||||
});
|
126
js/util.js
126
js/util.js
@ -450,6 +450,74 @@ var SN = { // StatusNet
|
||||
});
|
||||
},
|
||||
|
||||
FormProfileSearchXHR: function(form) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
dataType: 'xml',
|
||||
url: form.attr('action'),
|
||||
data: form.serialize() + '&ajax=1',
|
||||
beforeSend: function(xhr) {
|
||||
form
|
||||
.addClass(SN.C.S.Processing)
|
||||
.find('.submit')
|
||||
.addClass(SN.C.S.Disabled)
|
||||
.attr(SN.C.S.Disabled, SN.C.S.Disabled);
|
||||
},
|
||||
error: function (xhr, textStatus, errorThrown) {
|
||||
alert(errorThrown || textStatus);
|
||||
},
|
||||
success: function(data, textStatus) {
|
||||
var results_placeholder = $('#profile_search_results');
|
||||
if (typeof($('ul', data)[0]) != 'undefined') {
|
||||
var list = document._importNode($('ul', data)[0], true);
|
||||
results_placeholder.replaceWith(list);
|
||||
}
|
||||
else {
|
||||
var _error = $('<li/>').append(document._importNode($('p', data)[0], true));
|
||||
results_placeholder.html(_error);
|
||||
}
|
||||
form
|
||||
.removeClass(SN.C.S.Processing)
|
||||
.find('.submit')
|
||||
.removeClass(SN.C.S.Disabled)
|
||||
.attr(SN.C.S.Disabled, false);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
FormPeopletagsXHR: function(form) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
dataType: 'xml',
|
||||
url: form.attr('action'),
|
||||
data: form.serialize() + '&ajax=1',
|
||||
beforeSend: function(xhr) {
|
||||
form.addClass(SN.C.S.Processing)
|
||||
.find('.submit')
|
||||
.addClass(SN.C.S.Disabled)
|
||||
.attr(SN.C.S.Disabled, SN.C.S.Disabled);
|
||||
},
|
||||
error: function (xhr, textStatus, errorThrown) {
|
||||
alert(errorThrown || textStatus);
|
||||
},
|
||||
success: function(data, textStatus) {
|
||||
var results_placeholder = form.parents('.entity_tags');
|
||||
if (typeof($('.entity_tags', data)[0]) != 'undefined') {
|
||||
var tags = document._importNode($('.entity_tags', data)[0], true);
|
||||
$(tags).find('.editable').append($('<button class="peopletags_edit_button"/>'));
|
||||
results_placeholder.replaceWith(tags);
|
||||
} else {
|
||||
results_placeholder.find('p').remove();
|
||||
results_placeholder.append(document._importNode($('p', data)[0], true));
|
||||
form.removeClass(SN.C.S.Processing)
|
||||
.find('.submit')
|
||||
.removeClass(SN.C.S.Disabled)
|
||||
.attr(SN.C.S.Disabled, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
normalizeGeoData: function(form) {
|
||||
SN.C.I.NoticeDataGeo.NLat = form.find('[name=lat]').val();
|
||||
SN.C.I.NoticeDataGeo.NLon = form.find('[name=lon]').val();
|
||||
@ -479,6 +547,7 @@ var SN = { // StatusNet
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch an XML DOM from an XHR's response data.
|
||||
*
|
||||
@ -1326,11 +1395,23 @@ var SN = { // StatusNet
|
||||
$('.form_group_join').live('click', function() { SN.U.FormXHR($(this)); return false; });
|
||||
$('.form_group_leave').live('click', function() { SN.U.FormXHR($(this)); return false; });
|
||||
$('.form_user_nudge').live('click', function() { SN.U.FormXHR($(this)); return false; });
|
||||
$('.form_peopletag_subscribe').live('click', function() { SN.U.FormXHR($(this)); return false; });
|
||||
$('.form_peopletag_unsubscribe').live('click', function() { SN.U.FormXHR($(this)); return false; });
|
||||
$('.form_user_add_peopletag').live('click', function() { SN.U.FormXHR($(this)); return false; });
|
||||
$('.form_user_remove_peopletag').live('click', function() { SN.U.FormXHR($(this)); return false; });
|
||||
|
||||
SN.U.NewDirectMessage();
|
||||
}
|
||||
},
|
||||
|
||||
ProfileSearch: function() {
|
||||
if ($('body.user_in').length > 0) {
|
||||
$('.form_peopletag_edit_user_search input.submit').live('click', function() {
|
||||
SN.U.FormProfileSearchXHR($(this).parents('form')); return false;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Run setup code for login form:
|
||||
*
|
||||
@ -1353,6 +1434,45 @@ var SN = { // StatusNet
|
||||
});
|
||||
},
|
||||
|
||||
PeopletagAutocomplete: function() {
|
||||
$('.form_tag_user #tags').tagInput({
|
||||
tags: SN.C.PtagACData,
|
||||
tagSeparator: " ",
|
||||
animate: false,
|
||||
formatLine: function (i, e, search, matches) {
|
||||
var tag = "<b>" + e.tag.substring(0, search.length) + "</b>" + e.tag.substring(search.length);
|
||||
|
||||
var line = $("<div/>").addClass('mode-' + e.mode);
|
||||
line.append($("<div class='tagInputLineTag'>" + tag
|
||||
+ " <em class='privacy_mode'>" + e.mode + "</em></div>"));
|
||||
if (e.freq)
|
||||
line.append("<div class='tagInputLineFreq'>" + e.freq + "</div>");
|
||||
return line;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
PeopleTags: function() {
|
||||
$('.user_profile_tags .editable').append($('<button class="peopletags_edit_button"/>'));
|
||||
|
||||
$('.peopletags_edit_button').live('click', function() {
|
||||
var form = $(this).parents('dd').eq(0).find('form');
|
||||
// We can buy time from the above animation
|
||||
if (typeof SN.C.PtagACData === 'undefined') {
|
||||
$.getJSON(_peopletagAC + '?token=' + $('#token').val(), function(data) {
|
||||
SN.C.PtagACData = data;
|
||||
_loadTagInput(SN.Init.PeopletagAutocomplete);
|
||||
});
|
||||
} else { _loadTagInput(SN.Init.PeopletagAutocomplete); }
|
||||
|
||||
$(this).parents('ul').eq(0).fadeOut(200, function() {form.fadeIn(200).find('input#tags')});
|
||||
})
|
||||
|
||||
$('.user_profile_tags form .submit').live('click', function() {
|
||||
SN.U.FormPeopletagsXHR($(this).parents('form')); return false;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Add logic to any file upload forms to handle file size limits,
|
||||
* on browsers that support basic FileAPI.
|
||||
@ -1402,4 +1522,10 @@ $(document).ready(function(){
|
||||
if ($('#form_login').length > 0) {
|
||||
SN.Init.Login();
|
||||
}
|
||||
if ($('#profile_search_results').length > 0) {
|
||||
SN.Init.ProfileSearch();
|
||||
}
|
||||
if ($('.user_profile_tags .editable').length > 0) {
|
||||
SN.Init.PeopleTags();
|
||||
}
|
||||
});
|
||||
|
2
js/util.min.js
vendored
2
js/util.min.js
vendored
File diff suppressed because one or more lines are too long
@ -218,7 +218,7 @@ font-weight:bold;
|
||||
#form_settings_avatar legend,
|
||||
#newgroup legend,
|
||||
#editgroup legend,
|
||||
#form_tag_user legend,
|
||||
.form_tag_user legend,
|
||||
#form_remote_subscribe legend,
|
||||
#form_openid_login legend,
|
||||
#form_search legend,
|
||||
@ -228,10 +228,22 @@ font-weight:bold;
|
||||
#form_password_change legend,
|
||||
.form_entity_block legend,
|
||||
#form_filter_bytag legend,
|
||||
#apioauthauthorize_allowdeny {
|
||||
#apioauthauthorize_allowdeny,
|
||||
.form_tag_user_wrap form,
|
||||
.form_tag_user_wrap label,
|
||||
.form_tag_user_wrap legend {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.form_tag_user_wrap {
|
||||
clear:both;
|
||||
}
|
||||
.form_tag_user {
|
||||
float:left;
|
||||
width:auto;
|
||||
}
|
||||
.form_tag_user input.submit {
|
||||
width:50px;
|
||||
}
|
||||
.form_settings .form_data p.form_guide {
|
||||
clear:both;
|
||||
margin-left:26%;
|
||||
@ -707,7 +719,7 @@ min-height:123px;
|
||||
float:left;
|
||||
margin-bottom:18px;
|
||||
margin-left:0;
|
||||
overflow:hidden;
|
||||
overflow:visible;
|
||||
}
|
||||
.entity_profile dt,
|
||||
#entity_statistics dt {
|
||||
@ -735,6 +747,17 @@ margin-bottom:18px;
|
||||
margin-left:113px;
|
||||
margin-bottom:4px;
|
||||
}
|
||||
.entity_tags p.error {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.peopletags_edit_button {
|
||||
cursor:pointer;
|
||||
border:0;
|
||||
padding:0;
|
||||
width:16px;
|
||||
height:16px;
|
||||
}
|
||||
|
||||
.entity_profile .entity_fn,
|
||||
.entity_profile .entity_nickname {
|
||||
@ -775,7 +798,6 @@ font-style:italic;
|
||||
.entity_actions {
|
||||
float:right;
|
||||
margin-left:2%;
|
||||
margin-bottom:18px;
|
||||
min-width:21%;
|
||||
}
|
||||
.entity_actions h2 {
|
||||
@ -964,13 +986,89 @@ min-height:60px;
|
||||
.profile .form_group_join legend,
|
||||
.profile .form_group_leave legend,
|
||||
.profile .form_user_subscribe legend,
|
||||
.profile .form_user_unsubscribe legend {
|
||||
.profile .form_user_unsubscribe legend,
|
||||
.form_user_add_peopletag legend,
|
||||
.form_user_remove_peopletag legend {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.profile_search_wrap h3 {
|
||||
float:left;
|
||||
font-weight:normal;
|
||||
margin-right:10px;
|
||||
}
|
||||
.profiles {
|
||||
list-style-type:none;
|
||||
}
|
||||
.peopletag .entry-content {
|
||||
width:auto;
|
||||
}
|
||||
.peopletag .tagged-count a:after,
|
||||
.peopletag .subscriber-count a:after {
|
||||
content: ':';
|
||||
}
|
||||
.peopletag .updated {
|
||||
display:none;
|
||||
}
|
||||
.peopletag .tag a{
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
.peopletag .tag:before {
|
||||
/* raquo */
|
||||
content: "\00BB";
|
||||
}
|
||||
.peopletag .entity_statistics {
|
||||
font-size:80%;
|
||||
}
|
||||
.peopletag .entity_statistics a {
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.profile-lister {
|
||||
list-style-type:none;
|
||||
}
|
||||
.profile-lister li {
|
||||
min-height:30px;
|
||||
padding:5px;
|
||||
clear:both;
|
||||
}
|
||||
.profile-lister li a {
|
||||
text-decoration:none;
|
||||
}
|
||||
.profile-lister li .photo {
|
||||
display:inline;
|
||||
margin-right:7px;
|
||||
margin-bottom:-5px;
|
||||
}
|
||||
.profile-lister li .fn {
|
||||
font-weight:bold;
|
||||
}
|
||||
#profile_search_results {
|
||||
border-radius:4px;
|
||||
-moz-border-radius:4px;
|
||||
-webkit-border-radius:4px;
|
||||
}
|
||||
.form_peopletag_edit_user_search legend,
|
||||
.form_peopletag_edit_user_search label,
|
||||
.form_peopletag_edit_user_search .form_guide {
|
||||
display:none;
|
||||
}
|
||||
.form_peopletag_edit_user_search #field {
|
||||
height:30px;
|
||||
}
|
||||
.form_peopletag_edit_user_search .submit {
|
||||
width:60px;
|
||||
}
|
||||
.form_user_remove_peopletag,
|
||||
.form_user_add_peopletag {
|
||||
float:right;
|
||||
}
|
||||
.form_user_add_peopletag input.submit,
|
||||
.form_user_remove_peopletag input.submit {
|
||||
width:100px;
|
||||
padding-left:25px;
|
||||
text-align:left;
|
||||
}
|
||||
.profile .entity_profile .fn.nickname,
|
||||
.profile .entity_profile .url[rel~=contact] {
|
||||
margin-left:0;
|
||||
@ -990,15 +1088,19 @@ clear:none;
|
||||
.profile .entity_profile .entity_tags,
|
||||
.profile .entity_profile .form_subscription_edit {
|
||||
margin-left:59px;
|
||||
margin-bottom:7px;
|
||||
clear:none;
|
||||
display:block;
|
||||
width:auto;
|
||||
}
|
||||
.profile .entity_profile .entity_tags dt {
|
||||
.entity_profile .entity_tags dt {
|
||||
display:inline;
|
||||
float:left;
|
||||
margin-right:11px;
|
||||
}
|
||||
|
||||
.profile .entity_profile .form_subscription_edit {
|
||||
clear:left;
|
||||
}
|
||||
.profile .entity_profile .form_subscription_edit label {
|
||||
font-weight:normal;
|
||||
margin-right:11px;
|
||||
@ -1083,7 +1185,8 @@ width:14.5%;
|
||||
/* NOTICE */
|
||||
.notice,
|
||||
.profile,
|
||||
.application {
|
||||
.application,
|
||||
#content .peopletag {
|
||||
position:relative;
|
||||
padding-top:11px;
|
||||
padding-bottom:11px;
|
||||
@ -1351,7 +1454,8 @@ margin-left:0;
|
||||
}
|
||||
.notice-options input,
|
||||
.notice-options a,
|
||||
.notice-options .repeated {
|
||||
.notice-options .repeated,
|
||||
.peopletags_edit_button {
|
||||
text-indent:-9999px;
|
||||
outline:none;
|
||||
}
|
||||
@ -1395,7 +1499,8 @@ height:16px;
|
||||
position:relative;
|
||||
padding-left:16px;
|
||||
}
|
||||
.notice .attachment.more {
|
||||
.notice .attachment.more,
|
||||
.mode-private .privacy_mode {
|
||||
text-indent:-9999px;
|
||||
width:16px;
|
||||
height:16px;
|
||||
@ -1508,16 +1613,22 @@ padding-left:7px;
|
||||
border-left-width:1px;
|
||||
border-left-style:solid;
|
||||
}
|
||||
#filter_tags #filter_tags_all {
|
||||
#filter_tags #filter_tags_all,
|
||||
#filter_tags #filter_tags_for {
|
||||
margin-left:0;
|
||||
border-left:0;
|
||||
padding-left:0;
|
||||
}
|
||||
#filter_tags_all a {
|
||||
#filter_tags_all a,
|
||||
#filter_tags_for a {
|
||||
text-decoration:none;
|
||||
font-weight:bold;
|
||||
margin-top:7px;
|
||||
float:left;
|
||||
}
|
||||
#filter_tags_for a {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#filter_tags_item label {
|
||||
margin-right:7px;
|
||||
@ -1536,6 +1647,15 @@ position:relative;
|
||||
top:3px;
|
||||
left:3px;
|
||||
}
|
||||
#filter_tags #form_filter_bymode .form_guide {
|
||||
display:none;
|
||||
}
|
||||
#filter_tags #form_filter_bymode .checkbox {
|
||||
float:none;
|
||||
}
|
||||
#filter_tags #form_filter_bymode legend {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
float:left;
|
||||
@ -1791,6 +1911,33 @@ width:auto;
|
||||
min-width:0;
|
||||
}
|
||||
|
||||
/* tag autocomplete */
|
||||
|
||||
.tagInputDiv {
|
||||
display: none;
|
||||
position: absolute;
|
||||
overflow: auto;
|
||||
margin-top:-1px;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.tagInputLine {
|
||||
font-weight: normal;
|
||||
padding:4px;
|
||||
}
|
||||
|
||||
.tagInputLineTag {
|
||||
min-width: 150px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tagInputLineFreq {
|
||||
min-width: 50px;
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
float:right;
|
||||
}
|
||||
|
||||
.inline-attachment img {
|
||||
/* Why on earth is this changed to block at the top? */
|
||||
display: inline;
|
||||
|
@ -136,6 +136,7 @@ color:#002FA7;
|
||||
.notice,
|
||||
.profile,
|
||||
.application,
|
||||
.peopletag,
|
||||
#content tbody tr {
|
||||
border-top-color:#C8D1D5;
|
||||
}
|
||||
@ -186,8 +187,13 @@ button.close,
|
||||
.form_user_unsubscribe input.submit,
|
||||
.form_group_join input.submit,
|
||||
.form_user_subscribe input.submit,
|
||||
.form_user_remove_peopletag input.submit,
|
||||
.form_user_add_peopletag input.submit,
|
||||
.form_peopletag_subscribe input.submit,
|
||||
.form_peopletag_unsubscribe input.submit,
|
||||
.form_remote_authorize input.submit,
|
||||
.entity_subscribe a,
|
||||
.entity_tag a,
|
||||
.entity_moderation p,
|
||||
.entity_sandbox input.submit,
|
||||
.entity_silence input.submit,
|
||||
@ -205,7 +211,9 @@ button.minimize,
|
||||
.entity_subscribe input.submit,
|
||||
#realtime_play,
|
||||
#realtime_pause,
|
||||
#realtime_popup {
|
||||
#realtime_popup,
|
||||
.peopletags_edit_button,
|
||||
.mode-private .privacy_mode {
|
||||
background-image:url(../../base/images/icons/icons-01.gif);
|
||||
background-repeat:no-repeat;
|
||||
background-color:transparent;
|
||||
@ -300,33 +308,66 @@ background-position:0 1px;
|
||||
.form_group_join input.submit,
|
||||
.form_group_leave input.submit,
|
||||
.form_user_subscribe input.submit,
|
||||
.form_peopletag_subscribe input.submit,
|
||||
.form_peopletag_unsubscribe input.submit,
|
||||
.form_user_unsubscribe input.submit,
|
||||
.form_remote_authorize input.submit,
|
||||
.form_user_add_peopletag input.submit,
|
||||
.form_user_remove_peopletag input.submit,
|
||||
.entity_subscribe a {
|
||||
background-color:#AAAAAA;
|
||||
color:#FFFFFF;
|
||||
}
|
||||
.form_group_leave input.submit,
|
||||
.form_user_unsubscribe input.submit {
|
||||
.form_user_unsubscribe input.submit,
|
||||
.form_user_remove_peopletag input.submit,
|
||||
.form_peopletag_unsubscribe input.submit {
|
||||
background-position:5px -1246px;
|
||||
}
|
||||
.form_group_join input.submit,
|
||||
.form_user_subscribe input.submit,
|
||||
.form_peopletag_subscribe input.submit,
|
||||
.form_remote_authorize input.submit,
|
||||
.entity_subscribe a {
|
||||
.form_user_add_peopletag input.submit,
|
||||
.entity_subscribe a,
|
||||
.entity_tag a {
|
||||
background-position:5px -1181px;
|
||||
}
|
||||
|
||||
.entity_edit a {
|
||||
.profile-lister li {
|
||||
border-top: 1px #eee solid;
|
||||
}
|
||||
.profile-lister li:first-child {
|
||||
border:0;
|
||||
}
|
||||
#profile_search_results.profile-lister {
|
||||
max-height:800px;
|
||||
margin:10px 0;
|
||||
border:1px #ddd solid;
|
||||
}
|
||||
|
||||
.entity_edit a, .peopletags_edit_button {
|
||||
background-position: 5px -719px;
|
||||
}
|
||||
|
||||
.peopletags_edit_button {
|
||||
background-position: 0px -724px;
|
||||
}
|
||||
.entity_tags li.mode-private {
|
||||
color: #829D25;
|
||||
}
|
||||
.mode-private .privacy_mode {
|
||||
background-position: 0px -1978px;
|
||||
}
|
||||
|
||||
.entity_send-a-message a {
|
||||
background-position: 5px -852px;
|
||||
}
|
||||
.entity_send-a-message .form_notice,
|
||||
.entity_moderation:hover ul,
|
||||
.entity_role:hover ul,
|
||||
.dialogbox {
|
||||
.dialogbox,
|
||||
#profile_search_results {
|
||||
box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7);
|
||||
-moz-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7);
|
||||
-webkit-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7);
|
||||
@ -515,4 +556,18 @@ background-position:90% 47%;
|
||||
background-position:10% 47%;
|
||||
}
|
||||
|
||||
.tagInputDiv {
|
||||
background-color: white;
|
||||
border: 1px solid lightgray;
|
||||
}
|
||||
|
||||
.tagInputDiv .mode-public .privacy_mode {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.tagInputSel {
|
||||
background-color: gray;
|
||||
color:white;
|
||||
}
|
||||
|
||||
}/*end of @media screen, projection, tv*/
|
||||
|
Loading…
Reference in New Issue
Block a user