Merge branch '0.9.x' of git@gitorious.org:statusnet/mainline into 0.9.x

This commit is contained in:
Evan Prodromou 2009-10-31 14:47:21 -04:00
commit 44ce8e2fcd
42 changed files with 1190 additions and 582 deletions

View File

@ -458,3 +458,19 @@ StartProfileListItemActionElements: Showing the profile list actions (prepend a
EndProfileListItemActionElements: Showing profile list actions (append a button here)
- $item: ProfileListItem widget
StartUserXRDS: Start XRDS output (right after the opening XRDS tag)
- $action: the current action
- &$xrdsoutputter - XRDSOutputter object to write to
EndUserXRDS: End XRDS output (right before the closing XRDS tag)
- $action: the current action
- &$xrdsoutputter - XRDSOutputter object to write to
StartPublicXRDS: Start XRDS output (right after the opening XRDS tag)
- $action: the current action
- &$xrdsoutputter - XRDSOutputter object to write to
EndPublicXRDS: End XRDS output (right before the closing XRDS tag)
- $action: the current action
- &$xrdsoutputter - XRDSOutputter object to write to

View File

@ -99,19 +99,17 @@ class AllAction extends ProfileAction
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
new Feed(Feed::RSS2,
common_local_url(
'api', array(
'apiaction' => 'statuses',
'method' => 'friends_timeline',
'argument' => $this->user->nickname.'.rss'
'ApiTimelineFriends', array(
'format' => 'rss',
'id' => $this->user->nickname
)
),
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
new Feed(Feed::ATOM,
common_local_url(
'api', array(
'apiaction' => 'statuses',
'method' => 'friends_timeline',
'argument' => $this->user->nickname.'.atom'
'ApiTimelineFriends', array(
'format' => 'atom',
'id' => $this->user->nickname
)
),
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname))

View File

@ -99,7 +99,9 @@ class NewmessageAction extends Action
$user = common_current_user();
if (!$user) {
$this->clientError(_('Only logged-in users can send direct messages.'), 403);
/* Go log in, and then come back. */
common_set_returnto($_SERVER['REQUEST_URI']);
common_redirect(common_local_url('login'));
return false;
}
@ -221,7 +223,22 @@ class NewmessageAction extends Action
}
$this->msg = $msg;
$this->showPage();
if ($this->trimmed('ajax')) {
$this->startHTML('text/xml;charset=UTF-8');
$this->elementStart('head');
$this->element('title', null, _('New message'));
$this->elementEnd('head');
$this->elementStart('body');
if (common_logged_in()) {
$this->showNoticeForm();
}
$this->elementEnd('div');
$this->elementEnd('body');
$this->endHTML();
}
else {
$this->showPage();
}
}
function showPageNotice()

View File

@ -131,6 +131,13 @@ class PublicAction extends Action
return _('Public timeline');
}
}
function extraHead()
{
parent::extraHead();
$this->element('meta', array('http-equiv' => 'X-XRDS-Location',
'content' => common_local_url('publicxrds')));
}
/**
* Output <head> elements for RSS and Atom feeds
@ -143,14 +150,12 @@ class PublicAction extends Action
return array(new Feed(Feed::RSS1, common_local_url('publicrss'),
_('Public Stream Feed (RSS 1.0)')),
new Feed(Feed::RSS2,
common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'public_timeline.rss')),
common_local_url('ApiTimelinePublic',
array('format' => 'rss')),
_('Public Stream Feed (RSS 2.0)')),
new Feed(Feed::ATOM,
common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'public_timeline.atom')),
common_local_url('ApiTimelinePublic',
array('format' => 'atom')),
_('Public Stream Feed (Atom)')));
}

81
actions/publicxrds.php Normal file
View File

@ -0,0 +1,81 @@
<?php
/**
* Public XRDS for OpenID
*
* PHP version 5
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* 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/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
require_once INSTALLDIR.'/lib/xrdsoutputter.php';
/**
* Public XRDS
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @author Craig Andrews <candrews@integralblue.com>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* @todo factor out similarities with XrdsAction
*/
class PublicxrdsAction extends Action
{
/**
* Is read only?
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* Class handler.
*
* @param array $args array of arguments
*
* @return nothing
*/
function handle($args)
{
parent::handle($args);
$xrdsOutputter = new XRDSOutputter();
$xrdsOutputter->startXRDS();
Event::handle('StartPublicXRDS', array($this,&$xrdsOutputter));
Event::handle('EndPublicXRDS', array($this,&$xrdsOutputter));
$xrdsOutputter->endXRDS();
}
}

View File

