From c8d6a77d8ae64d527838ed6691e6eabff4aa12e2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 05:45:38 -0500 Subject: [PATCH 01/68] common superclass for menu widgets --- lib/menu.php | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 lib/menu.php diff --git a/lib/menu.php b/lib/menu.php new file mode 100644 index 0000000000..b9791d2359 --- /dev/null +++ b/lib/menu.php @@ -0,0 +1,84 @@ +. + * + * @category Widget + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Superclass for menus + * + * @category General + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class Menu extends Widget +{ + var $action = null; + var $actionName = null; + /** + * Construction + * + * @param Action $action current action, used for output + */ + function __construct($action=null) + { + parent::__construct($action); + + $this->action = $action; + $this->actionName = $action->trimmed('action'); + } + + function item($actionName, $args, $label, $description, $id=null) + { + if (empty($id)) { + $id = $this->menuItemID($actionName); + } + + $url = common_local_url($actionName, $args); + + $this->out->menuItem($url, + $label, + $description, + $actionName == $this->actionName, + $id); + } + + function menuItemID($actionName) + { + return sprintf('nav_%s', $actionName); + } +} From 903053caec99da4443fa10f045f83239634b1a58 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 05:46:03 -0500 Subject: [PATCH 02/68] primary and secondary nav use menu superclass --- lib/action.php | 104 ++------------------------------------ lib/primarynav.php | 116 +++++++++++++++++++++++++++++++++++++++++++ lib/secondarynav.php | 90 +++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+), 100 deletions(-) create mode 100644 lib/primarynav.php create mode 100644 lib/secondarynav.php diff --git a/lib/action.php b/lib/action.php index 3ef9ffa3c8..54bea7c931 100644 --- a/lib/action.php +++ b/lib/action.php @@ -543,69 +543,8 @@ class Action extends HTMLOutputter // lawsuit */ function showPrimaryNav() { - $user = common_current_user(); - $this->elementStart('ul', array('class' => 'nav', - 'id' => 'site_nav_global_primary')); - if (Event::handle('StartPrimaryNav', array($this))) { - if (!empty($user)) { - $this->menuItem(common_local_url('all', - array('nickname' => $user->nickname)), - _m('Home'), - _m('Friends timeline'), - false, - 'nav_home'); - $this->menuItem(common_local_url('showstream', - array('nickname' => $user->nickname)), - _m('Profile'), - _m('Your profile'), - false, - 'nav_profile'); - $this->menuItem(common_local_url('public'), - _m('Public'), - _m('Everyone on this site'), - false, - 'nav_public'); - $this->menuItem(common_local_url('profilesettings'), - _m('Settings'), - _m('Change your personal settings'), - false, - 'nav_account'); - if ($user->hasRight(Right::CONFIGURESITE)) { - $this->menuItem(common_local_url('siteadminpanel'), - _m('Admin'), - _m('Site configuration'), - false, - 'nav_admin'); - } - $this->menuItem(common_local_url('logout'), - _m('Logout'), - _m('Logout from the site'), - false, - 'nav_logout'); - } else { - $this->menuItem(common_local_url('public'), - _m('Public'), - _m('Everyone on this site'), - false, - 'nav_public'); - $this->menuItem(common_local_url('login'), - _m('Login'), - _m('Login to the site'), - false, - 'nav_login'); - } - - if (!empty($user) || !common_config('site', 'private')) { - $this->menuItem(common_local_url('noticesearch'), - _m('Search'), - _m('Search the site'), - false, - 'nav_search'); - } - - Event::handle('EndPrimaryNav', array($this)); - } - $this->elementEnd('ul'); + $pn = new PrimaryNav($this); + $pn->show(); } /** @@ -850,43 +789,8 @@ class Action extends HTMLOutputter // lawsuit */ function showSecondaryNav() { - $this->elementStart('ul', array('class' => 'nav', - 'id' => 'site_nav_global_secondary')); - if (Event::handle('StartSecondaryNav', array($this))) { - $this->menuItem(common_local_url('doc', array('title' => 'help')), - // TRANS: Secondary navigation menu option leading to help on StatusNet. - _('Help')); - $this->menuItem(common_local_url('doc', array('title' => 'about')), - // TRANS: Secondary navigation menu option leading to text about StatusNet site. - _('About')); - $this->menuItem(common_local_url('doc', array('title' => 'faq')), - // TRANS: Secondary navigation menu option leading to Frequently Asked Questions. - _('FAQ')); - $bb = common_config('site', 'broughtby'); - if (!empty($bb)) { - $this->menuItem(common_local_url('doc', array('title' => 'tos')), - // TRANS: Secondary navigation menu option leading to Terms of Service. - _('TOS')); - } - $this->menuItem(common_local_url('doc', array('title' => 'privacy')), - // TRANS: Secondary navigation menu option leading to privacy policy. - _('Privacy')); - $this->menuItem(common_local_url('doc', array('title' => 'source')), - // TRANS: Secondary navigation menu option. Leads to information about StatusNet and its license. - _('Source')); - $this->menuItem(common_local_url('version'), - // TRANS: Secondary navigation menu option leading to version information on the StatusNet site. - _('Version')); - $this->menuItem(common_local_url('doc', array('title' => 'contact')), - // TRANS: Secondary navigation menu option leading to e-mail contact information on the - // TRANS: StatusNet site, where to report bugs, ... - _('Contact')); - $this->menuItem(common_local_url('doc', array('title' => 'badge')), - // TRANS: Secondary navigation menu option. Leads to information about embedding a timeline widget. - _('Badge')); - Event::handle('EndSecondaryNav', array($this)); - } - $this->elementEnd('ul'); + $sn = new SecondaryNav($this); + $sn->show(); } /** diff --git a/lib/primarynav.php b/lib/primarynav.php new file mode 100644 index 0000000000..01517d9429 --- /dev/null +++ b/lib/primarynav.php @@ -0,0 +1,116 @@ +. + * + * @category Menu + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Primary, top-level menu + * + * @category General + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class PrimaryNav extends Menu +{ + function show() + { + $user = common_current_user(); + $this->action->elementStart('ul', array('class' => 'nav', + 'id' => 'site_nav_global_primary')); + if (Event::handle('StartPrimaryNav', array($this->action))) { + if (!empty($user)) { + $this->action->menuItem(common_local_url('all', + array('nickname' => $user->nickname)), + _m('Home'), + _m('Friends timeline'), + false, + 'nav_home'); + $this->action->menuItem(common_local_url('showstream', + array('nickname' => $user->nickname)), + _m('Profile'), + _m('Your profile'), + false, + 'nav_profile'); + $this->action->menuItem(common_local_url('public'), + _m('Public'), + _m('Everyone on this site'), + false, + 'nav_public'); + $this->action->menuItem(common_local_url('profilesettings'), + _m('Settings'), + _m('Change your personal settings'), + false, + 'nav_account'); + if ($user->hasRight(Right::CONFIGURESITE)) { + $this->action->menuItem(common_local_url('siteadminpanel'), + _m('Admin'), + _m('Site configuration'), + false, + 'nav_admin'); + } + $this->action->menuItem(common_local_url('logout'), + _m('Logout'), + _m('Logout from the site'), + false, + 'nav_logout'); + } else { + $this->action->menuItem(common_local_url('public'), + _m('Public'), + _m('Everyone on this site'), + false, + 'nav_public'); + $this->action->menuItem(common_local_url('login'), + _m('Login'), + _m('Login to the site'), + false, + 'nav_login'); + } + + if (!empty($user) || !common_config('site', 'private')) { + $this->action->menuItem(common_local_url('noticesearch'), + _m('Search'), + _m('Search the site'), + false, + 'nav_search'); + } + + Event::handle('EndPrimaryNav', array($this->action)); + } + $this->action->elementEnd('ul'); + } +} diff --git a/lib/secondarynav.php b/lib/secondarynav.php new file mode 100644 index 0000000000..542de51ac1 --- /dev/null +++ b/lib/secondarynav.php @@ -0,0 +1,90 @@ +. + * + * @category Cache + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Secondary menu, shown at the bottom of all pages + * + * @category General + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class SecondaryNav extends Menu +{ + function show() + { + $this->out->elementStart('ul', array('class' => 'nav', + 'id' => 'site_nav_global_secondary')); + if (Event::handle('StartSecondaryNav', array($this->action))) { + $this->out->menuItem(common_local_url('doc', array('title' => 'help')), + // TRANS: Secondary navigation menu option leading to help on StatusNet. + _('Help')); + $this->out->menuItem(common_local_url('doc', array('title' => 'about')), + // TRANS: Secondary navigation menu option leading to text about StatusNet site. + _('About')); + $this->out->menuItem(common_local_url('doc', array('title' => 'faq')), + // TRANS: Secondary navigation menu option leading to Frequently Asked Questions. + _('FAQ')); + $bb = common_config('site', 'broughtby'); + if (!empty($bb)) { + $this->out->menuItem(common_local_url('doc', array('title' => 'tos')), + // TRANS: Secondary navigation menu option leading to Terms of Service. + _('TOS')); + } + $this->out->menuItem(common_local_url('doc', array('title' => 'privacy')), + // TRANS: Secondary navigation menu option leading to privacy policy. + _('Privacy')); + $this->out->menuItem(common_local_url('doc', array('title' => 'source')), + // TRANS: Secondary navigation menu option. Leads to information about StatusNet and its license. + _('Source')); + $this->out->menuItem(common_local_url('version'), + // TRANS: Secondary navigation menu option leading to version information on the StatusNet site. + _('Version')); + $this->out->menuItem(common_local_url('doc', array('title' => 'contact')), + // TRANS: Secondary navigation menu option leading to e-mail contact information on the + // TRANS: StatusNet site, where to report bugs, ... + _('Contact')); + $this->out->menuItem(common_local_url('doc', array('title' => 'badge')), + // TRANS: Secondary navigation menu option. Leads to information about embedding a timeline widget. + _('Badge')); + Event::handle('EndSecondaryNav', array($this->action)); + } + $this->out->elementEnd('ul'); + } +} \ No newline at end of file From d6d3dfda81ce60cb511f69a9d890d68e67ebd7d8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 05:51:00 -0500 Subject: [PATCH 03/68] AdminPanelNav has own module, uses Menu --- lib/adminpanelnav.php | 148 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 lib/adminpanelnav.php diff --git a/lib/adminpanelnav.php b/lib/adminpanelnav.php new file mode 100644 index 0000000000..ceedf6ceac --- /dev/null +++ b/lib/adminpanelnav.php @@ -0,0 +1,148 @@ +. + * + * @category Menu + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Menu for admin panels + * + * @category Output + * @package StatusNet + * @author Evan Prodromou + * @author Sarven Capadisli + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class AdminPanelNav extends Menu +{ + /** + * Show the menu + * + * @return void + */ + function show() + { + $action_name = $this->action->trimmed('action'); + + $this->action->elementStart('ul', array('class' => 'nav')); + + if (Event::handle('StartAdminPanelNav', array($this))) { + + if (AdminPanelAction::canAdmin('site')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Basic site configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('siteadminpanel'), _m('MENU', 'Site'), + $menu_title, $action_name == 'siteadminpanel', 'nav_site_admin_panel'); + } + + if (AdminPanelAction::canAdmin('design')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Design configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('designadminpanel'), _m('MENU', 'Design'), + $menu_title, $action_name == 'designadminpanel', 'nav_design_admin_panel'); + } + + if (AdminPanelAction::canAdmin('user')) { + // TRANS: Menu item title/tooltip + $menu_title = _('User configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('useradminpanel'), _('User'), + $menu_title, $action_name == 'useradminpanel', 'nav_user_admin_panel'); + } + + if (AdminPanelAction::canAdmin('access')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Access configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('accessadminpanel'), _('Access'), + $menu_title, $action_name == 'accessadminpanel', 'nav_access_admin_panel'); + } + + if (AdminPanelAction::canAdmin('paths')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Paths configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'), + $menu_title, $action_name == 'pathsadminpanel', 'nav_paths_admin_panel'); + } + + if (AdminPanelAction::canAdmin('sessions')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Sessions configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'), + $menu_title, $action_name == 'sessionsadminpanel', 'nav_sessions_admin_panel'); + } + + if (AdminPanelAction::canAdmin('sitenotice')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Edit site notice'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('sitenoticeadminpanel'), _('Site notice'), + $menu_title, $action_name == 'sitenoticeadminpanel', 'nav_sitenotice_admin_panel'); + } + + if (AdminPanelAction::canAdmin('snapshot')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Snapshots configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('snapshotadminpanel'), _('Snapshots'), + $menu_title, $action_name == 'snapshotadminpanel', 'nav_snapshot_admin_panel'); + } + + if (AdminPanelAction::canAdmin('license')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Set site license'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('licenseadminpanel'), _('License'), + $menu_title, $action_name == 'licenseadminpanel', 'nav_license_admin_panel'); + } + + if (AdminPanelAction::canAdmin('plugins')) { + // TRANS: Menu item title/tooltip + $menu_title = _('Plugins configuration'); + // TRANS: Menu item for site administration + $this->out->menuItem(common_local_url('pluginsadminpanel'), _('Plugins'), + $menu_title, $action_name == 'pluginsadminpanel', 'nav_design_admin_panel'); + } + + Event::handle('EndAdminPanelNav', array($this)); + } + $this->action->elementEnd('ul'); + } +} From a64c6c501555bc70ef617ecb8c4a21b6e1f91518 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 06:00:03 -0500 Subject: [PATCH 04/68] all nav menus use menu superclass --- lib/groupnav.php | 4 +--- lib/logingroupnav.php | 15 +-------------- lib/personalgroupnav.php | 37 ++++++++----------------------------- lib/publicgroupnav.php | 16 +--------------- lib/searchgroupnav.php | 12 ++++-------- lib/settingsnav.php | 19 +++---------------- lib/subgroupnav.php | 6 ++---- 7 files changed, 20 insertions(+), 89 deletions(-) diff --git a/lib/groupnav.php b/lib/groupnav.php index ee988d0a98..a2dd6eac00 100644 --- a/lib/groupnav.php +++ b/lib/groupnav.php @@ -49,9 +49,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * @see HTMLOutputter */ -class GroupNav extends Widget +class GroupNav extends Menu { - var $action = null; var $group = null; /** @@ -63,7 +62,6 @@ class GroupNav extends Widget function __construct($action=null, $group=null) { parent::__construct($action); - $this->action = $action; $this->group = $group; } diff --git a/lib/logingroupnav.php b/lib/logingroupnav.php index a309e7320f..3c67f76322 100644 --- a/lib/logingroupnav.php +++ b/lib/logingroupnav.php @@ -44,21 +44,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * * @see Widget */ -class LoginGroupNav extends Widget +class LoginGroupNav extends Menu { - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - /** * Show the menu * diff --git a/lib/personalgroupnav.php b/lib/personalgroupnav.php index 72d0893af7..d72a865677 100644 --- a/lib/personalgroupnav.php +++ b/lib/personalgroupnav.php @@ -2,7 +2,7 @@ /** * StatusNet, the distributed open-source microblogging tool * - * Base class for all actions (~views) + * Menu for personal group of actions * * PHP version 5 * @@ -19,11 +19,11 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - * @category Action + * @category Menu * @package StatusNet * @author Evan Prodromou * @author Sarven Capadisli - * @copyright 2008 StatusNet, Inc. + * @copyright 2008-2011 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ @@ -32,41 +32,20 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -require_once INSTALLDIR.'/lib/widget.php'; - /** - * Base class for all actions + * Menu for personal group of actions * - * This is the base class for all actions in the package. An action is - * more or less a "view" in an MVC framework. - * - * Actions are responsible for extracting and validating parameters; using - * model classes to read and write to the database; and doing ouput. - * - * @category Output + * @category Menu * @package StatusNet * @author Evan Prodromou * @author Sarven Capadisli + * @copyright 2008-2011 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ - * - * @see HTMLOutputter */ -class PersonalGroupNav extends Widget + +class PersonalGroupNav extends Menu { - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - /** * Show the menu * diff --git a/lib/publicgroupnav.php b/lib/publicgroupnav.php index ae9cbdebb4..bd2ad53124 100644 --- a/lib/publicgroupnav.php +++ b/lib/publicgroupnav.php @@ -46,22 +46,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * @see Widget */ -class PublicGroupNav extends Widget +class PublicGroupNav extends Menu { - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - /** * Show the menu * diff --git a/lib/searchgroupnav.php b/lib/searchgroupnav.php index e843dc096c..cfe8fde353 100644 --- a/lib/searchgroupnav.php +++ b/lib/searchgroupnav.php @@ -2,7 +2,7 @@ /** * StatusNet, the distributed open-source microblogging tool * - * Menu for search actions + * Menu for search group of actions * * PHP version 5 * @@ -22,7 +22,7 @@ * @category Menu * @package StatusNet * @author Evan Prodromou - * @copyright 2008 StatusNet, Inc. + * @copyright 2008-2011 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ @@ -31,12 +31,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -require_once INSTALLDIR.'/lib/widget.php'; - /** * Menu for public group of actions * - * @category Output + * @category Menu * @package StatusNet * @author Evan Prodromou * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 @@ -45,9 +43,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * @see Widget */ -class SearchGroupNav extends Widget +class SearchGroupNav extends Menu { - var $action = null; var $q = null; /** @@ -59,7 +56,6 @@ class SearchGroupNav extends Widget function __construct($action=null, $q = null) { parent::__construct($action); - $this->action = $action; $this->q = $q; } diff --git a/lib/settingsnav.php b/lib/settingsnav.php index a73f73f86a..697e7ee46b 100644 --- a/lib/settingsnav.php +++ b/lib/settingsnav.php @@ -1,7 +1,7 @@ - * @copyright 2010 StatusNet, Inc. + * @copyright 2010,2011 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ @@ -46,21 +46,8 @@ if (!defined('STATUSNET')) { * @see HTMLOutputter */ -class SettingsNav extends Widget +class SettingsNav extends Menu { - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - /** * Show the menu * diff --git a/lib/subgroupnav.php b/lib/subgroupnav.php index be3ba27480..ee4b0a8dff 100644 --- a/lib/subgroupnav.php +++ b/lib/subgroupnav.php @@ -22,7 +22,7 @@ * @category Subs * @package StatusNet * @author Evan Prodromou - * @copyright 2008-2009 StatusNet, Inc. + * @copyright 2008-2011 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ @@ -43,9 +43,8 @@ require_once INSTALLDIR.'/lib/widget.php'; * @link http://status.net/ */ -class SubGroupNav extends Widget +class SubGroupNav extends Menu { - var $action = null; var $user = null; /** @@ -57,7 +56,6 @@ class SubGroupNav extends Widget function __construct($action=null, $user=null) { parent::__construct($action); - $this->action = $action; $this->user = $user; } From d8cbc20a792ed8b04d7257186e571e926a5280ac Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 06:29:24 -0500 Subject: [PATCH 05/68] method to show submenus --- lib/menu.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/menu.php b/lib/menu.php index b9791d2359..7947b4d7e4 100644 --- a/lib/menu.php +++ b/lib/menu.php @@ -81,4 +81,12 @@ class Menu extends Widget { return sprintf('nav_%s', $actionName); } + + function submenu($label, $menu) + { + $this->action->elementStart('li'); + $this->action->text($label); + $menu->show(); + $this->action->elementEnd('li'); + } } From dba2aaa59fece223141809d2f1cdf506c479a8f2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 06:30:27 -0500 Subject: [PATCH 06/68] new mega-menu for default local navigation --- lib/defaultlocalnav.php | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 lib/defaultlocalnav.php diff --git a/lib/defaultlocalnav.php b/lib/defaultlocalnav.php new file mode 100644 index 0000000000..93eaf73393 --- /dev/null +++ b/lib/defaultlocalnav.php @@ -0,0 +1,69 @@ +. + * + * @category Menu + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Default menu + * + * @category Menu + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class DefaultLocalNav extends Menu +{ + function show() + { + $this->action->elementStart('ul', array('id' => 'nav_local_default')); + + $user = common_current_user(); + + if (!empty($user)) { + $pn = new PersonalGroupNav($this->action, $user); + $this->submenu(_m('Home'), $pn); + + $sn = new SubGroupNav($this->action, $user); + $this->submenu(_m('Profile'), $sn); + } + + $bn = new PublicGroupNav($this->action); + $this->submenu(_('Public'), $bn); + + $this->action->elementEnd('ul'); + } +} From 7d77bdcc483a223eaa4eef152f6d060c2465499c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 06:30:51 -0500 Subject: [PATCH 07/68] move top-level navigation to default local navigation --- lib/action.php | 3 ++- lib/primarynav.php | 23 +---------------------- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/lib/action.php b/lib/action.php index 54bea7c931..9a6a160e3f 100644 --- a/lib/action.php +++ b/lib/action.php @@ -637,7 +637,8 @@ class Action extends HTMLOutputter // lawsuit */ function showLocalNav() { - // does nothing by default + $nav = new DefaultLocalNav($this); + $nav->show(); } /** diff --git a/lib/primarynav.php b/lib/primarynav.php index 01517d9429..296328d8bd 100644 --- a/lib/primarynav.php +++ b/lib/primarynav.php @@ -54,23 +54,6 @@ class PrimaryNav extends Menu 'id' => 'site_nav_global_primary')); if (Event::handle('StartPrimaryNav', array($this->action))) { if (!empty($user)) { - $this->action->menuItem(common_local_url('all', - array('nickname' => $user->nickname)), - _m('Home'), - _m('Friends timeline'), - false, - 'nav_home'); - $this->action->menuItem(common_local_url('showstream', - array('nickname' => $user->nickname)), - _m('Profile'), - _m('Your profile'), - false, - 'nav_profile'); - $this->action->menuItem(common_local_url('public'), - _m('Public'), - _m('Everyone on this site'), - false, - 'nav_public'); $this->action->menuItem(common_local_url('profilesettings'), _m('Settings'), _m('Change your personal settings'), @@ -89,11 +72,6 @@ class PrimaryNav extends Menu false, 'nav_logout'); } else { - $this->action->menuItem(common_local_url('public'), - _m('Public'), - _m('Everyone on this site'), - false, - 'nav_public'); $this->action->menuItem(common_local_url('login'), _m('Login'), _m('Login to the site'), @@ -111,6 +89,7 @@ class PrimaryNav extends Menu Event::handle('EndPrimaryNav', array($this->action)); } + $this->action->elementEnd('ul'); } } From 0e1a22142304c720e2fa6e65f97c135d1f4268e4 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 15:52:46 -0500 Subject: [PATCH 08/68] add object menu to actions, default empty --- lib/action.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/action.php b/lib/action.php index 9a6a160e3f..5917d31b36 100644 --- a/lib/action.php +++ b/lib/action.php @@ -607,6 +607,10 @@ class Action extends HTMLOutputter // lawsuit $this->showContentBlock(); Event::handle('EndShowContentBlock', array($this)); } + if (Event::handle('StartShowObjectNavBlock', array($this))) { + $this->showObjectNavBlock(); + Event::handle('EndShowObjectNavBlock', array($this)); + } if (Event::handle('StartShowAside', array($this))) { $this->showAside(); Event::handle('EndShowAside', array($this)); @@ -641,6 +645,32 @@ class Action extends HTMLOutputter // lawsuit $nav->show(); } + /** + * Show menu for an object (group, profile) + * + * @return nothing + */ + function showObjectNavBlock() + { + // Need to have this ID for CSS; I'm too lazy to add it to + // all menus + $this->elementStart('div', array('id' => 'site_nav_object')); + $this->showObjectNav(); + $this->elementEnd('div'); + } + + /** + * Show object navigation. + * + * If there are things to do with this object, show it here. + * + * @return nothing + */ + function showObjectNav() + { + /* Nothing here. */ + } + /** * Show content block. * From 805d14577d8a7e87d2dcea66aa5d22d801987fa5 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 15:54:32 -0500 Subject: [PATCH 09/68] subscriber actions show the profile menu in object area --- lib/galleryaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galleryaction.php b/lib/galleryaction.php index b8edbbb7ba..107134a09b 100644 --- a/lib/galleryaction.php +++ b/lib/galleryaction.php @@ -94,7 +94,7 @@ class GalleryAction extends OwnerDesignAction $this->showPage(); } - function showLocalNav() + function showObjectNav() { $nav = new SubGroupNav($this, $this->user); $nav->show(); From c925a4d181c13ec5fc5669a23ea95ce6c3659e13 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 15:54:43 -0500 Subject: [PATCH 10/68] search actions show the search menu in object area --- lib/searchaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/searchaction.php b/lib/searchaction.php index 67d0bcdeb8..73c287eef3 100644 --- a/lib/searchaction.php +++ b/lib/searchaction.php @@ -70,7 +70,7 @@ class SearchAction extends Action * @return void * @see SearchGroupNav */ - function showLocalNav() + function showObjectNav() { $nav = new SearchGroupNav($this, $this->trimmed('q')); $nav->show(); From 8c03e8b0b3ef76146fc55cbf2e49ce2a35905806 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 15:59:01 -0500 Subject: [PATCH 11/68] use default local nav for allaction --- actions/all.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/actions/all.php b/actions/all.php index dc08592faf..896c63c7d9 100644 --- a/actions/all.php +++ b/actions/all.php @@ -127,12 +127,6 @@ class AllAction extends ProfileAction ); } - function showLocalNav() - { - $nav = new PersonalGroupNav($this); - $nav->show(); - } - function showEmptyListMessage() { // TRANS: Empty list message. %s is a user nickname. From 64ab7b7d07aea1c2082a946d3ea899ac47e92adc Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:00:07 -0500 Subject: [PATCH 12/68] use default local nav for public action --- actions/public.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/actions/public.php b/actions/public.php index 5fc547feaf..cbc753d900 100644 --- a/actions/public.php +++ b/actions/public.php @@ -168,21 +168,6 @@ class PublicAction extends Action _('Public Stream Feed (Atom)'))); } - /** - * Show tabset for this page - * - * Uses the PublicGroupNav widget - * - * @return void - * @see PublicGroupNav - */ - - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - function showEmptyList() { $message = _('This is the public timeline for %%site.name%% but no one has posted anything yet.') . ' '; From 0fef2cb66d5e19524a6bb253baff48045bf2f84c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:04:36 -0500 Subject: [PATCH 13/68] personal group nav uses current user --- lib/defaultlocalnav.php | 2 +- lib/personalgroupnav.php | 21 +++++++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/lib/defaultlocalnav.php b/lib/defaultlocalnav.php index 93eaf73393..b42d3a804c 100644 --- a/lib/defaultlocalnav.php +++ b/lib/defaultlocalnav.php @@ -54,7 +54,7 @@ class DefaultLocalNav extends Menu $user = common_current_user(); if (!empty($user)) { - $pn = new PersonalGroupNav($this->action, $user); + $pn = new PersonalGroupNav($this->action); $this->submenu(_m('Home'), $pn); $sn = new SubGroupNav($this->action, $user); diff --git a/lib/personalgroupnav.php b/lib/personalgroupnav.php index d72a865677..6a31358596 100644 --- a/lib/personalgroupnav.php +++ b/lib/personalgroupnav.php @@ -53,23 +53,16 @@ class PersonalGroupNav extends Menu */ function show() { - $user = null; + $user = common_current_user(); - // FIXME: we should probably pass this in - - $action = $this->action->trimmed('action'); - $nickname = $this->action->trimmed('nickname'); - - if ($nickname) { - $user = User::staticGet('nickname', $nickname); - $user_profile = $user->getProfile(); - $name = $user_profile->getBestName(); - } else { - // @fixme can this happen? is this valid? - $user_profile = false; - $name = $nickname; + if (empty($user)) { + throw new ServerException('Do not show personal group nav with no current user.'); } + $user_profile = $user->getProfile(); + $nickname = $user->nickname; + $name = $user_profile->getBestName(); + $this->out->elementStart('ul', array('class' => 'nav')); if (Event::handle('StartPersonalGroupNav', array($this))) { From 3377bc2ccff0cb83b1022a8f2d1d4c921bc6287c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:06:29 -0500 Subject: [PATCH 14/68] RepliesAction uses default local nav --- actions/replies.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/actions/replies.php b/actions/replies.php index 8f2fc6c7f3..fd178175d2 100644 --- a/actions/replies.php +++ b/actions/replies.php @@ -160,18 +160,6 @@ class RepliesAction extends OwnerDesignAction $this->user->nickname))); } - /** - * show the personal group nav - * - * @return void - */ - - function showLocalNav() - { - $nav = new PersonalGroupNav($this); - $nav->show(); - } - /** * Show the content * From efdc85224adedeae8dab0c1ada5f8f117b076f2f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:07:27 -0500 Subject: [PATCH 15/68] user groups show subgroupnav in object menu area --- actions/usergroups.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/usergroups.php b/actions/usergroups.php index 6606e76cdb..cf904bc929 100644 --- a/actions/usergroups.php +++ b/actions/usergroups.php @@ -112,7 +112,7 @@ class UsergroupsAction extends OwnerDesignAction $this->showPage(); } - function showLocalNav() + function showObjectNav() { $nav = new SubGroupNav($this, $this->user); $nav->show(); From 85320a7561013f84b9d562b91c7647c59a21b814 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:08:49 -0500 Subject: [PATCH 16/68] show object nav for blocked users in a group --- actions/blockedfromgroup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/blockedfromgroup.php b/actions/blockedfromgroup.php index 6ff572c05d..dd916b170a 100644 --- a/actions/blockedfromgroup.php +++ b/actions/blockedfromgroup.php @@ -122,7 +122,7 @@ class BlockedfromgroupAction extends GroupDesignAction _('A list of the users blocked from joining this group.')); } - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); From 737eb371f83c1059e80cb2d9d907f735283d6e94 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:09:35 -0500 Subject: [PATCH 17/68] show full local nav in public tag cloud --- actions/publictagcloud.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/actions/publictagcloud.php b/actions/publictagcloud.php index f6f1d31625..1432ca66a8 100644 --- a/actions/publictagcloud.php +++ b/actions/publictagcloud.php @@ -92,12 +92,6 @@ class PublictagcloudAction extends Action $this->elementEnd('div'); } - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - function handle($args) { parent::handle($args); From 4561caec1037a84d4b7dbd010e7b5a9b2464a0b7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:10:40 -0500 Subject: [PATCH 18/68] show default local nav in group edit --- actions/editgroup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/editgroup.php b/actions/editgroup.php index 0e04170051..08a75da12c 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -139,7 +139,7 @@ class EditgroupAction extends GroupDesignAction $this->showPage(); } - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); From 3c683ad7b54a1cc5decfe8c312b1580113c8eb31 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:11:19 -0500 Subject: [PATCH 19/68] default local nav in popular notices --- actions/favorited.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/actions/favorited.php b/actions/favorited.php index c137cf424f..17c2a58c94 100644 --- a/actions/favorited.php +++ b/actions/favorited.php @@ -163,19 +163,6 @@ class FavoritedAction extends Action $this->elementEnd('div'); } - /** - * Local navigation - * - * This page is part of the public group, so show that. - * - * @return void - */ - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - /** * Content area * From 0850c66a21dac58919ba4e3a8739602dce68b029 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:11:59 -0500 Subject: [PATCH 20/68] default local nav in featured user list --- actions/featured.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/actions/featured.php b/actions/featured.php index 9a7f128b57..394cfe6a8b 100644 --- a/actions/featured.php +++ b/actions/featured.php @@ -90,12 +90,6 @@ class FeaturedAction extends Action $this->elementEnd('div'); } - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - function getInstructions() { // TRANS: Description on page displaying featured users. From 4903c92dcec6d1ea0b7174efd6c15c261606077f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:15:03 -0500 Subject: [PATCH 21/68] show defaultlocalnav in groupdesignsettings --- actions/groupdesignsettings.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/actions/groupdesignsettings.php b/actions/groupdesignsettings.php index 3ef5e20e44..798064d16c 100644 --- a/actions/groupdesignsettings.php +++ b/actions/groupdesignsettings.php @@ -163,12 +163,22 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return nothing */ - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); } + /** + * Override to show default nav stuff + * + * @return nothing + */ + function showLocalNav() + { + Action::showLocalNav(); + } + /** * Get the design we want to edit * From 0c877860b51412d54ee876f15f4cdad18a8db274 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:17:01 -0500 Subject: [PATCH 22/68] show defaultlocalnav in grouplogo --- actions/grouplogo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/grouplogo.php b/actions/grouplogo.php index d490cd9875..db0d40ff0c 100644 --- a/actions/grouplogo.php +++ b/actions/grouplogo.php @@ -458,7 +458,7 @@ class GrouplogoAction extends GroupDesignAction $this->autofocus('avatarfile'); } - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); From f29274cd0d44079a602d23607b62616488068709 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:17:42 -0500 Subject: [PATCH 23/68] show defaultlocalnav in groupmembers --- actions/groupmembers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 7b1512dfab..e280fd1fd1 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -125,7 +125,7 @@ class GroupmembersAction extends GroupDesignAction _('A list of the users in this group.')); } - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); From 6ee77f1302014167fdcccb46b7ea76b368234b41 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:18:33 -0500 Subject: [PATCH 24/68] defaultlocalnav in groups --- actions/groups.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/actions/groups.php b/actions/groups.php index 958c5921bf..d1bc8d9458 100644 --- a/actions/groups.php +++ b/actions/groups.php @@ -80,12 +80,6 @@ class GroupsAction extends Action $this->showPage(); } - function showLocalNav() - { - $nav = new PublicGroupNav($this); - $nav->show(); - } - function showPageNotice() { $notice = From 55fa14baec295669f3546a35eeb34bb15a841fc8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:20:14 -0500 Subject: [PATCH 25/68] object menu in inviteaction --- actions/invite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/invite.php b/actions/invite.php index a2a0e0714a..c64ff8adda 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -289,7 +289,7 @@ class InviteAction extends CurrentUserDesignAction mail_send($recipients, $headers, $body); } - function showLocalNav() + function showObjectNav() { $nav = new SubGroupNav($this, common_current_user()); $nav->show(); From 374253f0f751e2d0a81035853d5f577c64b07aba Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:21:22 -0500 Subject: [PATCH 26/68] defaultlocalnav for favorites --- actions/showfavorites.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/actions/showfavorites.php b/actions/showfavorites.php index eda2cf38eb..67ee914a91 100644 --- a/actions/showfavorites.php +++ b/actions/showfavorites.php @@ -189,17 +189,6 @@ class ShowfavoritesAction extends OwnerDesignAction $this->user->nickname))); } - /** - * show the personal group nav - * - * @return void - */ - function showLocalNav() - { - $nav = new PersonalGroupNav($this); - $nav->show(); - } - function showEmptyListMessage() { if (common_logged_in()) { From a1a0382d26fdd444bb574081649406980cae383b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:22:19 -0500 Subject: [PATCH 27/68] object menu on showgroup --- actions/showgroup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/showgroup.php b/actions/showgroup.php index 21256294f3..397ca30505 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -167,7 +167,7 @@ class ShowgroupAction extends GroupDesignAction * * @return void */ - function showLocalNav() + function showObjectNav() { $nav = new GroupNav($this, $this->group); $nav->show(); From 64a1c9e3761639c30e5fe33fed9d2cfde201e0bb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:23:19 -0500 Subject: [PATCH 28/68] object menu for user profile --- actions/showstream.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/showstream.php b/actions/showstream.php index 0fd1c2c29f..afde49ecea 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -104,7 +104,7 @@ class ShowstreamAction extends ProfileAction $this->showNotices(); } - function showLocalNav() + function showObjectNav() { $nav = new SubGroupNav($this, $this->user); $nav->show(); From c4b53b4aefe5a7d69ce912d0908e55aae8768f35 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:35:25 -0500 Subject: [PATCH 29/68] don't show full profile menu all the time --- lib/defaultlocalnav.php | 3 --- lib/personalgroupnav.php | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/defaultlocalnav.php b/lib/defaultlocalnav.php index b42d3a804c..7af3c9673f 100644 --- a/lib/defaultlocalnav.php +++ b/lib/defaultlocalnav.php @@ -56,9 +56,6 @@ class DefaultLocalNav extends Menu if (!empty($user)) { $pn = new PersonalGroupNav($this->action); $this->submenu(_m('Home'), $pn); - - $sn = new SubGroupNav($this->action, $user); - $this->submenu(_m('Profile'), $sn); } $bn = new PublicGroupNav($this->action); diff --git a/lib/personalgroupnav.php b/lib/personalgroupnav.php index 6a31358596..e428e92e63 100644 --- a/lib/personalgroupnav.php +++ b/lib/personalgroupnav.php @@ -71,6 +71,12 @@ class PersonalGroupNav extends Menu _('Home'), sprintf(_('%s and friends'), $name), $action == 'all', 'nav_timeline_personal'); + $this->out->menuItem(common_local_url('showstream', array('nickname' => + $this->user->nickname)), + _('Profile'), + (empty($profile)) ? $this->user->nickname : $profile->getBestName(), + $action == 'showstream', + 'nav_profile'); $this->out->menuItem(common_local_url('replies', array('nickname' => $nickname)), _('Replies'), From 815a9a0c3e634be678aec1dce80a2364f7bd3897 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:37:21 -0500 Subject: [PATCH 30/68] fixup link to your profile --- lib/personalgroupnav.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/personalgroupnav.php b/lib/personalgroupnav.php index e428e92e63..348195a99d 100644 --- a/lib/personalgroupnav.php +++ b/lib/personalgroupnav.php @@ -72,9 +72,9 @@ class PersonalGroupNav extends Menu sprintf(_('%s and friends'), $name), $action == 'all', 'nav_timeline_personal'); $this->out->menuItem(common_local_url('showstream', array('nickname' => - $this->user->nickname)), + $nickname)), _('Profile'), - (empty($profile)) ? $this->user->nickname : $profile->getBestName(), + _('Your profile'), $action == 'showstream', 'nav_profile'); $this->out->menuItem(common_local_url('replies', array('nickname' => From 5bbcededa752133b2e607e8309d381df67f6a250 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 1 Mar 2011 16:48:20 -0500 Subject: [PATCH 31/68] move inbox/outbox to object menu --- lib/mailbox.php | 6 ++++ lib/mailboxmenu.php | 70 ++++++++++++++++++++++++++++++++++++++++ lib/personalgroupnav.php | 8 ++--- 3 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 lib/mailboxmenu.php diff --git a/lib/mailbox.php b/lib/mailbox.php index 7faeb7dba3..cb56eb5904 100644 --- a/lib/mailbox.php +++ b/lib/mailbox.php @@ -168,4 +168,10 @@ class MailboxAction extends CurrentUserDesignAction { return true; } + + function showObjectNav() + { + $mm = new MailboxMenu($this); + $mm->show(); + } } diff --git a/lib/mailboxmenu.php b/lib/mailboxmenu.php new file mode 100644 index 0000000000..d2d3607dce --- /dev/null +++ b/lib/mailboxmenu.php @@ -0,0 +1,70 @@ +. + * + * @category Cache + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Menu of existing mailboxes + * + * @category General + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class MailboxMenu extends Menu +{ + function show() + { + $cur = common_current_user(); + $nickname = $cur->nickname; + + $this->out->elementStart('ul', array('class' => 'nav')); + + $this->item('inbox', + array('nickname' => $nickname), + _('Inbox'), + _('Your incoming messages')); + + $this->item('outbox', + array('nickname' => $nickname), + _('Outbox'), + _('Your sent messages')); + + $this->out->elementEnd('ul'); + } + +} diff --git a/lib/personalgroupnav.php b/lib/personalgroupnav.php index 348195a99d..9d78857c6d 100644 --- a/lib/personalgroupnav.php +++ b/lib/personalgroupnav.php @@ -95,15 +95,11 @@ class PersonalGroupNav extends Menu $this->out->menuItem(common_local_url('inbox', array('nickname' => $nickname)), - _('Inbox'), + _('Messages'), _('Your incoming messages'), $action == 'inbox'); - $this->out->menuItem(common_local_url('outbox', array('nickname' => - $nickname)), - _('Outbox'), - _('Your sent messages'), - $action == 'outbox'); } + Event::handle('EndPersonalGroupNav', array($this)); } $this->out->elementEnd('ul'); From 53db4c2b85b27db85c8d29f059fe893f5c0b3745 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 2 Mar 2011 22:09:11 -0500 Subject: [PATCH 32/68] move notice form to content block --- lib/action.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/action.php b/lib/action.php index 5917d31b36..dc95b030d2 100644 --- a/lib/action.php +++ b/lib/action.php @@ -464,14 +464,7 @@ class Action extends HTMLOutputter // lawsuit Event::handle('EndShowSiteNotice', array($this)); } - if (common_logged_in()) { - if (Event::handle('StartShowNoticeForm', array($this))) { - $this->showNoticeForm(); - Event::handle('EndShowNoticeForm', array($this)); - } - } else { - $this->showAnonymousMessage(); - } + $this->elementEnd('div'); } @@ -679,6 +672,12 @@ class Action extends HTMLOutputter // lawsuit function showContentBlock() { $this->elementStart('div', array('id' => 'content')); + if (common_logged_in()) { + if (Event::handle('StartShowNoticeForm', array($this))) { + $this->showNoticeForm(); + Event::handle('EndShowNoticeForm', array($this)); + } + } if (Event::handle('StartShowPageTitle', array($this))) { $this->showPageTitle(); Event::handle('EndShowPageTitle', array($this)); From 85610d0881b9b40171100e4b913f3ff86305db8c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 2 Mar 2011 22:09:26 -0500 Subject: [PATCH 33/68] no notice form on settings pages --- lib/settingsaction.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/settingsaction.php b/lib/settingsaction.php index 8c00054dcb..dc60137ab4 100644 --- a/lib/settingsaction.php +++ b/lib/settingsaction.php @@ -163,4 +163,15 @@ class SettingsAction extends CurrentUserDesignAction $menu = new SettingsNav($this); $menu->show(); } + + /** + * Show notice form. + * + * @return nothing + */ + + function showNoticeForm() + { + return; + } } From 04189184612259914dacfb4dceae34f2c74cd425 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 3 Mar 2011 16:53:44 -0500 Subject: [PATCH 34/68] first pass at microapp class --- lib/microapp.php | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 lib/microapp.php diff --git a/lib/microapp.php b/lib/microapp.php new file mode 100644 index 0000000000..77e6abb7e3 --- /dev/null +++ b/lib/microapp.php @@ -0,0 +1,59 @@ +. + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Superclass for microapp plugins + * + * This class lets you define micro-applications with different kinds of activities. + * + * The applications work more-or-less like other + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class MicroAppPlugin extends Plugin +{ + abstract function isMyNotice($notice); + abstract function isMyActivity($activity); + abstract function saveNoticeFromActivity($activity); + abstract function activityFromNotice($notice); + abstract function showNotice($notice, $out); +} From 2695ead7b2f6c99eeb9aae10344c152bb8ef01cb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 3 Mar 2011 16:57:16 -0500 Subject: [PATCH 35/68] add activity object type to notice --- db/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/db/core.php b/db/core.php index 55d724b505..62730b853f 100644 --- a/db/core.php +++ b/db/core.php @@ -201,6 +201,7 @@ $schema['notice'] = array( 'location_id' => array('type' => 'int', 'description' => 'location id if possible'), 'location_ns' => array('type' => 'int', 'description' => 'namespace for location'), 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'), + 'object_type' => array('type' => 'varchar', 'length' => 32, 'description' => 'URI representing activity streams object type'), ), 'primary key' => array('id'), 'unique keys' => array( From 0fb1f10480bc574bca28955ff16e174dff49c7c8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 4 Mar 2011 16:41:17 -0500 Subject: [PATCH 36/68] correct length and default value for object_type --- db/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/core.php b/db/core.php index 62730b853f..16a59462d4 100644 --- a/db/core.php +++ b/db/core.php @@ -201,7 +201,7 @@ $schema['notice'] = array( 'location_id' => array('type' => 'int', 'description' => 'location id if possible'), 'location_ns' => array('type' => 'int', 'description' => 'namespace for location'), 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'), - 'object_type' => array('type' => 'varchar', 'length' => 32, 'description' => 'URI representing activity streams object type'), + 'object_type' => array('type' => 'varchar', 'length' => 255, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'), ), 'primary key' => array('id'), 'unique keys' => array( From 031f5a98f7554c4a396903a010e4d99f93444f6c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 5 Mar 2011 14:47:37 -0500 Subject: [PATCH 37/68] add a couple of methods to MicroAppPlugin --- lib/microapp.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/microapp.php b/lib/microapp.php index 77e6abb7e3..23b4b5bb84 100644 --- a/lib/microapp.php +++ b/lib/microapp.php @@ -49,11 +49,22 @@ if (!defined('STATUSNET')) { * @link http://status.net/ */ -class MicroAppPlugin extends Plugin +abstract class MicroAppPlugin extends Plugin { - abstract function isMyNotice($notice); - abstract function isMyActivity($activity); + abstract function types(); abstract function saveNoticeFromActivity($activity); abstract function activityFromNotice($notice); abstract function showNotice($notice, $out); + abstract function entryForm(); + + function isMyNotice($notice) { + $types = $this->types(); + return in_array($notice->object_type, $types); + } + + function isMyActivity($activity) { + $types = $this->types(); + return (count($activity->objects) == 1 && + in_array($activity->objects[0]->type, $types)); + } } From 7184036cf2f8dd0641b23449341be989f085c920 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 5 Mar 2011 14:48:10 -0500 Subject: [PATCH 38/68] move microapp.php to microappplugin.php --- lib/microappplugin.php | 70 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 lib/microappplugin.php diff --git a/lib/microappplugin.php b/lib/microappplugin.php new file mode 100644 index 0000000000..23b4b5bb84 --- /dev/null +++ b/lib/microappplugin.php @@ -0,0 +1,70 @@ +. + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Superclass for microapp plugins + * + * This class lets you define micro-applications with different kinds of activities. + * + * The applications work more-or-less like other + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +abstract class MicroAppPlugin extends Plugin +{ + abstract function types(); + abstract function saveNoticeFromActivity($activity); + abstract function activityFromNotice($notice); + abstract function showNotice($notice, $out); + abstract function entryForm(); + + function isMyNotice($notice) { + $types = $this->types(); + return in_array($notice->object_type, $types); + } + + function isMyActivity($activity) { + $types = $this->types(); + return (count($activity->objects) == 1 && + in_array($activity->objects[0]->type, $types)); + } +} From 17db6cce3d85fd464529443076466045fcba467a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 6 Mar 2011 16:33:36 -0500 Subject: [PATCH 39/68] first (non-working) move to microapp structure for bookmarks --- lib/microapp.php | 70 ---- lib/microappplugin.php | 214 +++++++++- plugins/Bookmark/BookmarkPlugin.php | 591 ++++++++++------------------ 3 files changed, 420 insertions(+), 455 deletions(-) delete mode 100644 lib/microapp.php diff --git a/lib/microapp.php b/lib/microapp.php deleted file mode 100644 index 23b4b5bb84..0000000000 --- a/lib/microapp.php +++ /dev/null @@ -1,70 +0,0 @@ -. - * - * @category Microapp - * @package StatusNet - * @author Evan Prodromou - * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET')) { - // This check helps protect against security problems; - // your code file can't be executed directly from the web. - exit(1); -} - -/** - * Superclass for microapp plugins - * - * This class lets you define micro-applications with different kinds of activities. - * - * The applications work more-or-less like other - * - * @category Microapp - * @package StatusNet - * @author Evan Prodromou - * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ - */ - -abstract class MicroAppPlugin extends Plugin -{ - abstract function types(); - abstract function saveNoticeFromActivity($activity); - abstract function activityFromNotice($notice); - abstract function showNotice($notice, $out); - abstract function entryForm(); - - function isMyNotice($notice) { - $types = $this->types(); - return in_array($notice->object_type, $types); - } - - function isMyActivity($activity) { - $types = $this->types(); - return (count($activity->objects) == 1 && - in_array($activity->objects[0]->type, $types)); - } -} diff --git a/lib/microappplugin.php b/lib/microappplugin.php index 23b4b5bb84..1cdbe965e6 100644 --- a/lib/microappplugin.php +++ b/lib/microappplugin.php @@ -51,11 +51,14 @@ if (!defined('STATUSNET')) { abstract class MicroAppPlugin extends Plugin { + abstract function appTitle(); + abstract function tag(); abstract function types(); - abstract function saveNoticeFromActivity($activity); - abstract function activityFromNotice($notice); + abstract function saveNoticeFromActivity($activity, $actor); + abstract function activityObjectFromNotice($notice); abstract function showNotice($notice, $out); - abstract function entryForm(); + abstract function entryForm($out); + abstract function deleteRelated($notice); function isMyNotice($notice) { $types = $this->types(); @@ -67,4 +70,209 @@ abstract class MicroAppPlugin extends Plugin return (count($activity->objects) == 1 && in_array($activity->objects[0]->type, $types)); } + + /** + * When a notice is deleted, delete the related objects + * + * @param Notice $notice Notice being deleted + * + * @return boolean hook value + */ + + function onNoticeDeleteRelated($notice) + { + if ($this->isMyNotice($notice)) { + $this->deleteRelated($notice); + } + + return true; + } + + /** + * Output the HTML for this kind of object in a list + * + * @param NoticeListItem $nli The list item being shown. + * + * @return boolean hook value + */ + + function onStartShowNoticeItem($nli) + { + if (!$this->isMyNotice($nli->notice)) { + return true; + } + + $out = $nli->out; + + $this->showNotice($notice, $out); + + $nli->showNoticeLink(); + $nli->showNoticeSource(); + $nli->showNoticeLocation(); + $nli->showContext(); + $nli->showRepeat(); + + $out->elementEnd('div'); + + $nli->showNoticeOptions(); + + return false; + } + + /** + * Render a notice as one of our objects + * + * @param Notice $notice Notice to render + * @param ActivityObject &$object Empty object to fill + * + * @return boolean hook value + */ + + function onStartActivityObjectFromNotice($notice, &$object) + { + if ($this->isMyNotice($notice)) { + $object = $this->activityObjectFromNotice($notice); + return false; + } + + return true; + } + + /** + * Handle a posted object from PuSH + * + * @param Activity $activity activity to handle + * @param Ostatus_profile $oprofile Profile for the feed + * + * @return boolean hook value + */ + + function onStartHandleFeedEntryWithProfile($activity, $oprofile) + { + if ($this->isMyActivity($activity)) { + + $actor = $oprofile->checkAuthorship($activity); + + if (empty($actor)) { + throw new ClientException(_('Can\'t get author for activity.')); + } + + $this->saveNoticeFromActivity($activity, $actor); + + return false; + } + + return true; + } + + /** + * Handle a posted object from Salmon + * + * @param Activity $activity activity to handle + * @param mixed $target user or group targeted + * + * @return boolean hook value + */ + + function onStartHandleSalmonTarget($activity, $target) + { + if ($this->isMyActivity($activity)) { + + $this->log(LOG_INFO, "Checking {$activity->id} as a valid Salmon slap."); + + if ($target instanceof User_group) { + $uri = $target->getUri(); + if (!in_array($uri, $activity->context->attention)) { + throw new ClientException(_("Bookmark not posted ". + "to this group.")); + } + } else if ($target instanceof User) { + $uri = $target->uri; + $original = null; + if (!empty($activity->context->replyToID)) { + $original = Notice::staticGet('uri', + $activity->context->replyToID); + } + if (!in_array($uri, $activity->context->attention) && + (empty($original) || + $original->profile_id != $target->id)) { + throw new ClientException(_("Bookmark not posted ". + "to this user.")); + } + } else { + throw new ServerException(_("Don't know how to handle ". + "this kind of target.")); + } + + $actor = Ostatus_profile::ensureActivityObjectProfile($activity->actor); + + $this->saveNoticeFromActivity($activity, $actor); + + return false; + } + + return true; + } + + /** + * Handle object posted via AtomPub + * + * @param Activity &$activity Activity that was posted + * @param User $user User that posted it + * @param Notice &$notice Resulting notice + * + * @return boolean hook value + */ + + function onStartAtomPubNewActivity(&$activity, $user, &$notice) + { + if ($this->isMyActivity($activity)) { + + $options = array('source' => 'atompub'); + + $this->saveNoticeFromActivity($activity, + $user->getProfile(), + $options); + + return false; + } + + return true; + } + + /** + * Handle object imported from a backup file + * + * @param User $user User to import for + * @param ActivityObject $author Original author per import file + * @param Activity $activity Activity to import + * @param boolean $trusted Is this a trusted user? + * @param boolean &$done Is this done (success or unrecoverable error) + * + * @return boolean hook value + */ + + function onStartImportActivity($user, $author, $activity, $trusted, &$done) + { + if ($this->isMyActivity($activity)) { + + $obj = $activity->objects[0]; + + $options = array('uri' => $bookmark->id, + 'url' => $bookmark->link, + 'source' => 'restore'); + + $saved = $this->saveNoticeFromActivity($activity, + $user->getProfile(), + $options); + + if (!empty($saved)) { + $done = true; + } + + return false; + } + + return true; + } } diff --git a/plugins/Bookmark/BookmarkPlugin.php b/plugins/Bookmark/BookmarkPlugin.php index 2e6baf5e4e..c3ff17c4e9 100644 --- a/plugins/Bookmark/BookmarkPlugin.php +++ b/plugins/Bookmark/BookmarkPlugin.php @@ -44,7 +44,7 @@ if (!defined('STATUSNET')) { * @link http://status.net/ */ -class BookmarkPlugin extends Plugin +class BookmarkPlugin extends MicroAppPlugin { const VERSION = '0.1'; const IMPORTDELICIOUS = 'BookmarkPlugin:IMPORTDELICIOUS'; @@ -120,25 +120,6 @@ class BookmarkPlugin extends Plugin return true; } - /** - * When a notice is deleted, delete the related Bookmark - * - * @param Notice $notice Notice being deleted - * - * @return boolean hook value - */ - - function onNoticeDeleteRelated($notice) - { - $nb = Bookmark::getByNotice($notice); - - if (!empty($nb)) { - $nb->delete(); - } - - return true; - } - /** * Show the CSS necessary for this plugin * @@ -218,212 +199,6 @@ class BookmarkPlugin extends Plugin return true; } - /** - * Output the HTML for a bookmark in a list - * - * @param NoticeListItem $nli The list item being shown. - * - * @return boolean hook value - */ - - function onStartShowNoticeItem($nli) - { - $nb = Bookmark::getByNotice($nli->notice); - - if (!empty($nb)) { - - $out = $nli->out; - $notice = $nli->notice; - $profile = $nli->profile; - - $atts = $notice->attachments(); - - if (count($atts) < 1) { - // Something wrong; let default code deal with it. - return true; - } - - $att = $atts[0]; - - // XXX: only show the bookmark URL for non-single-page stuff - - if ($out instanceof ShowbookmarkAction) { - } else { - $out->elementStart('h3'); - $out->element('a', - array('href' => $att->url, - 'class' => 'bookmark-title entry-title'), - $nb->title); - $out->elementEnd('h3'); - - $countUrl = common_local_url('noticebyurl', - array('id' => $att->id)); - - $out->element('a', array('class' => 'bookmark-notice-count', - 'href' => $countUrl), - $att->noticeCount()); - } - - // Replies look like "for:" tags - - $replies = $nli->notice->getReplies(); - $tags = $nli->notice->getTags(); - - if (!empty($replies) || !empty($tags)) { - - $out->elementStart('ul', array('class' => 'bookmark-tags')); - - foreach ($replies as $reply) { - $other = Profile::staticGet('id', $reply); - $out->elementStart('li'); - $out->element('a', array('rel' => 'tag', - 'href' => $other->profileurl, - 'title' => $other->getBestName()), - sprintf('for:%s', $other->nickname)); - $out->elementEnd('li'); - $out->text(' '); - } - - foreach ($tags as $tag) { - $out->elementStart('li'); - $out->element('a', - array('rel' => 'tag', - 'href' => Notice_tag::url($tag)), - $tag); - $out->elementEnd('li'); - $out->text(' '); - } - - $out->elementEnd('ul'); - } - - if (!empty($nb->description)) { - $out->element('p', - array('class' => 'bookmark-description'), - $nb->description); - } - - if (common_config('attachments', 'show_thumbs')) { - $haveThumbs = false; - foreach ($atts as $check) { - $thumbnail = File_thumbnail::staticGet('file_id', $check->id); - if (!empty($thumbnail)) { - $haveThumbs = true; - break; - } - } - if ($haveThumbs) { - $al = new InlineAttachmentList($notice, $out); - $al->show(); - } - } - - $out->elementStart('div', array('class' => 'bookmark-info entry-content')); - - $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); - - $out->element('img', - array('src' => ($avatar) ? - $avatar->displayUrl() : - Avatar::defaultImage(AVATAR_MINI_SIZE), - 'class' => 'avatar photo bookmark-avatar', - 'width' => AVATAR_MINI_SIZE, - 'height' => AVATAR_MINI_SIZE, - 'alt' => $profile->getBestName())); - - $out->raw(' '); - - $out->element('a', - array('href' => $profile->profileurl, - 'title' => $profile->getBestName()), - $profile->nickname); - - $nli->showNoticeLink(); - $nli->showNoticeSource(); - $nli->showNoticeLocation(); - $nli->showContext(); - $nli->showRepeat(); - - $out->elementEnd('div'); - - $nli->showNoticeOptions(); - - return false; - } - return true; - } - - /** - * Render a notice as a Bookmark object - * - * @param Notice $notice Notice to render - * @param ActivityObject &$object Empty object to fill - * - * @return boolean hook value - */ - - function onStartActivityObjectFromNotice($notice, &$object) - { - common_log(LOG_INFO, - "Checking {$notice->uri} to see if it's a bookmark."); - - $nb = Bookmark::getByNotice($notice); - - if (!empty($nb)) { - - common_log(LOG_INFO, - "Formatting notice {$notice->uri} as a bookmark."); - - $object->id = $notice->uri; - $object->type = ActivityObject::BOOKMARK; - $object->title = $nb->title; - $object->summary = $nb->description; - $object->link = $notice->bestUrl(); - - // Attributes of the URL - - $attachments = $notice->attachments(); - - if (count($attachments) != 1) { - throw new ServerException(_('Bookmark notice with the '. - 'wrong number of attachments.')); - } - - $target = $attachments[0]; - - $attrs = array('rel' => 'related', - 'href' => $target->url); - - if (!empty($target->title)) { - $attrs['title'] = $target->title; - } - - $object->extra[] = array('link', $attrs, null); - - // Attributes of the thumbnail, if any - - $thumbnail = $target->getThumbnail(); - - if (!empty($thumbnail)) { - $tattrs = array('rel' => 'preview', - 'href' => $thumbnail->url); - - if (!empty($thumbnail->width)) { - $tattrs['media:width'] = $thumbnail->width; - } - - if (!empty($thumbnail->height)) { - $tattrs['media:height'] = $thumbnail->height; - } - - $object->extra[] = array('link', $attrs, null); - } - - return false; - } - - return true; - } /** * Add our two queue handlers to the queue manager @@ -481,149 +256,7 @@ class BookmarkPlugin extends Plugin return true; } - /** - * Handle a posted bookmark from PuSH - * - * @param Activity $activity activity to handle - * @param Ostatus_profile $oprofile Profile for the feed - * - * @return boolean hook value - */ - function onStartHandleFeedEntryWithProfile($activity, $oprofile) - { - common_log(LOG_INFO, "BookmarkPlugin called for new feed entry."); - - if (self::_isPostBookmark($activity)) { - - common_log(LOG_INFO, - "Importing activity {$activity->id} as a bookmark."); - - $author = $oprofile->checkAuthorship($activity); - - if (empty($author)) { - throw new ClientException(_('Can\'t get author for activity.')); - } - - self::_postRemoteBookmark($author, - $activity); - - return false; - } - - return true; - } - - /** - * Handle a posted bookmark from Salmon - * - * @param Activity $activity activity to handle - * @param mixed $target user or group targeted - * - * @return boolean hook value - */ - - function onStartHandleSalmonTarget($activity, $target) - { - if (self::_isPostBookmark($activity)) { - - $this->log(LOG_INFO, "Checking {$activity->id} as a valid Salmon slap."); - - if ($target instanceof User_group) { - $uri = $target->getUri(); - if (!in_array($uri, $activity->context->attention)) { - throw new ClientException(_("Bookmark not posted ". - "to this group.")); - } - } else if ($target instanceof User) { - $uri = $target->uri; - $original = null; - if (!empty($activity->context->replyToID)) { - $original = Notice::staticGet('uri', - $activity->context->replyToID); - } - if (!in_array($uri, $activity->context->attention) && - (empty($original) || - $original->profile_id != $target->id)) { - throw new ClientException(_("Bookmark not posted ". - "to this user.")); - } - } else { - throw new ServerException(_("Don't know how to handle ". - "this kind of target.")); - } - - $author = Ostatus_profile::ensureActivityObjectProfile($activity->actor); - - self::_postRemoteBookmark($author, - $activity); - - return false; - } - - return true; - } - - /** - * Handle bookmark posted via AtomPub - * - * @param Activity &$activity Activity that was posted - * @param User $user User that posted it - * @param Notice &$notice Resulting notice - * - * @return boolean hook value - */ - - function onStartAtomPubNewActivity(&$activity, $user, &$notice) - { - if (self::_isPostBookmark($activity)) { - $options = array('source' => 'atompub'); - $notice = self::_postBookmark($user->getProfile(), - $activity, - $options); - return false; - } - - return true; - } - - /** - * Handle bookmark imported from a backup file - * - * @param User $user User to import for - * @param ActivityObject $author Original author per import file - * @param Activity $activity Activity to import - * @param boolean $trusted Is this a trusted user? - * @param boolean &$done Is this done (success or unrecoverable error) - * - * @return boolean hook value - */ - - function onStartImportActivity($user, $author, $activity, $trusted, &$done) - { - if (self::_isPostBookmark($activity)) { - - $bookmark = $activity->objects[0]; - - $this->log(LOG_INFO, - 'Importing Bookmark ' . $bookmark->id . - ' for user ' . $user->nickname); - - $options = array('uri' => $bookmark->id, - 'url' => $bookmark->link, - 'source' => 'restore'); - - $saved = self::_postBookmark($user->getProfile(), $activity, $options); - - if (!empty($saved)) { - $done = true; - } - - return false; - } - - return true; - } /** * Show a link to our delicious import page on profile settings form @@ -691,6 +324,44 @@ class BookmarkPlugin extends Plugin return self::_postBookmark($author->localProfile(), $activity, $options); } + /** + * Test if an activity represents posting a bookmark + * + * @param Activity $activity Activity to test + * + * @return true if it's a Post of a Bookmark, else false + */ + + static private function _isPostBookmark($activity) + { + return ($activity->verb == ActivityVerb::POST && + $activity->objects[0]->type == ActivityObject::BOOKMARK); + } + + function types() + { + return array(ActivityObject::BOOKMARK); + } + + /** + * When a notice is deleted, delete the related Bookmark + * + * @param Notice $notice Notice being deleted + * + * @return boolean hook value + */ + + function deleteRelated($notice) + { + $nb = Bookmark::getByNotice($notice); + + if (!empty($nb)) { + $nb->delete(); + } + + return true; + } + /** * Save a bookmark from an activity * @@ -701,10 +372,10 @@ class BookmarkPlugin extends Plugin * @return Notice resulting notice */ - static private function _postBookmark(Profile $profile, - Activity $activity, - $options=array()) + function saveNoticeFromActivity($activity, $profile) { + $options = array(); + $bookmark = $activity->objects[0]; $relLinkEls = ActivityUtils::getLinks($bookmark->element, 'related'); @@ -782,17 +453,173 @@ class BookmarkPlugin extends Plugin $options); } - /** - * Test if an activity represents posting a bookmark - * - * @param Activity $activity Activity to test - * - * @return true if it's a Post of a Bookmark, else false - */ - - static private function _isPostBookmark($activity) + function activityObjectFromNotice($notice) { - return ($activity->verb == ActivityVerb::POST && - $activity->objects[0]->type == ActivityObject::BOOKMARK); + assert($this->isMyNotice($notice)); + + common_log(LOG_INFO, + "Formatting notice {$notice->uri} as a bookmark."); + + $object = new ActivityObject(); + + $object->id = $notice->uri; + $object->type = ActivityObject::BOOKMARK; + $object->title = $nb->title; + $object->summary = $nb->description; + $object->link = $notice->bestUrl(); + + // Attributes of the URL + + $attachments = $notice->attachments(); + + if (count($attachments) != 1) { + throw new ServerException(_('Bookmark notice with the '. + 'wrong number of attachments.')); + } + + $target = $attachments[0]; + + $attrs = array('rel' => 'related', + 'href' => $target->url); + + if (!empty($target->title)) { + $attrs['title'] = $target->title; + } + + $object->extra[] = array('link', $attrs, null); + + // Attributes of the thumbnail, if any + + $thumbnail = $target->getThumbnail(); + + if (!empty($thumbnail)) { + $tattrs = array('rel' => 'preview', + 'href' => $thumbnail->url); + + if (!empty($thumbnail->width)) { + $tattrs['media:width'] = $thumbnail->width; + } + + if (!empty($thumbnail->height)) { + $tattrs['media:height'] = $thumbnail->height; + } + + $object->extra[] = array('link', $attrs, null); + } + + return $object; } + + function showNotice($notice, $out) + { + $profile = $notice->getProfile(); + + $atts = $notice->attachments(); + + if (count($atts) < 1) { + // Something wrong; let default code deal with it. + throw new Exception("That can't be right."); + } + + $att = $atts[0]; + + // XXX: only show the bookmark URL for non-single-page stuff + + if ($out instanceof ShowbookmarkAction) { + } else { + $out->elementStart('h3'); + $out->element('a', + array('href' => $att->url, + 'class' => 'bookmark-title entry-title'), + $nb->title); + $out->elementEnd('h3'); + + $countUrl = common_local_url('noticebyurl', + array('id' => $att->id)); + + $out->element('a', array('class' => 'bookmark-notice-count', + 'href' => $countUrl), + $att->noticeCount()); + } + + // Replies look like "for:" tags + + $replies = $nli->notice->getReplies(); + $tags = $nli->notice->getTags(); + + if (!empty($replies) || !empty($tags)) { + + $out->elementStart('ul', array('class' => 'bookmark-tags')); + + foreach ($replies as $reply) { + $other = Profile::staticGet('id', $reply); + $out->elementStart('li'); + $out->element('a', array('rel' => 'tag', + 'href' => $other->profileurl, + 'title' => $other->getBestName()), + sprintf('for:%s', $other->nickname)); + $out->elementEnd('li'); + $out->text(' '); + } + + foreach ($tags as $tag) { + $out->elementStart('li'); + $out->element('a', + array('rel' => 'tag', + 'href' => Notice_tag::url($tag)), + $tag); + $out->elementEnd('li'); + $out->text(' '); + } + + $out->elementEnd('ul'); + } + + if (!empty($nb->description)) { + $out->element('p', + array('class' => 'bookmark-description'), + $nb->description); + } + + if (common_config('attachments', 'show_thumbs')) { + $haveThumbs = false; + foreach ($atts as $check) { + $thumbnail = File_thumbnail::staticGet('file_id', $check->id); + if (!empty($thumbnail)) { + $haveThumbs = true; + break; + } + } + if ($haveThumbs) { + $al = new InlineAttachmentList($notice, $out); + $al->show(); + } + } + + $out->elementStart('div', array('class' => 'bookmark-info entry-content')); + + $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); + + $out->element('img', + array('src' => ($avatar) ? + $avatar->displayUrl() : + Avatar::defaultImage(AVATAR_MINI_SIZE), + 'class' => 'avatar photo bookmark-avatar', + 'width' => AVATAR_MINI_SIZE, + 'height' => AVATAR_MINI_SIZE, + 'alt' => $profile->getBestName())); + + $out->raw(' '); + + $out->element('a', + array('href' => $profile->profileurl, + 'title' => $profile->getBestName()), + $profile->nickname); + } + + function entryForm($out) + { + return new BookmarkForm($out); + } + } From b54a9f389cacd6b4efd5499316a10729e89e2578 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 6 Mar 2011 17:27:03 -0500 Subject: [PATCH 40/68] made the input-form switcher work, kinda --- lib/action.php | 56 +++++++++++++++++++++++++++-- lib/microappplugin.php | 42 +++++++++++++++++++--- plugins/Bookmark/BookmarkPlugin.php | 13 +++++-- 3 files changed, 101 insertions(+), 10 deletions(-) diff --git a/lib/action.php b/lib/action.php index 650f706a4b..1c616daf89 100644 --- a/lib/action.php +++ b/lib/action.php @@ -640,8 +640,60 @@ class Action extends HTMLOutputter // lawsuit */ function showNoticeForm() { - $notice_form = new NoticeForm($this); - $notice_form->show(); + $tabs = array('status' => _('Status')); + + $this->elementStart('div', 'input_forms'); + + if (Event::handle('StartShowEntryForms', array(&$tabs))) { + + $this->elementStart('ul', array('class' => 'nav', + 'id' => 'input_form_nav')); + + foreach ($tabs as $tag => $title) { + + $attrs = array('id' => 'input_form_nav_'.$title); + + if ($tag == 'status') { + $attrs['class'] = 'current'; + } + + $this->elementStart('li', $attrs); + + $this->element('a', + array('href' => 'javascript:switchInputFormTab("'.$tag.'")'), + $title); + $this->elementEnd('li'); + } + + $this->elementEnd('ul'); + + foreach ($tabs as $tag => $title) { + + $attrs = array('class' => 'input_form', + 'id' => 'input_form_'.$tag); + + if ($tag == 'status') { + $attrs['class'] .= ' active'; + } else { + $attrs['class'] .= ' inactive'; + } + + $this->elementStart('div', $attrs); + + $form = null; + + if (Event::handle('StartMakeEntryForm', array($tag, $this, &$form))) { + if ($tag == 'status') { + $form = new NoticeForm($this); + } + Event::handle('EndMakeEntryForm', array($tag, $this, $form)); + } + + if (!empty($form)) { + $form->show(); + } + } + } } /** diff --git a/lib/microappplugin.php b/lib/microappplugin.php index 1cdbe965e6..0b02f5da52 100644 --- a/lib/microappplugin.php +++ b/lib/microappplugin.php @@ -54,7 +54,7 @@ abstract class MicroAppPlugin extends Plugin abstract function appTitle(); abstract function tag(); abstract function types(); - abstract function saveNoticeFromActivity($activity, $actor); + abstract function saveNoticeFromActivity($activity, $actor, $options); abstract function activityObjectFromNotice($notice); abstract function showNotice($notice, $out); abstract function entryForm($out); @@ -157,6 +157,13 @@ abstract class MicroAppPlugin extends Plugin throw new ClientException(_('Can\'t get author for activity.')); } + $object = $activity->objects[0]; + + $options = array('uri' => $object->id, + 'url' => $object->link, + 'is_local' => Notice::REMOTE_OMB, + 'source' => 'ostatus'); + $this->saveNoticeFromActivity($activity, $actor); return false; @@ -196,7 +203,7 @@ abstract class MicroAppPlugin extends Plugin if (!in_array($uri, $activity->context->attention) && (empty($original) || $original->profile_id != $target->id)) { - throw new ClientException(_("Bookmark not posted ". + throw new ClientException(_("Object not posted ". "to this user.")); } } else { @@ -206,7 +213,14 @@ abstract class MicroAppPlugin extends Plugin $actor = Ostatus_profile::ensureActivityObjectProfile($activity->actor); - $this->saveNoticeFromActivity($activity, $actor); + $object = $activity->objects[0]; + + $options = array('uri' => $object->id, + 'url' => $object->link, + 'is_local' => Notice::REMOTE_OMB, + 'source' => 'ostatus'); + + $this->saveNoticeFromActivity($activity, $actor, $options); return false; } @@ -258,8 +272,8 @@ abstract class MicroAppPlugin extends Plugin $obj = $activity->objects[0]; - $options = array('uri' => $bookmark->id, - 'url' => $bookmark->link, + $options = array('uri' => $object->id, + 'url' => $object->link, 'source' => 'restore'); $saved = $this->saveNoticeFromActivity($activity, @@ -275,4 +289,22 @@ abstract class MicroAppPlugin extends Plugin return true; } + + function onStartShowEntryForms(&$tabs) + { + $tabs[$this->tag()] = $this->appTitle(); + return true; + } + + function onStartMakeEntryForm($tag, $out, &$form) + { + $this->log(LOG_INFO, "onStartMakeEntryForm() called for tag '$tag'"); + + if ($tag == $this->tag()) { + $form = $this->entryForm($out); + return false; + } + + return true; + } } diff --git a/plugins/Bookmark/BookmarkPlugin.php b/plugins/Bookmark/BookmarkPlugin.php index c3ff17c4e9..1ef5f5c0e3 100644 --- a/plugins/Bookmark/BookmarkPlugin.php +++ b/plugins/Bookmark/BookmarkPlugin.php @@ -372,10 +372,8 @@ class BookmarkPlugin extends MicroAppPlugin * @return Notice resulting notice */ - function saveNoticeFromActivity($activity, $profile) + function saveNoticeFromActivity($activity, $profile, $options=array()) { - $options = array(); - $bookmark = $activity->objects[0]; $relLinkEls = ActivityUtils::getLinks($bookmark->element, 'related'); @@ -622,4 +620,13 @@ class BookmarkPlugin extends MicroAppPlugin return new BookmarkForm($out); } + function tag() + { + return 'bookmark'; + } + + function appTitle() + { + return _m('Bookmark'); + } } From 457d76c0ca32350ac600006369ca318a269946fc Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 6 Mar 2011 17:32:26 -0500 Subject: [PATCH 41/68] submenu headers are

