diff --git a/js/jquery.tagInput.js b/js/jquery.tagInput.js
new file mode 100644
index 0000000000..8ed4058fb2
--- /dev/null
+++ b/js/jquery.tagInput.js
@@ -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 = "" + tag.substring(0, search.length) + "" + tag.substring(search.length);
+ }
+
+ var line = $("
");
+ line.append("
" + tag + "
");
+ if (obj.freq)
+ line.append("
" + obj.freq + "
");
+ 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=$("
suggested tags:
");
+ suggestedTagsPlaceHolder=stl.find(".tagInputSuggestedTagList");
+ theInput.after(stl);
+ }
+
+ //fill with suggestions
+ for (var tag in options.suggestedTags) {
+ suggestedTagsPlaceHolder.append($("" + options.suggestedTags[tag] + ""));
+ }
+
+ // 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 = $("");
+ 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 = $("").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;
+};
+
+
diff --git a/js/jquery.timers.js b/js/jquery.timers.js
new file mode 100644
index 0000000000..bb51157d40
--- /dev/null
+++ b/js/jquery.timers.js
@@ -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);
+ });
+});
diff --git a/js/util.js b/js/util.js
index cc94c5ced7..84943e8b24 100644
--- a/js/util.js
+++ b/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 = $('').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($(''));
+ 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 = "" + e.tag.substring(0, search.length) + "" + e.tag.substring(search.length);
+
+ var line = $("").addClass('mode-' + e.mode);
+ line.append($("
" + tag
+ + " " + e.mode + "
"));
+ if (e.freq)
+ line.append("
" + e.freq + "
");
+ return line;
+ }
+ });
+ },
+
+ PeopleTags: function() {
+ $('.user_profile_tags .editable').append($(''));
+
+ $('.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();
+ }
});
diff --git a/js/util.min.js b/js/util.min.js
index 280aca6a45..a31d366d7b 100644
--- a/js/util.min.js
+++ b/js/util.min.js
@@ -1 +1 @@
-var SN={C:{I:{CounterBlackout:false,MaxLength:140,PatternUsername:/^[0-9a-zA-Z\-_.]*$/,HTTP20x30x:[200,201,202,203,204,205,206,300,301,302,303,304,305,306,307]},S:{Disabled:"disabled",Warning:"warning",Error:"error",Success:"success",Processing:"processing",CommandResult:"command_result",FormNotice:"form_notice",NoticeDataGeo:"notice_data-geo",NoticeDataGeoCookie:"NoticeDataGeo",NoticeDataGeoSelected:"notice_data-geo_selected",StatusNetInstance:"StatusNetInstance"}},messages:{},msg:function(a){if(typeof SN.messages[a]=="undefined"){return"["+a+"]"}else{return SN.messages[a]}},U:{FormNoticeEnhancements:function(b){if(jQuery.data(b[0],"ElementData")===undefined){MaxLength=b.find(".count").text();if(typeof(MaxLength)=="undefined"){MaxLength=SN.C.I.MaxLength}jQuery.data(b[0],"ElementData",{MaxLength:MaxLength});SN.U.Counter(b);NDT=b.find("[name=status_textarea]");NDT.bind("keyup",function(c){SN.U.Counter(b)});var a=function(c){window.setTimeout(function(){SN.U.Counter(b)},50)};NDT.bind("cut",a).bind("paste",a)}else{b.find(".count").text(jQuery.data(b[0],"ElementData").MaxLength)}},Counter:function(d){SN.C.I.FormNoticeCurrent=d;var b=jQuery.data(d[0],"ElementData").MaxLength;if(b<=0){return}var c=b-SN.U.CharacterCount(d);var a=d.find(".count");if(c.toString()!=a.text()){if(!SN.C.I.CounterBlackout||c===0){if(a.text()!=String(c)){a.text(c)}if(c<0){d.addClass(SN.C.S.Warning)}else{d.removeClass(SN.C.S.Warning)}if(!SN.C.I.CounterBlackout){SN.C.I.CounterBlackout=true;SN.C.I.FormNoticeCurrent=d;window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);",500)}}}},CharacterCount:function(a){return a.find("[name=status_textarea]").val().length},ClearCounterBlackout:function(a){SN.C.I.CounterBlackout=false;SN.U.Counter(a)},RewriteAjaxAction:function(a){if(document.location.protocol=="https:"&&a.substr(0,5)=="http:"){return a.replace(/^http:\/\/[^:\/]+/,"https://"+document.location.host)}else{return a}},FormXHR:function(a){$.ajax({type:"POST",dataType:"xml",url:SN.U.RewriteAjaxAction(a.attr("action")),data:a.serialize()+"&ajax=1",beforeSend:function(b){a.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled)},error:function(c,d,b){alert(b||d)},success:function(b,c){if(typeof($("form",b)[0])!="undefined"){form_new=document._importNode($("form",b)[0],true);a.replaceWith(form_new)}else{a.replaceWith(document._importNode($("p",b)[0],true))}}})},FormNoticeXHR:function(b){SN.C.I.NoticeDataGeo={};b.append('');b.attr("action",SN.U.RewriteAjaxAction(b.attr("action")));var c=function(d,e){b.append($('').addClass(d).text(e))};var a=function(){b.find(".form_response").remove()};b.ajaxForm({dataType:"xml",timeout:"60000",beforeSend:function(d){if(b.find("[name=status_textarea]").val()==""){b.addClass(SN.C.S.Warning);return false}b.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled);SN.U.normalizeGeoData(b);return true},error:function(f,g,e){b.removeClass(SN.C.S.Processing).find(".submit").removeClass(SN.C.S.Disabled).removeAttr(SN.C.S.Disabled,SN.C.S.Disabled);a();if(g=="timeout"){c("error","Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.")}else{var d=SN.U.GetResponseXML(f);if($("."+SN.C.S.Error,d).length>0){b.append(document._importNode($("."+SN.C.S.Error,d)[0],true))}else{if(parseInt(f.status)===0||jQuery.inArray(parseInt(f.status),SN.C.I.HTTP20x30x)>=0){b.resetForm().find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}else{c("error","(Sorry! We had trouble sending your notice ("+f.status+" "+f.statusText+"). Please report the problem to the site administrator if this happens again.")}}}},success:function(i,f){a();var n=$("#"+SN.C.S.Error,i);if(n.length>0){c("error",n.text())}else{if($("body")[0].id=="bookmarklet"){self.close()}var d=$("#"+SN.C.S.CommandResult,i);if(d.length>0){c("success",d.text())}else{var m=document._importNode($("li",i)[0],true);var k=$("#notices_primary .notices:first");var l=b.closest("li.notice-reply");if(l.length>0){var e=$(m).attr("id");if($("#"+e).length==0){var j=l.closest("li.notice");l.replaceWith(m);SN.U.NoticeInlineReplyPlaceholder(j)}else{l.remove()}}else{if(k.length>0&&SN.U.belongsOnTimeline(m)){if($("#"+m.id).length===0){var h=b.find("[name=inreplyto]").val();var g="#notices_primary #notice-"+h;if($("body")[0].id=="conversation"){if(h.length>0&&$(g+" .notices").length<1){$(g).append('
');h.find("button.close").click(function(){e.find("[name=notice_data-geo]").removeAttr("checked").change()});e.append(h)}var b;if(c){b=$("").attr("href",c)}else{b=$("")}b.text(a);if(f||g){var d=f+";"+g;b.attr("title",d);if(!a){b.text(d)}}h.find(".geo_status").empty().append(b)},NewDirectMessage:function(){NDM=$(".entity_send-a-message a");NDM.attr({href:NDM.attr("href")+"&ajax=1"});NDM.bind("click",function(){var a=$(".entity_send-a-message form");if(a.length===0){$(this).addClass(SN.C.S.Processing);$.get(NDM.attr("href"),null,function(b){$(".entity_send-a-message").append(document._importNode($("form",b)[0],true));a=$(".entity_send-a-message .form_notice");SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);a.append('');$(".entity_send-a-message button").click(function(){a.hide();return false});NDM.removeClass(SN.C.S.Processing)})}else{a.show();$(".entity_send-a-message textarea").focus()}return false})},GetFullYear:function(c,d,a){var b=new Date();b.setFullYear(c,d,a);return b},StatusNetInstance:{Set:function(b){var a=SN.U.StatusNetInstance.Get();if(a!==null){b=$.extend(a,b)}$.cookie(SN.C.S.StatusNetInstance,JSON.stringify(b),{path:"/",expires:SN.U.GetFullYear(2029,0,1)})},Get:function(){var a=$.cookie(SN.C.S.StatusNetInstance);if(a!==null){return JSON.parse(a)}return null},Delete:function(){$.cookie(SN.C.S.StatusNetInstance,null)}},belongsOnTimeline:function(b){var a=$("body").attr("id");if(a=="public"){return true}var c=$("#nav_profile a").attr("href");if(c){var d=$(b).find(".entry-title .author a.url").attr("href");if(d==c){if(a=="all"||a=="showstream"){return true}}}return false}},Init:{NoticeForm:function(){if($("body.user_in").length>0){$("."+SN.C.S.FormNotice).each(function(){var a=$(this);SN.U.NoticeLocationAttach(a);SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);SN.U.NoticeDataAttach(a)})}},Notices:function(){if($("body.user_in").length>0){SN.U.NoticeFavor();SN.U.NoticeRepeat();SN.U.NoticeReply();SN.U.NoticeInlineReplySetup()}SN.U.NoticeAttachments()},EntityActions:function(){if($("body.user_in").length>0){$(".form_user_subscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_unsubscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".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});SN.U.NewDirectMessage()}},Login:function(){if(SN.U.StatusNetInstance.Get()!==null){var a=SN.U.StatusNetInstance.Get().Nickname;if(a!==null){$("#form_login #nickname").val(a)}}$("#form_login").bind("submit",function(){SN.U.StatusNetInstance.Set({Nickname:$("#form_login #nickname").val()});return true})},UploadForms:function(){$("input[type=file]").change(function(d){if(typeof this.files=="object"&&this.files.length>0){var c=0;for(var b=0;b0&&c>a){var e="File too large: maximum upload size is %d bytes.";alert(e.replace("%d",a));$(this).val("");d.preventDefault();return false}}})}}};$(document).ready(function(){SN.Init.UploadForms();if($("."+SN.C.S.FormNotice).length>0){SN.Init.NoticeForm()}if($("#content .notices").length>0){SN.Init.Notices()}if($("#content .entity_actions").length>0){SN.Init.EntityActions()}if($("#form_login").length>0){SN.Init.Login()}});if(!document.ELEMENT_NODE){document.ELEMENT_NODE=1;document.ATTRIBUTE_NODE=2;document.TEXT_NODE=3;document.CDATA_SECTION_NODE=4;document.ENTITY_REFERENCE_NODE=5;document.ENTITY_NODE=6;document.PROCESSING_INSTRUCTION_NODE=7;document.COMMENT_NODE=8;document.DOCUMENT_NODE=9;document.DOCUMENT_TYPE_NODE=10;document.DOCUMENT_FRAGMENT_NODE=11;document.NOTATION_NODE=12}document._importNode=function(e,a){switch(e.nodeType){case document.ELEMENT_NODE:var d=document.createElement(e.nodeName);if(e.attributes&&e.attributes.length>0){for(var c=0,b=e.attributes.length;c0){for(var c=0,b=e.childNodes.length;c0){var j=c.pop();j()}}};window._google_loader_apiLoaded=function(){f()};var d=function(){return(window.google&&google.loader)};var g=function(j){if(d()){return true}h(j);e();return false};e();return{shim:true,type:"ClientLocation",lastPosition:null,getCurrentPosition:function(k,n,o){var m=this;if(!g(function(){m.getCurrentPosition(k,n,o)})){return}if(google.loader.ClientLocation){var l=google.loader.ClientLocation;var j={coords:{latitude:l.latitude,longitude:l.longitude,altitude:null,accuracy:43000,altitudeAccuracy:null,heading:null,speed:null},address:{city:l.address.city,country:l.address.country,country_code:l.address.country_code,region:l.address.region},timestamp:new Date()};k(j);this.lastPosition=j}else{if(n==="function"){n({code:3,message:"Using the Google ClientLocation API and it is not able to calculate a location."})}}},watchPosition:function(j,l,m){this.getCurrentPosition(j,l,m);var k=this;var n=setInterval(function(){k.getCurrentPosition(j,l,m)},10000);return n},clearWatch:function(j){clearInterval(j)},getPermission:function(l,j,k){return true}}});navigator.geolocation=(window.google&&google.gears)?a():b()})()};
\ No newline at end of file
+var SN={C:{I:{CounterBlackout:false,MaxLength:140,PatternUsername:/^[0-9a-zA-Z\-_.]*$/,HTTP20x30x:[200,201,202,203,204,205,206,300,301,302,303,304,305,306,307]},S:{Disabled:"disabled",Warning:"warning",Error:"error",Success:"success",Processing:"processing",CommandResult:"command_result",FormNotice:"form_notice",NoticeDataGeo:"notice_data-geo",NoticeDataGeoCookie:"NoticeDataGeo",NoticeDataGeoSelected:"notice_data-geo_selected",StatusNetInstance:"StatusNetInstance"}},messages:{},msg:function(a){if(typeof SN.messages[a]=="undefined"){return"["+a+"]"}else{return SN.messages[a]}},U:{FormNoticeEnhancements:function(b){if(jQuery.data(b[0],"ElementData")===undefined){MaxLength=b.find(".count").text();if(typeof(MaxLength)=="undefined"){MaxLength=SN.C.I.MaxLength}jQuery.data(b[0],"ElementData",{MaxLength:MaxLength});SN.U.Counter(b);NDT=b.find("[name=status_textarea]");NDT.bind("keyup",function(c){SN.U.Counter(b)});var a=function(c){window.setTimeout(function(){SN.U.Counter(b)},50)};NDT.bind("cut",a).bind("paste",a)}else{b.find(".count").text(jQuery.data(b[0],"ElementData").MaxLength)}},Counter:function(d){SN.C.I.FormNoticeCurrent=d;var b=jQuery.data(d[0],"ElementData").MaxLength;if(b<=0){return}var c=b-SN.U.CharacterCount(d);var a=d.find(".count");if(c.toString()!=a.text()){if(!SN.C.I.CounterBlackout||c===0){if(a.text()!=String(c)){a.text(c)}if(c<0){d.addClass(SN.C.S.Warning)}else{d.removeClass(SN.C.S.Warning)}if(!SN.C.I.CounterBlackout){SN.C.I.CounterBlackout=true;SN.C.I.FormNoticeCurrent=d;window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);",500)}}}},CharacterCount:function(a){return a.find("[name=status_textarea]").val().length},ClearCounterBlackout:function(a){SN.C.I.CounterBlackout=false;SN.U.Counter(a)},RewriteAjaxAction:function(a){if(document.location.protocol=="https:"&&a.substr(0,5)=="http:"){return a.replace(/^http:\/\/[^:\/]+/,"https://"+document.location.host)}else{return a}},FormXHR:function(a){$.ajax({type:"POST",dataType:"xml",url:SN.U.RewriteAjaxAction(a.attr("action")),data:a.serialize()+"&ajax=1",beforeSend:function(b){a.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled)},error:function(c,d,b){alert(b||d)},success:function(b,c){if(typeof($("form",b)[0])!="undefined"){form_new=document._importNode($("form",b)[0],true);a.replaceWith(form_new)}else{a.replaceWith(document._importNode($("p",b)[0],true))}}})},FormNoticeXHR:function(b){SN.C.I.NoticeDataGeo={};b.append('');b.attr("action",SN.U.RewriteAjaxAction(b.attr("action")));var c=function(d,e){b.append($('').addClass(d).text(e))};var a=function(){b.find(".form_response").remove()};b.ajaxForm({dataType:"xml",timeout:"60000",beforeSend:function(d){if(b.find("[name=status_textarea]").val()==""){b.addClass(SN.C.S.Warning);return false}b.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled);SN.U.normalizeGeoData(b);return true},error:function(f,g,e){b.removeClass(SN.C.S.Processing).find(".submit").removeClass(SN.C.S.Disabled).removeAttr(SN.C.S.Disabled,SN.C.S.Disabled);a();if(g=="timeout"){c("error","Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.")}else{var d=SN.U.GetResponseXML(f);if($("."+SN.C.S.Error,d).length>0){b.append(document._importNode($("."+SN.C.S.Error,d)[0],true))}else{if(parseInt(f.status)===0||jQuery.inArray(parseInt(f.status),SN.C.I.HTTP20x30x)>=0){b.resetForm().find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}else{c("error","(Sorry! We had trouble sending your notice ("+f.status+" "+f.statusText+"). Please report the problem to the site administrator if this happens again.")}}}},success:function(i,f){a();var n=$("#"+SN.C.S.Error,i);if(n.length>0){c("error",n.text())}else{if($("body")[0].id=="bookmarklet"){self.close()}var d=$("#"+SN.C.S.CommandResult,i);if(d.length>0){c("success",d.text())}else{var m=document._importNode($("li",i)[0],true);var k=$("#notices_primary .notices:first");var l=b.closest("li.notice-reply");if(l.length>0){var e=$(m).attr("id");if($("#"+e).length==0){var j=l.closest("li.notice");l.replaceWith(m);SN.U.NoticeInlineReplyPlaceholder(j)}else{l.remove()}}else{if(k.length>0&&SN.U.belongsOnTimeline(m)){if($("#"+m.id).length===0){var h=b.find("[name=inreplyto]").val();var g="#notices_primary #notice-"+h;if($("body")[0].id=="conversation"){if(h.length>0&&$(g+" .notices").length<1){$(g).append('