@ -138,11 +138,25 @@ class RepliesAction extends OwnerDesignAction
function getFeeds()
{
$rssurl = common_local_url('repliesrss',
array('nickname' => $this->user->nickname));
$rsstitle = sprintf(_('Feed for replies to %s'), $this->user->nickname);
return array(new Feed(Feed::RSS1, $rssurl, $rsstitle));
return array(new Feed(Feed::RSS1,
common_local_url('repliesrss',
array('nickname' => $this->user->nickname)),
sprintf(_('Replies feed for %s (RSS 1.0)'),
$this->user->nickname)),
new Feed(Feed::RSS2,
common_local_url('ApiTimelineMentions',
array(
'id' => $this->user->nickname,
'format' => 'rss')),
sprintf(_('Replies feed for %s (RSS 2.0)'),
$this->user->nickname)),
new Feed(Feed::ATOM,
common_local_url('ApiTimelineMentions',
array(
'id' => $this->user->nickname,
'format' => 'atom')),
sprintf(_('Replies feed for %s (Atom)'),
$this->user->nickname)));
}
/**

View File

@ -164,13 +164,25 @@ class ShowfavoritesAction extends OwnerDesignAction
function getFeeds()
{
$feedurl = common_local_url('favoritesrss',
array('nickname' =>
$this->user->nickname));
$feedtitle = sprintf(_('Feed for favorites of %s'),
$this->user->nickname);
return array(new Feed(Feed::RSS1, $feedurl, $feedtitle));
return array(new Feed(Feed::RSS1,
common_local_url('favoritesrss',
array('nickname' => $this->user->nickname)),
sprintf(_('Feed for favorites of %s (RSS 1.0)'),
$this->user->nickname)),
new Feed(Feed::RSS2,
common_local_url('ApiTimelineFavorites',
array(
'id' => $this->user->nickname,
'format' => 'rss')),
sprintf(_('Feed for favorites of %s (RSS 2.0)'),
$this->user->nickname)),
new Feed(Feed::ATOM,
common_local_url('ApiTimelineFavorites',
array(
'id' => $this->user->nickname,
'format' => 'atom')),
sprintf(_('Feed for favorites of %s (Atom)'),
$this->user->nickname)));
}
/**

View File

@ -328,17 +328,15 @@ class ShowgroupAction extends GroupDesignAction
sprintf(_('Notice feed for %s group (RSS 1.0)'),
$this->group->nickname)),
new Feed(Feed::RSS2,
common_local_url('api',
array('apiaction' => 'groups',
'method' => 'timeline',
'argument' => $this->group->nickname.'.rss')),
common_local_url('ApiTimelineGroup',
array('format' => 'rss',
'id' => $this->group->nickname)),
sprintf(_('Notice feed for %s group (RSS 2.0)'),
$this->group->nickname)),
new Feed(Feed::ATOM,
common_local_url('api',
array('apiaction' => 'groups',
'method' => 'timeline',
'argument' => $this->group->nickname.'.atom')),
common_local_url('ApiTimelineGroup',
array('format' => 'atom',
'id' => $this->group->nickname)),
sprintf(_('Notice feed for %s group (Atom)'),
$this->group->nickname)),
new Feed(Feed::FOAF,

View File

@ -172,9 +172,9 @@ class ShownoticeAction extends OwnerDesignAction
function title()
{
if (!empty($this->profile->fullname)) {
$base = $this->profile->fullname . ' (' . $this->user->nickname . ') ';
$base = $this->profile->fullname . ' (' . $this->profile->nickname . ') ';
} else {
$base = $this->user->nickname;
$base = $this->profile->nickname;
}
return sprintf(_('%1$s\'s status on %2$s'),

View File

@ -128,17 +128,17 @@ class ShowstreamAction extends ProfileAction
sprintf(_('Notice feed for %s (RSS 1.0)'),
$this->user->nickname)),
new Feed(Feed::RSS2,
common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'user_timeline',
'argument' => $this->user->nickname.'.rss')),
common_local_url('ApiTimelineUser',
array(
'id' => $this->user->nickname,
'format' => 'rss')),
sprintf(_('Notice feed for %s (RSS 2.0)'),
$this->user->nickname)),
new Feed(Feed::ATOM,
common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'user_timeline',
'argument' => $this->user->nickname.'.atom')),
common_local_url('ApiTimelineUser',
array(
'id' => $this->user->nickname,
'format' => 'atom')),
sprintf(_('Notice feed for %s (Atom)'),
$this->user->nickname)),
new Feed(Feed::FOAF,

View File

@ -86,17 +86,15 @@ class TagAction extends Action
sprintf(_('Notice feed for tag %s (RSS 1.0)'),
$this->tag)),
new Feed(Feed::RSS2,
common_local_url('api',
array('apiaction' => 'tags',
'method' => 'timeline',
'argument' => $this->tag.'.rss')),
sprintf(_('Notice feed for %s group (RSS 2.0)'),
common_local_url('ApiTimelineTag',
array('format' => 'rss',
'tag' => $this->tag)),
sprintf(_('Notice feed for tag %s (RSS 2.0)'),
$this->tag)),
new Feed(Feed::ATOM,
common_local_url('api',
array('apiaction' => 'tags',
'method' => 'timeline',
'argument' => $this->tag.'.atom')),
common_local_url('ApiTimelineTag',
array('format' => 'atom',
'tag' => $this->tag)),
sprintf(_('Notice feed for tag %s (Atom)'),
$this->tag)));
}

View File

@ -36,6 +36,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
require_once INSTALLDIR.'/lib/omb.php';
require_once INSTALLDIR.'/extlib/libomb/service_provider.php';
require_once INSTALLDIR.'/extlib/libomb/xrds_mapper.php';
require_once INSTALLDIR.'/lib/xrdsoutputter.php';
/**
* XRDS for OpenMicroBlogging
@ -49,6 +50,8 @@ require_once INSTALLDIR.'/extlib/libomb/xrds_mapper.php';
*/
class XrdsAction extends Action
{
var $user;
/**
* Is read only?
*
@ -58,6 +61,18 @@ class XrdsAction extends Action
{
return true;
}
function prepare($args)
{
parent::prepare($args);
$nickname = $this->trimmed('nickname');
$this->user = User::staticGet('nickname', $nickname);
if (!$this->user) {
$this->clientError(_('No such user.'));
return;
}
return true;
}
/**
* Class handler.
@ -69,49 +84,64 @@ class XrdsAction extends Action
function handle($args)
{
parent::handle($args);
$nickname = $this->trimmed('nickname');
$user = User::staticGet('nickname', $nickname);
if (!$user) {
$this->clientError(_('No such user.'));
return;
}
$this->showXrds($user);
}
$xrdsOutputter = new XRDSOutputter();
$xrdsOutputter->startXRDS();
/**
* Show XRDS for a user.
*
* @param class $user XRDS for this user.
*
* @return void
*/
function showXrds($user)
{
$srv = new OMB_Service_Provider(profile_to_omb_profile($user->uri,
$user->getProfile()));
/* Use libombs default XRDS Writer. */
$xrds_writer = null;
$srv->writeXRDS(new Laconica_XRDS_Mapper(), $xrds_writer);
}
}
Event::handle('StartUserXRDS', array($this,&$xrdsOutputter));
class Laconica_XRDS_Mapper implements OMB_XRDS_Mapper
{
protected $urls;
//oauth
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xml:id' => 'oauth',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
$xrdsOutputter->showXrdsService(OAUTH_ENDPOINT_REQUEST,
common_local_url('requesttoken'),
array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1));
$xrdsOutputter->showXrdsService( OAUTH_ENDPOINT_AUTHORIZE,
common_local_url('userauthorization'),
array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1),
null,
$this->user->getIdentifierURI());
$xrdsOutputter->showXrdsService(OAUTH_ENDPOINT_ACCESS,
common_local_url('accesstoken'),
array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1),
null,
$this->user->getIdentifierURI());
$xrdsOutputter->showXrdsService(OAUTH_ENDPOINT_RESOURCE,
null,
array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1),
null,
$this->user->getIdentifierURI());
$xrdsOutputter->elementEnd('XRD');
//omb
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xml:id' => 'oauth',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
$xrdsOutputter->showXrdsService(OMB_ENDPOINT_POSTNOTICE,
common_local_url('postnotice'));
$xrdsOutputter->showXrdsService(OMB_ENDPOINT_UPDATEPROFILE,
common_local_url('updateprofile'));
$xrdsOutputter->elementEnd('XRD');
//misc
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xml:id' => 'oauth',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->showXrdsService(OAUTH_DISCOVERY,
'#oauth');
$xrdsOutputter->showXrdsService(OMB_VERSION,
'#omb');
$xrdsOutputter->elementEnd('XRD');
public function __construct()
{
$this->urls = array(
OAUTH_ENDPOINT_REQUEST => 'requesttoken',
OAUTH_ENDPOINT_AUTHORIZE => 'userauthorization',
OAUTH_ENDPOINT_ACCESS => 'accesstoken',
OMB_ENDPOINT_POSTNOTICE => 'postnotice',
OMB_ENDPOINT_UPDATEPROFILE => 'updateprofile');
}
Event::handle('EndUserXRDS', array($this,&$xrdsOutputter));
public function getURL($action)
{
return common_local_url($this->urls[$action]);
$xrdsOutputter->endXRDS();
}
}
?>

View File

@ -1181,10 +1181,9 @@ class Notice extends Memcached_DataObject
$xs->element('link', array('href' => $profile->profileurl));
$user = User::staticGet('id', $profile->id);
if (!empty($user)) {
$atom_feed = common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'user_timeline',
'argument' => $profile->nickname.'.atom'));
$atom_feed = common_local_url('ApiTimelineUser',
array('format' => 'atom',
'id' => $profile->nickname));
$xs->element('link', array('rel' => 'self',
'type' => 'application/atom+xml',
'href' => $profile->profileurl));

View File

@ -537,6 +537,16 @@ modified = 384
canonical = K
display = U
[user_openid_trustroot]
trustroot = 130
user_id = 129
created = 142
modified = 384
[user_openid__keys]
trustroot = K
user_id = K
[user_role]
user_id = 129
role = 130

View File

@ -20,7 +20,7 @@
/**
* The library version string
*/
define('Auth_OpenID_VERSION', '2.1.2');
define('Auth_OpenID_VERSION', '2.1.3');
/**
* Require the fetcher code.

View File

@ -376,7 +376,7 @@ function Auth_OpenID_detectMathLibrary($exts)
// Try to load dynamic modules.
if (!$loaded) {
foreach ($extension['modules'] as $module) {
if (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode') && @dl($module . "." . PHP_SHLIB_SUFFIX)) {
if (@dl($module . "." . PHP_SHLIB_SUFFIX)) {
$loaded = true;
break;
}

View File

@ -1295,7 +1295,8 @@ class Auth_OpenID_GenericConsumer {
Auth_OpenID_OPENID2_NS => array_merge($basic_sig_fields,
array('response_nonce',
'claimed_id',
'assoc_handle')),
'assoc_handle',
'op_endpoint')),
Auth_OpenID_OPENID1_NS => array_merge($basic_sig_fields,
array('nonce'))
);

View File

@ -887,6 +887,11 @@ class Auth_OpenID_Message {
function getAliasedArg($aliased_key, $default = null)
{
if ($aliased_key == 'ns') {
// Return the namespace URI for the OpenID namespace
return $this->getOpenIDNamespace();
}
$parts = explode('.', $aliased_key, 2);
if (count($parts) != 2) {

View File

@ -138,7 +138,7 @@ class Auth_Yadis_HTTPFetcher {
* pass the URLHasAllowedScheme check or if the server's response
* is malformed.
*/
function get($url, $headers)
function get($url, $headers = null)
{
trigger_error("not implemented", E_USER_ERROR);
}

View File

@ -127,8 +127,6 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
Auth_OpenID_USER_AGENT.' '.$curl_user_agent);
curl_setopt($c, CURLOPT_TIMEOUT, $off);
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RANGE,
"0-".(1024 * Auth_OpenID_FETCHER_MAX_RESPONSE_KB));
curl_exec($c);

