diff options
author | Zach Copley <zach@status.net> | 2009-11-19 20:12:46 -0800 |
---|---|---|
committer | Zach Copley <zach@status.net> | 2009-11-19 20:12:46 -0800 |
commit | 4b98edf75f4e255f8c61087bd1525d89653a521f (patch) | |
tree | b2a7eb6d77429eadb1beabe2d5e6ae1c1a2831d6 /js | |
parent | f92574dbcb1f2d7cd0aaf3c9362db46fa066e888 (diff) | |
parent | c213477081afefb1720c8ae729d1965e7a1dac63 (diff) |
Merge branch '0.9-release'
* 0.9-release: (874 commits)
Removed call to NewDirectMessage() until IE return is fixed i.e.,
Don't show flag user button your own profile
Fixed HXR response for flag user
Using the right form class name
Using common_redirect
Left a form_data class of a <ul> in the user admin panel
Added validation to fields in user admin panel
Added a user admin panel
Added mobile logos for default and identica themes
Changed gif to png
Changed this to action. THANKS zach!
Doing content negotiation only once
Add execute bit to pingqueuehandler
Localisation updates for !StatusNet from !translatewiki.net
Use the browser's geolocation API to set the location on the notice form
Add geometa library, and include it.
Add location form elements to the noticeform, and save their values on submission
Use the $user object nickname, as login name doesnt have to == nickname anymore with plugins such as ldap/etc
Revert "Re added NICKNAME_FMT constant to router.php."
Moved most path and server settings to a new paths admin panel
...
Conflicts:
js/util.js
locale/it_IT/LC_MESSAGES/statusnet.mo
locale/mk_MK/LC_MESSAGES/statusnet.mo
locale/mk_MK/LC_MESSAGES/statusnet.po
locale/pt_BR/LC_MESSAGES/statusnet.mo
locale/vi_VN/LC_MESSAGES/statusnet.mo
plugins/InfiniteScroll/infinitescroll.js
plugins/Realtime/realtimeupdate.js
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(); + } +}); + |