Merge branch '0.7.x' of git@gitorious.org:laconica/dev

Conflicts:
	README
	lib/router.php
This commit is contained in:
Evan Prodromou 2009-04-01 14:40:58 -04:00
commit 3bec08c878
30 changed files with 799 additions and 441 deletions

10
README
View File

@ -877,7 +877,7 @@ This section is a catch-all for site-wide variables.
name: the name of your site, like 'YourCompany Microblog'.
server: the server part of your site's URLs, like 'example.net'.
path: The path part of your site's URLs, like 'mublog' or '/'
path: The path part of your site's URLs, like 'mublog' or ''
(installed in root).
fancy: whether or not your site uses fancy URLs (see Fancy URLs
section above). Default is false.
@ -1184,10 +1184,10 @@ newuser
Options with new users.
subscribe: nickname of a user account to automatically subscribe new
users to. Typically this would be system account for e.g.
service updates or announcements. Users are able to unsub
if they want. Default is null; no auto subscribe.
default: nickname of a user account to automatically subscribe new
users to. Typically this would be system account for e.g.
service updates or announcements. Users are able to unsub
if they want. Default is null; no auto subscribe.
welcome: nickname of a user account that sends welcome messages to new
users. Can be the same as 'subscribe' account, although on
busy servers it may be a good idea to keep that one just for

View File