View File

@ -83,8 +83,6 @@ class Auth_Yadis_PlainHTTPFetcher extends Auth_Yadis_HTTPFetcher {
"User-Agent: $user_agent",
"Host: ".$parts['host'].
($specify_port ? ":".$parts['port'] : ""),
"Range: 0-".
(1024*Auth_OpenID_FETCHER_MAX_RESPONSE_KB),
"Port: ".$parts['port']);
$errno = 0;

View File

@ -91,7 +91,7 @@ class Auth_Yadis_XMLParser {
* @return array $node_list An array of matching opaque node
* objects to be used with other methods of this parser class.
*/
function evalXPath($xpath, $node = null)
function &evalXPath($xpath, $node = null)
{
// Not implemented.
}
@ -349,7 +349,7 @@ function &Auth_Yadis_getXMLParser()
foreach ($extensions as $name => $params) {
if (!extension_loaded($name)) {
foreach ($params['libname'] as $libname) {
if (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode') && @dl($libname)) {
if (@dl($libname)) {
$classname = $params['classname'];
}
}

View File

@ -143,7 +143,7 @@ function checkMirror($action_obj, $args)
function isLoginAction($action)
{
static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register');
static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds');
$login = null;

View File

@ -692,9 +692,7 @@ function writeConf($sitename, $server, $path, $fancy, $db)
// database
"\$config['db']['database'] = '{$db['database']}';\n\n".
($db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":'').
"\$config['db']['type'] = '{$db['type']}';\n\n".
"?>";
"\$config['db']['type'] = '{$db['type']}';\n\n";
// write configuration file out to install directory
$res = file_put_contents(INSTALLDIR.'/config.php', $cfg);

View File

@ -14,373 +14,377 @@
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category UI interaction
* @package StatusNet
* @author Sarven Capadisli <csarven@status.net>
* @author Evan Prodromou <evan@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
$(document).ready(function(){
var counterBlackout = false;
// count character on keyup
function counter(event){
if (maxLength <= 0) {
return;
}
var currentLength = $("#notice_data-text").val().length;
var remaining = maxLength - currentLength;
var counter = $("#notice_text-count");
if (remaining.toString() != counter.text()) {
if (!counterBlackout || remaining == 0) {
if (counter.text() != String(remaining)) {
counter.text(remaining);
}
if ($('body.user_in').length > 0) {
$('.'+SN.C.S.FormNotice).each(function() { SN.U.FormNoticeEnhancements($(this)); });
if (remaining < 0) {
$("#form_notice").addClass("warning");
} else {
$("#form_notice").removeClass("warning");
}
// Skip updates for the next 500ms.
// On slower hardware, updating on every keypress is unpleasant.
if (!counterBlackout) {
counterBlackout = true;
window.setTimeout(clearCounterBlackout, 500);
}
}
}
}
function clearCounterBlackout() {
// Allow keyup events to poke the counter again
counterBlackout = false;
// Check if the string changed since we last looked
counter(null);
}
$('.form_user_subscribe').each(function() { SN.U.FormXHR($(this)); });
$('.form_user_unsubscribe').each(function() { SN.U.FormXHR($(this)); });
$('.form_favor').each(function() { SN.U.FormXHR($(this)); });
$('.form_disfavor').each(function() { SN.U.FormXHR($(this)); });
$('.form_group_join').each(function() { SN.U.FormXHR($(this)); });
$('.form_group_leave').each(function() { SN.U.FormXHR($(this)); });
$('.form_user_nudge').each(function() { SN.U.FormXHR($(this)); });
function submitonreturn(event) {
if (event.keyCode == 13 || event.keyCode == 10) {
// iPhone sends \n not \r for 'return'
$("#form_notice").submit();
event.preventDefault();
event.stopPropagation();
$("#notice_data-text").blur();
$("body").focus();
return false;
}
return true;
}
SN.U.NoticeReply();
// define maxLength if it wasn't defined already
SN.U.NoticeDataAttach();
if (typeof(maxLength) == "undefined") {
maxLength = 140;
SN.U.NewDirectMessage();
}
if ($("#notice_data-text").length) {
if (maxLength > 0) {
$("#notice_data-text").bind("keyup", counter);
// run once in case there's something in there
counter();
}
$("#notice_data-text").bind("keydown", submitonreturn);
if($('body')[0].id != 'conversation') {
$("#notice_data-text").focus();
}
}
// XXX: refactor this code
var favoptions = { dataType: 'xml',
beforeSubmit: function(data, target, options) {
$(target).addClass('processing');
return true;
},
success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
var dis = new_form.id;
var fav = dis.replace('disfavor', 'favor');
$('form#'+fav).replaceWith(new_form);
$('form#'+dis).ajaxForm(disoptions).each(addAjaxHidden);
}
};
var disoptions = { dataType: 'xml',
beforeSubmit: function(data, target, options) {
$(target).addClass('processing');
return true;
},
success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
var fav = new_form.id;
var dis = fav.replace('favor', 'disfavor');
$('form#'+dis).replaceWith(new_form);
$('form#'+fav).ajaxForm(favoptions).each(addAjaxHidden);
}
};
var joinoptions = { dataType: 'xml',
success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
var leave = new_form.id;
var join = leave.replace('leave', 'join');
$('form#'+join).replaceWith(new_form);
$('form#'+leave).ajaxForm(leaveoptions).each(addAjaxHidden);
}
};
var leaveoptions = { dataType: 'xml',
success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
var join = new_form.id;
var leave = join.replace('join', 'leave');
$('form#'+leave).replaceWith(new_form);
$('form#'+join).ajaxForm(joinoptions).each(addAjaxHidden);
}
};
function addAjaxHidden() {
var ajax = document.createElement('input');
ajax.setAttribute('type', 'hidden');
ajax.setAttribute('name', 'ajax');
ajax.setAttribute('value', 1);
this.appendChild(ajax);
}
$("form.form_favor").ajaxForm(favoptions);
$("form.form_disfavor").ajaxForm(disoptions);
$("form.form_group_join").ajaxForm(joinoptions);
$("form.form_group_leave").ajaxForm(leaveoptions);
$("form.form_favor").each(addAjaxHidden);
$("form.form_disfavor").each(addAjaxHidden);
$("form.form_group_join").each(addAjaxHidden);
$("form.form_group_leave").each(addAjaxHidden);
$("#form_user_nudge").ajaxForm ({ dataType: 'xml',
beforeSubmit: function(xml) { $("#form_user_nudge input[type=submit]").attr("disabled", "disabled");
$("#form_user_nudge input[type=submit]").addClass("disabled");
},
success: function(xml) { $("#form_user_nudge").replaceWith(document._importNode($("#nudge_response", xml).get(0),true));
$("#form_user_nudge input[type=submit]").removeAttr("disabled");
$("#form_user_nudge input[type=submit]").removeClass("disabled");
}
});
$("#form_user_nudge").each(addAjaxHidden);
var Subscribe = { dataType: 'xml',
beforeSubmit: function(formData, jqForm, options) { $(".form_user_subscribe input[type=submit]").attr("disabled", "disabled");
$(".form_user_subscribe input[type=submit]").addClass("disabled");
},
success: function(xml) { var form_unsubscribe = document._importNode($('form', xml).get(0), true);
var form_unsubscribe_id = form_unsubscribe.id;
var form_subscribe_id = form_unsubscribe_id.replace('unsubscribe', 'subscribe');
$("form#"+form_subscribe_id).replaceWith(form_unsubscribe);
$("form#"+form_unsubscribe_id).ajaxForm(UnSubscribe).each(addAjaxHidden);
$("dd.subscribers").text(parseInt($("dd.subscribers").text())+1);
$(".form_user_subscribe input[type=submit]").removeAttr("disabled");
$(".form_user_subscribe input[type=submit]").removeClass("disabled");
}
};
var UnSubscribe = { dataType: 'xml',
beforeSubmit: function(formData, jqForm, options) { $(".form_user_unsubscribe input[type=submit]").attr("disabled", "disabled");
$(".form_user_unsubscribe input[type=submit]").addClass("disabled");
},
success: function(xml) { var form_subscribe = document._importNode($('form', xml).get(0), true);
var form_subscribe_id = form_subscribe.id;
var form_unsubscribe_id = form_subscribe_id.replace('subscribe', 'unsubscribe');
$("form#"+form_unsubscribe_id).replaceWith(form_subscribe);
$("form#"+form_subscribe_id).ajaxForm(Subscribe).each(addAjaxHidden);
$("#profile_send_a_new_message").remove();
$("#profile_nudge").remove();
$("dd.subscribers").text(parseInt($("dd.subscribers").text())-1);
$(".form_user_unsubscribe input[type=submit]").removeAttr("disabled");
$(".form_user_unsubscribe input[type=submit]").removeClass("disabled");
}
};
$(".form_user_subscribe").ajaxForm(Subscribe);
$(".form_user_unsubscribe").ajaxForm(UnSubscribe);
$(".form_user_subscribe").each(addAjaxHidden);
$(".form_user_unsubscribe").each(addAjaxHidden);
var PostNotice = { dataType: 'xml',
beforeSubmit: function(formData, jqForm, options) { if ($("#notice_data-text").get(0).value.length == 0) {
$("#form_notice").addClass("warning");
return false;
}
$("#form_notice").addClass("processing");
$("#notice_action-submit").attr("disabled", "disabled");
$("#notice_action-submit").addClass("disabled");
return true;
},
timeout: '60000',
error: function (xhr, textStatus, errorThrown) { $("#form_notice").removeClass("processing");
$("#notice_action-submit").removeAttr("disabled");
$("#notice_action-submit").removeClass("disabled");
if (textStatus == "timeout") {
alert ("Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists");
}
else {
if ($(".error", xhr.responseXML).length > 0) {
$('#form_notice').append(document._importNode($(".error", xhr.responseXML).get(0), true));
}
else {
var HTTP20x30x = [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307];
if(jQuery.inArray(parseInt(xhr.status), HTTP20x30x) < 0) {
alert("Sorry! We had trouble sending your notice ("+xhr.status+" "+xhr.statusText+"). Please report the problem to the site administrator if this happens again.");
}
else {
$("#notice_data-text").val("");
if (maxLength > 0) {
counter();
}
}
}
}
},
success: function(xml) { if ($("#error", xml).length > 0) {
var result = document._importNode($("p", xml).get(0), true);
result = result.textContent || result.innerHTML;
alert(result);
}
else {
if($('body')[0].id == 'bookmarklet') {
self.close();
}
if ($("#command_result", xml).length > 0) {
var result = document._importNode($("p", xml).get(0), true);
result = result.textContent || result.innerHTML;
alert(result);
}
else {
li = $("li", xml).get(0);
if ($("#"+li.id).length == 0) {
var notice_irt_value = $('#notice_in-reply-to').val();
var notice_irt = '#notices_primary #notice-'+notice_irt_value;
if($('body')[0].id == 'conversation') {
if(notice_irt_value.length > 0 && $(notice_irt+' .notices').length < 1) {
$(notice_irt).append('<ul class="notices"></ul>');
}
$($(notice_irt+' .notices')[0]).append(document._importNode(li, true));
}
else {
$("#notices_primary .notices").prepend(document._importNode(li, true));
}
$('#'+li.id).css({display:'none'});
$('#'+li.id).fadeIn(2500);
NoticeReply();
NoticeAttachments();
}
}
$("#notice_data-text").val("");
$("#notice_data-attach").val("");
$("#notice_in-reply-to").val("");
$('#notice_data-attach_selected').remove();
if (maxLength > 0) {
counter();
}
}
$("#form_notice").removeClass("processing");
$("#notice_action-submit").removeAttr("disabled");
$("#notice_action-submit").removeClass("disabled");
}
};
$("#form_notice").ajaxForm(PostNotice);
$("#form_notice").each(addAjaxHidden);
NoticeReply();
NoticeAttachments();
NoticeDataAttach();
SN.U.NoticeAttachments();
});
function NoticeReply() {
if ($('#notice_data-text').length > 0 && $('#content .notice_reply').length > 0) {
$('#content .notice').each(function() {
var notice = $(this)[0];
$($('.notice_reply', notice)[0]).click(function() {
var nickname = ($('.author .nickname', notice).length > 0) ? $($('.author .nickname', notice)[0]) : $('.author .nickname.uid');
NoticeReplySet(nickname.text(), $($('.notice_id', notice)[0]).text());
var SN = { // StatusNet
C: { // Config
I: { // Init
CounterBlackout: false,
MaxLength: 140,
PatternUsername: /^[0-9a-zA-Z\-_.]*$/,
HTTP20x30x: [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307]
},
S: { // Selector
Disabled: 'disabled',
Warning: 'warning',
Error: 'error',
Success: 'success',
Processing: 'processing',
CommandResult: 'command_result',
FormNotice: 'form_notice',
NoticeDataText: 'notice_data-text',
NoticeTextCount: 'notice_text-count',
NoticeInReplyTo: 'notice_in-reply-to',
NoticeDataAttach: 'notice_data-attach',
NoticeDataAttachSelected: 'notice_data-attach_selected',
NoticeActionSubmit: 'notice_action-submit'
}
},
U: { // Utils
FormNoticeEnhancements: function(form) {
form_id = form.attr('id');
if (maxLength > 0) {
$('#'+form_id+' #'+SN.C.S.NoticeDataText).bind('keyup', function(e) {
SN.U.Counter(form);
});
// run once in case there's something in there
SN.U.Counter(form);
}
$('#'+form_id+' #'+SN.C.S.NoticeDataText).bind('keydown', function(e) {
SN.U.SubmitOnReturn(e, form);
});
if($('body')[0].id != 'conversation') {
$('#'+form_id+' textarea').focus();
}
SN.U.FormNoticeXHR(form);
},
SubmitOnReturn: function(event, el) {
if (event.keyCode == 13 || event.keyCode == 10) {
el.submit();
event.preventDefault();
event.stopPropagation();
$('#'+el[0].id+' #'+SN.U.NoticeDataText).blur();
$('body').focus();
return false;
}
return true;
},
Counter: function(form) {
SN.C.I.FormNoticeCurrent = form;
form_id = form.attr('id');
if (typeof(maxLength) == "undefined") {
maxLength = SN.C.I.MaxLength;
}
if (maxLength <= 0) {
return;
}
var remaining = maxLength - $('#'+form_id+' #'+SN.C.S.NoticeDataText).val().length;
var counter = $('#'+form_id+' #'+SN.C.S.NoticeTextCount);
if (remaining.toString() != counter.text()) {
if (!SN.C.I.CounterBlackout || remaining == 0) {
if (counter.text() != String(remaining)) {
counter.text(remaining);
}
if (remaining < 0) {
form.addClass(SN.C.S.Warning);
} else {
form.removeClass(SN.C.S.Warning);
}
// Skip updates for the next 500ms.
// On slower hardware, updating on every keypress is unpleasant.
if (!SN.C.I.CounterBlackout) {
SN.C.I.CounterBlackout = true;
SN.C.I.FormNoticeCurrent = form;
window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);", 500);
}
}
}
},
ClearCounterBlackout: function(form) {
// Allow keyup events to poke the counter again
SN.C.I.CounterBlackout = false;
// Check if the string changed since we last looked
SN.U.Counter(form);
},
FormXHR: function(f) {
f.bind('submit', function(e) {
form_id = $(this)[0].id;
$.ajax({
type: 'POST',
dataType: 'xml',
url: $(this)[0].action,
data: $(this).serialize() + '&ajax=1',
beforeSend: function(xhr) {
$('#'+form_id).addClass(SN.C.S.Processing);
$('#'+form_id+' .submit').addClass(SN.C.S.Disabled);
$('#'+form_id+' .submit').attr(SN.C.S.Disabled, SN.C.S.Disabled);
},
error: function (xhr, textStatus, errorThrown) {
alert(errorThrown || textStatus);
},
success: function(data, textStatus) {
if (typeof($('form', data)[0]) != 'undefined') {
form_new = document._importNode($('form', data)[0], true);
$('#'+form_id).replaceWith(form_new);
$('#'+form_new.id).each(function() { SN.U.FormXHR($(this)); });
}
else {
$('#'+form_id).replaceWith(document._importNode($('p', data)[0], true));
}
}
});
return false;
});
});
},
FormNoticeXHR: function(form) {
form_id = form.attr('id');
form.append('<input type="hidden" name="ajax" value="1"/>');
form.ajaxForm({
dataType: 'xml',
timeout: '60000',
beforeSend: function(xhr) {
if ($('#'+form_id+' #'+SN.C.S.NoticeDataText)[0].value.length === 0) {
form.addClass(SN.C.S.Warning);
return false;
}
form.addClass(SN.C.S.Processing);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).addClass(SN.C.S.Disabled);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).attr(SN.C.S.Disabled, SN.C.S.Disabled);
return true;
},
error: function (xhr, textStatus, errorThrown) {
form.removeClass(SN.C.S.Processing);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeClass(SN.C.S.Disabled);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeAttr(SN.C.S.Disabled, SN.C.S.Disabled);
if (textStatus == 'timeout') {
alert ('Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists');
}
else {
if ($('.'+SN.C.S.Error, xhr.responseXML).length > 0) {
form.append(document._importNode($('.'+SN.C.S.Error, xhr.responseXML)[0], true));
}
else {
if(jQuery.inArray(parseInt(xhr.status), SN.C.I.HTTP20x30x) < 0) {
alert('Sorry! We had trouble sending your notice ('+xhr.status+' '+xhr.statusText+'). Please report the problem to the site administrator if this happens again.');
}
else {
$('#'+form_id+' #'+SN.C.S.NoticeDataText).val('');
SN.U.Counter($('#'+SN.C.S.FormNotice));
}
}
}
},
success: function(data, textStatus) {
if ($('#'+SN.C.S.Error, data).length > 0) {
var result = document._importNode($('p', data)[0], true);
alert(result.textContent || result.innerHTML);
}
else {
if($('body')[0].id == 'bookmarklet') {
self.close();
}
if ($('#'+SN.C.S.CommandResult, data).length > 0) {
var result = document._importNode($('p', data)[0], true);
alert(result.textContent || result.innerHTML);
}
else {
notice = document._importNode($('li', data)[0], true);
if ($('#'+notice.id).length == 0) {
var notice_irt_value = $('#'+SN.C.S.NoticeInReplyTo).val();
var notice_irt = '#notices_primary #notice-'+notice_irt_value;
if($('body')[0].id == 'conversation') {
if(notice_irt_value.length > 0 && $(notice_irt+' .notices').length < 1) {
$(notice_irt).append('<ul class="notices"></ul>');
}
$($(notice_irt+' .notices')[0]).append(notice);
}
else {
$("#notices_primary .notices").prepend(notice);
}
$('#'+notice.id).css({display:'none'});
$('#'+notice.id).fadeIn(2500);
SN.U.NoticeAttachments();
SN.U.NoticeReply();
}
}
$('#'+form_id+' #'+SN.C.S.NoticeDataText).val('');
$('#'+form_id+' #'+SN.C.S.NoticeDataAttach).val('');
$('#'+form_id+' #'+SN.C.S.NoticeInReplyTo).val('');
$('#'+form_id+' #'+SN.C.S.NoticeDataAttachSelected).remove();
SN.U.Counter($('#'+SN.C.S.FormNotice));
}
},
complete: function(xhr, textStatus) {
form.removeClass(SN.C.S.Processing);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeAttr(SN.C.S.Disabled);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeClass(SN.C.S.Disabled);
}
});
},
NoticeReply: function() {
if ($('#'+SN.C.S.NoticeDataText).length > 0 && $('#content .notice_reply').length > 0) {
$('#content .notice').each(function() {
var notice = $(this)[0];
$($('.notice_reply', notice)[0]).click(function() {
var nickname = ($('.author .nickname', notice).length > 0) ? $($('.author .nickname', notice)[0]) : $('.author .nickname.uid');
SN.U.NoticeReplySet(nickname.text(), $($('.notice_id', notice)[0]).text());
return false;
});
});
}
},
NoticeReplySet: function(nick,id) {
if (nick.match(SN.C.I.PatternUsername)) {
var text = $('#'+SN.C.S.NoticeDataText);
if (text.length) {
replyto = '@' + nick + ' ';
text.val(replyto + text.val().replace(RegExp(replyto, 'i'), ''));
$('#'+SN.C.S.FormNotice+' input#'+SN.C.S.NoticeInReplyTo).val(id);
if (text.get(0).setSelectionRange) {
var len = text.val().length;
text.get(0).setSelectionRange(len,len);
text.get(0).focus();
}
return false;
}
}
return true;
},
NoticeAttachments: function() {
$.fn.jOverlay.options = {
method : 'GET',
data : '',
url : '',
color : '#000',
opacity : '0.6',
zIndex : 99,
center : false,
imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif',
bgClickToClose : true,
success : function() {
$('#jOverlayContent').append('<button>&#215;</button>');
$('#jOverlayContent button').click($.closeOverlay);
},
timeout : 0,
autoHide : true,
css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'}
};
$('#content .notice a.attachment').click(function() {
$().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
return false;
});
var t;
$("body:not(#shownotice) #content .notice a.thumbnail").hover(
function() {
var anchor = $(this);
$("a.thumbnail").children('img').hide();
anchor.closest(".entry-title").addClass('ov');
if (anchor.children('img').length == 0) {
t = setTimeout(function() {
$.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) {
anchor.append(data);
});
}, 500);
}
else {
anchor.children('img').show();
}
},
function() {
clearTimeout(t);
$("a.thumbnail").children('img').hide();
$(this).closest(".entry-title").removeClass('ov');
}
);
},
NoticeDataAttach: function() {
NDA = $('#'+SN.C.S.NoticeDataAttach);
NDA.change(function() {
S = '<div id="'+SN.C.S.NoticeDataAttachSelected+'" class="'+SN.C.S.Success+'"><code>'+$(this).val()+'</code> <button>&#215;</button></div>';
NDAS = $('#'+SN.C.S.NoticeDataAttachSelected);
(NDAS.length > 0) ? NDAS.replaceWith(S) : $('#'+SN.C.S.FormNotice).append(S);
$('#'+SN.C.S.NoticeDataAttachSelected+' button').click(function(){
$('#'+SN.C.S.NoticeDataAttachSelected).remove();
NDA.val('');
});
});
},
NewDirectMessage: function() {
NDM = $('.entity_send-a-message a');
NDM.attr({'href':NDM.attr('href')+'&ajax=1'});
NDM.click(function() {
var NDMF = $('.entity_send-a-message form');
if (NDMF.length == 0) {
$.get(NDM.attr('href'), null, function(data) {
$('.entity_send-a-message').append(document._importNode($('form', data).get(0), true));
NDMF = $('.entity_send-a-message .form_notice');
SN.U.FormNoticeEnhancements(NDMF);
NDMF.append('<button>&#215;</button>');
$('.entity_send-a-message button').click(function(){
NDMF.hide();
return false;
});
});
}
else {
NDMF.show();
$('.entity_send-a-message textarea').focus();
}
return false;
});
}
}
}
function NoticeReplySet(nick,id) {
rgx_username = /^[0-9a-zA-Z\-_.]*$/;
if (nick.match(rgx_username)) {
var text = $("#notice_data-text");
if (text.length) {
replyto = "@" + nick + " ";
text.val(replyto + text.val().replace(RegExp(replyto, 'i'), ''));
$("#form_notice input#notice_in-reply-to").val(id);
if (text.get(0).setSelectionRange) {
var len = text.val().length;
text.get(0).setSelectionRange(len,len);
text.get(0).focus();
}
return false;
}
}
return true;
}
function NoticeAttachments() {
$.fn.jOverlay.options = {
method : 'GET',
data : '',
url : '',
color : '#000',
opacity : '0.6',
zIndex : 99,
center : false,
imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif',
bgClickToClose : true,
success : function() {
$('#jOverlayContent').append('<button>&#215;</button>');
$('#jOverlayContent button').click($.closeOverlay);
},
timeout : 0,
autoHide : true,
css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'}
};
$('#content .notice a.attachment').click(function() {
$().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
return false;
});
var t;
$("body:not(#shownotice) #content .notice a.thumbnail").hover(
function() {
var anchor = $(this);
$("a.thumbnail").children('img').hide();
anchor.closest(".entry-title").addClass('ov');
if (anchor.children('img').length == 0) {
t = setTimeout(function() {
$.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) {
anchor.append(data);
});
}, 500);
}
else {
anchor.children('img').show();
}
},
function() {
clearTimeout(t);
$("a.thumbnail").children('img').hide();
$(this).closest(".entry-title").removeClass('ov');
}
);
}
function NoticeDataAttach() {
NDA = $('#notice_data-attach');
NDA.change(function() {
S = '<div id="notice_data-attach_selected" class="success"><code>'+$(this).val()+'</code> <button>&#215;</button></div>';
NDAS = $('#notice_data-attach_selected');
(NDAS.length > 0) ? NDAS.replaceWith(S) : $('#form_notice').append(S);
$('#notice_data-attach_selected button').click(function(){
$('#notice_data-attach_selected').remove();
NDA.val('');
});
});
}

