diff --git a/actions/all.php b/actions/all.php index 2936df4599..2826319c0d 100644 --- a/actions/all.php +++ b/actions/all.php @@ -127,12 +127,6 @@ class AllAction extends ProfileAction ); } - function showLocalNav() - { - $nav = new PersonalGroupNav($this); - $nav->show(); - } - function showEmptyListMessage() { // TRANS: Empty list message. %s is a user nickname. diff --git a/actions/blockedfromgroup.php b/actions/blockedfromgroup.php index 6ff572c05d..dd916b170a 100644 --- a/actions/blockedfromgroup.php +++ b/actions/blockedfromgroup.php @@ -122,7 +122,7 @@ class BlockedfromgroupAction extends GroupDesignAction _('A list of the users blocked from joining this group.')); } - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); diff --git a/actions/editgroup.php b/actions/editgroup.php index 0e04170051..08a75da12c 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -139,7 +139,7 @@ class EditgroupAction extends GroupDesignAction $this->showPage(); } - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); diff --git a/actions/favorited.php b/actions/favorited.php index c137cf424f..17c2a58c94 100644 --- a/actions/favorited.php +++ b/actions/favorited.php @@ -163,19 +163,6 @@ class FavoritedAction extends Action $this->elementEnd('div'); } - /** - * Local navigation - * - * This page is part of the public group, so show that. - * - * @return void - */ - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - /** * Content area * diff --git a/actions/featured.php b/actions/featured.php index 9a7f128b57..394cfe6a8b 100644 --- a/actions/featured.php +++ b/actions/featured.php @@ -90,12 +90,6 @@ class FeaturedAction extends Action $this->elementEnd('div'); } - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - function getInstructions() { // TRANS: Description on page displaying featured users. diff --git a/actions/groupdesignsettings.php b/actions/groupdesignsettings.php index 3ef5e20e44..798064d16c 100644 --- a/actions/groupdesignsettings.php +++ b/actions/groupdesignsettings.php @@ -163,12 +163,22 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return nothing */ - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); } + /** + * Override to show default nav stuff + * + * @return nothing + */ + function showLocalNav() + { + Action::showLocalNav(); + } + /** * Get the design we want to edit * diff --git a/actions/grouplogo.php b/actions/grouplogo.php index d490cd9875..db0d40ff0c 100644 --- a/actions/grouplogo.php +++ b/actions/grouplogo.php @@ -458,7 +458,7 @@ class GrouplogoAction extends GroupDesignAction $this->autofocus('avatarfile'); } - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 7b1512dfab..e280fd1fd1 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -125,7 +125,7 @@ class GroupmembersAction extends GroupDesignAction _('A list of the users in this group.')); } - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); diff --git a/actions/groups.php b/actions/groups.php index 958c5921bf..d1bc8d9458 100644 --- a/actions/groups.php +++ b/actions/groups.php @@ -80,12 +80,6 @@ class GroupsAction extends Action $this->showPage(); } - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - function showPageNotice() { $notice = diff --git a/actions/invite.php b/actions/invite.php index a2a0e0714a..c64ff8adda 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -289,7 +289,7 @@ class InviteAction extends CurrentUserDesignAction mail_send($recipients, $headers, $body); } - function showLocalNav() + function showObjectNav() { $nav = new SubGroupNav($this, common_current_user()); $nav->show(); diff --git a/actions/public.php b/actions/public.php index 727c76d528..adeb58b0ee 100644 --- a/actions/public.php +++ b/actions/public.php @@ -168,21 +168,6 @@ class PublicAction extends Action _('Public Stream Feed (Atom)'))); } - /** - * Show tabset for this page - * - * Uses the PublicGroupNav widget - * - * @return void - * @see PublicGroupNav - */ - - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - function showEmptyList() { $message = _('This is the public timeline for %%site.name%% but no one has posted anything yet.') . ' '; diff --git a/actions/publictagcloud.php b/actions/publictagcloud.php index f6f1d31625..1432ca66a8 100644 --- a/actions/publictagcloud.php +++ b/actions/publictagcloud.php @@ -92,12 +92,6 @@ class PublictagcloudAction extends Action $this->elementEnd('div'); } - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - function handle($args) { parent::handle($args); diff --git a/actions/replies.php b/actions/replies.php index 8f2fc6c7f3..fd178175d2 100644 --- a/actions/replies.php +++ b/actions/replies.php @@ -160,18 +160,6 @@ class RepliesAction extends OwnerDesignAction $this->user->nickname))); } - /** - * show the personal group nav - * - * @return void - */ - - function showLocalNav() - { - $nav = new PersonalGroupNav($this); - $nav->show(); - } - /** * Show the content * diff --git a/actions/showfavorites.php b/actions/showfavorites.php index eda2cf38eb..67ee914a91 100644 --- a/actions/showfavorites.php +++ b/actions/showfavorites.php @@ -189,17 +189,6 @@ class ShowfavoritesAction extends OwnerDesignAction $this->user->nickname))); } - /** - * show the personal group nav - * - * @return void - */ - function showLocalNav() - { - $nav = new PersonalGroupNav($this); - $nav->show(); - } - function showEmptyListMessage() { if (common_logged_in()) { diff --git a/actions/showgroup.php b/actions/showgroup.php index a38945c131..411940ef9a 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -167,7 +167,7 @@ class ShowgroupAction extends GroupDesignAction * * @return void */ - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); diff --git a/actions/showstream.php b/actions/showstream.php index 0fd1c2c29f..afde49ecea 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -104,7 +104,7 @@ class ShowstreamAction extends ProfileAction $this->showNotices(); } - function showLocalNav() + function showObjectNav() { $nav = new SubGroupNav($this, $this->user); $nav->show(); diff --git a/actions/usergroups.php b/actions/usergroups.php index 6606e76cdb..cf904bc929 100644 --- a/actions/usergroups.php +++ b/actions/usergroups.php @@ -112,7 +112,7 @@ class UsergroupsAction extends OwnerDesignAction $this->showPage(); } - function showLocalNav() + function showObjectNav() { $nav = new SubGroupNav($this, $this->user); $nav->show(); diff --git a/classes/Notice.php b/classes/Notice.php index 157fdf2dc4..d520f4728f 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -72,6 +72,7 @@ class Notice extends Memcached_DataObject public $location_id; // int(4) public $location_ns; // int(4) public $repeat_of; // int(4) + public $object_type; // varchar(255) /* Static get */ function staticGet($k,$v=NULL) @@ -241,6 +242,7 @@ class Notice extends Memcached_DataObject * array 'urls' list of attached/referred URLs to save with the * notice in place of extracting links from content * boolean 'distribute' whether to distribute the notice, default true + * string 'object_type' URL of the associated object type (default ActivityObject::NOTE) * * @fixme tag override * @@ -360,6 +362,12 @@ class Notice extends Memcached_DataObject $notice->rendered = common_render_content($final, $notice); } + if (empty($object_type)) { + $notice->object_type = (empty($notice->reply_to)) ? ActivityObject::NOTE : ActivityObject::COMMENT; + } else { + $notice->object_type = $object_type; + } + if (Event::handle('StartNoticeSave', array(&$notice))) { // XXX: some of these functions write to the DB diff --git a/classes/statusnet.ini b/classes/statusnet.ini index bf8d173805..338e5c5aea 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -336,6 +336,7 @@ lon = 1 location_id = 1 location_ns = 1 repeat_of = 1 +object_type = 2 [notice__keys] id = N diff --git a/db/core.php b/db/core.php index 55d724b505..16a59462d4 100644 --- a/db/core.php +++ b/db/core.php @@ -201,6 +201,7 @@ $schema['notice'] = array( 'location_id' => array('type' => 'int', 'description' => 'location id if possible'), 'location_ns' => array('type' => 'int', 'description' => 'namespace for location'), 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'), + 'object_type' => array('type' => 'varchar', 'length' => 255, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'), ), 'primary key' => array('id'), 'unique keys' => array( diff --git a/js/util.js b/js/util.js index cc94c5ced7..fc03bc75fe 100644 --- a/js/util.js +++ b/js/util.js @@ -31,7 +31,8 @@ var SN = { // StatusNet 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] + HTTP20x30x: [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307], + NoticeFormMaster: null // to be cloned from the one at top }, /** @@ -600,10 +601,10 @@ var SN = { // StatusNet // Create the reply form entry at the end var replyItem = $('li.notice-reply', list); if (replyItem.length == 0) { - var url = $('#form_notice').attr('action'); replyItem = $('<li class="notice-reply"></li>'); - $.get(url, {ajax: 1}, function(data, textStatus, xhr) { - var formEl = document._importNode($('form', data)[0], true); + + var intermediateStep = function(formMaster) { + var formEl = document._importNode(formMaster, true); replyItem.append(formEl); list.append(replyItem); @@ -614,7 +615,20 @@ var SN = { // StatusNet SN.U.NoticeDataAttach(form); nextStep(); - }); + }; + if (SN.C.I.NoticeFormMaster) { + // We've already saved a master copy of the form. + // Clone it in! + intermediateStep(SN.C.I.NoticeFormMaster); + } else { + // Fetch a fresh copy of the notice form over AJAX. + // Warning: this can have a delay, which looks bad. + // @fixme this fallback may or may not work + var url = $('#form_notice').attr('action'); + $.get(url, {ajax: 1}, function(data, textStatus, xhr) { + intermediateStep($('form', data)[0]); + }); + } } } }, @@ -1272,7 +1286,16 @@ var SN = { // StatusNet // UI links currently on the page use malleable names. return false; - } + }, + + switchInputFormTab: function(tag) { + // The one that's current isn't current anymore + $('.input_form_nav_tab.current').removeClass('current'); + $('#input_form_nav_'+tag).addClass('current'); + + $('.input_form.current').removeClass('current'); + $('#input_form_'+tag).addClass('current'); + } }, Init: { @@ -1304,6 +1327,10 @@ var SN = { // StatusNet */ Notices: function() { if ($('body.user_in').length > 0) { + var masterForm = $('.form_notice:first'); + if (masterForm.length > 0) { + SN.C.I.NoticeFormMaster = document._importNode(masterForm[0], true); + } SN.U.NoticeFavor(); SN.U.NoticeRepeat(); SN.U.NoticeReply(); diff --git a/js/util.min.js b/js/util.min.js index 280aca6a45..af8b2200e9 100644 --- a/js/util.min.js +++ b/js/util.min.js @@ -1 +1 @@ -var SN={C:{I:{CounterBlackout:false,MaxLength:140,PatternUsername:/^[0-9a-zA-Z\-_.]*$/,HTTP20x30x:[200,201,202,203,204,205,206,300,301,302,303,304,305,306,307]},S:{Disabled:"disabled",Warning:"warning",Error:"error",Success:"success",Processing:"processing",CommandResult:"command_result",FormNotice:"form_notice",NoticeDataGeo:"notice_data-geo",NoticeDataGeoCookie:"NoticeDataGeo",NoticeDataGeoSelected:"notice_data-geo_selected",StatusNetInstance:"StatusNetInstance"}},messages:{},msg:function(a){if(typeof SN.messages[a]=="undefined"){return"["+a+"]"}else{return SN.messages[a]}},U:{FormNoticeEnhancements:function(b){if(jQuery.data(b[0],"ElementData")===undefined){MaxLength=b.find(".count").text();if(typeof(MaxLength)=="undefined"){MaxLength=SN.C.I.MaxLength}jQuery.data(b[0],"ElementData",{MaxLength:MaxLength});SN.U.Counter(b);NDT=b.find("[name=status_textarea]");NDT.bind("keyup",function(c){SN.U.Counter(b)});var a=function(c){window.setTimeout(function(){SN.U.Counter(b)},50)};NDT.bind("cut",a).bind("paste",a)}else{b.find(".count").text(jQuery.data(b[0],"ElementData").MaxLength)}},Counter:function(d){SN.C.I.FormNoticeCurrent=d;var b=jQuery.data(d[0],"ElementData").MaxLength;if(b<=0){return}var c=b-SN.U.CharacterCount(d);var a=d.find(".count");if(c.toString()!=a.text()){if(!SN.C.I.CounterBlackout||c===0){if(a.text()!=String(c)){a.text(c)}if(c<0){d.addClass(SN.C.S.Warning)}else{d.removeClass(SN.C.S.Warning)}if(!SN.C.I.CounterBlackout){SN.C.I.CounterBlackout=true;SN.C.I.FormNoticeCurrent=d;window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);",500)}}}},CharacterCount:function(a){return a.find("[name=status_textarea]").val().length},ClearCounterBlackout:function(a){SN.C.I.CounterBlackout=false;SN.U.Counter(a)},RewriteAjaxAction:function(a){if(document.location.protocol=="https:"&&a.substr(0,5)=="http:"){return a.replace(/^http:\/\/[^:\/]+/,"https://"+document.location.host)}else{return a}},FormXHR:function(a){$.ajax({type:"POST",dataType:"xml",url:SN.U.RewriteAjaxAction(a.attr("action")),data:a.serialize()+"&ajax=1",beforeSend:function(b){a.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled)},error:function(c,d,b){alert(b||d)},success:function(b,c){if(typeof($("form",b)[0])!="undefined"){form_new=document._importNode($("form",b)[0],true);a.replaceWith(form_new)}else{a.replaceWith(document._importNode($("p",b)[0],true))}}})},FormNoticeXHR:function(b){SN.C.I.NoticeDataGeo={};b.append('<input type="hidden" name="ajax" value="1"/>');b.attr("action",SN.U.RewriteAjaxAction(b.attr("action")));var c=function(d,e){b.append($('<p class="form_response"></p>').addClass(d).text(e))};var a=function(){b.find(".form_response").remove()};b.ajaxForm({dataType:"xml",timeout:"60000",beforeSend:function(d){if(b.find("[name=status_textarea]").val()==""){b.addClass(SN.C.S.Warning);return false}b.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled);SN.U.normalizeGeoData(b);return true},error:function(f,g,e){b.removeClass(SN.C.S.Processing).find(".submit").removeClass(SN.C.S.Disabled).removeAttr(SN.C.S.Disabled,SN.C.S.Disabled);a();if(g=="timeout"){c("error","Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.")}else{var d=SN.U.GetResponseXML(f);if($("."+SN.C.S.Error,d).length>0){b.append(document._importNode($("."+SN.C.S.Error,d)[0],true))}else{if(parseInt(f.status)===0||jQuery.inArray(parseInt(f.status),SN.C.I.HTTP20x30x)>=0){b.resetForm().find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}else{c("error","(Sorry! We had trouble sending your notice ("+f.status+" "+f.statusText+"). Please report the problem to the site administrator if this happens again.")}}}},success:function(i,f){a();var n=$("#"+SN.C.S.Error,i);if(n.length>0){c("error",n.text())}else{if($("body")[0].id=="bookmarklet"){self.close()}var d=$("#"+SN.C.S.CommandResult,i);if(d.length>0){c("success",d.text())}else{var m=document._importNode($("li",i)[0],true);var k=$("#notices_primary .notices:first");var l=b.closest("li.notice-reply");if(l.length>0){var e=$(m).attr("id");if($("#"+e).length==0){var j=l.closest("li.notice");l.replaceWith(m);SN.U.NoticeInlineReplyPlaceholder(j)}else{l.remove()}}else{if(k.length>0&&SN.U.belongsOnTimeline(m)){if($("#"+m.id).length===0){var h=b.find("[name=inreplyto]").val();var g="#notices_primary #notice-"+h;if($("body")[0].id=="conversation"){if(h.length>0&&$(g+" .notices").length<1){$(g).append('<ul class="notices"></ul>')}$($(g+" .notices")[0]).append(m)}else{k.prepend(m)}$("#"+m.id).css({display:"none"}).fadeIn(2500);SN.U.NoticeWithAttachment($("#"+m.id));SN.U.NoticeReplyTo($("#"+m.id))}}else{c("success",$("title",i).text())}}}b.resetForm();b.find("[name=inreplyto]").val("");b.find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}},complete:function(d,e){b.removeClass(SN.C.S.Processing).find(".submit").removeAttr(SN.C.S.Disabled).removeClass(SN.C.S.Disabled);b.find("[name=lat]").val(SN.C.I.NoticeDataGeo.NLat);b.find("[name=lon]").val(SN.C.I.NoticeDataGeo.NLon);b.find("[name=location_ns]").val(SN.C.I.NoticeDataGeo.NLNS);b.find("[name=location_id]").val(SN.C.I.NoticeDataGeo.NLID);b.find("[name=notice_data-geo]").attr("checked",SN.C.I.NoticeDataGeo.NDG)}})},normalizeGeoData:function(a){SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val();SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val();SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked");var b=$.cookie(SN.C.S.NoticeDataGeoCookie);if(b!==null&&b!="disabled"){b=JSON.parse(b);SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val(b.NLat).val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val(b.NLon).val();if(b.NLNS){SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val(b.NLNS).val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val(b.NLID).val()}else{a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("")}}if(b=="disabled"){SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",false).attr("checked")}else{SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",true).attr("checked")}},GetResponseXML:function(b){try{return b.responseXML}catch(a){return(new DOMParser()).parseFromString(b.responseText,"text/xml")}},NoticeReply:function(){if($("#content .notice_reply").length>0){$("#content .notice").each(function(){SN.U.NoticeReplyTo($(this))})}},NoticeReplyTo:function(a){a.find(".notice_reply").live("click",function(c){c.preventDefault();var b=($(".author .nickname",a).length>0)?$($(".author .nickname",a)[0]):$(".author .nickname.uid");SN.U.NoticeInlineReplyTrigger(a,"@"+b.text());return false})},NoticeInlineReplyTrigger:function(g,h){var b=$($(".notice_id",g)[0]).text();var d=g;var e=g.closest(".notices");if(e.hasClass("threaded-replies")){d=e.closest(".notice")}else{e=$("ul.threaded-replies",g);if(e.length==0){e=$('<ul class="notices threaded-replies xoxo"></ul>');g.append(e)}}var i=$(".notice-reply-form",e);var c=function(){i.find("input[name=inreplyto]").val(b);var l=i.find("textarea");if(l.length==0){throw"No textarea"}var k="";if(h){k=h+" "}l.val(k+l.val().replace(RegExp(k,"i"),""));l.data("initialText",$.trim(h+""));l.focus();if(l[0].setSelectionRange){var j=l.val().length;l[0].setSelectionRange(j,j)}};if(i.length>0){c()}else{$("li.notice-reply-placeholder").remove();var f=$("li.notice-reply",e);if(f.length==0){var a=$("#form_notice").attr("action");f=$('<li class="notice-reply"></li>');$.get(a,{ajax:1},function(l,n,m){var j=document._importNode($("form",l)[0],true);f.append(j);e.append(f);var k=i=$(j);SN.U.NoticeLocationAttach(k);SN.U.FormNoticeXHR(k);SN.U.FormNoticeEnhancements(k);SN.U.NoticeDataAttach(k);c()})}}},NoticeFavor:function(){$(".form_favor").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_disfavor").live("click",function(){SN.U.FormXHR($(this));return false})},NoticeInlineReplyPlaceholder:function(b){var a=b.find("ul.threaded-replies");var c=$('<li class="notice-reply-placeholder"><input class="placeholder"></li>');c.click(function(){SN.U.NoticeInlineReplyTrigger(b)});c.find("input").val(SN.msg("reply_placeholder"));a.append(c)},NoticeInlineReplySetup:function(){$(".threaded-replies").each(function(){var b=$(this);var a=b.closest(".notice");SN.U.NoticeInlineReplyPlaceholder(a)})},NoticeRepeat:function(){$(".form_repeat").live("click",function(a){a.preventDefault();SN.U.NoticeRepeatConfirmation($(this));return false})},NoticeRepeatConfirmation:function(a){var c=a.find(".submit");var b=c.clone();b.addClass("submit_dialogbox").removeClass("submit");a.append(b);b.bind("click",function(){SN.U.FormXHR(a);return false});c.hide();a.addClass("dialogbox").append('<button class="close">×</button>').closest(".notice-options").addClass("opaque");a.find("button.close").click(function(){$(this).remove();a.removeClass("dialogbox").closest(".notice-options").removeClass("opaque");a.find(".submit_dialogbox").remove();a.find(".submit").show();return false})},NoticeAttachments:function(){$(".notice a.attachment").each(function(){SN.U.NoticeWithAttachment($(this).closest(".notice"))})},NoticeWithAttachment:function(b){if(b.find(".attachment").length===0){return}var a=b.find(".attachment.more");if(a.length>0){$(a[0]).click(function(){var c=$(this);c.addClass(SN.C.S.Processing);$.get(c.attr("href")+"/ajax",null,function(d){c.parent(".entry-content").html($(d).find("#attachment_view .entry-content").html())});return false}).attr("title",SN.msg("showmore_tooltip"))}},NoticeDataAttach:function(b){var a=b.find("input[type=file]");a.change(function(f){b.find(".attach-status").remove();var d=$(this).val();if(!d){return false}var c=$('<div class="attach-status '+SN.C.S.Success+'"><code></code> <button class="close">×</button></div>');c.find("code").text(d);c.find("button").click(function(){c.remove();a.val("");return false});b.append(c);if(typeof this.files=="object"){for(var e=0;e<this.files.length;e++){SN.U.PreviewAttach(b,this.files[e])}}})},maxFileSize:function(b){var a=$(b).find("input[name=MAX_FILE_SIZE]").attr("value");if(a){return parseInt(a)}else{return 0}},PreviewAttach:function(d,c){var e=c.type+" "+Math.round(c.size/1024)+"KB";var f=true;var h;if(typeof window.createObjectURL!="undefined"){h=function(i,j){j(window.createObjectURL(i))}}else{if(typeof window.FileReader!="undefined"){h=function(j,k){var i=new FileReader();i.onload=function(l){k(i.result)};i.readAsDataURL(j)}}else{f=false}}var a=["image/png","image/jpeg","image/gif","image/svg+xml"];if($.inArray(c.type,a)==-1){f=false}var g=8*1024*1024;if(c.size>g){f=false}if(f){h(c,function(j){var i=$("<img>").attr("title",e).attr("alt",e).attr("src",j).attr("style","height: 120px");d.find(".attach-status").append(i)})}else{var b=$("<div></div>").text(e);d.find(".attach-status").append(b)}},NoticeLocationAttach:function(a){var e=a.find("[name=lat]");var k=a.find("[name=lon]");var g=a.find("[name=location_ns]").val();var l=a.find("[name=location_id]").val();var b="";var d=a.find("[name=notice_data-geo]");var c=a.find("[name=notice_data-geo]");var j=a.find("label.notice_data-geo");function f(n){j.attr("title",jQuery.trim(j.text())).removeClass("checked");a.find("[name=lat]").val("");a.find("[name=lon]").val("");a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("");a.find("[name=notice_data-geo]").attr("checked",false);$.cookie(SN.C.S.NoticeDataGeoCookie,"disabled",{path:"/"});if(n){a.find(".geo_status_wrapper").removeClass("success").addClass("error");a.find(".geo_status_wrapper .geo_status").text(n)}else{a.find(".geo_status_wrapper").remove()}}function m(n,o){SN.U.NoticeGeoStatus(a,"Looking up place name...");$.getJSON(n,o,function(p){var q,r;if(typeof(p.location_ns)!="undefined"){a.find("[name=location_ns]").val(p.location_ns);q=p.location_ns}if(typeof(p.location_id)!="undefined"){a.find("[name=location_id]").val(p.location_id);r=p.location_id}if(typeof(p.name)=="undefined"){NLN_text=o.lat+";"+o.lon}else{NLN_text=p.name}SN.U.NoticeGeoStatus(a,NLN_text,o.lat,o.lon,p.url);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+NLN_text+")");a.find("[name=lat]").val(o.lat);a.find("[name=lon]").val(o.lon);a.find("[name=location_ns]").val(q);a.find("[name=location_id]").val(r);a.find("[name=notice_data-geo]").attr("checked",true);var s={NLat:o.lat,NLon:o.lon,NLNS:q,NLID:r,NLN:NLN_text,NLNU:p.url,NDG:true};$.cookie(SN.C.S.NoticeDataGeoCookie,JSON.stringify(s),{path:"/"})})}if(c.length>0){if($.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){c.attr("checked",false)}else{c.attr("checked",true)}var h=a.find(".notice_data-geo_wrap");var i=h.attr("title");h.removeAttr("title");j.attr("title",j.text());c.change(function(){if(c.attr("checked")===true||$.cookie(SN.C.S.NoticeDataGeoCookie)===null){j.attr("title",NoticeDataGeo_text.ShareDisable).addClass("checked");if($.cookie(SN.C.S.NoticeDataGeoCookie)===null||$.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){if(navigator.geolocation){SN.U.NoticeGeoStatus(a,"Requesting location from browser...");navigator.geolocation.getCurrentPosition(function(p){a.find("[name=lat]").val(p.coords.latitude);a.find("[name=lon]").val(p.coords.longitude);var q={lat:p.coords.latitude,lon:p.coords.longitude,token:$("#token").val()};m(i,q)},function(p){switch(p.code){case p.PERMISSION_DENIED:f("Location permission denied.");break;case p.TIMEOUT:f("Location lookup timeout.");break}},{timeout:10000})}else{if(e.length>0&&k.length>0){var n={lat:e,lon:k,token:$("#token").val()};m(i,n)}else{f();c.remove();j.remove()}}}else{var o=JSON.parse($.cookie(SN.C.S.NoticeDataGeoCookie));a.find("[name=lat]").val(o.NLat);a.find("[name=lon]").val(o.NLon);a.find("[name=location_ns]").val(o.NLNS);a.find("[name=location_id]").val(o.NLID);a.find("[name=notice_data-geo]").attr("checked",o.NDG);SN.U.NoticeGeoStatus(a,o.NLN,o.NLat,o.NLon,o.NLNU);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+o.NLN+")").addClass("checked")}}else{f()}}).change()}},NoticeGeoStatus:function(e,a,f,g,c){var h=e.find(".geo_status_wrapper");if(h.length==0){h=$('<div class="'+SN.C.S.Success+' geo_status_wrapper"><button class="close" style="float:right">×</button><div class="geo_status"></div></div>');h.find("button.close").click(function(){e.find("[name=notice_data-geo]").removeAttr("checked").change()});e.append(h)}var b;if(c){b=$("<a></a>").attr("href",c)}else{b=$("<span></span>")}b.text(a);if(f||g){var d=f+";"+g;b.attr("title",d);if(!a){b.text(d)}}h.find(".geo_status").empty().append(b)},NewDirectMessage:function(){NDM=$(".entity_send-a-message a");NDM.attr({href:NDM.attr("href")+"&ajax=1"});NDM.bind("click",function(){var a=$(".entity_send-a-message form");if(a.length===0){$(this).addClass(SN.C.S.Processing);$.get(NDM.attr("href"),null,function(b){$(".entity_send-a-message").append(document._importNode($("form",b)[0],true));a=$(".entity_send-a-message .form_notice");SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);a.append('<button class="close">×</button>');$(".entity_send-a-message button").click(function(){a.hide();return false});NDM.removeClass(SN.C.S.Processing)})}else{a.show();$(".entity_send-a-message textarea").focus()}return false})},GetFullYear:function(c,d,a){var b=new Date();b.setFullYear(c,d,a);return b},StatusNetInstance:{Set:function(b){var a=SN.U.StatusNetInstance.Get();if(a!==null){b=$.extend(a,b)}$.cookie(SN.C.S.StatusNetInstance,JSON.stringify(b),{path:"/",expires:SN.U.GetFullYear(2029,0,1)})},Get:function(){var a=$.cookie(SN.C.S.StatusNetInstance);if(a!==null){return JSON.parse(a)}return null},Delete:function(){$.cookie(SN.C.S.StatusNetInstance,null)}},belongsOnTimeline:function(b){var a=$("body").attr("id");if(a=="public"){return true}var c=$("#nav_profile a").attr("href");if(c){var d=$(b).find(".entry-title .author a.url").attr("href");if(d==c){if(a=="all"||a=="showstream"){return true}}}return false}},Init:{NoticeForm:function(){if($("body.user_in").length>0){$("."+SN.C.S.FormNotice).each(function(){var a=$(this);SN.U.NoticeLocationAttach(a);SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);SN.U.NoticeDataAttach(a)})}},Notices:function(){if($("body.user_in").length>0){SN.U.NoticeFavor();SN.U.NoticeRepeat();SN.U.NoticeReply();SN.U.NoticeInlineReplySetup()}SN.U.NoticeAttachments()},EntityActions:function(){if($("body.user_in").length>0){$(".form_user_subscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_unsubscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_join").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_leave").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_nudge").live("click",function(){SN.U.FormXHR($(this));return false});SN.U.NewDirectMessage()}},Login:function(){if(SN.U.StatusNetInstance.Get()!==null){var a=SN.U.StatusNetInstance.Get().Nickname;if(a!==null){$("#form_login #nickname").val(a)}}$("#form_login").bind("submit",function(){SN.U.StatusNetInstance.Set({Nickname:$("#form_login #nickname").val()});return true})},UploadForms:function(){$("input[type=file]").change(function(d){if(typeof this.files=="object"&&this.files.length>0){var c=0;for(var b=0;b<this.files.length;b++){c+=this.files[b].size}var a=SN.U.maxFileSize($(this.form));if(a>0&&c>a){var e="File too large: maximum upload size is %d bytes.";alert(e.replace("%d",a));$(this).val("");d.preventDefault();return false}}})}}};$(document).ready(function(){SN.Init.UploadForms();if($("."+SN.C.S.FormNotice).length>0){SN.Init.NoticeForm()}if($("#content .notices").length>0){SN.Init.Notices()}if($("#content .entity_actions").length>0){SN.Init.EntityActions()}if($("#form_login").length>0){SN.Init.Login()}});if(!document.ELEMENT_NODE){document.ELEMENT_NODE=1;document.ATTRIBUTE_NODE=2;document.TEXT_NODE=3;document.CDATA_SECTION_NODE=4;document.ENTITY_REFERENCE_NODE=5;document.ENTITY_NODE=6;document.PROCESSING_INSTRUCTION_NODE=7;document.COMMENT_NODE=8;document.DOCUMENT_NODE=9;document.DOCUMENT_TYPE_NODE=10;document.DOCUMENT_FRAGMENT_NODE=11;document.NOTATION_NODE=12}document._importNode=function(e,a){switch(e.nodeType){case document.ELEMENT_NODE:var d=document.createElement(e.nodeName);if(e.attributes&&e.attributes.length>0){for(var c=0,b=e.attributes.length;c<b;){if(e.attributes[c].nodeName=="class"){d.className=e.getAttribute(e.attributes[c++].nodeName)}else{d.setAttribute(e.attributes[c].nodeName,e.getAttribute(e.attributes[c++].nodeName))}}}if(a&&e.childNodes&&e.childNodes.length>0){for(var c=0,b=e.childNodes.length;c<b;){d.appendChild(document._importNode(e.childNodes[c++],a))}}return d;break;case document.TEXT_NODE:case document.CDATA_SECTION_NODE:case document.COMMENT_NODE:return document.createTextNode(e.nodeValue);break}};if(typeof navigator.geolocation=="undefined"||navigator.geolocation.shim){(function(){(function(){if(window.google&&google.gears){return}var c=null;if(typeof GearsFactory!="undefined"){c=new GearsFactory()}else{try{c=new ActiveXObject("Gears.Factory");if(c.getBuildInfo().indexOf("ie_mobile")!=-1){c.privateSetGlobalObject(this)}}catch(d){if((typeof navigator.mimeTypes!="undefined")&&navigator.mimeTypes["application/x-googlegears"]){c=document.createElement("object");c.style.display="none";c.width=0;c.height=0;c.type="application/x-googlegears";document.documentElement.appendChild(c)}}}if(!c){return}if(!window.google){google={}}if(!google.gears){google.gears={factory:c}}})();var a=(function(){var d=google.gears.factory.create("beta.geolocation");var c=function(f,e){return function(g){f(g);e.lastPosition=g}};return{shim:true,type:"Gears",lastPosition:null,getCurrentPosition:function(e,g,h){var f=this;var i=c(e,f);d.getCurrentPosition(i,g,h)},watchPosition:function(e,f,g){d.watchPosition(e,f,g)},clearWatch:function(e){d.clearWatch(e)},getPermission:function(g,e,f){d.getPermission(g,e,f)}}});var b=(function(){var i=false;var e=function(){if(!d()&&!i){i=true;var j=document.createElement("script");j.src=(document.location.protocol=="https:"?"https://":"http://")+"www.google.com/jsapi?callback=_google_loader_apiLoaded";j.type="text/javascript";document.getElementsByTagName("body")[0].appendChild(j)}};var c=[];var h=function(j){c.push(j)};var f=function(){if(d()){while(c.length>0){var j=c.pop();j()}}};window._google_loader_apiLoaded=function(){f()};var d=function(){return(window.google&&google.loader)};var g=function(j){if(d()){return true}h(j);e();return false};e();return{shim:true,type:"ClientLocation",lastPosition:null,getCurrentPosition:function(k,n,o){var m=this;if(!g(function(){m.getCurrentPosition(k,n,o)})){return}if(google.loader.ClientLocation){var l=google.loader.ClientLocation;var j={coords:{latitude:l.latitude,longitude:l.longitude,altitude:null,accuracy:43000,altitudeAccuracy:null,heading:null,speed:null},address:{city:l.address.city,country:l.address.country,country_code:l.address.country_code,region:l.address.region},timestamp:new Date()};k(j);this.lastPosition=j}else{if(n==="function"){n({code:3,message:"Using the Google ClientLocation API and it is not able to calculate a location."})}}},watchPosition:function(j,l,m){this.getCurrentPosition(j,l,m);var k=this;var n=setInterval(function(){k.getCurrentPosition(j,l,m)},10000);return n},clearWatch:function(j){clearInterval(j)},getPermission:function(l,j,k){return true}}});navigator.geolocation=(window.google&&google.gears)?a():b()})()}; \ No newline at end of file +var SN={C:{I:{CounterBlackout:false,MaxLength:140,PatternUsername:/^[0-9a-zA-Z\-_.]*$/,HTTP20x30x:[200,201,202,203,204,205,206,300,301,302,303,304,305,306,307],NoticeFormMaster:null},S:{Disabled:"disabled",Warning:"warning",Error:"error",Success:"success",Processing:"processing",CommandResult:"command_result",FormNotice:"form_notice",NoticeDataGeo:"notice_data-geo",NoticeDataGeoCookie:"NoticeDataGeo",NoticeDataGeoSelected:"notice_data-geo_selected",StatusNetInstance:"StatusNetInstance"}},messages:{},msg:function(a){if(typeof SN.messages[a]=="undefined"){return"["+a+"]"}else{return SN.messages[a]}},U:{FormNoticeEnhancements:function(b){if(jQuery.data(b[0],"ElementData")===undefined){MaxLength=b.find(".count").text();if(typeof(MaxLength)=="undefined"){MaxLength=SN.C.I.MaxLength}jQuery.data(b[0],"ElementData",{MaxLength:MaxLength});SN.U.Counter(b);NDT=b.find("[name=status_textarea]");NDT.bind("keyup",function(c){SN.U.Counter(b)});var a=function(c){window.setTimeout(function(){SN.U.Counter(b)},50)};NDT.bind("cut",a).bind("paste",a)}else{b.find(".count").text(jQuery.data(b[0],"ElementData").MaxLength)}},Counter:function(d){SN.C.I.FormNoticeCurrent=d;var b=jQuery.data(d[0],"ElementData").MaxLength;if(b<=0){return}var c=b-SN.U.CharacterCount(d);var a=d.find(".count");if(c.toString()!=a.text()){if(!SN.C.I.CounterBlackout||c===0){if(a.text()!=String(c)){a.text(c)}if(c<0){d.addClass(SN.C.S.Warning)}else{d.removeClass(SN.C.S.Warning)}if(!SN.C.I.CounterBlackout){SN.C.I.CounterBlackout=true;SN.C.I.FormNoticeCurrent=d;window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);",500)}}}},CharacterCount:function(a){return a.find("[name=status_textarea]").val().length},ClearCounterBlackout:function(a){SN.C.I.CounterBlackout=false;SN.U.Counter(a)},RewriteAjaxAction:function(a){if(document.location.protocol=="https:"&&a.substr(0,5)=="http:"){return a.replace(/^http:\/\/[^:\/]+/,"https://"+document.location.host)}else{return a}},FormXHR:function(a){$.ajax({type:"POST",dataType:"xml",url:SN.U.RewriteAjaxAction(a.attr("action")),data:a.serialize()+"&ajax=1",beforeSend:function(b){a.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled)},error:function(c,d,b){alert(b||d)},success:function(b,c){if(typeof($("form",b)[0])!="undefined"){form_new=document._importNode($("form",b)[0],true);a.replaceWith(form_new)}else{a.replaceWith(document._importNode($("p",b)[0],true))}}})},FormNoticeXHR:function(b){SN.C.I.NoticeDataGeo={};b.append('<input type="hidden" name="ajax" value="1"/>');b.attr("action",SN.U.RewriteAjaxAction(b.attr("action")));var c=function(d,e){b.append($('<p class="form_response"></p>').addClass(d).text(e))};var a=function(){b.find(".form_response").remove()};b.ajaxForm({dataType:"xml",timeout:"60000",beforeSend:function(d){if(b.find("[name=status_textarea]").val()==""){b.addClass(SN.C.S.Warning);return false}b.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled);SN.U.normalizeGeoData(b);return true},error:function(f,g,e){b.removeClass(SN.C.S.Processing).find(".submit").removeClass(SN.C.S.Disabled).removeAttr(SN.C.S.Disabled,SN.C.S.Disabled);a();if(g=="timeout"){c("error","Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.")}else{var d=SN.U.GetResponseXML(f);if($("."+SN.C.S.Error,d).length>0){b.append(document._importNode($("."+SN.C.S.Error,d)[0],true))}else{if(parseInt(f.status)===0||jQuery.inArray(parseInt(f.status),SN.C.I.HTTP20x30x)>=0){b.resetForm().find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}else{c("error","(Sorry! We had trouble sending your notice ("+f.status+" "+f.statusText+"). Please report the problem to the site administrator if this happens again.")}}}},success:function(i,f){a();var n=$("#"+SN.C.S.Error,i);if(n.length>0){c("error",n.text())}else{if($("body")[0].id=="bookmarklet"){self.close()}var d=$("#"+SN.C.S.CommandResult,i);if(d.length>0){c("success",d.text())}else{var m=document._importNode($("li",i)[0],true);var k=$("#notices_primary .notices:first");var l=b.closest("li.notice-reply");if(l.length>0){var e=$(m).attr("id");if($("#"+e).length==0){var j=l.closest("li.notice");l.replaceWith(m);SN.U.NoticeInlineReplyPlaceholder(j)}else{l.remove()}}else{if(k.length>0&&SN.U.belongsOnTimeline(m)){if($("#"+m.id).length===0){var h=b.find("[name=inreplyto]").val();var g="#notices_primary #notice-"+h;if($("body")[0].id=="conversation"){if(h.length>0&&$(g+" .notices").length<1){$(g).append('<ul class="notices"></ul>')}$($(g+" .notices")[0]).append(m)}else{k.prepend(m)}$("#"+m.id).css({display:"none"}).fadeIn(2500);SN.U.NoticeWithAttachment($("#"+m.id));SN.U.NoticeReplyTo($("#"+m.id))}}else{c("success",$("title",i).text())}}}b.resetForm();b.find("[name=inreplyto]").val("");b.find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}},complete:function(d,e){b.removeClass(SN.C.S.Processing).find(".submit").removeAttr(SN.C.S.Disabled).removeClass(SN.C.S.Disabled);b.find("[name=lat]").val(SN.C.I.NoticeDataGeo.NLat);b.find("[name=lon]").val(SN.C.I.NoticeDataGeo.NLon);b.find("[name=location_ns]").val(SN.C.I.NoticeDataGeo.NLNS);b.find("[name=location_id]").val(SN.C.I.NoticeDataGeo.NLID);b.find("[name=notice_data-geo]").attr("checked",SN.C.I.NoticeDataGeo.NDG)}})},normalizeGeoData:function(a){SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val();SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val();SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked");var b=$.cookie(SN.C.S.NoticeDataGeoCookie);if(b!==null&&b!="disabled"){b=JSON.parse(b);SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val(b.NLat).val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val(b.NLon).val();if(b.NLNS){SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val(b.NLNS).val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val(b.NLID).val()}else{a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("")}}if(b=="disabled"){SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",false).attr("checked")}else{SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",true).attr("checked")}},GetResponseXML:function(b){try{return b.responseXML}catch(a){return(new DOMParser()).parseFromString(b.responseText,"text/xml")}},NoticeReply:function(){if($("#content .notice_reply").length>0){$("#content .notice").each(function(){SN.U.NoticeReplyTo($(this))})}},NoticeReplyTo:function(a){a.find(".notice_reply").live("click",function(c){c.preventDefault();var b=($(".author .nickname",a).length>0)?$($(".author .nickname",a)[0]):$(".author .nickname.uid");SN.U.NoticeInlineReplyTrigger(a,"@"+b.text());return false})},NoticeInlineReplyTrigger:function(h,i){var b=$($(".notice_id",h)[0]).text();var e=h;var f=h.closest(".notices");if(f.hasClass("threaded-replies")){e=f.closest(".notice")}else{f=$("ul.threaded-replies",h);if(f.length==0){f=$('<ul class="notices threaded-replies xoxo"></ul>');h.append(f)}}var j=$(".notice-reply-form",f);var d=function(){j.find("input[name=inreplyto]").val(b);var m=j.find("textarea");if(m.length==0){throw"No textarea"}var l="";if(i){l=i+" "}m.val(l+m.val().replace(RegExp(l,"i"),""));m.data("initialText",$.trim(i+""));m.focus();if(m[0].setSelectionRange){var k=m.val().length;m[0].setSelectionRange(k,k)}};if(j.length>0){d()}else{$("li.notice-reply-placeholder").remove();var g=$("li.notice-reply",f);if(g.length==0){g=$('<li class="notice-reply"></li>');var c=function(k){var l=document._importNode(k,true);g.append(l);f.append(g);var m=j=$(l);SN.U.NoticeLocationAttach(m);SN.U.FormNoticeXHR(m);SN.U.FormNoticeEnhancements(m);SN.U.NoticeDataAttach(m);d()};if(SN.C.I.NoticeFormMaster){c(SN.C.I.NoticeFormMaster)}else{var a=$("#form_notice").attr("action");$.get(a,{ajax:1},function(k,m,l){c($("form",k)[0])})}}}},NoticeFavor:function(){$(".form_favor").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_disfavor").live("click",function(){SN.U.FormXHR($(this));return false})},NoticeInlineReplyPlaceholder:function(b){var a=b.find("ul.threaded-replies");var c=$('<li class="notice-reply-placeholder"><input class="placeholder"></li>');c.click(function(){SN.U.NoticeInlineReplyTrigger(b)});c.find("input").val(SN.msg("reply_placeholder"));a.append(c)},NoticeInlineReplySetup:function(){$(".threaded-replies").each(function(){var b=$(this);var a=b.closest(".notice");SN.U.NoticeInlineReplyPlaceholder(a)})},NoticeRepeat:function(){$(".form_repeat").live("click",function(a){a.preventDefault();SN.U.NoticeRepeatConfirmation($(this));return false})},NoticeRepeatConfirmation:function(a){var c=a.find(".submit");var b=c.clone();b.addClass("submit_dialogbox").removeClass("submit");a.append(b);b.bind("click",function(){SN.U.FormXHR(a);return false});c.hide();a.addClass("dialogbox").append('<button class="close">×</button>').closest(".notice-options").addClass("opaque");a.find("button.close").click(function(){$(this).remove();a.removeClass("dialogbox").closest(".notice-options").removeClass("opaque");a.find(".submit_dialogbox").remove();a.find(".submit").show();return false})},NoticeAttachments:function(){$(".notice a.attachment").each(function(){SN.U.NoticeWithAttachment($(this).closest(".notice"))})},NoticeWithAttachment:function(b){if(b.find(".attachment").length===0){return}var a=b.find(".attachment.more");if(a.length>0){$(a[0]).click(function(){var c=$(this);c.addClass(SN.C.S.Processing);$.get(c.attr("href")+"/ajax",null,function(d){c.parent(".entry-content").html($(d).find("#attachment_view .entry-content").html())});return false}).attr("title",SN.msg("showmore_tooltip"))}},NoticeDataAttach:function(b){var a=b.find("input[type=file]");a.change(function(f){b.find(".attach-status").remove();var d=$(this).val();if(!d){return false}var c=$('<div class="attach-status '+SN.C.S.Success+'"><code></code> <button class="close">×</button></div>');c.find("code").text(d);c.find("button").click(function(){c.remove();a.val("");return false});b.append(c);if(typeof this.files=="object"){for(var e=0;e<this.files.length;e++){SN.U.PreviewAttach(b,this.files[e])}}})},maxFileSize:function(b){var a=$(b).find("input[name=MAX_FILE_SIZE]").attr("value");if(a){return parseInt(a)}else{return 0}},PreviewAttach:function(d,c){var e=c.type+" "+Math.round(c.size/1024)+"KB";var f=true;var h;if(typeof window.createObjectURL!="undefined"){h=function(i,j){j(window.createObjectURL(i))}}else{if(typeof window.FileReader!="undefined"){h=function(j,k){var i=new FileReader();i.onload=function(l){k(i.result)};i.readAsDataURL(j)}}else{f=false}}var a=["image/png","image/jpeg","image/gif","image/svg+xml"];if($.inArray(c.type,a)==-1){f=false}var g=8*1024*1024;if(c.size>g){f=false}if(f){h(c,function(j){var i=$("<img>").attr("title",e).attr("alt",e).attr("src",j).attr("style","height: 120px");d.find(".attach-status").append(i)})}else{var b=$("<div></div>").text(e);d.find(".attach-status").append(b)}},NoticeLocationAttach:function(a){var e=a.find("[name=lat]");var k=a.find("[name=lon]");var g=a.find("[name=location_ns]").val();var l=a.find("[name=location_id]").val();var b="";var d=a.find("[name=notice_data-geo]");var c=a.find("[name=notice_data-geo]");var j=a.find("label.notice_data-geo");function f(n){j.attr("title",jQuery.trim(j.text())).removeClass("checked");a.find("[name=lat]").val("");a.find("[name=lon]").val("");a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("");a.find("[name=notice_data-geo]").attr("checked",false);$.cookie(SN.C.S.NoticeDataGeoCookie,"disabled",{path:"/"});if(n){a.find(".geo_status_wrapper").removeClass("success").addClass("error");a.find(".geo_status_wrapper .geo_status").text(n)}else{a.find(".geo_status_wrapper").remove()}}function m(n,o){SN.U.NoticeGeoStatus(a,"Looking up place name...");$.getJSON(n,o,function(p){var q,r;if(typeof(p.location_ns)!="undefined"){a.find("[name=location_ns]").val(p.location_ns);q=p.location_ns}if(typeof(p.location_id)!="undefined"){a.find("[name=location_id]").val(p.location_id);r=p.location_id}if(typeof(p.name)=="undefined"){NLN_text=o.lat+";"+o.lon}else{NLN_text=p.name}SN.U.NoticeGeoStatus(a,NLN_text,o.lat,o.lon,p.url);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+NLN_text+")");a.find("[name=lat]").val(o.lat);a.find("[name=lon]").val(o.lon);a.find("[name=location_ns]").val(q);a.find("[name=location_id]").val(r);a.find("[name=notice_data-geo]").attr("checked",true);var s={NLat:o.lat,NLon:o.lon,NLNS:q,NLID:r,NLN:NLN_text,NLNU:p.url,NDG:true};$.cookie(SN.C.S.NoticeDataGeoCookie,JSON.stringify(s),{path:"/"})})}if(c.length>0){if($.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){c.attr("checked",false)}else{c.attr("checked",true)}var h=a.find(".notice_data-geo_wrap");var i=h.attr("title");h.removeAttr("title");j.attr("title",j.text());c.change(function(){if(c.attr("checked")===true||$.cookie(SN.C.S.NoticeDataGeoCookie)===null){j.attr("title",NoticeDataGeo_text.ShareDisable).addClass("checked");if($.cookie(SN.C.S.NoticeDataGeoCookie)===null||$.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){if(navigator.geolocation){SN.U.NoticeGeoStatus(a,"Requesting location from browser...");navigator.geolocation.getCurrentPosition(function(p){a.find("[name=lat]").val(p.coords.latitude);a.find("[name=lon]").val(p.coords.longitude);var q={lat:p.coords.latitude,lon:p.coords.longitude,token:$("#token").val()};m(i,q)},function(p){switch(p.code){case p.PERMISSION_DENIED:f("Location permission denied.");break;case p.TIMEOUT:f("Location lookup timeout.");break}},{timeout:10000})}else{if(e.length>0&&k.length>0){var n={lat:e,lon:k,token:$("#token").val()};m(i,n)}else{f();c.remove();j.remove()}}}else{var o=JSON.parse($.cookie(SN.C.S.NoticeDataGeoCookie));a.find("[name=lat]").val(o.NLat);a.find("[name=lon]").val(o.NLon);a.find("[name=location_ns]").val(o.NLNS);a.find("[name=location_id]").val(o.NLID);a.find("[name=notice_data-geo]").attr("checked",o.NDG);SN.U.NoticeGeoStatus(a,o.NLN,o.NLat,o.NLon,o.NLNU);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+o.NLN+")").addClass("checked")}}else{f()}}).change()}},NoticeGeoStatus:function(e,a,f,g,c){var h=e.find(".geo_status_wrapper");if(h.length==0){h=$('<div class="'+SN.C.S.Success+' geo_status_wrapper"><button class="close" style="float:right">×</button><div class="geo_status"></div></div>');h.find("button.close").click(function(){e.find("[name=notice_data-geo]").removeAttr("checked").change()});e.append(h)}var b;if(c){b=$("<a></a>").attr("href",c)}else{b=$("<span></span>")}b.text(a);if(f||g){var d=f+";"+g;b.attr("title",d);if(!a){b.text(d)}}h.find(".geo_status").empty().append(b)},NewDirectMessage:function(){NDM=$(".entity_send-a-message a");NDM.attr({href:NDM.attr("href")+"&ajax=1"});NDM.bind("click",function(){var a=$(".entity_send-a-message form");if(a.length===0){$(this).addClass(SN.C.S.Processing);$.get(NDM.attr("href"),null,function(b){$(".entity_send-a-message").append(document._importNode($("form",b)[0],true));a=$(".entity_send-a-message .form_notice");SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);a.append('<button class="close">×</button>');$(".entity_send-a-message button").click(function(){a.hide();return false});NDM.removeClass(SN.C.S.Processing)})}else{a.show();$(".entity_send-a-message textarea").focus()}return false})},GetFullYear:function(c,d,a){var b=new Date();b.setFullYear(c,d,a);return b},StatusNetInstance:{Set:function(b){var a=SN.U.StatusNetInstance.Get();if(a!==null){b=$.extend(a,b)}$.cookie(SN.C.S.StatusNetInstance,JSON.stringify(b),{path:"/",expires:SN.U.GetFullYear(2029,0,1)})},Get:function(){var a=$.cookie(SN.C.S.StatusNetInstance);if(a!==null){return JSON.parse(a)}return null},Delete:function(){$.cookie(SN.C.S.StatusNetInstance,null)}},belongsOnTimeline:function(b){var a=$("body").attr("id");if(a=="public"){return true}var c=$("#nav_profile a").attr("href");if(c){var d=$(b).find(".entry-title .author a.url").attr("href");if(d==c){if(a=="all"||a=="showstream"){return true}}}return false},switchInputFormTab:function(a){$(".input_form_nav_tab.current").removeClass("current");$("#input_form_nav_"+a).addClass("current");$(".input_form.current").removeClass("current");$("#input_form_"+a).addClass("current")}},Init:{NoticeForm:function(){if($("body.user_in").length>0){$("."+SN.C.S.FormNotice).each(function(){var a=$(this);SN.U.NoticeLocationAttach(a);SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);SN.U.NoticeDataAttach(a)})}},Notices:function(){if($("body.user_in").length>0){var a=$(".form_notice:first");if(a.length>0){SN.C.I.NoticeFormMaster=document._importNode(a[0],true)}SN.U.NoticeFavor();SN.U.NoticeRepeat();SN.U.NoticeReply();SN.U.NoticeInlineReplySetup()}SN.U.NoticeAttachments()},EntityActions:function(){if($("body.user_in").length>0){$(".form_user_subscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_unsubscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_join").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_leave").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_nudge").live("click",function(){SN.U.FormXHR($(this));return false});SN.U.NewDirectMessage()}},Login:function(){if(SN.U.StatusNetInstance.Get()!==null){var a=SN.U.StatusNetInstance.Get().Nickname;if(a!==null){$("#form_login #nickname").val(a)}}$("#form_login").bind("submit",function(){SN.U.StatusNetInstance.Set({Nickname:$("#form_login #nickname").val()});return true})},UploadForms:function(){$("input[type=file]").change(function(d){if(typeof this.files=="object"&&this.files.length>0){var c=0;for(var b=0;b<this.files.length;b++){c+=this.files[b].size}var a=SN.U.maxFileSize($(this.form));if(a>0&&c>a){var e="File too large: maximum upload size is %d bytes.";alert(e.replace("%d",a));$(this).val("");d.preventDefault();return false}}})}}};$(document).ready(function(){SN.Init.UploadForms();if($("."+SN.C.S.FormNotice).length>0){SN.Init.NoticeForm()}if($("#content .notices").length>0){SN.Init.Notices()}if($("#content .entity_actions").length>0){SN.Init.EntityActions()}if($("#form_login").length>0){SN.Init.Login()}});if(!document.ELEMENT_NODE){document.ELEMENT_NODE=1;document.ATTRIBUTE_NODE=2;document.TEXT_NODE=3;document.CDATA_SECTION_NODE=4;document.ENTITY_REFERENCE_NODE=5;document.ENTITY_NODE=6;document.PROCESSING_INSTRUCTION_NODE=7;document.COMMENT_NODE=8;document.DOCUMENT_NODE=9;document.DOCUMENT_TYPE_NODE=10;document.DOCUMENT_FRAGMENT_NODE=11;document.NOTATION_NODE=12}document._importNode=function(e,a){switch(e.nodeType){case document.ELEMENT_NODE:var d=document.createElement(e.nodeName);if(e.attributes&&e.attributes.length>0){for(var c=0,b=e.attributes.length;c<b;){if(e.attributes[c].nodeName=="class"){d.className=e.getAttribute(e.attributes[c++].nodeName)}else{d.setAttribute(e.attributes[c].nodeName,e.getAttribute(e.attributes[c++].nodeName))}}}if(a&&e.childNodes&&e.childNodes.length>0){for(var c=0,b=e.childNodes.length;c<b;){d.appendChild(document._importNode(e.childNodes[c++],a))}}return d;break;case document.TEXT_NODE:case document.CDATA_SECTION_NODE:case document.COMMENT_NODE:return document.createTextNode(e.nodeValue);break}};if(typeof navigator.geolocation=="undefined"||navigator.geolocation.shim){(function(){(function(){if(window.google&&google.gears){return}var c=null;if(typeof GearsFactory!="undefined"){c=new GearsFactory()}else{try{c=new ActiveXObject("Gears.Factory");if(c.getBuildInfo().indexOf("ie_mobile")!=-1){c.privateSetGlobalObject(this)}}catch(d){if((typeof navigator.mimeTypes!="undefined")&&navigator.mimeTypes["application/x-googlegears"]){c=document.createElement("object");c.style.display="none";c.width=0;c.height=0;c.type="application/x-googlegears";document.documentElement.appendChild(c)}}}if(!c){return}if(!window.google){google={}}if(!google.gears){google.gears={factory:c}}})();var a=(function(){var d=google.gears.factory.create("beta.geolocation");var c=function(f,e){return function(g){f(g);e.lastPosition=g}};return{shim:true,type:"Gears",lastPosition:null,getCurrentPosition:function(e,g,h){var f=this;var i=c(e,f);d.getCurrentPosition(i,g,h)},watchPosition:function(e,f,g){d.watchPosition(e,f,g)},clearWatch:function(e){d.clearWatch(e)},getPermission:function(g,e,f){d.getPermission(g,e,f)}}});var b=(function(){var i=false;var e=function(){if(!d()&&!i){i=true;var j=document.createElement("script");j.src=(document.location.protocol=="https:"?"https://":"http://")+"www.google.com/jsapi?callback=_google_loader_apiLoaded";j.type="text/javascript";document.getElementsByTagName("body")[0].appendChild(j)}};var c=[];var h=function(j){c.push(j)};var f=function(){if(d()){while(c.length>0){var j=c.pop();j()}}};window._google_loader_apiLoaded=function(){f()};var d=function(){return(window.google&&google.loader)};var g=function(j){if(d()){return true}h(j);e();return false};e();return{shim:true,type:"ClientLocation",lastPosition:null,getCurrentPosition:function(k,n,o){var m=this;if(!g(function(){m.getCurrentPosition(k,n,o)})){return}if(google.loader.ClientLocation){var l=google.loader.ClientLocation;var j={coords:{latitude:l.latitude,longitude:l.longitude,altitude:null,accuracy:43000,altitudeAccuracy:null,heading:null,speed:null},address:{city:l.address.city,country:l.address.country,country_code:l.address.country_code,region:l.address.region},timestamp:new Date()};k(j);this.lastPosition=j}else{if(n==="function"){n({code:3,message:"Using the Google ClientLocation API and it is not able to calculate a location."})}}},watchPosition:function(j,l,m){this.getCurrentPosition(j,l,m);var k=this;var n=setInterval(function(){k.getCurrentPosition(j,l,m)},10000);return n},clearWatch:function(j){clearInterval(j)},getPermission:function(l,j,k){return true}}});navigator.geolocation=(window.google&&google.gears)?a():b()})()}; \ No newline at end of file diff --git a/lib/action.php b/lib/action.php index 31e52dfcf2..28b0fdbacf 100644 --- a/lib/action.php +++ b/lib/action.php @@ -476,14 +476,7 @@ class Action extends HTMLOutputter // lawsuit Event::handle('EndShowSiteNotice', array($this)); } - if (common_logged_in()) { - if (Event::handle('StartShowNoticeForm', array($this))) { - $this->showNoticeForm(); - Event::handle('EndShowNoticeForm', array($this)); - } - } else { - $this->showAnonymousMessage(); - } + $this->elementEnd('div'); } @@ -555,69 +548,10 @@ class Action extends HTMLOutputter // lawsuit */ function showPrimaryNav() { - $user = common_current_user(); - $this->elementStart('ul', array('class' => 'nav', - 'id' => 'site_nav_global_primary')); - if (Event::handle('StartPrimaryNav', array($this))) { - if (!empty($user)) { - $this->menuItem(common_local_url('all', - array('nickname' => $user->nickname)), - _m('Home'), - _m('Friends timeline'), - false, - 'nav_home'); - $this->menuItem(common_local_url('showstream', - array('nickname' => $user->nickname)), - _m('Profile'), - _m('Your profile'), - false, - 'nav_profile'); - $this->menuItem(common_local_url('public'), - _m('Public'), - _m('Everyone on this site'), - false, - 'nav_public'); - $this->menuItem(common_local_url('profilesettings'), - _m('Settings'), - _m('Change your personal settings'), - false, - 'nav_account'); - if ($user->hasRight(Right::CONFIGURESITE)) { - $this->menuItem(common_local_url('siteadminpanel'), - _m('Admin'), - _m('Site configuration'), - false, - 'nav_admin'); - } - $this->menuItem(common_local_url('logout'), - _m('Logout'), - _m('Logout from the site'), - false, - 'nav_logout'); - } else { - $this->menuItem(common_local_url('public'), - _m('Public'), - _m('Everyone on this site'), - false, - 'nav_public'); - $this->menuItem(common_local_url('login'), - _m('Login'), - _m('Login to the site'), - false, - 'nav_login'); - } - - if (!empty($user) || !common_config('site', 'private')) { - $this->menuItem(common_local_url('noticesearch'), - _m('Search'), - _m('Search the site'), - false, - 'nav_search'); - } - - Event::handle('EndPrimaryNav', array($this)); - } - $this->elementEnd('ul'); + $this->elementStart('div', array('id' => 'site_nav_global_primary')); + $pn = new PrimaryNav($this); + $pn->show(); + $this->elementEnd('div'); } /** @@ -646,8 +580,63 @@ class Action extends HTMLOutputter // lawsuit */ function showNoticeForm() { - $notice_form = new NoticeForm($this); - $notice_form->show(); + $tabs = array('status' => _('Status')); + + $this->elementStart('div', 'input_forms'); + + if (Event::handle('StartShowEntryForms', array(&$tabs))) { + + $this->elementStart('ul', array('class' => 'nav', + 'id' => 'input_form_nav')); + + foreach ($tabs as $tag => $title) { + + $attrs = array('id' => 'input_form_nav_'.$tag, + 'class' => 'input_form_nav_tab'); + + if ($tag == 'status') { + $attrs['class'] = 'current'; + } + + $this->elementStart('li', $attrs); + + $this->element('a', + array('href' => 'javascript:SN.U.switchInputFormTab("'.$tag.'")'), + $title); + $this->elementEnd('li'); + } + + $this->elementEnd('ul'); + + foreach ($tabs as $tag => $title) { + + $attrs = array('class' => 'input_form', + 'id' => 'input_form_'.$tag); + + if ($tag == 'status') { + $attrs['class'] .= ' current'; + } + + $this->elementStart('div', $attrs); + + $form = null; + + if (Event::handle('StartMakeEntryForm', array($tag, $this, &$form))) { + if ($tag == 'status') { + $form = new NoticeForm($this); + } + Event::handle('EndMakeEntryForm', array($tag, $this, $form)); + } + + if (!empty($form)) { + $form->show(); + } + + $this->elementEnd('div'); + } + } + + $this->elementEnd('div'); } /** @@ -680,6 +669,10 @@ class Action extends HTMLOutputter // lawsuit $this->showContentBlock(); Event::handle('EndShowContentBlock', array($this)); } + if (Event::handle('StartShowObjectNavBlock', array($this))) { + $this->showObjectNavBlock(); + Event::handle('EndShowObjectNavBlock', array($this)); + } if (Event::handle('StartShowAside', array($this))) { $this->showAside(); Event::handle('EndShowAside', array($this)); @@ -710,7 +703,34 @@ class Action extends HTMLOutputter // lawsuit */ function showLocalNav() { - // does nothing by default + $nav = new DefaultLocalNav($this); + $nav->show(); + } + + /** + * Show menu for an object (group, profile) + * + * @return nothing + */ + function showObjectNavBlock() + { + // Need to have this ID for CSS; I'm too lazy to add it to + // all menus + $this->elementStart('div', array('id' => 'site_nav_object')); + $this->showObjectNav(); + $this->elementEnd('div'); + } + + /** + * Show object navigation. + * + * If there are things to do with this object, show it here. + * + * @return nothing + */ + function showObjectNav() + { + /* Nothing here. */ } /** @@ -721,6 +741,12 @@ class Action extends HTMLOutputter // lawsuit function showContentBlock() { $this->elementStart('div', array('id' => 'content')); + if (common_logged_in()) { + if (Event::handle('StartShowNoticeForm', array($this))) { + $this->showNoticeForm(); + Event::handle('EndShowNoticeForm', array($this)); + } + } if (Event::handle('StartShowPageTitle', array($this))) { $this->showPageTitle(); Event::handle('EndShowPageTitle', array($this)); @@ -862,43 +888,8 @@ class Action extends HTMLOutputter // lawsuit */ function showSecondaryNav() { - $this->elementStart('ul', array('class' => 'nav', - 'id' => 'site_nav_global_secondary')); - if (Event::handle('StartSecondaryNav', array($this))) { - $this->menuItem(common_local_url('doc', array('title' => 'help')), - // TRANS: Secondary navigation menu option leading to help on StatusNet. - _('Help')); - $this->menuItem(common_local_url('doc', array('title' => 'about')), - // TRANS: Secondary navigation menu option leading to text about StatusNet site. - _('About')); - $this->menuItem(common_local_url('doc', array('title' => 'faq')), - // TRANS: Secondary navigation menu option leading to Frequently Asked Questions. - _('FAQ')); - $bb = common_config('site', 'broughtby'); - if (!empty($bb)) { - $this->menuItem(common_local_url('doc', array('title' => 'tos')), - // TRANS: Secondary navigation menu option leading to Terms of Service. - _('TOS')); - } - $this->menuItem(common_local_url('doc', array('title' => 'privacy')), - // TRANS: Secondary navigation menu option leading to privacy policy. - _('Privacy')); - $this->menuItem(common_local_url('doc', array('title' => 'source')), - // TRANS: Secondary navigation menu option. Leads to information about StatusNet and its license. - _('Source')); - $this->menuItem(common_local_url('version'), - // TRANS: Secondary navigation menu option leading to version information on the StatusNet site. - _('Version')); - $this->menuItem(common_local_url('doc', array('title' => 'contact')), - // TRANS: Secondary navigation menu option leading to e-mail contact information on the - // TRANS: StatusNet site, where to report bugs, ... - _('Contact')); - $this->menuItem(common_local_url('doc', array('title' => 'badge')), - // TRANS: Secondary navigation menu option. Leads to information about embedding a timeline widget. - _('Badge')); - Event::handle('EndSecondaryNav', array($this)); - } - $this->elementEnd('ul'); + $sn = new SecondaryNav($this); + $sn->show(); } /** diff --git a/lib/activityobject.php b/lib/activityobject.php index a69e1a1b42..de2fcab767 100644 --- a/lib/activityobject.php +++ b/lib/activityobject.php @@ -422,7 +422,7 @@ class ActivityObject if (Event::handle('StartActivityObjectFromNotice', array($notice, &$object))) { - $object->type = ActivityObject::NOTE; + $object->type = (empty($notice->object_type)) ? ActivityObject::NOTE : $notice->object_type; $object->id = $notice->uri; $object->title = $notice->content; diff --git a/lib/adminpanelaction.php b/lib/adminpanelaction.php index 8dd16e9d0c..a085fcd5dc 100644 --- a/lib/adminpanelaction.php +++ b/lib/adminpanelaction.php @@ -291,129 +291,3 @@ class AdminPanelAction extends Action return $isOK; } } - -/** - * Menu for public group of actions - * - * @category Output - * @package StatusNet - * @author Evan Prodromou <evan@status.net> - * @author Sarven Capadisli <csarven@status.net> - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - * - * @see Widget - */ -class AdminPanelNav extends Widget -{ - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - - /** - * Show the menu - * - * @return void - */ - function show() - { - $action_name = $this->action->trimmed('action'); - - $this->action->elementStart('ul', array('class' => 'nav')); - - if (Event::handle('StartAdminPanelNav', array($this))) { - - if (AdminPanelAction::canAdmin('site')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Basic site configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('siteadminpanel'), _m('MENU', 'Site'), - $menu_title, $action_name == 'siteadminpanel', 'nav_site_admin_panel'); - } - - if (AdminPanelAction::canAdmin('design')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Design configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('designadminpanel'), _m('MENU', 'Design'), - $menu_title, $action_name == 'designadminpanel', 'nav_design_admin_panel'); - } - - if (AdminPanelAction::canAdmin('user')) { - // TRANS: Menu item title/tooltip - $menu_title = _('User configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('useradminpanel'), _('User'), - $menu_title, $action_name == 'useradminpanel', 'nav_user_admin_panel'); - } - - if (AdminPanelAction::canAdmin('access')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Access configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('accessadminpanel'), _('Access'), - $menu_title, $action_name == 'accessadminpanel', 'nav_access_admin_panel'); - } - - if (AdminPanelAction::canAdmin('paths')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Paths configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'), - $menu_title, $action_name == 'pathsadminpanel', 'nav_paths_admin_panel'); - } - - if (AdminPanelAction::canAdmin('sessions')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Sessions configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'), - $menu_title, $action_name == 'sessionsadminpanel', 'nav_sessions_admin_panel'); - } - - if (AdminPanelAction::canAdmin('sitenotice')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Edit site notice'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('sitenoticeadminpanel'), _('Site notice'), - $menu_title, $action_name == 'sitenoticeadminpanel', 'nav_sitenotice_admin_panel'); - } - - if (AdminPanelAction::canAdmin('snapshot')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Snapshots configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('snapshotadminpanel'), _('Snapshots'), - $menu_title, $action_name == 'snapshotadminpanel', 'nav_snapshot_admin_panel'); - } - - if (AdminPanelAction::canAdmin('license')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Set site license'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('licenseadminpanel'), _('License'), - $menu_title, $action_name == 'licenseadminpanel', 'nav_license_admin_panel'); - } - - if (AdminPanelAction::canAdmin('plugins')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Plugins configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('pluginsadminpanel'), _('Plugins'), - $menu_title, $action_name == 'pluginsadminpanel', 'nav_design_admin_panel'); - } - - Event::handle('EndAdminPanelNav', array($this)); - } - $this->action->elementEnd('ul'); - } -} diff --git a/lib/adminpanelnav.php b/lib/adminpanelnav.php new file mode 100644 index 0000000000..ceedf6ceac --- /dev/null +++ b/lib/adminpanelnav.php @@ -0,0 +1,148 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2011, StatusNet, Inc. + * + * Menu for admin panels + * + * PHP version 5 + * + * 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/>. + * + * @category Menu + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Menu for admin panels + * + * @category Output + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @author Sarven Capadisli <csarven@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class AdminPanelNav extends Menu +{ + /** + * Show the menu + * + * @return void + */ + function show() + { + $action_name = $this->action->trimmed('action'); + + $this->action->elementStart('ul', array('class' => 'nav')); + + if (Event::handle('StartAdminPanelNav', array($this))) { + + if (AdminPanelAction::canAdmin('site')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Basic site configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('siteadminpanel'), _m('MENU', 'Site'), + $menu_title, $action_name == 'siteadminpanel', 'nav_site_admin_panel'); + } + + if (AdminPanelAction::canAdmin('design')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Design configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('designadminpanel'), _m('MENU', 'Design'), + $menu_title, $action_name == 'designadminpanel', 'nav_design_admin_panel'); + } + + if (AdminPanelAction::canAdmin('user')) { + // TRANS: Menu item title/tooltip + $menu_title = _('User configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('useradminpanel'), _('User'), + $menu_title, $action_name == 'useradminpanel', 'nav_user_admin_panel'); + } + + if (AdminPanelAction::canAdmin('access')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Access configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('accessadminpanel'), _('Access'), + $menu_title, $action_name == 'accessadminpanel', 'nav_access_admin_panel'); + } + + if (AdminPanelAction::canAdmin('paths')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Paths configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'), + $menu_title, $action_name == 'pathsadminpanel', 'nav_paths_admin_panel'); + } + + if (AdminPanelAction::canAdmin('sessions')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Sessions configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'), + $menu_title, $action_name == 'sessionsadminpanel', 'nav_sessions_admin_panel'); + } + + if (AdminPanelAction::canAdmin('sitenotice')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Edit site notice'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('sitenoticeadminpanel'), _('Site notice'), + $menu_title, $action_name == 'sitenoticeadminpanel', 'nav_sitenotice_admin_panel'); + } + + if (AdminPanelAction::canAdmin('snapshot')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Snapshots configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('snapshotadminpanel'), _('Snapshots'), + $menu_title, $action_name == 'snapshotadminpanel', 'nav_snapshot_admin_panel'); + } + + if (AdminPanelAction::canAdmin('license')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Set site license'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('licenseadminpanel'), _('License'), + $menu_title, $action_name == 'licenseadminpanel', 'nav_license_admin_panel'); + } + + if (AdminPanelAction::canAdmin('plugins')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Plugins configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('pluginsadminpanel'), _('Plugins'), + $menu_title, $action_name == 'pluginsadminpanel', 'nav_design_admin_panel'); + } + + Event::handle('EndAdminPanelNav', array($this)); + } + $this->action->elementEnd('ul'); + } +} diff --git a/lib/default.php b/lib/default.php index c612557d69..e6caf0301a 100644 --- a/lib/default.php +++ b/lib/default.php @@ -33,7 +33,7 @@ $default = 'nickname' => 'statusnet', 'wildcard' => null, 'server' => $_server, - 'theme' => 'default', + 'theme' => 'neo', 'path' => $_path, 'logfile' => null, 'logo' => null, diff --git a/lib/defaultlocalnav.php b/lib/defaultlocalnav.php new file mode 100644 index 0000000000..7af3c9673f --- /dev/null +++ b/lib/defaultlocalnav.php @@ -0,0 +1,66 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2011, StatusNet, Inc. + * + * Default local nav + * + * PHP version 5 + * + * 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/>. + * + * @category Menu + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Default menu + * + * @category Menu + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class DefaultLocalNav extends Menu +{ + function show() + { + $this->action->elementStart('ul', array('id' => 'nav_local_default')); + + $user = common_current_user(); + + if (!empty($user)) { + $pn = new PersonalGroupNav($this->action); + $this->submenu(_m('Home'), $pn); + } + + $bn = new PublicGroupNav($this->action); + $this->submenu(_('Public'), $bn); + + $this->action->elementEnd('ul'); + } +} diff --git a/lib/galleryaction.php b/lib/galleryaction.php index b8edbbb7ba..107134a09b 100644 --- a/lib/galleryaction.php +++ b/lib/galleryaction.php @@ -94,7 +94,7 @@ class GalleryAction extends OwnerDesignAction $this->showPage(); } - function showLocalNav() + function showObjectNav() { $nav = new SubGroupNav($this, $this->user); $nav->show(); diff --git a/lib/groupnav.php b/lib/groupnav.php index ee988d0a98..a2dd6eac00 100644 --- a/lib/groupnav.php +++ b/lib/groupnav.php @@ -49,9 +49,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * @see HTMLOutputter */ -class GroupNav extends Widget +class GroupNav extends Menu { - var $action = null; var $group = null; /** @@ -63,7 +62,6 @@ class GroupNav extends Widget function __construct($action=null, $group=null) { parent::__construct($action); - $this->action = $action; $this->group = $group; } diff --git a/lib/logingroupnav.php b/lib/logingroupnav.php index a309e7320f..3c67f76322 100644 --- a/lib/logingroupnav.php +++ b/lib/logingroupnav.php @@ -44,21 +44,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * * @see Widget */ -class LoginGroupNav extends Widget +class LoginGroupNav extends Menu { - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - /** * Show the menu * diff --git a/lib/mailbox.php b/lib/mailbox.php index 7faeb7dba3..cb56eb5904 100644 --- a/lib/mailbox.php +++ b/lib/mailbox.php @@ -168,4 +168,10 @@ class MailboxAction extends CurrentUserDesignAction { return true; } + + function showObjectNav() + { + $mm = new MailboxMenu($this); + $mm->show(); + } } diff --git a/lib/mailboxmenu.php b/lib/mailboxmenu.php new file mode 100644 index 0000000000..d2d3607dce --- /dev/null +++ b/lib/mailboxmenu.php @@ -0,0 +1,70 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2011, StatusNet, Inc. + * + * Private mailboxes menu + * + * PHP version 5 + * + * 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/>. + * + * @category Cache + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Menu of existing mailboxes + * + * @category General + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class MailboxMenu extends Menu +{ + function show() + { + $cur = common_current_user(); + $nickname = $cur->nickname; + + $this->out->elementStart('ul', array('class' => 'nav')); + + $this->item('inbox', + array('nickname' => $nickname), + _('Inbox'), + _('Your incoming messages')); + + $this->item('outbox', + array('nickname' => $nickname), + _('Outbox'), + _('Your sent messages')); + + $this->out->elementEnd('ul'); + } + +} diff --git a/lib/menu.php b/lib/menu.php new file mode 100644 index 0000000000..2713b44d50 --- /dev/null +++ b/lib/menu.php @@ -0,0 +1,92 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2011, StatusNet, Inc. + * + * Menu widget + * + * PHP version 5 + * + * 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/>. + * + * @category Widget + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Superclass for menus + * + * @category General + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class Menu extends Widget +{ + var $action = null; + var $actionName = null; + /** + * Construction + * + * @param Action $action current action, used for output + */ + function __construct($action=null) + { + parent::__construct($action); + + $this->action = $action; + $this->actionName = $action->trimmed('action'); + } + + function item($actionName, $args, $label, $description, $id=null) + { + if (empty($id)) { + $id = $this->menuItemID($actionName); + } + + $url = common_local_url($actionName, $args); + + $this->out->menuItem($url, + $label, + $description, + $actionName == $this->actionName, + $id); + } + + function menuItemID($actionName) + { + return sprintf('nav_%s', $actionName); + } + + function submenu($label, $menu) + { + $this->action->elementStart('li'); + $this->action->element('h3', null, $label); + $menu->show(); + $this->action->elementEnd('li'); + } +} diff --git a/lib/microappplugin.php b/lib/microappplugin.php new file mode 100644 index 0000000000..dbbc6262af --- /dev/null +++ b/lib/microappplugin.php @@ -0,0 +1,311 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2011, StatusNet, Inc. + * + * Superclass for microapp plugin + * + * PHP version 5 + * + * 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/>. + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Superclass for microapp plugins + * + * This class lets you define micro-applications with different kinds of activities. + * + * The applications work more-or-less like other + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +abstract class MicroAppPlugin extends Plugin +{ + abstract function appTitle(); + abstract function tag(); + abstract function types(); + abstract function saveNoticeFromActivity($activity, $actor, $options); + abstract function activityObjectFromNotice($notice); + abstract function showNotice($notice, $out); + abstract function entryForm($out); + abstract function deleteRelated($notice); + + function isMyNotice($notice) { + $types = $this->types(); + return in_array($notice->object_type, $types); + } + + function isMyActivity($activity) { + $types = $this->types(); + return (count($activity->objects) == 1 && + in_array($activity->objects[0]->type, $types)); + } + + /** + * When a notice is deleted, delete the related objects + * + * @param Notice $notice Notice being deleted + * + * @return boolean hook value + */ + + function onNoticeDeleteRelated($notice) + { + if ($this->isMyNotice($notice)) { + $this->deleteRelated($notice); + } + + return true; + } + + /** + * Output the HTML for this kind of object in a list + * + * @param NoticeListItem $nli The list item being shown. + * + * @return boolean hook value + */ + + function onStartShowNoticeItem($nli) + { + if (!$this->isMyNotice($nli->notice)) { + return true; + } + + $out = $nli->out; + $notice = $nli->notice; + + $this->showNotice($notice, $out); + + $nli->showNoticeLink(); + $nli->showNoticeSource(); + $nli->showNoticeLocation(); + $nli->showContext(); + $nli->showRepeat(); + + $out->elementEnd('div'); + + $nli->showNoticeOptions(); + + return false; + } + + /** + * Render a notice as one of our objects + * + * @param Notice $notice Notice to render + * @param ActivityObject &$object Empty object to fill + * + * @return boolean hook value + */ + + function onStartActivityObjectFromNotice($notice, &$object) + { + if ($this->isMyNotice($notice)) { + $object = $this->activityObjectFromNotice($notice); + return false; + } + + return true; + } + + /** + * Handle a posted object from PuSH + * + * @param Activity $activity activity to handle + * @param Ostatus_profile $oprofile Profile for the feed + * + * @return boolean hook value + */ + + function onStartHandleFeedEntryWithProfile($activity, $oprofile) + { + if ($this->isMyActivity($activity)) { + + $actor = $oprofile->checkAuthorship($activity); + + if (empty($actor)) { + throw new ClientException(_('Can\'t get author for activity.')); + } + + $object = $activity->objects[0]; + + $options = array('uri' => $object->id, + 'url' => $object->link, + 'is_local' => Notice::REMOTE_OMB, + 'source' => 'ostatus'); + + $this->saveNoticeFromActivity($activity, $actor); + + return false; + } + + return true; + } + + /** + * Handle a posted object from Salmon + * + * @param Activity $activity activity to handle + * @param mixed $target user or group targeted + * + * @return boolean hook value + */ + + function onStartHandleSalmonTarget($activity, $target) + { + if ($this->isMyActivity($activity)) { + + $this->log(LOG_INFO, "Checking {$activity->id} as a valid Salmon slap."); + + if ($target instanceof User_group) { + $uri = $target->getUri(); + if (!in_array($uri, $activity->context->attention)) { + throw new ClientException(_("Bookmark not posted ". + "to this group.")); + } + } else if ($target instanceof User) { + $uri = $target->uri; + $original = null; + if (!empty($activity->context->replyToID)) { + $original = Notice::staticGet('uri', + $activity->context->replyToID); + } + if (!in_array($uri, $activity->context->attention) && + (empty($original) || + $original->profile_id != $target->id)) { + throw new ClientException(_("Object not posted ". + "to this user.")); + } + } else { + throw new ServerException(_("Don't know how to handle ". + "this kind of target.")); + } + + $actor = Ostatus_profile::ensureActivityObjectProfile($activity->actor); + + $object = $activity->objects[0]; + + $options = array('uri' => $object->id, + 'url' => $object->link, + 'is_local' => Notice::REMOTE_OMB, + 'source' => 'ostatus'); + + $this->saveNoticeFromActivity($activity, $actor, $options); + + return false; + } + + return true; + } + + /** + * Handle object posted via AtomPub + * + * @param Activity &$activity Activity that was posted + * @param User $user User that posted it + * @param Notice &$notice Resulting notice + * + * @return boolean hook value + */ + + function onStartAtomPubNewActivity(&$activity, $user, &$notice) + { + if ($this->isMyActivity($activity)) { + + $options = array('source' => 'atompub'); + + $this->saveNoticeFromActivity($activity, + $user->getProfile(), + $options); + + return false; + } + + return true; + } + + /** + * Handle object imported from a backup file + * + * @param User $user User to import for + * @param ActivityObject $author Original author per import file + * @param Activity $activity Activity to import + * @param boolean $trusted Is this a trusted user? + * @param boolean &$done Is this done (success or unrecoverable error) + * + * @return boolean hook value + */ + + function onStartImportActivity($user, $author, $activity, $trusted, &$done) + { + if ($this->isMyActivity($activity)) { + + $obj = $activity->objects[0]; + + $options = array('uri' => $object->id, + 'url' => $object->link, + 'source' => 'restore'); + + $saved = $this->saveNoticeFromActivity($activity, + $user->getProfile(), + $options); + + if (!empty($saved)) { + $done = true; + } + + return false; + } + + return true; + } + + function onStartShowEntryForms(&$tabs) + { + $tabs[$this->tag()] = $this->appTitle(); + return true; + } + + function onStartMakeEntryForm($tag, $out, &$form) + { + $this->log(LOG_INFO, "onStartMakeEntryForm() called for tag '$tag'"); + + if ($tag == $this->tag()) { + $form = $this->entryForm($out); + return false; + } + + return true; + } +} diff --git a/lib/personalgroupnav.php b/lib/personalgroupnav.php index 72d0893af7..3d6bb98fc0 100644 --- a/lib/personalgroupnav.php +++ b/lib/personalgroupnav.php @@ -2,7 +2,7 @@ /** * StatusNet, the distributed open-source microblogging tool * - * Base class for all actions (~views) + * Menu for personal group of actions * * PHP version 5 * @@ -19,11 +19,11 @@ * 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 Action + * @category Menu * @package StatusNet * @author Evan Prodromou <evan@status.net> * @author Sarven Capadisli <csarven@status.net> - * @copyright 2008 StatusNet, Inc. + * @copyright 2008-2011 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/ */ @@ -32,41 +32,20 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -require_once INSTALLDIR.'/lib/widget.php'; - /** - * Base class for all actions + * Menu for personal group of actions * - * This is the base class for all actions in the package. An action is - * more or less a "view" in an MVC framework. - * - * Actions are responsible for extracting and validating parameters; using - * model classes to read and write to the database; and doing ouput. - * - * @category Output + * @category Menu * @package StatusNet * @author Evan Prodromou <evan@status.net> * @author Sarven Capadisli <csarven@status.net> + * @copyright 2008-2011 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/ - * - * @see HTMLOutputter */ -class PersonalGroupNav extends Widget + +class PersonalGroupNav extends Menu { - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - /** * Show the menu * @@ -74,23 +53,16 @@ class PersonalGroupNav extends Widget */ function show() { - $user = null; + $user = common_current_user(); - // FIXME: we should probably pass this in - - $action = $this->action->trimmed('action'); - $nickname = $this->action->trimmed('nickname'); - - if ($nickname) { - $user = User::staticGet('nickname', $nickname); - $user_profile = $user->getProfile(); - $name = $user_profile->getBestName(); - } else { - // @fixme can this happen? is this valid? - $user_profile = false; - $name = $nickname; + if (empty($user)) { + throw new ServerException('Do not show personal group nav with no current user.'); } + $user_profile = $user->getProfile(); + $nickname = $user->nickname; + $name = $user_profile->getBestName(); + $this->out->elementStart('ul', array('class' => 'nav')); if (Event::handle('StartPersonalGroupNav', array($this))) { @@ -98,17 +70,23 @@ class PersonalGroupNav extends Widget $nickname)), _('Home'), sprintf(_('%s and friends'), $name), - $action == 'all', 'nav_timeline_personal'); + $this->action == 'all', 'nav_timeline_personal'); + $this->out->menuItem(common_local_url('showstream', array('nickname' => + $nickname)), + _('Profile'), + _('Your profile'), + $this->action == 'showstream', + 'nav_profile'); $this->out->menuItem(common_local_url('replies', array('nickname' => $nickname)), _('Replies'), sprintf(_('Replies to %s'), $name), - $action == 'replies', 'nav_timeline_replies'); + $this->action == 'replies', 'nav_timeline_replies'); $this->out->menuItem(common_local_url('showfavorites', array('nickname' => $nickname)), _('Favorites'), sprintf(_('%s\'s favorite notices'), ($user_profile) ? $name : _('User')), - $action == 'showfavorites', 'nav_timeline_favorites'); + $this->action == 'showfavorites', 'nav_timeline_favorites'); $cur = common_current_user(); @@ -117,15 +95,11 @@ class PersonalGroupNav extends Widget $this->out->menuItem(common_local_url('inbox', array('nickname' => $nickname)), - _('Inbox'), + _('Messages'), _('Your incoming messages'), - $action == 'inbox'); - $this->out->menuItem(common_local_url('outbox', array('nickname' => - $nickname)), - _('Outbox'), - _('Your sent messages'), - $action == 'outbox'); + $this->action == 'inbox'); } + Event::handle('EndPersonalGroupNav', array($this)); } $this->out->elementEnd('ul'); diff --git a/lib/primarynav.php b/lib/primarynav.php new file mode 100644 index 0000000000..7748d7a1c7 --- /dev/null +++ b/lib/primarynav.php @@ -0,0 +1,94 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2011, StatusNet, Inc. + * + * Primary nav, show on all pages + * + * PHP version 5 + * + * 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/>. + * + * @category Menu + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Primary, top-level menu + * + * @category General + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class PrimaryNav extends Menu +{ + function show() + { + $user = common_current_user(); + $this->action->elementStart('ul', array('class' => 'nav')); + if (Event::handle('StartPrimaryNav', array($this->action))) { + if (!empty($user)) { + $this->action->menuItem(common_local_url('profilesettings'), + _m('Settings'), + _m('Change your personal settings'), + false, + 'nav_account'); + if ($user->hasRight(Right::CONFIGURESITE)) { + $this->action->menuItem(common_local_url('siteadminpanel'), + _m('Admin'), + _m('Site configuration'), + false, + 'nav_admin'); + } + $this->action->menuItem(common_local_url('logout'), + _m('Logout'), + _m('Logout from the site'), + false, + 'nav_logout'); + } else { + $this->action->menuItem(common_local_url('login'), + _m('Login'), + _m('Login to the site'), + false, + 'nav_login'); + } + + if (!empty($user) || !common_config('site', 'private')) { + $this->action->menuItem(common_local_url('noticesearch'), + _m('Search'), + _m('Search the site'), + false, + 'nav_search'); + } + + Event::handle('EndPrimaryNav', array($this->action)); + } + + $this->action->elementEnd('ul'); + } +} diff --git a/lib/publicgroupnav.php b/lib/publicgroupnav.php index ae9cbdebb4..bd2ad53124 100644 --- a/lib/publicgroupnav.php +++ b/lib/publicgroupnav.php @@ -46,22 +46,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * @see Widget */ -class PublicGroupNav extends Widget +class PublicGroupNav extends Menu { - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - /** * Show the menu * diff --git a/lib/searchaction.php b/lib/searchaction.php index 67d0bcdeb8..73c287eef3 100644 --- a/lib/searchaction.php +++ b/lib/searchaction.php @@ -70,7 +70,7 @@ class SearchAction extends Action * @return void * @see SearchGroupNav */ - function showLocalNav() + function showObjectNav() { $nav = new SearchGroupNav($this, $this->trimmed('q')); $nav->show(); diff --git a/lib/searchgroupnav.php b/lib/searchgroupnav.php index e843dc096c..cfe8fde353 100644 --- a/lib/searchgroupnav.php +++ b/lib/searchgroupnav.php @@ -2,7 +2,7 @@ /** * StatusNet, the distributed open-source microblogging tool * - * Menu for search actions + * Menu for search group of actions * * PHP version 5 * @@ -22,7 +22,7 @@ * @category Menu * @package StatusNet * @author Evan Prodromou <evan@status.net> - * @copyright 2008 StatusNet, Inc. + * @copyright 2008-2011 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/ */ @@ -31,12 +31,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -require_once INSTALLDIR.'/lib/widget.php'; - /** * Menu for public group of actions * - * @category Output + * @category Menu * @package StatusNet * @author Evan Prodromou <evan@status.net> * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 @@ -45,9 +43,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * @see Widget */ -class SearchGroupNav extends Widget +class SearchGroupNav extends Menu { - var $action = null; var $q = null; /** @@ -59,7 +56,6 @@ class SearchGroupNav extends Widget function __construct($action=null, $q = null) { parent::__construct($action); - $this->action = $action; $this->q = $q; } diff --git a/lib/secondarynav.php b/lib/secondarynav.php new file mode 100644 index 0000000000..542de51ac1 --- /dev/null +++ b/lib/secondarynav.php @@ -0,0 +1,90 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2011, StatusNet, Inc. + * + * Secondary menu, shown at foot of all pages + * + * PHP version 5 + * + * 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/>. + * + * @category Cache + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Secondary menu, shown at the bottom of all pages + * + * @category General + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class SecondaryNav extends Menu +{ + function show() + { + $this->out->elementStart('ul', array('class' => 'nav', + 'id' => 'site_nav_global_secondary')); + if (Event::handle('StartSecondaryNav', array($this->action))) { + $this->out->menuItem(common_local_url('doc', array('title' => 'help')), + // TRANS: Secondary navigation menu option leading to help on StatusNet. + _('Help')); + $this->out->menuItem(common_local_url('doc', array('title' => 'about')), + // TRANS: Secondary navigation menu option leading to text about StatusNet site. + _('About')); + $this->out->menuItem(common_local_url('doc', array('title' => 'faq')), + // TRANS: Secondary navigation menu option leading to Frequently Asked Questions. + _('FAQ')); + $bb = common_config('site', 'broughtby'); + if (!empty($bb)) { + $this->out->menuItem(common_local_url('doc', array('title' => 'tos')), + // TRANS: Secondary navigation menu option leading to Terms of Service. + _('TOS')); + } + $this->out->menuItem(common_local_url('doc', array('title' => 'privacy')), + // TRANS: Secondary navigation menu option leading to privacy policy. + _('Privacy')); + $this->out->menuItem(common_local_url('doc', array('title' => 'source')), + // TRANS: Secondary navigation menu option. Leads to information about StatusNet and its license. + _('Source')); + $this->out->menuItem(common_local_url('version'), + // TRANS: Secondary navigation menu option leading to version information on the StatusNet site. + _('Version')); + $this->out->menuItem(common_local_url('doc', array('title' => 'contact')), + // TRANS: Secondary navigation menu option leading to e-mail contact information on the + // TRANS: StatusNet site, where to report bugs, ... + _('Contact')); + $this->out->menuItem(common_local_url('doc', array('title' => 'badge')), + // TRANS: Secondary navigation menu option. Leads to information about embedding a timeline widget. + _('Badge')); + Event::handle('EndSecondaryNav', array($this->action)); + } + $this->out->elementEnd('ul'); + } +} \ No newline at end of file diff --git a/lib/settingsaction.php b/lib/settingsaction.php index 8c00054dcb..dc60137ab4 100644 --- a/lib/settingsaction.php +++ b/lib/settingsaction.php @@ -163,4 +163,15 @@ class SettingsAction extends CurrentUserDesignAction $menu = new SettingsNav($this); $menu->show(); } + + /** + * Show notice form. + * + * @return nothing + */ + + function showNoticeForm() + { + return; + } } diff --git a/lib/settingsnav.php b/lib/settingsnav.php index a73f73f86a..697e7ee46b 100644 --- a/lib/settingsnav.php +++ b/lib/settingsnav.php @@ -1,7 +1,7 @@ <?php /** * StatusNet - the distributed open-source microblogging tool - * Copyright (C) 2010, StatusNet, Inc. + * Copyright (C) 2010,2011, StatusNet, Inc. * * Settings menu * @@ -23,7 +23,7 @@ * @category Widget * @package StatusNet * @author Evan Prodromou <evan@status.net> - * @copyright 2010 StatusNet, Inc. + * @copyright 2010,2011 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ @@ -46,21 +46,8 @@ if (!defined('STATUSNET')) { * @see HTMLOutputter */ -class SettingsNav extends Widget +class SettingsNav extends Menu { - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - /** * Show the menu * diff --git a/lib/subgroupnav.php b/lib/subgroupnav.php index be3ba27480..ee4b0a8dff 100644 --- a/lib/subgroupnav.php +++ b/lib/subgroupnav.php @@ -22,7 +22,7 @@ * @category Subs * @package StatusNet * @author Evan Prodromou <evan@status.net> - * @copyright 2008-2009 StatusNet, Inc. + * @copyright 2008-2011 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/ */ @@ -43,9 +43,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * @link http://status.net/ */ -class SubGroupNav extends Widget +class SubGroupNav extends Menu { - var $action = null; var $user = null; /** @@ -57,7 +56,6 @@ class SubGroupNav extends Widget function __construct($action=null, $user=null) { parent::__construct($action); - $this->action = $action; $this->user = $user; } diff --git a/lib/userprofile.php b/lib/userprofile.php index 0b7efb22fc..9c563db5d0 100644 --- a/lib/userprofile.php +++ b/lib/userprofile.php @@ -95,6 +95,8 @@ class UserProfile extends Widget function showAvatar() { + $this->out->elementStart('div', 'ur_face'); + if (Event::handle('StartProfilePageAvatar', array($this->out, $this->profile))) { $avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE); @@ -119,6 +121,8 @@ class UserProfile extends Widget Event::handle('EndProfilePageAvatar', array($this->out, $this->profile)); } + + $this->out->elementEnd('div'); } function showNickname() diff --git a/plugins/Bookmark/Bookmark.php b/plugins/Bookmark/Bookmark.php index 777b50f724..04cd8dbfa8 100644 --- a/plugins/Bookmark/Bookmark.php +++ b/plugins/Bookmark/Bookmark.php @@ -307,7 +307,8 @@ class Bookmark extends Memcached_DataObject $options = array_merge(array('urls' => array($url), 'rendered' => $rendered, 'tags' => $tags, - 'replies' => $replies), + 'replies' => $replies, + 'object_type' => ActivityObject::BOOKMARK), $options); if (!array_key_exists('uri', $options)) { diff --git a/plugins/Bookmark/BookmarkPlugin.php b/plugins/Bookmark/BookmarkPlugin.php index 2e6baf5e4e..44f3db7867 100644 --- a/plugins/Bookmark/BookmarkPlugin.php +++ b/plugins/Bookmark/BookmarkPlugin.php @@ -44,7 +44,7 @@ if (!defined('STATUSNET')) { * @link http://status.net/ */ -class BookmarkPlugin extends Plugin +class BookmarkPlugin extends MicroAppPlugin { const VERSION = '0.1'; const IMPORTDELICIOUS = 'BookmarkPlugin:IMPORTDELICIOUS'; @@ -120,25 +120,6 @@ class BookmarkPlugin extends Plugin return true; } - /** - * When a notice is deleted, delete the related Bookmark - * - * @param Notice $notice Notice being deleted - * - * @return boolean hook value - */ - - function onNoticeDeleteRelated($notice) - { - $nb = Bookmark::getByNotice($notice); - - if (!empty($nb)) { - $nb->delete(); - } - - return true; - } - /** * Show the CSS necessary for this plugin * @@ -218,212 +199,6 @@ class BookmarkPlugin extends Plugin return true; } - /** - * Output the HTML for a bookmark in a list - * - * @param NoticeListItem $nli The list item being shown. - * - * @return boolean hook value - */ - - function onStartShowNoticeItem($nli) - { - $nb = Bookmark::getByNotice($nli->notice); - - if (!empty($nb)) { - - $out = $nli->out; - $notice = $nli->notice; - $profile = $nli->profile; - - $atts = $notice->attachments(); - - if (count($atts) < 1) { - // Something wrong; let default code deal with it. - return true; - } - - $att = $atts[0]; - - // XXX: only show the bookmark URL for non-single-page stuff - - if ($out instanceof ShowbookmarkAction) { - } else { - $out->elementStart('h3'); - $out->element('a', - array('href' => $att->url, - 'class' => 'bookmark-title entry-title'), - $nb->title); - $out->elementEnd('h3'); - - $countUrl = common_local_url('noticebyurl', - array('id' => $att->id)); - - $out->element('a', array('class' => 'bookmark-notice-count', - 'href' => $countUrl), - $att->noticeCount()); - } - - // Replies look like "for:" tags - - $replies = $nli->notice->getReplies(); - $tags = $nli->notice->getTags(); - - if (!empty($replies) || !empty($tags)) { - - $out->elementStart('ul', array('class' => 'bookmark-tags')); - - foreach ($replies as $reply) { - $other = Profile::staticGet('id', $reply); - $out->elementStart('li'); - $out->element('a', array('rel' => 'tag', - 'href' => $other->profileurl, - 'title' => $other->getBestName()), - sprintf('for:%s', $other->nickname)); - $out->elementEnd('li'); - $out->text(' '); - } - - foreach ($tags as $tag) { - $out->elementStart('li'); - $out->element('a', - array('rel' => 'tag', - 'href' => Notice_tag::url($tag)), - $tag); - $out->elementEnd('li'); - $out->text(' '); - } - - $out->elementEnd('ul'); - } - - if (!empty($nb->description)) { - $out->element('p', - array('class' => 'bookmark-description'), - $nb->description); - } - - if (common_config('attachments', 'show_thumbs')) { - $haveThumbs = false; - foreach ($atts as $check) { - $thumbnail = File_thumbnail::staticGet('file_id', $check->id); - if (!empty($thumbnail)) { - $haveThumbs = true; - break; - } - } - if ($haveThumbs) { - $al = new InlineAttachmentList($notice, $out); - $al->show(); - } - } - - $out->elementStart('div', array('class' => 'bookmark-info entry-content')); - - $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); - - $out->element('img', - array('src' => ($avatar) ? - $avatar->displayUrl() : - Avatar::defaultImage(AVATAR_MINI_SIZE), - 'class' => 'avatar photo bookmark-avatar', - 'width' => AVATAR_MINI_SIZE, - 'height' => AVATAR_MINI_SIZE, - 'alt' => $profile->getBestName())); - - $out->raw(' '); - - $out->element('a', - array('href' => $profile->profileurl, - 'title' => $profile->getBestName()), - $profile->nickname); - - $nli->showNoticeLink(); - $nli->showNoticeSource(); - $nli->showNoticeLocation(); - $nli->showContext(); - $nli->showRepeat(); - - $out->elementEnd('div'); - - $nli->showNoticeOptions(); - - return false; - } - return true; - } - - /** - * Render a notice as a Bookmark object - * - * @param Notice $notice Notice to render - * @param ActivityObject &$object Empty object to fill - * - * @return boolean hook value - */ - - function onStartActivityObjectFromNotice($notice, &$object) - { - common_log(LOG_INFO, - "Checking {$notice->uri} to see if it's a bookmark."); - - $nb = Bookmark::getByNotice($notice); - - if (!empty($nb)) { - - common_log(LOG_INFO, - "Formatting notice {$notice->uri} as a bookmark."); - - $object->id = $notice->uri; - $object->type = ActivityObject::BOOKMARK; - $object->title = $nb->title; - $object->summary = $nb->description; - $object->link = $notice->bestUrl(); - - // Attributes of the URL - - $attachments = $notice->attachments(); - - if (count($attachments) != 1) { - throw new ServerException(_('Bookmark notice with the '. - 'wrong number of attachments.')); - } - - $target = $attachments[0]; - - $attrs = array('rel' => 'related', - 'href' => $target->url); - - if (!empty($target->title)) { - $attrs['title'] = $target->title; - } - - $object->extra[] = array('link', $attrs, null); - - // Attributes of the thumbnail, if any - - $thumbnail = $target->getThumbnail(); - - if (!empty($thumbnail)) { - $tattrs = array('rel' => 'preview', - 'href' => $thumbnail->url); - - if (!empty($thumbnail->width)) { - $tattrs['media:width'] = $thumbnail->width; - } - - if (!empty($thumbnail->height)) { - $tattrs['media:height'] = $thumbnail->height; - } - - $object->extra[] = array('link', $attrs, null); - } - - return false; - } - - return true; - } /** * Add our two queue handlers to the queue manager @@ -481,149 +256,7 @@ class BookmarkPlugin extends Plugin return true; } - /** - * Handle a posted bookmark from PuSH - * - * @param Activity $activity activity to handle - * @param Ostatus_profile $oprofile Profile for the feed - * - * @return boolean hook value - */ - function onStartHandleFeedEntryWithProfile($activity, $oprofile) - { - common_log(LOG_INFO, "BookmarkPlugin called for new feed entry."); - - if (self::_isPostBookmark($activity)) { - - common_log(LOG_INFO, - "Importing activity {$activity->id} as a bookmark."); - - $author = $oprofile->checkAuthorship($activity); - - if (empty($author)) { - throw new ClientException(_('Can\'t get author for activity.')); - } - - self::_postRemoteBookmark($author, - $activity); - - return false; - } - - return true; - } - - /** - * Handle a posted bookmark from Salmon - * - * @param Activity $activity activity to handle - * @param mixed $target user or group targeted - * - * @return boolean hook value - */ - - function onStartHandleSalmonTarget($activity, $target) - { - if (self::_isPostBookmark($activity)) { - - $this->log(LOG_INFO, "Checking {$activity->id} as a valid Salmon slap."); - - if ($target instanceof User_group) { - $uri = $target->getUri(); - if (!in_array($uri, $activity->context->attention)) { - throw new ClientException(_("Bookmark not posted ". - "to this group.")); - } - } else if ($target instanceof User) { - $uri = $target->uri; - $original = null; - if (!empty($activity->context->replyToID)) { - $original = Notice::staticGet('uri', - $activity->context->replyToID); - } - if (!in_array($uri, $activity->context->attention) && - (empty($original) || - $original->profile_id != $target->id)) { - throw new ClientException(_("Bookmark not posted ". - "to this user.")); - } - } else { - throw new ServerException(_("Don't know how to handle ". - "this kind of target.")); - } - - $author = Ostatus_profile::ensureActivityObjectProfile($activity->actor); - - self::_postRemoteBookmark($author, - $activity); - - return false; - } - - return true; - } - - /** - * Handle bookmark posted via AtomPub - * - * @param Activity &$activity Activity that was posted - * @param User $user User that posted it - * @param Notice &$notice Resulting notice - * - * @return boolean hook value - */ - - function onStartAtomPubNewActivity(&$activity, $user, &$notice) - { - if (self::_isPostBookmark($activity)) { - $options = array('source' => 'atompub'); - $notice = self::_postBookmark($user->getProfile(), - $activity, - $options); - return false; - } - - return true; - } - - /** - * Handle bookmark imported from a backup file - * - * @param User $user User to import for - * @param ActivityObject $author Original author per import file - * @param Activity $activity Activity to import - * @param boolean $trusted Is this a trusted user? - * @param boolean &$done Is this done (success or unrecoverable error) - * - * @return boolean hook value - */ - - function onStartImportActivity($user, $author, $activity, $trusted, &$done) - { - if (self::_isPostBookmark($activity)) { - - $bookmark = $activity->objects[0]; - - $this->log(LOG_INFO, - 'Importing Bookmark ' . $bookmark->id . - ' for user ' . $user->nickname); - - $options = array('uri' => $bookmark->id, - 'url' => $bookmark->link, - 'source' => 'restore'); - - $saved = self::_postBookmark($user->getProfile(), $activity, $options); - - if (!empty($saved)) { - $done = true; - } - - return false; - } - - return true; - } /** * Show a link to our delicious import page on profile settings form @@ -691,6 +324,44 @@ class BookmarkPlugin extends Plugin return self::_postBookmark($author->localProfile(), $activity, $options); } + /** + * Test if an activity represents posting a bookmark + * + * @param Activity $activity Activity to test + * + * @return true if it's a Post of a Bookmark, else false + */ + + static private function _isPostBookmark($activity) + { + return ($activity->verb == ActivityVerb::POST && + $activity->objects[0]->type == ActivityObject::BOOKMARK); + } + + function types() + { + return array(ActivityObject::BOOKMARK); + } + + /** + * When a notice is deleted, delete the related Bookmark + * + * @param Notice $notice Notice being deleted + * + * @return boolean hook value + */ + + function deleteRelated($notice) + { + $nb = Bookmark::getByNotice($notice); + + if (!empty($nb)) { + $nb->delete(); + } + + return true; + } + /** * Save a bookmark from an activity * @@ -701,9 +372,7 @@ class BookmarkPlugin extends Plugin * @return Notice resulting notice */ - static private function _postBookmark(Profile $profile, - Activity $activity, - $options=array()) + function saveNoticeFromActivity($activity, $profile, $options=array()) { $bookmark = $activity->objects[0]; @@ -782,17 +451,184 @@ class BookmarkPlugin extends Plugin $options); } - /** - * Test if an activity represents posting a bookmark - * - * @param Activity $activity Activity to test - * - * @return true if it's a Post of a Bookmark, else false - */ - - static private function _isPostBookmark($activity) + function activityObjectFromNotice($notice) { - return ($activity->verb == ActivityVerb::POST && - $activity->objects[0]->type == ActivityObject::BOOKMARK); + assert($this->isMyNotice($notice)); + + common_log(LOG_INFO, + "Formatting notice {$notice->uri} as a bookmark."); + + $object = new ActivityObject(); + + $object->id = $notice->uri; + $object->type = ActivityObject::BOOKMARK; + $object->title = $nb->title; + $object->summary = $nb->description; + $object->link = $notice->bestUrl(); + + // Attributes of the URL + + $attachments = $notice->attachments(); + + if (count($attachments) != 1) { + throw new ServerException(_('Bookmark notice with the '. + 'wrong number of attachments.')); + } + + $target = $attachments[0]; + + $attrs = array('rel' => 'related', + 'href' => $target->url); + + if (!empty($target->title)) { + $attrs['title'] = $target->title; + } + + $object->extra[] = array('link', $attrs, null); + + // Attributes of the thumbnail, if any + + $thumbnail = $target->getThumbnail(); + + if (!empty($thumbnail)) { + $tattrs = array('rel' => 'preview', + 'href' => $thumbnail->url); + + if (!empty($thumbnail->width)) { + $tattrs['media:width'] = $thumbnail->width; + } + + if (!empty($thumbnail->height)) { + $tattrs['media:height'] = $thumbnail->height; + } + + $object->extra[] = array('link', $attrs, null); + } + + return $object; + } + + function showNotice($notice, $out) + { + $nb = Bookmark::getByNotice($notice); + + $profile = $notice->getProfile(); + + $atts = $notice->attachments(); + + if (count($atts) < 1) { + // Something wrong; let default code deal with it. + throw new Exception("That can't be right."); + } + + $att = $atts[0]; + + // XXX: only show the bookmark URL for non-single-page stuff + + if ($out instanceof ShowbookmarkAction) { + } else { + $out->elementStart('h3'); + $out->element('a', + array('href' => $att->url, + 'class' => 'bookmark-title entry-title'), + $nb->title); + $out->elementEnd('h3'); + + $countUrl = common_local_url('noticebyurl', + array('id' => $att->id)); + + $out->element('a', array('class' => 'bookmark-notice-count', + 'href' => $countUrl), + $att->noticeCount()); + } + + // Replies look like "for:" tags + + $replies = $notice->getReplies(); + $tags = $notice->getTags(); + + if (!empty($replies) || !empty($tags)) { + + $out->elementStart('ul', array('class' => 'bookmark-tags')); + + foreach ($replies as $reply) { + $other = Profile::staticGet('id', $reply); + $out->elementStart('li'); + $out->element('a', array('rel' => 'tag', + 'href' => $other->profileurl, + 'title' => $other->getBestName()), + sprintf('for:%s', $other->nickname)); + $out->elementEnd('li'); + $out->text(' '); + } + + foreach ($tags as $tag) { + $out->elementStart('li'); + $out->element('a', + array('rel' => 'tag', + 'href' => Notice_tag::url($tag)), + $tag); + $out->elementEnd('li'); + $out->text(' '); + } + + $out->elementEnd('ul'); + } + + if (!empty($nb->description)) { + $out->element('p', + array('class' => 'bookmark-description'), + $nb->description); + } + + if (common_config('attachments', 'show_thumbs')) { + $haveThumbs = false; + foreach ($atts as $check) { + $thumbnail = File_thumbnail::staticGet('file_id', $check->id); + if (!empty($thumbnail)) { + $haveThumbs = true; + break; + } + } + if ($haveThumbs) { + $al = new InlineAttachmentList($notice, $out); + $al->show(); + } + } + + $out->elementStart('div', array('class' => 'bookmark-info entry-content')); + + $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); + + $out->element('img', + array('src' => ($avatar) ? + $avatar->displayUrl() : + Avatar::defaultImage(AVATAR_MINI_SIZE), + 'class' => 'avatar photo bookmark-avatar', + 'width' => AVATAR_MINI_SIZE, + 'height' => AVATAR_MINI_SIZE, + 'alt' => $profile->getBestName())); + + $out->raw(' '); + + $out->element('a', + array('href' => $profile->profileurl, + 'title' => $profile->getBestName()), + $profile->nickname); + } + + function entryForm($out) + { + return new BookmarkForm($out); + } + + function tag() + { + return 'bookmark'; + } + + function appTitle() + { + return _m('Bookmark'); } } diff --git a/theme/neo/css/display.css b/theme/neo/css/display.css new file mode 100644 index 0000000000..a542ed7609 --- /dev/null +++ b/theme/neo/css/display.css @@ -0,0 +1,828 @@ +/** theme: neo + * + * @package StatusNet + * @author Samantha Doherty <sammy@status.net> + * @copyright 2011 StatusNet, Inc. + * @license http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution 3.0 Unported + * @link http://status.net/ + */ + + +@media screen, projection, tv { + +body { + background-color: #C6C8CC; + background-image: url(../images/bg.png); + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 82%; +} + +a {color: #3e3e8c;} + +h1 {font-size: 1.6em;} +h2 {font-size: 1.6em;} +h3 {font-size: 1.4em;} +h4 {font-size: 1.4em;} +h5 {font-size: 1.2em;} +h6 {font-size: 1em;} + +#wrap { + width: 930px; + margin: 0px auto; + padding: 0px 15px 10px 15px; + background-color: #fff; + border-left: 10px solid #E0E0E0; + border-right: 10px solid #E0E0E0; +} + +#header { + width: 940px; + padding: 0px; + padding-top: 50px; +} + +address { + float: left; + margin-right: 20px; + margin-top: 0px; +} + +.poweredby { + background: url(../images/sn-tiny.png) no-repeat top left; + height: 40px; + font-size: 0.8em; + color: #fff; + line-height: 42px; + padding-left: 50px; + position: absolute; + top: 6px; + left: 0; + z-index: 99; + font-style: normal; +} + +.poweredby a { + color: #fff !important; + font-weight: bold; +} + +#site_nav_global_primary { + display: block; + position: absolute; + top: 0; + left: 0; + z-index: 98; + background-color: #364A84; + width: 960px; + margin-left: -15px; + margin-top: 0px; + height: 24px; + line-height: 20px; + border-top: 10px solid #fff; + border-bottom: 1px solid #fff; +} + +#site_nav_global_primary ul { + float: right; +} + +#site_nav_global_primary li { + margin-right: 0px; +} + +#site_nav_global_primary li:last-child { + margin-right: 16px; +} + +#site_nav_global_primary a { + color: #fff !important; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); + padding: 2px 12px 2px 12px; + height: 20px; + display: block; + float: left; +} + +#site_nav_global_primary a:hover { + color: #fff !important; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); + background: #4c619c; + text-decoration: none; +} + +#site_notice { + color: #000; + float: right; + width: 280px; + padding: 10px; + margin-left: 40px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +#site_notice a { + color: #3e3e8c; +} + +#anon_notice { + color: #000; + clear: both; + background: none; + padding: 0px; + margin-bottom: 10px; +} + +#anon_notice a { + color: #3e3e8c; +} + +.form_notice { + float: left; + margin-top: 0px; + width: 510px; + padding: 10px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + background: #cdd1dd; +} + +.form_notice fieldset { + width: 100%; +} + +.form_notice textarea { + width: 378px; + height: 54px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.form_notice label[for=notice_data-attach], +.form_notice #notice_data-attach { + top: 27px; + right: 86px; +} + +.form_notice #notice_data-geo_wrap label, +.form_notice #notice_data-geo_wrap input { + top: 52px; + right: 86px; +} + +.form_notice #notice_action-submit { + font-size: 0.9em; + top: 80px; + right: -2px; + height: 2.4em; + width: 106px; +} + +.form_notice .error, +.form_notice .success { + width: 341px; +} + +.form_notice .error { + margin-left: 0px; +} + +#core { + clear: both; + margin: 0px; + width: 930px; + margin-left: 0px; + margin-top: 8px; +} + +#content { + width: 530px; + margin-right: 0px; + padding-left: 30px; + padding-right: 30px; +} + +#site_nav_local_views { + display: block; + float: left; + width: 130px; + margin-top: 5px; +} + +#site_nav_local_views H3 { + border-bottom: 3px solid #A6ADBF; + color: #A6ADBF; + font-size: 1.1em; + letter-spacing: 2px; + margin-bottom: 10px; + text-transform: uppercase; +} + +#site_nav_local_views li { + display: block; + margin: 0px 0px 6px 0px; +} + +#site_nav_local_views li ul { + margin-bottom: 20px; +} + +#site_nav_local_views a { + padding: 2px 0px 2px 10px; + display: block; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +#site_nav_local_views a:hover { + background: #8e98b4 !important; + color: #fff !important; + text-decoration: none; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); +} + +#site_nav_local_views .current a { + text-decoration: none; + background: #8e98b4 !important; + color: #fff !important; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); +} + +#aside_primary { + background: none; + width: 210px; + padding-top: 0px; + margin-top: 5px; +} + +#aside_primary .section { + width: 100%; + margin-left: 0px; + margin-right: 0px; +} + +#aside_primary h2 { + border-bottom: 3px solid #A6ADBF; + color: #A6ADBF; + font-size: 1.1em; + letter-spacing: 2px; + margin-bottom: 10px; + text-transform: uppercase; + text-align: right; +} + +.section ul.entities { + width: 290px; +} + +.section .entities li { + margin-right: 17px; + margin-bottom: 10px; + width: 24px; +} + +#popular_notices .avatar { + position: relative; + top: 2px; + margin-bottom: 4px; +} + +#aside_primary td { + padding-right: 20px; + padding-bottom: 14px; +} + +#aside_primary td .nickname { + line-height: 1.6em; +} + +.section .avatar { + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); + -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); +} + +#content h1 { + border-bottom: 3px solid #A6ADBF; + color: #A6ADBF; + font-size: 1.4em; + letter-spacing: 4px; + text-transform: uppercase; +} + +#notices_primary { + margin-top: -5px; +} + +#content .notice { + padding-bottom: 14px; + border-bottom: 2px dotted #eee; +} + +.notice { + line-height: 1.35em; + margin-bottom: 10px; +} + +#content .notice .author .photo { + left: 0px; + top: 6px; +} + +#content .notice .entry-title { + min-height: 34px; +} + +#showstream .notice .entry-title { + min-height: 1px; +} + +#shownotice .notice .entry-title { + min-height:123px; +} + +.notice div.entry-content { + font-size: 0.9em; + line-height: 1.2em; + margin-top: 6px; + opacity: 0.6; +} + +.notice:hover div.entry-content { + opacity: 1; +} + +.user_in .notice div.entry-content { + max-width: 440px; +} + +div.entry-content a.response:before { + content: "("; +} + +div.entry-content a.response:after { + content: ")"; +} + +.notice-options { + margin-top: 4px; +} + +.pagination { + height: 1.2em; +} + +#jOverlayContent button { + top: 20px; + right: 36px; +} + +.entity_profile { + float: left; + width: 435px; + margin-top: 4px; +} + +td.entity_profile { /* cf directory table */ + width: auto; +} + +.entity_profile .entity_depiction { + margin-top: 4px; +} + +.entity_actions { + width: 140px; + margin-top: 8px; + margin-bottom: 10px; +} + +.entity_actions a, .entity_actions p, .entity_actions .entity_subscribe input, .entity_actions .entity_block input, .entity_actions .entity_moderation input, .entity_actions .entity_role input, .entity_actions .entity_nudge input, .entity_actions .entity_delete input { + text-shadow:0 1px 0 rgba(255,255,255,0.4); + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + background-color: #CDD1DD !important; +} + +.entity_moderation:hover ul, +.entity_role:hover ul { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} + +.entity_send-a-message .form_notice legend { + text-shadow:0 1px 0 rgba(255,255,255,0.4); +} + +.entity_send-a-message .form_notice { + border: 1px solid #7B4E82; +} + +.entity_send-a-message .form_notice #notice_action-submit { + color: #fff !important; + top: 46px; +} + +#aside_primary #entity_remote_subscribe a:hover { + background-color: #fff !important; +} + +#entity_remote_subscribe .dialogbox { + border: 1px solid #7B4E82; + border-radius: 8px; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; +} + +#entity_remote_subscribe input { + padding-left: 4px; +} + +#entity_remote_subscribe .submit_dialogbox { + margin-top: 10px; + float: right; +} + +#filter_tags_item .submit { + left: 6px; + top: -3px; +} + +.pagination { + height: 1.2em; + padding-bottom: 12px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +#footer { + color: #000; + margin-left: 0px; + margin-right: 0px; + -webkit-border-top-left-radius: 6px; + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topleft: 6px; + -moz-border-radius-topright: 6px; + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +#footer a { + color: #3e3e8c; +} + +#site_nav_global_secondary { + margin-bottom: 10px; +} + +.error, .success { + background-color: #F7E8E8; + padding: 4px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.success { + background-color: #f2f2f2; +} + +.form_notice input.submit, .form_settings input.submit, .form_settings input.cancel { + border-radius: 3px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); + color:#fff; + font-weight: normal; + font-size: 1em; + height: 2.2em; + padding-left: 1em; + padding-right: 1em; + background: #7080aa; + background: -moz-linear-gradient(top, #7b8dbb , #7080aa); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7b8dbb), color-stop(100%,#7080aa)); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7b8dbb', endColorstr='#7080aa',GradientType=0 ); + border-width: 1px; +} + +.form_notice input.submit:hover, .form_settings input.submit:hover, .form_settings input.cancel:hover { + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.8); + background: #7b8dbb; + background: -moz-linear-gradient(top, #7080aa , #7b8dbb); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7080aa), color-stop(100%,#7b8dbb)); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7080aa', endColorstr='#7b8dbb',GradientType=0 ); +} + +.form_settings input#settings_design_reset, .form_settings input.cancel { + background: #e2e2e2; + color: #8e181b; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5); +} + +.form_settings input#settings_design_reset:hover, .form_settings input.cancel:hover { + background: #f2f2f2; + color: #8e181b; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5); +} + +.form_settings input.checkbox, .form_settings input.radio { + margin-left: 24%; + margin-top: 2px; + position: relative; + left: -14px; +} + +.form_settings label.checkbox, .form_settings label.radio { + width: auto; + max-width: 60%; + position: relative; + left: -30px; +} + +.form_settings li input.radio { + clear: left; +} + +.form_settings label.radio { + margin-left: 10px; + margin-right: 10px; + text-align: left; +} + +#form_login p.form_guide, #form_register #settings_rememberme p.form_guide, #form_openid_login #settings_rememberme p.form_guide, #settings_twitter_remove p.form_guide, #design_background-image_onoff p.form_guide { + margin-left: 26%; +} + +#form_search ul.form_data #q { + margin-left: 10px; +} + +.form_settings fieldset fieldset { + margin-bottom: 30px; + padding-top: 25px; +} + + +#content thead th { +text-align:left; +} +#content tbody th { +vertical-align:top; +text-align:left; +font-weight:normal; +padding-top:11px; +padding-right:18px; +} +#content tbody tr { + border-top: 1px dotted #bbb; +} +#content td { +padding:11px 18px 11px 0; +vertical-align:top; +} +#content td:last-child { +padding-right:0; +} + + +#realtime_actions { + position: relative !important; + float: right; + padding-top: 15px; + margin-bottom: -8px !important; +} + +.realtime-popup #content { + padding-left: 4px !important; + padding-right: 4px !important; + margin-right: 0px; +} + +.realtime-popup .form_notice textarea { + width: 325px !important; +} + +.realtime-popup .form_notice #notice_action-submit { + top: 59px !important; + right: 6px !important; +} + +.realtime-popup .form_notice label[for=notice_data-attach], .realtime-popup .form_notice #notice_data-attach { + right: 74px; + top: 3px !important; +} + +.realtime-popup .form_notice #notice_data-geo_wrap label, .realtime-popup .form_notice #notice_data-geo_wrap input { + right: 8px; + top: 3px !important; +} + + +/* Bookmark specific styles */ + +#content .bookmark .entry-title { + margin-left: 0px; +} + +.bookmark h3 { + margin: 0px 0px 8px 0px; + float: left; + line-height: 1.2em; + max-width: 92%; +} + +.bookmark-notice-count { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + padding: 1px 6px; + font-size: 1.2em; + line-height: 1.2em; + background: #fff; + border: 1px solid #7b8dbb; + color: #3e3e8c !important; + position: relative; + right: 4px; + margin-left: 10px; +} + +.bookmark-notice-count:hover { + text-decoration: none; + background: #f2f2f2; + border: 1px solid #7b8dbb; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5); +} + +.notice .bookmark-description { + clear: both; + margin-left: 0px; + margin-bottom: 0px; +} + +.notice .bookmark-author { + margin-left: 0px; + float: left; +} + +.bookmark-tags { + clear: both; + margin-bottom: 8px; + line-height: 1.6em; +} + +ul.bookmark-tags a { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + padding: 1px 6px; + background: #f2f2f2; + color: #3e3e8c !important; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5); + font-size: 0.9em; +} + +ul.bookmark-tags a:hover { + background-color: #cdd1dd; + text-decoration: none; +} + +.bookmark-avatar { + float: none !important; + position: relative; + top: 2px; +} + +.bookmark div.entry-content { + font-size: 0.9em; + line-height: 1.2em; + margin-top: 6px; + opacity: 0.6; + margin-bottom: 0px; +} + +.bookmark:hover div.entry-content { + opacity: 1; +} + +.bookmark .notice-options { + margin-top: 16px; +} + +#bookmarkpopup { + min-width: 600px; + margin-top: 0px; + height: 100%; + border: 10px solid #364A84; + background: #364A84; +} + +#bookmarkpopup #wrap { + width: auto; + min-width: 560px; + padding: 40px 0px 25px 0px; + margin-right: 2px; + background: #fff url(../mobilelogo.png) no-repeat 6px 6px; +} + +#bookmarkpopup #header { + width: auto; + padding: 0px 10px; +} + +#bookmarkpopup .form_settings label { + margin-top: 2px; + text-align: right; + width: 24%; + font-size: 1.2em; +} + +#bookmarkpopup .form_settings .form_data input { + width: 60%; +} + +#bookmarkpopup .form_guide { + color: #777; +} + +#bookmarkpopup #submit { + float: right; + margin-right: 0px; +} + +#bookmarkpopup fieldset fieldset { + margin-bottom: 10px; +} + +/* Onboard specific styles */ + +.onboard-flash { + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + font-size: 1.1em; + box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5); + -webkit-box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5); +} + +.onboard-flash p { + margin-bottom: 10px; +} + +.onboard-flash .next:before { + content: '\00BB'; + padding-right: 6px; +} + +.onboard-breadcrumbs { + margin-bottom: 16px !important; +} + +.onboard-breadcrumbs li { + background: none !important; + border-top: none !important; + padding: 6px 12px 2px 0px !important; +} + +.onboard-breadcrumbs li:last-child { + padding-right: 0px !important; +} + +.onboard-breadcrumbs a { + text-decoration: none; +} + +.onboard-breadcrumbs a:hover { + color: #3e3e8c !important; +} + +/* Billing specific styles */ + +#content table.billing_info { + margin-top: 10px; + background:rgba(240, 240, 240, 0.4); +} + +#content table.billing_info th { + text-align: right; + width: 50%; +} + +.invalid { + border: solid 2px red !important; +} + +#payment_history table { + width: 100%; +} + +#billingadminpanel .form_settings input { + margin-right: 0px; +} + +}/*end of @media screen, projection, tv*/ diff --git a/theme/neo/css/ie.css b/theme/neo/css/ie.css new file mode 100644 index 0000000000..41f7dc9f88 --- /dev/null +++ b/theme/neo/css/ie.css @@ -0,0 +1,81 @@ +/* Temporary copy of base styles for overriding */ + +input.checkbox, +input.radio { +top:0; +} +.form_notice textarea { + width: 328px; +} +.form_notice .form_note + label { +position:absolute; +top:25px; +left:83%; +text-indent:-9999px; +height:16px; +width:16px; +display:block; + left: 390px; + top: 27px; +} +.form_notice #notice_action-submit { + width: 106px; + max-width: 106px; +} +.form_notice #notice_data-attach_selected, +.form_notice #notice_data-geo_selected { +width:78.75%; +} +.form_notice #notice_data-attach_selected button, +.form_notice #notice_data-geo_selected button { +padding:0 4px; +} +.notice-options input.submit { +font-size:0; +text-align:right; +text-indent:0; +} +.notice div.entry-content .timestamp a { +margin-right:4px; +} +.entity_profile { +width:64%; +} +.notice { +z-index:1; +} +.notice:hover { +z-index:9999; +} +.notice .thumbnail img { +z-index:9999; +} + +.form_settings fieldset fieldset legend { +line-height:auto; +} + +/* IE specific styles */ + +#site_nav_global_primary ul { + margin-right: 0px; +} + +.notice-options input.submit { + color:#FFFFFF; +} + +.form_notice #notice_data-attach { + filter: alpha(opacity=0); +} + +.form_notice .form_note + label { + background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -328px; +} + +.form_notice #notice_data-geo_wrap label { + background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -1780px; +} +.form_notice #notice_data-geo_wrap label.checked { + background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -1846px; +} diff --git a/theme/neo/css/mp-screen.css b/theme/neo/css/mp-screen.css new file mode 100644 index 0000000000..d3f95db9b6 --- /dev/null +++ b/theme/neo/css/mp-screen.css @@ -0,0 +1,204 @@ +/* mobile style */ + +body { + background-image: none; + min-width: 0; +} + +#wrap { + margin: 0; + padding: 0; + min-width:0; + max-width:100%; +} + +#header { + width: 96%; + padding: 0 2%; + padding-top: 20px; +} + +.user_in #header { + padding-top: 40px; +} + +address { +margin:1em 0 0 0; +float:left; +width:100%; +} + +address img + .fn { +display:block; +margin-top:1em; + margin-right: 10px; +clear: left; +float:left; +} + +#site_nav_global_primary { + margin:0; + width: 100%; + padding: 4px 0; + height: auto; + position:absolute; + top:0; + left:0; + font-size: 1em; + letter-spacing: 0em; + border-top: none; +} + +#site_nav_global_primary li { + margin-left:0; + margin-right:0px; + float:left; + font-size:0.9em; + padding: 2px 4px; + line-height: 1em; + height: auto; +} + +#site_nav_global_primary li a { + height: auto; +} + +.form_notice { + float: left; + margin-left: 0px; + width: 300px; + padding: 4px; +} + +#form_notice-direct.form_notice { + padding-top: 10px; +} + +.form_notice textarea { + width: 210px; + height: 50px; + padding: 4px; +} + +#notice_text-count { +position:absolute; +bottom:2px; + left: 175px; + font-size: 0.8em; +z-index:9; +} + +#form_notice-direct.form_notice #notice_text-count { + left: 0px; +} + +/*input type=file no good in +iPhone/iPod Touch, Android, Opera Mini Simulator +*/ +.form_notice #notice_text-count + label, +.form_notice label[for="notice_data-attach"] { +display:none; +} +.form_notice #notice_data-attach { +position:static; +clear:both; +width:65%; +height:auto; +display:block; +z-index:9; +padding:0; +margin:0; +background:none; +opacity:1; +} + +.form_notice #notice_action-submit { + text-align: center; + left: 230px; + top: 32px; + width: 70px; + font-size: 0.8em; +} + +#form_notice-direct.form_notice #notice_action-submit { + top: 62px; +} + +#site_nav_local_views { + height: auto; + font-size: 0.9em; + line-height: 2em; + margin-bottom: 0px; + padding-left: 4px; + background: none; +} + +#site_nav_local_views li { + margin-right: 6px; +} + +#site_nav_local_views a { + background-color: #7080aa; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + margin-right: 2px; + margin-bottom: 2px; +} + +#core { + width: 100%; + margin: 0; +} + +#content { + width: 96%; + padding: 10px 2%; + margin: 0; + min-height: auto; +} + +#footer { + margin: 0; + padding: 10px 4px 4px 4px; +} + + +.form_settings fieldset { +margin-bottom:7px; +} + +.form_settings label { +width:auto; +display:block; +float:none; + text-align: left; +} + +.form_settings .form_data li { +margin-bottom:7px; +} + +.form_settings .form_data textarea, +.form_settings .form_data select, +.form_settings .form_data input { +margin-left:0; +display:block; +} +.form_settings .form_data textarea { +width:96.41%; +} + +.form_settings .form_data label { +float:none; +} + +.form_settings .form_data p.form_guide { +width:auto; +margin-left:0; +} + +#settings_design_color .form_data { + width: auto; + margin-right: 0; +} diff --git a/theme/neo/default-avatar-mini.png b/theme/neo/default-avatar-mini.png new file mode 100644 index 0000000000..a3410e307e Binary files /dev/null and b/theme/neo/default-avatar-mini.png differ diff --git a/theme/neo/default-avatar-profile.png b/theme/neo/default-avatar-profile.png new file mode 100644 index 0000000000..8f635d1aa6 Binary files /dev/null and b/theme/neo/default-avatar-profile.png differ diff --git a/theme/neo/default-avatar-stream.png b/theme/neo/default-avatar-stream.png new file mode 100644 index 0000000000..a3024639f4 Binary files /dev/null and b/theme/neo/default-avatar-stream.png differ diff --git a/theme/neo/images/bg.png b/theme/neo/images/bg.png new file mode 100644 index 0000000000..df665bd727 Binary files /dev/null and b/theme/neo/images/bg.png differ diff --git a/theme/neo/logo.png b/theme/neo/logo.png new file mode 100644 index 0000000000..61a445a61a Binary files /dev/null and b/theme/neo/logo.png differ diff --git a/theme/neo/mobilelogo.png b/theme/neo/mobilelogo.png new file mode 100644 index 0000000000..781e79578c Binary files /dev/null and b/theme/neo/mobilelogo.png differ diff --git a/theme/neo/theme.ini b/theme/neo/theme.ini new file mode 100644 index 0000000000..0209008d40 --- /dev/null +++ b/theme/neo/theme.ini @@ -0,0 +1 @@ +include=rebase diff --git a/theme/rebase/css/display.css b/theme/rebase/css/display.css index 32df41b93a..f569131213 100644 --- a/theme/rebase/css/display.css +++ b/theme/rebase/css/display.css @@ -1953,8 +1953,27 @@ margin-bottom:18px; padding-left:20px; } +#input_form_nav { + list-style-type: none; +} -}/*end of @media screen, projection, tv*/ +#input_form_nav li { + display:inline; +} + +.input_form_nav_tab.current { + text-decoration: underline; +} + +.input_form { + display: none; +} + +.input_form.current { + display: block; +} + +/*end of @media screen, projection, tv*/ @media print {