]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch '0.9.x' of gitorious.org:statusnet/mainline into 0.9.x
authorEvan Prodromou <evan@status.net>
Fri, 25 Feb 2011 20:56:40 +0000 (12:56 -0800)
committerEvan Prodromou <evan@status.net>
Fri, 25 Feb 2011 20:56:40 +0000 (12:56 -0800)
23 files changed:
actions/apistatusnetconfig.php
actions/backupaccount.php
actions/noticesearch.php
classes/Notice.php
lib/action.php
lib/router.php
lib/useractivitystream.php
lib/util.php
plugins/FacebookBridge/FacebookBridgePlugin.php
plugins/FacebookBridge/lib/facebookclient.php
plugins/MobileProfile/MobileProfilePlugin.php
plugins/TwitterBridge/twitterimport.php
scripts/backupuser.php
tests/HashTagDetectionTests.php
theme/cleaner/css/display.css [new file with mode: 0644]
theme/cleaner/css/ie.css [new file with mode: 0644]
theme/cleaner/css/mp-screen.css [new file with mode: 0644]
theme/cleaner/default-avatar-mini.png [new file with mode: 0644]
theme/cleaner/default-avatar-profile.png [new file with mode: 0644]
theme/cleaner/default-avatar-stream.png [new file with mode: 0644]
theme/cleaner/logo.png [new file with mode: 0644]
theme/cleaner/mobilelogo.png [new file with mode: 0644]
theme/cleaner/theme.ini [new file with mode: 0644]

index 771a95baec6e4d1f7603c7506b09e8a3a819e806..b34c6cc54415e1f0a4def0fa05ca37ebfea51deb 100644 (file)
@@ -59,7 +59,8 @@ class ApiStatusnetConfigAction extends ApiAction
         'notice' => array('contentlimit'),
         'throttle' => array('enabled', 'count', 'timespan'),
         'xmpp' => array('enabled', 'server', 'port', 'user'),
-        'integration' => array('source')
+        'integration' => array('source'),
+        'attachments' => array('uploads', 'file_quota')
     );
 
     /**
@@ -96,7 +97,7 @@ class ApiStatusnetConfigAction extends ApiAction
             foreach ($this->keys as $section => $settings) {
                 $this->elementStart($section);
                 foreach ($settings as $setting) {
-                    $value = common_config($section, $setting);
+                    $value = $this->setting($section, $setting);
                     if (is_array($value)) {
                         $value = implode(',', $value);
                     } else if ($value === false || $value == '0') {
@@ -125,7 +126,7 @@ class ApiStatusnetConfigAction extends ApiAction
                 $result[$section] = array();
                 foreach ($settings as $setting) {
                     $result[$section][$setting]
-                        = common_config($section, $setting);
+                        = $this->setting($section, $setting);
                 }
             }
             $this->initDocument('json');
@@ -143,6 +144,20 @@ class ApiStatusnetConfigAction extends ApiAction
         }
     }
 
+    function setting($section, $key) {
+        $result = common_config($section, $key);
+        if ($key == 'file_quota') {
+            // hack: adjust for the live upload limit
+            if (common_config($section, 'uploads')) {
+                $max = ImageFile::maxFileSizeInt();
+            } else {
+                $max = 0;
+            }
+            return min($result, $max);
+        }
+        return $result;
+    }
+
     /**
      * Return true if read only.
      *
index e32b8d03de317b7e2207f4b1b3f2b8dc4fa26edd..8f642f3b7708e61463237cfe74f80916fb955f3f 100644 (file)
@@ -118,11 +118,13 @@ class BackupaccountAction extends Action
     {
         $cur = common_current_user();
 
-        $stream = new UserActivityStream($cur);
+        $stream = new UserActivityStream($cur, true, UserActivityStream::OUTPUT_RAW);
 
         header('Content-Disposition: attachment; filename='.$cur->nickname.'.atom');
         header('Content-Type: application/atom+xml; charset=utf-8');
 
+        // @fixme atom feed logic is in getString...
+        // but we just want it to output to the outputter.
         $this->raw($stream->getString());
     }
 
index de1e7001f49fdae45731031114e2cbdeb477af3a..4f4c7a05ba35fdd510cf4c9d69f465595b101926 100644 (file)
@@ -202,13 +202,20 @@ class SearchNoticeListItem extends NoticeListItem {
         $options = implode('|', array_map('preg_quote', array_map('htmlspecialchars', $terms),
                                                             array_fill(0, sizeof($terms), '/')));
         $pattern = "/($options)/i";
-        $result  = preg_replace($pattern, '<strong>\\1</strong>', $text);
+        $result = '';
+
+        /* Divide up into text (highlight me) and tags (don't touch) */
+        $chunks = preg_split('/(<[^>]+>)/', $text, 0, PREG_SPLIT_DELIM_CAPTURE);
+        foreach ($chunks as $i => $chunk) {
+            if ($i % 2 == 1) {
+                // odd: delimiter (tag)
+                $result .= $chunk;
+            } else {
+                // even: freetext between tags
+                $result .= preg_replace($pattern, '<strong>\\1</strong>', $chunk);
+            }
+        }
 
-        /* Remove highlighting from inside links, loop incase multiple highlights in links */
-        $pattern = '/(\w+="[^"]*)<strong>('.$options.')<\/strong>([^"]*")/iU';
-        do {
-            $result = preg_replace($pattern, '\\1\\2\\3', $result, -1, $count);
-        } while ($count);
         return $result;
     }
 }