View File

@ -185,7 +185,14 @@ function _have_config()
}
// XXX: Throw a conniption if database not installed
// XXX: Find a way to use htmlwriter for this instead of handcoded markup
if (!_have_config()) {
echo '<p>'. _('No configuation file found. ') .'</p>';
echo '<p>'. _('I looked for configuration files in the following places: ') .'<br/> '. implode($_config_files, '<br/>');
echo '<p>'. _('You may wish to run the installer to fix this.') .'</p>';
echo '<a href="install.php">'. _('Go to the installer.') .'</a>';
exit;
}
// Fixup for statusnet.ini
$_db_name = substr($config['db']['database'], strrpos($config['db']['database'], '/') + 1);

View File

@ -80,10 +80,21 @@ class MessageForm extends Form
/**
* ID of the form
*
* @return int ID of the form
* @return string ID of the form
*/
function id()
{
return 'form_notice-direct';
}
/**
* Class of the form
*
* @return string class of the form
*/
function formClass()
{
return 'form_notice';
}

View File

@ -105,7 +105,7 @@ class NoticeForm extends Form
/**
* ID of the form
*
* @return int ID of the form
* @return string ID of the form
*/
function id()
@ -113,6 +113,17 @@ class NoticeForm extends Form
return 'form_notice';
}
/**
* Class of the form
*
* @return string class of the form
*/
function formClass()
{
return 'form_notice';
}
/**
* Action of the form
*

View File

@ -108,6 +108,9 @@ class Router
$m->connect('main/oembed',
array('action' => 'oembed'));
$m->connect('main/xrds',
array('action' => 'publicxrds'));
// these take a code
foreach (array('register', 'confirmaddress', 'recoverpassword') as $c) {

View File

@ -1,21 +1,12 @@
<?php
/**
* Public XRDS for OpenID
* StatusNet, the distributed open-source microblogging tool
*
* Low-level generator for HTML
*
* PHP version 5
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* LICENCE: 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.
@ -27,60 +18,44 @@
*
* 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 Output
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2008 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/
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
require_once INSTALLDIR.'/lib/xmloutputter.php';
/**
* Public XRDS for OpenID
* Low-level generator for XRDS XML
*
* @category Action
* @category Output
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @author Craig Andrews <candrews@integralblue.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*
* @todo factor out similarities with XrdsAction
* @see Action
* @see XMLOutputter
*/
class PublicxrdsAction extends Action
class XRDSOutputter extends XMLOutputter
{
/**
* Is read only?
*
* @return boolean true
*/
function isReadOnly($args)
public function startXRDS()
{
return true;
}
/**
* Class handler.
*
* @param array $args array of arguments
*
* @return nothing
*/
function handle($args)
{
parent::handle($args);
header('Content-Type: application/xrds+xml');
$this->startXML();
$this->elementStart('XRDS', array('xmlns' => 'xri://$xrds'));
$this->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$this->element('Type', null, 'xri://$xrds*simple');
foreach (array('finishopenidlogin', 'finishaddopenid') as $finish) {
$this->showService(Auth_OpenID_RP_RETURN_TO_URL_TYPE,
common_local_url($finish));
}
$this->elementEnd('XRD');
}
public function endXRDS()
{
$this->elementEnd('XRDS');
$this->endXML();
}
@ -96,7 +71,7 @@ class PublicxrdsAction extends Action
*
* @return void
*/
function showService($type, $uri, $params=null, $sigs=null, $localId=null)
function showXrdsService($type, $uri, $params=null, $sigs=null, $localId=null)
{
$this->elementStart('Service');
if ($uri) {
@ -119,4 +94,3 @@ class PublicxrdsAction extends Action
$this->elementEnd('Service');
}
}

View File

@ -62,17 +62,59 @@ class OpenIDPlugin extends Plugin
* @return boolean hook return
*/
function onRouterInitialized($m)
function onStartInitializeRouter($m)
{
$m->connect('main/openid', array('action' => 'openidlogin'));
$m->connect('main/openidtrust', array('action' => 'openidtrust'));
$m->connect('settings/openid', array('action' => 'openidsettings'));
$m->connect('xrds', array('action' => 'publicxrds'));
$m->connect('index.php?action=finishopenidlogin', array('action' => 'finishopenidlogin'));
$m->connect('index.php?action=finishaddopenid', array('action' => 'finishaddopenid'));
$m->connect('main/openidserver', array('action' => 'openidserver'));
return true;
}
function onEndPublicXRDS($action, &$xrdsOutputter)
{
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
//consumer
foreach (array('finishopenidlogin', 'finishaddopenid') as $finish) {
$xrdsOutputter->showXrdsService(Auth_OpenID_RP_RETURN_TO_URL_TYPE,
common_local_url($finish));
}
//provider
$xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/server',
common_local_url('openidserver'),
null,
null,
'http://specs.openid.net/auth/2.0/identifier_select');
$xrdsOutputter->elementEnd('XRD');
}
function onEndUserXRDS($action, &$xrdsOutputter)
{
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xml:id' => 'openid',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
//consumer
$xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/return_to',
common_local_url('finishopenidlogin'));
//provider
$xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/signon',
common_local_url('openidserver'),
null,
null,
common_profile_url($action->user->nickname));
$xrdsOutputter->elementEnd('XRD');
}
function onEndLoginGroupNav(&$action)
{
$action_name = $action->trimmed('action');
@ -107,6 +149,8 @@ class OpenIDPlugin extends Plugin
case 'XrdsAction':
case 'PublicxrdsAction':
case 'OpenidsettingsAction':
case 'OpenidserverAction':
case 'OpenidtrustAction':
require_once(INSTALLDIR.'/plugins/OpenID/' . strtolower(mb_substr($cls, 0, -6)) . '.php');
return false;
case 'User_openid':
@ -136,6 +180,7 @@ class OpenIDPlugin extends Plugin
{
case 'openidlogin':
case 'finishopenidlogin':
case 'openidserver':
$login = true;
return false;
default:
@ -152,12 +197,16 @@ class OpenIDPlugin extends Plugin
function onEndShowHeadElements($action)
{
if ($action->trimmed('action') == 'public') {
// for client side of OpenID authentication
$action->element('meta', array('http-equiv' => 'X-XRDS-Location',
'content' => common_local_url('publicxrds')));
if($action instanceof ShowstreamAction){
$action->element('link', array('rel' => 'openid2.provider',
'href' => common_local_url('openidserver')));
$action->element('link', array('rel' => 'openid2.local_id',
'href' => $action->profile->profileurl));
$action->element('link', array('rel' => 'openid.server',
'href' => common_local_url('openidserver')));
$action->element('link', array('rel' => 'openid.delegate',
'href' => $action->profile->profileurl));
}
return true;
}
@ -239,6 +288,14 @@ class OpenIDPlugin extends Plugin
new ColumnDef('created', 'datetime',
null, false),
new ColumnDef('modified', 'timestamp')));
$schema->ensureTable('user_openid_trustroot',
array(new ColumnDef('trustroot', 'varchar',
'255', false, 'PRI'),
new ColumnDef('user_id', 'integer',
null, false, 'PRI'),
new ColumnDef('created', 'datetime',
null, false),
new ColumnDef('modified', 'timestamp')));
return true;
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* Table Definition for user_openid_trustroot
*/
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
class User_openid_trustroot extends Memcached_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'user_openid_trustroot'; // table name
public $trustroot; // varchar(255) primary_key not_null
public $user_id; // int(4) primary_key not_null
public $created; // datetime() not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
function staticGet($k,$v=null)
{ return Memcached_DataObject::staticGet('User_openid_trustroot',$k,$v); }
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
function &pkeyGet($kv)
{
return Memcached_DataObject::pkeyGet('User_openid_trustroot', $kv);
}
}

