2008-08-27 02:38:35 +01:00
/ *
2009-08-25 23:40:12 +01:00
* StatusNet - a distributed open - source microblogging tool
* Copyright ( C ) 2008 , StatusNet , Inc .
2008-08-27 02:38:35 +01:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* 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/>.
2009-10-30 14:49:47 +00:00
*
* @ 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/
2008-08-27 02:38:35 +01:00
* /
2009-10-30 11:40:08 +00:00
var SN = { // StatusNet
C : { // Config
2009-10-30 14:59:17 +00:00
I : { // Init
2009-10-30 14:43:41 +00:00
CounterBlackout : false ,
MaxLength : 140 ,
2009-10-30 12:15:11 +00:00
PatternUsername : /^[0-9a-zA-Z\-_.]*$/ ,
2010-03-31 09:57:20 +01:00
HTTP20x30x : [ 200 , 201 , 202 , 203 , 204 , 205 , 206 , 300 , 301 , 302 , 303 , 304 , 305 , 306 , 307 ]
2009-10-30 12:15:11 +00:00
} ,
2009-10-30 15:21:03 +00:00
2009-10-30 11:40:08 +00:00
S : { // Selector
Disabled : 'disabled' ,
Warning : 'warning' ,
Error : 'error' ,
2009-10-30 13:16:38 +00:00
Success : 'success' ,
2009-10-30 12:15:11 +00:00
Processing : 'processing' ,
2009-10-31 17:01:19 +00:00
CommandResult : 'command_result' ,
2009-10-30 12:15:11 +00:00
FormNotice : 'form_notice' ,
NoticeDataText : 'notice_data-text' ,
NoticeTextCount : 'notice_text-count' ,
NoticeInReplyTo : 'notice_in-reply-to' ,
NoticeDataAttach : 'notice_data-attach' ,
2009-10-30 13:16:38 +00:00
NoticeDataAttachSelected : 'notice_data-attach_selected' ,
2009-11-19 20:17:18 +00:00
NoticeActionSubmit : 'notice_action-submit' ,
NoticeLat : 'notice_data-lat' ,
NoticeLon : 'notice_data-lon' ,
NoticeLocationId : 'notice_data-location_id' ,
2009-12-29 21:17:17 +00:00
NoticeLocationNs : 'notice_data-location_ns' ,
2010-01-08 13:58:23 +00:00
NoticeGeoName : 'notice_data-geo_name' ,
2010-01-03 00:33:41 +00:00
NoticeDataGeo : 'notice_data-geo' ,
2010-03-03 00:15:24 +00:00
NoticeDataGeoCookie : 'NoticeDataGeo' ,
2010-02-24 15:35:20 +00:00
NoticeDataGeoSelected : 'notice_data-geo_selected' ,
StatusNetInstance : 'StatusNetInstance'
2010-11-12 20:10:51 +00:00
}
2010-11-02 20:05:16 +00:00
} ,
messages : { } ,
msg : function ( key ) {
if ( typeof SN . messages [ key ] == "undefined" ) {
return '[' + key + ']' ;
} else {
return SN . messages [ key ] ;
2009-10-30 11:40:08 +00:00
}
} ,
U : { // Utils
2009-10-31 17:55:13 +00:00
FormNoticeEnhancements : function ( form ) {
2009-12-10 13:16:07 +00:00
if ( jQuery . data ( form [ 0 ] , 'ElementData' ) === undefined ) {
2010-03-16 20:02:56 +00:00
MaxLength = form . find ( '#' + SN . C . S . NoticeTextCount ) . text ( ) ;
2009-12-10 13:16:07 +00:00
if ( typeof ( MaxLength ) == 'undefined' ) {
MaxLength = SN . C . I . MaxLength ;
}
jQuery . data ( form [ 0 ] , 'ElementData' , { MaxLength : MaxLength } ) ;
SN . U . Counter ( form ) ;
2010-03-16 20:02:56 +00:00
NDT = form . find ( '#' + SN . C . S . NoticeDataText ) ;
2009-12-10 13:16:07 +00:00
NDT . bind ( 'keyup' , function ( e ) {
2009-10-31 17:55:13 +00:00
SN . U . Counter ( form ) ;
} ) ;
2009-12-10 13:16:07 +00:00
NDT . bind ( 'keydown' , function ( e ) {
SN . U . SubmitOnReturn ( e , form ) ;
} ) ;
}
2009-12-10 13:52:05 +00:00
else {
2010-03-16 20:02:56 +00:00
form . find ( '#' + SN . C . S . NoticeTextCount ) . text ( jQuery . data ( form [ 0 ] , 'ElementData' ) . MaxLength ) ;
2009-12-10 13:52:05 +00:00
}
2009-10-31 17:55:13 +00:00
2010-06-23 19:29:13 +01:00
if ( $ ( 'body' ) [ 0 ] . id != 'conversation' && window . location . hash . length === 0 && $ ( window ) . scrollTop ( ) == 0 ) {
2010-03-16 20:02:56 +00:00
form . find ( 'textarea' ) . focus ( ) ;
2009-10-31 17:55:13 +00:00
}
} ,
2009-10-30 13:31:57 +00:00
SubmitOnReturn : function ( event , el ) {
if ( event . keyCode == 13 || event . keyCode == 10 ) {
el . submit ( ) ;
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
2009-11-02 16:55:47 +00:00
$ ( '#' + el [ 0 ] . id + ' #' + SN . C . S . NoticeDataText ) . blur ( ) ;
$ ( 'body' ) . focus ( ) ;
2009-10-30 13:31:57 +00:00
return false ;
}
return true ;
} ,
2009-10-31 17:55:13 +00:00
Counter : function ( form ) {
SN . C . I . FormNoticeCurrent = form ;
2009-10-30 14:43:41 +00:00
2009-12-10 13:16:07 +00:00
var MaxLength = jQuery . data ( form [ 0 ] , 'ElementData' ) . MaxLength ;
if ( MaxLength <= 0 ) {
2009-10-30 14:43:41 +00:00
return ;
}
2010-08-12 20:47:07 +01:00
var remaining = MaxLength - SN . U . CharacterCount ( form ) ;
2010-03-16 20:02:56 +00:00
var counter = form . find ( '#' + SN . C . S . NoticeTextCount ) ;
2009-10-30 14:43:41 +00:00
if ( remaining . toString ( ) != counter . text ( ) ) {
2009-11-02 17:06:52 +00:00
if ( ! SN . C . I . CounterBlackout || remaining === 0 ) {
2009-10-30 14:43:41 +00:00
if ( counter . text ( ) != String ( remaining ) ) {
counter . text ( remaining ) ;
}
if ( remaining < 0 ) {
2009-10-31 17:55:13 +00:00
form . addClass ( SN . C . S . Warning ) ;
2009-10-30 14:43:41 +00:00
} else {
2009-10-31 17:55:13 +00:00
form . removeClass ( SN . C . S . Warning ) ;
2009-10-30 14:43:41 +00:00
}
// 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 ;
2009-10-31 17:55:13 +00:00
SN . C . I . FormNoticeCurrent = form ;
window . setTimeout ( "SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);" , 500 ) ;
2009-10-30 14:43:41 +00:00
}
}
}
} ,
2010-08-12 20:47:07 +01:00
CharacterCount : function ( form ) {
return form . find ( '#' + SN . C . S . NoticeDataText ) . val ( ) . length ;
} ,
2009-10-31 17:55:13 +00:00
ClearCounterBlackout : function ( form ) {
2009-10-30 14:43:41 +00:00
// Allow keyup events to poke the counter again
SN . C . I . CounterBlackout = false ;
// Check if the string changed since we last looked
2009-10-31 17:55:13 +00:00
SN . U . Counter ( form ) ;
2009-10-30 14:43:41 +00:00
} ,
2010-01-31 22:37:22 +00:00
FormXHR : 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 ) {
if ( typeof ( $ ( 'form' , data ) [ 0 ] ) != 'undefined' ) {
form _new = document . _importNode ( $ ( 'form' , data ) [ 0 ] , true ) ;
form . replaceWith ( form _new ) ;
}
else {
form . replaceWith ( document . _importNode ( $ ( 'p' , data ) [ 0 ] , true ) ) ;
}
}
} ) ;
2009-10-30 12:15:11 +00:00
} ,
2009-10-31 17:01:19 +00:00
FormNoticeXHR : function ( form ) {
2010-01-30 14:28:31 +00:00
SN . C . I . NoticeDataGeo = { } ;
2009-10-31 17:01:19 +00:00
form . append ( '<input type="hidden" name="ajax" value="1"/>' ) ;
form . ajaxForm ( {
2009-10-30 15:21:03 +00:00
dataType : 'xml' ,
2009-10-30 21:11:56 +00:00
timeout : '60000' ,
2010-01-05 01:15:08 +00:00
beforeSend : function ( formData ) {
2010-01-30 14:03:01 +00:00
if ( form . find ( '#' + SN . C . S . NoticeDataText ) [ 0 ] . value . length === 0 ) {
2009-10-31 17:01:19 +00:00
form . addClass ( SN . C . S . Warning ) ;
2009-10-30 12:15:11 +00:00
return false ;
}
2010-01-30 14:19:13 +00:00
form
. addClass ( SN . C . S . Processing )
. find ( '#' + SN . C . S . NoticeActionSubmit )
. addClass ( SN . C . S . Disabled )
. attr ( SN . C . S . Disabled , SN . C . S . Disabled ) ;
2010-01-05 01:15:08 +00:00
2010-01-30 14:28:31 +00:00
SN . C . I . NoticeDataGeo . NLat = $ ( '#' + SN . C . S . NoticeLat ) . val ( ) ;
SN . C . I . NoticeDataGeo . NLon = $ ( '#' + SN . C . S . NoticeLon ) . val ( ) ;
SN . C . I . NoticeDataGeo . NLNS = $ ( '#' + SN . C . S . NoticeLocationNs ) . val ( ) ;
SN . C . I . NoticeDataGeo . NLID = $ ( '#' + SN . C . S . NoticeLocationId ) . val ( ) ;
SN . C . I . NoticeDataGeo . NDG = $ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' ) ;
2010-01-08 16:43:03 +00:00
cookieValue = $ . cookie ( SN . C . S . NoticeDataGeoCookie ) ;
if ( cookieValue !== null && cookieValue != 'disabled' ) {
cookieValue = JSON . parse ( cookieValue ) ;
2010-01-30 14:28:31 +00:00
SN . C . I . NoticeDataGeo . NLat = $ ( '#' + SN . C . S . NoticeLat ) . val ( cookieValue . NLat ) . val ( ) ;
SN . C . I . NoticeDataGeo . NLon = $ ( '#' + SN . C . S . NoticeLon ) . val ( cookieValue . NLon ) . val ( ) ;
2010-01-22 00:27:08 +00:00
if ( $ ( '#' + SN . C . S . NoticeLocationNs ) . val ( cookieValue . NLNS ) ) {
2010-01-30 14:28:31 +00:00
SN . C . I . NoticeDataGeo . NLNS = $ ( '#' + SN . C . S . NoticeLocationNs ) . val ( cookieValue . NLNS ) . val ( ) ;
SN . C . I . NoticeDataGeo . NLID = $ ( '#' + SN . C . S . NoticeLocationId ) . val ( cookieValue . NLID ) . val ( ) ;
2010-01-22 00:27:08 +00:00
}
2010-01-08 16:43:03 +00:00
}
if ( cookieValue == 'disabled' ) {
2010-01-30 14:28:31 +00:00
SN . C . I . NoticeDataGeo . NDG = $ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' , false ) . attr ( 'checked' ) ;
2010-01-08 16:43:03 +00:00
}
else {
2010-01-30 14:28:31 +00:00
SN . C . I . NoticeDataGeo . NDG = $ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' , true ) . attr ( 'checked' ) ;
2010-01-08 16:43:03 +00:00
}
2010-01-05 01:15:08 +00:00
2009-10-30 12:15:11 +00:00
return true ;
} ,
error : function ( xhr , textStatus , errorThrown ) {
2010-01-30 14:19:13 +00:00
form
. removeClass ( SN . C . S . Processing )
. find ( '#' + SN . C . S . NoticeActionSubmit )
. removeClass ( SN . C . S . Disabled )
. removeAttr ( SN . C . S . Disabled , SN . C . S . Disabled ) ;
2010-01-30 14:03:01 +00:00
form . find ( '.form_response' ) . remove ( ) ;
2009-10-30 12:15:11 +00:00
if ( textStatus == 'timeout' ) {
2009-12-07 10:26:29 +00:00
form . append ( '<p class="form_response error">Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.</p>' ) ;
2009-10-30 12:15:11 +00:00
}
else {
2010-11-17 22:24:35 +00:00
var response = SN . U . GetResponseXML ( xhr ) ;
if ( $ ( '.' + SN . C . S . Error , response ) . length > 0 ) {
form . append ( document . _importNode ( $ ( '.' + SN . C . S . Error , response ) [ 0 ] , true ) ) ;
2009-10-30 12:15:11 +00:00
}
else {
2009-12-07 09:55:12 +00:00
if ( parseInt ( xhr . status ) === 0 || jQuery . inArray ( parseInt ( xhr . status ) , SN . C . I . HTTP20x30x ) >= 0 ) {
2010-03-31 09:57:20 +01:00
form
. resetForm ( )
. find ( '#' + SN . C . S . NoticeDataAttachSelected ) . remove ( ) ;
2010-01-30 14:03:01 +00:00
SN . U . FormNoticeEnhancements ( form ) ;
2009-10-30 12:15:11 +00:00
}
else {
2009-12-07 10:26:29 +00:00
form . append ( '<p class="form_response error">(Sorry! We had trouble sending your notice (' + xhr . status + ' ' + xhr . statusText + '). Please report the problem to the site administrator if this happens again.</p>' ) ;
2009-10-30 12:15:11 +00:00
}
}
}
} ,
success : function ( data , textStatus ) {
2010-01-30 14:03:01 +00:00
form . find ( '.form_response' ) . remove ( ) ;
2009-11-02 17:06:52 +00:00
var result ;
2009-10-30 12:15:11 +00:00
if ( $ ( '#' + SN . C . S . Error , data ) . length > 0 ) {
2009-12-08 22:31:23 +00:00
result = document . _importNode ( $ ( 'p' , data ) [ 0 ] , true ) ;
2009-11-30 15:25:06 +00:00
result = result . textContent || result . innerHTML ;
2009-12-07 10:26:29 +00:00
form . append ( '<p class="form_response error">' + result + '</p>' ) ;
2009-10-30 12:15:11 +00:00
}
else {
if ( $ ( 'body' ) [ 0 ] . id == 'bookmarklet' ) {
self . close ( ) ;
}
2009-10-31 17:01:19 +00:00
2009-12-02 22:25:38 +00:00
if ( $ ( '#' + SN . C . S . CommandResult , data ) . length > 0 ) {
result = document . _importNode ( $ ( 'p' , data ) [ 0 ] , true ) ;
result = result . textContent || result . innerHTML ;
2009-12-07 10:26:29 +00:00
form . append ( '<p class="form_response success">' + result + '</p>' ) ;
2009-12-02 22:25:38 +00:00
}
else {
2010-07-29 21:27:09 +01:00
// New notice post was successful. If on our timeline, show it!
var notice = document . _importNode ( $ ( 'li' , data ) [ 0 ] , true ) ;
2009-12-02 22:41:58 +00:00
var notices = $ ( '#notices_primary .notices' ) ;
2010-07-29 21:27:09 +01:00
if ( notices . length > 0 && SN . U . belongsOnTimeline ( notice ) ) {
2009-12-02 22:41:58 +00:00
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 ) ;
2009-10-30 12:15:11 +00:00
}
2009-12-02 22:41:58 +00:00
else {
notices . prepend ( notice ) ;
}
2010-01-30 14:19:13 +00:00
$ ( '#' + notice . id )
. css ( { display : 'none' } )
. fadeIn ( 2500 ) ;
2009-12-02 22:41:58 +00:00
SN . U . NoticeWithAttachment ( $ ( '#' + notice . id ) ) ;
SN . U . NoticeReplyTo ( $ ( '#' + notice . id ) ) ;
2009-12-02 22:25:38 +00:00
}
2009-12-02 22:41:58 +00:00
}
else {
2010-07-29 21:27:09 +01:00
// Not on a timeline that this belongs on?
// Just show a success message.
2009-12-02 22:41:58 +00:00
result = document . _importNode ( $ ( 'title' , data ) [ 0 ] , true ) ;
result _title = result . textContent || result . innerHTML ;
2009-12-07 10:26:29 +00:00
form . append ( '<p class="form_response success">' + result _title + '</p>' ) ;
2009-12-02 22:41:58 +00:00
}
2009-10-30 12:15:11 +00:00
}
2010-01-30 14:03:01 +00:00
form . resetForm ( ) ;
2010-03-31 09:57:20 +01:00
form . find ( '#' + SN . C . S . NoticeInReplyTo ) . val ( '' ) ;
form . find ( '#' + SN . C . S . NoticeDataAttachSelected ) . remove ( ) ;
2010-01-30 14:03:01 +00:00
SN . U . FormNoticeEnhancements ( form ) ;
2009-10-30 12:15:11 +00:00
}
} ,
complete : function ( xhr , textStatus ) {
2010-01-30 14:19:13 +00:00
form
. removeClass ( SN . C . S . Processing )
. find ( '#' + SN . C . S . NoticeActionSubmit )
. removeAttr ( SN . C . S . Disabled )
. removeClass ( SN . C . S . Disabled ) ;
2010-01-05 01:15:08 +00:00
2010-01-30 14:28:31 +00:00
$ ( '#' + SN . C . S . NoticeLat ) . val ( SN . C . I . NoticeDataGeo . NLat ) ;
$ ( '#' + SN . C . S . NoticeLon ) . val ( SN . C . I . NoticeDataGeo . NLon ) ;
2010-01-22 00:27:08 +00:00
if ( $ ( '#' + SN . C . S . NoticeLocationNs ) ) {
2010-01-30 14:28:31 +00:00
$ ( '#' + SN . C . S . NoticeLocationNs ) . val ( SN . C . I . NoticeDataGeo . NLNS ) ;
$ ( '#' + SN . C . S . NoticeLocationId ) . val ( SN . C . I . NoticeDataGeo . NLID ) ;
2010-01-22 00:27:08 +00:00
}
2010-01-30 14:28:31 +00:00
$ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' , SN . C . I . NoticeDataGeo . NDG ) ;
2009-10-30 12:15:11 +00:00
}
} ) ;
2009-10-30 12:56:01 +00:00
} ,
2010-11-17 22:24:35 +00:00
GetResponseXML : function ( xhr ) {
// Work around unavailable responseXML when document.domain
// has been modified by Meteor or other tools.
try {
return xhr . responseXML ;
} catch ( e ) {
return ( new DOMParser ( ) ) . parseFromString ( xhr . responseText , "text/xml" ) ;
}
} ,
2009-10-30 12:56:01 +00:00
NoticeReply : function ( ) {
if ( $ ( '#' + SN . C . S . NoticeDataText ) . length > 0 && $ ( '#content .notice_reply' ) . length > 0 ) {
2009-11-28 15:44:16 +00:00
$ ( '#content .notice' ) . each ( function ( ) { SN . U . NoticeReplyTo ( $ ( this ) ) ; } ) ;
}
} ,
2010-02-25 13:51:23 +00:00
NoticeReplyTo : function ( notice ) {
notice . find ( '.notice_reply' ) . live ( '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 ;
} ) ;
2009-10-30 12:56:01 +00:00
} ,
2009-10-30 12:56:53 +00:00
NoticeReplySet : function ( nick , id ) {
2009-10-30 12:56:01 +00:00
if ( nick . match ( SN . C . I . PatternUsername ) ) {
var text = $ ( '#' + SN . C . S . NoticeDataText ) ;
2009-11-27 17:11:49 +00:00
if ( text . length > 0 ) {
2009-10-30 12:56:01 +00:00
replyto = '@' + nick + ' ' ;
text . val ( replyto + text . val ( ) . replace ( RegExp ( replyto , 'i' ) , '' ) ) ;
2009-11-27 17:11:49 +00:00
$ ( '#' + SN . C . S . FormNotice + ' #' + SN . C . S . NoticeInReplyTo ) . val ( id ) ;
2009-11-27 17:35:58 +00:00
text [ 0 ] . focus ( ) ;
if ( text [ 0 ] . setSelectionRange ) {
var len = text . val ( ) . length ;
2009-11-02 13:28:14 +00:00
text [ 0 ] . setSelectionRange ( len , len ) ;
2009-10-30 12:56:01 +00:00
}
}
}
2009-10-30 13:02:51 +00:00
} ,
2009-11-13 20:56:55 +00:00
NoticeFavor : function ( ) {
2010-01-31 22:37:22 +00:00
$ ( '.form_favor' ) . live ( 'click' , function ( ) { SN . U . FormXHR ( $ ( this ) ) ; return false ; } ) ;
$ ( '.form_disfavor' ) . live ( 'click' , function ( ) { SN . U . FormXHR ( $ ( this ) ) ; return false ; } ) ;
2009-11-13 20:56:55 +00:00
} ,
2009-12-11 15:12:34 +00:00
NoticeRepeat : function ( ) {
2010-02-10 10:16:27 +00:00
$ ( '.form_repeat' ) . live ( 'click' , function ( e ) {
e . preventDefault ( ) ;
2009-12-23 20:42:37 +00:00
SN . U . NoticeRepeatConfirmation ( $ ( this ) ) ;
2010-01-31 22:37:22 +00:00
return false ;
2009-12-23 20:42:37 +00:00
} ) ;
} ,
NoticeRepeatConfirmation : function ( form ) {
2010-02-10 10:16:27 +00:00
var submit _i = form . find ( '.submit' ) ;
2009-12-23 20:42:37 +00:00
2010-02-10 10:16:27 +00:00
var submit = submit _i . clone ( ) ;
submit
. addClass ( 'submit_dialogbox' )
. removeClass ( 'submit' ) ;
form . append ( submit ) ;
submit . bind ( 'click' , function ( ) { SN . U . FormXHR ( form ) ; return false ; } ) ;
2009-12-23 20:42:37 +00:00
2010-02-10 10:16:27 +00:00
submit _i . hide ( ) ;
2009-12-23 20:42:37 +00:00
2010-02-10 10:16:27 +00:00
form
. addClass ( 'dialogbox' )
. append ( '<button class="close">×</button>' )
. closest ( '.notice-options' )
. addClass ( 'opaque' ) ;
2009-12-23 20:42:37 +00:00
2010-02-10 10:16:27 +00:00
form . find ( 'button.close' ) . click ( function ( ) {
$ ( this ) . remove ( ) ;
2009-12-23 20:42:37 +00:00
2010-02-10 10:16:27 +00:00
form
. removeClass ( 'dialogbox' )
. closest ( '.notice-options' )
. removeClass ( 'opaque' ) ;
2009-12-23 20:42:37 +00:00
2010-02-10 10:16:27 +00:00
form . find ( '.submit_dialogbox' ) . remove ( ) ;
form . find ( '.submit' ) . show ( ) ;
2009-12-23 20:42:37 +00:00
2010-02-10 10:16:27 +00:00
return false ;
2009-12-23 20:42:37 +00:00
} ) ;
2009-12-11 15:10:53 +00:00
} ,
2009-10-30 13:02:51 +00:00
NoticeAttachments : function ( ) {
2009-12-08 22:31:23 +00:00
$ ( '.notice a.attachment' ) . each ( function ( ) {
2009-11-29 19:05:39 +00:00
SN . U . NoticeWithAttachment ( $ ( this ) . closest ( '.notice' ) ) ;
} ) ;
} ,
NoticeWithAttachment : function ( notice ) {
2010-02-16 16:09:34 +00:00
if ( notice . find ( '.attachment' ) . length === 0 ) {
2009-11-29 19:18:17 +00:00
return ;
}
2010-03-17 23:19:32 +00:00
var attachment _more = notice . find ( '.attachment.more' ) ;
if ( attachment _more . length > 0 ) {
2010-03-26 13:56:15 +00:00
$ ( attachment _more [ 0 ] ) . click ( function ( ) {
var m = $ ( this ) ;
m . addClass ( SN . C . S . Processing ) ;
$ . get ( m . attr ( 'href' ) + '/ajax' , null , function ( data ) {
m . parent ( '.entry-content' ) . html ( $ ( data ) . find ( '#attachment_view .entry-content' ) . html ( ) ) ;
2010-03-17 23:19:32 +00:00
} ) ;
2009-10-30 13:02:51 +00:00
2010-03-17 23:19:32 +00:00
return false ;
2010-11-02 20:05:16 +00:00
} ) . attr ( 'title' , SN . msg ( 'showmore_tooltip' ) ) ;
2010-03-17 23:19:32 +00:00
}
2009-10-30 13:16:38 +00:00
} ,
2010-03-31 09:57:20 +01:00
NoticeDataAttach : function ( ) {
NDA = $ ( '#' + SN . C . S . NoticeDataAttach ) ;
2009-10-30 13:16:38 +00:00
NDA . change ( function ( ) {
2010-03-31 09:57:20 +01:00
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 ( ) ;
2009-10-30 13:16:38 +00:00
NDA . val ( '' ) ;
2010-01-03 02:00:12 +00:00
return false ;
2009-10-30 13:16:38 +00:00
} ) ;
} ) ;
2009-10-31 15:14:38 +00:00
} ,
2009-11-19 20:17:18 +00:00
NoticeLocationAttach : function ( ) {
2010-01-04 23:36:22 +00:00
var NLat = $ ( '#' + SN . C . S . NoticeLat ) . val ( ) ;
var NLon = $ ( '#' + SN . C . S . NoticeLon ) . val ( ) ;
2010-01-05 01:15:08 +00:00
var NLNS = $ ( '#' + SN . C . S . NoticeLocationNs ) . val ( ) ;
var NLID = $ ( '#' + SN . C . S . NoticeLocationId ) . val ( ) ;
2010-01-08 13:58:23 +00:00
var NLN = $ ( '#' + SN . C . S . NoticeGeoName ) . text ( ) ;
2010-01-08 13:36:52 +00:00
var NDGe = $ ( '#' + SN . C . S . NoticeDataGeo ) ;
2010-01-04 23:36:22 +00:00
2010-01-04 13:44:32 +00:00
function removeNoticeDataGeo ( ) {
2010-01-14 01:48:57 +00:00
$ ( 'label[for=' + SN . C . S . NoticeDataGeo + ']' )
. attr ( 'title' , jQuery . trim ( $ ( 'label[for=' + SN . C . S . NoticeDataGeo + ']' ) . text ( ) ) )
. removeClass ( 'checked' ) ;
2010-01-08 13:36:52 +00:00
2010-01-04 13:44:32 +00:00
$ ( '#' + SN . C . S . NoticeLat ) . val ( '' ) ;
$ ( '#' + SN . C . S . NoticeLon ) . val ( '' ) ;
$ ( '#' + SN . C . S . NoticeLocationNs ) . val ( '' ) ;
$ ( '#' + SN . C . S . NoticeLocationId ) . val ( '' ) ;
2010-01-08 13:36:52 +00:00
$ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' , false ) ;
2010-03-03 00:15:24 +00:00
$ . cookie ( SN . C . S . NoticeDataGeoCookie , 'disabled' , { path : '/' } ) ;
2010-01-04 13:44:32 +00:00
}
2010-01-18 12:55:14 +00:00
function getJSONgeocodeURL ( geocodeURL , data ) {
2010-01-04 23:36:22 +00:00
$ . getJSON ( geocodeURL , data , function ( location ) {
2010-01-08 13:36:52 +00:00
var lns , lid ;
2010-01-04 23:36:22 +00:00
if ( typeof ( location . location _ns ) != 'undefined' ) {
$ ( '#' + SN . C . S . NoticeLocationNs ) . val ( location . location _ns ) ;
2010-01-08 13:36:52 +00:00
lns = location . location _ns ;
2010-01-04 23:36:22 +00:00
}
if ( typeof ( location . location _id ) != 'undefined' ) {
$ ( '#' + SN . C . S . NoticeLocationId ) . val ( location . location _id ) ;
2010-01-08 13:36:52 +00:00
lid = location . location _id ;
2010-01-04 23:36:22 +00:00
}
if ( typeof ( location . name ) == 'undefined' ) {
2010-01-18 12:55:14 +00:00
NLN _text = data . lat + ';' + data . lon ;
2010-01-04 23:36:22 +00:00
}
else {
NLN _text = location . name ;
}
2010-01-14 01:48:57 +00:00
$ ( 'label[for=' + SN . C . S . NoticeDataGeo + ']' )
. attr ( 'title' , NoticeDataGeo _text . ShareDisable + ' (' + NLN _text + ')' ) ;
2010-01-08 13:36:52 +00:00
$ ( '#' + SN . C . S . NoticeLat ) . val ( data . lat ) ;
$ ( '#' + SN . C . S . NoticeLon ) . val ( data . lon ) ;
$ ( '#' + SN . C . S . NoticeLocationNs ) . val ( lns ) ;
$ ( '#' + SN . C . S . NoticeLocationId ) . val ( lid ) ;
$ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' , true ) ;
var cookieValue = {
2010-01-16 19:44:37 +00:00
NLat : data . lat ,
NLon : data . lon ,
NLNS : lns ,
NLID : lid ,
NLN : NLN _text ,
NLNU : location . url ,
NDG : true
2010-01-08 13:36:52 +00:00
} ;
2010-01-25 14:55:04 +00:00
2010-03-03 00:15:24 +00:00
$ . cookie ( SN . C . S . NoticeDataGeoCookie , JSON . stringify ( cookieValue ) , { path : '/' } ) ;
2010-01-04 23:36:22 +00:00
} ) ;
}
2010-01-05 00:37:53 +00:00
2010-01-08 13:36:52 +00:00
if ( NDGe . length > 0 ) {
2010-01-08 16:43:03 +00:00
if ( $ . cookie ( SN . C . S . NoticeDataGeoCookie ) == 'disabled' ) {
2010-01-08 13:36:52 +00:00
NDGe . attr ( 'checked' , false ) ;
}
else {
NDGe . attr ( 'checked' , true ) ;
}
2010-01-05 01:31:34 +00:00
2010-01-08 13:58:23 +00:00
var NGW = $ ( '#notice_data-geo_wrap' ) ;
var geocodeURL = NGW . attr ( 'title' ) ;
NGW . removeAttr ( 'title' ) ;
2009-12-31 18:27:05 +00:00
2010-01-14 01:48:57 +00:00
$ ( 'label[for=' + SN . C . S . NoticeDataGeo + ']' )
. attr ( 'title' , jQuery . trim ( $ ( 'label[for=' + SN . C . S . NoticeDataGeo + ']' ) . text ( ) ) ) ;
2009-12-31 18:08:21 +00:00
2010-01-08 13:36:52 +00:00
NDGe . change ( function ( ) {
2010-01-08 16:43:03 +00:00
if ( $ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' ) === true || $ . cookie ( SN . C . S . NoticeDataGeoCookie ) === null ) {
2010-01-14 01:48:57 +00:00
$ ( 'label[for=' + SN . C . S . NoticeDataGeo + ']' )
. attr ( 'title' , NoticeDataGeo _text . ShareDisable )
. addClass ( 'checked' ) ;
2010-01-03 01:48:41 +00:00
2010-01-08 16:43:03 +00:00
if ( $ . cookie ( SN . C . S . NoticeDataGeoCookie ) === null || $ . cookie ( SN . C . S . NoticeDataGeoCookie ) == 'disabled' ) {
2010-01-08 13:36:52 +00:00
if ( navigator . geolocation ) {
navigator . geolocation . getCurrentPosition (
function ( position ) {
$ ( '#' + SN . C . S . NoticeLat ) . val ( position . coords . latitude ) ;
$ ( '#' + SN . C . S . NoticeLon ) . val ( position . coords . longitude ) ;
var data = {
2010-01-16 19:44:37 +00:00
lat : position . coords . latitude ,
lon : position . coords . longitude ,
token : $ ( '#token' ) . val ( )
2010-01-08 13:36:52 +00:00
} ;
2010-01-18 12:55:14 +00:00
getJSONgeocodeURL ( geocodeURL , data ) ;
2010-01-08 13:36:52 +00:00
} ,
function ( error ) {
2010-01-13 15:36:42 +00:00
switch ( error . code ) {
case error . PERMISSION _DENIED :
removeNoticeDataGeo ( ) ;
break ;
case error . TIMEOUT :
2010-01-13 15:51:32 +00:00
$ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' , false ) ;
2010-01-13 15:36:42 +00:00
break ;
2010-01-08 13:36:52 +00:00
}
2010-01-13 15:36:42 +00:00
} ,
{
2010-01-13 15:50:45 +00:00
timeout : 10000
2010-01-08 13:36:52 +00:00
}
) ;
}
else {
if ( NLat . length > 0 && NLon . length > 0 ) {
2010-01-04 09:52:35 +00:00
var data = {
2010-01-18 12:55:14 +00:00
lat : NLat ,
lon : NLon ,
token : $ ( '#token' ) . val ( )
2010-01-04 09:52:35 +00:00
} ;
2010-01-18 12:55:14 +00:00
getJSONgeocodeURL ( geocodeURL , data ) ;
2010-01-04 09:52:35 +00:00
}
2010-01-08 13:36:52 +00:00
else {
removeNoticeDataGeo ( ) ;
$ ( '#' + SN . C . S . NoticeDataGeo ) . remove ( ) ;
$ ( 'label[for=' + SN . C . S . NoticeDataGeo + ']' ) . remove ( ) ;
}
}
2009-12-31 16:25:51 +00:00
}
else {
2010-01-08 16:43:03 +00:00
var cookieValue = JSON . parse ( $ . cookie ( SN . C . S . NoticeDataGeoCookie ) ) ;
2010-01-08 14:23:37 +00:00
2010-01-08 13:36:52 +00:00
$ ( '#' + SN . C . S . NoticeLat ) . val ( cookieValue . NLat ) ;
$ ( '#' + SN . C . S . NoticeLon ) . val ( cookieValue . NLon ) ;
$ ( '#' + SN . C . S . NoticeLocationNs ) . val ( cookieValue . NLNS ) ;
$ ( '#' + SN . C . S . NoticeLocationId ) . val ( cookieValue . NLID ) ;
$ ( '#' + SN . C . S . NoticeDataGeo ) . attr ( 'checked' , cookieValue . NDG ) ;
2010-01-14 01:48:57 +00:00
$ ( 'label[for=' + SN . C . S . NoticeDataGeo + ']' )
. attr ( 'title' , NoticeDataGeo _text . ShareDisable + ' (' + cookieValue . NLN + ')' )
. addClass ( 'checked' ) ;
2009-12-29 21:17:17 +00:00
}
2010-01-04 23:36:22 +00:00
}
else {
removeNoticeDataGeo ( ) ;
}
} ) . change ( ) ;
2009-12-29 21:17:17 +00:00
}
2009-11-19 20:17:18 +00:00
} ,
2009-10-31 15:14:38 +00:00
NewDirectMessage : function ( ) {
NDM = $ ( '.entity_send-a-message a' ) ;
NDM . attr ( { 'href' : NDM . attr ( 'href' ) + '&ajax=1' } ) ;
2009-11-27 13:42:30 +00:00
NDM . bind ( 'click' , function ( ) {
2009-10-31 15:14:38 +00:00
var NDMF = $ ( '.entity_send-a-message form' ) ;
2009-11-02 17:06:52 +00:00
if ( NDMF . length === 0 ) {
2010-02-01 14:13:54 +00:00
$ ( this ) . addClass ( SN . C . S . Processing ) ;
2009-10-31 15:14:38 +00:00
$ . get ( NDM . attr ( 'href' ) , null , function ( data ) {
2009-11-02 13:28:14 +00:00
$ ( '.entity_send-a-message' ) . append ( document . _importNode ( $ ( 'form' , data ) [ 0 ] , true ) ) ;
2009-10-31 17:01:19 +00:00
NDMF = $ ( '.entity_send-a-message .form_notice' ) ;
2009-11-02 17:56:55 +00:00
SN . U . FormNoticeXHR ( NDMF ) ;
2009-10-31 17:55:13 +00:00
SN . U . FormNoticeEnhancements ( NDMF ) ;
2009-11-01 19:53:25 +00:00
NDMF . append ( '<button class="close">×</button>' ) ;
2009-10-31 15:14:38 +00:00
$ ( '.entity_send-a-message button' ) . click ( function ( ) {
NDMF . hide ( ) ;
return false ;
} ) ;
2010-02-01 14:13:54 +00:00
NDM . removeClass ( SN . C . S . Processing ) ;
2009-10-31 15:14:38 +00:00
} ) ;
}
else {
NDMF . show ( ) ;
$ ( '.entity_send-a-message textarea' ) . focus ( ) ;
}
return false ;
} ) ;
2010-01-25 14:55:04 +00:00
} ,
2010-01-26 00:58:10 +00:00
GetFullYear : function ( year , month , day ) {
2010-01-25 14:55:04 +00:00
var date = new Date ( ) ;
2010-01-26 00:58:10 +00:00
date . setFullYear ( year , month , day ) ;
2010-01-25 14:55:04 +00:00
return date ;
2010-02-24 15:35:20 +00:00
} ,
StatusNetInstance : {
Set : function ( value ) {
var SNI = SN . U . StatusNetInstance . Get ( ) ;
if ( SNI !== null ) {
value = $ . extend ( SNI , value ) ;
}
$ . cookie (
SN . C . S . StatusNetInstance ,
JSON . stringify ( value ) ,
{
path : '/' ,
expires : SN . U . GetFullYear ( 2029 , 0 , 1 )
} ) ;
} ,
Get : function ( ) {
var cookieValue = $ . cookie ( SN . C . S . StatusNetInstance ) ;
if ( cookieValue !== null ) {
return JSON . parse ( cookieValue ) ;
}
return null ;
} ,
Delete : function ( ) {
$ . cookie ( SN . C . S . StatusNetInstance , null ) ;
}
2010-07-29 21:27:09 +01:00
} ,
/ * *
* Check if the current page is a timeline where the current user ' s
* posts should be displayed immediately on success .
*
* @ fixme this should be done in a saner way , with machine - readable
* info about what page we ' re looking at .
* /
belongsOnTimeline : function ( notice ) {
var action = $ ( "body" ) . attr ( 'id' ) ;
if ( action == 'public' ) {
return true ;
}
var profileLink = $ ( '#nav_profile a' ) . attr ( 'href' ) ;
if ( profileLink ) {
var authorUrl = $ ( notice ) . find ( '.entry-title .author a.url' ) . attr ( 'href' ) ;
if ( authorUrl == profileLink ) {
if ( action == 'all' || action == 'showstream' ) {
// Posts always show on your own friends and profile streams.
return true ;
}
}
}
// @fixme tag, group, reply timelines should be feasible as well.
// Mismatch between id-based and name-based user/group links currently complicates
// the lookup, since all our inline mentions contain the absolute links but the
// UI links currently on the page use malleable names.
return false ;
2009-10-30 11:40:08 +00:00
}
2009-11-11 18:20:58 +00:00
} ,
2009-11-02 17:06:52 +00:00
2009-11-11 18:20:58 +00:00
Init : {
2009-11-11 18:47:14 +00:00
NoticeForm : function ( ) {
2009-11-11 18:20:58 +00:00
if ( $ ( 'body.user_in' ) . length > 0 ) {
2010-01-08 13:36:52 +00:00
SN . U . NoticeLocationAttach ( ) ;
2009-11-11 18:20:58 +00:00
$ ( '.' + SN . C . S . FormNotice ) . each ( function ( ) {
SN . U . FormNoticeXHR ( $ ( this ) ) ;
SN . U . FormNoticeEnhancements ( $ ( this ) ) ;
} ) ;
2009-11-02 17:06:52 +00:00
2010-03-31 09:57:20 +01:00
SN . U . NoticeDataAttach ( ) ;
2009-11-11 18:47:14 +00:00
}
} ,
Notices : function ( ) {
if ( $ ( 'body.user_in' ) . length > 0 ) {
2009-11-13 20:56:55 +00:00
SN . U . NoticeFavor ( ) ;
2009-12-11 15:12:34 +00:00
SN . U . NoticeRepeat ( ) ;
2009-11-11 18:20:58 +00:00
SN . U . NoticeReply ( ) ;
2009-11-11 18:47:14 +00:00
}
2009-11-02 17:06:52 +00:00
2009-11-11 18:47:14 +00:00
SN . U . NoticeAttachments ( ) ;
} ,
EntityActions : function ( ) {
if ( $ ( 'body.user_in' ) . length > 0 ) {
2010-01-31 22:37:22 +00:00
$ ( '.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 ; } ) ;
2009-12-10 13:29:27 +00:00
SN . U . NewDirectMessage ( ) ;
2009-11-11 18:20:58 +00:00
}
2010-02-24 15:39:16 +00:00
} ,
Login : function ( ) {
if ( SN . U . StatusNetInstance . Get ( ) !== null ) {
var nickname = SN . U . StatusNetInstance . Get ( ) . Nickname ;
if ( nickname !== null ) {
$ ( '#form_login #nickname' ) . val ( nickname ) ;
}
}
$ ( '#form_login' ) . bind ( 'submit' , function ( ) {
SN . U . StatusNetInstance . Set ( { Nickname : $ ( '#form_login #nickname' ) . val ( ) } ) ;
return true ;
} ) ;
2009-11-11 18:20:58 +00:00
}
2009-11-02 17:06:52 +00:00
}
2009-11-11 18:20:58 +00:00
} ;
2009-11-02 17:06:52 +00:00
2009-11-11 18:20:58 +00:00
$ ( document ) . ready ( function ( ) {
2009-11-11 18:47:14 +00:00
if ( $ ( '.' + SN . C . S . FormNotice ) . length > 0 ) {
SN . Init . NoticeForm ( ) ;
}
if ( $ ( '#content .notices' ) . length > 0 ) {
2009-11-11 18:20:58 +00:00
SN . Init . Notices ( ) ;
}
2009-11-11 18:47:14 +00:00
if ( $ ( '#content .entity_actions' ) . length > 0 ) {
SN . Init . EntityActions ( ) ;
}
2010-02-24 15:39:16 +00:00
if ( $ ( '#form_login' ) . length > 0 ) {
SN . Init . Login ( ) ;
}
2009-11-02 17:06:52 +00:00
} ) ;
2010-09-03 03:21:07 +01:00
// Formerly in xbImportNode.js
/* is this stuff defined? */
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 ( node , allChildren ) {
/* find the node type to import */
switch ( node . nodeType ) {
case document . ELEMENT _NODE :
/* create a new element */
var newNode = document . createElement ( node . nodeName ) ;
/* does the node have any attributes to add? */
if ( node . attributes && node . attributes . length > 0 )
/* add all of the attributes */
for ( var i = 0 , il = node . attributes . length ; i < il ; ) {
if ( node . attributes [ i ] . nodeName == 'class' ) {
newNode . className = node . getAttribute ( node . attributes [ i ++ ] . nodeName ) ;
} else {
newNode . setAttribute ( node . attributes [ i ] . nodeName , node . getAttribute ( node . attributes [ i ++ ] . nodeName ) ) ;
}
}
/* are we going after children too, and does the node have any? */
if ( allChildren && node . childNodes && node . childNodes . length > 0 )
/* recursively get all of the child nodes */
for ( var i = 0 , il = node . childNodes . length ; i < il ; )
newNode . appendChild ( document . _importNode ( node . childNodes [ i ++ ] , allChildren ) ) ;
return newNode ;
break ;
case document . TEXT _NODE :
case document . CDATA _SECTION _NODE :
case document . COMMENT _NODE :
return document . createTextNode ( node . nodeValue ) ;
break ;
}
} ;
// 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 = ( document . location . protocol == "https:" ? "https://" : "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 = {
coords : {
latitude : cl . latitude ,
longitude : cl . longitude ,
altitude : null ,
accuracy : 43000 , // same as Gears accuracy over wifi?
altitudeAccuracy : null ,
heading : null ,
speed : null
} ,
// 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
} ,
timestamp : new Date ( )
} ;
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 ( ) ;
} ) ( ) ;
}