index 6b56a613db013b161099b3256013fb74e15a3887..a25991fa322fc779d17299fa5944ba2a7a9caaa8 100644 (file)
@@ -153,7 +153,7 @@ class Notice extends Memcached_DataObject
     function saveTags()
     {
         /* extract all #hastags */
-        $count = preg_match_all('/(?:^|\s)#([\pL\pN_\-\.]{1,64})/', strtolower($this->content), $match);
+        $count = preg_match_all('/(?:^|\s)#([\pL\pN_\-\.]{1,64})/u', strtolower($this->content), $match);
         if (!$count) {
             return true;
         }
index 26ebd20932247cb870d1c6f37326406c29a26812..173e2c2a5877491d690fc8813e6e00c05fed9956 100644 (file)
@@ -854,8 +854,11 @@ class Action extends HTMLOutputter // lawsuit
     function showFooter()
     {
         $this->elementStart('div', array('id' => 'footer'));
-        $this->showSecondaryNav();
-        $this->showLicenses();
+        if (Event::handle('StartShowInsideFooter', array($this))) {
+            $this->showSecondaryNav();
+            $this->showLicenses();
+            Event::handle('EndShowInsideFooter', array($this));
+        }
         $this->elementEnd('div');
     }
 
index a4547b325807d5d1b8d7c3f08e5b54d7aa4c0e97..e956b02c631067f56c2aaa01397cbb23a54b7fdd 100644 (file)
@@ -116,6 +116,8 @@ class Router
     static $bare = array('requesttoken', 'accesstoken', 'userauthorization',
                          'postnotice', 'updateprofile', 'finishremotesubscribe');
 
+    const REGEX_TAG = '[^\/]+'; // [\pL\pN_\-\.]{1,64} better if we can do unicode regexes
+
     static function get()
     {
         if (!Router::$inst) {
@@ -348,14 +350,14 @@ class Router
             $m->connect('tag', array('action' => 'publictagcloud'));
             $m->connect('tag/:tag/rss',
                         array('action' => 'tagrss'),
-                        array('tag' => '[\pL\pN_\-\.]{1,64}'));
+                        array('tag' => self::REGEX_TAG));
             $m->connect('tag/:tag',
                         array('action' => 'tag'),
-                        array('tag' => '[\pL\pN_\-\.]{1,64}'));
+                        array('tag' => self::REGEX_TAG));
 
             $m->connect('peopletag/:tag',
                         array('action' => 'peopletag'),
-                        array('tag' => '[a-zA-Z0-9]+'));
+                        array('tag' => self::REGEX_TAG));
 
             // groups
 