View File

@ -23,6 +23,7 @@ require_once(INSTALLDIR.'/plugins/OpenID/User_openid.php');
require_once('Auth/OpenID.php');
require_once('Auth/OpenID/Consumer.php');
require_once('Auth/OpenID/Server.php');
require_once('Auth/OpenID/SReg.php');
require_once('Auth/OpenID/MySQLStore.php');
@ -50,6 +51,13 @@ function oid_consumer()
return $consumer;
}
function oid_server()
{
$store = oid_store();
$server = new Auth_OpenID_Server($store, common_local_url('openidserver'));
return $server;
}
function oid_clear_last()
{
oid_set_last('');

View File

@ -0,0 +1,151 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Settings for OpenID
*
* PHP version 5
*
* LICENCE: 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 Settings
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2008-2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/action.php';
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
require_once(INSTALLDIR.'/plugins/OpenID/User_openid_trustroot.php');
/**
* Settings for OpenID
*
* Lets users add, edit and delete OpenIDs from their account
*
* @category Settings
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class OpenidserverAction extends Action
{
var $oserver;
function prepare($args)
{
parent::prepare($args);
$this->oserver = oid_server();
return true;
}
function handle($args)
{
parent::handle($args);
$request = $this->oserver->decodeRequest();
if (in_array($request->mode, array('checkid_immediate',
'checkid_setup'))) {
$user = common_current_user();
if(!$user){
if($request->immediate){
//cannot prompt the user to login in immediate mode, so answer false
$response = $this->generateDenyResponse($request);
}else{
/* Go log in, and then come back. */
common_set_returnto($_SERVER['REQUEST_URI']);
common_redirect(common_local_url('login'));
return;
}
}else if(common_profile_url($user->nickname) == $request->identity || $request->idSelect()){
$user_openid_trustroot = User_openid_trustroot::pkeyGet(
array('user_id'=>$user->id, 'trustroot'=>$request->trust_root));
if(empty($user_openid_trustroot)){
if($request->immediate){
//cannot prompt the user to trust this trust root in immediate mode, so answer false
$response = $this->generateDenyResponse($request);
}else{
common_ensure_session();
$_SESSION['openid_trust_root'] = $request->trust_root;
$allowResponse = $this->generateAllowResponse($request, $user);
$this->oserver->encodeResponse($allowResponse); //sign the response
$denyResponse = $this->generateDenyResponse($request);
$this->oserver->encodeResponse($denyResponse); //sign the response
$_SESSION['openid_allow_url'] = $allowResponse->encodeToUrl();
$_SESSION['openid_deny_url'] = $denyResponse->encodeToUrl();
//ask the user to trust this trust root
common_redirect(common_local_url('openidtrust'));
return;
}
}else{
//user has previously authorized this trust root
$response = $this->generateAllowResponse($request, $user);
//$response = $request->answer(true, null, common_profile_url($user->nickname));
}
} else if ($request->immediate) {
$response = $this->generateDenyResponse($request);
} else {
//invalid
$this->clientError(sprintf(_('You are not authorized to use the identity %s'),$request->identity),$code=403);
}
} else {
$response = $this->oserver->handleRequest($request);
}
if($response){
$response = $this->oserver->encodeResponse($response);
if ($response->code != AUTH_OPENID_HTTP_OK) {
header(sprintf("HTTP/1.1 %d ", $response->code),
true, $response->code);
}
if($response->headers){
foreach ($response->headers as $k => $v) {
header("$k: $v");
}
}
$this->raw($response->body);
}else{
$this->clientError(_('Just an OpenID provider. Nothing to see here, move along...'),$code=500);
}
}
function generateAllowResponse($request, $user){
$response = $request->answer(true, null, common_profile_url($user->nickname));
$profile = $user->getProfile();
$sreg_data = array(
'fullname' => $profile->fullname,
'nickname' => $user->nickname,
'email' => $user->email,
'language' => $user->language,
'timezone' => $user->timezone);
$sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($request);
$sreg_response = Auth_OpenID_SRegResponse::extractResponse(
$sreg_request, $sreg_data);
$sreg_response->toMessage($response->fields);
return $response;
}
function generateDenyResponse($request){
$response = $request->answer(false);
return $response;
}
}

