diff --git a/actions/avatarsettings.php b/actions/avatarsettings.php
index c2bb35a395..38e3103f4a 100644
--- a/actions/avatarsettings.php
+++ b/actions/avatarsettings.php
@@ -382,13 +382,7 @@ class AvatarsettingsAction extends AccountSettingsAction
function showStylesheets()
{
parent::showStylesheets();
- $jcropStyle =
- common_path('theme/base/css/jquery.Jcrop.css?version='.LACONICA_VERSION);
-
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => $jcropStyle,
- 'media' => 'screen, projection, tv'));
+ $this->cssLink('css/jquery.Jcrop.css','base','screen, projection, tv');
}
/**
@@ -402,13 +396,8 @@ class AvatarsettingsAction extends AccountSettingsAction
parent::showScripts();
if ($this->mode == 'crop') {
- $jcropPack = common_path('js/jcrop/jquery.Jcrop.pack.js');
- $jcropGo = common_path('js/jcrop/jquery.Jcrop.go.js');
-
- $this->element('script', array('type' => 'text/javascript',
- 'src' => $jcropPack));
- $this->element('script', array('type' => 'text/javascript',
- 'src' => $jcropGo));
+ $this->script('js/jcrop/jquery.Jcrop.pack.js');
+ $this->script('js/jcrop/jquery.Jcrop.go.js');
}
}
}
diff --git a/actions/finishopenidlogin.php b/actions/finishopenidlogin.php
index ff0b35218f..ba1e933e3e 100644
--- a/actions/finishopenidlogin.php
+++ b/actions/finishopenidlogin.php
@@ -217,7 +217,7 @@ class FinishopenidloginAction extends Action
if (!Validate::string($nickname, array('min_length' => 1,
'max_length' => 64,
- 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+ 'format' => NICKNAME_FMT))) {
$this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.'));
return;
}
@@ -389,7 +389,7 @@ class FinishopenidloginAction extends Action
{
if (!Validate::string($str, array('min_length' => 1,
'max_length' => 64,
- 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+ 'format' => NICKNAME_FMT))) {
return false;
}
if (!User::allowed_nickname($str)) {
diff --git a/actions/grouplogo.php b/actions/grouplogo.php
index 8f6158daca..5edb10cf8a 100644
--- a/actions/grouplogo.php
+++ b/actions/grouplogo.php
@@ -428,13 +428,7 @@ class GrouplogoAction extends GroupDesignAction
function showStylesheets()
{
parent::showStylesheets();
- $jcropStyle =
- common_path('theme/base/css/jquery.Jcrop.css?version='.LACONICA_VERSION);
-
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => $jcropStyle,
- 'media' => 'screen, projection, tv'));
+ $this->cssLink('css/jquery.Jcrop.css','base','screen, projection, tv');
}
/**
@@ -448,13 +442,8 @@ class GrouplogoAction extends GroupDesignAction
parent::showScripts();
if ($this->mode == 'crop') {
- $jcropPack = common_path('js/jcrop/jquery.Jcrop.pack.js');
- $jcropGo = common_path('js/jcrop/jquery.Jcrop.go.js');
-
- $this->element('script', array('type' => 'text/javascript',
- 'src' => $jcropPack));
- $this->element('script', array('type' => 'text/javascript',
- 'src' => $jcropGo));
+ $this->script('js/jcrop/jquery.Jcrop.pack.js');
+ $this->script('js/jcrop/jquery.Jcrop.go.js');
}
}
diff --git a/actions/profilesettings.php b/actions/profilesettings.php
index fb847680b9..d8fb2c9bb1 100644
--- a/actions/profilesettings.php
+++ b/actions/profilesettings.php
@@ -189,7 +189,7 @@ class ProfilesettingsAction extends AccountSettingsAction
// Some validation
if (!Validate::string($nickname, array('min_length' => 1,
'max_length' => 64,
- 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+ 'format' => NICKNAME_FMT))) {
$this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.'));
return;
} else if (!User::allowed_nickname($nickname)) {
diff --git a/actions/twitapistatuses.php b/actions/twitapistatuses.php
index c9943698dc..185129d5ee 100644
--- a/actions/twitapistatuses.php
+++ b/actions/twitapistatuses.php
@@ -449,7 +449,8 @@ class TwitapistatusesAction extends TwitterapiAction
function friends($args, $apidata)
{
parent::handle($args);
- return $this->subscriptions($apidata, 'subscribed', 'subscriber');
+ $includeStatuses=! (boolean) $args['lite'];
+ return $this->subscriptions($apidata, 'subscribed', 'subscriber', false, $includeStatuses);
}
function friendsIDs($args, $apidata)
@@ -461,7 +462,8 @@ class TwitapistatusesAction extends TwitterapiAction
function followers($args, $apidata)
{
parent::handle($args);
- return $this->subscriptions($apidata, 'subscriber', 'subscribed');
+ $includeStatuses=! (boolean) $args['lite'];
+ return $this->subscriptions($apidata, 'subscriber', 'subscribed', false, $includeStatuses);
}
function followersIDs($args, $apidata)
@@ -470,7 +472,7 @@ class TwitapistatusesAction extends TwitterapiAction
return $this->subscriptions($apidata, 'subscriber', 'subscribed', true);
}
- function subscriptions($apidata, $other_attr, $user_attr, $onlyIDs=false)
+ function subscriptions($apidata, $other_attr, $user_attr, $onlyIDs=false, $includeStatuses=true)
{
$this->auth_user = $apidata['user'];
$user = $this->get_user($apidata['api_arg'], $apidata);
@@ -526,26 +528,26 @@ class TwitapistatusesAction extends TwitterapiAction
if ($onlyIDs) {
$this->showIDs($others, $type);
} else {
- $this->show_profiles($others, $type);
+ $this->show_profiles($others, $type, $includeStatuses);
}
$this->end_document($type);
}
- function show_profiles($profiles, $type)
+ function show_profiles($profiles, $type, $includeStatuses)
{
switch ($type) {
case 'xml':
$this->elementStart('users', array('type' => 'array'));
foreach ($profiles as $profile) {
- $this->show_profile($profile);
+ $this->show_profile($profile,$type,null,$includeStatuses);
}
$this->elementEnd('users');
break;
case 'json':
$arrays = array();
foreach ($profiles as $profile) {
- $arrays[] = $this->twitter_user_array($profile, true);
+ $arrays[] = $this->twitter_user_array($profile, $includeStatuses);
}
print json_encode($arrays);
break;
diff --git a/actions/updateprofile.php b/actions/updateprofile.php
index d8b62fb090..f6cb277aa7 100644
--- a/actions/updateprofile.php
+++ b/actions/updateprofile.php
@@ -79,7 +79,7 @@ class UpdateprofileAction extends Action
$nickname = $req->get_parameter('omb_listenee_nickname');
if ($nickname && !Validate::string($nickname, array('min_length' => 1,
'max_length' => 64,
- 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+ 'format' => NICKNAME_FMT))) {
$this->clientError(_('Nickname must have only lowercase letters and numbers and no spaces.'));
return false;
}
diff --git a/actions/userauthorization.php b/actions/userauthorization.php
index 8dc2c808d6..00903ae01a 100644
--- a/actions/userauthorization.php
+++ b/actions/userauthorization.php
@@ -481,7 +481,7 @@ class UserauthorizationAction extends Action
$nickname = $_GET['omb_listenee_nickname'];
if (!Validate::string($nickname, array('min_length' => 1,
'max_length' => 64,
- 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+ 'format' => NICKNAME_FMT))) {
throw new OAuthException('Nickname must have only letters and numbers and no spaces.');
}
$profile = $_GET['omb_listenee_profile'];
diff --git a/db/notice_source.sql b/db/notice_source.sql
index 983ea91502..f590d1b97a 100644
--- a/db/notice_source.sql
+++ b/db/notice_source.sql
@@ -22,6 +22,8 @@ VALUES
('IdentiFox','IdentiFox','http://www.bitbucket.org/uncryptic/identifox/', now()),
('identitwitch','IdentiTwitch','http://richfish.org/identitwitch/', now()),
('LaTwit','LaTwit','http://latwit.mac65.com/', now()),
+ ('LiveTweeter', 'LiveTweeter', 'http://addons.songbirdnest.com/addon/1204', now()),
+ ('livetweeter', 'livetweeter', 'http://addons.songbirdnest.com/addon/1204', now()),
('maisha', 'Maisha', 'http://maisha.grango.org/', now()),
('mbpidgin','mbpidgin','http://code.google.com/p/microblog-purple/', now()),
('Mobidentica', 'Mobidentica', 'http://www.substanceofcode.com/software/mobidentica/', now()),
@@ -34,6 +36,7 @@ VALUES
('pocketwit','PockeTwit','http://code.google.com/p/pocketwit/', now()),
('posty','Posty','http://spreadingfunkyness.com/posty/', now()),
('qtwitter','qTwitter','http://qtwitter.ayoy.net/', now()),
+ ('qwit', 'Qwit', 'http://code.google.com/p/qwit/', now()),
('royalewithcheese','Royale With Cheese','http://p.hellyeah.org/', now()),
('rssdent','rssdent','http://github.com/zcopley/rssdent/tree/master', now()),
('rygh.no','rygh.no','http://rygh.no/', now()),
diff --git a/install.php b/install.php
index 227f99789a..ea21356518 100644
--- a/install.php
+++ b/install.php
@@ -383,9 +383,7 @@ function runDbScript($filename, $conn, $type='mysql')
?>
xml version="1.0" encoding="UTF-8" "; ?>
-
+
Install Laconica
diff --git a/lib/action.php b/lib/action.php
index a5244371a5..1c6170693f 100644
--- a/lib/action.php
+++ b/lib/action.php
@@ -193,21 +193,12 @@ class Action extends HTMLOutputter // lawsuit
if (Event::handle('StartShowStyles', array($this))) {
if (Event::handle('StartShowLaconicaStyles', array($this))) {
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => theme_path('css/display.css', null) . '?version=' . LACONICA_VERSION,
- 'media' => 'screen, projection, tv'));
+ $this->cssLink('css/display.css',null,'screen, projection, tv');
if (common_config('site', 'mobile')) {
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => theme_path('css/mobile.css', 'base') . '?version=' . LACONICA_VERSION,
- // TODO: "handheld" CSS for other mobile devices
- 'media' => 'only screen and (max-device-width: 480px)')); // Mobile WebKit
+ // TODO: "handheld" CSS for other mobile devices
+ $this->cssLink('css/mobile.css','base','only screen and (max-device-width: 480px)'); // Mobile WebKit
}
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => theme_path('css/print.css', 'base') . '?version=' . LACONICA_VERSION,
- 'media' => 'print'));
+ $this->cssLink('css/print.css','base','print');
Event::handle('EndShowLaconicaStyles', array($this));
}
@@ -253,26 +244,14 @@ class Action extends HTMLOutputter // lawsuit
{
if (Event::handle('StartShowScripts', array($this))) {
if (Event::handle('StartShowJQueryScripts', array($this))) {
- $this->element('script', array('type' => 'text/javascript',
- 'src' => common_path('js/jquery.min.js')),
- ' ');
- $this->element('script', array('type' => 'text/javascript',
- 'src' => common_path('js/jquery.form.js')),
- ' ');
-
- $this->element('script', array('type' => 'text/javascript',
- 'src' => common_path('js/jquery.joverlay.min.js')),
- ' ');
-
+ $this->script('js/jquery.min.js');
+ $this->script('js/jquery.form.js');
+ $this->script('js/jquery.joverlay.min.js');
Event::handle('EndShowJQueryScripts', array($this));
}
if (Event::handle('StartShowLaconicaScripts', array($this))) {
- $this->element('script', array('type' => 'text/javascript',
- 'src' => common_path('js/xbImportNode.js')),
- ' ');
- $this->element('script', array('type' => 'text/javascript',
- 'src' => common_path('js/util.js?version='.LACONICA_VERSION)),
- ' ');
+ $this->script('js/xbImportNode.js');
+ $this->script('js/util.js');
// Frame-busting code to avoid clickjacking attacks.
$this->element('script', array('type' => 'text/javascript'),
'if (window.top !== window.self) { window.top.location.href = window.self.location.href; }');
diff --git a/lib/designsettings.php b/lib/designsettings.php
index 1b0e621669..a48ec9d227 100644
--- a/lib/designsettings.php
+++ b/lib/designsettings.php
@@ -311,13 +311,7 @@ class DesignSettingsAction extends AccountSettingsAction
function showStylesheets()
{
parent::showStylesheets();
- $farbtasticStyle =
- common_path('theme/base/css/farbtastic.css?version='.LACONICA_VERSION);
-
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => $farbtasticStyle,
- 'media' => 'screen, projection, tv'));
+ $this->cssLink('css/farbtastic.css','base','screen, projection, tv');
}
/**
@@ -330,13 +324,8 @@ class DesignSettingsAction extends AccountSettingsAction
{
parent::showScripts();
- $farbtasticPack = common_path('js/farbtastic/farbtastic.js');
- $userDesignGo = common_path('js/userdesign.go.js');
-
- $this->element('script', array('type' => 'text/javascript',
- 'src' => $farbtasticPack));
- $this->element('script', array('type' => 'text/javascript',
- 'src' => $userDesignGo));
+ $this->script('js/farbtastic/farbtastic.js');
+ $this->script('js/farbtastic/farbtastic.go.js');
}
/**
diff --git a/lib/facebookaction.php b/lib/facebookaction.php
index 5be2f2fe66..ab11b613ed 100644
--- a/lib/facebookaction.php
+++ b/lib/facebookaction.php
@@ -95,34 +95,13 @@ class FacebookAction extends Action
function showStylesheets()
{
- // Add a timestamp to the file so Facebook cache wont ignore our changes
- $ts = filemtime(INSTALLDIR.'/theme/base/css/display.css');
-
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => theme_path('css/display.css', 'base') . '?ts=' . $ts));
-
- $theme = common_config('site', 'theme');
-
- $ts = filemtime(INSTALLDIR. '/theme/' . $theme .'/css/display.css');
-
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => theme_path('css/display.css', null) . '?ts=' . $ts));
-
- $ts = filemtime(INSTALLDIR.'/theme/base/css/facebookapp.css');
-
- $this->element('link', array('rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => theme_path('css/facebookapp.css', 'base') . '?ts=' . $ts));
+ $this->cssLink('css/display.css', 'base');
+ $this->cssLink('css/facebookapp.css', 'base');
}
function showScripts()
{
- // Add a timestamp to the file so Facebook cache wont ignore our changes
- $ts = filemtime(INSTALLDIR.'/js/facebookapp.js');
-
- $this->element('script', array('src' => common_path('js/facebookapp.js') . '?ts=' . $ts));
+ $this->script('js/facebookapp.js');
}
/**
diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php
index 06603ac054..f4445b44f8 100644
--- a/lib/htmloutputter.php
+++ b/lib/htmloutputter.php
@@ -109,10 +109,11 @@ class HTMLOutputter extends XMLOutputter
header('Content-Type: '.$type);
$this->extraHeaders();
-
- $this->startXML('html',
- '-//W3C//DTD XHTML 1.0 Strict//EN',
- 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd');
+ if( ! substr($type,0,strlen('text/html'))=='text/html' ){
+ // Browsers don't like it when xw->startDocument('1.0', 'UTF-8');
+ }
+ $this->xw->writeDTD('html', $public, $system);
$language = $this->getLanguage();
@@ -338,6 +339,55 @@ class HTMLOutputter extends XMLOutputter
'title' => $title));
}
+ /**
+ * output a script (almost always javascript) tag
+ *
+ * @param string $src relative or absolute script path
+ * @param string $type 'type' attribute value of the tag
+ *
+ * @return void
+ */
+ function script($src, $type='text/javascript')
+ {
+ $url = parse_url($src);
+ if(! ($url->scheme || $url->host || $url->query || $url->fragment))
+ {
+ $src = common_path($src) . '?version=' . LACONICA_VERSION;
+ }
+ $this->element('script', array('type' => $type,
+ 'src' => $src),
+ ' ');
+ }
+
+ /**
+ * output a css link
+ *
+ * @param string $src relative path within the theme directory, or an absolute path
+ * @param string $theme 'theme' that contains the stylesheet
+ * @param string media 'media' attribute of the tag
+ *
+ * @return void
+ */
+ function cssLink($src,$theme=null,$media=null)
+ {
+ if (!$theme) {
+ $theme = common_config('site', 'theme');
+ }
+ $url = parse_url($src);
+ if(! ($url->scheme || $url->host || $url->query || $url->fragment))
+ {
+ if(file_exists(theme_file($src,$theme))){
+ $src = theme_path($src, $theme) . '?version=' . LACONICA_VERSION;
+ }else{
+ $src = common_path($src);
+ }
+ }
+ $this->element('link', array('rel' => 'stylesheet',
+ 'type' => 'text/css',
+ 'href' => $src,
+ 'media' => $media));
+ }
+
/**
* output an HTML textarea and associated elements
*
diff --git a/lib/twitterapi.php b/lib/twitterapi.php
index 4115d9dcb4..4737c5874f 100644
--- a/lib/twitterapi.php
+++ b/lib/twitterapi.php
@@ -844,9 +844,9 @@ class TwitterapiAction extends Action
$this->endXML();
}
- function show_profile($profile, $content_type='xml', $notice=null)
+ function show_profile($profile, $content_type='xml', $notice=null, $includeStatuses=true)
{
- $profile_array = $this->twitter_user_array($profile, true);
+ $profile_array = $this->twitter_user_array($profile, $includeStatuses);
switch ($content_type) {
case 'xml':
$this->show_twitter_xml_user($profile_array);
diff --git a/plugins/Autocomplete/Autocomplete.js b/plugins/Autocomplete/Autocomplete.js
new file mode 100644
index 0000000000..759ed60ae9
--- /dev/null
+++ b/plugins/Autocomplete/Autocomplete.js
@@ -0,0 +1,19 @@
+$(document).ready(function(){
+ $.getJSON($('address .url')[0].href+'/api/statuses/friends.json?user_id=' + current_user['id'] + '&lite=true&callback=?',
+ function(friends){
+ $('#notice_data-text').autocomplete(friends, {
+ multiple: true,
+ multipleSeparator: " ",
+ formatItem: function(row, i, max){
+ return '@' + row.screen_name + ' (' + row.name + ')';
+ },
+ formatMatch: function(row, i, max){
+ return '@' + row.screen_name;
+ },
+ formatResult: function(row){
+ return '@' + row.screen_name;
+ }
+ });
+ }
+ );
+});
diff --git a/plugins/Autocomplete/AutocompletePlugin.php b/plugins/Autocomplete/AutocompletePlugin.php
new file mode 100644
index 0000000000..58b6a84cab
--- /dev/null
+++ b/plugins/Autocomplete/AutocompletePlugin.php
@@ -0,0 +1,63 @@
+.
+ *
+ * @category Plugin
+ * @package Laconica
+ * @author Craig Andrews
+ * @copyright 2009 Craig Andrews http://candrews.integralblue.com
+ * @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);
+}
+
+class AutocompletePlugin extends Plugin
+{
+ function __construct()
+ {
+ parent::__construct();
+ }
+
+ function onEndShowScripts($action){
+ if (common_logged_in()) {
+ $current_user = common_current_user();
+ $js_string = <<
+var current_user = { id: '$current_user->id' };
+
+EOT;
+ $action->raw($js_string);
+ $action->script('plugins/Autocomplete/jquery-autocomplete/jquery.autocomplete.pack.js');
+ $action->script('plugins/Autocomplete/Autocomplete.js');
+ }
+ }
+
+ function onEndShowLaconicaStyles($action)
+ {
+ if (common_logged_in()) {
+ $action->cssLink('plugins/Autocomplete/jquery-autocomplete/jquery.autocomplete.css');
+ }
+ }
+
+}
+?>
diff --git a/plugins/Autocomplete/jquery-autocomplete/changelog.txt b/plugins/Autocomplete/jquery-autocomplete/changelog.txt
new file mode 100644
index 0000000000..94cb5ccde7
--- /dev/null
+++ b/plugins/Autocomplete/jquery-autocomplete/changelog.txt
@@ -0,0 +1,20 @@
+1.0.2
+-----
+* Fixed missing semicolon
+
+1.0.1
+-----
+* Fixed element creation (