@@ -812,7 +814,7 @@ class Router
                     $m->connect($a.'/:tag',
                                 array('action' => $a,
                                       'nickname' => $nickname),
-                                array('tag' => '[a-zA-Z0-9]+'));
+                                array('tag' => self::REGEX_TAG));
                 }
 
                 foreach (array('rss', 'groups') as $a) {
@@ -839,12 +841,12 @@ class Router
                 $m->connect('tag/:tag/rss',
                             array('action' => 'userrss',
                                   'nickname' => $nickname),
-                            array('tag' => '[\pL\pN_\-\.]{1,64}'));
+                            array('tag' => self::REGEX_TAG));
 
                 $m->connect('tag/:tag',
                             array('action' => 'showstream',
                                   'nickname' => $nickname),
-                            array('tag' => '[\pL\pN_\-\.]{1,64}'));
+                            array('tag' => self::REGEX_TAG));
 
                 $m->connect('rsd.xml',
                             array('action' => 'rsd',
@@ -875,7 +877,7 @@ class Router
                 foreach (array('subscriptions', 'subscribers') as $a) {
                     $m->connect(':nickname/'.$a.'/:tag',
                                 array('action' => $a),
-                                array('tag' => '[a-zA-Z0-9]+',
+                                array('tag' => self::REGEX_TAG,
                                       'nickname' => Nickname::DISPLAY_FMT));
                 }
 
@@ -903,12 +905,12 @@ class Router
                 $m->connect(':nickname/tag/:tag/rss',
                             array('action' => 'userrss'),
                             array('nickname' => Nickname::DISPLAY_FMT),
-                            array('tag' => '[\pL\pN_\-\.]{1,64}'));
+                            array('tag' => self::REGEX_TAG));
 
                 $m->connect(':nickname/tag/:tag',
                             array('action' => 'showstream'),
                             array('nickname' => Nickname::DISPLAY_FMT),
-                            array('tag' => '[\pL\pN_\-\.]{1,64}'));
+                            array('tag' => self::REGEX_TAG));
 
                 $m->connect(':nickname/rsd.xml',
                             array('action' => 'rsd'),
index 53d0107aa957a575d1895e58dbcc39c1c1442366..d1e3e28fb8ed7afe555fc29f17beef69572f20d3 100644 (file)
@@ -29,15 +29,48 @@ class UserActivityStream extends AtomUserNoticeFeed
 {
     public $activities = array();
 
-    function __construct($user, $indent = true)
+    const OUTPUT_STRING = 1;
+    const OUTPUT_RAW = 2;
+    public $outputMode = self::OUTPUT_STRING;
+
+    /**
+     *
+     * @param User $user
+     * @param boolean $indent
+     * @param boolean $outputMode: UserActivityStream::OUTPUT_STRING to return a string,
+     *                           or UserActivityStream::OUTPUT_RAW to go to raw output.
+     *                           Raw output mode will attempt to stream, keeping less
+     *                           data in memory but will leave $this->activities incomplete.
+     */
+    function __construct($user, $indent = true, $outputMode = UserActivityStream::OUTPUT_STRING)
     {
         parent::__construct($user, null, $indent);
 
+        $this->outputMode = $outputMode;
+        if ($this->outputMode == self::OUTPUT_STRING) {
+            // String buffering? Grab all the notices now.
+            $notices = $this->getNotices();
+        } elseif ($this->outputMode == self::OUTPUT_RAW) {
+            // Raw output... need to restructure from the stringer init.
+            $this->xw = new XMLWriter();
+            $this->xw->openURI('php://output');
+            if(is_null($indent)) {
+                $indent = common_config('site', 'indent');
+            }
+            $this->xw->setIndent($indent);
+
+            // We'll fetch notices later.
+            $notices = array();
+        } else {
+            throw new Exception('Invalid outputMode provided to ' . __METHOD__);
+        }
+
+        // Assume that everything but notices is feasible
+        // to pull at once and work with in memory...
         $subscriptions = $this->getSubscriptions();
         $subscribers   = $this->getSubscribers();
         $groups        = $this->getGroups();
         $faves         = $this->getFaves();
-        $notices       = $this->getNotices();
 
         $objs = array_merge($subscriptions, $subscribers, $groups, $faves, $notices);
 
@@ -45,16 +78,44 @@ class UserActivityStream extends AtomUserNoticeFeed
 
         usort($objs, 'UserActivityStream::compareObject');
 
+        // We'll keep these around for later, and interleave them into
+        // the output stream with the user's notices.
         foreach ($objs as $obj) {
             $this->activities[] = $obj->asActivity();
         }
     }
 
+    /**
+     * Interleave the pre-sorted subs/groups/faves with the user's
+     * notices, all in reverse chron order.
+     */
     function renderEntries()
     {
+        $end = time() + 1;
         foreach ($this->activities as $act) {
+            $start = $act->time;
+
+            if ($this->outputMode == self::OUTPUT_RAW && $start != $end) {
+                // In raw mode, we haven't pre-fetched notices.
+                // Grab the chunks of notices between other activities.
+                $notices = $this->getNoticesBetween($start, $end);
+                foreach ($notices as $noticeAct) {
+                    $noticeAct->asActivity()->outputTo($this, false, false);
+                }
+            }
+
             // Only show the author sub-element if it's different from default user
             $act->outputTo($this, false, ($act->actor->id != $this->user->uri));
+
+            $end = $start;
+        }
+
+        if ($this->outputMode == self::OUTPUT_RAW) {
+            // Grab anything after the last pre-sorted activity.
+            $notices = $this->getNoticesBetween(0, $end);
+            foreach ($notices as $noticeAct) {
+                $noticeAct->asActivity()->outputTo($this, false, false);
+            }
         }
     }
 
@@ -121,7 +182,13 @@ class UserActivityStream extends AtomUserNoticeFeed
         return $faves;
     }
 
-    function getNotices()
+    /**
+     *
+     * @param int $start unix timestamp for earliest
+     * @param int $end unix timestamp for latest
+     * @return array of Notice objects
+     */
+    function getNoticesBetween($start=0, $end=0)
     {
         $notices = array();
 
@@ -129,6 +196,17 @@ class UserActivityStream extends AtomUserNoticeFeed
 
         $notice->profile_id = $this->user->id;
 
+        if ($start) {
+            $tsstart = common_sql_date($start);
+            $notice->whereAdd("created >= '$tsstart'");
+        }
+        if ($end) {
+            $tsend = common_sql_date($end);
+            $notice->whereAdd("created < '$tsend'");
+        }
+
+        $notice->orderBy('created DESC');
+
         if ($notice->find()) {
             while ($notice->fetch()) {
                 $notices[] = clone($notice);
@@ -138,6 +216,11 @@ class UserActivityStream extends AtomUserNoticeFeed
         return $notices;
     }
 
+    function getNotices()
+    {
+        return $this->getNoticesBetween();
+    }
+
     function getGroups()
     {
         $groups = array();
index 1e73ff9ac9b0c1428ef2c0b25d444476c54d5b05..f734062eced327cec4423eaf9732634778af207d 100644 (file)
@@ -787,7 +787,7 @@ function common_render_text($text)
 
     $r = preg_replace('/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}]/', '', $r);
     $r = common_replace_urls_callback($r, 'common_linkify');
-    $r = preg_replace('/(^|\&quot\;|\'|\(|\[|\{|\s+)#([\pL\pN_\-\.]{1,64})/e', "'\\1#'.common_tag_link('\\2')", $r);
+    $r = preg_replace('/(^|\&quot\;|\'|\(|\[|\{|\s+)#([\pL\pN_\-\.]{1,64})/ue', "'\\1#'.common_tag_link('\\2')", $r);
     // XXX: machine tags
     return $r;
 }
index 7e17c2d7ecf5d280b5e6981385a17c43ebb913d7..37b931e23ec98a4d238c9792a8c140716f1b4954 100644 (file)
@@ -179,28 +179,22 @@ class FacebookBridgePlugin extends Plugin
         // Always add the admin panel route
         $m->connect('admin/facebook', array('action' => 'facebookadminpanel'));
 
-        // Only add these routes if an application has been setup on
-        // Facebook for the plugin to use.
-        if ($this->hasApplication()) {
-
-            $m->connect(
-                'main/facebooklogin',
-                array('action' => 'facebooklogin')
-            );
-            $m->connect(
-                'main/facebookfinishlogin',
-                array('action' => 'facebookfinishlogin')
-            );
-            $m->connect(
-                'settings/facebook',
-                array('action' => 'facebooksettings')
-            );
-            $m->connect(
-                'facebook/deauthorize',
-                array('action' => 'facebookdeauthorize')
-            );
-
-        }
+        $m->connect(
+            'main/facebooklogin',
+            array('action' => 'facebooklogin')
+        );
+        $m->connect(
+            'main/facebookfinishlogin',
+            array('action' => 'facebookfinishlogin')
+        );
+        $m->connect(
+            'settings/facebook',
+            array('action' => 'facebooksettings')
+        );
+        $m->connect(
+            'facebook/deauthorize',
+            array('action' => 'facebookdeauthorize')
+        );
 
         return true;
     }
index 030a75caed1f084dde630a7a28b6ea9f077e09c1..516f252d98d7cdc185fc41a07665459d9677016d 100644 (file)
@@ -51,7 +51,14 @@ class Facebookclient
     function __construct($notice)
     {
         $this->facebook = self::getFacebook();
-        $this->notice   = $notice;
+
+        if (empty($this->facebook)) {
+            throw new FacebookApiException(
+                "Could not create Facebook client! Bad application ID or secret?"
+            );
+        }
+
+        $this->notice = $notice;
 
         $this->flink = Foreign_link::getByUserID(
             $notice->profile_id,
@@ -89,6 +96,22 @@ class Facebookclient
             $secret = common_config('facebook', 'global_secret');
         }
 
+        if (empty($appId)) {
+            common_log(
+                LOG_WARNING,
+                "Couldn't find Facebook application ID!",
+                __FILE__
+            );
+        }
+
+        if (empty($secret)) {
+            common_log(
+                LOG_WARNING,
+                "Couldn't find Facebook application ID!",
+                __FILE__
+            );
+        }
+
         return new Facebook(
             array(
                'appId'  => $appId,
@@ -174,6 +197,9 @@ class Facebookclient
                 return $this->sendGraph();
             }
         }
+
+        // dequeue
+        return true;
     }
 
     /*
index b9c25ab998913d65cbf79ca2794a6f07ff30f9fc..ec08fa1e2cbf1ee3ad5cc41c0d85883ed0dbb7a5 100644 (file)
@@ -68,6 +68,9 @@ class MobileProfilePlugin extends WAP20Plugin
             $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'])) {
 
             $this->serveMobile = true;
+        } else if (isset($_COOKIE['MobileOverride'])) {
+            // Cookie override is controlled by link at bottom.
+            $this->serveMobile = (bool)$_COOKIE['MobileOverride'];
         } else {
             // If they like the WAP 2.0 mimetype, serve them MP
             // @fixme $type is undefined, making this if case useless and spewing errors.
@@ -381,9 +384,40 @@ class MobileProfilePlugin extends WAP20Plugin
         }
     }
 
-    function onStartShowScripts($action)
+    function onEndShowScripts($action)
     {
+        $action->inlineScript('
+            $(function() {
+                $("#mobile-toggle-disable").click(function() {
+                    $.cookie("MobileOverride", "0", {path: "/"});
+                    window.location.reload();
+                    return false;
+                });
+                $("#mobile-toggle-enable").click(function() {
+                    $.cookie("MobileOverride", "1", {path: "/"});
+                    window.location.reload();
+                    return false;
+                });
+            });'
+        );
+    }
 
+
+    function onEndShowInsideFooter($action)
+    {
+        if ($this->serveMobile) {
+            // TRANS: Link to switch site layout from mobile to desktop mode. Appears at very bottom of page.
+            $linkText = _m('Switch to desktop site layout.');
+            $key = 'mobile-toggle-disable';
+        } else {
+            // TRANS: Link to switch site layout from desktop to mobile mode. Appears at very bottom of page.
+            $linkText = _m('Switch to mobile site layout.');
+            $key = 'mobile-toggle-enable';
+        }
+        $action->elementStart('p');
+        $action->element('a', array('href' => '#', 'id' => $key), $linkText);
+        $action->elementEnd('p');
+        return true;
     }
 
     function _common_path($relative, $ssl=false)
index 475a99efac69d3ab81ed88d88c65152f9780f830..5ddf5380d745128a2057a6085bb1a01435b1bb74 100644 (file)
@@ -554,8 +554,8 @@ class TwitterImport
         }
 
         // Move all the entities into order so we can
-        // replace them in reverse order and thus
-        // not mess up their indices
+        // replace them and escape surrounding plaintext
+        // in order
 
         $toReplace = array();
 
@@ -577,56 +577,85 @@ class TwitterImport
             }
         }
 
-        // sort in reverse order by key
+        // sort in forward order by key
 
-        krsort($toReplace);
+        ksort($toReplace);
+
+        $result = '';
+        $cursor = 0;
 
         foreach ($toReplace as $part) {
             list($type, $object) = $part;
+            $start = $object->indices[0];
+            $end = $object->indices[1];
+            if ($cursor < $start) {
+                // Copy in the preceding plaintext
+                $result .= $this->twitEscape(mb_substr($text, $cursor, $start - $cursor));
+                $cursor = $start;
+            }
+            $orig = $this->twitEscape(mb_substr($text, $start, $end - $start));
             switch($type) {
             case self::URL:
-                $linkText = $this->makeUrlLink($object);
+                $linkText = $this->makeUrlLink($object, $orig);
                 break;
             case self::HASHTAG:
-                $linkText = $this->makeHashtagLink($object);
+                $linkText = $this->makeHashtagLink($object, $orig);
                 break;
             case self::MENTION:
-                $linkText = $this->makeMentionLink($object);
+                $linkText = $this->makeMentionLink($object, $orig);
                 break;
             default:
+                $linkText = $orig;
                 continue;
             }
-            $text = mb_substr($text, 0, $object->indices[0]) . $linkText . mb_substr($text, $object->indices[1]);
+            $result .= $linkText;
+            $cursor = $end;
         }
-        return $text;
+        $last = $this->twitEscape(mb_substr($text, $cursor));
+        $result .= $last;
+
+        return $result;
+    }
+
+    function twitEscape($str)
+    {
+        // Twitter seems to preemptive turn < and > into &lt; and &gt;
+        // but doesn't for &, so while you may have some magic protection
+        // against XSS by not bothing to escape manually, you still get
+        // invalid XHTML. Thanks!
+        //
+        // Looks like their web interface pretty much sends anything
+        // through intact, so.... to do equivalent, decode all entities
+        // and then re-encode the special ones.
+        return htmlspecialchars(html_entity_decode($str, ENT_COMPAT, 'UTF-8'));
     }
 
-    function makeUrlLink($object)
+    function makeUrlLink($object, $orig)
     {
-        return "<a href='{$object->url}' class='extlink'>{$object->url}</a>";
+        return "<a href='{$object->url}' class='extlink'>{$orig}</a>";
     }
 
-    function makeHashtagLink($object)
+    function makeHashtagLink($object, $orig)
     {
-        return "#" . self::tagLink($object->text);
+        return "#" . self::tagLink($object->text, substr($orig, 1));
     }
 
-    function makeMentionLink($object)
+    function makeMentionLink($object, $orig)
     {
-        return "@".self::atLink($object->screen_name, $object->name);
+        return "@".self::atLink($object->screen_name, $object->name, substr($orig, 1));
     }
 
-    static function tagLink($tag)
+    static function tagLink($tag, $orig)
     {
-        return "<a href='https://search.twitter.com/search?q=%23{$tag}' class='hashtag'>{$tag}</a>";
+        return "<a href='https://search.twitter.com/search?q=%23{$tag}' class='hashtag'>{$orig}</a>";
     }
 
-    static function atLink($screenName, $fullName=null)
+    static function atLink($screenName, $fullName, $orig)
     {
         if (!empty($fullName)) {
-            return "<a href='http://twitter.com/#!/{$screenName}' title='{$fullName}'>{$screenName}</a>";
+            return "<a href='http://twitter.com/#!/{$screenName}' title='{$fullName}'>{$orig}</a>";
         } else {
-            return "<a href='http://twitter.com/#!/{$screenName}'>{$screenName}</a>";
+            return "<a href='http://twitter.com/#!/{$screenName}'>{$orig}</a>";
         }
     }
 
index 49fc1cefdc68cbc2648c1de7065386798b6e9100..ee2951fc8f146609dfb8cfdbcea071e96202666c 100644 (file)
@@ -36,7 +36,7 @@ require_once INSTALLDIR.'/scripts/commandline.inc';
 
 try {
     $user = getUser();
-    $actstr = new UserActivityStream($user);
+    $actstr = new UserActivityStream($user, true, UserActivityStream::OUTPUT_RAW);
     print $actstr->getString();
 } catch (Exception $e) {
     print $e->getMessage()."\n";
index 483d7135e1592b2e9656d037b12fa130b667f695..47031d5bc41bae3ea77292a93cbd4e1755e7020b 100644 (file)
@@ -42,6 +42,21 @@ class HashTagDetectionTests extends PHPUnit_Framework_TestCase
                            'say {#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span>} people'),
                      array('say \'#hello\' people',
                            'say \'#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span>\' people'),
+
+                     // Unicode legit letters
+                     array('#éclair yummy',
+                           '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('éclair'))) . '" rel="tag">éclair</a></span> yummy'),
+                     array('#维基百科 zh.wikipedia!',
+                           '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('维基百科'))) . '" rel="tag">维基百科</a></span> zh.wikipedia!'),
+                     array('#Россия russia',
+                           '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('Россия'))) . '" rel="tag">Россия</a></span> russia'),
+
+                     // Unicode punctuators -- the ideographic "," separates the tag, just as "," does
+                     array('#维基百科,zh.wikipedia!',
+                           '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('维基百科'))) . '" rel="tag">维基百科</a></span>,zh.wikipedia!'),
+                     array('#维基百科,zh.wikipedia!',
+                           '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('维基百科'))) . '" rel="tag">维基百科</a></span>,zh.wikipedia!'),
+
                      );
     }
 }
diff --git a/theme/cleaner/css/display.css b/theme/cleaner/css/display.css
new file mode 100644 (file)
index 0000000..8d27c64
--- /dev/null
@@ -0,0 +1,810 @@
+/** theme: cleaner
+ *
+ * @package   StatusNet
+ * @author    Samantha Doherty <sammy@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license   http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution 3.0 Unported
+ * @link      http://status.net/
+ */
+
+
+@media screen, projection, tv {
+
+body {
+    background-color: #e2e2e2;
+    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 
+    font-size: 82%;
+}
+
+a {color: #3e3e8c;}
+
+h1 {font-size: 1.6em;}
+h2 {font-size: 1.6em;}
+h3 {font-size: 1.4em;}
+h4 {font-size: 1.4em;}
+h5 {font-size: 1.2em;}
+h6 {font-size: 1em;}
+
+#wrap {
+    width: 940px;
+    margin: 0px auto;
+    padding: 0px 10px 10px 10px;
+    background-color: #fff;
+    box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5);
+    -moz-box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5);
+    -webkit-box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5);
+}
+
+#header {
+    width: 940px;
+    padding: 0px;
+    padding-top: 50px;
+}
+
+address {
+    float: left;
+    margin-right: 20px;
+    margin-top: 0px;
+}
+
+.poweredby {
+    background: url(../images/sn-tiny.png) no-repeat top left;
+    height: 40px;
+    font-size: 0.8em;
+    color: #fff;
+    line-height: 42px;
+    padding-left: 50px;
+    position: absolute;
+    top: 6px;
+    left: 0;
+    z-index: 99;
+    font-style: normal;
+}
+
+.poweredby a {
+    color: #fff !important;
+    font-weight: bold;
+}
+
+#site_nav_global_primary {
+    display: block;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 98;
+    background-color: #364A84;
+    width: 960px;
+    margin-left: -10px; 
+    margin-top: 0px;
+    height: 24px;
+    line-height: 20px;
+    text-align: right;
+    border-top: 10px solid #fff;
+    border-bottom: 1px solid #fff;
+}
+
+#site_nav_global_primary ul {
+    margin-right: -15px;
+    float: right;
+}
+
+#site_nav_global_primary li {
+    margin-right: 0px;
+}
+
+#site_nav_global_primary li:last-child {
+    margin-right: 16px;
+}
+
+#site_nav_global_primary a {
+    color: #fff !important;
+    text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5);
+    padding: 2px 12px 2px 12px;
+    height: 20px;
+    display: block;
+    float: left;
+}
+
+#site_nav_global_primary a:hover {
+    color: #fff !important;
+    text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5);
+    background: #4c619c;
+    text-decoration: none;
+}
+
+#site_notice {
+    color: #000;
+    float: right;
+    width: 280px;
+    padding: 10px; 
+    margin-left: 40px;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+}
+
+#site_notice a {
+    color: #3e3e8c;
+}
+
+#anon_notice {
+    color: #000;
+    clear: both;
+    background: none;
+    padding: 0px;
+    margin-bottom: 10px;
+}
+
+#anon_notice a {
+    color: #3e3e8c;
+}
+
+.form_notice {
+    float: right;
+    margin-top: 0px;
+    width: 460px;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+    background: #cdd1dd;
+}
+
+.form_notice fieldset {
+    width: 100%;
+}
+
+.form_notice textarea {
+    width: 328px;
+    height: 54px;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+}
+
+.form_notice label[for=notice_data-attach],
+.form_notice #notice_data-attach {
+    top: 27px;
+    right: 86px;
+}
+
+.form_notice #notice_data-geo_wrap label,
+.form_notice #notice_data-geo_wrap input {
+    top: 52px;
+    right: 86px;
+}
+
+.form_notice #notice_action-submit {
+    font-size: 0.9em;
+    top: 80px;
+       right: -2px;
+    height: 2.4em;
+    width: 106px;
+}
+
+.form_notice .error,
+.form_notice .success {
+    width: 341px;
+}
+
+.form_notice .error {
+    margin-left: 0px;
+}
+
+#core {
+    clear: both;
+    margin: 0px;
+    width: 940px;
+    margin-left: 0px;
+    margin-top: 4px;
+}
+
+#content {
+    padding-top: 10px;
+    width: 610px;
+    margin-right: 0px;
+    padding-left: 10px;
+    padding-right: 20px;
+}
+
+#site_nav_local_views {
+    background-color: #7080aa;
+    -webkit-border-top-left-radius: 6px;
+    -webkit-border-top-right-radius: 6px;
+    -moz-border-radius-topleft: 6px;
+    -moz-border-radius-topright: 6px;
+    border-top-left-radius: 6px;
+    border-top-right-radius: 6px;
+    height: 24px;
+    line-height: 20px;
+    margin-bottom: 0px;
+    padding-left: 0px;
+}
+
+#site_nav_local_views a {
+    color: #fff !important;
+    padding: 2px 12px 2px 12px;
+    display: block;
+    float: left;
+    height: 20px;
+    width: auto;
+    text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5);
+}
+
+#site_nav_local_views li:first-child a {
+    -webkit-border-top-left-radius: 6px;
+    -moz-border-radius-topleft: 6px;
+    border-top-left-radius: 6px;
+}
+
+#site_nav_local_views a:hover {
+    background: #8e98b4 !important;
+    color: #fff !important;
+    text-decoration: none;
+}
+
+#site_nav_local_views .current a {
+    text-decoration: none;
+    background: #8e98b4 !important;
+    color: #fff !important;
+}
+
+#aside_primary {
+    width: 290px;
+    padding-left: 10px;
+    padding-top: 14px;
+}
+
+#aside_primary .section {
+    width: 280px;
+    margin-left: 0px;
+    margin-right: 10px;
+
+}
+
+#aside_primary h2 {
+    font-size: 1.4em;
+    margin-bottom: 8px;
+    border-bottom: 2px solid #fff;
+}
+
+.section ul.entities {
+    width: 290px;
+}
+
+.section .entities li {
+    margin-right: 17px;
+    margin-bottom: 10px;
+    width: 24px;
+}
+
+#popular_notices .avatar {
+    position: relative;
+    top: 2px;
+    margin-bottom: 4px;
+}
+
+#aside_primary td {
+    padding-right: 20px;
+    padding-bottom: 14px;
+}
+
+#aside_primary td .nickname {
+    line-height: 1.6em;
+}
+
+.section .avatar {
+    box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
+    -moz-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
+    -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
+}
+
+#content h1 {
+    margin-bottom: 8px;
+    border-bottom: 2px solid #f2f2f2;
+}
+
+#notices_primary {
+    margin-top: -5px;
+}
+
+#content .notice {
+    padding-bottom: 14px;
+    border-bottom: 2px dotted #eee;
+}
+
+.notice {
+    line-height: 1.35em;
+    margin-bottom: 10px;
+}
+
+#content .notice .author .photo {
+    left: 0px;
+    top: 6px;
+}
+
+#content .notice .entry-title {
+    min-height: 34px;
+}
+
+#showstream .notice .entry-title {
+    min-height: 1px;
+}
+
+#shownotice .notice .entry-title {
+    min-height:123px;
+}
+
+.notice div.entry-content {
+    font-size: 0.9em;
+    line-height: 1.2em;
+    margin-top: 6px;
+    opacity: 0.6;
+}
+
+.notice:hover div.entry-content {
+    opacity: 1;
+}
+
+.user_in .notice div.entry-content {
+    max-width: 440px;
+}
+
+div.entry-content a.response:before {
+       content: "(";
+}
+
+div.entry-content a.response:after {
+       content: ")";
+}
+
+.notice-options {
+    margin-top: 4px;
+}
+
+.pagination {
+    height: 1.2em;
+}
+
+#jOverlayContent button {
+    top: 20px;
+    right: 36px;
+}
+
+.entity_profile {
+    float: left;
+    width: 435px;
+    margin-top: 4px;
+}
+
+.entity_profile .entity_depiction {
+    margin-top: 4px;
+}
+
+.entity_actions {
+    width: 140px;
+    margin-top: 8px;
+    margin-bottom: 10px;
+}
+
+.entity_actions a, .entity_actions p, .entity_actions .entity_subscribe input, .entity_actions .entity_block input, .entity_actions .entity_moderation input, .entity_actions .entity_role input, .entity_actions .entity_nudge input, .entity_actions .entity_delete input {
+       text-shadow:0 1px 0 rgba(255,255,255,0.4);
+    border-radius: 4px;
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+    background-color: #CDD1DD !important;
+}
+
+.entity_moderation:hover ul,
+.entity_role:hover ul {
+    border-radius: 4px;
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+}
+
+.entity_send-a-message .form_notice legend {
+       text-shadow:0 1px 0 rgba(255,255,255,0.4);
+}
+
+.entity_send-a-message .form_notice {
+    border: 1px solid #7B4E82;
+}
+
+.entity_send-a-message .form_notice #notice_action-submit {
+    color: #fff !important;
+    top: 46px;
+}
+
+#aside_primary #entity_remote_subscribe a:hover {
+    background-color: #fff !important;
+}
+
+#entity_remote_subscribe .dialogbox {
+    border: 1px solid #7B4E82;
+    border-radius: 8px;\r
+       -moz-border-radius: 8px;\r
+       -webkit-border-radius: 8px;
+}
+
+#entity_remote_subscribe input {
+    padding-left: 4px;
+}
+
+#entity_remote_subscribe .submit_dialogbox {
+    margin-top: 10px;
+    float: right;
+}
+
+#filter_tags_item .submit {
+  left: 6px;
+  top: -3px;
+}
+
+.pagination {
+    height: 1.2em;
+    padding-bottom: 12px;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+}
+
+#footer {
+    color: #000;
+    margin-left: 0px;
+    margin-right: 0px;
+    -webkit-border-top-left-radius: 6px;
+    -webkit-border-top-right-radius: 6px;
+    -moz-border-radius-topleft: 6px;
+    -moz-border-radius-topright: 6px;
+    border-top-left-radius: 6px;
+    border-top-right-radius: 6px;
+}
+
+#footer a {
+    color: #3e3e8c;
+}
+
+.error, .success {
+    background-color: #F7E8E8;
+    padding: 4px;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+}
+.success {
+    background-color: #f2f2f2;
+}
+
+.form_notice input.submit, .form_settings input.submit, .form_settings input.cancel {
+    border-radius: 3px;
+    -moz-border-radius: 3px;
+    -webkit-border-radius: 3px;
+    text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5);
+    color:#fff;
+    font-weight: normal;
+    font-size: 1em;
+    height: 2.2em;
+    padding-left: 1em;
+    padding-right: 1em;
+    background: #7080aa;
+    background: -moz-linear-gradient(top, #7b8dbb , #7080aa);
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7b8dbb), color-stop(100%,#7080aa)); 
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7b8dbb', endColorstr='#7080aa',GradientType=0 );
+    border-width: 1px;
+}
+
+.form_notice input.submit:hover, .form_settings input.submit:hover, .form_settings input.cancel:hover {
+    text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.8);
+    background: #7b8dbb;
+    background: -moz-linear-gradient(top, #7080aa , #7b8dbb);
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7080aa), color-stop(100%,#7b8dbb));
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7080aa', endColorstr='#7b8dbb',GradientType=0 );
+}
+
+.form_settings input#settings_design_reset, .form_settings input.cancel {
+    background: #e2e2e2;
+    color: #8e181b;
+    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5);
+}
+
+.form_settings input#settings_design_reset:hover, .form_settings input.cancel:hover {
+    background: #f2f2f2;
+    color: #8e181b;
+    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5);
+}
+
+.form_settings input.checkbox, .form_settings input.radio {
+    margin-left: 24%;
+    margin-top: 2px;
+    position: relative;
+    left: -14px;
+}
+
+.form_settings label.checkbox, .form_settings label.radio {
+    width: auto;
+    max-width: 60%;
+    position: relative;
+    left: -30px;
+}
+
+.form_settings li input.radio {
+    clear: left;
+}
+
+.form_settings label.radio {
+    margin-left: 10px;
+    margin-right: 10px;
+    text-align: left;
+}
+
+#form_login p.form_guide, #form_register #settings_rememberme p.form_guide, #form_openid_login #settings_rememberme p.form_guide, #settings_twitter_remove p.form_guide, #design_background-image_onoff p.form_guide {
+    margin-left: 26%;
+}
+
+#form_search ul.form_data #q {
+    margin-left: 10px;
+}
+
+.form_settings fieldset fieldset {
+    margin-bottom: 30px;
+    padding-top: 25px;
+}
+
+
+#content thead th {
+text-align:left;
+}
+#content tbody th {
+vertical-align:top;
+text-align:left;
+font-weight:normal;
+padding-top:11px;
+padding-right:18px;
+}
+#content tbody tr {
+    border-top: 1px dotted #bbb;
+}
+#content td {
+padding:11px 18px 11px 0;
+vertical-align:top;
+}
+#content td:last-child {
+padding-right:0;
+}
+
+
+#realtime_actions {
+    position: relative !important;
+    float: right;
+    padding-top: 15px;
+    margin-bottom: -8px !important;
+}
+
+.realtime-popup #content {
+    padding-left: 4px !important;
+    padding-right: 4px !important;
+    margin-right: 0px;
+}
+
+.realtime-popup .form_notice textarea {
+    width: 325px !important;
+}
+
+.realtime-popup .form_notice #notice_action-submit {
+    top: 59px !important;
+    right: 6px !important;
+}
+
+.realtime-popup .form_notice label[for=notice_data-attach], .realtime-popup .form_notice #notice_data-attach {
+    right: 74px;
+    top: 3px !important;
+}
+
+.realtime-popup .form_notice #notice_data-geo_wrap label, .realtime-popup .form_notice #notice_data-geo_wrap input {
+    right: 8px;
+    top: 3px !important;
+}
+
+
+/* Bookmark specific styles */
+
+#content .bookmark .entry-title {
+    margin-left: 0px;
+}
+
+.bookmark h3 {
+    margin: 0px 0px 8px 0px;
+    float: left;
+    line-height: 1.2em;
+    max-width: 92%;
+}
+
+.bookmark-notice-count {
+    border-radius: 4px;\r
+       -moz-border-radius: 4px;\r
+       -webkit-border-radius: 4px;
+    padding: 1px 6px;
+    font-size: 1.2em;
+    line-height: 1.2em;
+    background: #fff;
+    border: 1px solid #7b8dbb;
+    color: #3e3e8c !important;
+    position: relative;
+    right: 4px;
+    margin-left: 10px;
+}
+
+.bookmark-notice-count:hover {
+    text-decoration: none;
+    background: #f2f2f2;
+    border: 1px solid #7b8dbb;
+    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5);
+}
+
+.notice .bookmark-description {
+    clear: both;
+    margin-left: 0px;
+    margin-bottom: 0px;
+}
+
+.notice .bookmark-author {
+    margin-left: 0px;
+    float: left;
+}
+
+.bookmark-tags {
+    clear: both;
+    margin-bottom: 8px;
+    line-height: 1.6em;
+}
+
+ul.bookmark-tags a {
+    border-radius: 4px;\r
+       -moz-border-radius: 4px;\r
+       -webkit-border-radius: 4px;
+    padding: 1px 6px;
+    background: #f2f2f2;
+    color: #3e3e8c !important;
+    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5);
+    font-size: 0.9em;
+}
+
+ul.bookmark-tags a:hover {
+    background-color: #cdd1dd;
+    text-decoration: none;
+}
+
+.bookmark-avatar {
+    float: none !important;
+    position: relative;
+    top: 2px;
+}
+
+.bookmark div.entry-content {
+    font-size: 0.9em;
+    line-height: 1.2em;
+    margin-top: 6px;
+    opacity: 0.6;
+    margin-bottom: 0px;
+}
+
+.bookmark:hover div.entry-content {
+    opacity: 1;
+}
+
+.bookmark .notice-options {
+    margin-top: 16px;
+}
+
+#bookmarkpopup {
+    min-width: 600px;
+    margin-top: 0px;
+    height: 100%;
+    border: 10px solid #364A84;
+    background: #364A84;
+}
+
+#bookmarkpopup #wrap {
+    width: auto;
+    min-width: 560px;
+    padding: 40px 0px 25px 0px;
+    margin-right: 2px;
+    background: #fff url(../mobilelogo.png) no-repeat 6px 6px;
+}
+
+#bookmarkpopup #header {
+    width: auto;
+    padding: 0px 10px;
+}
+
+#bookmarkpopup .form_settings label {
+    margin-top: 2px;
+    text-align: right;
+    width: 24%;
+    font-size: 1.2em;
+}
+
+#bookmarkpopup .form_settings .form_data input {
+    width: 60%;
+}
+
+#bookmarkpopup .form_guide {
+    color: #777;
+}
+
+#bookmarkpopup #submit {
+    float: right;
+    margin-right: 0px;
+}
+
+#bookmarkpopup fieldset fieldset {
+    margin-bottom: 10px;
+}
+
+/* Onboard specific styles */
+
+.onboard-flash {
+    border-radius: 6px;\r
+       -moz-border-radius: 6px;\r
+       -webkit-border-radius: 6px;
+    font-size: 1.1em;
+    box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5);
+    -moz-box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5);
+    -webkit-box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5);
+}
+
+.onboard-flash p {
+    margin-bottom: 10px;
+}
+
+.onboard-flash .next:before {
+    content: '\00BB';
+    padding-right: 6px;
+}
+
+.onboard-breadcrumbs {
+    margin-bottom: 16px !important;
+}
+
+.onboard-breadcrumbs li {
+    background: none !important;
+    border-top: none !important;
+    padding: 6px 12px 2px 0px !important;
+}
+
+.onboard-breadcrumbs li:last-child {
+    padding-right: 0px !important;
+}
+
+.onboard-breadcrumbs a {
+    text-decoration: none;
+}
+
+.onboard-breadcrumbs a:hover {
+    color: #3e3e8c !important;
+}
+
+/* Billing specific styles */
+
+#content table.billing_info {
+    margin-top: 10px;
+    background:rgba(240, 240, 240, 0.4);
+}
+
+#content table.billing_info th {
+    text-align: right;
+    width: 50%;
+}
+
+.invalid {
+    border: solid 2px red !important;
+}
+
+#payment_history table {
+    width: 100%;
+}
+
+#billingadminpanel .form_settings input {
+    margin-right: 0px;
+}
+
+}/*end of @media screen, projection, tv*/
diff --git a/theme/cleaner/css/ie.css b/theme/cleaner/css/ie.css
new file mode 100644 (file)
index 0000000..41f7dc9
--- /dev/null
@@ -0,0 +1,81 @@
+/* Temporary copy of base styles for overriding */
+
+input.checkbox,
+input.radio {
+top:0;
+}
+.form_notice textarea {
+    width: 328px;
+}
+.form_notice .form_note + label {
+position:absolute;
+top:25px;
+left:83%;
+text-indent:-9999px;
+height:16px;
+width:16px;
+display:block;
+    left: 390px;
+    top: 27px;
+}
+.form_notice #notice_action-submit {
+    width: 106px;
+    max-width: 106px;
+}
+.form_notice #notice_data-attach_selected,
+.form_notice #notice_data-geo_selected {
+width:78.75%;
+}
+.form_notice #notice_data-attach_selected button,
+.form_notice #notice_data-geo_selected button {
+padding:0 4px;
+}
+.notice-options input.submit {
+font-size:0;
+text-align:right;
+text-indent:0;
+}
+.notice div.entry-content .timestamp a {
+margin-right:4px;
+}
+.entity_profile {
+width:64%;
+}
+.notice {
+z-index:1;
+}
+.notice:hover {
+z-index:9999;
+}
+.notice .thumbnail img {
+z-index:9999;
+}
+
+.form_settings fieldset fieldset legend {
+line-height:auto;
+}
+
+/* IE specific styles */
+
+#site_nav_global_primary ul {
+    margin-right: 0px;
+}
+
+.notice-options input.submit {
+    color:#FFFFFF;
+}
+
+.form_notice #notice_data-attach {
+    filter: alpha(opacity=0);
+}
+
+.form_notice .form_note + label {
+    background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -328px;
+}
+
+.form_notice #notice_data-geo_wrap label {
+   background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -1780px;
+}
+.form_notice #notice_data-geo_wrap label.checked {
+   background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -1846px;
+}
diff --git a/theme/cleaner/css/mp-screen.css b/theme/cleaner/css/mp-screen.css
new file mode 100644 (file)
index 0000000..d3f95db
--- /dev/null
@@ -0,0 +1,204 @@
+/* mobile style */
+
+body {
+    background-image: none;
+    min-width: 0;
+}
+
+#wrap {
+    margin: 0;
+    padding: 0;
+    min-width:0;
+    max-width:100%;
+}
+
+#header {
+    width: 96%;
+    padding: 0 2%;
+    padding-top: 20px;
+}
+
+.user_in #header {
+    padding-top: 40px;
+}
+
+address {
+margin:1em 0 0 0;
+float:left;
+width:100%;
+}
+
+address img + .fn {
+display:block;
+margin-top:1em;
+    margin-right: 10px;
+clear: left;
+float:left;
+}
+
+#site_nav_global_primary {
+    margin:0;
+    width: 100%;
+    padding: 4px 0;
+    height: auto;
+    position:absolute;
+    top:0;
+    left:0;
+    font-size: 1em;
+       letter-spacing: 0em;
+    border-top: none;
+}
+
+#site_nav_global_primary li {
+    margin-left:0;
+    margin-right:0px;
+    float:left;
+    font-size:0.9em;
+    padding: 2px 4px;
+    line-height: 1em;
+    height: auto;
+}
+
+#site_nav_global_primary li a {
+    height: auto;
+}
+
+.form_notice {
+    float: left;
+    margin-left: 0px;
+    width: 300px;
+    padding: 4px;
+}
+
+#form_notice-direct.form_notice {
+    padding-top: 10px;
+}
+
+.form_notice textarea {
+    width: 210px;
+    height: 50px;
+    padding: 4px;
+}
+
+#notice_text-count {
+position:absolute;
+bottom:2px;
+    left: 175px;
+    font-size: 0.8em;
+z-index:9;
+}
+
+#form_notice-direct.form_notice #notice_text-count {
+    left: 0px;
+}
+
+/*input type=file no good in
+iPhone/iPod Touch, Android, Opera Mini Simulator
+*/
+.form_notice #notice_text-count + label,
+.form_notice label[for="notice_data-attach"] {
+display:none;
+}
+.form_notice #notice_data-attach {
+position:static;
+clear:both;
+width:65%;
+height:auto;
+display:block;
+z-index:9;
+padding:0;
+margin:0;
+background:none;
+opacity:1;
+}
+
+.form_notice #notice_action-submit {
+    text-align: center;
+    left: 230px;
+    top: 32px;
+    width: 70px;
+    font-size: 0.8em;
+}
+
+#form_notice-direct.form_notice #notice_action-submit {
+    top: 62px;
+}
+
+#site_nav_local_views {
+    height: auto;
+    font-size: 0.9em;
+    line-height: 2em;
+    margin-bottom: 0px;
+    padding-left: 4px;
+    background: none;
+}
+
+#site_nav_local_views li {
+    margin-right: 6px;
+}
+
+#site_nav_local_views a {
+    background-color: #7080aa;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+    margin-right: 2px;
+    margin-bottom: 2px;
+}
+
+#core {
+    width: 100%;
+    margin: 0;
+}
+
+#content {
+    width: 96%;
+    padding: 10px 2%;
+    margin: 0;
+    min-height: auto;
+}
+
+#footer {
+    margin: 0;
+    padding: 10px 4px 4px 4px;
+}
+
+
+.form_settings fieldset {
+margin-bottom:7px;
+}
+
+.form_settings label {
+width:auto;
+display:block;
+float:none;
+    text-align: left;
+}
+
+.form_settings .form_data li {
+margin-bottom:7px;
+}
+
+.form_settings .form_data textarea,
+.form_settings .form_data select, 
+.form_settings .form_data input {
+margin-left:0;
+display:block;
+}
+.form_settings .form_data textarea {
+width:96.41%;
+}
+
+.form_settings .form_data label {
+float:none;
+}
+
+.form_settings .form_data p.form_guide {
+width:auto;
+margin-left:0;
+}
+
+#settings_design_color .form_data {
+ width: auto;
+ margin-right: 0;
+}
diff --git a/theme/cleaner/default-avatar-mini.png b/theme/cleaner/default-avatar-mini.png
new file mode 100644 (file)
index 0000000..a3410e3
Binary files /dev/null and b/theme/cleaner/default-avatar-mini.png differ
diff --git a/theme/cleaner/default-avatar-profile.png b/theme/cleaner/default-avatar-profile.png
new file mode 100644 (file)
index 0000000..8f635d1
Binary files /dev/null and b/theme/cleaner/default-avatar-profile.png differ
diff --git a/theme/cleaner/default-avatar-stream.png b/theme/cleaner/default-avatar-stream.png
new file mode 100644 (file)
index 0000000..a302463
Binary files /dev/null and b/theme/cleaner/default-avatar-stream.png differ
diff --git a/theme/cleaner/logo.png b/theme/cleaner/logo.png
new file mode 100644 (file)
index 0000000..7d6059a
Binary files /dev/null and b/theme/cleaner/logo.png differ
diff --git a/theme/cleaner/mobilelogo.png b/theme/cleaner/mobilelogo.png
new file mode 100644 (file)
index 0000000..781e795
Binary files /dev/null and b/theme/cleaner/mobilelogo.png differ
diff --git a/theme/cleaner/theme.ini b/theme/cleaner/theme.ini
new file mode 100644 (file)
index 0000000..0209008
--- /dev/null
@@ -0,0 +1 @@
+include=rebase