View File

@ -0,0 +1,142 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* 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/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
require_once(INSTALLDIR.'/plugins/OpenID/User_openid_trustroot.php');
class OpenidtrustAction extends Action
{
var $trust_root;
var $allowUrl;
var $denyUrl;
var $user;
/**
* Is this a read-only action?
*
* @return boolean false
*/
function isReadOnly($args)
{
return false;
}
/**
* Title of the page
*
* @return string title of the page
*/
function title()
{
return _('OpenID Identity Verification');
}
function prepare($args)
{
parent::prepare($args);
common_ensure_session();
$this->user = common_current_user();
if(empty($this->user)){
/* Go log in, and then come back. */
common_set_returnto($_SERVER['REQUEST_URI']);
common_redirect(common_local_url('login'));
return;
}
$this->trust_root = $_SESSION['openid_trust_root'];
$this->allowUrl = $_SESSION['openid_allow_url'];
$this->denyUrl = $_SESSION['openid_deny_url'];
if(empty($this->trust_root) || empty($this->allowUrl) || empty($this->denyUrl)){
$this->clientError(_('This page should only be reached during OpenID processing, not directly.'));
return;
}
return true;
}
function handle($args)
{
parent::handle($args);
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$this->handleSubmit();
}else{
$this->showPage();
}
}
function handleSubmit()
{
unset($_SESSION['openid_trust_root']);
unset($_SESSION['openid_allow_url']);
unset($_SESSION['openid_deny_url']);
if($this->arg('allow'))
{
//save to database
$user_openid_trustroot = new User_openid_trustroot();
$user_openid_trustroot->user_id = $this->user->id;
$user_openid_trustroot->trustroot = $this->trust_root;
$user_openid_trustroot->created = DB_DataObject_Cast::dateTime();
if (!$user_openid_trustroot->insert()) {
$err = PEAR::getStaticProperty('DB_DataObject','lastError');
common_debug('DB error ' . $err->code . ': ' . $err->message, __FILE__);
}
common_redirect($this->allowUrl, $code=302);
}else{
common_redirect($this->denyUrl, $code=302);
}
}
/**
* Show page notice
*
* Display a notice for how to use the page, or the
* error if it exists.
*
* @return void
*/
function showPageNotice()
{
$this->element('p',null,sprintf(_('%s has asked to verify your identity. Click Continue to verify your identity and login without creating a new password.'),$this->trust_root));
}
/**
* Core of the display code
*
* Shows the login form.
*
* @return void
*/
function showContent()
{
$this->elementStart('form', array('method' => 'post',
'id' => 'form_openidtrust',
'class' => 'form_settings',
'action' => common_local_url('openidtrust')));
$this->elementStart('fieldset');
$this->submit('allow', _('Continue'));
$this->submit('deny', _('Cancel'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
}

View File

@ -65,21 +65,21 @@ class PubSubHubBubPlugin extends Plugin
$feeds = array();
//public timeline feeds
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'public_timeline.rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'public_timeline.atom'));
$feeds[]=common_local_url('ApiTimelinePublic',array('format' => 'rss'));
$feeds[]=common_local_url('ApiTimelinePublic',array('format' => 'atom'));
//author's own feeds
$user = User::staticGet('id',$notice->profile_id);
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.atom'));
$feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'rss'));
$feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'atom'));
//tag feeds
$tag = new Notice_tag();
$tag->notice_id = $notice->id;
if ($tag->find()) {
while ($tag->fetch()) {
$feeds[]=common_local_url('api',array('apiaction' => 'tags','method' => 'timeline', 'argument'=>$tag->tag.'.atom'));
$feeds[]=common_local_url('api',array('apiaction' => 'tags','method' => 'timeline', 'argument'=>$tag->tag.'.rss'));
$feeds[]=common_local_url('ApiTimelineTag',array('tag'=>$tag->tag, 'format'=>'rss'));
$feeds[]=common_local_url('ApiTimelineTag',array('tag'=>$tag->tag, 'format'=>'atom'));
}
}
@ -89,8 +89,8 @@ class PubSubHubBubPlugin extends Plugin
if ($group_inbox->find()) {
while ($group_inbox->fetch()) {
$group = User_group::staticGet('id',$group_inbox->group_id);
$feeds[]=common_local_url('api',array('apiaction' => 'groups','method' => 'timeline','argument' => $group->nickname.'.rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'groups','method' => 'timeline','argument' => $group->nickname.'.atom'));
$feeds[]=common_local_url('ApiTimelineGroup',array('id' => $group->nickname,'format'=>'rss'));
$feeds[]=common_local_url('ApiTimelineGroup',array('id' => $group->nickname,'format'=>'atom'));
}
}
@ -100,18 +100,17 @@ class PubSubHubBubPlugin extends Plugin
if ($notice_inbox->find()) {
while ($notice_inbox->fetch()) {
$user = User::staticGet('id',$notice_inbox->user_id);
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.atom'));
$feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'rss'));
$feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'atom'));
}
}
/* TODO: when the reply page gets RSS and ATOM feeds, implement this
//feed of user replied to
if($notice->reply_to){
$user = User::staticGet('id',$notice->reply_to);
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.atom'));
}*/
$feeds[]=common_local_url('ApiTimelineMentions',array('id' => $user->nickname,'format'=>'rss'));
$feeds[]=common_local_url('ApiTimelineMentions',array('id' => $user->nickname,'format'=>'atom'));
}
foreach(array_unique($feeds) as $feed){
if(! $publisher->publish_update($feed)){

View File

@ -432,21 +432,21 @@ border-width:1px;
border-style:solid;
}
#form_notice {
.form_notice {
width:45%;
float:left;
position:relative;
line-height:1;
}
#form_notice fieldset {
.form_notice fieldset {
border:0;
padding:0;
position:relative;
}
#form_notice legend {
.form_notice legend {
display:none;
}
#form_notice textarea {
.form_notice textarea {
float:left;
border-radius:7px;
-moz-border-radius:7px;
@ -458,44 +458,44 @@ padding:7px 7px 16px 7px;
position:relative;
z-index:2;
}
#form_notice label {
.form_notice label {
display:block;
float:left;
font-size:1.3em;
margin-bottom:7px;
}
#form_notice label[for=notice_data-attach],
#form_notice #notice_data-attach {
.form_notice label[for=notice_data-attach],
.form_notice #notice_data-attach {
position:absolute;
top:25px;
right:10.5%;
cursor:pointer;
}
#form_notice label[for=notice_data-attach] {
.form_notice label[for=notice_data-attach] {
text-indent:-9999px;
width:16px;
height:16px;
}
#form_notice #notice_data-attach {
.form_notice #notice_data-attach {
padding:0;
height:16px;
}
#form_notice .form_note {
.form_notice .form_note {
position:absolute;
bottom:2px;
right:21.715%;
z-index:9;
}
#form_notice .form_note dt {
.form_notice .form_note dt {
font-weight:bold;
display:none;
}
#notice_text-count {
.form_notice #notice_text-count {
font-weight:bold;
line-height:1.15;
padding:1px 2px;
}
#form_notice #notice_action-submit {
.form_notice #notice_action-submit {
width:14%;
height:47px;
padding:0;
@ -503,24 +503,24 @@ position:absolute;
bottom:0;
right:0;
}
#form_notice label[for=to] {
.form_notice label[for=to] {
margin-top:7px;
}
#form_notice select[id=to] {
.form_notice select[id=to] {
margin-bottom:7px;
margin-left:18px;
float:left;
max-width:322px;
}
#form_notice .error,
#form_notice .success {
.form_notice .error,
.form_notice .success {
float:left;
clear:both;
width:81.5%;
margin-bottom:0;
line-height:1.618;
}
#form_notice #notice_data-attach_selected code {
.form_notice #notice_data-attach_selected code {
float:left;
width:90%;
display:block;
@ -528,7 +528,7 @@ font-size:1.1em;
line-height:1.8;
overflow:auto;
}
#form_notice #notice_data-attach_selected button {
.form_notice #notice_data-attach_selected button {
float:right;
font-size:0.8em;
}
@ -670,6 +670,40 @@ border-radius:4px;
margin-bottom:18px;
}
.entity_send-a-message button {
position:absolute;
top:0;
right:0;
}
.entity_send-a-message .form_notice {
position:absolute;
top:34px;
right:-1px;
padding:1.795%;
width:65%;
z-index:1;
background-color:#FFFFFF;
border:1px solid #CCCCCC;
-moz-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7);
-moz-border-radius:7px;
}
.entity_send-a-message .form_notice legend {
display:block;
margin-bottom:11px;
}
.entity_send-a-message .form_notice label,
.entity_send-a-message .form_notice select {
display:none;
}
.entity_send-a-message .form_notice input.submit {
text-align:center;
}
.entity_tags ul {
list-style-type:none;
display:inline;
@ -1299,7 +1333,7 @@ clear:both;
#bookmarklet address {
display:none;
}
#bookmarklet #form_notice {
#bookmarklet .form_notice {
width:auto;
}
#bookmarklet #wrap {