@ -166,6 +166,50 @@ class PublicAction extends Action
$nav->show();
}
function showPageNotice()
{
$notice = Notice::publicStream(0, 1);
if (!$notice) {
$this->serverError(_('Could not retrieve public stream.'));
return;
}
// no notices in the public stream, let's get out of here
if ($notice->count()) {
return;
}
$message = _('This is the public timeline for %%site.name%% but noone has posted anything yet.') . ' ';
if (common_logged_in()) {
$message .= _('Be the first to post!');
/*
sprintf(_('You are logged in... %%%%site.name%%%% groups let you find and talk with ' .
'people of similar interests. After you join a group ' .
'you can send messages to all other members using the ' .
'syntax "!groupname". Don\'t see a group you like? Try ' .
'[searching for one](%%%%action.groupsearch%%%%) or ' .
'[start your own!](%%%%action.newgroup%%%%)'));
*/
}
else {
$message .= _('Why not [register an account](%%action.register%%) and be the first to post!');
/*
sprintf(_('You are not logged in... %%%%site.name%%%% groups let you find and talk with ' .
'people of similar interests. After you join a group ' .
'you can send messages to all other members using the ' .
'syntax "!groupname". Don\'t see a group you like? Try ' .
'[searching for one](%%%%action.groupsearch%%%%) or ' .
'[start your own!](%%%%action.newgroup%%%%)'));
*/
}
$this->elementStart('div', 'blankfiller');
$this->raw(common_markup_to_html($message));
$this->elementEnd('div');
}
/**
* Fill the content area
*
@ -207,9 +251,14 @@ class PublicAction extends Action
function showAnonymousMessage()
{
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
'[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ([Read more](%%doc.help%%))');
if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
'[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ([Read more](%%doc.help%%))');
} else {
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool.');
}
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');

View File

@ -181,13 +181,21 @@ class RecoverpasswordAction extends Action
function showRecoverForm()
{
$this->elementStart('form', array('method' => 'post',
'id' => 'recoverpassword',
'id' => 'form_password_recover',
'class' => 'form_settings',
'action' => common_local_url('recoverpassword')));
$this->elementStart('fieldset');
$this->element('legend', null, _('Password recover'));
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->input('nicknameoremail', _('Nickname or email'),
$this->trimmed('nicknameoremail'),
_('Your nickname on this server, ' .
'or your registered email address.'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('recover', _('Recover'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
@ -213,14 +221,24 @@ class RecoverpasswordAction extends Action
function showResetForm()
{
$this->elementStart('form', array('method' => 'post',
'id' => 'recoverpassword',
'id' => 'form_password_change',
'class' => 'form_settings',
'action' => common_local_url('recoverpassword')));
$this->elementStart('fieldset');
$this->element('legend', null, _('Password change'));
$this->hidden('token', common_session_token());
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->password('newpassword', _('New password'),
_('6 or more characters, and don\'t forget it!'));
$this->elementEnd('li');
$this->elementStart('li');
$this->password('confirm', _('Confirm'),
_('Same as password above'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('reset', _('Reset'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}

View File

@ -396,11 +396,18 @@ class ShowgroupAction extends Action
function showAnonymousMessage()
{
$m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
'short messages about their life and interests. '.
'[Join now](%%%%action.register%%%%) to become part of this group and many more! ([Read more](%%%%doc.help%%%%))'),
if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
$m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
'short messages about their life and interests. '.
'[Join now](%%%%action.register%%%%) to become part of this group and many more! ([Read more](%%%%doc.help%%%%))'),
$this->group->nickname);
} else {
$m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
'short messages about their life and interests. '),
$this->group->nickname);
}
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');

View File

@ -535,10 +535,16 @@ class ShowstreamAction extends Action
function showAnonymousMessage()
{
$m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
'[Join now](%%%%action.register%%%%) to follow **%s**\'s notices and many more! ([Read more](%%%%doc.help%%%%))'),
$this->user->nickname, $this->user->nickname);
if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
$m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
'[Join now](%%%%action.register%%%%) to follow **%s**\'s notices and many more! ([Read more](%%%%doc.help%%%%))'),
$this->user->nickname, $this->user->nickname);
} else {
$m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. '),
$this->user->nickname, $this->user->nickname);
}
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');

BIN
apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -799,4 +799,98 @@ class Notice extends Memcached_DataObject
}
}
}
function asAtomEntry($namespace=false, $source=false)
{
$profile = $this->getProfile();
$xs = new XMLStringer(true);
if ($namespace) {
$attrs = array('xmlns' => 'http://www.w3.org/2005/Atom',
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0');
} else {
$attrs = array();
}
$xs->elementStart('entry', $attrs);
if ($source) {
$xs->elementStart('source');
$xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name'));
$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'));
$xs->element('link', array('rel' => 'self',
'type' => 'application/atom+xml',
'href' => $profile->profileurl));
$xs->element('link', array('rel' => 'license',
'href' => common_config('license', 'url')));
}
$xs->element('icon', null, $profile->avatarUrl(AVATAR_PROFILE_SIZE));
}
$xs->elementStart('author');
$xs->element('name', null, $profile->nickname);
$xs->element('uri', null, $profile->profileurl);
$xs->elementEnd('author');
if ($source) {
$xs->elementEnd('source');
}
$xs->element('title', null, $this->content);
$xs->element('summary', null, $this->content);
$xs->element('link', array('rel' => 'alternate',
'href' => $this->bestUrl()));
$xs->element('id', null, $this->uri);
$xs->element('published', null, common_date_w3dtf($this->created));
$xs->element('updated', null, common_date_w3dtf($this->modified));
if ($this->reply_to) {
$reply_notice = Notice::staticGet('id', $this->reply_to);
if (!empty($reply_notice)) {
$xs->element('link', array('rel' => 'related',
'href' => $reply_notice->bestUrl()));
$xs->element('thr:in-reply-to',
array('ref' => $reply_notice->uri,
'href' => $reply_notice->bestUrl()));
}
}
$xs->element('content', array('type' => 'html'), $this->rendered);
$tag = new Notice_tag();
$tag->notice_id = $this->id;
if ($tag->find()) {
while ($tag->fetch()) {
$xs->element('category', array('term' => $tag->tag));
}
}
$tag->free();
$xs->elementEnd('entry');
return $xs->getString();
}
function bestUrl()
{
if (!empty($this->url)) {
return $this->url;
} else if (!empty($this->uri) && preg_match('/^https?:/', $this->uri)) {
return $this->uri;
} else {
return common_local_url('shownotice',
array('notice' => $this->id));
}
}
}

View File

@ -1,7 +1,7 @@
<?php
/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
* Copyright (C) 2008, 2009, Control Yourself, 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
@ -17,11 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
/**
* Table Definition for user
*/
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
require_once 'Validate.php';
@ -79,13 +82,13 @@ class User extends Memcached_DataObject
function isSubscribed($other)
{
assert(!is_null($other));
# XXX: cache results of this query
// XXX: cache results of this query
$sub = Subscription::pkeyGet(array('subscriber' => $this->id,
'subscribed' => $other->id));
return (is_null($sub)) ? false : true;
}
# 'update' won't write key columns, so we have to do it ourselves.
// 'update' won't write key columns, so we have to do it ourselves.
function updateKeys(&$orig)
{
@ -96,7 +99,7 @@ class User extends Memcached_DataObject
}
}
if (count($parts) == 0) {
# No changes
// No changes
return true;
}
$toupdate = implode(', ', $parts);
@ -117,7 +120,7 @@ class User extends Memcached_DataObject
function allowed_nickname($nickname)
{
# XXX: should already be validated for size, content, etc.
// XXX: should already be validated for size, content, etc.
static $blacklist = array('rss', 'xrds', 'doc', 'main',
'settings', 'notice', 'user',
'search', 'avatar', 'tag', 'tags',
@ -147,7 +150,7 @@ class User extends Memcached_DataObject
$sub->subscriber = $this->id;
$sub->subscribed = $other->id;
$sub->created = common_sql_now(); # current time
$sub->created = common_sql_now(); // current time
if (!$sub->insert()) {
return false;
@ -173,7 +176,7 @@ class User extends Memcached_DataObject
static function register($fields) {
# MAGICALLY put fields into current scope
// MAGICALLY put fields into current scope
extract($fields);
@ -211,11 +214,11 @@ class User extends Memcached_DataObject
$user->id = $id;
$user->nickname = $nickname;
if (!empty($password)) { # may not have a password for OpenID users
if (!empty($password)) { // may not have a password for OpenID users
$user->password = common_munge_password($password, $id);
}
# Users who respond to invite email have proven their ownership of that address
// Users who respond to invite email have proven their ownership of that address
if (!empty($code)) {
$invite = Invitation::staticGet($code);
@ -240,7 +243,7 @@ class User extends Memcached_DataObject
return false;
}
# Everyone is subscribed to themself
// Everyone is subscribed to themself
$subscription = new Subscription();
$subscription->subscriber = $user->id;
@ -324,7 +327,7 @@ class User extends Memcached_DataObject
return $user;
}
# Things we do when the email changes
// Things we do when the email changes
function emailChanged()
{
@ -345,46 +348,46 @@ class User extends Memcached_DataObject
{
$cache = common_memcache();
# XXX: Kind of a hack.
// XXX: Kind of a hack.
if ($cache) {
# This is the stream of favorite notices, in rev chron
# order. This forces it into cache.
// This is the stream of favorite notices, in rev chron
// order. This forces it into cache.
$faves = $this->favoriteNotices(0, NOTICE_CACHE_WINDOW);
$cnt = 0;
while ($faves->fetch()) {
if ($faves->id < $notice->id) {
# If we passed it, it's not a fave
// If we passed it, it's not a fave
return false;
} else if ($faves->id == $notice->id) {
# If it matches a cached notice, then it's a fave
// If it matches a cached notice, then it's a fave
return true;
}
$cnt++;
}
# If we're not past the end of the cache window,
# then the cache has all available faves, so this one
# is not a fave.
// If we're not past the end of the cache window,
// then the cache has all available faves, so this one
// is not a fave.
if ($cnt < NOTICE_CACHE_WINDOW) {
return false;
}
# Otherwise, cache doesn't have all faves;
# fall through to the default
// Otherwise, cache doesn't have all faves;
// fall through to the default
}
$fave = Fave::pkeyGet(array('user_id' => $this->id,
'notice_id' => $notice->id));
return ((is_null($fave)) ? false : true);
}
function mutuallySubscribed($other)
{
return $this->isSubscribed($other) &&
$other->isSubscribed($this);
}
function mutuallySubscribedUsers()
{
# 3-way join; probably should get cached
$UT = common_config('db','type')=='pgsql'?'"user"':'user';
function mutuallySubscribedUsers()
{
// 3-way join; probably should get cached
$UT = common_config('db','type')=='pgsql'?'"user"':'user';
$qry = "SELECT $UT.* " .
"FROM subscription sub1 JOIN $UT ON sub1.subscribed = $UT.id " .
"JOIN subscription sub2 ON $UT.id = sub2.subscriber " .
@ -407,8 +410,8 @@ class User extends Memcached_DataObject
$offset, $limit, $since_id, $before_id, null, $since);
}
function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
{
function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
{
$profile = $this->getProfile();
if (!$profile) {
return null;
@ -417,8 +420,8 @@ class User extends Memcached_DataObject
}
}
function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE)
{
function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE)
{
$qry =
'SELECT notice.* ' .
'FROM notice JOIN fave ON notice.id = fave.notice_id ' .
@ -428,12 +431,12 @@ class User extends Memcached_DataObject
$offset, $limit);
}
function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
{
function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
{
$enabled = common_config('inboxes', 'enabled');
# Complicated code, depending on whether we support inboxes yet
# XXX: make this go away when inboxes become mandatory
// Complicated code, depending on whether we support inboxes yet
// XXX: make this go away when inboxes become mandatory
if ($enabled === false ||
($enabled == 'transitional' && $this->inboxed == 0)) {
@ -443,13 +446,13 @@ class User extends Memcached_DataObject
'WHERE subscription.subscriber = %d ';
$order = null;
} else if ($enabled === true ||
($enabled == 'transitional' && $this->inboxed == 1)) {
($enabled == 'transitional' && $this->inboxed == 1)) {
$qry =
'SELECT notice.* ' .
'FROM notice JOIN notice_inbox ON notice.id = notice_inbox.notice_id ' .
'WHERE notice_inbox.user_id = %d ';
# NOTE: we override ORDER
// NOTE: we override ORDER
$order = null;
}
return Notice::getStream(sprintf($qry, $this->id),
@ -458,35 +461,34 @@ class User extends Memcached_DataObject
$order, $since);
}
function blowFavesCache()
{
function blowFavesCache()
{
$cache = common_memcache();
if ($cache) {
# Faves don't happen chronologically, so we need to blow
# ;last cache, too
// Faves don't happen chronologically, so we need to blow
// ;last cache, too
$cache->delete(common_cache_key('user:faves:'.$this->id));
$cache->delete(common_cache_key('user:faves:'.$this->id).';last');
}
}
function getSelfTags()
{
function getSelfTags()
{
return Profile_tag::getTags($this->id, $this->id);
}
function setSelfTags($newtags)
{
function setSelfTags($newtags)
{
return Profile_tag::setTags($this->id, $this->id, $newtags);
}
function block($other)
{
# Add a new block record
// Add a new block record
$block = new Profile_block();
# Begin a transaction
// Begin a transaction
$block->query('BEGIN');
@ -500,7 +502,7 @@ class User extends Memcached_DataObject
return false;
}
# Cancel their subscription, if it exists
// Cancel their subscription, if it exists
$sub = Subscription::pkeyGet(array('subscriber' => $other->id,
'subscribed' => $this->id));
@ -520,8 +522,7 @@ class User extends Memcached_DataObject
function unblock($other)
{
# Get the block record
// Get the block record
$block = Profile_block::get($this->id, $other->id);

View File

@ -13,7 +13,7 @@ create table profile (
index profile_nickname_idx (nickname),
FULLTEXT(nickname, fullname, location, bio, homepage)
) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin;
) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
create table avatar (
profile_id integer not null comment 'foreign key to profile table' references profile (id),
@ -73,7 +73,7 @@ create table user (
modified timestamp comment 'date this record was modified',
index user_smsemail_idx (smsemail)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
/* remote people */
@ -103,7 +103,6 @@ create table subscription (
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table notice (
id integer auto_increment primary key comment 'unique identifier',
profile_id integer not null comment 'who made the update' references profile (id),
uri varchar(255) unique key comment 'universally unique identifier, usually a tag URI',
@ -119,7 +118,7 @@ create table notice (
index notice_profile_id_idx (profile_id),
index notice_created_idx (created),
FULLTEXT(content)
) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin;
) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
create table notice_source (
code varchar(32) primary key not null comment 'source code',
@ -130,7 +129,6 @@ create table notice_source (
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table reply (
notice_id integer not null comment 'notice that is the reply' references notice (id),
profile_id integer not null comment 'profile replied to' references profile (id),
modified timestamp not null comment 'date this record was modified',
@ -144,7 +142,6 @@ create table reply (
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table fave (
notice_id integer not null comment 'notice that is the favorite' references notice (id),
user_id integer not null comment 'user who likes this notice' references user (id),
modified timestamp not null comment 'date this record was modified',
@ -321,7 +318,6 @@ create table invitation (
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table message (
id integer auto_increment primary key comment 'unique identifier',
uri varchar(255) unique key comment 'universally unique identifier',
from_profile integer not null comment 'who the message is from' references profile (id),
@ -336,10 +332,9 @@ create table message (
index message_from_idx (from_profile),
index message_to_idx (to_profile),
index message_created_idx (created)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
create table notice_inbox (
user_id integer not null comment 'user receiving the message' references user (id),
notice_id integer not null comment 'notice received' references notice (id),
created datetime not null comment 'date the notice was created',
@ -362,7 +357,6 @@ create table profile_tag (
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table profile_block (
blocker integer not null comment 'user making the block' references user (id),
blocked integer not null comment 'profile that is blocked' references profile (id),
modified timestamp comment 'date of blocking',
@ -372,7 +366,6 @@ create table profile_block (
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table user_group (
id integer auto_increment primary key comment 'unique identifier',
nickname varchar(64) unique key comment 'nickname for addressing',
@ -391,10 +384,9 @@ create table user_group (
index user_group_nickname_idx (nickname)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
create table group_member (
group_id integer not null comment 'foreign key to user_group' references user_group (id),
profile_id integer not null comment 'foreign key to profile table' references profile (id),
is_admin boolean default false comment 'is this user an admin?',
@ -409,7 +401,6 @@ create table group_member (
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table related_group (
group_id integer not null comment 'foreign key to user_group' references user_group (id),
related_group_id integer not null comment 'foreign key to user_group' references user_group (id),

View File

@ -19,6 +19,7 @@ VALUES
('identichat','identichat','http://identichat.prosody.im/', now()),
('identitwitch','IdentiTwitch','http://richfish.org/identitwitch/', now()),
('mbpidgin','mbpidgin','http://code.google.com/p/microblog-purple/', now()),
('Mobidentica', 'Mobidentica', 'http://www.substanceofcode.com/software/mobidentica/', now()),
('moconica','Moconica','http://moconica.com/', now()),
('pocketwit','PockeTwit','http://code.google.com/p/pocketwit/', now()),
('posty','Posty','http://spreadingfunkyness.com/posty/', now()),
@ -44,4 +45,4 @@ VALUES
('twitux','Twitux','http://live.gnome.org/DanielMorales/Twitux', now()),
('twitvim','TwitVim','http://vim.sourceforge.net/scripts/script.php?script_id=2204', now()),
('urfastr','urfastr','http://urfastr.net/', now()),
('adium', 'Adium', 'http://www.adiumx.com/', now()));
('adium', 'Adium', 'http://www.adiumx.com/', now());

499
js/jquery.js vendored
View File

@ -1,13 +1,13 @@
/*!
* jQuery JavaScript Library v1.3.1
* jQuery JavaScript Library v1.3.2
* http://jquery.com/
*
* Copyright (c) 2009 John Resig
* Dual licensed under the MIT and GPL licenses.
* http://docs.jquery.com/License
*
* Date: 2009-01-21 20:42:16 -0500 (Wed, 21 Jan 2009)
* Revision: 6158
* Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
* Revision: 6246
*/
(function(){
@ -88,14 +88,16 @@ jQuery.fn = jQuery.prototype = {
this.context = selector.context;
}
return this.setArray(jQuery.makeArray(selector));
return this.setArray(jQuery.isArray( selector ) ?
selector :
jQuery.makeArray(selector));
},
// Start with an empty selector
selector: "",
// The current version of jQuery being used
jquery: "1.3.1",
jquery: "1.3.2",
// The number of elements contained in the matched element set
size: function() {
@ -108,7 +110,7 @@ jQuery.fn = jQuery.prototype = {
return num === undefined ?
// Return a 'clean' array
jQuery.makeArray( this ) :
Array.prototype.slice.call( this ) :
// Return just the object
this[ num ];
@ -278,23 +280,21 @@ jQuery.fn = jQuery.prototype = {
},
// For internal use only.
// Behaves like an Array's .push method, not like a jQuery method.
// Behaves like an Array's method, not like a jQuery method.
push: [].push,
sort: [].sort,
splice: [].splice,
find: function( selector ) {
if ( this.length === 1 && !/,/.test(selector) ) {
if ( this.length === 1 ) {
var ret = this.pushStack( [], "find", selector );
ret.length = 0;
jQuery.find( selector, this[0], ret );
return ret;
} else {
var elems = jQuery.map(this, function(elem){
return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
return jQuery.find( selector, elem );
});
return this.pushStack( /[^+>] [^+>]/.test( selector ) ?
jQuery.unique( elems ) :
elems, "find", selector );
})), "find", selector );
}
},
@ -310,33 +310,37 @@ jQuery.fn = jQuery.prototype = {
// attributes in IE that are actually only stored
// as properties will not be copied (such as the
// the name attribute on an input).
var clone = this.cloneNode(true),
container = document.createElement("div");
container.appendChild(clone);
return jQuery.clean([container.innerHTML])[0];
var html = this.outerHTML;
if ( !html ) {
var div = this.ownerDocument.createElement("div");
div.appendChild( this.cloneNode(true) );
html = div.innerHTML;
}
return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
} else
return this.cloneNode(true);
});
// Need to set the expando to null on the cloned set if it exists
// removeData doesn't work here, IE removes it from the original as well
// this is primarily for IE but the data expando shouldn't be copied over in any browser
var clone = ret.find("*").andSelf().each(function(){
if ( this[ expando ] !== undefined )
this[ expando ] = null;
});
// Copy the events from the original to the clone
if ( events === true )
this.find("*").andSelf().each(function(i){
if (this.nodeType == 3)
return;
var events = jQuery.data( this, "events" );
if ( events === true ) {
var orig = this.find("*").andSelf(), i = 0;
for ( var type in events )
for ( var handler in events[ type ] )
jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
ret.find("*").andSelf().each(function(){
if ( this.nodeName !== orig[i].nodeName )
return;
var events = jQuery.data( orig[i], "events" );
for ( var type in events ) {
for ( var handler in events[ type ] ) {
jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
}
}
i++;
});
}
// Return the cloned set
return ret;
@ -355,14 +359,18 @@ jQuery.fn = jQuery.prototype = {
},
closest: function( selector ) {
var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null;
var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
closer = 0;
return this.map(function(){
var cur = this;
while ( cur && cur.ownerDocument ) {
if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) )
if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
jQuery.data(cur, "closest", closer);
return cur;
}
cur = cur.parentNode;
closer++;
}
});
},
@ -475,7 +483,7 @@ jQuery.fn = jQuery.prototype = {
html: function( value ) {
return value === undefined ?
(this[0] ?
this[0].innerHTML :
this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
null) :
this.empty().append( value );
},
@ -507,13 +515,13 @@ jQuery.fn = jQuery.prototype = {
if ( this[0] ) {
var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
first = fragment.firstChild,
extra = this.length > 1 ? fragment.cloneNode(true) : fragment;
first = fragment.firstChild;
if ( first )
for ( var i = 0, l = this.length; i < l; i++ )
callback.call( root(this[i], first), i > 0 ? extra.cloneNode(true) : fragment );
callback.call( root(this[i], first), this.length > 1 || i > 0 ?
fragment.cloneNode(true) : fragment );
if ( scripts )
jQuery.each( scripts, evalScript );
}
@ -636,9 +644,7 @@ jQuery.extend({
// Evalulates a script in a global context
globalEval: function( data ) {
data = jQuery.trim( data );
if ( data ) {
if ( data && /\S/.test(data) ) {
// Inspired by code by Andrea Giammarchi
// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
var head = document.getElementsByTagName("head")[0] || document.documentElement,
@ -741,26 +747,32 @@ jQuery.extend({
elem.style[ name ] = old[ name ];
},
css: function( elem, name, force ) {
css: function( elem, name, force, extra ) {
if ( name == "width" || name == "height" ) {
var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
function getWH() {
val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
var padding = 0, border = 0;
if ( extra === "border" )
return;
jQuery.each( which, function() {
padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
if ( !extra )
val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
if ( extra === "margin" )
val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
else
val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
});
val -= Math.round(padding + border);
}
if ( jQuery(elem).is(":visible") )
if ( elem.offsetWidth !== 0 )
getWH();
else
jQuery.swap( elem, props, getWH );
return Math.max(0, val);
return Math.max(0, Math.round(val));
}
return jQuery.curCSS( elem, name, force );
@ -866,7 +878,7 @@ jQuery.extend({
});
// Trim whitespace, otherwise indexOf won't work as expected
var tags = jQuery.trim( elem ).toLowerCase();
var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
var wrap =
// option or optgroup
@ -906,11 +918,12 @@ jQuery.extend({
if ( !jQuery.support.tbody ) {
// String was a <table>, *may* have spurious <tbody>
var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
div.firstChild && div.firstChild.childNodes :
var hasBody = /<tbody/i.test(elem),
tbody = !tags.indexOf("<table") && !hasBody ?
div.firstChild && div.firstChild.childNodes :
// String was a bare <thead> or <tfoot>
wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
wrap[1] == "<table>" && !hasBody ?
div.childNodes :
[];
@ -1189,13 +1202,16 @@ jQuery.each({
insertAfter: "after",
replaceAll: "replaceWith"
}, function(name, original){
jQuery.fn[ name ] = function() {
var args = arguments;
jQuery.fn[ name ] = function( selector ) {
var ret = [], insert = jQuery( selector );
return this.each(function(){
for ( var i = 0, length = args.length; i < length; i++ )
jQuery( args[ i ] )[ original ]( this );
});
for ( var i = 0, l = insert.length; i < l; i++ ) {
var elems = (i > 0 ? this.clone(true) : this).get();
jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
ret = ret.concat( elems );
}
return this.pushStack( ret, name, selector );
};
});
@ -1234,7 +1250,7 @@ jQuery.each({
empty: function() {
// Remove element nodes and prevent memory leaks
jQuery( ">*", this ).remove();
jQuery(this).children().remove();
// Remove any remaining nodes
while ( this.firstChild )
@ -1402,7 +1418,7 @@ jQuery.fn.extend({
*/
(function(){
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]+['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
done = 0,
toString = Object.prototype.toString;
@ -1507,6 +1523,19 @@ var Sizzle = function(selector, context, results, seed) {
if ( extra ) {
Sizzle( extra, context, results, seed );
if ( sortOrder ) {
hasDuplicate = false;
results.sort(sortOrder);
if ( hasDuplicate ) {
for ( var i = 1; i < results.length; i++ ) {
if ( results[i] === results[i-1] ) {
results.splice(i--, 1);
}
}
}
}
}
return results;
@ -1548,7 +1577,8 @@ Sizzle.find = function(expr, context, isXML){
};
Sizzle.filter = function(expr, set, inplace, not){
var old = expr, result = [], curLoop = set, match, anyFound;
var old = expr, result = [], curLoop = set, match, anyFound,
isXMLFilter = set && set[0] && isXML(set[0]);
while ( expr && set.length ) {
for ( var type in Expr.filter ) {
@ -1561,7 +1591,7 @@ Sizzle.filter = function(expr, set, inplace, not){
}
if ( Expr.preFilter[ type ] ) {
match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not );
match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
if ( !match ) {
anyFound = found = true;
@ -1606,8 +1636,6 @@ Sizzle.filter = function(expr, set, inplace, not){
}
}
expr = expr.replace(/\s*,\s*/, "");
// Improper expression
if ( expr == old ) {
if ( anyFound == null ) {
@ -1645,26 +1673,33 @@ var Expr = Sizzle.selectors = {
}
},
relative: {
"+": function(checkSet, part){
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i];
if ( elem ) {
var cur = elem.previousSibling;
while ( cur && cur.nodeType !== 1 ) {
cur = cur.previousSibling;
}
checkSet[i] = typeof part === "string" ?
cur || false :
cur === part;
"+": function(checkSet, part, isXML){
var isPartStr = typeof part === "string",
isTag = isPartStr && !/\W/.test(part),
isPartStrNotTag = isPartStr && !isTag;
if ( isTag && !isXML ) {
part = part.toUpperCase();
}
for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
if ( (elem = checkSet[i]) ) {
while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
elem || false :
elem === part;
}
}
if ( typeof part === "string" ) {
if ( isPartStrNotTag ) {
Sizzle.filter( part, checkSet, true );
}
},
">": function(checkSet, part, isXML){
if ( typeof part === "string" && !/\W/.test(part) ) {
var isPartStr = typeof part === "string";
if ( isPartStr && !/\W/.test(part) ) {
part = isXML ? part : part.toUpperCase();
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
@ -1678,19 +1713,19 @@ var Expr = Sizzle.selectors = {
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i];
if ( elem ) {
checkSet[i] = typeof part === "string" ?
checkSet[i] = isPartStr ?
elem.parentNode :
elem.parentNode === part;
}
}
if ( typeof part === "string" ) {
if ( isPartStr ) {
Sizzle.filter( part, checkSet, true );
}
}
},
"": function(checkSet, part, isXML){
var doneName = "done" + (done++), checkFn = dirCheck;
var doneName = done++, checkFn = dirCheck;
if ( !part.match(/\W/) ) {
var nodeCheck = part = isXML ? part : part.toUpperCase();
@ -1700,7 +1735,7 @@ var Expr = Sizzle.selectors = {
checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
},
"~": function(checkSet, part, isXML){
var doneName = "done" + (done++), checkFn = dirCheck;
var doneName = done++, checkFn = dirCheck;
if ( typeof part === "string" && !part.match(/\W/) ) {
var nodeCheck = part = isXML ? part : part.toUpperCase();
@ -1718,8 +1753,16 @@ var Expr = Sizzle.selectors = {
}
},
NAME: function(match, context, isXML){
if ( typeof context.getElementsByName !== "undefined" && !isXML ) {
return context.getElementsByName(match[1]);
if ( typeof context.getElementsByName !== "undefined" ) {
var ret = [], results = context.getElementsByName(match[1]);
for ( var i = 0, l = results.length; i < l; i++ ) {
if ( results[i].getAttribute("name") === match[1] ) {
ret.push( results[i] );
}
}
return ret.length === 0 ? null : ret;
}
},
TAG: function(match, context){
@ -1727,13 +1770,16 @@ var Expr = Sizzle.selectors = {
}
},
preFilter: {
CLASS: function(match, curLoop, inplace, result, not){
CLASS: function(match, curLoop, inplace, result, not, isXML){
match = " " + match[1].replace(/\\/g, "") + " ";
var elem;
for ( var i = 0; (elem = curLoop[i]) != null; i++ ) {
if ( isXML ) {
return match;
}
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
if ( elem ) {
if ( not ^ (" " + elem.className + " ").indexOf(match) >= 0 ) {
if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
if ( !inplace )
result.push( elem );
} else if ( inplace ) {
@ -1764,14 +1810,14 @@ var Expr = Sizzle.selectors = {
}
// TODO: Move to normal caching system
match[0] = "done" + (done++);
match[0] = done++;
return match;
},
ATTR: function(match){
ATTR: function(match, curLoop, inplace, result, not, isXML){
var name = match[1].replace(/\\/g, "");
if ( Expr.attrMap[name] ) {
if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
}
@ -1784,7 +1830,7 @@ var Expr = Sizzle.selectors = {
PSEUDO: function(match, curLoop, inplace, result, not){
if ( match[1] === "not" ) {
// If we're dealing with a complex expression, or a simple one
if ( match[3].match(chunker).length > 1 ) {
if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
match[3] = Sizzle(match[3], null, null, curLoop);
} else {
var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
@ -1793,7 +1839,7 @@ var Expr = Sizzle.selectors = {
}
return false;
}
} else if ( Expr.match.POS.test( match[0] ) ) {
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
@ -1890,47 +1936,6 @@ var Expr = Sizzle.selectors = {
}
},
filter: {
CHILD: function(elem, match){
var type = match[1], parent = elem.parentNode;
var doneName = match[0];
if ( parent && (!parent[ doneName ] || !elem.nodeIndex) ) {
var count = 1;
for ( var node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType == 1 ) {
node.nodeIndex = count++;
}
}
parent[ doneName ] = count - 1;
}
if ( type == "first" ) {
return elem.nodeIndex == 1;
} else if ( type == "last" ) {
return elem.nodeIndex == parent[ doneName ];
} else if ( type == "only" ) {
return parent[ doneName ] == 1;
} else if ( type == "nth" ) {
var add = false, first = match[2], last = match[3];
if ( first == 1 && last == 0 ) {
return true;
}
if ( first == 0 ) {
if ( elem.nodeIndex == last ) {
add = true;
}
} else if ( (elem.nodeIndex - last) % first == 0 && (elem.nodeIndex - last) / first >= 0 ) {
add = true;
}
return add;
}
},
PSEUDO: function(elem, match, i, array){
var name = match[1], filter = Expr.filters[ name ];
@ -1950,6 +1955,49 @@ var Expr = Sizzle.selectors = {
return true;
}
},
CHILD: function(elem, match){
var type = match[1], node = elem;
switch (type) {
case 'only':
case 'first':
while (node = node.previousSibling) {
if ( node.nodeType === 1 ) return false;
}
if ( type == 'first') return true;
node = elem;
case 'last':
while (node = node.nextSibling) {
if ( node.nodeType === 1 ) return false;
}
return true;
case 'nth':
var first = match[2], last = match[3];
if ( first == 1 && last == 0 ) {
return true;
}
var doneName = match[0],
parent = elem.parentNode;
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
var count = 0;
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
}
parent.sizcache = doneName;
}
var diff = elem.nodeIndex - last;
if ( first == 0 ) {
return diff == 0;
} else {
return ( diff % first == 0 && diff / first >= 0 );
}
}
},
ID: function(elem, match){
return elem.nodeType === 1 && elem.getAttribute("id") === match;
},
@ -1957,10 +2005,20 @@ var Expr = Sizzle.selectors = {
return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
},
CLASS: function(elem, match){
return match.test( elem.className );
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1;
},
ATTR: function(elem, match){
var result = Expr.attrHandle[ match[1] ] ? Expr.attrHandle[ match[1] ]( elem ) : elem[ match[1] ] || elem.getAttribute( match[1] ), value = result + "", type = match[2], check = match[4];
var name = match[1],
result = Expr.attrHandle[ name ] ?
Expr.attrHandle[ name ]( elem ) :
elem[ name ] != null ?
elem[ name ] :
elem.getAttribute( name ),
value = result + "",
type = match[2],
check = match[4];
return result == null ?
type === "!=" :
type === "=" ?
@ -1969,8 +2027,8 @@ var Expr = Sizzle.selectors = {
value.indexOf(check) >= 0 :
type === "~=" ?
(" " + value + " ").indexOf(check) >= 0 :
!match[4] ?
result :
!check ?
value && result !== false :
type === "!=" ?
value != check :
type === "^=" ?
@ -2036,6 +2094,39 @@ try {
};
}
var sortOrder;
if ( document.documentElement.compareDocumentPosition ) {
sortOrder = function( a, b ) {
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
if ( ret === 0 ) {
hasDuplicate = true;
}
return ret;
};
} else if ( "sourceIndex" in document.documentElement ) {
sortOrder = function( a, b ) {
var ret = a.sourceIndex - b.sourceIndex;
if ( ret === 0 ) {
hasDuplicate = true;
}
return ret;
};
} else if ( document.createRange ) {
sortOrder = function( a, b ) {
var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
aRange.selectNode(a);
aRange.collapse(true);
bRange.selectNode(b);
bRange.collapse(true);
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
if ( ret === 0 ) {
hasDuplicate = true;
}
return ret;
};
}
// Check to see if the browser returns elements by name when
// querying by getElementById (and provide a workaround)
(function(){
@ -2099,7 +2190,8 @@ try {
// Check to see if an attribute returns normalized href attributes
div.innerHTML = "<a href='#'></a>";
if ( div.firstChild && div.firstChild.getAttribute("href") !== "#" ) {
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
div.firstChild.getAttribute("href") !== "#" ) {
Expr.attrHandle.href = function(elem){
return elem.getAttribute("href", 2);
};
@ -2136,29 +2228,50 @@ if ( document.querySelectorAll ) (function(){
Sizzle.matches = oldSizzle.matches;
})();
if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) {
if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
var div = document.createElement("div");
div.innerHTML = "<div class='test e'></div><div class='test'></div>";
// Opera can't find a second classname (in 9.6)
if ( div.getElementsByClassName("e").length === 0 )
return;
// Safari caches class attributes, doesn't catch changes (in 3.2)
div.lastChild.className = "e";
if ( div.getElementsByClassName("e").length === 1 )
return;
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function(match, context) {
return context.getElementsByClassName(match[1]);
Expr.find.CLASS = function(match, context, isXML) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
return context.getElementsByClassName(match[1]);
}
};
}
})();
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
var sibDir = dir == "previousSibling" && !isXML;
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i];
if ( elem ) {
if ( sibDir && elem.nodeType === 1 ){
elem.sizcache = doneName;
elem.sizset = i;
}
elem = elem[dir];
var match = false;
while ( elem && elem.nodeType ) {
var done = elem[doneName];
if ( done ) {
match = checkSet[ done ];
while ( elem ) {
if ( elem.sizcache === doneName ) {
match = checkSet[elem.sizset];
break;
}
if ( elem.nodeType === 1 && !isXML )
elem[doneName] = i;
if ( elem.nodeType === 1 && !isXML ){
elem.sizcache = doneName;
elem.sizset = i;
}
if ( elem.nodeName === cur ) {
match = elem;
@ -2174,22 +2287,28 @@ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
}
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
var sibDir = dir == "previousSibling" && !isXML;
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i];
if ( elem ) {
if ( sibDir && elem.nodeType === 1 ) {
elem.sizcache = doneName;
elem.sizset = i;
}
elem = elem[dir];
var match = false;
while ( elem && elem.nodeType ) {
if ( elem[doneName] ) {
match = checkSet[ elem[doneName] ];
while ( elem ) {
if ( elem.sizcache === doneName ) {
match = checkSet[elem.sizset];
break;
}
if ( elem.nodeType === 1 ) {
if ( !isXML )
elem[doneName] = i;
if ( !isXML ) {
elem.sizcache = doneName;
elem.sizset = i;
}
if ( typeof cur !== "string" ) {
if ( elem === cur ) {
match = true;
@ -2248,15 +2367,11 @@ jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;
Sizzle.selectors.filters.hidden = function(elem){
return "hidden" === elem.type ||
jQuery.css(elem, "display") === "none" ||
jQuery.css(elem, "visibility") === "hidden";
return elem.offsetWidth === 0 || elem.offsetHeight === 0;
};
Sizzle.selectors.filters.visible = function(elem){
return "hidden" !== elem.type &&
jQuery.css(elem, "display") !== "none" &&
jQuery.css(elem, "visibility") !== "hidden";
return elem.offsetWidth > 0 || elem.offsetHeight > 0;
};
Sizzle.selectors.filters.animated = function(elem){
@ -2552,7 +2667,8 @@ jQuery.event = {
var all, handlers;
event = arguments[0] = jQuery.event.fix( event || window.event );
event.currentTarget = this;
// Namespaced event handlers
var namespaces = event.type.split(".");
event.type = namespaces.shift();
@ -2883,9 +2999,13 @@ function liveHandler( event ){
}
});
elems.sort(function(a,b) {
return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
});
jQuery.each(elems, function(){
if ( this.fn.call(this.elem, event, this.fn.data) === false )
stop = false;
return (stop = false);
});
return stop;
@ -2949,7 +3069,7 @@ function bindReady(){
// If IE and not an iframe
// continually check to see if the document is ready
if ( document.documentElement.doScroll && typeof window.frameElement === "undefined" ) (function(){
if ( document.documentElement.doScroll && window == window.top ) (function(){
if ( jQuery.isReady ) return;
try {
@ -3079,12 +3199,11 @@ jQuery( window ).bind( 'unload', function(){
// document.body must exist before we can do this
jQuery(function(){
var div = document.createElement("div");
div.style.width = "1px";
div.style.paddingLeft = "1px";
div.style.width = div.style.paddingLeft = "1px";
document.body.appendChild( div );
jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
document.body.removeChild( div );
document.body.removeChild( div ).style.display = 'none';
});
})();
@ -3175,7 +3294,7 @@ jQuery.fn.extend({
.filter(function(){
return this.name && !this.disabled &&
(this.checked || /select|textarea/i.test(this.nodeName) ||
/text|hidden|password/i.test(this.type));
/text|hidden|password|search/i.test(this.type));
})
.map(function(i, elem){
var val = jQuery(this).val();
@ -3371,6 +3490,9 @@ jQuery.extend({
done = true;
success();
complete();
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
head.removeChild( script );
}
};
@ -3686,9 +3808,15 @@ jQuery.fn.extend({
elemdisplay[ tagName ] = display;
}
this[i].style.display = jQuery.data(this[i], "olddisplay", display);
jQuery.data(this[i], "olddisplay", display);
}
}
// Set the display of the elements in a second loop
// to avoid the constant reflow
for ( var i = 0, l = this.length; i < l; i++ ){
this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
}
return this;
}
@ -3702,8 +3830,14 @@ jQuery.fn.extend({
var old = jQuery.data(this[i], "olddisplay");
if ( !old && old !== "none" )
jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
}
// Set the display of the elements in a second loop
// to avoid the constant reflow
for ( var i = 0, l = this.length; i < l; i++ ){
this[i].style.display = "none";
}
return this;
}
},
@ -3915,7 +4049,7 @@ jQuery.fx.prototype = {
t.elem = this.elem;
if ( t() && jQuery.timers.push(t) == 1 ) {
if ( t() && jQuery.timers.push(t) && !timerId ) {
timerId = setInterval(function(){
var timers = jQuery.timers;
@ -3925,6 +4059,7 @@ jQuery.fx.prototype = {
if ( !timers.length ) {
clearInterval( timerId );
timerId = undefined;
}
}, 13);
}
@ -4193,22 +4328,21 @@ jQuery.each( ['Left', 'Top'], function(i, name) {
jQuery.each([ "Height", "Width" ], function(i, name){
var tl = i ? "Left" : "Top", // top or left
br = i ? "Right" : "Bottom"; // bottom or right
br = i ? "Right" : "Bottom", // bottom or right
lower = name.toLowerCase();
// innerHeight and innerWidth
jQuery.fn["inner" + name] = function(){
return this[ name.toLowerCase() ]() +
num(this, "padding" + tl) +
num(this, "padding" + br);
return this[0] ?
jQuery.css( this[0], lower, false, "padding" ) :
null;
};
// outerHeight and outerWidth
jQuery.fn["outer" + name] = function(margin) {
return this["inner" + name]() +
num(this, "border" + tl + "Width") +
num(this, "border" + br + "Width") +
(margin ?
num(this, "margin" + tl) + num(this, "margin" + br) : 0);
return this[0] ?
jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
null;
};
var type = name.toLowerCase();
@ -4238,4 +4372,5 @@ jQuery.each([ "Height", "Width" ], function(i, name){
this.css( type, typeof size === "string" ? size : size + "px" );
};
});})();
});
})();

10
js/jquery.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -161,6 +161,7 @@ $(document).ready(function(){
$("#form_notice").addClass("warning");
return false;
}
$("#form_notice").addClass("processing");
$("#notice_action-submit").attr("disabled", "disabled");
$("#notice_action-submit").addClass("disabled");
return true;
@ -179,6 +180,7 @@ $(document).ready(function(){
NoticeHover();
NoticeReply();
}
$("#form_notice").removeClass("processing");
$("#notice_action-submit").removeAttr("disabled");
$("#notice_action-submit").removeClass("disabled");
}

View File

@ -112,6 +112,7 @@ class Action extends HTMLOutputter // lawsuit
// XXX: attributes (profile?)
$this->elementStart('head');
$this->showTitle();
$this->showShortcutIcon();
$this->showStylesheets();
$this->showScripts();
$this->showOpenSearch();
@ -147,6 +148,32 @@ class Action extends HTMLOutputter // lawsuit
return _("Untitled page");
}
/**
* Show themed shortcut icon
*
* @return nothing
*/
function showShortcutIcon()
{
if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/favicon.ico')) {
$this->element('link', array('rel' => 'shortcut icon',
'href' => theme_path('favicon.ico')));
} else {
$this->element('link', array('rel' => 'shortcut icon',
'href' => common_path('favicon.ico')));
}
if (common_config('site', 'mobile')) {
if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/apple-touch-icon.png')) {
$this->element('link', array('rel' => 'apple-touch-icon',
'href' => theme_path('apple-touch-icon.png')));
} else {
$this->element('link', array('rel' => 'apple-touch-icon',
'href' => common_path('apple-touch-icon.png')));
}
}
}
/**
* Show stylesheets
*

View File

@ -163,50 +163,25 @@ function jabber_send_notice($to, $notice)
function jabber_format_entry($profile, $notice)
{
// FIXME: notice url might be remote
$entry = $notice->asAtomEntry(true, true);
$noticeurl = common_local_url('shownotice',
array('notice' => $notice->id));
$msg = jabber_format_notice($profile, $notice);
$self_url = common_local_url('userrss', array('nickname' => $profile->nickname));
$entry = "\n<entry xmlns='http://www.w3.org/2005/Atom'>\n";
$entry .= "<source>\n";
$entry .= "<title>" . $profile->nickname . " - " . common_config('site', 'name') . "</title>\n";
$entry .= "<link href='" . htmlspecialchars($profile->profileurl) . "'/>\n";
$entry .= "<link rel='self' type='application/rss+xml' href='" . $self_url . "'/>\n";
$entry .= "<author><name>" . $profile->nickname . "</name></author>\n";
$entry .= "<icon>" . $profile->avatarUrl(AVATAR_PROFILE_SIZE) . "</icon>\n";
$entry .= "</source>\n";
$entry .= "<title>" . htmlspecialchars($msg) . "</title>\n";
$entry .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";
$entry .= "<link rel='alternate' href='" . $noticeurl . "' />\n";
$entry .= "<id>". $notice->uri . "</id>\n";
$entry .= "<published>".common_date_w3dtf($notice->created)."</published>\n";
$entry .= "<updated>".common_date_w3dtf($notice->modified)."</updated>\n";
if ($notice->reply_to) {
$replyurl = common_local_url('shownotice',
array('notice' => $notice->reply_to));
$entry .= "<link rel='related' href='" . $replyurl . "'/>\n";
$xs = new XMLStringer();
$xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im'));
$xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml'));
$xs->element('a', array('href' => $profile->profileurl),
$profile->nickname);
$xs->text(": ");
if (!empty($notice->rendered)) {
$xs->raw($notice->rendered);
} else {
$xs->raw(common_render_content($notice->content, $notice));
}
$entry .= "</entry>\n";
$xs->elementEnd('body');
$xs->elementEnd('html');
$html = "\n<html xmlns='http://jabber.org/protocol/xhtml-im'>\n";
$html .= "<body xmlns='http://www.w3.org/1999/xhtml'>\n";
$html .= "<a href='".htmlspecialchars($profile->profileurl)."'>".$profile->nickname."</a>: ";
$html .= ($notice->rendered) ? $notice->rendered : common_render_content($notice->content, $notice);
$html .= "\n</body>\n";
$html .= "\n</html>\n";
$html = $xs->getString();
$address = "<addresses xmlns='http://jabber.org/protocol/address'>\n";
$address .= "<address type='replyto' jid='" . jabber_daemon_address() . "' />\n";
$address .= "</addresses>\n";
// FIXME: include a pubsub event, too.
return $html . $entry . $address;
return $html . ' ' . $entry;
}
/**

View File

@ -115,7 +115,7 @@ function get_all_languages() {
'he' => array('q' => 0.5, 'lang' => 'he_IL', 'name' => 'Hebrew', 'direction' => 'rtl'),
'it' => array('q' => 1, 'lang' => 'it_IT', 'name' => 'Italian', 'direction' => 'ltr'),
'jp' => array('q' => 0.5, 'lang' => 'ja_JP', 'name' => 'Japanese', 'direction' => 'ltr'),
'ko' => array('q' => 0.9, 'lang' => 'ko', 'name' => 'Korean', 'direction' => 'ltr'),
'ko' => array('q' => 0.9, 'lang' => 'ko_KR', 'name' => 'Korean', 'direction' => 'ltr'),
'mk' => array('q' => 0.5, 'lang' => 'mk_MK', 'name' => 'Macedonian', 'direction' => 'ltr'),
'nb' => array('q' => 0.1, 'lang' => 'nb_NO', 'name' => 'Norwegian (Bokmål)', 'direction' => 'ltr'),
'no' => array('q' => 0.1, 'lang' => 'nb_NO', 'name' => 'Norwegian (Bokmål)', 'direction' => 'ltr'),

View File

@ -70,16 +70,16 @@ class LoginGroupNav extends Widget
function show()
{
// action => array('prompt', 'title')
$menu =
array('login' =>
array(_('Login'),
_('Login with a username and password')),
'register' =>
array(_('Register'),
_('Sign up for a new account')),
'openidlogin' =>
array(_('OpenID'),
_('Login or register with OpenID')));
$menu = array();
$menu['login'] = array(_('Login'),
_('Login with a username and password'));
if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
$menu['register'] = array(_('Register'),
_('Sign up for a new account'));
}
$menu['openidlogin'] = array(_('OpenID'),
_('Login or register with OpenID'));
$action_name = $this->action->trimmed('action');
$this->action->elementStart('ul', array('class' => 'nav'));

View File

@ -132,20 +132,14 @@ class MessageForm extends Form
$mutual_users->free();
unset($mutual_users);
$this->out->elementStart('ul', 'form_data');
$this->out->elementStart('li', array('id' => 'notice_to'));
$this->out->dropdown('to', _('To'), $mutual, null, false,
($this->to) ? $this->to->id : null);
$this->out->elementEnd('li');
$this->out->elementStart('li', array('id' => 'notice_text'));
$this->out->element('textarea', array('id' => 'notice_data-text',
'cols' => 35,
'rows' => 4,
'name' => 'content'),
($this->content) ? $this->content : '');
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
}
/**
@ -156,14 +150,10 @@ class MessageForm extends Form
function formActions()
{
$this->out->elementStart('ul', 'form_actions');
$this->out->elementStart('li', array('id' => 'notice_submit'));
$this->out->element('input', array('id' => 'notice_action-submit',
'class' => 'submit',
'name' => 'message_send',
'type' => 'submit',
'value' => _('Send')));
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
}
}

View File

@ -134,9 +134,6 @@ class NoticeForm extends Form
function formData()
{
$this->out->elementStart('ul', 'form_data');
$this->out->elementStart('li', array('id' => 'notice_text'));
$this->out->element('label', array('for' => 'notice_data-text'),
sprintf(_('What\'s up, %s?'), $this->user->nickname));
// XXX: vary by defined max size
@ -145,8 +142,6 @@ class NoticeForm extends Form
'rows' => 4,
'name' => 'status_textarea'),
($this->content) ? $this->content : '');
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
$this->out->elementStart('dl', 'form_note');
$this->out->element('dt', null, _('Available characters'));
@ -168,14 +163,10 @@ class NoticeForm extends Form
function formActions()
{
$this->out->elementStart('ul', 'form_actions');
$this->out->elementStart('li', array('id' => 'notice_submit'));
$this->out->element('input', array('id' => 'notice_action-submit',
'class' => 'submit',
'name' => 'status_submit',
'type' => 'submit',
'value' => _('Send')));
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
}
}

View File

@ -68,8 +68,8 @@ class Router
}
}
function initialize() {
function initialize()
{
$m = Net_URL_Mapper::getInstance();
// In the "root"
@ -136,14 +136,17 @@ class Router
foreach (array('group', 'people', 'notice') as $s) {
$m->connect('search/'.$s, array('action' => $s.'search'));
$m->connect('search/'.$s.'?q=:q', array('action' => $s.'search'),array('q' => '.+'));
$m->connect('search/'.$s.'?q=:q',
array('action' => $s.'search'),
array('q' => '.+'));
}
// The second of these is needed to make the link work correctly
// when inserted into the page. The first is needed to match the
// route on the way in. Seems to be another Net_URL_Mapper bug to me.
$m->connect('search/notice/rss', array('action' => 'noticesearchrss'));
$m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'),array('q' => '.+'));
$m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'),
array('q' => '.+'));
// notice
@ -263,8 +266,8 @@ class Router
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
$m->connect('api/direct_messages/sent.'.$e,
array('action' => 'api',
'apiaction' => 'direct_messages',
'method' => 'sent.'.$e));
'apiaction' => 'direct_messages',
'method' => 'sent.'.$e));
}
$m->connect('api/direct_messages/destroy/:argument',
@ -328,9 +331,9 @@ class Router
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
$m->connect('api/favorites.'.$e,
array('action' => 'api',
'apiaction' => 'favorites',
'method' => 'favorites.'.$e));
array('action' => 'api',
'apiaction' => 'favorites',
'method' => 'favorites.'.$e));
}
// notifications
@ -415,7 +418,7 @@ class Router
$match = $this->m->match($path);
} catch (Net_URL_Mapper_InvalidException $e) {
common_log(LOG_ERR, "Problem getting route for $path - " .
$e->getMessage());
$e->getMessage());
$cac = new ClientErrorAction("Page not found.", 404);
$cac->showPage();
}
@ -438,10 +441,11 @@ class Router
// Due to a bug in the Net_URL_Mapper code, the returned URL may
// contain a malformed query of the form ?p1=v1?p2=v2?p3=v3. We
// repair that here rather than modifying the upstream code...
$qpos = strpos($url,'?');
$qpos = strpos($url, '?');
if ($qpos !== false) {
$url = substr($url, 0, $qpos+1) .
str_replace('?', '&', substr($url, $qpos+1));
str_replace('?', '&', substr($url, $qpos+1));
}
return $url;
}

View File

@ -94,11 +94,11 @@ class Rss10Action extends Action
function handle($args)
{
// Get the list of notices
$this->notices = $this->getNotices();
// Parent handling, including cache check
parent::handle($args);
$this->showRss($this->limit);
// Get the list of notices
$this->notices = $this->getNotices($this->limit);
$this->showRss();
}
/**
@ -132,15 +132,13 @@ class Rss10Action extends Action
return null;
}
function showRss($limit=0)
function showRss()
{
$notices = $this->getNotices($limit);
$this->initRss();
$this->showChannel($notices);
$this->showChannel();
$this->showImage();
foreach ($notices as $n) {
foreach ($this->notices as $n) {
$this->showItem($n);
}
@ -148,7 +146,7 @@ class Rss10Action extends Action
$this->endRss();
}
function showChannel($notices)
function showChannel()
{
$channel = $this->getChannel();
@ -167,7 +165,7 @@ class Rss10Action extends Action
$this->elementStart('items');
$this->elementStart('rdf:Seq');
foreach ($notices as $notice) {
foreach ($this->notices as $notice) {
$this->element('sioct:MicroblogPost', array('rdf:resource' => $notice->uri));
}

View File

@ -238,21 +238,6 @@ class TwitterapiAction extends Action
$this->elementEnd('item');
}
function show_twitter_atom_entry($entry)
{
$this->elementStart('entry');
$this->element('title', null, $entry['title']);
$this->element('content', array('type' => 'html'), $entry['content']);
$this->element('id', null, $entry['id']);
$this->element('published', null, $entry['published']);
$this->element('updated', null, $entry['updated']);
$this->element('link', array('href' => $entry['link'], 'rel' => 'alternate', 'type' => 'text/html'), null);
$this->elementStart('author');
$this->element('name', null, $entry['author']);
$this->elementEnd('author');
$this->elementEnd('entry');
}
function show_json_objects($objects)
{
print(json_encode($objects));
@ -383,7 +368,7 @@ class TwitterapiAction extends Action
}
if (!is_null($selfuri)) {
$this->element('link', array('href' => $selfuri,
$this->element('link', array('href' => $selfuri,
'rel' => 'self', 'type' => 'application/atom+xml'), null);
}
@ -392,13 +377,11 @@ class TwitterapiAction extends Action
if (is_array($notice)) {
foreach ($notice as $n) {
$entry = $this->twitter_rss_entry_array($n);
$this->show_twitter_atom_entry($entry);
$this->raw($n->asAtomEntry());
}
} else {
while ($notice->fetch()) {
$entry = $this->twitter_rss_entry_array($notice);
$this->show_twitter_atom_entry($entry);
$this->raw($notice->asAtomEntry());
}
}
@ -578,13 +561,16 @@ class TwitterapiAction extends Action
function init_twitter_atom()
{
$this->startXML();
$this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom', 'xml:lang' => 'en-US'));
// FIXME: don't hardcode the language here!
$this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom',
'xml:lang' => 'en-US',
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0'));
}
function end_twitter_atom()
{
$this->endXML();
$this->elementEnd('feed');
$this->endXML();
}
function show_profile($profile, $content_type='xml', $notice=null)

View File

@ -850,7 +850,7 @@ function common_redirect($url, $code=307)
303 => "See Other",
307 => "Temporary Redirect");
header("Status: ${code} $status[$code]");
header('HTTP/1.1 '.$code.' '.$status[$code]);
header("Location: $url");
$xo = new XMLOutputter();

View File

@ -105,12 +105,13 @@ class LinkbackPlugin extends Plugin
$pb = $match[1];
}
$tb = $this->getTrackback($result->body, $result->final_url);
if (!empty($tb)) {
$this->trackback($result->final_url, $tb);
} else if (!empty($pb)) {
if (!empty($pb)) {
$this->pingback($result->final_url, $pb);
} else {
$tb = $this->getTrackback($result->body, $result->final_url);
if (!empty($tb)) {
$this->trackback($result->final_url, $tb);
}
}
return $orig;

View File

@ -0,0 +1,104 @@
<?php
/**
* Laconica, the distributed open-source microblogging tool
*
* Plugin to use Piwik Analytics
*
* 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 Plugin
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
* @copyright 2008 Control Yourself, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://laconi.ca/
*/
if (!defined('LACONICA')) {
exit(1);
}
/**
* Plugin to use Piwik Analytics (based on the Google Analytics plugin by Evan)
*
* This plugin will spoot out the correct JavaScript spell to invoke
* Piwik Analytics on a page.
*
* To use this plugin please add the following three lines to your config.php
*
* require_once('plugins/PiwikAnalyticsPlugin.php');
* $pa = new PiwikAnalyticsPlugin("example.com/piwik/","id");
*
* exchange example.com/piwik/ with the url to your piwik installation and
* make sure you don't forget the final /
* exchange id with the ID your laconica installation has in your Piwik analytics
*
* @category Plugin
* @package Laconica
* @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://laconi.ca/
*
* @see Event
*/
class PiwikAnalyticsPlugin extends Plugin
{
/** the base of your Piwik installation */
var $piwikroot = null;
/** the Piwik Id of your laconica installation */
var $piwikId = null;
/**
* constructor
*
* @param string $root Piwik root URL
* @param string $id Piwik ID of this app
*/
function __construct($root=null, $id=null)
{
$this->piwikroot = $root;
$this->piwikid = $id;
parent::__construct();
}
/**
* Called when all scripts have been shown
*
* @param Action $action Current action
*
* @return boolean ignored
*/
function onEndShowScripts($action)
{
$js1 = 'var pkBaseURL = (("https:" == document.location.protocol) ? "https://'.
$this->piwikroot.'" : "http://'.$this->piwikroot.
'"); document.write(unescape("%3Cscript src=\'" + pkBaseURL + "piwik.js\''.
' type=\'text/javascript\'%3E%3C/script%3E"));';
$js2 = 'piwik_action_name = ""; piwik_idsite = '.$this->piwikid.
'; piwik_url = pkBaseURL + "piwik.php"; piwik_log(piwik_action_name, piwik_idsite, piwik_url);';
$action->elementStart('script', array('type' => 'text/javascript'));
$action->raw($js1);
$action->elementEnd('script');
$action->elementStart('script', array('type' => 'text/javascript'));
$action->raw($js2);
$action->elementEnd('script');
return true;
}
}

View File

@ -150,7 +150,9 @@ font-weight:bold;
#form_openid_login legend,
#form_search legend,
#form_invite legend,
#form_notice_delete legend {
#form_notice_delete legend,
#form_password_recover legend,
#form_password_change legend {
display:none;
}
@ -214,6 +216,9 @@ margin-right:0;
address .fn {
font-weight:bold;
}
address img + .fn {
display:none;
}
#header {
width:100%;
@ -419,6 +424,7 @@ padding:0;
display:none;
}
#form_notice textarea {
float:left;
border-radius:7px;
-moz-border-radius:7px;
-webkit-border-radius:7px;
@ -429,30 +435,19 @@ padding:7px 7px 16px 7px;
}
#form_notice label {
display:block;
float:left;
font-size:1.3em;
margin-bottom:7px;
}
#form_notice .form_data li {
float:left;
}
#form_notice #notice_attach_file label,
#form_notice #notice_submit label {
display:none;
}
#form_notice #notice_attachment {
margin-top:25px;
margin-left:4px;
}
#form_notice .form_note {
position:absolute;
top:99px;
right:98px;
z-index:9;
}
#form_notice .form_note dt {
font-weight:bold;
display:none;
@ -462,42 +457,19 @@ font-weight:bold;
line-height:1.15;
padding:1px 2px;
}
#form_notice #notice_data-attach_view {
position:absolute;
top:25px;
right:30px;
margin-left:4px;
padding:0;
width:16px;
height:16px;
border:0;
text-indent:-9999px;
}
#form_notice .form_actions {
#form_notice #notice_action-submit {
width:60px;
padding:8px;
position:absolute;
bottom:0;
right:0;
}
#form_notice .form_actions input.submit {
width:60px;
padding:8px;
}
#form_notice li {
margin-bottom:0;
}
#form_notice #notice_to {
margin-bottom:7px;
}
#notice_to label {
float:left;
margin-right:18px;
#form_notice label[for=to] {
margin-top:11px;
}
#notice_to select {
#form_notice select[id=to] {
margin-bottom:7px;
margin-left:18px;
float:left;
}
/*end FORM NOTICE*/

View File

@ -9,3 +9,6 @@ margin-left:0;
.entity_profile .entity_depiction {
margin-bottom:123px;
}
.notice div.entry-content {
width:63%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

View File

@ -19,9 +19,6 @@ font-size:1em;
address {
margin-right:71px;
}
address .fn {
display:none;
}
input, textarea, select, option {
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
@ -94,6 +91,11 @@ color:#333;
#form_notice.warning #notice_text-count {
color:#000;
}
#form_notice.processing #notice_action-submit {
background:#fff url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%;
cursor:wait;
text-indent:-9999px;
}
#nav_register a {

View File

@ -19,9 +19,6 @@ font-size:1em;
address {
margin-right:71px;
}
address .fn {
display:none;
}
input, textarea, select, option {
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
@ -94,7 +91,11 @@ color:#333;
#form_notice.warning #notice_text-count {
color:#000;
}
#form_notice.processing #notice_action-submit {
background:#fff url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%;
cursor:wait;
text-indent:-9999px;
}
#nav_register a {
text-decoration:none;