elements --- lib/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/menu.php b/lib/menu.php index 7947b4d7e4..2713b44d50 100644 --- a/lib/menu.php +++ b/lib/menu.php @@ -85,7 +85,7 @@ class Menu extends Widget function submenu($label, $menu) { $this->action->elementStart('li'); - $this->action->text($label); + $this->action->element('h3', null, $label); $menu->show(); $this->action->elementEnd('li'); } From 97dc0260d9633f857790d54649ad434b0f37ff62 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 3 Mar 2011 16:53:44 -0500 Subject: [PATCH 42/68] first pass at microapp class --- lib/microapp.php | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 lib/microapp.php diff --git a/lib/microapp.php b/lib/microapp.php new file mode 100644 index 0000000000..77e6abb7e3 --- /dev/null +++ b/lib/microapp.php @@ -0,0 +1,59 @@ +. + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Superclass for microapp plugins + * + * This class lets you define micro-applications with different kinds of activities. + * + * The applications work more-or-less like other + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class MicroAppPlugin extends Plugin +{ + abstract function isMyNotice($notice); + abstract function isMyActivity($activity); + abstract function saveNoticeFromActivity($activity); + abstract function activityFromNotice($notice); + abstract function showNotice($notice, $out); +} From a0e2ebec8fa614f7c0f3a1942cb47ca04aaca80e Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 3 Mar 2011 16:57:16 -0500 Subject: [PATCH 43/68] add activity object type to notice --- db/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/db/core.php b/db/core.php index 55d724b505..62730b853f 100644 --- a/db/core.php +++ b/db/core.php @@ -201,6 +201,7 @@ $schema['notice'] = array( 'location_id' => array('type' => 'int', 'description' => 'location id if possible'), 'location_ns' => array('type' => 'int', 'description' => 'namespace for location'), 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'), + 'object_type' => array('type' => 'varchar', 'length' => 32, 'description' => 'URI representing activity streams object type'), ), 'primary key' => array('id'), 'unique keys' => array( From 1b5faf1c4e264c396b8945cc192b04f99b6f9f1d Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 4 Mar 2011 16:41:17 -0500 Subject: [PATCH 44/68] correct length and default value for object_type --- db/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/core.php b/db/core.php index 62730b853f..16a59462d4 100644 --- a/db/core.php +++ b/db/core.php @@ -201,7 +201,7 @@ $schema['notice'] = array( 'location_id' => array('type' => 'int', 'description' => 'location id if possible'), 'location_ns' => array('type' => 'int', 'description' => 'namespace for location'), 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'), - 'object_type' => array('type' => 'varchar', 'length' => 32, 'description' => 'URI representing activity streams object type'), + 'object_type' => array('type' => 'varchar', 'length' => 255, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'), ), 'primary key' => array('id'), 'unique keys' => array( From a7b6f7a6698f646c3e9962b15d8d2c570b48a5a7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 5 Mar 2011 14:47:37 -0500 Subject: [PATCH 45/68] add a couple of methods to MicroAppPlugin --- lib/microapp.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/microapp.php b/lib/microapp.php index 77e6abb7e3..23b4b5bb84 100644 --- a/lib/microapp.php +++ b/lib/microapp.php @@ -49,11 +49,22 @@ if (!defined('STATUSNET')) { * @link http://status.net/ */ -class MicroAppPlugin extends Plugin +abstract class MicroAppPlugin extends Plugin { - abstract function isMyNotice($notice); - abstract function isMyActivity($activity); + abstract function types(); abstract function saveNoticeFromActivity($activity); abstract function activityFromNotice($notice); abstract function showNotice($notice, $out); + abstract function entryForm(); + + function isMyNotice($notice) { + $types = $this->types(); + return in_array($notice->object_type, $types); + } + + function isMyActivity($activity) { + $types = $this->types(); + return (count($activity->objects) == 1 && + in_array($activity->objects[0]->type, $types)); + } } From 0c3d27046ecda5e584f9e71286f7e768f641d7ed Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 5 Mar 2011 14:48:10 -0500 Subject: [PATCH 46/68] move microapp.php to microappplugin.php --- lib/microappplugin.php | 70 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 lib/microappplugin.php diff --git a/lib/microappplugin.php b/lib/microappplugin.php new file mode 100644 index 0000000000..23b4b5bb84 --- /dev/null +++ b/lib/microappplugin.php @@ -0,0 +1,70 @@ +. + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Superclass for microapp plugins + * + * This class lets you define micro-applications with different kinds of activities. + * + * The applications work more-or-less like other + * + * @category Microapp + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +abstract class MicroAppPlugin extends Plugin +{ + abstract function types(); + abstract function saveNoticeFromActivity($activity); + abstract function activityFromNotice($notice); + abstract function showNotice($notice, $out); + abstract function entryForm(); + + function isMyNotice($notice) { + $types = $this->types(); + return in_array($notice->object_type, $types); + } + + function isMyActivity($activity) { + $types = $this->types(); + return (count($activity->objects) == 1 && + in_array($activity->objects[0]->type, $types)); + } +} From 52952d13c0b926b568d537d837aa36fcfcd9afa0 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 6 Mar 2011 16:33:36 -0500 Subject: [PATCH 47/68] first (non-working) move to microapp structure for bookmarks --- lib/microapp.php | 70 ---- lib/microappplugin.php | 214 +++++++++- plugins/Bookmark/BookmarkPlugin.php | 591 ++++++++++------------------ 3 files changed, 420 insertions(+), 455 deletions(-) delete mode 100644 lib/microapp.php diff --git a/lib/microapp.php b/lib/microapp.php deleted file mode 100644 index 23b4b5bb84..0000000000 --- a/lib/microapp.php +++ /dev/null @@ -1,70 +0,0 @@ -. - * - * @category Microapp - * @package StatusNet - * @author Evan Prodromou - * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET')) { - // This check helps protect against security problems; - // your code file can't be executed directly from the web. - exit(1); -} - -/** - * Superclass for microapp plugins - * - * This class lets you define micro-applications with different kinds of activities. - * - * The applications work more-or-less like other - * - * @category Microapp - * @package StatusNet - * @author Evan Prodromou - * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ - */ - -abstract class MicroAppPlugin extends Plugin -{ - abstract function types(); - abstract function saveNoticeFromActivity($activity); - abstract function activityFromNotice($notice); - abstract function showNotice($notice, $out); - abstract function entryForm(); - - function isMyNotice($notice) { - $types = $this->types(); - return in_array($notice->object_type, $types); - } - - function isMyActivity($activity) { - $types = $this->types(); - return (count($activity->objects) == 1 && - in_array($activity->objects[0]->type, $types)); - } -} diff --git a/lib/microappplugin.php b/lib/microappplugin.php index 23b4b5bb84..1cdbe965e6 100644 --- a/lib/microappplugin.php +++ b/lib/microappplugin.php @@ -51,11 +51,14 @@ if (!defined('STATUSNET')) { abstract class MicroAppPlugin extends Plugin { + abstract function appTitle(); + abstract function tag(); abstract function types(); - abstract function saveNoticeFromActivity($activity); - abstract function activityFromNotice($notice); + abstract function saveNoticeFromActivity($activity, $actor); + abstract function activityObjectFromNotice($notice); abstract function showNotice($notice, $out); - abstract function entryForm(); + abstract function entryForm($out); + abstract function deleteRelated($notice); function isMyNotice($notice) { $types = $this->types(); @@ -67,4 +70,209 @@ abstract class MicroAppPlugin extends Plugin return (count($activity->objects) == 1 && in_array($activity->objects[0]->type, $types)); } + + /** + * When a notice is deleted, delete the related objects + * + * @param Notice $notice Notice being deleted + * + * @return boolean hook value + */ + + function onNoticeDeleteRelated($notice) + { + if ($this->isMyNotice($notice)) { + $this->deleteRelated($notice); + } + + return true; + } + + /** + * Output the HTML for this kind of object in a list + * + * @param NoticeListItem $nli The list item being shown. + * + * @return boolean hook value + */ + + function onStartShowNoticeItem($nli) + { + if (!$this->isMyNotice($nli->notice)) { + return true; + } + + $out = $nli->out; + + $this->showNotice($notice, $out); + + $nli->showNoticeLink(); + $nli->showNoticeSource(); + $nli->showNoticeLocation(); + $nli->showContext(); + $nli->showRepeat(); + + $out->elementEnd('div'); + + $nli->showNoticeOptions(); + + return false; + } + + /** + * Render a notice as one of our objects + * + * @param Notice $notice Notice to render + * @param ActivityObject &$object Empty object to fill + * + * @return boolean hook value + */ + + function onStartActivityObjectFromNotice($notice, &$object) + { + if ($this->isMyNotice($notice)) { + $object = $this->activityObjectFromNotice($notice); + return false; + } + + return true; + } + + /** + * Handle a posted object from PuSH + * + * @param Activity $activity activity to handle + * @param Ostatus_profile $oprofile Profile for the feed + * + * @return boolean hook value + */ + + function onStartHandleFeedEntryWithProfile($activity, $oprofile) + { + if ($this->isMyActivity($activity)) { + + $actor = $oprofile->checkAuthorship($activity); + + if (empty($actor)) { + throw new ClientException(_('Can\'t get author for activity.')); + } + + $this->saveNoticeFromActivity($activity, $actor); + + return false; + } + + return true; + } + + /** + * Handle a posted object from Salmon + * + * @param Activity $activity activity to handle + * @param mixed $target user or group targeted + * + * @return boolean hook value + */ + + function onStartHandleSalmonTarget($activity, $target) + { + if ($this->isMyActivity($activity)) { + + $this->log(LOG_INFO, "Checking {$activity->id} as a valid Salmon slap."); + + if ($target instanceof User_group) { + $uri = $target->getUri(); + if (!in_array($uri, $activity->context->attention)) { + throw new ClientException(_("Bookmark not posted ". + "to this group.")); + } + } else if ($target instanceof User) { + $uri = $target->uri; + $original = null; + if (!empty($activity->context->replyToID)) { + $original = Notice::staticGet('uri', + $activity->context->replyToID); + } + if (!in_array($uri, $activity->context->attention) && + (empty($original) || + $original->profile_id != $target->id)) { + throw new ClientException(_("Bookmark not posted ". + "to this user.")); + } + } else { + throw new ServerException(_("Don't know how to handle ". + "this kind of target.")); + } + + $actor = Ostatus_profile::ensureActivityObjectProfile($activity->actor); + + $this->saveNoticeFromActivity($activity, $actor); + + return false; + } + + return true; + } + + /** + * Handle object posted via AtomPub + * + * @param Activity &$activity Activity that was posted + * @param User $user User that posted it + * @param Notice &$notice Resulting notice + * + * @return boolean hook value + */ + + function onStartAtomPubNewActivity(&$activity, $user, &$notice) + { + if ($this->isMyActivity($activity)) { + + $options = array('source' => 'atompub'); + + $this->saveNoticeFromActivity($activity, + $user->getProfile(), + $options); + + return false; + } + + return true; + } + + /** + * Handle object imported from a backup file + * + * @param User $user User to import for + * @param ActivityObject $author Original author per import file + * @param Activity $activity Activity to import + * @param boolean $trusted Is this a trusted user? + * @param boolean &$done Is this done (success or unrecoverable error) + * + * @return boolean hook value + */ + + function onStartImportActivity($user, $author, $activity, $trusted, &$done) + { + if ($this->isMyActivity($activity)) { + + $obj = $activity->objects[0]; + + $options = array('uri' => $bookmark->id, + 'url' => $bookmark->link, + 'source' => 'restore'); + + $saved = $this->saveNoticeFromActivity($activity, + $user->getProfile(), + $options); + + if (!empty($saved)) { + $done = true; + } + + return false; + } + + return true; + } } diff --git a/plugins/Bookmark/BookmarkPlugin.php b/plugins/Bookmark/BookmarkPlugin.php index 2e6baf5e4e..c3ff17c4e9 100644 --- a/plugins/Bookmark/BookmarkPlugin.php +++ b/plugins/Bookmark/BookmarkPlugin.php @@ -44,7 +44,7 @@ if (!defined('STATUSNET')) { * @link http://status.net/ */ -class BookmarkPlugin extends Plugin +class BookmarkPlugin extends MicroAppPlugin { const VERSION = '0.1'; const IMPORTDELICIOUS = 'BookmarkPlugin:IMPORTDELICIOUS'; @@ -120,25 +120,6 @@ class BookmarkPlugin extends Plugin return true; } - /** - * When a notice is deleted, delete the related Bookmark - * - * @param Notice $notice Notice being deleted - * - * @return boolean hook value - */ - - function onNoticeDeleteRelated($notice) - { - $nb = Bookmark::getByNotice($notice); - - if (!empty($nb)) { - $nb->delete(); - } - - return true; - } - /** * Show the CSS necessary for this plugin * @@ -218,212 +199,6 @@ class BookmarkPlugin extends Plugin return true; } - /** - * Output the HTML for a bookmark in a list - * - * @param NoticeListItem $nli The list item being shown. - * - * @return boolean hook value - */ - - function onStartShowNoticeItem($nli) - { - $nb = Bookmark::getByNotice($nli->notice); - - if (!empty($nb)) { - - $out = $nli->out; - $notice = $nli->notice; - $profile = $nli->profile; - - $atts = $notice->attachments(); - - if (count($atts) < 1) { - // Something wrong; let default code deal with it. - return true; - } - - $att = $atts[0]; - - // XXX: only show the bookmark URL for non-single-page stuff - - if ($out instanceof ShowbookmarkAction) { - } else { - $out->elementStart('h3'); - $out->element('a', - array('href' => $att->url, - 'class' => 'bookmark-title entry-title'), - $nb->title); - $out->elementEnd('h3'); - - $countUrl = common_local_url('noticebyurl', - array('id' => $att->id)); - - $out->element('a', array('class' => 'bookmark-notice-count', - 'href' => $countUrl), - $att->noticeCount()); - } - - // Replies look like "for:" tags - - $replies = $nli->notice->getReplies(); - $tags = $nli->notice->getTags(); - - if (!empty($replies) || !empty($tags)) { - - $out->elementStart('ul', array('class' => 'bookmark-tags')); - - foreach ($replies as $reply) { - $other = Profile::staticGet('id', $reply); - $out->elementStart('li'); - $out->element('a', array('rel' => 'tag', - 'href' => $other->profileurl, - 'title' => $other->getBestName()), - sprintf('for:%s', $other->nickname)); - $out->elementEnd('li'); - $out->text(' '); - } - - foreach ($tags as $tag) { - $out->elementStart('li'); - $out->element('a', - array('rel' => 'tag', - 'href' => Notice_tag::url($tag)), - $tag); - $out->elementEnd('li'); - $out->text(' '); - } - - $out->elementEnd('ul'); - } - - if (!empty($nb->description)) { - $out->element('p', - array('class' => 'bookmark-description'), - $nb->description); - } - - if (common_config('attachments', 'show_thumbs')) { - $haveThumbs = false; - foreach ($atts as $check) { - $thumbnail = File_thumbnail::staticGet('file_id', $check->id); - if (!empty($thumbnail)) { - $haveThumbs = true; - break; - } - } - if ($haveThumbs) { - $al = new InlineAttachmentList($notice, $out); - $al->show(); - } - } - - $out->elementStart('div', array('class' => 'bookmark-info entry-content')); - - $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); - - $out->element('img', - array('src' => ($avatar) ? - $avatar->displayUrl() : - Avatar::defaultImage(AVATAR_MINI_SIZE), - 'class' => 'avatar photo bookmark-avatar', - 'width' => AVATAR_MINI_SIZE, - 'height' => AVATAR_MINI_SIZE, - 'alt' => $profile->getBestName())); - - $out->raw(' '); - - $out->element('a', - array('href' => $profile->profileurl, - 'title' => $profile->getBestName()), - $profile->nickname); - - $nli->showNoticeLink(); - $nli->showNoticeSource(); - $nli->showNoticeLocation(); - $nli->showContext(); - $nli->showRepeat(); - - $out->elementEnd('div'); - - $nli->showNoticeOptions(); - - return false; - } - return true; - } - - /** - * Render a notice as a Bookmark object - * - * @param Notice $notice Notice to render - * @param ActivityObject &$object Empty object to fill - * - * @return boolean hook value - */ - - function onStartActivityObjectFromNotice($notice, &$object) - { - common_log(LOG_INFO, - "Checking {$notice->uri} to see if it's a bookmark."); - - $nb = Bookmark::getByNotice($notice); - - if (!empty($nb)) { - - common_log(LOG_INFO, - "Formatting notice {$notice->uri} as a bookmark."); - - $object->id = $notice->uri; - $object->type = ActivityObject::BOOKMARK; - $object->title = $nb->title; - $object->summary = $nb->description; - $object->link = $notice->bestUrl(); - - // Attributes of the URL - - $attachments = $notice->attachments(); - - if (count($attachments) != 1) { - throw new ServerException(_('Bookmark notice with the '. - 'wrong number of attachments.')); - } - - $target = $attachments[0]; - - $attrs = array('rel' => 'related', - 'href' => $target->url); - - if (!empty($target->title)) { - $attrs['title'] = $target->title; - } - - $object->extra[] = array('link', $attrs, null); - - // Attributes of the thumbnail, if any - - $thumbnail = $target->getThumbnail(); - - if (!empty($thumbnail)) { - $tattrs = array('rel' => 'preview', - 'href' => $thumbnail->url); - - if (!empty($thumbnail->width)) { - $tattrs['media:width'] = $thumbnail->width; - } - - if (!empty($thumbnail->height)) { - $tattrs['media:height'] = $thumbnail->height; - } - - $object->extra[] = array('link', $attrs, null); - } - - return false; - } - - return true; - } /** * Add our two queue handlers to the queue manager @@ -481,149 +256,7 @@ class BookmarkPlugin extends Plugin return true; } - /** - * Handle a posted bookmark from PuSH - * - * @param Activity $activity activity to handle - * @param Ostatus_profile $oprofile Profile for the feed - * - * @return boolean hook value - */ - function onStartHandleFeedEntryWithProfile($activity, $oprofile) - { - common_log(LOG_INFO, "BookmarkPlugin called for new feed entry."); - - if (self::_isPostBookmark($activity)) { - - common_log(LOG_INFO, - "Importing activity {$activity->id} as a bookmark."); - - $author = $oprofile->checkAuthorship($activity); - - if (empty($author)) { - throw new ClientException(_('Can\'t get author for activity.')); - } - - self::_postRemoteBookmark($author, - $activity); - - return false; - } - - return true; - } - - /** - * Handle a posted bookmark from Salmon - * - * @param Activity $activity activity to handle - * @param mixed $target user or group targeted - * - * @return boolean hook value - */ - - function onStartHandleSalmonTarget($activity, $target) - { - if (self::_isPostBookmark($activity)) { - - $this->log(LOG_INFO, "Checking {$activity->id} as a valid Salmon slap."); - - if ($target instanceof User_group) { - $uri = $target->getUri(); - if (!in_array($uri, $activity->context->attention)) { - throw new ClientException(_("Bookmark not posted ". - "to this group.")); - } - } else if ($target instanceof User) { - $uri = $target->uri; - $original = null; - if (!empty($activity->context->replyToID)) { - $original = Notice::staticGet('uri', - $activity->context->replyToID); - } - if (!in_array($uri, $activity->context->attention) && - (empty($original) || - $original->profile_id != $target->id)) { - throw new ClientException(_("Bookmark not posted ". - "to this user.")); - } - } else { - throw new ServerException(_("Don't know how to handle ". - "this kind of target.")); - } - - $author = Ostatus_profile::ensureActivityObjectProfile($activity->actor); - - self::_postRemoteBookmark($author, - $activity); - - return false; - } - - return true; - } - - /** - * Handle bookmark posted via AtomPub - * - * @param Activity &$activity Activity that was posted - * @param User $user User that posted it - * @param Notice &$notice Resulting notice - * - * @return boolean hook value - */ - - function onStartAtomPubNewActivity(&$activity, $user, &$notice) - { - if (self::_isPostBookmark($activity)) { - $options = array('source' => 'atompub'); - $notice = self::_postBookmark($user->getProfile(), - $activity, - $options); - return false; - } - - return true; - } - - /** - * Handle bookmark imported from a backup file - * - * @param User $user User to import for - * @param ActivityObject $author Original author per import file - * @param Activity $activity Activity to import - * @param boolean $trusted Is this a trusted user? - * @param boolean &$done Is this done (success or unrecoverable error) - * - * @return boolean hook value - */ - - function onStartImportActivity($user, $author, $activity, $trusted, &$done) - { - if (self::_isPostBookmark($activity)) { - - $bookmark = $activity->objects[0]; - - $this->log(LOG_INFO, - 'Importing Bookmark ' . $bookmark->id . - ' for user ' . $user->nickname); - - $options = array('uri' => $bookmark->id, - 'url' => $bookmark->link, - 'source' => 'restore'); - - $saved = self::_postBookmark($user->getProfile(), $activity, $options); - - if (!empty($saved)) { - $done = true; - } - - return false; - } - - return true; - } /** * Show a link to our delicious import page on profile settings form @@ -691,6 +324,44 @@ class BookmarkPlugin extends Plugin return self::_postBookmark($author->localProfile(), $activity, $options); } + /** + * Test if an activity represents posting a bookmark + * + * @param Activity $activity Activity to test + * + * @return true if it's a Post of a Bookmark, else false + */ + + static private function _isPostBookmark($activity) + { + return ($activity->verb == ActivityVerb::POST && + $activity->objects[0]->type == ActivityObject::BOOKMARK); + } + + function types() + { + return array(ActivityObject::BOOKMARK); + } + + /** + * When a notice is deleted, delete the related Bookmark + * + * @param Notice $notice Notice being deleted + * + * @return boolean hook value + */ + + function deleteRelated($notice) + { + $nb = Bookmark::getByNotice($notice); + + if (!empty($nb)) { + $nb->delete(); + } + + return true; + } + /** * Save a bookmark from an activity * @@ -701,10 +372,10 @@ class BookmarkPlugin extends Plugin * @return Notice resulting notice */ - static private function _postBookmark(Profile $profile, - Activity $activity, - $options=array()) + function saveNoticeFromActivity($activity, $profile) { + $options = array(); + $bookmark = $activity->objects[0]; $relLinkEls = ActivityUtils::getLinks($bookmark->element, 'related'); @@ -782,17 +453,173 @@ class BookmarkPlugin extends Plugin $options); } - /** - * Test if an activity represents posting a bookmark - * - * @param Activity $activity Activity to test - * - * @return true if it's a Post of a Bookmark, else false - */ - - static private function _isPostBookmark($activity) + function activityObjectFromNotice($notice) { - return ($activity->verb == ActivityVerb::POST && - $activity->objects[0]->type == ActivityObject::BOOKMARK); + assert($this->isMyNotice($notice)); + + common_log(LOG_INFO, + "Formatting notice {$notice->uri} as a bookmark."); + + $object = new ActivityObject(); + + $object->id = $notice->uri; + $object->type = ActivityObject::BOOKMARK; + $object->title = $nb->title; + $object->summary = $nb->description; + $object->link = $notice->bestUrl(); + + // Attributes of the URL + + $attachments = $notice->attachments(); + + if (count($attachments) != 1) { + throw new ServerException(_('Bookmark notice with the '. + 'wrong number of attachments.')); + } + + $target = $attachments[0]; + + $attrs = array('rel' => 'related', + 'href' => $target->url); + + if (!empty($target->title)) { + $attrs['title'] = $target->title; + } + + $object->extra[] = array('link', $attrs, null); + + // Attributes of the thumbnail, if any + + $thumbnail = $target->getThumbnail(); + + if (!empty($thumbnail)) { + $tattrs = array('rel' => 'preview', + 'href' => $thumbnail->url); + + if (!empty($thumbnail->width)) { + $tattrs['media:width'] = $thumbnail->width; + } + + if (!empty($thumbnail->height)) { + $tattrs['media:height'] = $thumbnail->height; + } + + $object->extra[] = array('link', $attrs, null); + } + + return $object; } + + function showNotice($notice, $out) + { + $profile = $notice->getProfile(); + + $atts = $notice->attachments(); + + if (count($atts) < 1) { + // Something wrong; let default code deal with it. + throw new Exception("That can't be right."); + } + + $att = $atts[0]; + + // XXX: only show the bookmark URL for non-single-page stuff + + if ($out instanceof ShowbookmarkAction) { + } else { + $out->elementStart('h3'); + $out->element('a', + array('href' => $att->url, + 'class' => 'bookmark-title entry-title'), + $nb->title); + $out->elementEnd('h3'); + + $countUrl = common_local_url('noticebyurl', + array('id' => $att->id)); + + $out->element('a', array('class' => 'bookmark-notice-count', + 'href' => $countUrl), + $att->noticeCount()); + } + + // Replies look like "for:" tags + + $replies = $nli->notice->getReplies(); + $tags = $nli->notice->getTags(); + + if (!empty($replies) || !empty($tags)) { + + $out->elementStart('ul', array('class' => 'bookmark-tags')); + + foreach ($replies as $reply) { + $other = Profile::staticGet('id', $reply); + $out->elementStart('li'); + $out->element('a', array('rel' => 'tag', + 'href' => $other->profileurl, + 'title' => $other->getBestName()), + sprintf('for:%s', $other->nickname)); + $out->elementEnd('li'); + $out->text(' '); + } + + foreach ($tags as $tag) { + $out->elementStart('li'); + $out->element('a', + array('rel' => 'tag', + 'href' => Notice_tag::url($tag)), + $tag); + $out->elementEnd('li'); + $out->text(' '); + } + + $out->elementEnd('ul'); + } + + if (!empty($nb->description)) { + $out->element('p', + array('class' => 'bookmark-description'), + $nb->description); + } + + if (common_config('attachments', 'show_thumbs')) { + $haveThumbs = false; + foreach ($atts as $check) { + $thumbnail = File_thumbnail::staticGet('file_id', $check->id); + if (!empty($thumbnail)) { + $haveThumbs = true; + break; + } + } + if ($haveThumbs) { + $al = new InlineAttachmentList($notice, $out); + $al->show(); + } + } + + $out->elementStart('div', array('class' => 'bookmark-info entry-content')); + + $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); + + $out->element('img', + array('src' => ($avatar) ? + $avatar->displayUrl() : + Avatar::defaultImage(AVATAR_MINI_SIZE), + 'class' => 'avatar photo bookmark-avatar', + 'width' => AVATAR_MINI_SIZE, + 'height' => AVATAR_MINI_SIZE, + 'alt' => $profile->getBestName())); + + $out->raw(' '); + + $out->element('a', + array('href' => $profile->profileurl, + 'title' => $profile->getBestName()), + $profile->nickname); + } + + function entryForm($out) + { + return new BookmarkForm($out); + } + } From 7aa55f820066106da9d13c6a5962661e924b38e5 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 6 Mar 2011 17:27:03 -0500 Subject: [PATCH 48/68] made the input-form switcher work, kinda --- lib/action.php | 56 +++++++++++++++++++++++++++-- lib/microappplugin.php | 42 +++++++++++++++++++--- plugins/Bookmark/BookmarkPlugin.php | 13 +++++-- 3 files changed, 101 insertions(+), 10 deletions(-) diff --git a/lib/action.php b/lib/action.php index 31e52dfcf2..a049fec97c 100644 --- a/lib/action.php +++ b/lib/action.php @@ -646,8 +646,60 @@ class Action extends HTMLOutputter // lawsuit */ function showNoticeForm() { - $notice_form = new NoticeForm($this); - $notice_form->show(); + $tabs = array('status' => _('Status')); + + $this->elementStart('div', 'input_forms'); + + if (Event::handle('StartShowEntryForms', array(&$tabs))) { + + $this->elementStart('ul', array('class' => 'nav', + 'id' => 'input_form_nav')); + + foreach ($tabs as $tag => $title) { + + $attrs = array('id' => 'input_form_nav_'.$title); + + if ($tag == 'status') { + $attrs['class'] = 'current'; + } + + $this->elementStart('li', $attrs); + + $this->element('a', + array('href' => 'javascript:switchInputFormTab("'.$tag.'")'), + $title); + $this->elementEnd('li'); + } + + $this->elementEnd('ul'); + + foreach ($tabs as $tag => $title) { + + $attrs = array('class' => 'input_form', + 'id' => 'input_form_'.$tag); + + if ($tag == 'status') { + $attrs['class'] .= ' active'; + } else { + $attrs['class'] .= ' inactive'; + } + + $this->elementStart('div', $attrs); + + $form = null; + + if (Event::handle('StartMakeEntryForm', array($tag, $this, &$form))) { + if ($tag == 'status') { + $form = new NoticeForm($this); + } + Event::handle('EndMakeEntryForm', array($tag, $this, $form)); + } + + if (!empty($form)) { + $form->show(); + } + } + } } /** diff --git a/lib/microappplugin.php b/lib/microappplugin.php index 1cdbe965e6..0b02f5da52 100644 --- a/lib/microappplugin.php +++ b/lib/microappplugin.php @@ -54,7 +54,7 @@ abstract class MicroAppPlugin extends Plugin abstract function appTitle(); abstract function tag(); abstract function types(); - abstract function saveNoticeFromActivity($activity, $actor); + abstract function saveNoticeFromActivity($activity, $actor, $options); abstract function activityObjectFromNotice($notice); abstract function showNotice($notice, $out); abstract function entryForm($out); @@ -157,6 +157,13 @@ abstract class MicroAppPlugin extends Plugin throw new ClientException(_('Can\'t get author for activity.')); } + $object = $activity->objects[0]; + + $options = array('uri' => $object->id, + 'url' => $object->link, + 'is_local' => Notice::REMOTE_OMB, + 'source' => 'ostatus'); + $this->saveNoticeFromActivity($activity, $actor); return false; @@ -196,7 +203,7 @@ abstract class MicroAppPlugin extends Plugin if (!in_array($uri, $activity->context->attention) && (empty($original) || $original->profile_id != $target->id)) { - throw new ClientException(_("Bookmark not posted ". + throw new ClientException(_("Object not posted ". "to this user.")); } } else { @@ -206,7 +213,14 @@ abstract class MicroAppPlugin extends Plugin $actor = Ostatus_profile::ensureActivityObjectProfile($activity->actor); - $this->saveNoticeFromActivity($activity, $actor); + $object = $activity->objects[0]; + + $options = array('uri' => $object->id, + 'url' => $object->link, + 'is_local' => Notice::REMOTE_OMB, + 'source' => 'ostatus'); + + $this->saveNoticeFromActivity($activity, $actor, $options); return false; } @@ -258,8 +272,8 @@ abstract class MicroAppPlugin extends Plugin $obj = $activity->objects[0]; - $options = array('uri' => $bookmark->id, - 'url' => $bookmark->link, + $options = array('uri' => $object->id, + 'url' => $object->link, 'source' => 'restore'); $saved = $this->saveNoticeFromActivity($activity, @@ -275,4 +289,22 @@ abstract class MicroAppPlugin extends Plugin return true; } + + function onStartShowEntryForms(&$tabs) + { + $tabs[$this->tag()] = $this->appTitle(); + return true; + } + + function onStartMakeEntryForm($tag, $out, &$form) + { + $this->log(LOG_INFO, "onStartMakeEntryForm() called for tag '$tag'"); + + if ($tag == $this->tag()) { + $form = $this->entryForm($out); + return false; + } + + return true; + } } diff --git a/plugins/Bookmark/BookmarkPlugin.php b/plugins/Bookmark/BookmarkPlugin.php index c3ff17c4e9..1ef5f5c0e3 100644 --- a/plugins/Bookmark/BookmarkPlugin.php +++ b/plugins/Bookmark/BookmarkPlugin.php @@ -372,10 +372,8 @@ class BookmarkPlugin extends MicroAppPlugin * @return Notice resulting notice */ - function saveNoticeFromActivity($activity, $profile) + function saveNoticeFromActivity($activity, $profile, $options=array()) { - $options = array(); - $bookmark = $activity->objects[0]; $relLinkEls = ActivityUtils::getLinks($bookmark->element, 'related'); @@ -622,4 +620,13 @@ class BookmarkPlugin extends MicroAppPlugin return new BookmarkForm($out); } + function tag() + { + return 'bookmark'; + } + + function appTitle() + { + return _m('Bookmark'); + } } From cf1a4d829283de1a95e5d33dc4f76e2a9c229110 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 04:57:49 -0500 Subject: [PATCH 49/68] Input form switcher works This change adds the input form switcher, which adds a navigation menu across the top of the input form, letting you switch between different kinds of input. The input menu doesn't yet look like a nice set of tabs; it could use some love. --- js/util.js | 11 ++++++++++- js/util.min.js | 2 +- lib/action.php | 11 ++++++----- theme/rebase/css/display.css | 21 ++++++++++++++++++++- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/js/util.js b/js/util.js index cc94c5ced7..2100521869 100644 --- a/js/util.js +++ b/js/util.js @@ -1272,7 +1272,16 @@ var SN = { // StatusNet // UI links currently on the page use malleable names. return false; - } + }, + + switchInputFormTab: function(tag) { + // The one that's current isn't current anymore + $('.input_form_nav_tab.current').removeClass('current'); + $('#input_form_nav_'+tag).addClass('current'); + + $('.input_form.current').removeClass('current'); + $('#input_form_'+tag).addClass('current'); + } }, Init: { diff --git a/js/util.min.js b/js/util.min.js index 280aca6a45..cfbd66d662 100644 --- a/js/util.min.js +++ b/js/util.min.js @@ -1 +1 @@ -var SN={C:{I:{CounterBlackout:false,MaxLength:140,PatternUsername:/^[0-9a-zA-Z\-_.]*$/,HTTP20x30x:[200,201,202,203,204,205,206,300,301,302,303,304,305,306,307]},S:{Disabled:"disabled",Warning:"warning",Error:"error",Success:"success",Processing:"processing",CommandResult:"command_result",FormNotice:"form_notice",NoticeDataGeo:"notice_data-geo",NoticeDataGeoCookie:"NoticeDataGeo",NoticeDataGeoSelected:"notice_data-geo_selected",StatusNetInstance:"StatusNetInstance"}},messages:{},msg:function(a){if(typeof SN.messages[a]=="undefined"){return"["+a+"]"}else{return SN.messages[a]}},U:{FormNoticeEnhancements:function(b){if(jQuery.data(b[0],"ElementData")===undefined){MaxLength=b.find(".count").text();if(typeof(MaxLength)=="undefined"){MaxLength=SN.C.I.MaxLength}jQuery.data(b[0],"ElementData",{MaxLength:MaxLength});SN.U.Counter(b);NDT=b.find("[name=status_textarea]");NDT.bind("keyup",function(c){SN.U.Counter(b)});var a=function(c){window.setTimeout(function(){SN.U.Counter(b)},50)};NDT.bind("cut",a).bind("paste",a)}else{b.find(".count").text(jQuery.data(b[0],"ElementData").MaxLength)}},Counter:function(d){SN.C.I.FormNoticeCurrent=d;var b=jQuery.data(d[0],"ElementData").MaxLength;if(b<=0){return}var c=b-SN.U.CharacterCount(d);var a=d.find(".count");if(c.toString()!=a.text()){if(!SN.C.I.CounterBlackout||c===0){if(a.text()!=String(c)){a.text(c)}if(c<0){d.addClass(SN.C.S.Warning)}else{d.removeClass(SN.C.S.Warning)}if(!SN.C.I.CounterBlackout){SN.C.I.CounterBlackout=true;SN.C.I.FormNoticeCurrent=d;window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);",500)}}}},CharacterCount:function(a){return a.find("[name=status_textarea]").val().length},ClearCounterBlackout:function(a){SN.C.I.CounterBlackout=false;SN.U.Counter(a)},RewriteAjaxAction:function(a){if(document.location.protocol=="https:"&&a.substr(0,5)=="http:"){return a.replace(/^http:\/\/[^:\/]+/,"https://"+document.location.host)}else{return a}},FormXHR:function(a){$.ajax({type:"POST",dataType:"xml",url:SN.U.RewriteAjaxAction(a.attr("action")),data:a.serialize()+"&ajax=1",beforeSend:function(b){a.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled)},error:function(c,d,b){alert(b||d)},success:function(b,c){if(typeof($("form",b)[0])!="undefined"){form_new=document._importNode($("form",b)[0],true);a.replaceWith(form_new)}else{a.replaceWith(document._importNode($("p",b)[0],true))}}})},FormNoticeXHR:function(b){SN.C.I.NoticeDataGeo={};b.append('');b.attr("action",SN.U.RewriteAjaxAction(b.attr("action")));var c=function(d,e){b.append($('

').addClass(d).text(e))};var a=function(){b.find(".form_response").remove()};b.ajaxForm({dataType:"xml",timeout:"60000",beforeSend:function(d){if(b.find("[name=status_textarea]").val()==""){b.addClass(SN.C.S.Warning);return false}b.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled);SN.U.normalizeGeoData(b);return true},error:function(f,g,e){b.removeClass(SN.C.S.Processing).find(".submit").removeClass(SN.C.S.Disabled).removeAttr(SN.C.S.Disabled,SN.C.S.Disabled);a();if(g=="timeout"){c("error","Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.")}else{var d=SN.U.GetResponseXML(f);if($("."+SN.C.S.Error,d).length>0){b.append(document._importNode($("."+SN.C.S.Error,d)[0],true))}else{if(parseInt(f.status)===0||jQuery.inArray(parseInt(f.status),SN.C.I.HTTP20x30x)>=0){b.resetForm().find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}else{c("error","(Sorry! We had trouble sending your notice ("+f.status+" "+f.statusText+"). Please report the problem to the site administrator if this happens again.")}}}},success:function(i,f){a();var n=$("#"+SN.C.S.Error,i);if(n.length>0){c("error",n.text())}else{if($("body")[0].id=="bookmarklet"){self.close()}var d=$("#"+SN.C.S.CommandResult,i);if(d.length>0){c("success",d.text())}else{var m=document._importNode($("li",i)[0],true);var k=$("#notices_primary .notices:first");var l=b.closest("li.notice-reply");if(l.length>0){var e=$(m).attr("id");if($("#"+e).length==0){var j=l.closest("li.notice");l.replaceWith(m);SN.U.NoticeInlineReplyPlaceholder(j)}else{l.remove()}}else{if(k.length>0&&SN.U.belongsOnTimeline(m)){if($("#"+m.id).length===0){var h=b.find("[name=inreplyto]").val();var g="#notices_primary #notice-"+h;if($("body")[0].id=="conversation"){if(h.length>0&&$(g+" .notices").length<1){$(g).append('
    ')}$($(g+" .notices")[0]).append(m)}else{k.prepend(m)}$("#"+m.id).css({display:"none"}).fadeIn(2500);SN.U.NoticeWithAttachment($("#"+m.id));SN.U.NoticeReplyTo($("#"+m.id))}}else{c("success",$("title",i).text())}}}b.resetForm();b.find("[name=inreplyto]").val("");b.find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}},complete:function(d,e){b.removeClass(SN.C.S.Processing).find(".submit").removeAttr(SN.C.S.Disabled).removeClass(SN.C.S.Disabled);b.find("[name=lat]").val(SN.C.I.NoticeDataGeo.NLat);b.find("[name=lon]").val(SN.C.I.NoticeDataGeo.NLon);b.find("[name=location_ns]").val(SN.C.I.NoticeDataGeo.NLNS);b.find("[name=location_id]").val(SN.C.I.NoticeDataGeo.NLID);b.find("[name=notice_data-geo]").attr("checked",SN.C.I.NoticeDataGeo.NDG)}})},normalizeGeoData:function(a){SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val();SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val();SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked");var b=$.cookie(SN.C.S.NoticeDataGeoCookie);if(b!==null&&b!="disabled"){b=JSON.parse(b);SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val(b.NLat).val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val(b.NLon).val();if(b.NLNS){SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val(b.NLNS).val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val(b.NLID).val()}else{a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("")}}if(b=="disabled"){SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",false).attr("checked")}else{SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",true).attr("checked")}},GetResponseXML:function(b){try{return b.responseXML}catch(a){return(new DOMParser()).parseFromString(b.responseText,"text/xml")}},NoticeReply:function(){if($("#content .notice_reply").length>0){$("#content .notice").each(function(){SN.U.NoticeReplyTo($(this))})}},NoticeReplyTo:function(a){a.find(".notice_reply").live("click",function(c){c.preventDefault();var b=($(".author .nickname",a).length>0)?$($(".author .nickname",a)[0]):$(".author .nickname.uid");SN.U.NoticeInlineReplyTrigger(a,"@"+b.text());return false})},NoticeInlineReplyTrigger:function(g,h){var b=$($(".notice_id",g)[0]).text();var d=g;var e=g.closest(".notices");if(e.hasClass("threaded-replies")){d=e.closest(".notice")}else{e=$("ul.threaded-replies",g);if(e.length==0){e=$('
      ');g.append(e)}}var i=$(".notice-reply-form",e);var c=function(){i.find("input[name=inreplyto]").val(b);var l=i.find("textarea");if(l.length==0){throw"No textarea"}var k="";if(h){k=h+" "}l.val(k+l.val().replace(RegExp(k,"i"),""));l.data("initialText",$.trim(h+""));l.focus();if(l[0].setSelectionRange){var j=l.val().length;l[0].setSelectionRange(j,j)}};if(i.length>0){c()}else{$("li.notice-reply-placeholder").remove();var f=$("li.notice-reply",e);if(f.length==0){var a=$("#form_notice").attr("action");f=$('
    • ');$.get(a,{ajax:1},function(l,n,m){var j=document._importNode($("form",l)[0],true);f.append(j);e.append(f);var k=i=$(j);SN.U.NoticeLocationAttach(k);SN.U.FormNoticeXHR(k);SN.U.FormNoticeEnhancements(k);SN.U.NoticeDataAttach(k);c()})}}},NoticeFavor:function(){$(".form_favor").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_disfavor").live("click",function(){SN.U.FormXHR($(this));return false})},NoticeInlineReplyPlaceholder:function(b){var a=b.find("ul.threaded-replies");var c=$('
    • ');c.click(function(){SN.U.NoticeInlineReplyTrigger(b)});c.find("input").val(SN.msg("reply_placeholder"));a.append(c)},NoticeInlineReplySetup:function(){$(".threaded-replies").each(function(){var b=$(this);var a=b.closest(".notice");SN.U.NoticeInlineReplyPlaceholder(a)})},NoticeRepeat:function(){$(".form_repeat").live("click",function(a){a.preventDefault();SN.U.NoticeRepeatConfirmation($(this));return false})},NoticeRepeatConfirmation:function(a){var c=a.find(".submit");var b=c.clone();b.addClass("submit_dialogbox").removeClass("submit");a.append(b);b.bind("click",function(){SN.U.FormXHR(a);return false});c.hide();a.addClass("dialogbox").append('').closest(".notice-options").addClass("opaque");a.find("button.close").click(function(){$(this).remove();a.removeClass("dialogbox").closest(".notice-options").removeClass("opaque");a.find(".submit_dialogbox").remove();a.find(".submit").show();return false})},NoticeAttachments:function(){$(".notice a.attachment").each(function(){SN.U.NoticeWithAttachment($(this).closest(".notice"))})},NoticeWithAttachment:function(b){if(b.find(".attachment").length===0){return}var a=b.find(".attachment.more");if(a.length>0){$(a[0]).click(function(){var c=$(this);c.addClass(SN.C.S.Processing);$.get(c.attr("href")+"/ajax",null,function(d){c.parent(".entry-content").html($(d).find("#attachment_view .entry-content").html())});return false}).attr("title",SN.msg("showmore_tooltip"))}},NoticeDataAttach:function(b){var a=b.find("input[type=file]");a.change(function(f){b.find(".attach-status").remove();var d=$(this).val();if(!d){return false}var c=$('
      ');c.find("code").text(d);c.find("button").click(function(){c.remove();a.val("");return false});b.append(c);if(typeof this.files=="object"){for(var e=0;eg){f=false}if(f){h(c,function(j){var i=$("").attr("title",e).attr("alt",e).attr("src",j).attr("style","height: 120px");d.find(".attach-status").append(i)})}else{var b=$("
      ").text(e);d.find(".attach-status").append(b)}},NoticeLocationAttach:function(a){var e=a.find("[name=lat]");var k=a.find("[name=lon]");var g=a.find("[name=location_ns]").val();var l=a.find("[name=location_id]").val();var b="";var d=a.find("[name=notice_data-geo]");var c=a.find("[name=notice_data-geo]");var j=a.find("label.notice_data-geo");function f(n){j.attr("title",jQuery.trim(j.text())).removeClass("checked");a.find("[name=lat]").val("");a.find("[name=lon]").val("");a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("");a.find("[name=notice_data-geo]").attr("checked",false);$.cookie(SN.C.S.NoticeDataGeoCookie,"disabled",{path:"/"});if(n){a.find(".geo_status_wrapper").removeClass("success").addClass("error");a.find(".geo_status_wrapper .geo_status").text(n)}else{a.find(".geo_status_wrapper").remove()}}function m(n,o){SN.U.NoticeGeoStatus(a,"Looking up place name...");$.getJSON(n,o,function(p){var q,r;if(typeof(p.location_ns)!="undefined"){a.find("[name=location_ns]").val(p.location_ns);q=p.location_ns}if(typeof(p.location_id)!="undefined"){a.find("[name=location_id]").val(p.location_id);r=p.location_id}if(typeof(p.name)=="undefined"){NLN_text=o.lat+";"+o.lon}else{NLN_text=p.name}SN.U.NoticeGeoStatus(a,NLN_text,o.lat,o.lon,p.url);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+NLN_text+")");a.find("[name=lat]").val(o.lat);a.find("[name=lon]").val(o.lon);a.find("[name=location_ns]").val(q);a.find("[name=location_id]").val(r);a.find("[name=notice_data-geo]").attr("checked",true);var s={NLat:o.lat,NLon:o.lon,NLNS:q,NLID:r,NLN:NLN_text,NLNU:p.url,NDG:true};$.cookie(SN.C.S.NoticeDataGeoCookie,JSON.stringify(s),{path:"/"})})}if(c.length>0){if($.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){c.attr("checked",false)}else{c.attr("checked",true)}var h=a.find(".notice_data-geo_wrap");var i=h.attr("title");h.removeAttr("title");j.attr("title",j.text());c.change(function(){if(c.attr("checked")===true||$.cookie(SN.C.S.NoticeDataGeoCookie)===null){j.attr("title",NoticeDataGeo_text.ShareDisable).addClass("checked");if($.cookie(SN.C.S.NoticeDataGeoCookie)===null||$.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){if(navigator.geolocation){SN.U.NoticeGeoStatus(a,"Requesting location from browser...");navigator.geolocation.getCurrentPosition(function(p){a.find("[name=lat]").val(p.coords.latitude);a.find("[name=lon]").val(p.coords.longitude);var q={lat:p.coords.latitude,lon:p.coords.longitude,token:$("#token").val()};m(i,q)},function(p){switch(p.code){case p.PERMISSION_DENIED:f("Location permission denied.");break;case p.TIMEOUT:f("Location lookup timeout.");break}},{timeout:10000})}else{if(e.length>0&&k.length>0){var n={lat:e,lon:k,token:$("#token").val()};m(i,n)}else{f();c.remove();j.remove()}}}else{var o=JSON.parse($.cookie(SN.C.S.NoticeDataGeoCookie));a.find("[name=lat]").val(o.NLat);a.find("[name=lon]").val(o.NLon);a.find("[name=location_ns]").val(o.NLNS);a.find("[name=location_id]").val(o.NLID);a.find("[name=notice_data-geo]").attr("checked",o.NDG);SN.U.NoticeGeoStatus(a,o.NLN,o.NLat,o.NLon,o.NLNU);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+o.NLN+")").addClass("checked")}}else{f()}}).change()}},NoticeGeoStatus:function(e,a,f,g,c){var h=e.find(".geo_status_wrapper");if(h.length==0){h=$('
      ');h.find("button.close").click(function(){e.find("[name=notice_data-geo]").removeAttr("checked").change()});e.append(h)}var b;if(c){b=$("").attr("href",c)}else{b=$("")}b.text(a);if(f||g){var d=f+";"+g;b.attr("title",d);if(!a){b.text(d)}}h.find(".geo_status").empty().append(b)},NewDirectMessage:function(){NDM=$(".entity_send-a-message a");NDM.attr({href:NDM.attr("href")+"&ajax=1"});NDM.bind("click",function(){var a=$(".entity_send-a-message form");if(a.length===0){$(this).addClass(SN.C.S.Processing);$.get(NDM.attr("href"),null,function(b){$(".entity_send-a-message").append(document._importNode($("form",b)[0],true));a=$(".entity_send-a-message .form_notice");SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);a.append('');$(".entity_send-a-message button").click(function(){a.hide();return false});NDM.removeClass(SN.C.S.Processing)})}else{a.show();$(".entity_send-a-message textarea").focus()}return false})},GetFullYear:function(c,d,a){var b=new Date();b.setFullYear(c,d,a);return b},StatusNetInstance:{Set:function(b){var a=SN.U.StatusNetInstance.Get();if(a!==null){b=$.extend(a,b)}$.cookie(SN.C.S.StatusNetInstance,JSON.stringify(b),{path:"/",expires:SN.U.GetFullYear(2029,0,1)})},Get:function(){var a=$.cookie(SN.C.S.StatusNetInstance);if(a!==null){return JSON.parse(a)}return null},Delete:function(){$.cookie(SN.C.S.StatusNetInstance,null)}},belongsOnTimeline:function(b){var a=$("body").attr("id");if(a=="public"){return true}var c=$("#nav_profile a").attr("href");if(c){var d=$(b).find(".entry-title .author a.url").attr("href");if(d==c){if(a=="all"||a=="showstream"){return true}}}return false}},Init:{NoticeForm:function(){if($("body.user_in").length>0){$("."+SN.C.S.FormNotice).each(function(){var a=$(this);SN.U.NoticeLocationAttach(a);SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);SN.U.NoticeDataAttach(a)})}},Notices:function(){if($("body.user_in").length>0){SN.U.NoticeFavor();SN.U.NoticeRepeat();SN.U.NoticeReply();SN.U.NoticeInlineReplySetup()}SN.U.NoticeAttachments()},EntityActions:function(){if($("body.user_in").length>0){$(".form_user_subscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_unsubscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_join").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_leave").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_nudge").live("click",function(){SN.U.FormXHR($(this));return false});SN.U.NewDirectMessage()}},Login:function(){if(SN.U.StatusNetInstance.Get()!==null){var a=SN.U.StatusNetInstance.Get().Nickname;if(a!==null){$("#form_login #nickname").val(a)}}$("#form_login").bind("submit",function(){SN.U.StatusNetInstance.Set({Nickname:$("#form_login #nickname").val()});return true})},UploadForms:function(){$("input[type=file]").change(function(d){if(typeof this.files=="object"&&this.files.length>0){var c=0;for(var b=0;b0&&c>a){var e="File too large: maximum upload size is %d bytes.";alert(e.replace("%d",a));$(this).val("");d.preventDefault();return false}}})}}};$(document).ready(function(){SN.Init.UploadForms();if($("."+SN.C.S.FormNotice).length>0){SN.Init.NoticeForm()}if($("#content .notices").length>0){SN.Init.Notices()}if($("#content .entity_actions").length>0){SN.Init.EntityActions()}if($("#form_login").length>0){SN.Init.Login()}});if(!document.ELEMENT_NODE){document.ELEMENT_NODE=1;document.ATTRIBUTE_NODE=2;document.TEXT_NODE=3;document.CDATA_SECTION_NODE=4;document.ENTITY_REFERENCE_NODE=5;document.ENTITY_NODE=6;document.PROCESSING_INSTRUCTION_NODE=7;document.COMMENT_NODE=8;document.DOCUMENT_NODE=9;document.DOCUMENT_TYPE_NODE=10;document.DOCUMENT_FRAGMENT_NODE=11;document.NOTATION_NODE=12}document._importNode=function(e,a){switch(e.nodeType){case document.ELEMENT_NODE:var d=document.createElement(e.nodeName);if(e.attributes&&e.attributes.length>0){for(var c=0,b=e.attributes.length;c0){for(var c=0,b=e.childNodes.length;c0){var j=c.pop();j()}}};window._google_loader_apiLoaded=function(){f()};var d=function(){return(window.google&&google.loader)};var g=function(j){if(d()){return true}h(j);e();return false};e();return{shim:true,type:"ClientLocation",lastPosition:null,getCurrentPosition:function(k,n,o){var m=this;if(!g(function(){m.getCurrentPosition(k,n,o)})){return}if(google.loader.ClientLocation){var l=google.loader.ClientLocation;var j={coords:{latitude:l.latitude,longitude:l.longitude,altitude:null,accuracy:43000,altitudeAccuracy:null,heading:null,speed:null},address:{city:l.address.city,country:l.address.country,country_code:l.address.country_code,region:l.address.region},timestamp:new Date()};k(j);this.lastPosition=j}else{if(n==="function"){n({code:3,message:"Using the Google ClientLocation API and it is not able to calculate a location."})}}},watchPosition:function(j,l,m){this.getCurrentPosition(j,l,m);var k=this;var n=setInterval(function(){k.getCurrentPosition(j,l,m)},10000);return n},clearWatch:function(j){clearInterval(j)},getPermission:function(l,j,k){return true}}});navigator.geolocation=(window.google&&google.gears)?a():b()})()}; \ No newline at end of file +var SN={C:{I:{CounterBlackout:false,MaxLength:140,PatternUsername:/^[0-9a-zA-Z\-_.]*$/,HTTP20x30x:[200,201,202,203,204,205,206,300,301,302,303,304,305,306,307]},S:{Disabled:"disabled",Warning:"warning",Error:"error",Success:"success",Processing:"processing",CommandResult:"command_result",FormNotice:"form_notice",NoticeDataGeo:"notice_data-geo",NoticeDataGeoCookie:"NoticeDataGeo",NoticeDataGeoSelected:"notice_data-geo_selected",StatusNetInstance:"StatusNetInstance"}},messages:{},msg:function(a){if(typeof SN.messages[a]=="undefined"){return"["+a+"]"}else{return SN.messages[a]}},U:{FormNoticeEnhancements:function(b){if(jQuery.data(b[0],"ElementData")===undefined){MaxLength=b.find(".count").text();if(typeof(MaxLength)=="undefined"){MaxLength=SN.C.I.MaxLength}jQuery.data(b[0],"ElementData",{MaxLength:MaxLength});SN.U.Counter(b);NDT=b.find("[name=status_textarea]");NDT.bind("keyup",function(c){SN.U.Counter(b)});var a=function(c){window.setTimeout(function(){SN.U.Counter(b)},50)};NDT.bind("cut",a).bind("paste",a)}else{b.find(".count").text(jQuery.data(b[0],"ElementData").MaxLength)}},Counter:function(d){SN.C.I.FormNoticeCurrent=d;var b=jQuery.data(d[0],"ElementData").MaxLength;if(b<=0){return}var c=b-SN.U.CharacterCount(d);var a=d.find(".count");if(c.toString()!=a.text()){if(!SN.C.I.CounterBlackout||c===0){if(a.text()!=String(c)){a.text(c)}if(c<0){d.addClass(SN.C.S.Warning)}else{d.removeClass(SN.C.S.Warning)}if(!SN.C.I.CounterBlackout){SN.C.I.CounterBlackout=true;SN.C.I.FormNoticeCurrent=d;window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);",500)}}}},CharacterCount:function(a){return a.find("[name=status_textarea]").val().length},ClearCounterBlackout:function(a){SN.C.I.CounterBlackout=false;SN.U.Counter(a)},RewriteAjaxAction:function(a){if(document.location.protocol=="https:"&&a.substr(0,5)=="http:"){return a.replace(/^http:\/\/[^:\/]+/,"https://"+document.location.host)}else{return a}},FormXHR:function(a){$.ajax({type:"POST",dataType:"xml",url:SN.U.RewriteAjaxAction(a.attr("action")),data:a.serialize()+"&ajax=1",beforeSend:function(b){a.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled)},error:function(c,d,b){alert(b||d)},success:function(b,c){if(typeof($("form",b)[0])!="undefined"){form_new=document._importNode($("form",b)[0],true);a.replaceWith(form_new)}else{a.replaceWith(document._importNode($("p",b)[0],true))}}})},FormNoticeXHR:function(b){SN.C.I.NoticeDataGeo={};b.append('');b.attr("action",SN.U.RewriteAjaxAction(b.attr("action")));var c=function(d,e){b.append($('

      ').addClass(d).text(e))};var a=function(){b.find(".form_response").remove()};b.ajaxForm({dataType:"xml",timeout:"60000",beforeSend:function(d){if(b.find("[name=status_textarea]").val()==""){b.addClass(SN.C.S.Warning);return false}b.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled);SN.U.normalizeGeoData(b);return true},error:function(f,g,e){b.removeClass(SN.C.S.Processing).find(".submit").removeClass(SN.C.S.Disabled).removeAttr(SN.C.S.Disabled,SN.C.S.Disabled);a();if(g=="timeout"){c("error","Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.")}else{var d=SN.U.GetResponseXML(f);if($("."+SN.C.S.Error,d).length>0){b.append(document._importNode($("."+SN.C.S.Error,d)[0],true))}else{if(parseInt(f.status)===0||jQuery.inArray(parseInt(f.status),SN.C.I.HTTP20x30x)>=0){b.resetForm().find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}else{c("error","(Sorry! We had trouble sending your notice ("+f.status+" "+f.statusText+"). Please report the problem to the site administrator if this happens again.")}}}},success:function(i,f){a();var n=$("#"+SN.C.S.Error,i);if(n.length>0){c("error",n.text())}else{if($("body")[0].id=="bookmarklet"){self.close()}var d=$("#"+SN.C.S.CommandResult,i);if(d.length>0){c("success",d.text())}else{var m=document._importNode($("li",i)[0],true);var k=$("#notices_primary .notices:first");var l=b.closest("li.notice-reply");if(l.length>0){var e=$(m).attr("id");if($("#"+e).length==0){var j=l.closest("li.notice");l.replaceWith(m);SN.U.NoticeInlineReplyPlaceholder(j)}else{l.remove()}}else{if(k.length>0&&SN.U.belongsOnTimeline(m)){if($("#"+m.id).length===0){var h=b.find("[name=inreplyto]").val();var g="#notices_primary #notice-"+h;if($("body")[0].id=="conversation"){if(h.length>0&&$(g+" .notices").length<1){$(g).append('
        ')}$($(g+" .notices")[0]).append(m)}else{k.prepend(m)}$("#"+m.id).css({display:"none"}).fadeIn(2500);SN.U.NoticeWithAttachment($("#"+m.id));SN.U.NoticeReplyTo($("#"+m.id))}}else{c("success",$("title",i).text())}}}b.resetForm();b.find("[name=inreplyto]").val("");b.find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}},complete:function(d,e){b.removeClass(SN.C.S.Processing).find(".submit").removeAttr(SN.C.S.Disabled).removeClass(SN.C.S.Disabled);b.find("[name=lat]").val(SN.C.I.NoticeDataGeo.NLat);b.find("[name=lon]").val(SN.C.I.NoticeDataGeo.NLon);b.find("[name=location_ns]").val(SN.C.I.NoticeDataGeo.NLNS);b.find("[name=location_id]").val(SN.C.I.NoticeDataGeo.NLID);b.find("[name=notice_data-geo]").attr("checked",SN.C.I.NoticeDataGeo.NDG)}})},normalizeGeoData:function(a){SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val();SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val();SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked");var b=$.cookie(SN.C.S.NoticeDataGeoCookie);if(b!==null&&b!="disabled"){b=JSON.parse(b);SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val(b.NLat).val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val(b.NLon).val();if(b.NLNS){SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val(b.NLNS).val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val(b.NLID).val()}else{a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("")}}if(b=="disabled"){SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",false).attr("checked")}else{SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",true).attr("checked")}},GetResponseXML:function(b){try{return b.responseXML}catch(a){return(new DOMParser()).parseFromString(b.responseText,"text/xml")}},NoticeReply:function(){if($("#content .notice_reply").length>0){$("#content .notice").each(function(){SN.U.NoticeReplyTo($(this))})}},NoticeReplyTo:function(a){a.find(".notice_reply").live("click",function(c){c.preventDefault();var b=($(".author .nickname",a).length>0)?$($(".author .nickname",a)[0]):$(".author .nickname.uid");SN.U.NoticeInlineReplyTrigger(a,"@"+b.text());return false})},NoticeInlineReplyTrigger:function(g,h){var b=$($(".notice_id",g)[0]).text();var d=g;var e=g.closest(".notices");if(e.hasClass("threaded-replies")){d=e.closest(".notice")}else{e=$("ul.threaded-replies",g);if(e.length==0){e=$('
          ');g.append(e)}}var i=$(".notice-reply-form",e);var c=function(){i.find("input[name=inreplyto]").val(b);var l=i.find("textarea");if(l.length==0){throw"No textarea"}var k="";if(h){k=h+" "}l.val(k+l.val().replace(RegExp(k,"i"),""));l.data("initialText",$.trim(h+""));l.focus();if(l[0].setSelectionRange){var j=l.val().length;l[0].setSelectionRange(j,j)}};if(i.length>0){c()}else{$("li.notice-reply-placeholder").remove();var f=$("li.notice-reply",e);if(f.length==0){var a=$("#form_notice").attr("action");f=$('
        • ');$.get(a,{ajax:1},function(l,n,m){var j=document._importNode($("form",l)[0],true);f.append(j);e.append(f);var k=i=$(j);SN.U.NoticeLocationAttach(k);SN.U.FormNoticeXHR(k);SN.U.FormNoticeEnhancements(k);SN.U.NoticeDataAttach(k);c()})}}},NoticeFavor:function(){$(".form_favor").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_disfavor").live("click",function(){SN.U.FormXHR($(this));return false})},NoticeInlineReplyPlaceholder:function(b){var a=b.find("ul.threaded-replies");var c=$('
        • ');c.click(function(){SN.U.NoticeInlineReplyTrigger(b)});c.find("input").val(SN.msg("reply_placeholder"));a.append(c)},NoticeInlineReplySetup:function(){$(".threaded-replies").each(function(){var b=$(this);var a=b.closest(".notice");SN.U.NoticeInlineReplyPlaceholder(a)})},NoticeRepeat:function(){$(".form_repeat").live("click",function(a){a.preventDefault();SN.U.NoticeRepeatConfirmation($(this));return false})},NoticeRepeatConfirmation:function(a){var c=a.find(".submit");var b=c.clone();b.addClass("submit_dialogbox").removeClass("submit");a.append(b);b.bind("click",function(){SN.U.FormXHR(a);return false});c.hide();a.addClass("dialogbox").append('').closest(".notice-options").addClass("opaque");a.find("button.close").click(function(){$(this).remove();a.removeClass("dialogbox").closest(".notice-options").removeClass("opaque");a.find(".submit_dialogbox").remove();a.find(".submit").show();return false})},NoticeAttachments:function(){$(".notice a.attachment").each(function(){SN.U.NoticeWithAttachment($(this).closest(".notice"))})},NoticeWithAttachment:function(b){if(b.find(".attachment").length===0){return}var a=b.find(".attachment.more");if(a.length>0){$(a[0]).click(function(){var c=$(this);c.addClass(SN.C.S.Processing);$.get(c.attr("href")+"/ajax",null,function(d){c.parent(".entry-content").html($(d).find("#attachment_view .entry-content").html())});return false}).attr("title",SN.msg("showmore_tooltip"))}},NoticeDataAttach:function(b){var a=b.find("input[type=file]");a.change(function(f){b.find(".attach-status").remove();var d=$(this).val();if(!d){return false}var c=$('
          ');c.find("code").text(d);c.find("button").click(function(){c.remove();a.val("");return false});b.append(c);if(typeof this.files=="object"){for(var e=0;eg){f=false}if(f){h(c,function(j){var i=$("").attr("title",e).attr("alt",e).attr("src",j).attr("style","height: 120px");d.find(".attach-status").append(i)})}else{var b=$("
          ").text(e);d.find(".attach-status").append(b)}},NoticeLocationAttach:function(a){var e=a.find("[name=lat]");var k=a.find("[name=lon]");var g=a.find("[name=location_ns]").val();var l=a.find("[name=location_id]").val();var b="";var d=a.find("[name=notice_data-geo]");var c=a.find("[name=notice_data-geo]");var j=a.find("label.notice_data-geo");function f(n){j.attr("title",jQuery.trim(j.text())).removeClass("checked");a.find("[name=lat]").val("");a.find("[name=lon]").val("");a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("");a.find("[name=notice_data-geo]").attr("checked",false);$.cookie(SN.C.S.NoticeDataGeoCookie,"disabled",{path:"/"});if(n){a.find(".geo_status_wrapper").removeClass("success").addClass("error");a.find(".geo_status_wrapper .geo_status").text(n)}else{a.find(".geo_status_wrapper").remove()}}function m(n,o){SN.U.NoticeGeoStatus(a,"Looking up place name...");$.getJSON(n,o,function(p){var q,r;if(typeof(p.location_ns)!="undefined"){a.find("[name=location_ns]").val(p.location_ns);q=p.location_ns}if(typeof(p.location_id)!="undefined"){a.find("[name=location_id]").val(p.location_id);r=p.location_id}if(typeof(p.name)=="undefined"){NLN_text=o.lat+";"+o.lon}else{NLN_text=p.name}SN.U.NoticeGeoStatus(a,NLN_text,o.lat,o.lon,p.url);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+NLN_text+")");a.find("[name=lat]").val(o.lat);a.find("[name=lon]").val(o.lon);a.find("[name=location_ns]").val(q);a.find("[name=location_id]").val(r);a.find("[name=notice_data-geo]").attr("checked",true);var s={NLat:o.lat,NLon:o.lon,NLNS:q,NLID:r,NLN:NLN_text,NLNU:p.url,NDG:true};$.cookie(SN.C.S.NoticeDataGeoCookie,JSON.stringify(s),{path:"/"})})}if(c.length>0){if($.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){c.attr("checked",false)}else{c.attr("checked",true)}var h=a.find(".notice_data-geo_wrap");var i=h.attr("title");h.removeAttr("title");j.attr("title",j.text());c.change(function(){if(c.attr("checked")===true||$.cookie(SN.C.S.NoticeDataGeoCookie)===null){j.attr("title",NoticeDataGeo_text.ShareDisable).addClass("checked");if($.cookie(SN.C.S.NoticeDataGeoCookie)===null||$.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){if(navigator.geolocation){SN.U.NoticeGeoStatus(a,"Requesting location from browser...");navigator.geolocation.getCurrentPosition(function(p){a.find("[name=lat]").val(p.coords.latitude);a.find("[name=lon]").val(p.coords.longitude);var q={lat:p.coords.latitude,lon:p.coords.longitude,token:$("#token").val()};m(i,q)},function(p){switch(p.code){case p.PERMISSION_DENIED:f("Location permission denied.");break;case p.TIMEOUT:f("Location lookup timeout.");break}},{timeout:10000})}else{if(e.length>0&&k.length>0){var n={lat:e,lon:k,token:$("#token").val()};m(i,n)}else{f();c.remove();j.remove()}}}else{var o=JSON.parse($.cookie(SN.C.S.NoticeDataGeoCookie));a.find("[name=lat]").val(o.NLat);a.find("[name=lon]").val(o.NLon);a.find("[name=location_ns]").val(o.NLNS);a.find("[name=location_id]").val(o.NLID);a.find("[name=notice_data-geo]").attr("checked",o.NDG);SN.U.NoticeGeoStatus(a,o.NLN,o.NLat,o.NLon,o.NLNU);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+o.NLN+")").addClass("checked")}}else{f()}}).change()}},NoticeGeoStatus:function(e,a,f,g,c){var h=e.find(".geo_status_wrapper");if(h.length==0){h=$('
          ');h.find("button.close").click(function(){e.find("[name=notice_data-geo]").removeAttr("checked").change()});e.append(h)}var b;if(c){b=$("").attr("href",c)}else{b=$("")}b.text(a);if(f||g){var d=f+";"+g;b.attr("title",d);if(!a){b.text(d)}}h.find(".geo_status").empty().append(b)},NewDirectMessage:function(){NDM=$(".entity_send-a-message a");NDM.attr({href:NDM.attr("href")+"&ajax=1"});NDM.bind("click",function(){var a=$(".entity_send-a-message form");if(a.length===0){$(this).addClass(SN.C.S.Processing);$.get(NDM.attr("href"),null,function(b){$(".entity_send-a-message").append(document._importNode($("form",b)[0],true));a=$(".entity_send-a-message .form_notice");SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);a.append('');$(".entity_send-a-message button").click(function(){a.hide();return false});NDM.removeClass(SN.C.S.Processing)})}else{a.show();$(".entity_send-a-message textarea").focus()}return false})},GetFullYear:function(c,d,a){var b=new Date();b.setFullYear(c,d,a);return b},StatusNetInstance:{Set:function(b){var a=SN.U.StatusNetInstance.Get();if(a!==null){b=$.extend(a,b)}$.cookie(SN.C.S.StatusNetInstance,JSON.stringify(b),{path:"/",expires:SN.U.GetFullYear(2029,0,1)})},Get:function(){var a=$.cookie(SN.C.S.StatusNetInstance);if(a!==null){return JSON.parse(a)}return null},Delete:function(){$.cookie(SN.C.S.StatusNetInstance,null)}},belongsOnTimeline:function(b){var a=$("body").attr("id");if(a=="public"){return true}var c=$("#nav_profile a").attr("href");if(c){var d=$(b).find(".entry-title .author a.url").attr("href");if(d==c){if(a=="all"||a=="showstream"){return true}}}return false},switchInputFormTab:function(a){$(".input_form_nav_tab.current").removeClass("current");$("#input_form_nav_"+a).addClass("current");$(".input_form.current").removeClass("current");$("#input_form_"+a).addClass("current")}},Init:{NoticeForm:function(){if($("body.user_in").length>0){$("."+SN.C.S.FormNotice).each(function(){var a=$(this);SN.U.NoticeLocationAttach(a);SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);SN.U.NoticeDataAttach(a)})}},Notices:function(){if($("body.user_in").length>0){SN.U.NoticeFavor();SN.U.NoticeRepeat();SN.U.NoticeReply();SN.U.NoticeInlineReplySetup()}SN.U.NoticeAttachments()},EntityActions:function(){if($("body.user_in").length>0){$(".form_user_subscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_unsubscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_join").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_leave").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_nudge").live("click",function(){SN.U.FormXHR($(this));return false});SN.U.NewDirectMessage()}},Login:function(){if(SN.U.StatusNetInstance.Get()!==null){var a=SN.U.StatusNetInstance.Get().Nickname;if(a!==null){$("#form_login #nickname").val(a)}}$("#form_login").bind("submit",function(){SN.U.StatusNetInstance.Set({Nickname:$("#form_login #nickname").val()});return true})},UploadForms:function(){$("input[type=file]").change(function(d){if(typeof this.files=="object"&&this.files.length>0){var c=0;for(var b=0;b0&&c>a){var e="File too large: maximum upload size is %d bytes.";alert(e.replace("%d",a));$(this).val("");d.preventDefault();return false}}})}}};$(document).ready(function(){SN.Init.UploadForms();if($("."+SN.C.S.FormNotice).length>0){SN.Init.NoticeForm()}if($("#content .notices").length>0){SN.Init.Notices()}if($("#content .entity_actions").length>0){SN.Init.EntityActions()}if($("#form_login").length>0){SN.Init.Login()}});if(!document.ELEMENT_NODE){document.ELEMENT_NODE=1;document.ATTRIBUTE_NODE=2;document.TEXT_NODE=3;document.CDATA_SECTION_NODE=4;document.ENTITY_REFERENCE_NODE=5;document.ENTITY_NODE=6;document.PROCESSING_INSTRUCTION_NODE=7;document.COMMENT_NODE=8;document.DOCUMENT_NODE=9;document.DOCUMENT_TYPE_NODE=10;document.DOCUMENT_FRAGMENT_NODE=11;document.NOTATION_NODE=12}document._importNode=function(e,a){switch(e.nodeType){case document.ELEMENT_NODE:var d=document.createElement(e.nodeName);if(e.attributes&&e.attributes.length>0){for(var c=0,b=e.attributes.length;c0){for(var c=0,b=e.childNodes.length;c0){var j=c.pop();j()}}};window._google_loader_apiLoaded=function(){f()};var d=function(){return(window.google&&google.loader)};var g=function(j){if(d()){return true}h(j);e();return false};e();return{shim:true,type:"ClientLocation",lastPosition:null,getCurrentPosition:function(k,n,o){var m=this;if(!g(function(){m.getCurrentPosition(k,n,o)})){return}if(google.loader.ClientLocation){var l=google.loader.ClientLocation;var j={coords:{latitude:l.latitude,longitude:l.longitude,altitude:null,accuracy:43000,altitudeAccuracy:null,heading:null,speed:null},address:{city:l.address.city,country:l.address.country,country_code:l.address.country_code,region:l.address.region},timestamp:new Date()};k(j);this.lastPosition=j}else{if(n==="function"){n({code:3,message:"Using the Google ClientLocation API and it is not able to calculate a location."})}}},watchPosition:function(j,l,m){this.getCurrentPosition(j,l,m);var k=this;var n=setInterval(function(){k.getCurrentPosition(j,l,m)},10000);return n},clearWatch:function(j){clearInterval(j)},getPermission:function(l,j,k){return true}}});navigator.geolocation=(window.google&&google.gears)?a():b()})()}; \ No newline at end of file diff --git a/lib/action.php b/lib/action.php index a049fec97c..b7f0036699 100644 --- a/lib/action.php +++ b/lib/action.php @@ -657,7 +657,8 @@ class Action extends HTMLOutputter // lawsuit foreach ($tabs as $tag => $title) { - $attrs = array('id' => 'input_form_nav_'.$title); + $attrs = array('id' => 'input_form_nav_'.$tag, + 'class' => 'input_form_nav_tab'); if ($tag == 'status') { $attrs['class'] = 'current'; @@ -666,7 +667,7 @@ class Action extends HTMLOutputter // lawsuit $this->elementStart('li', $attrs); $this->element('a', - array('href' => 'javascript:switchInputFormTab("'.$tag.'")'), + array('href' => 'javascript:SN.U.switchInputFormTab("'.$tag.'")'), $title); $this->elementEnd('li'); } @@ -679,9 +680,7 @@ class Action extends HTMLOutputter // lawsuit 'id' => 'input_form_'.$tag); if ($tag == 'status') { - $attrs['class'] .= ' active'; - } else { - $attrs['class'] .= ' inactive'; + $attrs['class'] .= ' current'; } $this->elementStart('div', $attrs); @@ -698,6 +697,8 @@ class Action extends HTMLOutputter // lawsuit if (!empty($form)) { $form->show(); } + + $this->elementEnd('div'); } } } diff --git a/theme/rebase/css/display.css b/theme/rebase/css/display.css index 32df41b93a..f569131213 100644 --- a/theme/rebase/css/display.css +++ b/theme/rebase/css/display.css @@ -1953,8 +1953,27 @@ margin-bottom:18px; padding-left:20px; } +#input_form_nav { + list-style-type: none; +} -}/*end of @media screen, projection, tv*/ +#input_form_nav li { + display:inline; +} + +.input_form_nav_tab.current { + text-decoration: underline; +} + +.input_form { + display: none; +} + +.input_form.current { + display: block; +} + +/*end of @media screen, projection, tv*/ @media print { From 876c7a42c835273b71a0a2a10c9e79e1660ebe47 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 12:36:04 -0500 Subject: [PATCH 50/68] remove adminpanelnav from adminpanelaction module --- lib/adminpanelaction.php | 126 --------------------------------------- 1 file changed, 126 deletions(-) diff --git a/lib/adminpanelaction.php b/lib/adminpanelaction.php index 8dd16e9d0c..a085fcd5dc 100644 --- a/lib/adminpanelaction.php +++ b/lib/adminpanelaction.php @@ -291,129 +291,3 @@ class AdminPanelAction extends Action return $isOK; } } - -/** - * Menu for public group of actions - * - * @category Output - * @package StatusNet - * @author Evan Prodromou - * @author Sarven Capadisli - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - * - * @see Widget - */ -class AdminPanelNav extends Widget -{ - var $action = null; - - /** - * Construction - * - * @param Action $action current action, used for output - */ - function __construct($action=null) - { - parent::__construct($action); - $this->action = $action; - } - - /** - * Show the menu - * - * @return void - */ - function show() - { - $action_name = $this->action->trimmed('action'); - - $this->action->elementStart('ul', array('class' => 'nav')); - - if (Event::handle('StartAdminPanelNav', array($this))) { - - if (AdminPanelAction::canAdmin('site')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Basic site configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('siteadminpanel'), _m('MENU', 'Site'), - $menu_title, $action_name == 'siteadminpanel', 'nav_site_admin_panel'); - } - - if (AdminPanelAction::canAdmin('design')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Design configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('designadminpanel'), _m('MENU', 'Design'), - $menu_title, $action_name == 'designadminpanel', 'nav_design_admin_panel'); - } - - if (AdminPanelAction::canAdmin('user')) { - // TRANS: Menu item title/tooltip - $menu_title = _('User configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('useradminpanel'), _('User'), - $menu_title, $action_name == 'useradminpanel', 'nav_user_admin_panel'); - } - - if (AdminPanelAction::canAdmin('access')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Access configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('accessadminpanel'), _('Access'), - $menu_title, $action_name == 'accessadminpanel', 'nav_access_admin_panel'); - } - - if (AdminPanelAction::canAdmin('paths')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Paths configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'), - $menu_title, $action_name == 'pathsadminpanel', 'nav_paths_admin_panel'); - } - - if (AdminPanelAction::canAdmin('sessions')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Sessions configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'), - $menu_title, $action_name == 'sessionsadminpanel', 'nav_sessions_admin_panel'); - } - - if (AdminPanelAction::canAdmin('sitenotice')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Edit site notice'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('sitenoticeadminpanel'), _('Site notice'), - $menu_title, $action_name == 'sitenoticeadminpanel', 'nav_sitenotice_admin_panel'); - } - - if (AdminPanelAction::canAdmin('snapshot')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Snapshots configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('snapshotadminpanel'), _('Snapshots'), - $menu_title, $action_name == 'snapshotadminpanel', 'nav_snapshot_admin_panel'); - } - - if (AdminPanelAction::canAdmin('license')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Set site license'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('licenseadminpanel'), _('License'), - $menu_title, $action_name == 'licenseadminpanel', 'nav_license_admin_panel'); - } - - if (AdminPanelAction::canAdmin('plugins')) { - // TRANS: Menu item title/tooltip - $menu_title = _('Plugins configuration'); - // TRANS: Menu item for site administration - $this->out->menuItem(common_local_url('pluginsadminpanel'), _('Plugins'), - $menu_title, $action_name == 'pluginsadminpanel', 'nav_design_admin_panel'); - } - - Event::handle('EndAdminPanelNav', array($this)); - } - $this->action->elementEnd('ul'); - } -} From b4f1281799766570ff68580e13c588ea8c8ce1f1 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 12:36:45 -0500 Subject: [PATCH 51/68] abstraction for starting and ending a menu --- lib/menu.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/menu.php b/lib/menu.php index 2713b44d50..751f8e1b7d 100644 --- a/lib/menu.php +++ b/lib/menu.php @@ -62,6 +62,23 @@ class Menu extends Widget $this->actionName = $action->trimmed('action'); } + function id() + { + return 'unknown_menu'; + } + + function menuStart() + { + $this->action->elementStart('div', array('id' => $this->id())); + $this->action->elementStart('ul', array('class' => 'nav')); + } + + function menuEnd() + { + $this->action->elementEnd('ul'); + $this->action->elementEnd('div'); + } + function item($actionName, $args, $label, $description, $id=null) { if (empty($id)) { From 8e03c83a57e29a0e840b44b1e5cb04e1422a845f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 12:37:07 -0500 Subject: [PATCH 52/68] primarynav uses menustart and menuend --- lib/primarynav.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/primarynav.php b/lib/primarynav.php index 296328d8bd..de3ea2641f 100644 --- a/lib/primarynav.php +++ b/lib/primarynav.php @@ -50,8 +50,7 @@ class PrimaryNav extends Menu function show() { $user = common_current_user(); - $this->action->elementStart('ul', array('class' => 'nav', - 'id' => 'site_nav_global_primary')); + $this->menuStart(); if (Event::handle('StartPrimaryNav', array($this->action))) { if (!empty($user)) { $this->action->menuItem(common_local_url('profilesettings'), @@ -89,7 +88,12 @@ class PrimaryNav extends Menu Event::handle('EndPrimaryNav', array($this->action)); } - + $this->menuEnd(); $this->action->elementEnd('ul'); } + + function id() + { + return 'site_nav_global_primary'; + } } From 6ab7329e85b1878b40165bc2475151a6e78195b4 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 12:39:31 -0500 Subject: [PATCH 53/68] Revert "primarynav uses menustart and menuend" This reverts commit 8e03c83a57e29a0e840b44b1e5cb04e1422a845f. --- lib/primarynav.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/primarynav.php b/lib/primarynav.php index de3ea2641f..296328d8bd 100644 --- a/lib/primarynav.php +++ b/lib/primarynav.php @@ -50,7 +50,8 @@ class PrimaryNav extends Menu function show() { $user = common_current_user(); - $this->menuStart(); + $this->action->elementStart('ul', array('class' => 'nav', + 'id' => 'site_nav_global_primary')); if (Event::handle('StartPrimaryNav', array($this->action))) { if (!empty($user)) { $this->action->menuItem(common_local_url('profilesettings'), @@ -88,12 +89,7 @@ class PrimaryNav extends Menu Event::handle('EndPrimaryNav', array($this->action)); } - $this->menuEnd(); + $this->action->elementEnd('ul'); } - - function id() - { - return 'site_nav_global_primary'; - } } From b751ab70fb4f9f7ad807e29b5716f2100aeb0de8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 12:39:52 -0500 Subject: [PATCH 54/68] Revert "abstraction for starting and ending a menu" This reverts commit b4f1281799766570ff68580e13c588ea8c8ce1f1. --- lib/menu.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/menu.php b/lib/menu.php index 751f8e1b7d..2713b44d50 100644 --- a/lib/menu.php +++ b/lib/menu.php @@ -62,23 +62,6 @@ class Menu extends Widget $this->actionName = $action->trimmed('action'); } - function id() - { - return 'unknown_menu'; - } - - function menuStart() - { - $this->action->elementStart('div', array('id' => $this->id())); - $this->action->elementStart('ul', array('class' => 'nav')); - } - - function menuEnd() - { - $this->action->elementEnd('ul'); - $this->action->elementEnd('div'); - } - function item($actionName, $args, $label, $description, $id=null) { if (empty($id)) { From 2272044ad1c8bcde9d79aeaf1b135dc7b47784da Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 12:42:51 -0500 Subject: [PATCH 55/68] wrapper div for primary nav --- lib/action.php | 2 ++ lib/primarynav.php | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/action.php b/lib/action.php index dc95b030d2..7ef959bc4e 100644 --- a/lib/action.php +++ b/lib/action.php @@ -536,8 +536,10 @@ class Action extends HTMLOutputter // lawsuit */ function showPrimaryNav() { + $this->elementStart('div', array('id' => 'site_nav_global_primary')); $pn = new PrimaryNav($this); $pn->show(); + $this->elementEnd('div'); } /** diff --git a/lib/primarynav.php b/lib/primarynav.php index 296328d8bd..7748d7a1c7 100644 --- a/lib/primarynav.php +++ b/lib/primarynav.php @@ -50,8 +50,7 @@ class PrimaryNav extends Menu function show() { $user = common_current_user(); - $this->action->elementStart('ul', array('class' => 'nav', - 'id' => 'site_nav_global_primary')); + $this->action->elementStart('ul', array('class' => 'nav')); if (Event::handle('StartPrimaryNav', array($this->action))) { if (!empty($user)) { $this->action->menuItem(common_local_url('profilesettings'), From 998733cdd44143b1a3ded13f28ff5e848516b1c6 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 12:49:20 -0500 Subject: [PATCH 56/68] UR FACE --- lib/userprofile.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/userprofile.php b/lib/userprofile.php index 0b7efb22fc..9c563db5d0 100644 --- a/lib/userprofile.php +++ b/lib/userprofile.php @@ -95,6 +95,8 @@ class UserProfile extends Widget function showAvatar() { + $this->out->elementStart('div', 'ur_face'); + if (Event::handle('StartProfilePageAvatar', array($this->out, $this->profile))) { $avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE); @@ -119,6 +121,8 @@ class UserProfile extends Widget Event::handle('EndProfilePageAvatar', array($this->out, $this->profile)); } + + $this->out->elementEnd('div'); } function showNickname() From 618a65898566a99bd06ac869c369934d11f7764f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 14:06:46 -0500 Subject: [PATCH 57/68] show correct notice in output --- lib/microappplugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/microappplugin.php b/lib/microappplugin.php index 0b02f5da52..dbbc6262af 100644 --- a/lib/microappplugin.php +++ b/lib/microappplugin.php @@ -103,6 +103,7 @@ abstract class MicroAppPlugin extends Plugin } $out = $nli->out; + $notice = $nli->notice; $this->showNotice($notice, $out); From 32f4daf44daa88df1b8e06a5e45a17f1f228d40a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 14:20:55 -0500 Subject: [PATCH 58/68] Notice saves its object type --- classes/Notice.php | 8 ++++++++ classes/statusnet.ini | 1 + 2 files changed, 9 insertions(+) diff --git a/classes/Notice.php b/classes/Notice.php index 157fdf2dc4..7be63b4e9f 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -72,6 +72,7 @@ class Notice extends Memcached_DataObject public $location_id; // int(4) public $location_ns; // int(4) public $repeat_of; // int(4) + public $object_type; // varchar(255) /* Static get */ function staticGet($k,$v=NULL) @@ -241,6 +242,7 @@ class Notice extends Memcached_DataObject * array 'urls' list of attached/referred URLs to save with the * notice in place of extracting links from content * boolean 'distribute' whether to distribute the notice, default true + * string 'object_type' URL of the associated object type (default ActivityObject::NOTE) * * @fixme tag override * @@ -360,6 +362,12 @@ class Notice extends Memcached_DataObject $notice->rendered = common_render_content($final, $notice); } + if (empty($object_type)) { + $notice->object_type = ActivityObject::NOTE; + } else { + $notice->object_type = $object_type; + } + if (Event::handle('StartNoticeSave', array(&$notice))) { // XXX: some of these functions write to the DB diff --git a/classes/statusnet.ini b/classes/statusnet.ini index bf8d173805..338e5c5aea 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -336,6 +336,7 @@ lon = 1 location_id = 1 location_ns = 1 repeat_of = 1 +object_type = 2 [notice__keys] id = N From 6862f765f6c0550ec7c28bb9ef7efdacd270d275 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 14:21:16 -0500 Subject: [PATCH 59/68] ActivityObject uses Notice's object_type by default --- lib/activityobject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/activityobject.php b/lib/activityobject.php index a69e1a1b42..de2fcab767 100644 --- a/lib/activityobject.php +++ b/lib/activityobject.php @@ -422,7 +422,7 @@ class ActivityObject if (Event::handle('StartActivityObjectFromNotice', array($notice, &$object))) { - $object->type = ActivityObject::NOTE; + $object->type = (empty($notice->object_type)) ? ActivityObject::NOTE : $notice->object_type; $object->id = $notice->uri; $object->title = $notice->content; From f5782e9e56759e5ce3b200d51204336443b78dd7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 14:25:05 -0500 Subject: [PATCH 60/68] save the object type when saving a new bookmark notice --- plugins/Bookmark/Bookmark.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Bookmark/Bookmark.php b/plugins/Bookmark/Bookmark.php index 777b50f724..04cd8dbfa8 100644 --- a/plugins/Bookmark/Bookmark.php +++ b/plugins/Bookmark/Bookmark.php @@ -307,7 +307,8 @@ class Bookmark extends Memcached_DataObject $options = array_merge(array('urls' => array($url), 'rendered' => $rendered, 'tags' => $tags, - 'replies' => $replies), + 'replies' => $replies, + 'object_type' => ActivityObject::BOOKMARK), $options); if (!array_key_exists('uri', $options)) { From 095e2a74d4af3f5312ab44e2f388bf48d0f6cc36 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 14:25:37 -0500 Subject: [PATCH 61/68] fix object errors with bookmark notices --- plugins/Bookmark/BookmarkPlugin.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/Bookmark/BookmarkPlugin.php b/plugins/Bookmark/BookmarkPlugin.php index 1ef5f5c0e3..44f3db7867 100644 --- a/plugins/Bookmark/BookmarkPlugin.php +++ b/plugins/Bookmark/BookmarkPlugin.php @@ -510,6 +510,8 @@ class BookmarkPlugin extends MicroAppPlugin function showNotice($notice, $out) { + $nb = Bookmark::getByNotice($notice); + $profile = $notice->getProfile(); $atts = $notice->attachments(); @@ -542,8 +544,8 @@ class BookmarkPlugin extends MicroAppPlugin // Replies look like "for:" tags - $replies = $nli->notice->getReplies(); - $tags = $nli->notice->getTags(); + $replies = $notice->getReplies(); + $tags = $notice->getTags(); if (!empty($replies) || !empty($tags)) { From e1d177de7e222db401c92a0343e0453219db4607 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 14:27:23 -0500 Subject: [PATCH 62/68] store reply_to notices as comment activity objects --- classes/Notice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/Notice.php b/classes/Notice.php index 7be63b4e9f..d520f4728f 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -363,7 +363,7 @@ class Notice extends Memcached_DataObject } if (empty($object_type)) { - $notice->object_type = ActivityObject::NOTE; + $notice->object_type = (empty($notice->reply_to)) ? ActivityObject::NOTE : ActivityObject::COMMENT; } else { $notice->object_type = $object_type; } From 0b95d68910bf2c67742083aeb88577dc3ac662fb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 14:32:21 -0500 Subject: [PATCH 63/68] cleaner is the new default theme (for now) --- lib/default.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/default.php b/lib/default.php index c612557d69..38903730f5 100644 --- a/lib/default.php +++ b/lib/default.php @@ -33,7 +33,7 @@ $default = 'nickname' => 'statusnet', 'wildcard' => null, 'server' => $_server, - 'theme' => 'default', + 'theme' => 'cleaner', 'path' => $_path, 'logfile' => null, 'logo' => null, From 15686cdf56bbb6eb39f80422579c273e8ae5ffad Mon Sep 17 00:00:00 2001 From: Samantha Doherty Date: Mon, 7 Mar 2011 14:43:06 -0500 Subject: [PATCH 64/68] First version of 3cl theme neo. --- theme/neo/css/display.css | 828 +++++++++++++++++++++++++++ theme/neo/css/ie.css | 81 +++ theme/neo/css/mp-screen.css | 204 +++++++ theme/neo/default-avatar-mini.png | Bin 0 -> 857 bytes theme/neo/default-avatar-profile.png | Bin 0 -> 3737 bytes theme/neo/default-avatar-stream.png | Bin 0 -> 1791 bytes theme/neo/images/bg.png | Bin 0 -> 207 bytes theme/neo/logo.png | Bin 0 -> 1633 bytes theme/neo/mobilelogo.png | Bin 0 -> 9357 bytes theme/neo/theme.ini | 1 + 10 files changed, 1114 insertions(+) create mode 100644 theme/neo/css/display.css create mode 100644 theme/neo/css/ie.css create mode 100644 theme/neo/css/mp-screen.css create mode 100644 theme/neo/default-avatar-mini.png create mode 100644 theme/neo/default-avatar-profile.png create mode 100644 theme/neo/default-avatar-stream.png create mode 100644 theme/neo/images/bg.png create mode 100644 theme/neo/logo.png create mode 100644 theme/neo/mobilelogo.png create mode 100644 theme/neo/theme.ini diff --git a/theme/neo/css/display.css b/theme/neo/css/display.css new file mode 100644 index 0000000000..a542ed7609 --- /dev/null +++ b/theme/neo/css/display.css @@ -0,0 +1,828 @@ +/** theme: neo + * + * @package StatusNet + * @author Samantha Doherty + * @copyright 2011 StatusNet, Inc. + * @license http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution 3.0 Unported + * @link http://status.net/ + */ + + +@media screen, projection, tv { + +body { + background-color: #C6C8CC; + background-image: url(../images/bg.png); + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 82%; +} + +a {color: #3e3e8c;} + +h1 {font-size: 1.6em;} +h2 {font-size: 1.6em;} +h3 {font-size: 1.4em;} +h4 {font-size: 1.4em;} +h5 {font-size: 1.2em;} +h6 {font-size: 1em;} + +#wrap { + width: 930px; + margin: 0px auto; + padding: 0px 15px 10px 15px; + background-color: #fff; + border-left: 10px solid #E0E0E0; + border-right: 10px solid #E0E0E0; +} + +#header { + width: 940px; + padding: 0px; + padding-top: 50px; +} + +address { + float: left; + margin-right: 20px; + margin-top: 0px; +} + +.poweredby { + background: url(../images/sn-tiny.png) no-repeat top left; + height: 40px; + font-size: 0.8em; + color: #fff; + line-height: 42px; + padding-left: 50px; + position: absolute; + top: 6px; + left: 0; + z-index: 99; + font-style: normal; +} + +.poweredby a { + color: #fff !important; + font-weight: bold; +} + +#site_nav_global_primary { + display: block; + position: absolute; + top: 0; + left: 0; + z-index: 98; + background-color: #364A84; + width: 960px; + margin-left: -15px; + margin-top: 0px; + height: 24px; + line-height: 20px; + border-top: 10px solid #fff; + border-bottom: 1px solid #fff; +} + +#site_nav_global_primary ul { + float: right; +} + +#site_nav_global_primary li { + margin-right: 0px; +} + +#site_nav_global_primary li:last-child { + margin-right: 16px; +} + +#site_nav_global_primary a { + color: #fff !important; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); + padding: 2px 12px 2px 12px; + height: 20px; + display: block; + float: left; +} + +#site_nav_global_primary a:hover { + color: #fff !important; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); + background: #4c619c; + text-decoration: none; +} + +#site_notice { + color: #000; + float: right; + width: 280px; + padding: 10px; + margin-left: 40px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +#site_notice a { + color: #3e3e8c; +} + +#anon_notice { + color: #000; + clear: both; + background: none; + padding: 0px; + margin-bottom: 10px; +} + +#anon_notice a { + color: #3e3e8c; +} + +.form_notice { + float: left; + margin-top: 0px; + width: 510px; + padding: 10px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + background: #cdd1dd; +} + +.form_notice fieldset { + width: 100%; +} + +.form_notice textarea { + width: 378px; + height: 54px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.form_notice label[for=notice_data-attach], +.form_notice #notice_data-attach { + top: 27px; + right: 86px; +} + +.form_notice #notice_data-geo_wrap label, +.form_notice #notice_data-geo_wrap input { + top: 52px; + right: 86px; +} + +.form_notice #notice_action-submit { + font-size: 0.9em; + top: 80px; + right: -2px; + height: 2.4em; + width: 106px; +} + +.form_notice .error, +.form_notice .success { + width: 341px; +} + +.form_notice .error { + margin-left: 0px; +} + +#core { + clear: both; + margin: 0px; + width: 930px; + margin-left: 0px; + margin-top: 8px; +} + +#content { + width: 530px; + margin-right: 0px; + padding-left: 30px; + padding-right: 30px; +} + +#site_nav_local_views { + display: block; + float: left; + width: 130px; + margin-top: 5px; +} + +#site_nav_local_views H3 { + border-bottom: 3px solid #A6ADBF; + color: #A6ADBF; + font-size: 1.1em; + letter-spacing: 2px; + margin-bottom: 10px; + text-transform: uppercase; +} + +#site_nav_local_views li { + display: block; + margin: 0px 0px 6px 0px; +} + +#site_nav_local_views li ul { + margin-bottom: 20px; +} + +#site_nav_local_views a { + padding: 2px 0px 2px 10px; + display: block; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +#site_nav_local_views a:hover { + background: #8e98b4 !important; + color: #fff !important; + text-decoration: none; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); +} + +#site_nav_local_views .current a { + text-decoration: none; + background: #8e98b4 !important; + color: #fff !important; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); +} + +#aside_primary { + background: none; + width: 210px; + padding-top: 0px; + margin-top: 5px; +} + +#aside_primary .section { + width: 100%; + margin-left: 0px; + margin-right: 0px; +} + +#aside_primary h2 { + border-bottom: 3px solid #A6ADBF; + color: #A6ADBF; + font-size: 1.1em; + letter-spacing: 2px; + margin-bottom: 10px; + text-transform: uppercase; + text-align: right; +} + +.section ul.entities { + width: 290px; +} + +.section .entities li { + margin-right: 17px; + margin-bottom: 10px; + width: 24px; +} + +#popular_notices .avatar { + position: relative; + top: 2px; + margin-bottom: 4px; +} + +#aside_primary td { + padding-right: 20px; + padding-bottom: 14px; +} + +#aside_primary td .nickname { + line-height: 1.6em; +} + +.section .avatar { + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); + -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); +} + +#content h1 { + border-bottom: 3px solid #A6ADBF; + color: #A6ADBF; + font-size: 1.4em; + letter-spacing: 4px; + text-transform: uppercase; +} + +#notices_primary { + margin-top: -5px; +} + +#content .notice { + padding-bottom: 14px; + border-bottom: 2px dotted #eee; +} + +.notice { + line-height: 1.35em; + margin-bottom: 10px; +} + +#content .notice .author .photo { + left: 0px; + top: 6px; +} + +#content .notice .entry-title { + min-height: 34px; +} + +#showstream .notice .entry-title { + min-height: 1px; +} + +#shownotice .notice .entry-title { + min-height:123px; +} + +.notice div.entry-content { + font-size: 0.9em; + line-height: 1.2em; + margin-top: 6px; + opacity: 0.6; +} + +.notice:hover div.entry-content { + opacity: 1; +} + +.user_in .notice div.entry-content { + max-width: 440px; +} + +div.entry-content a.response:before { + content: "("; +} + +div.entry-content a.response:after { + content: ")"; +} + +.notice-options { + margin-top: 4px; +} + +.pagination { + height: 1.2em; +} + +#jOverlayContent button { + top: 20px; + right: 36px; +} + +.entity_profile { + float: left; + width: 435px; + margin-top: 4px; +} + +td.entity_profile { /* cf directory table */ + width: auto; +} + +.entity_profile .entity_depiction { + margin-top: 4px; +} + +.entity_actions { + width: 140px; + margin-top: 8px; + margin-bottom: 10px; +} + +.entity_actions a, .entity_actions p, .entity_actions .entity_subscribe input, .entity_actions .entity_block input, .entity_actions .entity_moderation input, .entity_actions .entity_role input, .entity_actions .entity_nudge input, .entity_actions .entity_delete input { + text-shadow:0 1px 0 rgba(255,255,255,0.4); + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + background-color: #CDD1DD !important; +} + +.entity_moderation:hover ul, +.entity_role:hover ul { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} + +.entity_send-a-message .form_notice legend { + text-shadow:0 1px 0 rgba(255,255,255,0.4); +} + +.entity_send-a-message .form_notice { + border: 1px solid #7B4E82; +} + +.entity_send-a-message .form_notice #notice_action-submit { + color: #fff !important; + top: 46px; +} + +#aside_primary #entity_remote_subscribe a:hover { + background-color: #fff !important; +} + +#entity_remote_subscribe .dialogbox { + border: 1px solid #7B4E82; + border-radius: 8px; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; +} + +#entity_remote_subscribe input { + padding-left: 4px; +} + +#entity_remote_subscribe .submit_dialogbox { + margin-top: 10px; + float: right; +} + +#filter_tags_item .submit { + left: 6px; + top: -3px; +} + +.pagination { + height: 1.2em; + padding-bottom: 12px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +#footer { + color: #000; + margin-left: 0px; + margin-right: 0px; + -webkit-border-top-left-radius: 6px; + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topleft: 6px; + -moz-border-radius-topright: 6px; + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +#footer a { + color: #3e3e8c; +} + +#site_nav_global_secondary { + margin-bottom: 10px; +} + +.error, .success { + background-color: #F7E8E8; + padding: 4px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.success { + background-color: #f2f2f2; +} + +.form_notice input.submit, .form_settings input.submit, .form_settings input.cancel { + border-radius: 3px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5); + color:#fff; + font-weight: normal; + font-size: 1em; + height: 2.2em; + padding-left: 1em; + padding-right: 1em; + background: #7080aa; + background: -moz-linear-gradient(top, #7b8dbb , #7080aa); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7b8dbb), color-stop(100%,#7080aa)); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7b8dbb', endColorstr='#7080aa',GradientType=0 ); + border-width: 1px; +} + +.form_notice input.submit:hover, .form_settings input.submit:hover, .form_settings input.cancel:hover { + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.8); + background: #7b8dbb; + background: -moz-linear-gradient(top, #7080aa , #7b8dbb); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7080aa), color-stop(100%,#7b8dbb)); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7080aa', endColorstr='#7b8dbb',GradientType=0 ); +} + +.form_settings input#settings_design_reset, .form_settings input.cancel { + background: #e2e2e2; + color: #8e181b; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5); +} + +.form_settings input#settings_design_reset:hover, .form_settings input.cancel:hover { + background: #f2f2f2; + color: #8e181b; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5); +} + +.form_settings input.checkbox, .form_settings input.radio { + margin-left: 24%; + margin-top: 2px; + position: relative; + left: -14px; +} + +.form_settings label.checkbox, .form_settings label.radio { + width: auto; + max-width: 60%; + position: relative; + left: -30px; +} + +.form_settings li input.radio { + clear: left; +} + +.form_settings label.radio { + margin-left: 10px; + margin-right: 10px; + text-align: left; +} + +#form_login p.form_guide, #form_register #settings_rememberme p.form_guide, #form_openid_login #settings_rememberme p.form_guide, #settings_twitter_remove p.form_guide, #design_background-image_onoff p.form_guide { + margin-left: 26%; +} + +#form_search ul.form_data #q { + margin-left: 10px; +} + +.form_settings fieldset fieldset { + margin-bottom: 30px; + padding-top: 25px; +} + + +#content thead th { +text-align:left; +} +#content tbody th { +vertical-align:top; +text-align:left; +font-weight:normal; +padding-top:11px; +padding-right:18px; +} +#content tbody tr { + border-top: 1px dotted #bbb; +} +#content td { +padding:11px 18px 11px 0; +vertical-align:top; +} +#content td:last-child { +padding-right:0; +} + + +#realtime_actions { + position: relative !important; + float: right; + padding-top: 15px; + margin-bottom: -8px !important; +} + +.realtime-popup #content { + padding-left: 4px !important; + padding-right: 4px !important; + margin-right: 0px; +} + +.realtime-popup .form_notice textarea { + width: 325px !important; +} + +.realtime-popup .form_notice #notice_action-submit { + top: 59px !important; + right: 6px !important; +} + +.realtime-popup .form_notice label[for=notice_data-attach], .realtime-popup .form_notice #notice_data-attach { + right: 74px; + top: 3px !important; +} + +.realtime-popup .form_notice #notice_data-geo_wrap label, .realtime-popup .form_notice #notice_data-geo_wrap input { + right: 8px; + top: 3px !important; +} + + +/* Bookmark specific styles */ + +#content .bookmark .entry-title { + margin-left: 0px; +} + +.bookmark h3 { + margin: 0px 0px 8px 0px; + float: left; + line-height: 1.2em; + max-width: 92%; +} + +.bookmark-notice-count { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + padding: 1px 6px; + font-size: 1.2em; + line-height: 1.2em; + background: #fff; + border: 1px solid #7b8dbb; + color: #3e3e8c !important; + position: relative; + right: 4px; + margin-left: 10px; +} + +.bookmark-notice-count:hover { + text-decoration: none; + background: #f2f2f2; + border: 1px solid #7b8dbb; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5); +} + +.notice .bookmark-description { + clear: both; + margin-left: 0px; + margin-bottom: 0px; +} + +.notice .bookmark-author { + margin-left: 0px; + float: left; +} + +.bookmark-tags { + clear: both; + margin-bottom: 8px; + line-height: 1.6em; +} + +ul.bookmark-tags a { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + padding: 1px 6px; + background: #f2f2f2; + color: #3e3e8c !important; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.5); + font-size: 0.9em; +} + +ul.bookmark-tags a:hover { + background-color: #cdd1dd; + text-decoration: none; +} + +.bookmark-avatar { + float: none !important; + position: relative; + top: 2px; +} + +.bookmark div.entry-content { + font-size: 0.9em; + line-height: 1.2em; + margin-top: 6px; + opacity: 0.6; + margin-bottom: 0px; +} + +.bookmark:hover div.entry-content { + opacity: 1; +} + +.bookmark .notice-options { + margin-top: 16px; +} + +#bookmarkpopup { + min-width: 600px; + margin-top: 0px; + height: 100%; + border: 10px solid #364A84; + background: #364A84; +} + +#bookmarkpopup #wrap { + width: auto; + min-width: 560px; + padding: 40px 0px 25px 0px; + margin-right: 2px; + background: #fff url(../mobilelogo.png) no-repeat 6px 6px; +} + +#bookmarkpopup #header { + width: auto; + padding: 0px 10px; +} + +#bookmarkpopup .form_settings label { + margin-top: 2px; + text-align: right; + width: 24%; + font-size: 1.2em; +} + +#bookmarkpopup .form_settings .form_data input { + width: 60%; +} + +#bookmarkpopup .form_guide { + color: #777; +} + +#bookmarkpopup #submit { + float: right; + margin-right: 0px; +} + +#bookmarkpopup fieldset fieldset { + margin-bottom: 10px; +} + +/* Onboard specific styles */ + +.onboard-flash { + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + font-size: 1.1em; + box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5); + -webkit-box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5); +} + +.onboard-flash p { + margin-bottom: 10px; +} + +.onboard-flash .next:before { + content: '\00BB'; + padding-right: 6px; +} + +.onboard-breadcrumbs { + margin-bottom: 16px !important; +} + +.onboard-breadcrumbs li { + background: none !important; + border-top: none !important; + padding: 6px 12px 2px 0px !important; +} + +.onboard-breadcrumbs li:last-child { + padding-right: 0px !important; +} + +.onboard-breadcrumbs a { + text-decoration: none; +} + +.onboard-breadcrumbs a:hover { + color: #3e3e8c !important; +} + +/* Billing specific styles */ + +#content table.billing_info { + margin-top: 10px; + background:rgba(240, 240, 240, 0.4); +} + +#content table.billing_info th { + text-align: right; + width: 50%; +} + +.invalid { + border: solid 2px red !important; +} + +#payment_history table { + width: 100%; +} + +#billingadminpanel .form_settings input { + margin-right: 0px; +} + +}/*end of @media screen, projection, tv*/ diff --git a/theme/neo/css/ie.css b/theme/neo/css/ie.css new file mode 100644 index 0000000000..41f7dc9f88 --- /dev/null +++ b/theme/neo/css/ie.css @@ -0,0 +1,81 @@ +/* Temporary copy of base styles for overriding */ + +input.checkbox, +input.radio { +top:0; +} +.form_notice textarea { + width: 328px; +} +.form_notice .form_note + label { +position:absolute; +top:25px; +left:83%; +text-indent:-9999px; +height:16px; +width:16px; +display:block; + left: 390px; + top: 27px; +} +.form_notice #notice_action-submit { + width: 106px; + max-width: 106px; +} +.form_notice #notice_data-attach_selected, +.form_notice #notice_data-geo_selected { +width:78.75%; +} +.form_notice #notice_data-attach_selected button, +.form_notice #notice_data-geo_selected button { +padding:0 4px; +} +.notice-options input.submit { +font-size:0; +text-align:right; +text-indent:0; +} +.notice div.entry-content .timestamp a { +margin-right:4px; +} +.entity_profile { +width:64%; +} +.notice { +z-index:1; +} +.notice:hover { +z-index:9999; +} +.notice .thumbnail img { +z-index:9999; +} + +.form_settings fieldset fieldset legend { +line-height:auto; +} + +/* IE specific styles */ + +#site_nav_global_primary ul { + margin-right: 0px; +} + +.notice-options input.submit { + color:#FFFFFF; +} + +.form_notice #notice_data-attach { + filter: alpha(opacity=0); +} + +.form_notice .form_note + label { + background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -328px; +} + +.form_notice #notice_data-geo_wrap label { + background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -1780px; +} +.form_notice #notice_data-geo_wrap label.checked { + background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -1846px; +} diff --git a/theme/neo/css/mp-screen.css b/theme/neo/css/mp-screen.css new file mode 100644 index 0000000000..d3f95db9b6 --- /dev/null +++ b/theme/neo/css/mp-screen.css @@ -0,0 +1,204 @@ +/* mobile style */ + +body { + background-image: none; + min-width: 0; +} + +#wrap { + margin: 0; + padding: 0; + min-width:0; + max-width:100%; +} + +#header { + width: 96%; + padding: 0 2%; + padding-top: 20px; +} + +.user_in #header { + padding-top: 40px; +} + +address { +margin:1em 0 0 0; +float:left; +width:100%; +} + +address img + .fn { +display:block; +margin-top:1em; + margin-right: 10px; +clear: left; +float:left; +} + +#site_nav_global_primary { + margin:0; + width: 100%; + padding: 4px 0; + height: auto; + position:absolute; + top:0; + left:0; + font-size: 1em; + letter-spacing: 0em; + border-top: none; +} + +#site_nav_global_primary li { + margin-left:0; + margin-right:0px; + float:left; + font-size:0.9em; + padding: 2px 4px; + line-height: 1em; + height: auto; +} + +#site_nav_global_primary li a { + height: auto; +} + +.form_notice { + float: left; + margin-left: 0px; + width: 300px; + padding: 4px; +} + +#form_notice-direct.form_notice { + padding-top: 10px; +} + +.form_notice textarea { + width: 210px; + height: 50px; + padding: 4px; +} + +#notice_text-count { +position:absolute; +bottom:2px; + left: 175px; + font-size: 0.8em; +z-index:9; +} + +#form_notice-direct.form_notice #notice_text-count { + left: 0px; +} + +/*input type=file no good in +iPhone/iPod Touch, Android, Opera Mini Simulator +*/ +.form_notice #notice_text-count + label, +.form_notice label[for="notice_data-attach"] { +display:none; +} +.form_notice #notice_data-attach { +position:static; +clear:both; +width:65%; +height:auto; +display:block; +z-index:9; +padding:0; +margin:0; +background:none; +opacity:1; +} + +.form_notice #notice_action-submit { + text-align: center; + left: 230px; + top: 32px; + width: 70px; + font-size: 0.8em; +} + +#form_notice-direct.form_notice #notice_action-submit { + top: 62px; +} + +#site_nav_local_views { + height: auto; + font-size: 0.9em; + line-height: 2em; + margin-bottom: 0px; + padding-left: 4px; + background: none; +} + +#site_nav_local_views li { + margin-right: 6px; +} + +#site_nav_local_views a { + background-color: #7080aa; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + margin-right: 2px; + margin-bottom: 2px; +} + +#core { + width: 100%; + margin: 0; +} + +#content { + width: 96%; + padding: 10px 2%; + margin: 0; + min-height: auto; +} + +#footer { + margin: 0; + padding: 10px 4px 4px 4px; +} + + +.form_settings fieldset { +margin-bottom:7px; +} + +.form_settings label { +width:auto; +display:block; +float:none; + text-align: left; +} + +.form_settings .form_data li { +margin-bottom:7px; +} + +.form_settings .form_data textarea, +.form_settings .form_data select, +.form_settings .form_data input { +margin-left:0; +display:block; +} +.form_settings .form_data textarea { +width:96.41%; +} + +.form_settings .form_data label { +float:none; +} + +.form_settings .form_data p.form_guide { +width:auto; +margin-left:0; +} + +#settings_design_color .form_data { + width: auto; + margin-right: 0; +} diff --git a/theme/neo/default-avatar-mini.png b/theme/neo/default-avatar-mini.png new file mode 100644 index 0000000000000000000000000000000000000000..a3410e307ede7b70f4878fb83e7fd7c81353887e GIT binary patch literal 857 zcmV-f1E&0mP)Px&6G=otR7l5_mDz3^M-W9%_3Rw3q8!CbY~=rcB|v}xesCffGGZyT7A`~1a5zhs zA1IDA;)1B38eP?Ot8U-wlD|G*skIhs!59z`j4{NWfb+8s$JWl84vopB7y4&upVjP3#I@EPdRa-;^ zwTc^e0vy-D$Tpjzs2cR$5)tM}MjS_ULi2bAq3^QJOT-AO%BCo{bUo%e9CQ$Ct%^Kl zze;l!Ny`00(qyu$BJe#veHgXC|NeU0@&V|CK7&C_FZOVs2M6fJA>BA6@I7uOQ>yLD zBO>H^L9#69_nscza~*a<@mz=TS+6CEqmO((?sM_Wi29kz#0blD-SX@AI;d5;ameo< z$9sx9siN^&k8T_`rHcq@w%PNGqJVc7{nyLXF~VrnL+z8$)hf@5qN*()-wzMoU*|RM zDF6|{bDe{--AU!*JZ{-0w=0&bM;e9G005374Mop^53Q?zrxaz?vY!M{RkC$)G~i3Q z?!b4AXXJkXOlPaTE`Q0|_nUdEvbYn_?{^3T|1`jCk&@>H#xYOL7I-b6Ra%i|8;oO6 zRnCT8-oG8=`|fEK&E_fJukV}SyI->#hcEn=%~uge0dFrxO>h8LRa+eAdBOcOVKz@& zU&XG1xD&LcxGA^1tJ3R5gkihU+%K2c1ise{ilV3}iV9WT<6c#XLT7pD6UFT4ei ztqZbs@uC5aOK~^(4hf>R`npa&)OhK-JghjYY&PXy&%6%62-DfBbru9(6Lh{ zt+mv(fysVSpq_qOYOJDolPPL{Y$K j5VS#(tWln-qE`6{uAq@WFI4De00000NkvXXu0mjf*0Gv= literal 0 HcmV?d00001 diff --git a/theme/neo/default-avatar-profile.png b/theme/neo/default-avatar-profile.png new file mode 100644 index 0000000000000000000000000000000000000000..8f635d1aa657ecbab286f32ca274ba13f1f6c47c GIT binary patch literal 3737 zcmV;K4rcL*P)Px@Q%OWYRCwC$U1xI~xeWLzO@H|Njcx<+EMoa7iadar4gZWB~p! zi{UOMiaVG<^6t8d#kvy*Gw9ddKnFC)U%&l9qC}EXLJEmy!^UvXM!m*LdCz#d!D8h? zN(n;9C({+)f4Bvu6ofwh9TX)KAq0dHY`g%MH*<`qn^N9m z7zS{tC`mvHi6DpyVZM~fi(@XZ-uUU9zxa$uo+%vw1p=iMLI}*48(ds3AVjh6=(cUp z17|~M!l3JqbBOJSC?@8iFpRNWZ60NQ@)4*GfL+N00M`rg^TiZvH!f^wN&&`LCZSkw zd`zaRTw0)>jbe_=>nUO`4%S3MNVNbEO45l&F~{}I9J7UA*!Znx?O;YKGjVw{M-*{w z4IqR-N{Pi{jn&FM$owc`v|<2uKRQteiScBK$;>Te+|i(sFht0MHBw56?|!_#`=$&) zsK1ROjt`fUgz@t5=S+h=4FIVGZlz^9a|&CWErX`^^-zuUgAm{T>!)-9eQ4M8IhssY z_~*ZW-qWf>=ilu%pALXMJIH8ZAPk4y%#ut9LCgjI``snZFUF8kLI{zLp@c<^D}+E4 zas20h7kK~Sc2BDhB}NH4Eei&o2{D6VI&(k>!D!IX9;aDnFb#$%=GkpIBtA}-m@U@m zv>WKO8)!CdP?E?g=N!)3!(!>e*?5pbf-CC}ox=MCfi~o#z5)Ycy3{rL<*7=cpy zWXzXR;;YxA&juoiOla?qg#_X#Mi|8i!x)|yVB;n~_dVJwCh+Q{ue~S>0sQZW8&F0o z6`thXNm%0b*$}P9=l45A9$;gln1jb08#lmo=3wQxl>s58gk>6d_jaH?#$@JVI&-wP zjJn?}xInFD;mz3q#uq|VUj*QOkV;C4DB=jh2;=R384{&VOnpPY+sx%3eE)s|Aw(qt zBZWl2*TnIt_4s-x4_sw;!H`md3klB)@czRsf*>jl1oe4&wZPd#xV)Mklqku=c*YoB zo%YeJ9~PNC7=VX>2*Vhc*Hg^q>(We;dS|y?KS-(`qVIkh7nc3HFCbD#wA*!@opiGK zEIM06H3>opY}>@Uua41Z)Npk(D|~{x6Lq~X*BJe7GYNMvQW)bYrD!&6ygJs~sb$uH zFKNVd=HTLLk|ZTG0#rrX*3VH83cNobXWmXrA@?Gzgb+{yblMFZ4V$^LTU>A8+TygFp$wD2B6+&~EAZ1vNVX;Na>BA;AoWx@}@KY{RyS-E0&V4c!Id)kz;h z2#hC7a8X<+gAfA21zgY92cTvhEct{G)axdO!!8=Na&~!zhNE{uI6ED{^8&2ae&Gvq z9y4Sx3TCjh8sbZf>!8=dpjRu^ZzvqrT@X%B1~9h%K~X_HLJ5K(g0s;B!894z1Af3R z^UqFtr8B=20CquWHES3S+J#EL8q0NkO$|u2;Gx7l0m0XAhG^8Q$yJpe963Gip>CUn z`v!S@0?Iy3+)F7zDaG&K9ljSX;-Rm|gwfU6;pvW=}^tz41%LWetAk+hZZ(}>mV7bzr zFA4wv=yhAgY1Y;s$Vv)-DWA^nm*xo{8U~O;=1z(bLLj6-5QK+h~p%$9z`567hsgYvJ9A}3B#aI006jvMZIPF5`wsZo_7aRC~ z_^HoB0LVmZrI6ToL0Uy!830mBFiK!sruO3bS(73JfWr@F#IeBfs8hgvfcetL%5nFY z{#eTMei*zm0F-0as9Olas1VOsMMtv`V@XwV9@BF3ae<8+9L)4*vjzZwX_|*0raMFu zGY+Q9{Fnpd>0L=qQFTVosybS0OUcVEos<%o%r;m$9(c?PFFdFmfTF_@LX=ng>1-lQ zrYnSD3_?jMr8kuWP$t8Qq}js9Y_SICywt+8r_q1{x1nVe-Clomuy*}4O8Sd&#LCbB zR&bTu`Q;qm*2Au%n72|t07w!kMNLe~q++2cdVfAkeUz#ysVj>G5ke4zk#+#>K?y3z zK3`lfDrbJ>CTP9(3!7ki*xAgl0h5_qsAfJp08~=OS$l;pz{w( zpu!LjokZ7`9@9YHHMq!v;`>ZjHKb~6#Rv7b5~O?p)Z|<*Ec6_KloB;7-{*h0m=#jF zx660}0@GwL7)8BqqfxhDmBg!@zC>?tO3^_=Lr~;6bh`ZX@XYk5dJp4lh^Ew1|1xYx@b1+PniCg z1`tx>8jwnV5Mt%Hg>UgplWCWVFP9q#A+*B`f(tN%;q zjP=GZh532*|7ov_jNhd40;6FEmT71&xTOJ*N`4sQ!}%@dt8%*I0?Pd8*?-Rqw9Jnb z5~D#2^}1b{>B+qd+LZw1Y<;+#V6}3~Yg-^BEZfxTKkfM(VHju5AE-u4yad9<)<9Oxvj39ue>3r?h@nofTtDZ`K(f*8~EA>E9oxE7Cad|V(?baVc zj4|!)XAnkupaZDaZJ0(mUEhr?jNffL>~4JAj2EfNsiGH;!KilQrYO?e{n)mNM%^lO z;e8Z<`!7-sM-W5^!U)Ud29xK zjgR#vDMnS5zEyRgDq`osInTZWl1YE(EM3_%1K_N^y@_$o5k(wf6eErWq9{s}DZpLt z{VFMqFzR}+GAV~Kn4tx_QD$M*`Neoox^^=*dmlo{lO(P8oEFXKWe{-fZ#Rr`oBbK- zfoF23c1p^hn&A&=LiQMtcy@D10jS!J>)L+RP_}9+yOj0$bAQJK=Gi^zY7gfeob%rR z$YX+74lU(52~941 zTkTYK7pVm=3IHJKkg{}qEdW#*VOG!~f%)7iMGIb>21p^{y4e}gtTPymumlPi;=Pa)lRMInU_opZjTrY&{3oSF0_ubCg z!;e4Rq>27K^D4YDPKYFG$zzT^EWCrgmgi znVpRn;K%njSS;3BH?gK(dM<`#CWN5XsBKS(d^vf(T8CI~d~DnxWk!}9gxZ;S zek)U*5T(glkmovcCG}wx$g8h9Z6Te8Dr?S>lpT%xlSxz z-#Ty{FFnX{$OP2YfI4@}s6*MgjwfvekPre!lh*wwN8P;~@Mx7TNEcTN1Ywls1MV|RaDn5a zo>n8iGW$d9f}tAs?KbdxF@C_CvmTB|Jy@oZhKTph=2C*&$wF)FqfxiCmNcKc8dv>J z|LvtXVC`12*baIvSeCKZ23ZBne!j?l`)ae!_Re}$O)t(99`@__=Bpw4y=LNDY_Hv= zjKcRr%of=_PsZju3*2tC=>a{a&;1F7Lls02IACZsY89kcKG2D8|irtqsEQQLi!( zeh~lwNu=|S-y9{GFCpQqJ?)#8`du4muLkKBw@ms!_PR=bCbCvD00000NkvXXu0mjf D=79U5 literal 0 HcmV?d00001 diff --git a/theme/neo/default-avatar-stream.png b/theme/neo/default-avatar-stream.png new file mode 100644 index 0000000000000000000000000000000000000000..a3024639f481200223f0640450f65d4d3ffae513 GIT binary patch literal 1791 zcmVPx*xk*GpRA}C{T3K`3I1>H<9-=Pluxux>9VgkTo&WzkrejD?h}|?cyN)^K-j&k0?rTdpE^&<|2;MEy1HG!Ts35-#3%|cfM@_)6}8k z2Uej)KZx=5&cVgAo`e=?HVgz&vZYDJ8T=r|&9@0UZ41q21G>hMq#436#=`LdhJEc5 zFdTHie*4!u+SKT#2I?Gc0O;E-oQ*nC+P8n*uU)V#K25{U+N_#TwmhM{w2*z_oGXDL0iSVtai5K5pk_ACT zU;qfn1R={Z_(6?rGqVC3KDB)zt`Ga=QNdG=UJJmZdj^zq%Ma0;dvn2qBOp z89YD2-Te%H5Gw-_nZTgmmby|9X88PNycN?AxhDV&`yGsit!>L~0@zI^M1&;C@bz|z zx#LNb&F%x=T%So3-G|Q;q*=8UND#pC&rZj}^Rr&5RZA_f8;1el%hxf+Q&$Ou$OPZ99`HwS<1}){o&Fdtr z!V(}TSz)nQNoh>uF^@J(1Fx=zwUeoGDN%svv@Hz!Z6zK*h~*a0c^(=q6W5o6qpE@0 z)hGa*j(U3`t_rZsP-!Y)7#c2L^p7rQY8P{b6&j|Y1bF2q(!E9}_K%cf#}{*Uw}tW4 zIY<{p3A*iau$E=Q?wD##kpQANLz)SsNeV%^3)TiuxKY!}>n5f#DQ%WzQYA>i#{w%a zg71g$gSa#Y9c=;ARA6O!eO2A$lzVWJ5~gzxOV`hp#PjNvGyd~jNOg%!)S{ovd@PoJ z&c{%isecN9x}~r!#kNG*TJooAN9>TdYc3)xvFt{SIDVpOdAcZDV*L{S1ih~X?f%pDIR6SW6iG7HGEc+)c0t)|KZ zL@(y=8-G7txAAr&o@(J?Lua589@ z?p=V7;sozM+#)G4W5Gj2c_|_7z6j7X21D1-?KELo26UYx4D+Ptc>$6%LngLCFvcK+ zz;qtqWY8>$_rRdve!PX;$qS4zctM2!{_h4aFGuKhntRcbF$VU>zdulw3z&uu+is!L zI@~raoDhzigV{WQBnZF$a$d>z?&J92YX-$-$FSc)yVclAcI;t1Cjbz{VCoE<%e$z< z(~1n!`3k-tgFx#ET-9a8auwt5LEho5UFQ3c%QW=$)Q>HfOL~ffyj;bYFFZtX0uqEb zug+lTOw^f5JQ;vuji(+KOCK6%cym4a>2o2DCtjx~Z9F^egE1z3G34TT h51qDEYw8C8{|Awj`>|Veoaq1n002ovPDHLkV1i2$S&jez literal 0 HcmV?d00001 diff --git a/theme/neo/images/bg.png b/theme/neo/images/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..df665bd7274c7cc30c20d33c5cba5dcf4366c258 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^AT~b-6Oas=domJ8NtU=qlmzFem6RtIr7}3C*bcsI2U%KL?9?)iYvMD;Al%g2t-(J+t1-@V}Qn8xhDY6kkJh9`9wg5rd!2#z-z)L zOq~Cik0Wl9oB%vSfIQ-QZ{RtPY@|59YP|D7ZHg4Hy#sCxWRY4%NA%H&Y&b0Sfy4ZzVS@B<$! zISJLopeh;H#P^{n*BFr6;YW`Zm6z0;uzY9 z_pGD}kctn|TN&`-npKIxz2hPh5<8u|=7!)8> z^McM`?wSa*Aqh?aZ-j0sjD1txKhp@@P^BoCC~!z)6SK!>sv!A}ft71ctasZ3_z+a9 z-idne}mk*sy9TuyuVag5aYwtQFZOjh&FIJFp;KoS2(`+ z+ILJ}6HMlqNObprvc94fC;~6~y(Z6)dCkDG*c_5vm_7*01#%s6y<3#E!8I=?B%coS zsbdX3_6_>dz^bNV{LdK&1-t}wyVPm$iijyQjcXhmfx&n(Q1U`BKHzn?xaLy;KLyf- zL2<%n6FG-BTaC-r3AG7PM@1K}3abi?``RgoI4FZl@_ag&@_ZsY^*qQ8^k_Mj4!~zD zKpj<+^_QBsa51sAggfR|7EKMj#Q$Uv-khut2hAK8G`F1R!O?QrWc{s>N0bDQnMq|~ zB-S1b%pBv}duDe;4;FttQOq@rs8XFB^r(miW9AiFZx~x0QcQ9O|ngGWh%27JFzBFTzrD6&^H4D=3GO#B_OlZ#m`k1h`)TaIFun`(O z{eJ2LJ+>EIO#t*zUQYUc7ZB2uiLJ$;MCgrv?1{HSHhB3sn8^e1MV(1(#N-**E;j`M z9{%lnsxdd3*m&$Y3$<>?o>pY22)>1CEsg{*zagOE@ZbR%{w64E!RWG}F9rB0JD%DS zJRhEwj6O{I)b#a;@olA0Y%W+oxc(vBm$H9^KfEQioqX$c96WUO12dzfIl;^qi!INOMpc(3EKpedj50oUpcXDJnOv;hXnerAN z>-IqCC`OF+;mkYmBL(1HvhEY#Zb$>kk$`=L!GRx9vVW4&SzdVD_Hj~*vH`(>n`(P&1xJWY5(~RYT;4G=*v(@7T@^aC1`2)+m>;MV_$PWcof0Zso0Y6A?3Z6M`@_6b z-;wY5_Kd)vTgu$^cFleF8b!zy0ILxGJwr->utCO43u|*Agsr7{mxSOZ^Vg=E)bSm1 zRRY45XJNA@0@$0ra$INq@cAxTO*I>+WS0MG!_s)!7AIN*ovOU@QYcH`u>UsI4e2VS fFs78@rvL*0?F*Xy43a9iMr->$96UX)cn~alCfiB*y1DNoi4(5LApr300vLA4V#jMIZc6R7<#rU@v z|0-HnVXs#9EjOSw)&s2abpSj7ur^=(U@>K4D$-aR>G#hsH#U}AxLNZ67lZ62!DF5V z1zhZPS3_U`syrXQqfo3}QzQ&S3I@alO_qT<`gt&0=G7X@WT>1(&^b3BP%yG*6%oX?jT&(A5 zOUOqTq*+DBNeRJpAbKf{=742C)fS7-V(PT8!|Yh4cyQc>>JO4=IptCaI0L3nJ&lJa{HxCXVO&E1T~@kDtO@hl>of~S z3=EEl5qObwJ~p*Yz_~pr13v`y*EA34z6iR%;a!1sG&xm=da-^DT?F8#HBYYI1KQfr z(UnKV`TGqX3QvOYAoP+WV@o>?swQJBP7RVBz#hM=3r z+!yft4&Y5qyHc-O#~2(=4%& zNq+DYT3nRnNx!Zo$25X`up_O}1vq2*jjmf5-v5_=IolaO3=jSSKCG~9V4*j;h#P81 zn7Bjrylz|KiD-RAo959y_>2JWHJOdq+jrHLVS@_qEbxQJ9qCno_y^(=A*%{Fz3F*W z3A{%dvbD9n=cP+=A5pX=}}t`xmG zA8cue&*89rH8qbQHP%*6P$4&=zl~pCHtqamS>uVxSwub^3yK7SJU{0rMq0drD~H;| zFhVg918=D%Ym3!KP9BN^iwPTPP$?nFz7Iw`t7W-&A^T^K#0Ufz^c>O#8(Mxw>m+cRP+7iJ?5(;>l<(LqB4t}d_3lzpUbacC zDH_I>sU^iT7vF4CRZSUy3h|wE|8xIHac#sgAhX13AiAe;w(j1mVsSAmQ?MuHa6?Un zmy^KyOK^DSf(8ESyGwCRDNM@*%3WU)R)+BUoocq2UM%@F-<@+H6zGO+BY01fJPzFS+%XttS2l_Pa6hM!5Ug#IoGjr-AL}_vVaGjg>t?nyg zaCj_Dxu&B%rYT?1@1|VbsZz&97XSoaRcJ`A7WQ2tArd0&ur%y|cN=Y}t9Txp<1zR& z3fZ0^98&n(@vBOHQDMH?XbkD()SO!5dgjLUz`))68Y11^yAbPH<&_bbqyg0CQ|Tj3 z4f7Ep+NhC1LILsu7Z`sFCY#k3NzWutI0eki&Z{q{>-Y%Kd6`o=YR79one{s);TO;E ziq*6v_kbq_9Q*+co=YnD>Y>m6e94-OsB^OkM#zOP@^ zcQ75J-0RJz4;W#la*9huVj5?ynPvdl8fzk*W-z%K6?cY=up`@&bon{ooMf?&Ya%Ns z2OWuySXQ9keq51Yl+vdO-JWwa_{!j@FB8Zs$3@V{Hh_Hl7zrUag71WrtV)@q(G~3P zpacJ0OPv?J%nKrBMAO+=w{q70>WZY4xV~d=un`;&zjsD(o+{#$8V!B`;3rW;bORZU zeX?P1xhqAlEYY8d{bwz{f*(gIJOp)35FZ9V4iSYJQvw$(*@C3{x3tVIGhmDumc1Ku z2eI~LP$8PQ%t_-LO||7eqKdBgJ92J%0vki-<5gM0pHz4PZ@hDjC@ggDef;nr#$n0| z$nOoODYN>bwUG$l6|=i?Q##ytj^WC10*b;2#TI8-UR{uH*vhZ<`up3uthfzMy8UjSGy5_-++9mj*h zezdW!LR}&B+ATGJO3%jP_u_7SrKx`BB@F^bJc98_JXuE2^9+n_$nG3a;&kwvVB=Xcj2~+MzpRHTR^nn zUiR0Oz;pdQj>c+Ku1te{@FMEJSFLh!+?ECeE%SWR2(Iea>f6$Q`Nb{q#hHOzj{pBz Z`|)dg_CLLlRA)x>#~(Oy>hNRV{V%a^K%f8s literal 0 HcmV?d00001 diff --git a/theme/neo/theme.ini b/theme/neo/theme.ini new file mode 100644 index 0000000000..0209008d40 --- /dev/null +++ b/theme/neo/theme.ini @@ -0,0 +1 @@ +include=rebase From 4c0a746831c4c96d4d7ae827d491d5a00993a4bb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 15:00:43 -0500 Subject: [PATCH 65/68] neo is the default --- lib/default.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/default.php b/lib/default.php index 38903730f5..e6caf0301a 100644 --- a/lib/default.php +++ b/lib/default.php @@ -33,7 +33,7 @@ $default = 'nickname' => 'statusnet', 'wildcard' => null, 'server' => $_server, - 'theme' => 'cleaner', + 'theme' => 'neo', 'path' => $_path, 'logfile' => null, 'logo' => null, From b7a8863b27235374fcc1f576eb49a418709c8262 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Mar 2011 15:06:21 -0500 Subject: [PATCH 66/68] lost a in input_forms --- lib/action.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/action.php b/lib/action.php index e7c55ef10c..28b0fdbacf 100644 --- a/lib/action.php +++ b/lib/action.php @@ -635,6 +635,8 @@ class Action extends HTMLOutputter // lawsuit $this->elementEnd('div'); } } + + $this->elementEnd('div'); } /** From 985ff9243159a8cf69c4440216c3ae6d2d0992e5 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 7 Mar 2011 12:10:34 -0800 Subject: [PATCH 67/68] Fix bad reference --- lib/personalgroupnav.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/personalgroupnav.php b/lib/personalgroupnav.php index 9d78857c6d..3d6bb98fc0 100644 --- a/lib/personalgroupnav.php +++ b/lib/personalgroupnav.php @@ -70,23 +70,23 @@ class PersonalGroupNav extends Menu $nickname)), _('Home'), sprintf(_('%s and friends'), $name), - $action == 'all', 'nav_timeline_personal'); + $this->action == 'all', 'nav_timeline_personal'); $this->out->menuItem(common_local_url('showstream', array('nickname' => $nickname)), _('Profile'), _('Your profile'), - $action == 'showstream', + $this->action == 'showstream', 'nav_profile'); $this->out->menuItem(common_local_url('replies', array('nickname' => $nickname)), _('Replies'), sprintf(_('Replies to %s'), $name), - $action == 'replies', 'nav_timeline_replies'); + $this->action == 'replies', 'nav_timeline_replies'); $this->out->menuItem(common_local_url('showfavorites', array('nickname' => $nickname)), _('Favorites'), sprintf(_('%s\'s favorite notices'), ($user_profile) ? $name : _('User')), - $action == 'showfavorites', 'nav_timeline_favorites'); + $this->action == 'showfavorites', 'nav_timeline_favorites'); $cur = common_current_user(); @@ -97,7 +97,7 @@ class PersonalGroupNav extends Menu $nickname)), _('Messages'), _('Your incoming messages'), - $action == 'inbox'); + $this->action == 'inbox'); } Event::handle('EndPersonalGroupNav', array($this)); From 0c2289fb2fb6c1b1639dba8cc76cd06b882cc2f9 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 7 Mar 2011 12:18:46 -0800 Subject: [PATCH 68/68] Avoid AJAX fetch delay for inline replies when possible; we clone a copy of the notice form skeleton at initialization, then insert it in place instead of fetching a new one. --- js/util.js | 28 +++++++++++++++++++++++----- js/util.min.js | 2 +- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/js/util.js b/js/util.js index 2100521869..fc03bc75fe 100644 --- a/js/util.js +++ b/js/util.js @@ -31,7 +31,8 @@ var SN = { // StatusNet CounterBlackout: false, MaxLength: 140, PatternUsername: /^[0-9a-zA-Z\-_.]*$/, - HTTP20x30x: [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307] + HTTP20x30x: [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307], + NoticeFormMaster: null // to be cloned from the one at top }, /** @@ -600,10 +601,10 @@ var SN = { // StatusNet // Create the reply form entry at the end var replyItem = $('li.notice-reply', list); if (replyItem.length == 0) { - var url = $('#form_notice').attr('action'); replyItem = $('
        • '); - $.get(url, {ajax: 1}, function(data, textStatus, xhr) { - var formEl = document._importNode($('form', data)[0], true); + + var intermediateStep = function(formMaster) { + var formEl = document._importNode(formMaster, true); replyItem.append(formEl); list.append(replyItem); @@ -614,7 +615,20 @@ var SN = { // StatusNet SN.U.NoticeDataAttach(form); nextStep(); - }); + }; + if (SN.C.I.NoticeFormMaster) { + // We've already saved a master copy of the form. + // Clone it in! + intermediateStep(SN.C.I.NoticeFormMaster); + } else { + // Fetch a fresh copy of the notice form over AJAX. + // Warning: this can have a delay, which looks bad. + // @fixme this fallback may or may not work + var url = $('#form_notice').attr('action'); + $.get(url, {ajax: 1}, function(data, textStatus, xhr) { + intermediateStep($('form', data)[0]); + }); + } } } }, @@ -1313,6 +1327,10 @@ var SN = { // StatusNet */ Notices: function() { if ($('body.user_in').length > 0) { + var masterForm = $('.form_notice:first'); + if (masterForm.length > 0) { + SN.C.I.NoticeFormMaster = document._importNode(masterForm[0], true); + } SN.U.NoticeFavor(); SN.U.NoticeRepeat(); SN.U.NoticeReply(); diff --git a/js/util.min.js b/js/util.min.js index cfbd66d662..af8b2200e9 100644 --- a/js/util.min.js +++ b/js/util.min.js @@ -1 +1 @@ -var SN={C:{I:{CounterBlackout:false,MaxLength:140,PatternUsername:/^[0-9a-zA-Z\-_.]*$/,HTTP20x30x:[200,201,202,203,204,205,206,300,301,302,303,304,305,306,307]},S:{Disabled:"disabled",Warning:"warning",Error:"error",Success:"success",Processing:"processing",CommandResult:"command_result",FormNotice:"form_notice",NoticeDataGeo:"notice_data-geo",NoticeDataGeoCookie:"NoticeDataGeo",NoticeDataGeoSelected:"notice_data-geo_selected",StatusNetInstance:"StatusNetInstance"}},messages:{},msg:function(a){if(typeof SN.messages[a]=="undefined"){return"["+a+"]"}else{return SN.messages[a]}},U:{FormNoticeEnhancements:function(b){if(jQuery.data(b[0],"ElementData")===undefined){MaxLength=b.find(".count").text();if(typeof(MaxLength)=="undefined"){MaxLength=SN.C.I.MaxLength}jQuery.data(b[0],"ElementData",{MaxLength:MaxLength});SN.U.Counter(b);NDT=b.find("[name=status_textarea]");NDT.bind("keyup",function(c){SN.U.Counter(b)});var a=function(c){window.setTimeout(function(){SN.U.Counter(b)},50)};NDT.bind("cut",a).bind("paste",a)}else{b.find(".count").text(jQuery.data(b[0],"ElementData").MaxLength)}},Counter:function(d){SN.C.I.FormNoticeCurrent=d;var b=jQuery.data(d[0],"ElementData").MaxLength;if(b<=0){return}var c=b-SN.U.CharacterCount(d);var a=d.find(".count");if(c.toString()!=a.text()){if(!SN.C.I.CounterBlackout||c===0){if(a.text()!=String(c)){a.text(c)}if(c<0){d.addClass(SN.C.S.Warning)}else{d.removeClass(SN.C.S.Warning)}if(!SN.C.I.CounterBlackout){SN.C.I.CounterBlackout=true;SN.C.I.FormNoticeCurrent=d;window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);",500)}}}},CharacterCount:function(a){return a.find("[name=status_textarea]").val().length},ClearCounterBlackout:function(a){SN.C.I.CounterBlackout=false;SN.U.Counter(a)},RewriteAjaxAction:function(a){if(document.location.protocol=="https:"&&a.substr(0,5)=="http:"){return a.replace(/^http:\/\/[^:\/]+/,"https://"+document.location.host)}else{return a}},FormXHR:function(a){$.ajax({type:"POST",dataType:"xml",url:SN.U.RewriteAjaxAction(a.attr("action")),data:a.serialize()+"&ajax=1",beforeSend:function(b){a.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled)},error:function(c,d,b){alert(b||d)},success:function(b,c){if(typeof($("form",b)[0])!="undefined"){form_new=document._importNode($("form",b)[0],true);a.replaceWith(form_new)}else{a.replaceWith(document._importNode($("p",b)[0],true))}}})},FormNoticeXHR:function(b){SN.C.I.NoticeDataGeo={};b.append('');b.attr("action",SN.U.RewriteAjaxAction(b.attr("action")));var c=function(d,e){b.append($('

          ').addClass(d).text(e))};var a=function(){b.find(".form_response").remove()};b.ajaxForm({dataType:"xml",timeout:"60000",beforeSend:function(d){if(b.find("[name=status_textarea]").val()==""){b.addClass(SN.C.S.Warning);return false}b.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled);SN.U.normalizeGeoData(b);return true},error:function(f,g,e){b.removeClass(SN.C.S.Processing).find(".submit").removeClass(SN.C.S.Disabled).removeAttr(SN.C.S.Disabled,SN.C.S.Disabled);a();if(g=="timeout"){c("error","Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.")}else{var d=SN.U.GetResponseXML(f);if($("."+SN.C.S.Error,d).length>0){b.append(document._importNode($("."+SN.C.S.Error,d)[0],true))}else{if(parseInt(f.status)===0||jQuery.inArray(parseInt(f.status),SN.C.I.HTTP20x30x)>=0){b.resetForm().find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}else{c("error","(Sorry! We had trouble sending your notice ("+f.status+" "+f.statusText+"). Please report the problem to the site administrator if this happens again.")}}}},success:function(i,f){a();var n=$("#"+SN.C.S.Error,i);if(n.length>0){c("error",n.text())}else{if($("body")[0].id=="bookmarklet"){self.close()}var d=$("#"+SN.C.S.CommandResult,i);if(d.length>0){c("success",d.text())}else{var m=document._importNode($("li",i)[0],true);var k=$("#notices_primary .notices:first");var l=b.closest("li.notice-reply");if(l.length>0){var e=$(m).attr("id");if($("#"+e).length==0){var j=l.closest("li.notice");l.replaceWith(m);SN.U.NoticeInlineReplyPlaceholder(j)}else{l.remove()}}else{if(k.length>0&&SN.U.belongsOnTimeline(m)){if($("#"+m.id).length===0){var h=b.find("[name=inreplyto]").val();var g="#notices_primary #notice-"+h;if($("body")[0].id=="conversation"){if(h.length>0&&$(g+" .notices").length<1){$(g).append('
            ')}$($(g+" .notices")[0]).append(m)}else{k.prepend(m)}$("#"+m.id).css({display:"none"}).fadeIn(2500);SN.U.NoticeWithAttachment($("#"+m.id));SN.U.NoticeReplyTo($("#"+m.id))}}else{c("success",$("title",i).text())}}}b.resetForm();b.find("[name=inreplyto]").val("");b.find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}},complete:function(d,e){b.removeClass(SN.C.S.Processing).find(".submit").removeAttr(SN.C.S.Disabled).removeClass(SN.C.S.Disabled);b.find("[name=lat]").val(SN.C.I.NoticeDataGeo.NLat);b.find("[name=lon]").val(SN.C.I.NoticeDataGeo.NLon);b.find("[name=location_ns]").val(SN.C.I.NoticeDataGeo.NLNS);b.find("[name=location_id]").val(SN.C.I.NoticeDataGeo.NLID);b.find("[name=notice_data-geo]").attr("checked",SN.C.I.NoticeDataGeo.NDG)}})},normalizeGeoData:function(a){SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val();SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val();SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked");var b=$.cookie(SN.C.S.NoticeDataGeoCookie);if(b!==null&&b!="disabled"){b=JSON.parse(b);SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val(b.NLat).val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val(b.NLon).val();if(b.NLNS){SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val(b.NLNS).val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val(b.NLID).val()}else{a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("")}}if(b=="disabled"){SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",false).attr("checked")}else{SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",true).attr("checked")}},GetResponseXML:function(b){try{return b.responseXML}catch(a){return(new DOMParser()).parseFromString(b.responseText,"text/xml")}},NoticeReply:function(){if($("#content .notice_reply").length>0){$("#content .notice").each(function(){SN.U.NoticeReplyTo($(this))})}},NoticeReplyTo:function(a){a.find(".notice_reply").live("click",function(c){c.preventDefault();var b=($(".author .nickname",a).length>0)?$($(".author .nickname",a)[0]):$(".author .nickname.uid");SN.U.NoticeInlineReplyTrigger(a,"@"+b.text());return false})},NoticeInlineReplyTrigger:function(g,h){var b=$($(".notice_id",g)[0]).text();var d=g;var e=g.closest(".notices");if(e.hasClass("threaded-replies")){d=e.closest(".notice")}else{e=$("ul.threaded-replies",g);if(e.length==0){e=$('
              ');g.append(e)}}var i=$(".notice-reply-form",e);var c=function(){i.find("input[name=inreplyto]").val(b);var l=i.find("textarea");if(l.length==0){throw"No textarea"}var k="";if(h){k=h+" "}l.val(k+l.val().replace(RegExp(k,"i"),""));l.data("initialText",$.trim(h+""));l.focus();if(l[0].setSelectionRange){var j=l.val().length;l[0].setSelectionRange(j,j)}};if(i.length>0){c()}else{$("li.notice-reply-placeholder").remove();var f=$("li.notice-reply",e);if(f.length==0){var a=$("#form_notice").attr("action");f=$('
            • ');$.get(a,{ajax:1},function(l,n,m){var j=document._importNode($("form",l)[0],true);f.append(j);e.append(f);var k=i=$(j);SN.U.NoticeLocationAttach(k);SN.U.FormNoticeXHR(k);SN.U.FormNoticeEnhancements(k);SN.U.NoticeDataAttach(k);c()})}}},NoticeFavor:function(){$(".form_favor").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_disfavor").live("click",function(){SN.U.FormXHR($(this));return false})},NoticeInlineReplyPlaceholder:function(b){var a=b.find("ul.threaded-replies");var c=$('
            • ');c.click(function(){SN.U.NoticeInlineReplyTrigger(b)});c.find("input").val(SN.msg("reply_placeholder"));a.append(c)},NoticeInlineReplySetup:function(){$(".threaded-replies").each(function(){var b=$(this);var a=b.closest(".notice");SN.U.NoticeInlineReplyPlaceholder(a)})},NoticeRepeat:function(){$(".form_repeat").live("click",function(a){a.preventDefault();SN.U.NoticeRepeatConfirmation($(this));return false})},NoticeRepeatConfirmation:function(a){var c=a.find(".submit");var b=c.clone();b.addClass("submit_dialogbox").removeClass("submit");a.append(b);b.bind("click",function(){SN.U.FormXHR(a);return false});c.hide();a.addClass("dialogbox").append('').closest(".notice-options").addClass("opaque");a.find("button.close").click(function(){$(this).remove();a.removeClass("dialogbox").closest(".notice-options").removeClass("opaque");a.find(".submit_dialogbox").remove();a.find(".submit").show();return false})},NoticeAttachments:function(){$(".notice a.attachment").each(function(){SN.U.NoticeWithAttachment($(this).closest(".notice"))})},NoticeWithAttachment:function(b){if(b.find(".attachment").length===0){return}var a=b.find(".attachment.more");if(a.length>0){$(a[0]).click(function(){var c=$(this);c.addClass(SN.C.S.Processing);$.get(c.attr("href")+"/ajax",null,function(d){c.parent(".entry-content").html($(d).find("#attachment_view .entry-content").html())});return false}).attr("title",SN.msg("showmore_tooltip"))}},NoticeDataAttach:function(b){var a=b.find("input[type=file]");a.change(function(f){b.find(".attach-status").remove();var d=$(this).val();if(!d){return false}var c=$('
              ');c.find("code").text(d);c.find("button").click(function(){c.remove();a.val("");return false});b.append(c);if(typeof this.files=="object"){for(var e=0;eg){f=false}if(f){h(c,function(j){var i=$("").attr("title",e).attr("alt",e).attr("src",j).attr("style","height: 120px");d.find(".attach-status").append(i)})}else{var b=$("
              ").text(e);d.find(".attach-status").append(b)}},NoticeLocationAttach:function(a){var e=a.find("[name=lat]");var k=a.find("[name=lon]");var g=a.find("[name=location_ns]").val();var l=a.find("[name=location_id]").val();var b="";var d=a.find("[name=notice_data-geo]");var c=a.find("[name=notice_data-geo]");var j=a.find("label.notice_data-geo");function f(n){j.attr("title",jQuery.trim(j.text())).removeClass("checked");a.find("[name=lat]").val("");a.find("[name=lon]").val("");a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("");a.find("[name=notice_data-geo]").attr("checked",false);$.cookie(SN.C.S.NoticeDataGeoCookie,"disabled",{path:"/"});if(n){a.find(".geo_status_wrapper").removeClass("success").addClass("error");a.find(".geo_status_wrapper .geo_status").text(n)}else{a.find(".geo_status_wrapper").remove()}}function m(n,o){SN.U.NoticeGeoStatus(a,"Looking up place name...");$.getJSON(n,o,function(p){var q,r;if(typeof(p.location_ns)!="undefined"){a.find("[name=location_ns]").val(p.location_ns);q=p.location_ns}if(typeof(p.location_id)!="undefined"){a.find("[name=location_id]").val(p.location_id);r=p.location_id}if(typeof(p.name)=="undefined"){NLN_text=o.lat+";"+o.lon}else{NLN_text=p.name}SN.U.NoticeGeoStatus(a,NLN_text,o.lat,o.lon,p.url);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+NLN_text+")");a.find("[name=lat]").val(o.lat);a.find("[name=lon]").val(o.lon);a.find("[name=location_ns]").val(q);a.find("[name=location_id]").val(r);a.find("[name=notice_data-geo]").attr("checked",true);var s={NLat:o.lat,NLon:o.lon,NLNS:q,NLID:r,NLN:NLN_text,NLNU:p.url,NDG:true};$.cookie(SN.C.S.NoticeDataGeoCookie,JSON.stringify(s),{path:"/"})})}if(c.length>0){if($.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){c.attr("checked",false)}else{c.attr("checked",true)}var h=a.find(".notice_data-geo_wrap");var i=h.attr("title");h.removeAttr("title");j.attr("title",j.text());c.change(function(){if(c.attr("checked")===true||$.cookie(SN.C.S.NoticeDataGeoCookie)===null){j.attr("title",NoticeDataGeo_text.ShareDisable).addClass("checked");if($.cookie(SN.C.S.NoticeDataGeoCookie)===null||$.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){if(navigator.geolocation){SN.U.NoticeGeoStatus(a,"Requesting location from browser...");navigator.geolocation.getCurrentPosition(function(p){a.find("[name=lat]").val(p.coords.latitude);a.find("[name=lon]").val(p.coords.longitude);var q={lat:p.coords.latitude,lon:p.coords.longitude,token:$("#token").val()};m(i,q)},function(p){switch(p.code){case p.PERMISSION_DENIED:f("Location permission denied.");break;case p.TIMEOUT:f("Location lookup timeout.");break}},{timeout:10000})}else{if(e.length>0&&k.length>0){var n={lat:e,lon:k,token:$("#token").val()};m(i,n)}else{f();c.remove();j.remove()}}}else{var o=JSON.parse($.cookie(SN.C.S.NoticeDataGeoCookie));a.find("[name=lat]").val(o.NLat);a.find("[name=lon]").val(o.NLon);a.find("[name=location_ns]").val(o.NLNS);a.find("[name=location_id]").val(o.NLID);a.find("[name=notice_data-geo]").attr("checked",o.NDG);SN.U.NoticeGeoStatus(a,o.NLN,o.NLat,o.NLon,o.NLNU);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+o.NLN+")").addClass("checked")}}else{f()}}).change()}},NoticeGeoStatus:function(e,a,f,g,c){var h=e.find(".geo_status_wrapper");if(h.length==0){h=$('
              ');h.find("button.close").click(function(){e.find("[name=notice_data-geo]").removeAttr("checked").change()});e.append(h)}var b;if(c){b=$("").attr("href",c)}else{b=$("")}b.text(a);if(f||g){var d=f+";"+g;b.attr("title",d);if(!a){b.text(d)}}h.find(".geo_status").empty().append(b)},NewDirectMessage:function(){NDM=$(".entity_send-a-message a");NDM.attr({href:NDM.attr("href")+"&ajax=1"});NDM.bind("click",function(){var a=$(".entity_send-a-message form");if(a.length===0){$(this).addClass(SN.C.S.Processing);$.get(NDM.attr("href"),null,function(b){$(".entity_send-a-message").append(document._importNode($("form",b)[0],true));a=$(".entity_send-a-message .form_notice");SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);a.append('');$(".entity_send-a-message button").click(function(){a.hide();return false});NDM.removeClass(SN.C.S.Processing)})}else{a.show();$(".entity_send-a-message textarea").focus()}return false})},GetFullYear:function(c,d,a){var b=new Date();b.setFullYear(c,d,a);return b},StatusNetInstance:{Set:function(b){var a=SN.U.StatusNetInstance.Get();if(a!==null){b=$.extend(a,b)}$.cookie(SN.C.S.StatusNetInstance,JSON.stringify(b),{path:"/",expires:SN.U.GetFullYear(2029,0,1)})},Get:function(){var a=$.cookie(SN.C.S.StatusNetInstance);if(a!==null){return JSON.parse(a)}return null},Delete:function(){$.cookie(SN.C.S.StatusNetInstance,null)}},belongsOnTimeline:function(b){var a=$("body").attr("id");if(a=="public"){return true}var c=$("#nav_profile a").attr("href");if(c){var d=$(b).find(".entry-title .author a.url").attr("href");if(d==c){if(a=="all"||a=="showstream"){return true}}}return false},switchInputFormTab:function(a){$(".input_form_nav_tab.current").removeClass("current");$("#input_form_nav_"+a).addClass("current");$(".input_form.current").removeClass("current");$("#input_form_"+a).addClass("current")}},Init:{NoticeForm:function(){if($("body.user_in").length>0){$("."+SN.C.S.FormNotice).each(function(){var a=$(this);SN.U.NoticeLocationAttach(a);SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);SN.U.NoticeDataAttach(a)})}},Notices:function(){if($("body.user_in").length>0){SN.U.NoticeFavor();SN.U.NoticeRepeat();SN.U.NoticeReply();SN.U.NoticeInlineReplySetup()}SN.U.NoticeAttachments()},EntityActions:function(){if($("body.user_in").length>0){$(".form_user_subscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_unsubscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_join").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_leave").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_nudge").live("click",function(){SN.U.FormXHR($(this));return false});SN.U.NewDirectMessage()}},Login:function(){if(SN.U.StatusNetInstance.Get()!==null){var a=SN.U.StatusNetInstance.Get().Nickname;if(a!==null){$("#form_login #nickname").val(a)}}$("#form_login").bind("submit",function(){SN.U.StatusNetInstance.Set({Nickname:$("#form_login #nickname").val()});return true})},UploadForms:function(){$("input[type=file]").change(function(d){if(typeof this.files=="object"&&this.files.length>0){var c=0;for(var b=0;b0&&c>a){var e="File too large: maximum upload size is %d bytes.";alert(e.replace("%d",a));$(this).val("");d.preventDefault();return false}}})}}};$(document).ready(function(){SN.Init.UploadForms();if($("."+SN.C.S.FormNotice).length>0){SN.Init.NoticeForm()}if($("#content .notices").length>0){SN.Init.Notices()}if($("#content .entity_actions").length>0){SN.Init.EntityActions()}if($("#form_login").length>0){SN.Init.Login()}});if(!document.ELEMENT_NODE){document.ELEMENT_NODE=1;document.ATTRIBUTE_NODE=2;document.TEXT_NODE=3;document.CDATA_SECTION_NODE=4;document.ENTITY_REFERENCE_NODE=5;document.ENTITY_NODE=6;document.PROCESSING_INSTRUCTION_NODE=7;document.COMMENT_NODE=8;document.DOCUMENT_NODE=9;document.DOCUMENT_TYPE_NODE=10;document.DOCUMENT_FRAGMENT_NODE=11;document.NOTATION_NODE=12}document._importNode=function(e,a){switch(e.nodeType){case document.ELEMENT_NODE:var d=document.createElement(e.nodeName);if(e.attributes&&e.attributes.length>0){for(var c=0,b=e.attributes.length;c0){for(var c=0,b=e.childNodes.length;c0){var j=c.pop();j()}}};window._google_loader_apiLoaded=function(){f()};var d=function(){return(window.google&&google.loader)};var g=function(j){if(d()){return true}h(j);e();return false};e();return{shim:true,type:"ClientLocation",lastPosition:null,getCurrentPosition:function(k,n,o){var m=this;if(!g(function(){m.getCurrentPosition(k,n,o)})){return}if(google.loader.ClientLocation){var l=google.loader.ClientLocation;var j={coords:{latitude:l.latitude,longitude:l.longitude,altitude:null,accuracy:43000,altitudeAccuracy:null,heading:null,speed:null},address:{city:l.address.city,country:l.address.country,country_code:l.address.country_code,region:l.address.region},timestamp:new Date()};k(j);this.lastPosition=j}else{if(n==="function"){n({code:3,message:"Using the Google ClientLocation API and it is not able to calculate a location."})}}},watchPosition:function(j,l,m){this.getCurrentPosition(j,l,m);var k=this;var n=setInterval(function(){k.getCurrentPosition(j,l,m)},10000);return n},clearWatch:function(j){clearInterval(j)},getPermission:function(l,j,k){return true}}});navigator.geolocation=(window.google&&google.gears)?a():b()})()}; \ No newline at end of file +var SN={C:{I:{CounterBlackout:false,MaxLength:140,PatternUsername:/^[0-9a-zA-Z\-_.]*$/,HTTP20x30x:[200,201,202,203,204,205,206,300,301,302,303,304,305,306,307],NoticeFormMaster:null},S:{Disabled:"disabled",Warning:"warning",Error:"error",Success:"success",Processing:"processing",CommandResult:"command_result",FormNotice:"form_notice",NoticeDataGeo:"notice_data-geo",NoticeDataGeoCookie:"NoticeDataGeo",NoticeDataGeoSelected:"notice_data-geo_selected",StatusNetInstance:"StatusNetInstance"}},messages:{},msg:function(a){if(typeof SN.messages[a]=="undefined"){return"["+a+"]"}else{return SN.messages[a]}},U:{FormNoticeEnhancements:function(b){if(jQuery.data(b[0],"ElementData")===undefined){MaxLength=b.find(".count").text();if(typeof(MaxLength)=="undefined"){MaxLength=SN.C.I.MaxLength}jQuery.data(b[0],"ElementData",{MaxLength:MaxLength});SN.U.Counter(b);NDT=b.find("[name=status_textarea]");NDT.bind("keyup",function(c){SN.U.Counter(b)});var a=function(c){window.setTimeout(function(){SN.U.Counter(b)},50)};NDT.bind("cut",a).bind("paste",a)}else{b.find(".count").text(jQuery.data(b[0],"ElementData").MaxLength)}},Counter:function(d){SN.C.I.FormNoticeCurrent=d;var b=jQuery.data(d[0],"ElementData").MaxLength;if(b<=0){return}var c=b-SN.U.CharacterCount(d);var a=d.find(".count");if(c.toString()!=a.text()){if(!SN.C.I.CounterBlackout||c===0){if(a.text()!=String(c)){a.text(c)}if(c<0){d.addClass(SN.C.S.Warning)}else{d.removeClass(SN.C.S.Warning)}if(!SN.C.I.CounterBlackout){SN.C.I.CounterBlackout=true;SN.C.I.FormNoticeCurrent=d;window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);",500)}}}},CharacterCount:function(a){return a.find("[name=status_textarea]").val().length},ClearCounterBlackout:function(a){SN.C.I.CounterBlackout=false;SN.U.Counter(a)},RewriteAjaxAction:function(a){if(document.location.protocol=="https:"&&a.substr(0,5)=="http:"){return a.replace(/^http:\/\/[^:\/]+/,"https://"+document.location.host)}else{return a}},FormXHR:function(a){$.ajax({type:"POST",dataType:"xml",url:SN.U.RewriteAjaxAction(a.attr("action")),data:a.serialize()+"&ajax=1",beforeSend:function(b){a.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled)},error:function(c,d,b){alert(b||d)},success:function(b,c){if(typeof($("form",b)[0])!="undefined"){form_new=document._importNode($("form",b)[0],true);a.replaceWith(form_new)}else{a.replaceWith(document._importNode($("p",b)[0],true))}}})},FormNoticeXHR:function(b){SN.C.I.NoticeDataGeo={};b.append('');b.attr("action",SN.U.RewriteAjaxAction(b.attr("action")));var c=function(d,e){b.append($('

              ').addClass(d).text(e))};var a=function(){b.find(".form_response").remove()};b.ajaxForm({dataType:"xml",timeout:"60000",beforeSend:function(d){if(b.find("[name=status_textarea]").val()==""){b.addClass(SN.C.S.Warning);return false}b.addClass(SN.C.S.Processing).find(".submit").addClass(SN.C.S.Disabled).attr(SN.C.S.Disabled,SN.C.S.Disabled);SN.U.normalizeGeoData(b);return true},error:function(f,g,e){b.removeClass(SN.C.S.Processing).find(".submit").removeClass(SN.C.S.Disabled).removeAttr(SN.C.S.Disabled,SN.C.S.Disabled);a();if(g=="timeout"){c("error","Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.")}else{var d=SN.U.GetResponseXML(f);if($("."+SN.C.S.Error,d).length>0){b.append(document._importNode($("."+SN.C.S.Error,d)[0],true))}else{if(parseInt(f.status)===0||jQuery.inArray(parseInt(f.status),SN.C.I.HTTP20x30x)>=0){b.resetForm().find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}else{c("error","(Sorry! We had trouble sending your notice ("+f.status+" "+f.statusText+"). Please report the problem to the site administrator if this happens again.")}}}},success:function(i,f){a();var n=$("#"+SN.C.S.Error,i);if(n.length>0){c("error",n.text())}else{if($("body")[0].id=="bookmarklet"){self.close()}var d=$("#"+SN.C.S.CommandResult,i);if(d.length>0){c("success",d.text())}else{var m=document._importNode($("li",i)[0],true);var k=$("#notices_primary .notices:first");var l=b.closest("li.notice-reply");if(l.length>0){var e=$(m).attr("id");if($("#"+e).length==0){var j=l.closest("li.notice");l.replaceWith(m);SN.U.NoticeInlineReplyPlaceholder(j)}else{l.remove()}}else{if(k.length>0&&SN.U.belongsOnTimeline(m)){if($("#"+m.id).length===0){var h=b.find("[name=inreplyto]").val();var g="#notices_primary #notice-"+h;if($("body")[0].id=="conversation"){if(h.length>0&&$(g+" .notices").length<1){$(g).append('
                ')}$($(g+" .notices")[0]).append(m)}else{k.prepend(m)}$("#"+m.id).css({display:"none"}).fadeIn(2500);SN.U.NoticeWithAttachment($("#"+m.id));SN.U.NoticeReplyTo($("#"+m.id))}}else{c("success",$("title",i).text())}}}b.resetForm();b.find("[name=inreplyto]").val("");b.find(".attach-status").remove();SN.U.FormNoticeEnhancements(b)}},complete:function(d,e){b.removeClass(SN.C.S.Processing).find(".submit").removeAttr(SN.C.S.Disabled).removeClass(SN.C.S.Disabled);b.find("[name=lat]").val(SN.C.I.NoticeDataGeo.NLat);b.find("[name=lon]").val(SN.C.I.NoticeDataGeo.NLon);b.find("[name=location_ns]").val(SN.C.I.NoticeDataGeo.NLNS);b.find("[name=location_id]").val(SN.C.I.NoticeDataGeo.NLID);b.find("[name=notice_data-geo]").attr("checked",SN.C.I.NoticeDataGeo.NDG)}})},normalizeGeoData:function(a){SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val();SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val();SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked");var b=$.cookie(SN.C.S.NoticeDataGeoCookie);if(b!==null&&b!="disabled"){b=JSON.parse(b);SN.C.I.NoticeDataGeo.NLat=a.find("[name=lat]").val(b.NLat).val();SN.C.I.NoticeDataGeo.NLon=a.find("[name=lon]").val(b.NLon).val();if(b.NLNS){SN.C.I.NoticeDataGeo.NLNS=a.find("[name=location_ns]").val(b.NLNS).val();SN.C.I.NoticeDataGeo.NLID=a.find("[name=location_id]").val(b.NLID).val()}else{a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("")}}if(b=="disabled"){SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",false).attr("checked")}else{SN.C.I.NoticeDataGeo.NDG=a.find("[name=notice_data-geo]").attr("checked",true).attr("checked")}},GetResponseXML:function(b){try{return b.responseXML}catch(a){return(new DOMParser()).parseFromString(b.responseText,"text/xml")}},NoticeReply:function(){if($("#content .notice_reply").length>0){$("#content .notice").each(function(){SN.U.NoticeReplyTo($(this))})}},NoticeReplyTo:function(a){a.find(".notice_reply").live("click",function(c){c.preventDefault();var b=($(".author .nickname",a).length>0)?$($(".author .nickname",a)[0]):$(".author .nickname.uid");SN.U.NoticeInlineReplyTrigger(a,"@"+b.text());return false})},NoticeInlineReplyTrigger:function(h,i){var b=$($(".notice_id",h)[0]).text();var e=h;var f=h.closest(".notices");if(f.hasClass("threaded-replies")){e=f.closest(".notice")}else{f=$("ul.threaded-replies",h);if(f.length==0){f=$('
                  ');h.append(f)}}var j=$(".notice-reply-form",f);var d=function(){j.find("input[name=inreplyto]").val(b);var m=j.find("textarea");if(m.length==0){throw"No textarea"}var l="";if(i){l=i+" "}m.val(l+m.val().replace(RegExp(l,"i"),""));m.data("initialText",$.trim(i+""));m.focus();if(m[0].setSelectionRange){var k=m.val().length;m[0].setSelectionRange(k,k)}};if(j.length>0){d()}else{$("li.notice-reply-placeholder").remove();var g=$("li.notice-reply",f);if(g.length==0){g=$('
                • ');var c=function(k){var l=document._importNode(k,true);g.append(l);f.append(g);var m=j=$(l);SN.U.NoticeLocationAttach(m);SN.U.FormNoticeXHR(m);SN.U.FormNoticeEnhancements(m);SN.U.NoticeDataAttach(m);d()};if(SN.C.I.NoticeFormMaster){c(SN.C.I.NoticeFormMaster)}else{var a=$("#form_notice").attr("action");$.get(a,{ajax:1},function(k,m,l){c($("form",k)[0])})}}}},NoticeFavor:function(){$(".form_favor").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_disfavor").live("click",function(){SN.U.FormXHR($(this));return false})},NoticeInlineReplyPlaceholder:function(b){var a=b.find("ul.threaded-replies");var c=$('
                • ');c.click(function(){SN.U.NoticeInlineReplyTrigger(b)});c.find("input").val(SN.msg("reply_placeholder"));a.append(c)},NoticeInlineReplySetup:function(){$(".threaded-replies").each(function(){var b=$(this);var a=b.closest(".notice");SN.U.NoticeInlineReplyPlaceholder(a)})},NoticeRepeat:function(){$(".form_repeat").live("click",function(a){a.preventDefault();SN.U.NoticeRepeatConfirmation($(this));return false})},NoticeRepeatConfirmation:function(a){var c=a.find(".submit");var b=c.clone();b.addClass("submit_dialogbox").removeClass("submit");a.append(b);b.bind("click",function(){SN.U.FormXHR(a);return false});c.hide();a.addClass("dialogbox").append('').closest(".notice-options").addClass("opaque");a.find("button.close").click(function(){$(this).remove();a.removeClass("dialogbox").closest(".notice-options").removeClass("opaque");a.find(".submit_dialogbox").remove();a.find(".submit").show();return false})},NoticeAttachments:function(){$(".notice a.attachment").each(function(){SN.U.NoticeWithAttachment($(this).closest(".notice"))})},NoticeWithAttachment:function(b){if(b.find(".attachment").length===0){return}var a=b.find(".attachment.more");if(a.length>0){$(a[0]).click(function(){var c=$(this);c.addClass(SN.C.S.Processing);$.get(c.attr("href")+"/ajax",null,function(d){c.parent(".entry-content").html($(d).find("#attachment_view .entry-content").html())});return false}).attr("title",SN.msg("showmore_tooltip"))}},NoticeDataAttach:function(b){var a=b.find("input[type=file]");a.change(function(f){b.find(".attach-status").remove();var d=$(this).val();if(!d){return false}var c=$('
                  ');c.find("code").text(d);c.find("button").click(function(){c.remove();a.val("");return false});b.append(c);if(typeof this.files=="object"){for(var e=0;eg){f=false}if(f){h(c,function(j){var i=$("").attr("title",e).attr("alt",e).attr("src",j).attr("style","height: 120px");d.find(".attach-status").append(i)})}else{var b=$("
                  ").text(e);d.find(".attach-status").append(b)}},NoticeLocationAttach:function(a){var e=a.find("[name=lat]");var k=a.find("[name=lon]");var g=a.find("[name=location_ns]").val();var l=a.find("[name=location_id]").val();var b="";var d=a.find("[name=notice_data-geo]");var c=a.find("[name=notice_data-geo]");var j=a.find("label.notice_data-geo");function f(n){j.attr("title",jQuery.trim(j.text())).removeClass("checked");a.find("[name=lat]").val("");a.find("[name=lon]").val("");a.find("[name=location_ns]").val("");a.find("[name=location_id]").val("");a.find("[name=notice_data-geo]").attr("checked",false);$.cookie(SN.C.S.NoticeDataGeoCookie,"disabled",{path:"/"});if(n){a.find(".geo_status_wrapper").removeClass("success").addClass("error");a.find(".geo_status_wrapper .geo_status").text(n)}else{a.find(".geo_status_wrapper").remove()}}function m(n,o){SN.U.NoticeGeoStatus(a,"Looking up place name...");$.getJSON(n,o,function(p){var q,r;if(typeof(p.location_ns)!="undefined"){a.find("[name=location_ns]").val(p.location_ns);q=p.location_ns}if(typeof(p.location_id)!="undefined"){a.find("[name=location_id]").val(p.location_id);r=p.location_id}if(typeof(p.name)=="undefined"){NLN_text=o.lat+";"+o.lon}else{NLN_text=p.name}SN.U.NoticeGeoStatus(a,NLN_text,o.lat,o.lon,p.url);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+NLN_text+")");a.find("[name=lat]").val(o.lat);a.find("[name=lon]").val(o.lon);a.find("[name=location_ns]").val(q);a.find("[name=location_id]").val(r);a.find("[name=notice_data-geo]").attr("checked",true);var s={NLat:o.lat,NLon:o.lon,NLNS:q,NLID:r,NLN:NLN_text,NLNU:p.url,NDG:true};$.cookie(SN.C.S.NoticeDataGeoCookie,JSON.stringify(s),{path:"/"})})}if(c.length>0){if($.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){c.attr("checked",false)}else{c.attr("checked",true)}var h=a.find(".notice_data-geo_wrap");var i=h.attr("title");h.removeAttr("title");j.attr("title",j.text());c.change(function(){if(c.attr("checked")===true||$.cookie(SN.C.S.NoticeDataGeoCookie)===null){j.attr("title",NoticeDataGeo_text.ShareDisable).addClass("checked");if($.cookie(SN.C.S.NoticeDataGeoCookie)===null||$.cookie(SN.C.S.NoticeDataGeoCookie)=="disabled"){if(navigator.geolocation){SN.U.NoticeGeoStatus(a,"Requesting location from browser...");navigator.geolocation.getCurrentPosition(function(p){a.find("[name=lat]").val(p.coords.latitude);a.find("[name=lon]").val(p.coords.longitude);var q={lat:p.coords.latitude,lon:p.coords.longitude,token:$("#token").val()};m(i,q)},function(p){switch(p.code){case p.PERMISSION_DENIED:f("Location permission denied.");break;case p.TIMEOUT:f("Location lookup timeout.");break}},{timeout:10000})}else{if(e.length>0&&k.length>0){var n={lat:e,lon:k,token:$("#token").val()};m(i,n)}else{f();c.remove();j.remove()}}}else{var o=JSON.parse($.cookie(SN.C.S.NoticeDataGeoCookie));a.find("[name=lat]").val(o.NLat);a.find("[name=lon]").val(o.NLon);a.find("[name=location_ns]").val(o.NLNS);a.find("[name=location_id]").val(o.NLID);a.find("[name=notice_data-geo]").attr("checked",o.NDG);SN.U.NoticeGeoStatus(a,o.NLN,o.NLat,o.NLon,o.NLNU);j.attr("title",NoticeDataGeo_text.ShareDisable+" ("+o.NLN+")").addClass("checked")}}else{f()}}).change()}},NoticeGeoStatus:function(e,a,f,g,c){var h=e.find(".geo_status_wrapper");if(h.length==0){h=$('
                  ');h.find("button.close").click(function(){e.find("[name=notice_data-geo]").removeAttr("checked").change()});e.append(h)}var b;if(c){b=$("").attr("href",c)}else{b=$("")}b.text(a);if(f||g){var d=f+";"+g;b.attr("title",d);if(!a){b.text(d)}}h.find(".geo_status").empty().append(b)},NewDirectMessage:function(){NDM=$(".entity_send-a-message a");NDM.attr({href:NDM.attr("href")+"&ajax=1"});NDM.bind("click",function(){var a=$(".entity_send-a-message form");if(a.length===0){$(this).addClass(SN.C.S.Processing);$.get(NDM.attr("href"),null,function(b){$(".entity_send-a-message").append(document._importNode($("form",b)[0],true));a=$(".entity_send-a-message .form_notice");SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);a.append('');$(".entity_send-a-message button").click(function(){a.hide();return false});NDM.removeClass(SN.C.S.Processing)})}else{a.show();$(".entity_send-a-message textarea").focus()}return false})},GetFullYear:function(c,d,a){var b=new Date();b.setFullYear(c,d,a);return b},StatusNetInstance:{Set:function(b){var a=SN.U.StatusNetInstance.Get();if(a!==null){b=$.extend(a,b)}$.cookie(SN.C.S.StatusNetInstance,JSON.stringify(b),{path:"/",expires:SN.U.GetFullYear(2029,0,1)})},Get:function(){var a=$.cookie(SN.C.S.StatusNetInstance);if(a!==null){return JSON.parse(a)}return null},Delete:function(){$.cookie(SN.C.S.StatusNetInstance,null)}},belongsOnTimeline:function(b){var a=$("body").attr("id");if(a=="public"){return true}var c=$("#nav_profile a").attr("href");if(c){var d=$(b).find(".entry-title .author a.url").attr("href");if(d==c){if(a=="all"||a=="showstream"){return true}}}return false},switchInputFormTab:function(a){$(".input_form_nav_tab.current").removeClass("current");$("#input_form_nav_"+a).addClass("current");$(".input_form.current").removeClass("current");$("#input_form_"+a).addClass("current")}},Init:{NoticeForm:function(){if($("body.user_in").length>0){$("."+SN.C.S.FormNotice).each(function(){var a=$(this);SN.U.NoticeLocationAttach(a);SN.U.FormNoticeXHR(a);SN.U.FormNoticeEnhancements(a);SN.U.NoticeDataAttach(a)})}},Notices:function(){if($("body.user_in").length>0){var a=$(".form_notice:first");if(a.length>0){SN.C.I.NoticeFormMaster=document._importNode(a[0],true)}SN.U.NoticeFavor();SN.U.NoticeRepeat();SN.U.NoticeReply();SN.U.NoticeInlineReplySetup()}SN.U.NoticeAttachments()},EntityActions:function(){if($("body.user_in").length>0){$(".form_user_subscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_unsubscribe").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_join").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_group_leave").live("click",function(){SN.U.FormXHR($(this));return false});$(".form_user_nudge").live("click",function(){SN.U.FormXHR($(this));return false});SN.U.NewDirectMessage()}},Login:function(){if(SN.U.StatusNetInstance.Get()!==null){var a=SN.U.StatusNetInstance.Get().Nickname;if(a!==null){$("#form_login #nickname").val(a)}}$("#form_login").bind("submit",function(){SN.U.StatusNetInstance.Set({Nickname:$("#form_login #nickname").val()});return true})},UploadForms:function(){$("input[type=file]").change(function(d){if(typeof this.files=="object"&&this.files.length>0){var c=0;for(var b=0;b0&&c>a){var e="File too large: maximum upload size is %d bytes.";alert(e.replace("%d",a));$(this).val("");d.preventDefault();return false}}})}}};$(document).ready(function(){SN.Init.UploadForms();if($("."+SN.C.S.FormNotice).length>0){SN.Init.NoticeForm()}if($("#content .notices").length>0){SN.Init.Notices()}if($("#content .entity_actions").length>0){SN.Init.EntityActions()}if($("#form_login").length>0){SN.Init.Login()}});if(!document.ELEMENT_NODE){document.ELEMENT_NODE=1;document.ATTRIBUTE_NODE=2;document.TEXT_NODE=3;document.CDATA_SECTION_NODE=4;document.ENTITY_REFERENCE_NODE=5;document.ENTITY_NODE=6;document.PROCESSING_INSTRUCTION_NODE=7;document.COMMENT_NODE=8;document.DOCUMENT_NODE=9;document.DOCUMENT_TYPE_NODE=10;document.DOCUMENT_FRAGMENT_NODE=11;document.NOTATION_NODE=12}document._importNode=function(e,a){switch(e.nodeType){case document.ELEMENT_NODE:var d=document.createElement(e.nodeName);if(e.attributes&&e.attributes.length>0){for(var c=0,b=e.attributes.length;c0){for(var c=0,b=e.childNodes.length;c0){var j=c.pop();j()}}};window._google_loader_apiLoaded=function(){f()};var d=function(){return(window.google&&google.loader)};var g=function(j){if(d()){return true}h(j);e();return false};e();return{shim:true,type:"ClientLocation",lastPosition:null,getCurrentPosition:function(k,n,o){var m=this;if(!g(function(){m.getCurrentPosition(k,n,o)})){return}if(google.loader.ClientLocation){var l=google.loader.ClientLocation;var j={coords:{latitude:l.latitude,longitude:l.longitude,altitude:null,accuracy:43000,altitudeAccuracy:null,heading:null,speed:null},address:{city:l.address.city,country:l.address.country,country_code:l.address.country_code,region:l.address.region},timestamp:new Date()};k(j);this.lastPosition=j}else{if(n==="function"){n({code:3,message:"Using the Google ClientLocation API and it is not able to calculate a location."})}}},watchPosition:function(j,l,m){this.getCurrentPosition(j,l,m);var k=this;var n=setInterval(function(){k.getCurrentPosition(j,l,m)},10000);return n},clearWatch:function(j){clearInterval(j)},getPermission:function(l,j,k){return true}}});navigator.geolocation=(window.google&&google.gears)?a():b()})()}; \ No newline at end of file