View File

@ -3,10 +3,10 @@ input.checkbox,
input.radio {
top:0;
}
#form_notice textarea {
.form_notice textarea {
width:78%;
}
#form_notice .form_note + label {
.form_notice .form_note + label {
position:absolute;
top:25px;
left:83%;
@ -15,14 +15,14 @@ height:16px;
width:16px;
display:block;
}
#form_notice #notice_action-submit {
.form_notice #notice_action-submit {
width:17%;
max-width:17%;
}
#form_notice #notice_data-attach_selected {
.form_notice #notice_data-attach_selected {
width:78.5%;
}
#form_notice #notice_data-attach_selected button {
.form_notice #notice_data-attach_selected button {
padding:0 4px;
}
.notice-options input.submit {

View File

@ -37,14 +37,14 @@ background:none;
}
input.submit,
#form_notice.warning #notice_text-count,
.form_notice.warning #notice_text-count,
.form_settings .form_note,
.entity_remote_subscribe {
background-color:#9BB43E;
}
input:focus, textarea:focus, select:focus,
#form_notice.warning #notice_data-text {
.form_notice.warning #notice_data-text {
border-color:#9BB43E;
box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
@ -84,13 +84,13 @@ background-color:#C8D1D5;
#notice_text-count {
color:#333333;
}
#form_notice.warning #notice_text-count {
.form_notice.warning #notice_text-count {
color:#000000;
}
#form_notice label[for=notice_data-attach] {
.form_notice label[for=notice_data-attach] {
background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px;
}
#form_notice #notice_data-attach {
.form_notice #notice_data-attach {
opacity:0;
}

