diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/geometa.js | 216 | ||||
-rw-r--r-- | js/identica-badge.js | 163 | ||||
-rw-r--r-- | js/util.js | 752 |
3 files changed, 741 insertions, 390 deletions
diff --git a/js/geometa.js b/js/geometa.js new file mode 100644 index 000000000..ced5be060 --- /dev/null +++ b/js/geometa.js @@ -0,0 +1,216 @@ +// A shim to implement the W3C Geolocation API Specification using Gears or the Ajax API +if ( typeof navigator.geolocation == "undefined" || navigator.geolocation.shim ) (function(){ + +// -- BEGIN GEARS_INIT +(function() { + // We are already defined. Hooray! + if (window.google && google.gears) { + return; + } + + var factory = null; + + // Firefox + if (typeof GearsFactory != 'undefined') { + factory = new GearsFactory(); + } else { + // IE + try { + factory = new ActiveXObject('Gears.Factory'); + // privateSetGlobalObject is only required and supported on WinCE. + if (factory.getBuildInfo().indexOf('ie_mobile') != -1) { + factory.privateSetGlobalObject(this); + } + } catch (e) { + // Safari + if ((typeof navigator.mimeTypes != 'undefined') + && navigator.mimeTypes["application/x-googlegears"]) { + factory = document.createElement("object"); + factory.style.display = "none"; + factory.width = 0; + factory.height = 0; + factory.type = "application/x-googlegears"; + document.documentElement.appendChild(factory); + } + } + } + + // *Do not* define any objects if Gears is not installed. This mimics the + // behavior of Gears defining the objects in the future. + if (!factory) { + return; + } + + // Now set up the objects, being careful not to overwrite anything. + // + // Note: In Internet Explorer for Windows Mobile, you can't add properties to + // the window object. However, global objects are automatically added as + // properties of the window object in all browsers. + if (!window.google) { + google = {}; + } + + if (!google.gears) { + google.gears = {factory: factory}; + } +})(); +// -- END GEARS_INIT + +var GearsGeoLocation = (function() { + // -- PRIVATE + var geo = google.gears.factory.create('beta.geolocation'); + + var wrapSuccess = function(callback, self) { // wrap it for lastPosition love + return function(position) { + callback(position); + self.lastPosition = position; + } + } + + // -- PUBLIC + return { + shim: true, + + type: "Gears", + + lastPosition: null, + + getCurrentPosition: function(successCallback, errorCallback, options) { + var self = this; + var sc = wrapSuccess(successCallback, self); + geo.getCurrentPosition(sc, errorCallback, options); + }, + + watchPosition: function(successCallback, errorCallback, options) { + geo.watchPosition(successCallback, errorCallback, options); + }, + + clearWatch: function(watchId) { + geo.clearWatch(watchId); + }, + + getPermission: function(siteName, imageUrl, extraMessage) { + geo.getPermission(siteName, imageUrl, extraMessage); + } + + }; +})(); + +var AjaxGeoLocation = (function() { + // -- PRIVATE + var loading = false; + var loadGoogleLoader = function() { + if (!hasGoogleLoader() && !loading) { + loading = true; + var s = document.createElement('script'); + s.src = 'http://www.google.com/jsapi?callback=_google_loader_apiLoaded'; + s.type = "text/javascript"; + document.getElementsByTagName('body')[0].appendChild(s); + } + }; + + var queue = []; + var addLocationQueue = function(callback) { + queue.push(callback); + } + + var runLocationQueue = function() { + if (hasGoogleLoader()) { + while (queue.length > 0) { + var call = queue.pop(); + call(); + } + } + } + + window['_google_loader_apiLoaded'] = function() { + runLocationQueue(); + } + + var hasGoogleLoader = function() { + return (window['google'] && google['loader']); + } + + var checkGoogleLoader = function(callback) { + if (hasGoogleLoader()) return true; + + addLocationQueue(callback); + + loadGoogleLoader(); + + return false; + }; + + loadGoogleLoader(); // start to load as soon as possible just in case + + // -- PUBLIC + return { + shim: true, + + type: "ClientLocation", + + lastPosition: null, + + getCurrentPosition: function(successCallback, errorCallback, options) { + var self = this; + if (!checkGoogleLoader(function() { + self.getCurrentPosition(successCallback, errorCallback, options); + })) return; + + if (google.loader.ClientLocation) { + var cl = google.loader.ClientLocation; + + var position = { + latitude: cl.latitude, + longitude: cl.longitude, + altitude: null, + accuracy: 43000, // same as Gears accuracy over wifi? + altitudeAccuracy: null, + heading: null, + velocity: null, + timestamp: new Date(), + + // extra info that is outside of the bounds of the core API + address: { + city: cl.address.city, + country: cl.address.country, + country_code: cl.address.country_code, + region: cl.address.region + } + }; + + successCallback(position); + + this.lastPosition = position; + } else if (errorCallback === "function") { + errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."}); + } + }, + + watchPosition: function(successCallback, errorCallback, options) { + this.getCurrentPosition(successCallback, errorCallback, options); + + var self = this; + var watchId = setInterval(function() { + self.getCurrentPosition(successCallback, errorCallback, options); + }, 10000); + + return watchId; + }, + + clearWatch: function(watchId) { + clearInterval(watchId); + }, + + getPermission: function(siteName, imageUrl, extraMessage) { + // for now just say yes :) + return true; + } + + }; +})(); + +// If you have Gears installed use that, else use Ajax ClientLocation +navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation : AjaxGeoLocation; + +})(); diff --git a/js/identica-badge.js b/js/identica-badge.js index 49c42b70c..8276f22a1 100644 --- a/js/identica-badge.js +++ b/js/identica-badge.js @@ -1,8 +1,71 @@ // identica badge -- updated to work with the native API, 12-4-2008 // Modified to point to Identi.ca, 2-20-2009 by Zach +// Modified for XHTML, 27-9-2009 by Will Daniels +// (see http://willdaniels.co.uk/blog/tech-stuff/26-identica-badge-xhtml) // copyright Kent Brewster 2008 // see http://kentbrewster.com/identica-badge for info -( function() { + +function createHTMLElement(tagName) { + if(document.createElementNS) + var elem = document.createElementNS("http://www.w3.org/1999/xhtml", tagName); + else + var elem = document.createElement(tagName); + + return elem; +} + +function isNumeric(value) { + if (value == null || !value.toString().match(/^[-]?\d*\.?\d*$/)) return false; + return true; +} + +function markupPost(raw, server) { + var start = 0; var p = createHTMLElement('p'); + + raw.replace(/((http|https):\/\/|\!|@|#)(([\w_]+)?[^\s]*)/g, + function(sub, type, scheme, url, word, offset, full) + { + if(!scheme && !word) return; // just punctuation + var label = ''; var href = ''; + var pretext = full.substr(start, offset - start); + + moniker = word.split('_'); // behaviour with underscores differs + if(type == '#') moniker = moniker.join(''); + else word = moniker = moniker[0].toLowerCase(); + + switch(type) { + case 'http://': case 'https://': // html links + href = scheme + '://' + url; break; + case '@': // link users + href = 'http://' + server + '/' + moniker; break; + case '!': // link groups + href = 'http://' + server + '/group/' + moniker; break; + case '#': // link tags + href = 'http://' + server + '/tag/' + moniker; break; + default: // bad call (just reset position for text) + start = offset; + } + if(scheme) { // only urls will have scheme + label = sub; start = offset + sub.length; + } else { + label = word; pretext += type; + start = offset + word.length + type.length; + } + p.appendChild(document.createTextNode(pretext)); + + var link = createHTMLElement('a'); + link.appendChild(document.createTextNode(label)); + link.href = href; link.target = '_statusnet'; + p.appendChild(link); + }); + + if(start != raw.length) { + endtext = raw.substr(start); + p.appendChild(document.createTextNode(endtext)); + } + return p; +} +(function() { var trueName = ''; for (var i = 0; i < 16; i++) { trueName += String.fromCharCode(Math.floor(Math.random() * 26) + 97); @@ -13,7 +76,7 @@ return { runFunction : [], init : function(target) { - var theScripts = document.getElementsByTagName('SCRIPT'); + var theScripts = document.getElementsByTagName('script'); for (var i = 0; i < theScripts.length; i++) { if (theScripts[i].src.match(target)) { $.a = {}; @@ -66,9 +129,17 @@ "server" : "identi.ca" }; for (var k in $.d) { if ($.a[k] === undefined) { $.a[k] = $.d[k]; } } + // fix inout units + if(isNumeric($.a.width)) { + $.a.innerWidth = ($.a.width - 22) + 'px'; $.a.width += 'px'; + } else { + $.a.innerWidth = 'auto'; + } + if(isNumeric($.a.height)) $.a.height += 'px'; }, - buildPresentation : function () { - var ns = document.createElement('style'); + buildPresentation : function () { + var setZoom = ''; if(navigator.appName == 'Microsoft Internet Explorer') setZoom = 'zoom:1;'; + var ns = createHTMLElement('style'); document.getElementsByTagName('head')[0].appendChild(ns); if (!window.createPopup) { ns.appendChild(document.createTextNode('')); @@ -76,36 +147,37 @@ } var s = document.styleSheets[document.styleSheets.length - 1]; var rules = { - "" : "{zoom:1;margin:0;padding:0;width:" + $.a.width + "px;background:" + $.a.background + ";border:" + $.a.border + ";font:13px/1.2em tahoma, veranda, arial, helvetica, clean, sans-serif;*font-size:small;*font:x-small;}", + "" : "{margin:0px;padding:0px;width:" + $.a.width + ";background:" + $.a.background + ";border:" + $.a.border + ";font:87%/1.2em tahoma, veranda, arial, helvetica, clean, sans-serif;}", "a" : "{cursor:pointer;text-decoration:none;}", "a:hover" : "{text-decoration:underline;}", - "cite" : "{font-weight:bold;margin:0 0 0 4px;padding:0;display:block;font-style:normal;line-height:" + ($.a.thumbnailSize/2) + "px;}", - "cite a" : "{color:#C15D42;}", - "date":"{font-size:87%;margin:0 0 0 4px;padding:0;display:block;font-style:normal;line-height:" + ($.a.thumbnailSize/2) + "px;}", - "date:after" : "{clear:both; content:\".\"; display:block; height:0; visibility:hidden; }", - "date a" : "{color:#676;}", - "h3" : "{margin:0;padding:" + $.a.padding + "px;font-weight:bold;background:" + $.a.headerBackground + " url('http://" + $.a.server + "/favicon.ico') " + $.a.padding + "px 50% no-repeat;text-indent:" + ($.a.padding + 16) + "px;}", + ".cite" : "{" + setZoom + "font-weight:bold;margin:0px 0px 0px 4px;padding:0px;display:block;font-style:normal;line-height:" + ($.a.thumbnailSize/2) + "px;vertical-align:middle;}", + ".cite a" : "{color:#C15D42;}", + ".date":"{margin:0px 0px 0px 4px;padding:0px;display:block;font-style:normal;line-height:" + ($.a.thumbnailSize/2) + "px;vertical-align:middle;}", + ".date:after" : "{clear:both;content:\".\"; display:block;height:0px;visibility:hidden;}", + ".date a" : "{color:#676;}", + "h3" : "{margin:0px;padding:" + $.a.padding + "px;font-weight:bold;background:" + $.a.headerBackground + " url('http://" + $.a.server + "/favicon.ico') " + $.a.padding + "px 50% no-repeat;padding-left:" + ($.a.padding + 20) + "px;}", "h3.loading" : "{background-image:url('http://l.yimg.com/us.yimg.com/i/us/my/mw/anim_loading_sm.gif');}", "h3 a" : "{font-size:92%; color:" + $.a.headerColor + ";}", - "h4" : "{font-weight:normal; background:" + $.a.headerBackground + ";text-align:right;margin:0;padding:" + $.a.padding + "px;}", + "h4" : "{font-weight:normal;background:" + $.a.headerBackground + ";text-align:right;margin:0px;padding:" + $.a.padding + "px;}", "h4 a" : "{font-size:92%; color:" + $.a.headerColor + ";}", - "img":"{float:left; height:" + $.a.thumbnailSize + "px;width:" + $.a.thumbnailSize + "px;border:" + $.a.thumbnailBorder + ";margin-right:" + $.a.padding + "px;}", - "p" : "{margin:0; padding:0;width:" + ($.a.width - 22) + "px;overflow:hidden;font-size:87%;}", + "img":"{float:left;height:" + $.a.thumbnailSize + "px;width:" + $.a.thumbnailSize + "px;border:" + $.a.thumbnailBorder + ";margin-right:" + $.a.padding + "px;}", + "p" : "{margin:2px 0px 0px 0px;padding:0px;width:" + $.a.innerWidth + ";overflow:hidden;line-height:normal;}", "p a" : "{color:#C15D42;}", - "ul":"{margin:0; padding:0; height:" + $.a.height + "px;width:" + $.a.width + "px;overflow:auto;}", - "ul li":"{background:" + $.a.evenBackground + ";margin:0;padding:" + $.a.padding + "px;list-style:none;width:" + ($.a.width - 22) + "px;overflow:hidden;border-bottom:1px solid #D8E2D7;}", + "ul":"{margin:0px; padding:0px; height:" + $.a.height + ";width:" + $.a.innerWidth + ";overflow:auto;}", + "ul li":"{background:" + $.a.evenBackground + ";margin:0px;padding:" + $.a.padding + "px;list-style:none;width:auto;overflow:hidden;border-bottom:1px solid #D8E2D7;}", "ul li:hover":"{background:#f3f8ea;}" }; var ieRules = ""; // brute-force each and every style rule here to !important // sometimes you have to take off and nuke the site from orbit; it's the only way to be sure for (var z in rules) { - var selector = '.' + trueName + ' ' + z; + if(z.charAt(0)=='.') var selector = '.' + trueName + '-' + z.substring(1); + else var selector = '.' + trueName + ' ' + z; var rule = rules[z]; if (typeof rule === 'string') { var important = rule.replace(/;/gi, '!important;'); if (!window.createPopup) { - var theRule = document.createTextNode(selector + important); + var theRule = document.createTextNode(selector + important + '\n'); ns.appendChild(theRule); } else { ieRules += selector + important; @@ -115,17 +187,17 @@ if (window.createPopup) { s.cssText = ieRules; } }, buildStructure : function() { - $.s = document.createElement('DIV'); + $.s = createHTMLElement('div'); $.s.className = trueName; - $.s.h = document.createElement('H3'); - $.s.h.a = document.createElement('A'); + $.s.h = createHTMLElement('h3'); + $.s.h.a = createHTMLElement('a'); $.s.h.a.target = '_statusnet'; $.s.h.appendChild($.s.h.a); $.s.appendChild($.s.h); - $.s.r = document.createElement('UL'); + $.s.r = createHTMLElement('ul'); $.s.appendChild($.s.r); - $.s.f = document.createElement('H4'); - var a = document.createElement('A'); + $.s.f = createHTMLElement('h4'); + var a = createHTMLElement('a'); a.innerHTML = 'get this'; a.target = '_blank'; a.href = 'http://identi.ca/doc/badge'; @@ -139,7 +211,7 @@ var id = trueName + '.f.runFunction[' + n + ']'; $.f.runFunction[n] = function(r) { delete($.f.runFunction[n]); - var a = document.createElement('A'); + var a = createHTMLElement('a'); a.rel = $.a.user; a.rev = r.name; a.id = r.screen_name; @@ -178,10 +250,11 @@ } } r = $.f.sortArray(r, "status_id", true); - $.s.h.className = ''; + $.s.h.className = ''; // for IE6 + $.s.h.removeAttribute('class'); for (var i = 0; i < r.length; i++) { - var li = document.createElement('LI'); - var icon = document.createElement('A'); + var li = createHTMLElement('li'); + var icon = createHTMLElement('a'); if (r[i] && r[i].url) { icon.href = r[i].url; icon.target = '_statusnet'; @@ -192,17 +265,19 @@ icon.title = 'Visit ' + r[i].screen_name + ' at http://' + $.a.server + '/' + r[i].screen_name; } - var img = document.createElement('IMG'); + var img = createHTMLElement('img'); + img.alt = 'profile image for ' + r[i].screen_name; img.src = r[i].profile_image_url; icon.appendChild(img); - li.appendChild(icon); + li.appendChild(icon); - var user = document.createElement('CITE'); - var a = document.createElement('A'); + var user = createHTMLElement('span'); + user.className = trueName + '-cite'; + var a = createHTMLElement('a'); a.rel = r[i].id; a.rev = r[i].name; a.id = r[i].screen_name; - a.innerHTML = r[i].name; + a.innerHTML = r[i].name; a.href = 'http://' + $.a.server + '/' + r[i].screen_name; a.onclick = function() { $.f.changeUserTo(this); @@ -210,16 +285,17 @@ }; user.appendChild(a); li.appendChild(user); - var updated = document.createElement('DATE'); + var updated = createHTMLElement('span'); + updated.className = trueName + '-date'; if (r[i].status && r[i].status.created_at) { - var date_link = document.createElement('A'); + var date_link = createHTMLElement('a'); date_link.innerHTML = r[i].status.created_at.split(/\+/)[0]; date_link.href = 'http://' + $.a.server + '/notice/' + r[i].status.id; date_link.target = '_statusnet'; updated.appendChild(date_link); if (r[i].status.in_reply_to_status_id) { updated.appendChild(document.createTextNode(' in reply to ')); - var in_reply_to = document.createElement('A'); + var in_reply_to = createHTMLElement('a'); in_reply_to.innerHTML = r[i].status.in_reply_to_status_id; in_reply_to.href = 'http://' + $.a.server + '/notice/' + r[i].status.in_reply_to_status_id; in_reply_to.target = '_statusnet'; @@ -229,20 +305,16 @@ updated.innerHTML = 'has not updated yet'; } li.appendChild(updated); - var p = document.createElement('P'); + var p = createHTMLElement('p'); if (r[i].status && r[i].status.text) { var raw = r[i].status.text; - var cooked = raw; - cooked = cooked.replace(/http:\/\/([^ ]+)/g, "<a href=\"http://$1\" target=\"_statusnet\">http://$1</a>"); - cooked = cooked.replace(/@([\w*]+)/g, '@<a href="http://' + $.a.server + '/$1" target=\"_statusnet\">$1</a>'); - cooked = cooked.replace(/#([\w*]+)/g, '#<a href="http://' + $.a.server + '/tag/$1" target="_statusnet">$1</a>'); - p.innerHTML = cooked; + p = markupPost(raw, $.a.server); } li.appendChild(p); - var a = p.getElementsByTagName('A'); + var a = p.getElementsByTagName('a'); for (var j = 0; j < a.length; j++) { if (a[j].className == 'changeUserTo') { - a[j].className = ''; + a[j].removeAttribute('class'); a[j].href = 'http://' + $.a.server + '/' + a[j].innerHTML; a[j].rel = a[j].innerHTML; a[j].onclick = function() { @@ -269,7 +341,7 @@ return r; }, runScript : function(url, id) { - var s = document.createElement('script'); + var s = createHTMLElement('script'); s.id = id; s.type ='text/javascript'; s.src = url; @@ -292,3 +364,4 @@ } } )(); + diff --git a/js/util.js b/js/util.js index 879bb38ae..8846fcd3d 100644 --- a/js/util.js +++ b/js/util.js @@ -14,363 +14,425 @@ * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @category UI interaction + * @package StatusNet + * @author Sarven Capadisli <csarven@status.net> + * @author Evan Prodromou <evan@status.net> + * @copyright 2009 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ */ -$(document).ready(function(){ - var counterBlackout = false; - - // count character on keyup - function counter(event){ - var maxLength = 140; - var currentLength = $("#notice_data-text").val().length; - var remaining = maxLength - currentLength; - var counter = $("#notice_text-count"); - - if (remaining.toString() != counter.text()) { - if (!counterBlackout || remaining == 0) { - if (counter.text() != String(remaining)) { - counter.text(remaining); - } - - if (remaining < 0) { - $("#form_notice").addClass("warning"); - } else { - $("#form_notice").removeClass("warning"); +var SN = { // StatusNet + C: { // Config + I: { // Init + 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: { // Selector + Disabled: 'disabled', + Warning: 'warning', + Error: 'error', + Success: 'success', + Processing: 'processing', + CommandResult: 'command_result', + FormNotice: 'form_notice', + NoticeDataText: 'notice_data-text', + NoticeTextCount: 'notice_text-count', + NoticeInReplyTo: 'notice_in-reply-to', + NoticeDataAttach: 'notice_data-attach', + NoticeDataAttachSelected: 'notice_data-attach_selected', + NoticeActionSubmit: 'notice_action-submit', + NoticeLat: 'notice_data-lat', + NoticeLon: 'notice_data-lon', + NoticeLocationId: 'notice_data-location_id', + NoticeLocationNs: 'notice_data-location_ns' + } + }, + + U: { // Utils + FormNoticeEnhancements: function(form) { + form_id = form.attr('id'); + $('#'+form_id+' #'+SN.C.S.NoticeDataText).unbind('keyup'); + $('#'+form_id+' #'+SN.C.S.NoticeDataText).unbind('keydown'); + if (maxLength > 0) { + $('#'+form_id+' #'+SN.C.S.NoticeDataText).bind('keyup', function(e) { + SN.U.Counter(form); + }); + // run once in case there's something in there + SN.U.Counter(form); + } + + $('#'+form_id+' #'+SN.C.S.NoticeDataText).bind('keydown', function(e) { + SN.U.SubmitOnReturn(e, form); + }); + + if($('body')[0].id != 'conversation') { + $('#'+form_id+' textarea').focus(); + } + }, + + SubmitOnReturn: function(event, el) { + if (event.keyCode == 13 || event.keyCode == 10) { + el.submit(); + event.preventDefault(); + event.stopPropagation(); + $('#'+el[0].id+' #'+SN.C.S.NoticeDataText).blur(); + $('body').focus(); + return false; + } + return true; + }, + + Counter: function(form) { + SN.C.I.FormNoticeCurrent = form; + form_id = form.attr('id'); + if (typeof(maxLength) == "undefined") { + maxLength = SN.C.I.MaxLength; + } + + if (maxLength <= 0) { + return; + } + + var remaining = maxLength - $('#'+form_id+' #'+SN.C.S.NoticeDataText).val().length; + var counter = $('#'+form_id+' #'+SN.C.S.NoticeTextCount); + + if (remaining.toString() != counter.text()) { + if (!SN.C.I.CounterBlackout || remaining === 0) { + if (counter.text() != String(remaining)) { + counter.text(remaining); + } + if (remaining < 0) { + form.addClass(SN.C.S.Warning); + } else { + form.removeClass(SN.C.S.Warning); + } + // Skip updates for the next 500ms. + // On slower hardware, updating on every keypress is unpleasant. + if (!SN.C.I.CounterBlackout) { + SN.C.I.CounterBlackout = true; + SN.C.I.FormNoticeCurrent = form; + window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);", 500); + } + } + } + }, + + ClearCounterBlackout: function(form) { + // Allow keyup events to poke the counter again + SN.C.I.CounterBlackout = false; + // Check if the string changed since we last looked + SN.U.Counter(form); + }, + + FormXHR: function(f) { + f.bind('submit', function(e) { + form_id = $(this)[0].id; + $.ajax({ + type: 'POST', + dataType: 'xml', + url: $(this)[0].action, + data: $(this).serialize() + '&ajax=1', + beforeSend: function(xhr) { + $('#'+form_id).addClass(SN.C.S.Processing); + $('#'+form_id+' .submit').addClass(SN.C.S.Disabled); + $('#'+form_id+' .submit').attr(SN.C.S.Disabled, SN.C.S.Disabled); + }, + error: function (xhr, textStatus, errorThrown) { + alert(errorThrown || textStatus); + }, + success: function(data, textStatus) { + if (typeof($('form', data)[0]) != 'undefined') { + form_new = document._importNode($('form', data)[0], true); + $('#'+form_id).replaceWith(form_new); + $('#'+form_new.id).each(function() { SN.U.FormXHR($(this)); }); + } + else { + $('#'+form_id).replaceWith(document._importNode($('p', data)[0], true)); + } + } + }); + return false; + }); + }, + + FormNoticeXHR: function(form) { + form_id = form.attr('id'); + form.append('<input type="hidden" name="ajax" value="1"/>'); + form.ajaxForm({ + dataType: 'xml', + timeout: '60000', + beforeSend: function(xhr) { + if ($('#'+form_id+' #'+SN.C.S.NoticeDataText)[0].value.length === 0) { + form.addClass(SN.C.S.Warning); + return false; + } + form.addClass(SN.C.S.Processing); + $('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).addClass(SN.C.S.Disabled); + $('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).attr(SN.C.S.Disabled, SN.C.S.Disabled); + return true; + }, + error: function (xhr, textStatus, errorThrown) { + form.removeClass(SN.C.S.Processing); + $('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeClass(SN.C.S.Disabled); + $('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeAttr(SN.C.S.Disabled, SN.C.S.Disabled); + if (textStatus == 'timeout') { + alert ('Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists'); + } + else { + if ($('.'+SN.C.S.Error, xhr.responseXML).length > 0) { + form.append(document._importNode($('.'+SN.C.S.Error, xhr.responseXML)[0], true)); + } + else { + if(jQuery.inArray(parseInt(xhr.status), SN.C.I.HTTP20x30x) < 0) { + alert('Sorry! We had trouble sending your notice ('+xhr.status+' '+xhr.statusText+'). Please report the problem to the site administrator if this happens again.'); + } + else { + $('#'+form_id+' #'+SN.C.S.NoticeDataText).val(''); + SN.U.FormNoticeEnhancements($('#'+form_id)); + } + } + } + }, + success: function(data, textStatus) { + var result; + if ($('#'+SN.C.S.Error, data).length > 0) { + result = document._importNode($('p', data)[0], true); + alert(result.textContent || result.innerHTML); + } + else { + if($('body')[0].id == 'bookmarklet') { + self.close(); + } + + if ($('#'+SN.C.S.CommandResult, data).length > 0) { + result = document._importNode($('p', data)[0], true); + alert(result.textContent || result.innerHTML); } - // Skip updates for the next 500ms. - // On slower hardware, updating on every keypress is unpleasant. - if (!counterBlackout) { - counterBlackout = true; - window.setTimeout(clearCounterBlackout, 500); + else { + notice = document._importNode($('li', data)[0], true); + if ($('#'+notice.id).length === 0) { + var notice_irt_value = $('#'+SN.C.S.NoticeInReplyTo).val(); + var notice_irt = '#notices_primary #notice-'+notice_irt_value; + if($('body')[0].id == 'conversation') { + if(notice_irt_value.length > 0 && $(notice_irt+' .notices').length < 1) { + $(notice_irt).append('<ul class="notices"></ul>'); + } + $($(notice_irt+' .notices')[0]).append(notice); + } + else { + $("#notices_primary .notices").prepend(notice); + } + $('#'+notice.id).css({display:'none'}); + $('#'+notice.id).fadeIn(2500); + SN.U.NoticeAttachments(); + SN.U.NoticeReply(); + SN.U.NoticeFavor(); + } } + $('#'+form_id+' #'+SN.C.S.NoticeDataText).val(''); + $('#'+form_id+' #'+SN.C.S.NoticeDataAttach).val(''); + $('#'+form_id+' #'+SN.C.S.NoticeInReplyTo).val(''); + $('#'+form_id+' #'+SN.C.S.NoticeDataAttachSelected).remove(); + SN.U.FormNoticeEnhancements($('#'+form_id)); } + }, + complete: function(xhr, textStatus) { + form.removeClass(SN.C.S.Processing); + $('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeAttr(SN.C.S.Disabled); + $('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeClass(SN.C.S.Disabled); } - } - - function clearCounterBlackout() { - // Allow keyup events to poke the counter again - counterBlackout = false; - // Check if the string changed since we last looked - counter(null); - } - - function submitonreturn(event) { - if (event.keyCode == 13 || event.keyCode == 10) { - // iPhone sends \n not \r for 'return' - $("#form_notice").submit(); - event.preventDefault(); - event.stopPropagation(); - $("#notice_data-text").blur(); - $("body").focus(); - return false; - } - return true; - } - - if ($("#notice_data-text").length) { - $("#notice_data-text").bind("keyup", counter); - $("#notice_data-text").bind("keydown", submitonreturn); - - // run once in case there's something in there - counter(); - - if($('body')[0].id != 'conversation') { - $("#notice_data-text").focus(); - } - } - - // XXX: refactor this code - - var joinoptions = { dataType: 'xml', - success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true); - var leave = new_form.id; - var join = leave.replace('leave', 'join'); - $('form#'+join).replaceWith(new_form); - $('form#'+leave).ajaxForm(leaveoptions).each(addAjaxHidden); - } - }; - - var leaveoptions = { dataType: 'xml', - success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true); - var join = new_form.id; - var leave = join.replace('join', 'leave'); - $('form#'+leave).replaceWith(new_form); - $('form#'+join).ajaxForm(joinoptions).each(addAjaxHidden); - } - }; - - $("form.form_group_join").ajaxForm(joinoptions); - $("form.form_group_leave").ajaxForm(leaveoptions); - $("form.form_group_join").each(addAjaxHidden); - $("form.form_group_leave").each(addAjaxHidden); - - $("#form_user_nudge").ajaxForm ({ dataType: 'xml', - beforeSubmit: function(xml) { $("#form_user_nudge input[type=submit]").attr("disabled", "disabled"); - $("#form_user_nudge input[type=submit]").addClass("disabled"); - }, - success: function(xml) { $("#form_user_nudge").replaceWith(document._importNode($("#nudge_response", xml).get(0),true)); - $("#form_user_nudge input[type=submit]").removeAttr("disabled"); - $("#form_user_nudge input[type=submit]").removeClass("disabled"); - } - }); - $("#form_user_nudge").each(addAjaxHidden); - - var Subscribe = { dataType: 'xml', - beforeSubmit: function(formData, jqForm, options) { $(".form_user_subscribe input[type=submit]").attr("disabled", "disabled"); - $(".form_user_subscribe input[type=submit]").addClass("disabled"); - }, - success: function(xml) { var form_unsubscribe = document._importNode($('form', xml).get(0), true); - var form_unsubscribe_id = form_unsubscribe.id; - var form_subscribe_id = form_unsubscribe_id.replace('unsubscribe', 'subscribe'); - $("form#"+form_subscribe_id).replaceWith(form_unsubscribe); - $("form#"+form_unsubscribe_id).ajaxForm(UnSubscribe).each(addAjaxHidden); - $("dd.subscribers").text(parseInt($("dd.subscribers").text())+1); - $(".form_user_subscribe input[type=submit]").removeAttr("disabled"); - $(".form_user_subscribe input[type=submit]").removeClass("disabled"); - } - }; - - var UnSubscribe = { dataType: 'xml', - beforeSubmit: function(formData, jqForm, options) { $(".form_user_unsubscribe input[type=submit]").attr("disabled", "disabled"); - $(".form_user_unsubscribe input[type=submit]").addClass("disabled"); - }, - success: function(xml) { var form_subscribe = document._importNode($('form', xml).get(0), true); - var form_subscribe_id = form_subscribe.id; - var form_unsubscribe_id = form_subscribe_id.replace('subscribe', 'unsubscribe'); - $("form#"+form_unsubscribe_id).replaceWith(form_subscribe); - $("form#"+form_subscribe_id).ajaxForm(Subscribe).each(addAjaxHidden); - $("#profile_send_a_new_message").remove(); - $("#profile_nudge").remove(); - $("dd.subscribers").text(parseInt($("dd.subscribers").text())-1); - $(".form_user_unsubscribe input[type=submit]").removeAttr("disabled"); - $(".form_user_unsubscribe input[type=submit]").removeClass("disabled"); - } - }; - - $(".form_user_subscribe").ajaxForm(Subscribe); - $(".form_user_unsubscribe").ajaxForm(UnSubscribe); - $(".form_user_subscribe").each(addAjaxHidden); - $(".form_user_unsubscribe").each(addAjaxHidden); - - var PostNotice = { dataType: 'xml', - beforeSubmit: function(formData, jqForm, options) { if ($("#notice_data-text").get(0).value.length == 0) { - $("#form_notice").addClass("warning"); - return false; - } - $("#form_notice").addClass("processing"); - $("#notice_action-submit").attr("disabled", "disabled"); - $("#notice_action-submit").addClass("disabled"); - return true; - }, - timeout: '60000', - error: function (xhr, textStatus, errorThrown) { $("#form_notice").removeClass("processing"); - $("#notice_action-submit").removeAttr("disabled"); - $("#notice_action-submit").removeClass("disabled"); - if (textStatus == "timeout") { - alert ("Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists"); - } - else { - if ($(".error", xhr.responseXML).length > 0) { - $('#form_notice').append(document._importNode($(".error", xhr.responseXML).get(0), true)); - } - else { - var HTTP20x30x = [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307]; - if(jQuery.inArray(parseInt(xhr.status), HTTP20x30x) < 0) { - alert("Sorry! We had trouble sending your notice ("+xhr.status+" "+xhr.statusText+"). Please report the problem to the site administrator if this happens again."); - } - else { - $("#notice_data-text").val(""); - counter(); - } - } - } - }, - success: function(xml) { if ($("#error", xml).length > 0) { - var result = document._importNode($("p", xml).get(0), true); - result = result.textContent || result.innerHTML; - alert(result); - } - else { - if ($("#command_result", xml).length > 0) { - var result = document._importNode($("p", xml).get(0), true); - result = result.textContent || result.innerHTML; - alert(result); - } - else { - li = $("li", xml).get(0); - if ($("#"+li.id).length == 0) { - var notice_irt_value = $('#notice_in-reply-to').val(); - var notice_irt = '#notices_primary #notice-'+notice_irt_value; - if($('body')[0].id == 'conversation') { - if(notice_irt_value.length > 0 && $(notice_irt+' .notices').length < 1) { - $(notice_irt).append('<ul class="notices"></ul>'); - } - $($(notice_irt+' .notices')[0]).append(document._importNode(li, true)); - } - else { - $("#notices_primary .notices").prepend(document._importNode(li, true)); - } - $('#'+li.id).css({display:'none'}); - $('#'+li.id).fadeIn(2500); - NoticeReply(); - NoticeAttachments(); - NoticeFavors(); - } - } - $("#notice_data-text").val(""); - $("#notice_data-attach").val(""); - $("#notice_in-reply-to").val(""); - $('#notice_data-attach_selected').remove(); - counter(); - } - $("#form_notice").removeClass("processing"); - $("#notice_action-submit").removeAttr("disabled"); - $("#notice_action-submit").removeClass("disabled"); - } - }; - $("#form_notice").ajaxForm(PostNotice); - $("#form_notice").each(addAjaxHidden); - NoticeReply(); - NoticeAttachments(); - NoticeDataAttach(); - NoticeFavors(); -}); + }); + }, + + NoticeReply: function() { + if ($('#'+SN.C.S.NoticeDataText).length > 0 && $('#content .notice_reply').length > 0) { + $('#content .notice').each(function() { + var notice = $(this)[0]; + $($('.notice_reply', notice)[0]).click(function() { + var nickname = ($('.author .nickname', notice).length > 0) ? $($('.author .nickname', notice)[0]) : $('.author .nickname.uid'); + SN.U.NoticeReplySet(nickname.text(), $($('.notice_id', notice)[0]).text()); + return false; + }); + }); + } + }, + + NoticeReplySet: function(nick,id) { + if (nick.match(SN.C.I.PatternUsername)) { + var text = $('#'+SN.C.S.NoticeDataText); + if (text.length) { + replyto = '@' + nick + ' '; + text.val(replyto + text.val().replace(RegExp(replyto, 'i'), '')); + $('#'+SN.C.S.FormNotice+' input#'+SN.C.S.NoticeInReplyTo).val(id); + if (text[0].setSelectionRange) { + var len = text.val().length; + text[0].setSelectionRange(len,len); + text[0].focus(); + } + return false; + } + } + return true; + }, + + NoticeFavor: function() { + $('.form_favor').each(function() { SN.U.FormXHR($(this)); }); + $('.form_disfavor').each(function() { SN.U.FormXHR($(this)); }); + }, + + NoticeAttachments: function() { + $.fn.jOverlay.options = { + method : 'GET', + data : '', + url : '', + color : '#000', + opacity : '0.6', + zIndex : 99, + center : false, + imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif', + bgClickToClose : true, + success : function() { + $('#jOverlayContent').append('<button class="close">×</button>'); + $('#jOverlayContent button').click($.closeOverlay); + }, + timeout : 0, + autoHide : true, + css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'} + }; -function addAjaxHidden() { - var ajax = document.createElement('input'); - ajax.setAttribute('type', 'hidden'); - ajax.setAttribute('name', 'ajax'); - ajax.setAttribute('value', 1); - this.appendChild(ajax); -} - -function NoticeFavors() { - - // XXX: refactor this code - var favoptions = { dataType: 'xml', - beforeSubmit: function(data, target, options) { - $(target).addClass('processing'); - return true; - }, - success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true); - var dis = new_form.id; - var fav = dis.replace('disfavor', 'favor'); - $('form#'+fav).replaceWith(new_form); - $('form#'+dis).ajaxForm(disoptions).each(addAjaxHidden); - } - }; - - var disoptions = { dataType: 'xml', - beforeSubmit: function(data, target, options) { - $(target).addClass('processing'); - return true; - }, - success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true); - var fav = new_form.id; - var dis = fav.replace('favor', 'disfavor'); - $('form#'+dis).replaceWith(new_form); - $('form#'+fav).ajaxForm(favoptions).each(addAjaxHidden); - } - }; - - $("form.form_favor").ajaxForm(favoptions); - $("form.form_disfavor").ajaxForm(disoptions); - $("form.form_favor").each(addAjaxHidden); - $("form.form_disfavor").each(addAjaxHidden); -} - -function NoticeReply() { - if ($('#notice_data-text').length > 0 && $('#content .notice_reply').length > 0) { - $('#content .notice').each(function() { - var notice = $(this)[0]; - $($('.notice_reply', notice)[0]).click(function() { - var nickname = ($('.author .nickname', notice).length > 0) ? $($('.author .nickname', notice)[0]) : $('.author .nickname.uid'); - NoticeReplySet(nickname.text(), $($('.notice_id', notice)[0]).text()); + $('#content .notice a.attachment').click(function() { + $().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'}); return false; }); - }); - } -} - -function NoticeReplySet(nick,id) { - rgx_username = /^[0-9a-zA-Z\-_.]*$/; - if (nick.match(rgx_username)) { - var text = $("#notice_data-text"); - if (text.length) { - replyto = "@" + nick + " "; - text.val(replyto + text.val().replace(RegExp(replyto, 'i'), '')); - $("#form_notice input#notice_in-reply-to").val(id); - if (text.get(0).setSelectionRange) { - var len = text.val().length; - text.get(0).setSelectionRange(len,len); - text.get(0).focus(); - } - return false; - } - } - return true; -} - -function NoticeAttachments() { - $.fn.jOverlay.options = { - method : 'GET', - data : '', - url : '', - color : '#000', - opacity : '0.6', - zIndex : 99, - center : false, - imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif', - bgClickToClose : true, - success : function() { - $('#jOverlayContent').append('<button>×</button>'); - $('#jOverlayContent button').click($.closeOverlay); + + var t; + $("body:not(#shownotice) #content .notice a.thumbnail").hover( + function() { + var anchor = $(this); + $("a.thumbnail").children('img').hide(); + anchor.closest(".entry-title").addClass('ov'); + + if (anchor.children('img').length === 0) { + t = setTimeout(function() { + $.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) { + anchor.append(data); + }); + }, 500); + } + else { + anchor.children('img').show(); + } + }, + function() { + clearTimeout(t); + $("a.thumbnail").children('img').hide(); + $(this).closest(".entry-title").removeClass('ov'); + } + ); }, - timeout : 0, - autoHide : true, - css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'} - }; - - $('#content .notice a.attachment').click(function() { - $().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'}); - return false; - }); - - var t; - $("body:not(#shownotice) #content .notice a.thumbnail").hover( - function() { - var anchor = $(this); - $("a.thumbnail").children('img').hide(); - anchor.closest(".entry-title").addClass('ov'); - - if (anchor.children('img').length == 0) { - t = setTimeout(function() { - $.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) { - anchor.append(data); + + NoticeDataAttach: function() { + NDA = $('#'+SN.C.S.NoticeDataAttach); + NDA.change(function() { + S = '<div id="'+SN.C.S.NoticeDataAttachSelected+'" class="'+SN.C.S.Success+'"><code>'+$(this).val()+'</code> <button class="close">×</button></div>'; + NDAS = $('#'+SN.C.S.NoticeDataAttachSelected); + if (NDAS.length > 0) { + NDAS.replaceWith(S); + } + else { + $('#'+SN.C.S.FormNotice).append(S); + } + $('#'+SN.C.S.NoticeDataAttachSelected+' button').click(function(){ + $('#'+SN.C.S.NoticeDataAttachSelected).remove(); + NDA.val(''); + }); + }); + }, + + NoticeLocationAttach: function() { + if(navigator.geolocation) navigator.geolocation.watchPosition(function(position) { + $('#'+SN.C.S.NoticeLat).val(position.coords.latitude); + $('#'+SN.C.S.NoticeLon).val(position.coords.longitude); + }); + }, + + NewDirectMessage: function() { + NDM = $('.entity_send-a-message a'); + NDM.attr({'href':NDM.attr('href')+'&ajax=1'}); + NDM.click(function() { + var NDMF = $('.entity_send-a-message form'); + if (NDMF.length === 0) { + $.get(NDM.attr('href'), null, function(data) { + $('.entity_send-a-message').append(document._importNode($('form', data)[0], true)); + NDMF = $('.entity_send-a-message .form_notice'); + SN.U.FormNoticeXHR(NDMF); + SN.U.FormNoticeEnhancements(NDMF); + NDMF.append('<button class="close">×</button>'); + $('.entity_send-a-message button').click(function(){ + NDMF.hide(); + return false; + }); }); - }, 500); + } + else { + NDMF.show(); + $('.entity_send-a-message textarea').focus(); + } + return false; + }); + } + }, + + Init: { + NoticeForm: function() { + if ($('body.user_in').length > 0) { + $('.'+SN.C.S.FormNotice).each(function() { + SN.U.FormNoticeXHR($(this)); + SN.U.FormNoticeEnhancements($(this)); + }); + + SN.U.NoticeDataAttach(); + SN.U.NoticeLocationAttach(); } - else { - anchor.children('img').show(); + }, + + Notices: function() { + if ($('body.user_in').length > 0) { + SN.U.NoticeFavor(); + + SN.U.NoticeReply(); } + + SN.U.NoticeAttachments(); }, - function() { - clearTimeout(t); - $("a.thumbnail").children('img').hide(); - $(this).closest(".entry-title").removeClass('ov'); + + EntityActions: function() { + if ($('body.user_in').length > 0) { + $('.form_user_subscribe').each(function() { SN.U.FormXHR($(this)); }); + $('.form_user_unsubscribe').each(function() { SN.U.FormXHR($(this)); }); + $('.form_group_join').each(function() { SN.U.FormXHR($(this)); }); + $('.form_group_leave').each(function() { SN.U.FormXHR($(this)); }); + $('.form_user_nudge').each(function() { SN.U.FormXHR($(this)); }); + } } - ); -} - -function NoticeDataAttach() { - NDA = $('#notice_data-attach'); - NDA.change(function() { - S = '<div id="notice_data-attach_selected" class="success"><code>'+$(this).val()+'</code> <button>×</button></div>'; - NDAS = $('#notice_data-attach_selected'); - (NDAS.length > 0) ? NDAS.replaceWith(S) : $('#form_notice').append(S); - $('#notice_data-attach_selected button').click(function(){ - $('#notice_data-attach_selected').remove(); - NDA.val(''); - }); - }); -} + } +}; + +$(document).ready(function(){ + 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(); + } +}); + |