View File

@ -6,9 +6,9 @@ color:#FFFFFF;
#site_nav_local_views a {
background-color:#C8D1D5;
}
#form_notice .form_note + label {
.form_notice .form_note + label {
background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%;
}
#form_notice #notice_data-attach {
.form_notice #notice_data-attach {
filter: alpha(opacity=0);
}

View File

@ -37,14 +37,14 @@ background:none;
}
input.submit,
#form_notice.warning #notice_text-count,
.form_notice.warning #notice_text-count,
.form_settings .form_note,
.entity_remote_subscribe {
background-color:#9BB43E;
}
input:focus, textarea:focus, select:focus,
#form_notice.warning #notice_data-text {
.form_notice.warning #notice_data-text {
border-color:#9BB43E;
box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
@ -84,13 +84,13 @@ background-color:#CEE1E9;
#notice_text-count {
color:#333333;
}
#form_notice.warning #notice_text-count {
.form_notice.warning #notice_text-count {
color:#000000;
}
#form_notice label[for=notice_data-attach] {
.form_notice label[for=notice_data-attach] {
background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px;
}
#form_notice #notice_data-attach {
.form_notice #notice_data-attach {
opacity:0;
}

View File

@ -6,10 +6,10 @@ color:#FFFFFF;
#site_nav_local_views a {
background-color:#D9DADB;
}
#form_notice .form_note + label {
.form_notice .form_note + label {
background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px;
}
#form_notice #notice_data-attach {
.form_notice #notice_data-attach {
filter: alpha(opacity=0);
}
.notice-options form.form_favor input.submit {