From e3caec9d8a512586461de91962c0a7d295d09228 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Wed, 2 Dec 2009 21:24:41 -0500 Subject: Load notice data using javascript from the html on the page instead of writing json representations of the notices on each page Clicking on a geo link pops up a map (round 2) --- plugins/Mapstraction/MapstractionPlugin.php | 72 +---------------------------- plugins/Mapstraction/allmap.php | 61 +++++++++++++++++++++++- plugins/Mapstraction/usermap.php | 66 +++++++++++++++++++++++++- 3 files changed, 127 insertions(+), 72 deletions(-) (limited to 'plugins') diff --git a/plugins/Mapstraction/MapstractionPlugin.php b/plugins/Mapstraction/MapstractionPlugin.php index c0c2c5b8e..a0dbf5204 100644 --- a/plugins/Mapstraction/MapstractionPlugin.php +++ b/plugins/Mapstraction/MapstractionPlugin.php @@ -58,12 +58,12 @@ class MapstractionPlugin extends Plugin * * The way to register new actions from a plugin. * - * @param Router $m reference to router + * @param Router &$m reference to router * * @return boolean event handler return */ - function onRouterInitialized($m) + function onRouterInitialized(&$m) { $m->connect(':nickname/all/map', array('action' => 'allmap'), @@ -110,11 +110,6 @@ class MapstractionPlugin extends Plugin function onEndShowScripts($action) { $actionName = $action->trimmed('action'); - // These are the ones that have maps on 'em - if (!in_array($actionName, - array('showstream', 'all', 'allmap', 'usermap'))) { - return true; - } switch ($this->provider) { @@ -151,39 +146,6 @@ class MapstractionPlugin extends Plugin $action->raw(sprintf('var _provider = "%s";', $this->provider)); $action->elementEnd('script'); - switch ($actionName) { - case 'usermap': - case 'showstream': - $notice = empty($action->tag) - ? $action->user->getNotices(($action->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1) - : $action->user->getTaggedNotices($action->tag, ($action->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null); - break; - case 'all': - case 'allmap': - $cur = common_current_user(); - if (!empty($cur) && $cur->id == $action->user->id) { - $notice = $action->user->noticeInbox(($action->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); - } else { - $notice = $action->user->noticesWithFriends(($action->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); - } - break; - } - - $jsonArray = array(); - - while ($notice->fetch()) { - if (!empty($notice->lat) && !empty($notice->lon)) { - $jsonNotice = $this->noticeAsJson($notice); - $jsonArray[] = $jsonNotice; - } - } - - $action->elementStart('script', array('type' => 'text/javascript')); - $action->raw('/*raw('var _notices = ' . json_encode($jsonArray)); - $action->raw('/*]]>*/'); // XHTML compat for Safari - $action->elementEnd('script'); - return true; } @@ -214,34 +176,4 @@ class MapstractionPlugin extends Plugin $action->elementEnd('div'); } - - function noticeAsJson($notice) - { - // FIXME: this code should be abstracted to a neutral third - // party, like Notice::asJson(). I'm not sure of the ethics - // of refactoring from within a plugin, so I'm just abusing - // the ApiAction method. Don't do this unless you're me! - - require_once(INSTALLDIR.'/lib/api.php'); - - $act = new ApiAction('/dev/null'); - - $arr = $act->twitterStatusArray($notice, true); - $arr['url'] = $notice->bestUrl(); - $arr['html'] = $notice->rendered; - $arr['source'] = $arr['source']; - - if (!empty($notice->reply_to)) { - $reply_to = Notice::staticGet('id', $notice->reply_to); - if (!empty($reply_to)) { - $arr['in_reply_to_status_url'] = $reply_to->bestUrl(); - } - $reply_to = null; - } - - $profile = $notice->getProfile(); - $arr['user']['profile_url'] = $profile->profileurl; - - return $arr; - } } diff --git a/plugins/Mapstraction/allmap.php b/plugins/Mapstraction/allmap.php index 6a48b141f..3a78ac0d4 100644 --- a/plugins/Mapstraction/allmap.php +++ b/plugins/Mapstraction/allmap.php @@ -122,4 +122,63 @@ class AllmapAction extends OwnerDesignAction 'class' => 'gray smallmap', 'style' => "width: 100%; height: 400px")); } -} \ No newline at end of file + + function showScripts() + { + parent::showScripts(); + $cur = common_current_user(); + if (!empty($cur) && $cur->id == $this->user->id) { + $notice = $this->user->noticeInbox(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); + } else { + $notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); + } + + $jsonArray = array(); + + while ($notice->fetch()) { + if (!empty($notice->lat) && !empty($notice->lon)) { + $jsonNotice = $this->noticeAsJson($notice); + $jsonArray[] = $jsonNotice; + } + } + + $this->elementStart('script', array('type' => 'text/javascript')); + $this->raw('/*raw('var _notices = ' . json_encode($jsonArray).'; '); + $this->raw('showMapstraction($("#map_canvas"),_notices);'); + $this->raw('/*]]>*/'); // XHTML compat for Safari + $this->elementEnd('script'); + + return true; + } + + function noticeAsJson($notice) + { + // FIXME: this code should be abstracted to a neutral third + // party, like Notice::asJson(). I'm not sure of the ethics + // of refactoring from within a plugin, so I'm just abusing + // the ApiAction method. Don't do this unless you're me! + + require_once(INSTALLDIR.'/lib/api.php'); + + $act = new ApiAction('/dev/null'); + + $arr = $act->twitterStatusArray($notice, true); + $arr['url'] = $notice->bestUrl(); + $arr['html'] = $notice->rendered; + $arr['source'] = $arr['source']; + + if (!empty($notice->reply_to)) { + $reply_to = Notice::staticGet('id', $notice->reply_to); + if (!empty($reply_to)) { + $arr['in_reply_to_status_url'] = $reply_to->bestUrl(); + } + $reply_to = null; + } + + $profile = $notice->getProfile(); + $arr['user']['profile_url'] = $profile->profileurl; + + return $arr; + } +} diff --git a/plugins/Mapstraction/usermap.php b/plugins/Mapstraction/usermap.php index fbf1469c3..afa48b162 100644 --- a/plugins/Mapstraction/usermap.php +++ b/plugins/Mapstraction/usermap.php @@ -123,4 +123,68 @@ class UsermapAction extends OwnerDesignAction 'class' => 'gray smallmap', 'style' => "width: 100%; height: 400px")); } -} \ No newline at end of file + + /** + * Hook for adding extra JavaScript + * + * @param Action $action Action object for the page + * + * @return boolean event handler return + */ + + function showScripts() + { + parent::showScripts(); + $notice = empty($this->tag) + ? $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1) + : $this->user->getTaggedNotices($this->tag, ($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null); + + $jsonArray = array(); + + while ($notice->fetch()) { + if (!empty($notice->lat) && !empty($notice->lon)) { + $jsonNotice = $this->noticeAsJson($notice); + $jsonArray[] = $jsonNotice; + } + } + + $this->elementStart('script', array('type' => 'text/javascript')); + $this->raw('/*raw('var _notices = ' . json_encode($jsonArray).'; '); + $this->raw('showMapstraction($("#map_canvas"),_notices);'); + $this->raw('/*]]>*/'); // XHTML compat for Safari + $this->elementEnd('script'); + + return true; + } + + function noticeAsJson($notice) + { + // FIXME: this code should be abstracted to a neutral third + // party, like Notice::asJson(). I'm not sure of the ethics + // of refactoring from within a plugin, so I'm just abusing + // the ApiAction method. Don't do this unless you're me! + + require_once(INSTALLDIR.'/lib/api.php'); + + $act = new ApiAction('/dev/null'); + + $arr = $act->twitterStatusArray($notice, true); + $arr['url'] = $notice->bestUrl(); + $arr['html'] = $notice->rendered; + $arr['source'] = $arr['source']; + + if (!empty($notice->reply_to)) { + $reply_to = Notice::staticGet('id', $notice->reply_to); + if (!empty($reply_to)) { + $arr['in_reply_to_status_url'] = $reply_to->bestUrl(); + } + $reply_to = null; + } + + $profile = $notice->getProfile(); + $arr['user']['profile_url'] = $profile->profileurl; + + return $arr; + } +} -- cgit v1.2.3-54-g00ecf From c89b10ffe4adb1df724b6a7c5c31b42c7dd3376b Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 2 Dec 2009 09:47:02 -0800 Subject: Code style cleanup: dropped some unnecessary =& reference assignments where they're used only out of habit for PHP 4-style object semantics --- actions/all.php | 2 +- actions/subscribers.php | 2 +- actions/subscriptions.php | 2 +- actions/userbyid.php | 2 +- lib/schema.php | 18 +++++++++--------- lib/util.php | 2 +- plugins/OpenID/finishaddopenid.php | 4 ++-- scripts/fixup_utf8.php | 8 ++++---- 8 files changed, 20 insertions(+), 20 deletions(-) (limited to 'plugins') diff --git a/actions/all.php b/actions/all.php index 61cedce74..5a9d97dd7 100644 --- a/actions/all.php +++ b/actions/all.php @@ -160,7 +160,7 @@ class AllAction extends ProfileAction function showPageTitle() { - $user =& common_current_user(); + $user = common_current_user(); if ($user && ($user->id == $this->user->id)) { $this->element('h1', null, _("You and friends")); } else { diff --git a/actions/subscribers.php b/actions/subscribers.php index df9ec9961..cc9452820 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -57,7 +57,7 @@ class SubscribersAction extends GalleryAction function showPageNotice() { - $user =& common_current_user(); + $user = common_current_user(); if ($user && ($user->id == $this->profile->id)) { $this->element('p', null, _('These are the people who listen to '. diff --git a/actions/subscriptions.php b/actions/subscriptions.php index cc7b38ee4..0dc5ee762 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -59,7 +59,7 @@ class SubscriptionsAction extends GalleryAction function showPageNotice() { - $user =& common_current_user(); + $user = common_current_user(); if ($user && ($user->id == $this->profile->id)) { $this->element('p', null, _('These are the people whose notices '. diff --git a/actions/userbyid.php b/actions/userbyid.php index 86a61f20b..ebff7e4a7 100644 --- a/actions/userbyid.php +++ b/actions/userbyid.php @@ -69,7 +69,7 @@ class UserbyidAction extends Action if (!$id) { $this->clientError(_('No id.')); } - $user =& User::staticGet($id); + $user = User::staticGet($id); if (!$user) { $this->clientError(_('No such user.')); } diff --git a/lib/schema.php b/lib/schema.php index df7cb65f5..a8ba91b87 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -94,7 +94,7 @@ class Schema public function getTableDef($name) { - $res =& $this->conn->query('DESCRIBE ' . $name); + $res = $this->conn->query('DESCRIBE ' . $name); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); @@ -213,7 +213,7 @@ class Schema $sql .= "); "; - $res =& $this->conn->query($sql); + $res = $this->conn->query($sql); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); @@ -234,7 +234,7 @@ class Schema public function dropTable($name) { - $res =& $this->conn->query("DROP TABLE $name"); + $res = $this->conn->query("DROP TABLE $name"); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); @@ -269,7 +269,7 @@ class Schema $name = "$table_".implode("_", $columnNames)."_idx"; } - $res =& $this->conn->query("ALTER TABLE $table ". + $res = $this->conn->query("ALTER TABLE $table ". "ADD INDEX $name (". implode(",", $columnNames).")"); @@ -291,7 +291,7 @@ class Schema public function dropIndex($table, $name) { - $res =& $this->conn->query("ALTER TABLE $table DROP INDEX $name"); + $res = $this->conn->query("ALTER TABLE $table DROP INDEX $name"); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); @@ -314,7 +314,7 @@ class Schema { $sql = "ALTER TABLE $table ADD COLUMN " . $this->_columnSql($columndef); - $res =& $this->conn->query($sql); + $res = $this->conn->query($sql); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); @@ -339,7 +339,7 @@ class Schema $sql = "ALTER TABLE $table MODIFY COLUMN " . $this->_columnSql($columndef); - $res =& $this->conn->query($sql); + $res = $this->conn->query($sql); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); @@ -363,7 +363,7 @@ class Schema { $sql = "ALTER TABLE $table DROP COLUMN $columnName"; - $res =& $this->conn->query($sql); + $res = $this->conn->query($sql); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); @@ -446,7 +446,7 @@ class Schema $sql = 'ALTER TABLE ' . $tableName . ' ' . implode(', ', $phrase); - $res =& $this->conn->query($sql); + $res = $this->conn->query($sql); if (PEAR::isError($res)) { throw new Exception($res->getMessage()); diff --git a/lib/util.php b/lib/util.php index 99a0a1db3..ab046e871 100644 --- a/lib/util.php +++ b/lib/util.php @@ -127,7 +127,7 @@ function common_check_user($nickname, $password) if (0 == strcmp(common_munge_password($password, $user->id), $user->password)) { //internal checking passed - $authenticatedUser =& $user; + $authenticatedUser = $user; } } } diff --git a/plugins/OpenID/finishaddopenid.php b/plugins/OpenID/finishaddopenid.php index 6e889205d..7cd916523 100644 --- a/plugins/OpenID/finishaddopenid.php +++ b/plugins/OpenID/finishaddopenid.php @@ -80,7 +80,7 @@ class FinishaddopenidAction extends Action function tryLogin() { - $consumer =& oid_consumer(); + $consumer = oid_consumer(); $response = $consumer->complete(common_local_url('finishaddopenid')); @@ -103,7 +103,7 @@ class FinishaddopenidAction extends Action $sreg = $sreg_resp->contents(); } - $cur =& common_current_user(); + $cur = common_current_user(); $other = oid_get_user($canonical); diff --git a/scripts/fixup_utf8.php b/scripts/fixup_utf8.php index 5a9fba7c3..30befadfd 100755 --- a/scripts/fixup_utf8.php +++ b/scripts/fixup_utf8.php @@ -145,7 +145,7 @@ class UTF8FixerUpper echo "$id..."; - $result =& $this->dbu->execute($sth, array($content, $rendered, $id)); + $result = $this->dbu->execute($sth, array($content, $rendered, $id)); if (PEAR::isError($result)) { echo "ERROR: " . $result->getMessage() . "\n"; @@ -209,7 +209,7 @@ class UTF8FixerUpper echo "$id..."; - $result =& $this->dbu->execute($sth, array($fullname, $location, $bio, $id)); + $result = $this->dbu->execute($sth, array($fullname, $location, $bio, $id)); if (PEAR::isError($result)) { echo "ERROR: " . $result->getMessage() . "\n"; @@ -273,7 +273,7 @@ class UTF8FixerUpper echo "$id..."; - $result =& $this->dbu->execute($sth, array($fullname, $location, $description, $id)); + $result = $this->dbu->execute($sth, array($fullname, $location, $description, $id)); if (PEAR::isError($result)) { echo "ERROR: " . $result->getMessage() . "\n"; @@ -330,7 +330,7 @@ class UTF8FixerUpper echo "$id..."; - $result =& $this->dbu->execute($sth, array($content, $rendered, $id)); + $result = $this->dbu->execute($sth, array($content, $rendered, $id)); if (PEAR::isError($result)) { echo "ERROR: " . $result->getMessage() . "\n"; -- cgit v1.2.3-54-g00ecf From 43a1a355241079da6bf355a996910b9d116bf105 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Thu, 3 Dec 2009 19:43:02 -0500 Subject: refactor the common parts of usermap and allmap into a common base class --- plugins/Mapstraction/MapstractionPlugin.php | 1 + plugins/Mapstraction/allmap.php | 125 ++------------------ plugins/Mapstraction/map.php | 170 ++++++++++++++++++++++++++++ plugins/Mapstraction/usermap.php | 130 ++------------------- 4 files changed, 189 insertions(+), 237 deletions(-) create mode 100644 plugins/Mapstraction/map.php (limited to 'plugins') diff --git a/plugins/Mapstraction/MapstractionPlugin.php b/plugins/Mapstraction/MapstractionPlugin.php index a0dbf5204..ca1a3bf20 100644 --- a/plugins/Mapstraction/MapstractionPlugin.php +++ b/plugins/Mapstraction/MapstractionPlugin.php @@ -90,6 +90,7 @@ class MapstractionPlugin extends Plugin { case 'AllmapAction': case 'UsermapAction': + case 'MapAction': include_once INSTALLDIR.'/plugins/Mapstraction/' . strtolower(mb_substr($cls, 0, -6)) . '.php'; return false; default: diff --git a/plugins/Mapstraction/allmap.php b/plugins/Mapstraction/allmap.php index 3a78ac0d4..0c4f03b31 100644 --- a/plugins/Mapstraction/allmap.php +++ b/plugins/Mapstraction/allmap.php @@ -37,59 +37,26 @@ if (!defined('STATUSNET')) { * @category Mapstraction * @package StatusNet * @author Evan Prodromou + * @author Craig Andrews * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ -class AllmapAction extends OwnerDesignAction +class AllmapAction extends MapAction { - var $profile = null; - var $page = null; - var $notices = null; - - public $plugin = null; - function prepare($args) { - parent::prepare($args); - - $nickname_arg = $this->arg('nickname'); - $nickname = common_canonical_nickname($nickname_arg); - - // Permanent redirect on non-canonical nickname - - if ($nickname_arg != $nickname) { - $args = array('nickname' => $nickname); - if ($this->arg('page') && $this->arg('page') != 1) { - $args['page'] = $this->arg['page']; + if(parent::prepare($args)) { + $cur = common_current_user(); + if (!empty($cur) && $cur->id == $this->user->id) { + $this->notice = $this->user->noticeInbox(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); + } else { + $this->notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); } - common_redirect(common_local_url($this->trimmed('action'), $args), 301); - return false; - } - - $this->user = User::staticGet('nickname', $nickname); - - if (!$this->user) { - $this->clientError(_('No such user.'), 404); + return true; + }else{ return false; } - - $this->profile = $this->user->getProfile(); - - if (!$this->profile) { - $this->serverError(_('User has no profile.')); - return false; - } - - $page = $this->trimmed('page'); - - if (!empty($page) && Validate::number($page)) { - $this->page = $page+0; - } else { - $this->page = 1; - } - - return true; } function title() @@ -109,76 +76,4 @@ class AllmapAction extends OwnerDesignAction $this->page); } } - - function handle($args) - { - parent::handle($args); - $this->showPage(); - } - - function showContent() - { - $this->element('div', array('id' => 'map_canvas', - 'class' => 'gray smallmap', - 'style' => "width: 100%; height: 400px")); - } - - function showScripts() - { - parent::showScripts(); - $cur = common_current_user(); - if (!empty($cur) && $cur->id == $this->user->id) { - $notice = $this->user->noticeInbox(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); - } else { - $notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); - } - - $jsonArray = array(); - - while ($notice->fetch()) { - if (!empty($notice->lat) && !empty($notice->lon)) { - $jsonNotice = $this->noticeAsJson($notice); - $jsonArray[] = $jsonNotice; - } - } - - $this->elementStart('script', array('type' => 'text/javascript')); - $this->raw('/*raw('var _notices = ' . json_encode($jsonArray).'; '); - $this->raw('showMapstraction($("#map_canvas"),_notices);'); - $this->raw('/*]]>*/'); // XHTML compat for Safari - $this->elementEnd('script'); - - return true; - } - - function noticeAsJson($notice) - { - // FIXME: this code should be abstracted to a neutral third - // party, like Notice::asJson(). I'm not sure of the ethics - // of refactoring from within a plugin, so I'm just abusing - // the ApiAction method. Don't do this unless you're me! - - require_once(INSTALLDIR.'/lib/api.php'); - - $act = new ApiAction('/dev/null'); - - $arr = $act->twitterStatusArray($notice, true); - $arr['url'] = $notice->bestUrl(); - $arr['html'] = $notice->rendered; - $arr['source'] = $arr['source']; - - if (!empty($notice->reply_to)) { - $reply_to = Notice::staticGet('id', $notice->reply_to); - if (!empty($reply_to)) { - $arr['in_reply_to_status_url'] = $reply_to->bestUrl(); - } - $reply_to = null; - } - - $profile = $notice->getProfile(); - $arr['user']['profile_url'] = $profile->profileurl; - - return $arr; - } } diff --git a/plugins/Mapstraction/map.php b/plugins/Mapstraction/map.php new file mode 100644 index 000000000..89723f43c --- /dev/null +++ b/plugins/Mapstraction/map.php @@ -0,0 +1,170 @@ +. + * + * @category Mapstraction + * @package StatusNet + * @author Evan Prodromou + * @copyright 2009 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Show a map of notices + * + * @category Mapstraction + * @package StatusNet + * @author Evan Prodromou + * @author Craig Andrews + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +class MapAction extends OwnerDesignAction +{ + var $profile = null; + var $page = null; + var $notices = null; + + function prepare($args) + { + parent::prepare($args); + + $nickname_arg = $this->arg('nickname'); + $nickname = common_canonical_nickname($nickname_arg); + + // Permanent redirect on non-canonical nickname + + if ($nickname_arg != $nickname) { + $args = array('nickname' => $nickname); + if ($this->arg('page') && $this->arg('page') != 1) { + $args['page'] = $this->arg['page']; + } + common_redirect(common_local_url($this->trimmed('action'), $args), 301); + return false; + } + + $this->user = User::staticGet('nickname', $nickname); + + if (!$this->user) { + $this->clientError(_('No such user.'), 404); + return false; + } + + $this->profile = $this->user->getProfile(); + + if (!$this->profile) { + $this->serverError(_('User has no profile.')); + return false; + } + + $page = $this->trimmed('page'); + + if (!empty($page) && Validate::number($page)) { + $this->page = $page+0; + } else { + $this->page = 1; + } + + $this->notices = empty($this->tag) + ? $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1) + : $this->user->getTaggedNotices($this->tag, ($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null); + + return true; + } + + function handle($args) + { + parent::handle($args); + $this->showPage(); + } + + function showContent() + { + $this->element('div', array('id' => 'map_canvas', + 'class' => 'gray smallmap', + 'style' => "width: 100%; height: 400px")); + } + + /** + * Hook for adding extra JavaScript + * + * @param Action $action Action object for the page + * + * @return boolean event handler return + */ + + function showScripts() + { + parent::showScripts(); + $jsonArray = array(); + + while ($this->notice->fetch()) { + if (!empty($this->notice->lat) && !empty($this->notice->lon)) { + $jsonNotice = $this->noticeAsJson($this->notice); + $jsonArray[] = $jsonNotice; + } + } + + $this->elementStart('script', array('type' => 'text/javascript')); + $this->raw('/*raw('var _notices = ' . json_encode($jsonArray).'; '); + $this->raw('showMapstraction($("#map_canvas"),_notices);'); + $this->raw('/*]]>*/'); // XHTML compat for Safari + $this->elementEnd('script'); + + return true; + } + + function noticeAsJson($notice) + { + // FIXME: this code should be abstracted to a neutral third + // party, like Notice::asJson(). I'm not sure of the ethics + // of refactoring from within a plugin, so I'm just abusing + // the ApiAction method. Don't do this unless you're me! + + require_once(INSTALLDIR.'/lib/api.php'); + + $act = new ApiAction('/dev/null'); + + $arr = $act->twitterStatusArray($notice, true); + $arr['url'] = $notice->bestUrl(); + $arr['html'] = $notice->rendered; + $arr['source'] = $arr['source']; + + if (!empty($notice->reply_to)) { + $reply_to = Notice::staticGet('id', $notice->reply_to); + if (!empty($reply_to)) { + $arr['in_reply_to_status_url'] = $reply_to->bestUrl(); + } + $reply_to = null; + } + + $profile = $notice->getProfile(); + $arr['user']['profile_url'] = $profile->profileurl; + + return $arr; + } +} diff --git a/plugins/Mapstraction/usermap.php b/plugins/Mapstraction/usermap.php index afa48b162..3e517ee86 100644 --- a/plugins/Mapstraction/usermap.php +++ b/plugins/Mapstraction/usermap.php @@ -37,61 +37,24 @@ if (!defined('STATUSNET')) { * @category Mapstraction * @package StatusNet * @author Evan Prodromou + * @author Craig Andrews * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ -class UsermapAction extends OwnerDesignAction +class UsermapAction extends MapAction { - var $profile = null; - var $page = null; - var $notices = null; - - public $plugin = null; function prepare($args) { - parent::prepare($args); - - $nickname_arg = $this->arg('nickname'); - $nickname = common_canonical_nickname($nickname_arg); - - // Permanent redirect on non-canonical nickname - - if ($nickname_arg != $nickname) { - $args = array('nickname' => $nickname); - if ($this->arg('page') && $this->arg('page') != 1) { - $args['page'] = $this->arg['page']; - } - common_redirect(common_local_url($this->trimmed('action'), $args), 301); - return false; - } - - $this->user = User::staticGet('nickname', $nickname); - - if (!$this->user) { - $this->clientError(_('No such user.'), 404); - return false; - } - - $this->profile = $this->user->getProfile(); - - if (!$this->profile) { - $this->serverError(_('User has no profile.')); + if(parent::prepare($args)) { + $this->notice = empty($this->tag) + ? $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1) + : $this->user->getTaggedNotices($this->tag, ($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null); + return true; + }else{ return false; } - - $page = $this->trimmed('page'); - - if (!empty($page) && Validate::number($page)) { - $this->page = $page+0; - } else { - $this->page = 1; - } - - $this->notices = $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); - - return true; } function title() @@ -110,81 +73,4 @@ class UsermapAction extends OwnerDesignAction $this->page); } } - - function handle($args) - { - parent::handle($args); - $this->showPage(); - } - - function showContent() - { - $this->element('div', array('id' => 'map_canvas', - 'class' => 'gray smallmap', - 'style' => "width: 100%; height: 400px")); - } - - /** - * Hook for adding extra JavaScript - * - * @param Action $action Action object for the page - * - * @return boolean event handler return - */ - - function showScripts() - { - parent::showScripts(); - $notice = empty($this->tag) - ? $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1) - : $this->user->getTaggedNotices($this->tag, ($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null); - - $jsonArray = array(); - - while ($notice->fetch()) { - if (!empty($notice->lat) && !empty($notice->lon)) { - $jsonNotice = $this->noticeAsJson($notice); - $jsonArray[] = $jsonNotice; - } - } - - $this->elementStart('script', array('type' => 'text/javascript')); - $this->raw('/*raw('var _notices = ' . json_encode($jsonArray).'; '); - $this->raw('showMapstraction($("#map_canvas"),_notices);'); - $this->raw('/*]]>*/'); // XHTML compat for Safari - $this->elementEnd('script'); - - return true; - } - - function noticeAsJson($notice) - { - // FIXME: this code should be abstracted to a neutral third - // party, like Notice::asJson(). I'm not sure of the ethics - // of refactoring from within a plugin, so I'm just abusing - // the ApiAction method. Don't do this unless you're me! - - require_once(INSTALLDIR.'/lib/api.php'); - - $act = new ApiAction('/dev/null'); - - $arr = $act->twitterStatusArray($notice, true); - $arr['url'] = $notice->bestUrl(); - $arr['html'] = $notice->rendered; - $arr['source'] = $arr['source']; - - if (!empty($notice->reply_to)) { - $reply_to = Notice::staticGet('id', $notice->reply_to); - if (!empty($reply_to)) { - $arr['in_reply_to_status_url'] = $reply_to->bestUrl(); - } - $reply_to = null; - } - - $profile = $notice->getProfile(); - $arr['user']['profile_url'] = $profile->profileurl; - - return $arr; - } } -- cgit v1.2.3-54-g00ecf From 35ff3961e8a51e41517d8a8b9e5a1a21f826e4ca Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Thu, 3 Dec 2009 19:59:31 -0500 Subject: Remove unnecessary pass by reference indicators --- plugins/Mapstraction/MapstractionPlugin.php | 4 ++-- plugins/UserFlag/UserFlagPlugin.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/Mapstraction/MapstractionPlugin.php b/plugins/Mapstraction/MapstractionPlugin.php index ca1a3bf20..c4f9cd77d 100644 --- a/plugins/Mapstraction/MapstractionPlugin.php +++ b/plugins/Mapstraction/MapstractionPlugin.php @@ -58,12 +58,12 @@ class MapstractionPlugin extends Plugin * * The way to register new actions from a plugin. * - * @param Router &$m reference to router + * @param Router $m reference to router * * @return boolean event handler return */ - function onRouterInitialized(&$m) + function onRouterInitialized($m) { $m->connect(':nickname/all/map', array('action' => 'allmap'), diff --git a/plugins/UserFlag/UserFlagPlugin.php b/plugins/UserFlag/UserFlagPlugin.php index 60c0c2c0a..e13c2555a 100644 --- a/plugins/UserFlag/UserFlagPlugin.php +++ b/plugins/UserFlag/UserFlagPlugin.php @@ -68,7 +68,7 @@ class UserFlagPlugin extends Plugin return true; } - function onRouterInitialized(&$m) { + function onRouterInitialized($m) { $m->connect('main/flag/profile', array('action' => 'flagprofile')); $m->connect('admin/profile/flag', array('action' => 'adminprofileflag')); return true; -- cgit v1.2.3-54-g00ecf From 01b089d9be046db1253cb3bb90e8635b50fddd84 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 4 Dec 2009 12:36:00 -0500 Subject: Added minify plugin --- plugins/Minify/MinifyPlugin.php | 101 + plugins/Minify/README | 20 + plugins/Minify/extlib/minify/HISTORY.txt | 75 + plugins/Minify/extlib/minify/LICENSE.txt | 26 + plugins/Minify/extlib/minify/README.txt | 53 + plugins/Minify/extlib/minify/UPGRADING.txt | 35 + plugins/Minify/extlib/minify/min/README.txt | 132 + plugins/Minify/extlib/minify/min/builder/_index.js | 242 ++ plugins/Minify/extlib/minify/min/builder/bm.js | 36 + plugins/Minify/extlib/minify/min/builder/index.php | 182 ++ .../Minify/extlib/minify/min/builder/ocCheck.php | 36 + .../extlib/minify/min/builder/rewriteTest.js | 1 + plugins/Minify/extlib/minify/min/groupsConfig.php | 34 + plugins/Minify/extlib/minify/min/index.php | 66 + plugins/Minify/extlib/minify/min/lib/FirePHP.php | 1370 ++++++++ .../extlib/minify/min/lib/HTTP/ConditionalGet.php | 348 ++ .../Minify/extlib/minify/min/lib/HTTP/Encoder.php | 326 ++ plugins/Minify/extlib/minify/min/lib/JSMin.php | 314 ++ plugins/Minify/extlib/minify/min/lib/JSMinPlus.php | 1872 +++++++++++ plugins/Minify/extlib/minify/min/lib/Minify.php | 532 +++ .../Minify/extlib/minify/min/lib/Minify/Build.php | 103 + .../Minify/extlib/minify/min/lib/Minify/CSS.php | 83 + .../minify/min/lib/Minify/CSS/Compressor.php | 250 ++ .../minify/min/lib/Minify/CSS/UriRewriter.php | 270 ++ .../extlib/minify/min/lib/Minify/Cache/APC.php | 130 + .../extlib/minify/min/lib/Minify/Cache/File.php | 125 + .../minify/min/lib/Minify/Cache/Memcache.php | 137 + .../minify/min/lib/Minify/CommentPreserver.php | 90 + .../minify/min/lib/Minify/Controller/Base.php | 202 ++ .../minify/min/lib/Minify/Controller/Files.php | 78 + .../minify/min/lib/Minify/Controller/Groups.php | 94 + .../minify/min/lib/Minify/Controller/MinApp.php | 132 + .../minify/min/lib/Minify/Controller/Page.php | 82 + .../minify/min/lib/Minify/Controller/Version1.php | 118 + .../Minify/extlib/minify/min/lib/Minify/HTML.php | 245 ++ .../minify/min/lib/Minify/ImportProcessor.php | 157 + .../Minify/extlib/minify/min/lib/Minify/Lines.php | 131 + .../Minify/extlib/minify/min/lib/Minify/Logger.php | 45 + .../Minify/extlib/minify/min/lib/Minify/Packer.php | 37 + .../Minify/extlib/minify/min/lib/Minify/Source.php | 187 ++ .../extlib/minify/min/lib/Minify/YUICompressor.php | 139 + plugins/Minify/extlib/minify/min/lib/Solar/Dir.php | 199 ++ plugins/Minify/extlib/minify/min/utils.php | 90 + .../min_unit_tests/HTTP_ConditionalGet/2.php | 44 + .../min_unit_tests/HTTP_ConditionalGet/3.php | 40 + .../min_unit_tests/HTTP_ConditionalGet/4.php | 49 + .../min_unit_tests/HTTP_ConditionalGet/5.php | 27 + .../HTTP_ConditionalGet/_include.php | 64 + .../min_unit_tests/HTTP_ConditionalGet/index.php | 36 + .../minify/min_unit_tests/HTTP_Encoder/green.png | Bin 0 -> 202 bytes .../minify/min_unit_tests/HTTP_Encoder/index.php | 60 + .../Minify/extlib/minify/min_unit_tests/_inc.php | 50 + .../min_unit_tests/_test_files/css/comments.css | 9 + .../_test_files/css/comments.min.css | 3 + .../min_unit_tests/_test_files/css/hacks.css | 66 + .../min_unit_tests/_test_files/css/hacks.min.css | 4 + .../min_unit_tests/_test_files/css/issue62.css | 890 +++++ .../min_unit_tests/_test_files/css/issue62.min.css | 25 + .../_test_files/css/paths_prepend.css | 12 + .../_test_files/css/paths_prepend.min.css | 1 + .../_test_files/css/paths_rewrite.css | 14 + .../_test_files/css/paths_rewrite.min.css | 1 + .../min_unit_tests/_test_files/css/readme.txt | 1 + .../min_unit_tests/_test_files/css/selectors.css | 42 + .../_test_files/css/selectors.min.css | 37 + .../min_unit_tests/_test_files/css/styles.css | 31 + .../min_unit_tests/_test_files/css/styles.min.css | 3 + .../min_unit_tests/_test_files/css/subsilver.css | 434 +++ .../_test_files/css/subsilver.min.css | 18 + .../_test_files/css/unusual_strings.css | 10 + .../_test_files/css/unusual_strings.min.css | 2 + .../min_unit_tests/_test_files/css/vladmirated.css | 658 ++++ .../_test_files/css/vladmirated.min.css | 79 + .../_test_files/css_uriRewriter/exp.css | 14 + .../_test_files/css_uriRewriter/in.css | 14 + .../min_unit_tests/_test_files/html/before.html | 96 + .../_test_files/html/before.min.html | 36 + .../min_unit_tests/_test_files/html/before2.html | 95 + .../_test_files/html/before2.min.html | 36 + .../_test_files/importProcessor/1/adjacent.css | 3 + .../_test_files/importProcessor/1/tv.css | 4 + .../_test_files/importProcessor/adjacent.css | 4 + .../_test_files/importProcessor/input.css | 4 + .../_test_files/importProcessor/output.css | 48 + .../minify/min_unit_tests/_test_files/js/before.js | 57 + .../min_unit_tests/_test_files/js/before.min.js | 22 + .../_test_files/js/before.min_plus.js | 22 + .../min_unit_tests/_test_files/js/condcomm.js | 14 + .../_test_files/js/condcomm.min_plus.js | 13 + .../min_unit_tests/_test_files/js/issue74.js | 4 + .../min_unit_tests/_test_files/js/issue74.min.js | 1 + .../_test_files/js/issue74.min_plus.js | 1 + .../min_unit_tests/_test_files/js/jquery-1.2.3.js | 3408 ++++++++++++++++++++ .../_test_files/minify/QueryString.js | 168 + .../min_unit_tests/_test_files/minify/email.js | 24 + .../min_unit_tests/_test_files/minify/issue73_1.js | 2 + .../min_unit_tests/_test_files/minify/issue73_2.js | 3 + .../_test_files/minify/issue89_1.css | 7 + .../_test_files/minify/issue89_2.css | 7 + .../_test_files/minify/issue89_out.min.css | 1 + .../_test_files/minify/lines_bugs.js | 2 + .../_test_files/minify/lines_output.js | 280 ++ .../min_unit_tests/_test_files/minify/minified.css | 5 + .../min_unit_tests/_test_files/minify/minified.js | 12 + .../min_unit_tests/test_HTTP_ConditionalGet.php | 137 + .../minify/min_unit_tests/test_HTTP_Encoder.php | 260 ++ .../extlib/minify/min_unit_tests/test_JSMin.php | 63 + .../minify/min_unit_tests/test_JSMinPlus.php | 80 + .../extlib/minify/min_unit_tests/test_Minify.php | 213 ++ .../minify/min_unit_tests/test_Minify_Build.php | 36 + .../minify/min_unit_tests/test_Minify_CSS.php | 53 + .../min_unit_tests/test_Minify_CSS_UriRewriter.php | 56 + .../min_unit_tests/test_Minify_Cache_APC.php | 33 + .../min_unit_tests/test_Minify_Cache_File.php | 54 + .../min_unit_tests/test_Minify_Cache_Memcache.php | 38 + .../test_Minify_CommentPreserver.php | 37 + .../minify/min_unit_tests/test_Minify_HTML.php | 59 + .../min_unit_tests/test_Minify_ImportProcessor.php | 48 + .../minify/min_unit_tests/test_Minify_Lines.php | 36 + .../extlib/minify/min_unit_tests/test_all.php | 17 + .../minify/min_unit_tests/test_environment.php | 100 + .../minify/min_unit_tests/test_js_in_browser.html | 4 + plugins/Minify/minify.php | 122 + 123 files changed, 17488 insertions(+) create mode 100644 plugins/Minify/MinifyPlugin.php create mode 100644 plugins/Minify/README create mode 100644 plugins/Minify/extlib/minify/HISTORY.txt create mode 100644 plugins/Minify/extlib/minify/LICENSE.txt create mode 100644 plugins/Minify/extlib/minify/README.txt create mode 100644 plugins/Minify/extlib/minify/UPGRADING.txt create mode 100644 plugins/Minify/extlib/minify/min/README.txt create mode 100644 plugins/Minify/extlib/minify/min/builder/_index.js create mode 100644 plugins/Minify/extlib/minify/min/builder/bm.js create mode 100644 plugins/Minify/extlib/minify/min/builder/index.php create mode 100644 plugins/Minify/extlib/minify/min/builder/ocCheck.php create mode 100644 plugins/Minify/extlib/minify/min/builder/rewriteTest.js create mode 100644 plugins/Minify/extlib/minify/min/groupsConfig.php create mode 100644 plugins/Minify/extlib/minify/min/index.php create mode 100644 plugins/Minify/extlib/minify/min/lib/FirePHP.php create mode 100644 plugins/Minify/extlib/minify/min/lib/HTTP/ConditionalGet.php create mode 100644 plugins/Minify/extlib/minify/min/lib/HTTP/Encoder.php create mode 100644 plugins/Minify/extlib/minify/min/lib/JSMin.php create mode 100644 plugins/Minify/extlib/minify/min/lib/JSMinPlus.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Build.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/CSS.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/CSS/Compressor.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/CSS/UriRewriter.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Cache/APC.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Cache/File.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Cache/Memcache.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/CommentPreserver.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Controller/Base.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Controller/Files.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Controller/Groups.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Controller/MinApp.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Controller/Page.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Controller/Version1.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/HTML.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/ImportProcessor.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Lines.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Logger.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Packer.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/Source.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Minify/YUICompressor.php create mode 100644 plugins/Minify/extlib/minify/min/lib/Solar/Dir.php create mode 100644 plugins/Minify/extlib/minify/min/utils.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/2.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/3.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/4.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/5.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/_include.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/index.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/green.png create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/index.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_inc.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/readme.txt create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/exp.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/in.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.html create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.min.html create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.html create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.min.html create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/adjacent.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/tv.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/adjacent.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/input.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/output.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min_plus.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.min_plus.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min_plus.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/jquery-1.2.3.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/QueryString.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/email.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue73_1.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue73_2.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue89_1.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue89_2.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue89_out.min.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/lines_bugs.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/lines_output.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/minified.css create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/minified.js create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_HTTP_ConditionalGet.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_HTTP_Encoder.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_JSMin.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_JSMinPlus.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Build.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_CSS.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_CSS_UriRewriter.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Cache_APC.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Cache_File.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Cache_Memcache.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_CommentPreserver.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_HTML.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_ImportProcessor.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Lines.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_all.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_environment.php create mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_js_in_browser.html create mode 100644 plugins/Minify/minify.php (limited to 'plugins') diff --git a/plugins/Minify/MinifyPlugin.php b/plugins/Minify/MinifyPlugin.php new file mode 100644 index 000000000..4d37fbc70 --- /dev/null +++ b/plugins/Minify/MinifyPlugin.php @@ -0,0 +1,101 @@ + +Author URI: http://candrews.integralblue.com/ +*/ + +/* + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2009, StatusNet, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @package MinifyPlugin + * @maintainer Craig Andrews + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } + +class MinifyPlugin extends Plugin +{ + + /** + * Add Minification related paths to the router table + * + * Hook for RouterInitialized event. + * + * @return boolean hook return + */ + + function onStartInitializeRouter($m) + { + $m->connect('main/min', + array('action' => 'minify')); + return true; + } + + function onAutoload($cls) + { + switch ($cls) + { + case 'MinifyAction': + require_once(INSTALLDIR.'/plugins/Minify/' . strtolower(mb_substr($cls, 0, -6)) . '.php'); + return false; + default: + return true; + } + } + + function onLoginAction($action, &$login) + { + switch ($action) + { + case 'minify': + $login = true; + return false; + default: + return true; + } + } + + function onStartScriptElement($action,&$src,&$type) { + $url = parse_url($src); + if( empty($url->scheme) && empty($url->host) && empty($url->query) && empty($url->fragment)) + { + $src = common_path('main/min?f='.$src.'&v=' . STATUSNET_VERSION); + } + } + + function onStartCssLinkElement($action,&$src,&$theme,&$media) { + $url = parse_url($src); + if( empty($url->scheme) && empty($url->host) && empty($url->query) && empty($url->fragment)) + { + if(file_exists(Theme::file($src,$theme))){ + //src is a relative path, so we can do minification + if(isset($theme)) { + $src = common_path('main/min?f=theme/'.$theme.'/'.$src.'&v=' . STATUSNET_VERSION); + } else { + $src = common_path('main/min?f=theme/default/'.$src.'&v=' . STATUSNET_VERSION); + } + } + } + } +} + diff --git a/plugins/Minify/README b/plugins/Minify/README new file mode 100644 index 000000000..7fb7e239a --- /dev/null +++ b/plugins/Minify/README @@ -0,0 +1,20 @@ +The Minify plugin minifies your CSS and Javascript, removing whitespace and comments. + +Note that if enabled this plugin and use a theme server + ($config['theme']['server']), your theme server will not be used. + +Installation +============ +add "addPlugin('minify', + array('setting'=>'value', 'setting2'=>'value2', ...);" +to the bottom of your config.php + +Settings +======== +None at the moment + +Example +======= + +addPlugin('minify', array()); + diff --git a/plugins/Minify/extlib/minify/HISTORY.txt b/plugins/Minify/extlib/minify/HISTORY.txt new file mode 100644 index 000000000..95a46c87e --- /dev/null +++ b/plugins/Minify/extlib/minify/HISTORY.txt @@ -0,0 +1,75 @@ +Minify Release History + +Version 2.1.3 + * HTTP fixes + * ETag generation now valid (different when gzipped) + * Vary header always sent when Accept-Encoding is sniffed + * Cache-Control no longer has "must-revalidate" due to webkit bug + See: http://mrclay.org/index.php/2009/02/24/safari-4-beta-cache-controlmust-revalidate-bug/ + * Dropped deflate encoding. Browser and proxy support could be buggy. + See: http://stackoverflow.com/questions/883841/ + * File cache now works w/o setting $min_cachePath + * Allow setting contentType in Minify_Source objects + * No more 5.3 deprecation warnings: split() removed + +Version 2.1.2 + * Javascript fixes + * Debug mode no longer confused by "*/*" in strings/RegExps (jQuery) + * quote characters inside RegExp literals no longer cause exception + * files ending in single-line comments no longer cause code loss + * CSS: data: URLs no longer mangled + * Optional error logging to Firefox's FirePHP extension + * Unit tests to check for common DOCUMENT_ROOT problems + * DOCUMENT_ROOT no longer overwritten on IIS servers + * Builder app doesn't fail on systems without gzdeflate() + * APC caching class included + +Version 2.1.1 + * Bug fix release + * Detection and workarounds for zlib.output_compression and non-PHP encoding modules + * Zlib not required (mod_rewrite, et.al., can still be used for encoding) + * HTML : More IE conditional comments preserved + * Minify_groupUri() utility fixed + +Version 2.1.0 + * "min" default application for quick deployment + * Minify URI Builder app & bookmarklet for quickly creating minify URIs + * Relative URIs in CSS file are fixed automatically by default + * "debug" mode for revealing original line #s in combined files + * Better IIS support + * Improved minifier classes: + * JS: preserves IE conditional comments + * CSS: smaller output, preserves more hacks and valid CSS syntax, + shorter line lengths, other bug fixes + * HTML: smaller output, shorter line lengths, other bug fixes + * Default Cache-Control: max-age of 30 minutes + * Conditional GETs supported even when max-age sent + * Experimental memcache cache class (default is files) + * Minify_Cache_File has flock()s (by default) + * Workaround for Windows mtime reporting bug + +Version 2.0.2 beta (2008-06-24) + * Fast new cache system. Cached files served almost 3x as fast. + * Dropped support of compress encoding (though HTTP_Encoder still supports it) + +Version 2.0.1 (2008-05-31) + * E_STRICT compliance (Cache_Lite_File). + +Version 2.0.0 (2008-05-22) + * Complete code overhaul. Minify is now a PEAR-style class and toolkit + for building customized minifying file servers. + * Content-Encoding: deflate/gzip/compress, based on request headers + * Expanded CSS and HTML minifiers with test cases + * Easily plug-in 3rd-party minifiers (like Packer) + * Plug-able front end controller allows changing the way files are chosen + * Compression & encoding modules lazy-loaded as needed (304 responses use + use minimal code) + * Separate utility classes for HTTP encoding and cache control + +Version 1.0.1 (2007-05-05) + * Fixed various problems resolving pathnames when hosted on an NFS mount. + * Fixed 'undefined constant' notice. + * Replaced old JSMin library with a much faster custom implementation. + +Version 1.0.0 (2007-05-02) + * First release. \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/LICENSE.txt b/plugins/Minify/extlib/minify/LICENSE.txt new file mode 100644 index 000000000..8f008adb5 --- /dev/null +++ b/plugins/Minify/extlib/minify/LICENSE.txt @@ -0,0 +1,26 @@ +Copyright (c) 2008 Ryan Grove +Copyright (c) 2008 Steve Clay +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of this project nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/Minify/extlib/minify/README.txt b/plugins/Minify/extlib/minify/README.txt new file mode 100644 index 000000000..3899b9953 --- /dev/null +++ b/plugins/Minify/extlib/minify/README.txt @@ -0,0 +1,53 @@ +WELCOME TO MINIFY 2.1! + +Minify is an HTTP content server. It compresses sources of content +(usually files), combines the result and serves it with appropriate +HTTP headers. These headers can allow clients to perform conditional +GETs (serving content only when clients do not have a valid cache) +and tell clients to cache the file for a period of time. +More info: http://code.google.com/p/minify/ + + +UPGRADING + +See UPGRADING.txt for instructions. + + +INSTALLATION AND USAGE: + +1. Place the /min/ directory as a child of your DOCUMENT_ROOT +directory: i.e. you will have: /home/user/www/public_html/min + +2. Open http://yourdomain/min/ in a web browser. This will forward +you to the Minify URI Builder application, which will help you +quickly start using Minify to serve content on your site. + + +UNIT TESTING: + +1. Place the /min_unit_tests/ directory as a child of your DOCUMENT_ROOT +directory: i.e. you will have: /home/user/www/public_html/min_unit_tests + +2. To run unit tests, access: http://yourdomain/min_unit_tests/test_all.php + +(If you wish, the other test_*.php files can be run to test individual +components with more verbose output.) + +3. Remove /min_unit_tests/ from your DOCUMENT_ROOT when you are done. + + +EXTRAS: + +The min_extras folder contains files for benchmarking using Apache ab on Windows +and a couple single-use tools. DO NOT place this on your production server. + + +FILE ENCODINGS + +Minify *should* work fine with files encoded in UTF-8 or other 8-bit +encodings like ISO 8859/Windows-1252. By default Minify appends +";charset=utf-8" to the Content-Type headers it sends. + +Leading UTF-8 BOMs are stripped from all sources to prevent +duplication in output files, and files are converted to Unix newlines. + diff --git a/plugins/Minify/extlib/minify/UPGRADING.txt b/plugins/Minify/extlib/minify/UPGRADING.txt new file mode 100644 index 000000000..5025faf9b --- /dev/null +++ b/plugins/Minify/extlib/minify/UPGRADING.txt @@ -0,0 +1,35 @@ +Minify Upgrade Guide + +UPGRADING FROM 2.1.* + +1. Rename the following files: + + /min/config.php --> /min/old_config.php + /min/groupsConfig.php --> /min/old_groupsConfig.php + +2. Overwrite all files in /min (and /min_unit_tests) with those from this zip. + +3. Delete /min/groupsConfig.php + +4. Rename /min/old_groupsConfig.php --> /min/groupsConfig.php + +5. Merge your settings in old_config.php into config.php. + + * If you've set $_SERVER['DOCUMENT_ROOT'], instead set the new option + $min_documentRoot. This is advantageous on IIS systems because Minify + will no longer overwrite the path you specified. + + * $min_errorLogger adds the ability to enable FirePHP logging. + +6. (optional) Delete /min/old_config.php and the Minify files from your cache + directory (specified in $min_cachePath). + + +INSTALLING FRESH + +See README.txt for instructions on installing this app for the first time. + + +SUPPORT + +Send a message to http://groups.google.com/group/minify \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min/README.txt b/plugins/Minify/extlib/minify/min/README.txt new file mode 100644 index 000000000..a7cf774a1 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/README.txt @@ -0,0 +1,132 @@ +The files in this directory represent the default Minify setup designed to ease +integration with your site. This app will combine and minify your Javascript or +CSS files and serve them with HTTP compression and cache headers. + + +RECOMMENDED + +It's recommended to edit config.php to set $min_cachePath to a writeable +(by PHP) directory on your system. This will improve performance. + + +GETTING STARTED + +The quickest way to get started is to use the Minify URI Builder application +on your website: http://example.com/min/builder/ + + +MINIFYING A SINGLE FILE + +Let's say you want to serve this file: + http://example.com/wp-content/themes/default/default.css + +Here's the "Minify URL" for this file: + http://example.com/min/?f=wp-content/themes/default/default.css + +In other words, the "f" argument is set to the file path from root without the +initial "/". As CSS files may contain relative URIs, Minify will automatically +"fix" these by rewriting them as root relative. + + +COMBINING MULTIPLE FILES IN ONE DOWNLOAD + +Separate the paths given to "f" with commas. + +Let's say you have CSS files at these URLs: + http://example.com/scripts/jquery-1.2.6.js + http://example.com/scripts/site.js + +You can combine these files through Minify by requesting this URL: + http://example.com/min/?f=scripts/jquery-1.2.6.js,scripts/site.js + + +SIMPLIFYING URLS WITH A BASE PATH + +If you're combining files that share the same ancestor directory, you can use +the "b" argument to set the base directory for the "f" argument. Do not include +the leading or trailing "/" characters. + +E.g., the following URLs will serve the exact same content: + http://example.com/min/?f=scripts/jquery-1.2.6.js,scripts/site.js,scripts/home.js + http://example.com/min/?b=scripts&f=jquery-1.2.6.js,site.js,home.js + + +MINIFY URLS IN HTML + +In (X)HTML files, don't forget to replace any "&" characters with "&". + + +SPECIFYING ALLOWED DIRECTORIES + +By default, Minify will serve any *.css/*.js files within the DOCUMENT_ROOT. If +you'd prefer to limit Minify's access to certain directories, set the +$min_serveOptions['minApp']['allowDirs'] array in config.php. E.g. to limit +to the /js and /themes/default directories, use: + +$min_serveOptions['minApp']['allowDirs'] = array('//js', '//themes/default'); + + +GROUPS: FASTER PERFORMANCE AND BETTER URLS + +For the best performance, edit groupsConfig.php to pre-specify groups of files +to be combined under preset keys. E.g., here's an example configuration in +groupsConfig.php: + +return array( + 'js' => array('//js/Class.js', '//js/email.js') +); + +This pre-selects the following files to be combined under the key "js": + http://example.com/js/Class.js + http://example.com/js/email.js + +You can now serve these files with this simple URL: + http://example.com/min/?g=js + + +GROUPS: SPECIFYING FILES OUTSIDE THE DOC_ROOT + +In the groupsConfig.php array, the "//" in the file paths is a shortcut for +the DOCUMENT_ROOT, but you can also specify paths from the root of the filesystem +or relative to the DOC_ROOT: + +return array( + 'js' => array( + '//js/file.js' // file within DOC_ROOT + ,'//../file.js' // file in parent directory of DOC_ROOT + ,'C:/Users/Steve/file.js' // file anywhere on filesystem + ) +); + + +FAR-FUTURE EXPIRES HEADERS + +Minify can send far-future (one year) Expires headers. To enable this you must +add a number to the querystring (e.g. /min/?g=js&1234 or /min/f=file.js&1234) +and alter it whenever a source file is changed. If you have a build process you +can use a build/source control revision number. + +If you serve files as a group, you can use the utility function Minify_groupUri() +to get a "versioned" Minify URI for use in your HTML. E.g.: + +"; + + +DEBUG MODE + +In debug mode, instead of compressing files, Minify sends combined files with +comments prepended to each line to show the line number in the original source +file. To enable this, set $min_allowDebugFlag to true in config.php and append +"&debug=1" to your URIs. E.g. /min/?f=script1.js,script2.js&debug=1 + +Known issue: files with comment-like strings/regexps can cause problems in this mode. + + +QUESTIONS? + +http://groups.google.com/group/minify \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min/builder/_index.js b/plugins/Minify/extlib/minify/min/builder/_index.js new file mode 100644 index 000000000..8e5313a3b --- /dev/null +++ b/plugins/Minify/extlib/minify/min/builder/_index.js @@ -0,0 +1,242 @@ +var MUB = { + _uid : 0 + ,_minRoot : '/min/?' + ,checkRewrite : function () { + var testUri = location.pathname.replace(/\/[^\/]*$/, '/rewriteTest.js').substr(1); + function fail() { + $('#minRewriteFailed')[0].className = 'topNote'; + }; + $.ajax({ + url : '../f=' + testUri + '&' + (new Date()).getTime() + ,success : function (data) { + if (data === '1') { + MUB._minRoot = '/min/'; + $('span.minRoot').html('/min/'); + } else + fail(); + } + ,error : fail + }); + } + /** + * Get markup for new source LI element + */ + ,newLi : function () { + return '
  • http://' + location.host + '/' + + ' ' + + '
  • '; + } + /** + * Add new empty source LI and attach handlers to buttons + */ + ,addLi : function () { + $('#sources').append(MUB.newLi()); + var li = $('#li' + MUB._uid)[0]; + $('button[title=Remove]', li).click(function () { + $('#results').hide(); + var hadValue = !!$('input', li)[0].value; + $(li).remove(); + }); + $('button[title$=Earlier]', li).click(function () { + $(li).prev('li').find('input').each(function () { + $('#results').hide(); + // this = previous li input + var tmp = this.value; + this.value = $('input', li).val(); + $('input', li).val(tmp); + MUB.updateAllTestLinks(); + }); + }); + $('button[title$=Later]', li).click(function () { + $(li).next('li').find('input').each(function () { + $('#results').hide(); + // this = next li input + var tmp = this.value; + this.value = $('input', li).val(); + $('input', li).val(tmp); + MUB.updateAllTestLinks(); + }); + }); + ++MUB._uid; + } + /** + * In the context of a source LI element, this will analyze the URI in + * the INPUT and check the URL on the site. + */ + ,liUpdateTestLink : function () { // call in context of li element + if (! $('input', this)[0].value) + return; + var li = this; + $('span', this).html(''); + var url = 'http://' + location.host + '/' + + $('input', this)[0].value.replace(/^\//, ''); + $.ajax({ + url : url + ,complete : function (xhr, stat) { + if ('success' == stat) + $('span', li).html('✓'); + else { + $('span', li).html('') + .find('button').click(function () { + MUB.liUpdateTestLink.call(li); + }); + } + } + ,dataType : 'text' + }); + } + /** + * Check all source URLs + */ + ,updateAllTestLinks : function () { + $('#sources li').each(MUB.liUpdateTestLink); + } + /** + * In a given array of strings, find the character they all have at + * a particular index + * @param Array arr array of strings + * @param Number pos index to check + * @return mixed a common char or '' if any do not match + */ + ,getCommonCharAtPos : function (arr, pos) { + var i + ,l = arr.length + ,c = arr[0].charAt(pos); + if (c === '' || l === 1) + return c; + for (i = 1; i < l; ++i) + if (arr[i].charAt(pos) !== c) + return ''; + return c; + } + /** + * Get the shortest URI to minify the set of source files + * @param Array sources URIs + */ + ,getBestUri : function (sources) { + var pos = 0 + ,base = '' + ,c; + while (true) { + c = MUB.getCommonCharAtPos(sources, pos); + if (c === '') + break; + else + base += c; + ++pos; + } + base = base.replace(/[^\/]+$/, ''); + var uri = MUB._minRoot + 'f=' + sources.join(','); + if (base.charAt(base.length - 1) === '/') { + // we have a base dir! + var basedSources = sources + ,i + ,l = sources.length; + for (i = 0; i < l; ++i) { + basedSources[i] = sources[i].substr(base.length); + } + base = base.substr(0, base.length - 1); + var bUri = MUB._minRoot + 'b=' + base + '&f=' + basedSources.join(','); + //window.console && console.log([uri, bUri]); + uri = uri.length < bUri.length + ? uri + : bUri; + } + return uri; + } + /** + * Create the Minify URI for the sources + */ + ,update : function () { + MUB.updateAllTestLinks(); + var sources = [] + ,ext = false + ,fail = false; + $('#sources input').each(function () { + var m, val; + if (! fail && this.value && (m = this.value.match(/\.(css|js)$/))) { + var thisExt = m[1]; + if (ext === false) + ext = thisExt; + else if (thisExt !== ext) { + fail = true; + return alert('extensions must match!'); + } + this.value = this.value.replace(/^\//, ''); + if (-1 != $.inArray(this.value, sources)) { + fail = true; + return alert('duplicate file!'); + } + sources.push(this.value); + } + }); + if (fail || ! sources.length) + return; + $('#groupConfig').val(" 'keyName' => array('//" + sources.join("', '//") + "'),"); + var uri = MUB.getBestUri(sources) + ,uriH = uri.replace(//, '>').replace(/&/, '&'); + $('#uriA').html(uriH)[0].href = uri; + $('#uriHtml').val( + ext === 'js' + ? '' + : '' + ); + $('#results').show(); + } + /** + * Handler for the "Add file +" button + */ + ,addButtonClick : function () { + $('#results').hide(); + MUB.addLi(); + MUB.updateAllTestLinks(); + $('#update').show().click(MUB.update); + $('#sources li:last input')[0].focus(); + } + /** + * Runs on DOMready + */ + ,init : function () { + $('#app').show(); + $('#sources').html(''); + $('#add button').click(MUB.addButtonClick); + // make easier to copy text out of + $('#uriHtml, #groupConfig').click(function () { + this.select(); + }).focus(function () { + this.select(); + }); + $('a.ext').attr({target:'_blank'}); + if (location.hash) { + // make links out of URIs from bookmarklet + $('#getBm').hide(); + $('#bmUris').html('

    Found by bookmarklet: /' + + location.hash.substr(1).split(',').join(' | /') + + '

    ' + ); + $('#bmUris a').click(function () { + MUB.addButtonClick(); + $('#sources li:last input').val(this.innerHTML) + MUB.liUpdateTestLink.call($('#sources li:last')[0]); + $('#results').hide(); + return false; + }).attr({title:'Add file +'}); + } else { + // copy bookmarklet code into href + var bmUri = location.pathname.replace(/\/[^\/]*$/, '/bm.js').substr(1); + $.ajax({ + url : '../?f=' + bmUri + ,success : function (code) { + $('#bm')[0].href = code + .replace('%BUILDER_URL%', location.href) + .replace(/\n/g, ' '); + } + ,dataType : 'text' + }); + $.browser.msie && $('#getBm p:last').append(' Sorry, not supported in MSIE!'); + MUB.addButtonClick(); + } + MUB.checkRewrite(); + } +}; +window.onload = MUB.init; \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min/builder/bm.js b/plugins/Minify/extlib/minify/min/builder/bm.js new file mode 100644 index 000000000..10d194381 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/builder/bm.js @@ -0,0 +1,36 @@ +javascript:(function() { + var d = document + ,uris = [] + ,i = 0 + ,o + ,home = (location + '').split('/').splice(0, 3).join('/') + '/'; + function add(uri) { + return (0 === uri.indexOf(home)) + && (!/[\?&]/.test(uri)) + && uris.push(escape(uri.substr(home.length))); + }; + function sheet(ss) { + // we must check the domain with add() before accessing ss.cssRules + // otherwise a security exception will be thrown + if (ss.href && add(ss.href) && ss.cssRules) { + var i = 0, r; + while (r = ss.cssRules[i++]) + r.styleSheet && sheet(r.styleSheet); + } + }; + while (o = d.getElementsByTagName('script')[i++]) + o.src && !(o.type && /vbs/i.test(o.type)) && add(o.src); + i = 0; + while (o = d.styleSheets[i++]) + /* http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-DocumentStyle-styleSheets + document.styleSheet is a list property where [0] accesses the 1st element and + [outOfRange] returns null. In IE, styleSheets is a function, and also throws an + exception when you check the out of bounds index. (sigh) */ + sheet(o); + if (uris.length) + window.open('%BUILDER_URL%#' + uris.join(',')); + else + alert('No js/css files found with URLs within "' + + home.split('/')[2] + + '".\n(This tool is limited to URLs with the same domain.)'); +})(); \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min/builder/index.php b/plugins/Minify/extlib/minify/min/builder/index.php new file mode 100644 index 000000000..1b2098222 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/builder/index.php @@ -0,0 +1,182 @@ + + + + + Minify URI Builder + + + + +

    Note: Please set $min_cachePath +in /min/config.php to improve performance.

    + + +

    Note: Your webserver does not seem to + support mod_rewrite (used in /min/.htaccess). Your Minify URIs will contain "?", which +may reduce the benefit of proxy cache servers.

    + +

    Minify URI Builder

    + + + +
    + +

    Create a list of Javascript or CSS files (or 1 is fine) you'd like to combine +and click [Update].

    + +
    +
    + +
    + +

    + +
    + +

    Minify URI

    +

    Place this URI in your HTML to serve the files above combined, minified, compressed and +with cache headers.

    + + + +
    URI/min (opens in new window)
    HTML
    + +

    How to serve these files as a group

    +

    For the best performance you can serve these files as a pre-defined group with a URI +like: /min/?g=keyName

    +

    To do this, add a line like this to /min/groupsConfig.php:

    + +
    return array(
    +    ... your existing groups here ...
    +
    +);
    + +

    Make sure to replace keyName with a unique key for this group.

    +
    + +
    +

    Find URIs on a Page

    +

    You can use the bookmarklet below to fetch all CSS & Javascript URIs from a page +on your site. When you active it, this page will open in a new window with a list of +available URIs to add.

    + +

    Create Minify URIs (right-click, add to bookmarks)

    +
    + +

    Combining CSS files that contain @import

    +

    If your CSS files contain @import declarations, Minify will not +remove them. Therefore, you will want to remove those that point to files already +in your list, and move any others to the top of the first file in your list +(imports below any styles will be ignored by browsers as invalid).

    +

    If you desire, you can use Minify URIs in imports and they will not be touched +by Minify. E.g. @import "/min/?g=css2";

    + +
    + +
    +

    Need help? Search or post to the Minify discussion list.

    +

    This app is minified :) view +source

    + + + + + + + ob_get_contents() + ,'id' => __FILE__ + ,'lastModifiedTime' => max( + // regenerate cache if either of these change + filemtime(__FILE__) + ,filemtime(dirname(__FILE__) . '/../config.php') + ) + ,'minifyAll' => true + ,'encodeOutput' => $encodeOutput +); +ob_end_clean(); + +set_include_path(dirname(__FILE__) . '/../lib' . PATH_SEPARATOR . get_include_path()); + +require 'Minify.php'; + +if (0 === stripos(PHP_OS, 'win')) { + Minify::setDocRoot(); // we may be on IIS +} +Minify::setCache(isset($min_cachePath) ? $min_cachePath : null); +Minify::$uploaderHoursBehind = $min_uploaderHoursBehind; + +Minify::serve('Page', $serveOpts); diff --git a/plugins/Minify/extlib/minify/min/builder/ocCheck.php b/plugins/Minify/extlib/minify/min/builder/ocCheck.php new file mode 100644 index 000000000..c47baa33d --- /dev/null +++ b/plugins/Minify/extlib/minify/min/builder/ocCheck.php @@ -0,0 +1,36 @@ + 'World!' + ,'method' => 'deflate' + )); + $he->encode(); + $he->sendAll(); + +} else { + // echo status "0" or "1" + header('Content-Type: text/plain'); + echo (int)$_oc; +} diff --git a/plugins/Minify/extlib/minify/min/builder/rewriteTest.js b/plugins/Minify/extlib/minify/min/builder/rewriteTest.js new file mode 100644 index 000000000..56a6051ca --- /dev/null +++ b/plugins/Minify/extlib/minify/min/builder/rewriteTest.js @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min/groupsConfig.php b/plugins/Minify/extlib/minify/min/groupsConfig.php new file mode 100644 index 000000000..9e2514d7a --- /dev/null +++ b/plugins/Minify/extlib/minify/min/groupsConfig.php @@ -0,0 +1,34 @@ + array('//js/file1.js', '//js/file2.js'), + // 'css' => array('//css/file1.css', '//css/file2.css'), + + // custom source example + /*'js2' => array( + dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', + // do NOT process this file + new Minify_Source(array( + 'filepath' => dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', + 'minifier' => create_function('$a', 'return $a;') + )) + ),//*/ + + /*'js3' => array( + dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', + // do NOT process this file + new Minify_Source(array( + 'filepath' => dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', + 'minifier' => array('Minify_Packer', 'minify') + )) + ),//*/ +); \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min/index.php b/plugins/Minify/extlib/minify/min/index.php new file mode 100644 index 000000000..51c352569 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/index.php @@ -0,0 +1,66 @@ + + * @license http://www.opensource.org/licenses/bsd-license.php + * @package FirePHP + */ + + +/** + * Sends the given data to the FirePHP Firefox Extension. + * The data can be displayed in the Firebug Console or in the + * "Server" request tab. + * + * For more information see: http://www.firephp.org/ + * + * @copyright Copyright (C) 2007-2008 Christoph Dorn + * @author Christoph Dorn + * @license http://www.opensource.org/licenses/bsd-license.php + * @package FirePHP + */ +class FirePHP { + + /** + * FirePHP version + * + * @var string + */ + const VERSION = '0.2.0'; + + /** + * Firebug LOG level + * + * Logs a message to firebug console. + * + * @var string + */ + const LOG = 'LOG'; + + /** + * Firebug INFO level + * + * Logs a message to firebug console and displays an info icon before the message. + * + * @var string + */ + const INFO = 'INFO'; + + /** + * Firebug WARN level + * + * Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise. + * + * @var string + */ + const WARN = 'WARN'; + + /** + * Firebug ERROR level + * + * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. + * + * @var string + */ + const ERROR = 'ERROR'; + + /** + * Dumps a variable to firebug's server panel + * + * @var string + */ + const DUMP = 'DUMP'; + + /** + * Displays a stack trace in firebug console + * + * @var string + */ + const TRACE = 'TRACE'; + + /** + * Displays an exception in firebug console + * + * Increments the firebug error count. + * + * @var string + */ + const EXCEPTION = 'EXCEPTION'; + + /** + * Displays an table in firebug console + * + * @var string + */ + const TABLE = 'TABLE'; + + /** + * Starts a group in firebug console + * + * @var string + */ + const GROUP_START = 'GROUP_START'; + + /** + * Ends a group in firebug console + * + * @var string + */ + const GROUP_END = 'GROUP_END'; + + /** + * Singleton instance of FirePHP + * + * @var FirePHP + */ + protected static $instance = null; + + /** + * Wildfire protocol message index + * + * @var int + */ + protected $messageIndex = 1; + + /** + * Options for the library + * + * @var array + */ + protected $options = array(); + + /** + * Filters used to exclude object members when encoding + * + * @var array + */ + protected $objectFilters = array(); + + /** + * A stack of objects used to detect recursion during object encoding + * + * @var object + */ + protected $objectStack = array(); + + /** + * Flag to enable/disable logging + * + * @var boolean + */ + protected $enabled = true; + + /** + * The object constructor + */ + function __construct() { + $this->options['maxObjectDepth'] = 10; + $this->options['maxArrayDepth'] = 20; + $this->options['useNativeJsonEncode'] = true; + $this->options['includeLineNumbers'] = true; + } + + /** + * When the object gets serialized only include specific object members. + * + * @return array + */ + public function __sleep() { + return array('options','objectFilters','enabled'); + } + + /** + * Gets singleton instance of FirePHP + * + * @param boolean $AutoCreate + * @return FirePHP + */ + public static function getInstance($AutoCreate=false) { + if($AutoCreate===true && !self::$instance) { + self::init(); + } + return self::$instance; + } + + /** + * Creates FirePHP object and stores it for singleton access + * + * @return FirePHP + */ + public static function init() { + return self::$instance = new self(); + } + + /** + * Enable and disable logging to Firebug + * + * @param boolean $Enabled TRUE to enable, FALSE to disable + * @return void + */ + public function setEnabled($Enabled) { + $this->enabled = $Enabled; + } + + /** + * Check if logging is enabled + * + * @return boolean TRUE if enabled + */ + public function getEnabled() { + return $this->enabled; + } + + /** + * Specify a filter to be used when encoding an object + * + * Filters are used to exclude object members. + * + * @param string $Class The class name of the object + * @param array $Filter An array or members to exclude + * @return void + */ + public function setObjectFilter($Class, $Filter) { + $this->objectFilters[$Class] = $Filter; + } + + /** + * Set some options for the library + * + * Options: + * - maxObjectDepth: The maximum depth to traverse objects (default: 10) + * - maxArrayDepth: The maximum depth to traverse arrays (default: 20) + * - useNativeJsonEncode: If true will use json_encode() (default: true) + * - includeLineNumbers: If true will include line numbers and filenames (default: true) + * + * @param array $Options The options to be set + * @return void + */ + public function setOptions($Options) { + $this->options = array_merge($this->options,$Options); + } + + /** + * Register FirePHP as your error handler + * + * Will throw exceptions for each php error. + */ + public function registerErrorHandler() + { + //NOTE: The following errors will not be caught by this error handler: + // E_ERROR, E_PARSE, E_CORE_ERROR, + // E_CORE_WARNING, E_COMPILE_ERROR, + // E_COMPILE_WARNING, E_STRICT + + set_error_handler(array($this,'errorHandler')); + } + + /** + * FirePHP's error handler + * + * Throws exception for each php error that will occur. + * + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param int $errline + * @param array $errcontext + */ + public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) + { + // Don't throw exception if error reporting is switched off + if (error_reporting() == 0) { + return; + } + // Only throw exceptions for errors we are asking for + if (error_reporting() & $errno) { + throw new ErrorException($errstr, 0, $errno, $errfile, $errline); + } + } + + /** + * Register FirePHP as your exception handler + */ + public function registerExceptionHandler() + { + set_exception_handler(array($this,'exceptionHandler')); + } + + /** + * FirePHP's exception handler + * + * Logs all exceptions to your firebug console and then stops the script. + * + * @param Exception $Exception + * @throws Exception + */ + function exceptionHandler($Exception) { + $this->fb($Exception); + } + + /** + * Set custom processor url for FirePHP + * + * @param string $URL + */ + public function setProcessorUrl($URL) + { + $this->setHeader('X-FirePHP-ProcessorURL', $URL); + } + + /** + * Set custom renderer url for FirePHP + * + * @param string $URL + */ + public function setRendererUrl($URL) + { + $this->setHeader('X-FirePHP-RendererURL', $URL); + } + + /** + * Start a group for following messages + * + * @param string $Name + * @return true + * @throws Exception + */ + public function group($Name) { + return $this->fb(null, $Name, FirePHP::GROUP_START); + } + + /** + * Ends a group you have started before + * + * @return true + * @throws Exception + */ + public function groupEnd() { + return $this->fb(null, null, FirePHP::GROUP_END); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::LOG + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public function log($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP::LOG); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::INFO + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public function info($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP::INFO); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::WARN + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public function warn($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP::WARN); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::ERROR + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public function error($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP::ERROR); + } + + /** + * Dumps key and variable to firebug server panel + * + * @see FirePHP::DUMP + * @param string $Key + * @param mixed $Variable + * @return true + * @throws Exception + */ + public function dump($Key, $Variable) { + return $this->fb($Variable, $Key, FirePHP::DUMP); + } + + /** + * Log a trace in the firebug console + * + * @see FirePHP::TRACE + * @param string $Label + * @return true + * @throws Exception + */ + public function trace($Label) { + return $this->fb($Label, FirePHP::TRACE); + } + + /** + * Log a table in the firebug console + * + * @see FirePHP::TABLE + * @param string $Label + * @param string $Table + * @return true + * @throws Exception + */ + public function table($Label, $Table) { + return $this->fb($Table, $Label, FirePHP::TABLE); + } + + /** + * Check if FirePHP is installed on client + * + * @return boolean + */ + public function detectClientExtension() { + /* Check if FirePHP is installed on client */ + if(!@preg_match_all('/\sFirePHP\/([\.|\d]*)\s?/si',$this->getUserAgent(),$m) || + !version_compare($m[1][0],'0.0.6','>=')) { + return false; + } + return true; + } + + /** + * Log varible to Firebug + * + * @see http://www.firephp.org/Wiki/Reference/Fb + * @param mixed $Object The variable to be logged + * @return true Return TRUE if message was added to headers, FALSE otherwise + * @throws Exception + */ + public function fb($Object) { + + if(!$this->enabled) { + return false; + } + + if (headers_sent($filename, $linenum)) { + throw $this->newException('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); + } + + $Type = null; + $Label = null; + + if(func_num_args()==1) { + } else + if(func_num_args()==2) { + switch(func_get_arg(1)) { + case self::LOG: + case self::INFO: + case self::WARN: + case self::ERROR: + case self::DUMP: + case self::TRACE: + case self::EXCEPTION: + case self::TABLE: + case self::GROUP_START: + case self::GROUP_END: + $Type = func_get_arg(1); + break; + default: + $Label = func_get_arg(1); + break; + } + } else + if(func_num_args()==3) { + $Type = func_get_arg(2); + $Label = func_get_arg(1); + } else { + throw $this->newException('Wrong number of arguments to fb() function!'); + } + + + if(!$this->detectClientExtension()) { + return false; + } + + $meta = array(); + $skipFinalObjectEncode = false; + + if($Object instanceof Exception) { + + $meta['file'] = $this->_escapeTraceFile($Object->getFile()); + $meta['line'] = $Object->getLine(); + + $trace = $Object->getTrace(); + if($Object instanceof ErrorException + && isset($trace[0]['function']) + && $trace[0]['function']=='errorHandler' + && isset($trace[0]['class']) + && $trace[0]['class']=='FirePHP') { + + $severity = false; + switch($Object->getSeverity()) { + case E_WARNING: $severity = 'E_WARNING'; break; + case E_NOTICE: $severity = 'E_NOTICE'; break; + case E_USER_ERROR: $severity = 'E_USER_ERROR'; break; + case E_USER_WARNING: $severity = 'E_USER_WARNING'; break; + case E_USER_NOTICE: $severity = 'E_USER_NOTICE'; break; + case E_STRICT: $severity = 'E_STRICT'; break; + case E_RECOVERABLE_ERROR: $severity = 'E_RECOVERABLE_ERROR'; break; + case E_DEPRECATED: $severity = 'E_DEPRECATED'; break; + case E_USER_DEPRECATED: $severity = 'E_USER_DEPRECATED'; break; + } + + $Object = array('Class'=>get_class($Object), + 'Message'=>$severity.': '.$Object->getMessage(), + 'File'=>$this->_escapeTraceFile($Object->getFile()), + 'Line'=>$Object->getLine(), + 'Type'=>'trigger', + 'Trace'=>$this->_escapeTrace(array_splice($trace,2))); + $skipFinalObjectEncode = true; + } else { + $Object = array('Class'=>get_class($Object), + 'Message'=>$Object->getMessage(), + 'File'=>$this->_escapeTraceFile($Object->getFile()), + 'Line'=>$Object->getLine(), + 'Type'=>'throw', + 'Trace'=>$this->_escapeTrace($trace)); + $skipFinalObjectEncode = true; + } + $Type = self::EXCEPTION; + + } else + if($Type==self::TRACE) { + + $trace = debug_backtrace(); + if(!$trace) return false; + for( $i=0 ; $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' + || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { + /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ + } else + if(isset($trace[$i]['class']) + && isset($trace[$i+1]['file']) + && $trace[$i]['class']=='FirePHP' + && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip fb() */ + } else + if($trace[$i]['function']=='fb' + || $trace[$i]['function']=='trace' + || $trace[$i]['function']=='send') { + $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', + 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', + 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', + 'Message'=>$trace[$i]['args'][0], + 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', + 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', + 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', + 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); + + $skipFinalObjectEncode = true; + $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; + $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; + break; + } + } + + } else + if($Type==self::TABLE) { + + if(isset($Object[0]) && is_string($Object[0])) { + $Object[1] = $this->encodeTable($Object[1]); + } else { + $Object = $this->encodeTable($Object); + } + + $skipFinalObjectEncode = true; + + } else { + if($Type===null) { + $Type = self::LOG; + } + } + + if($this->options['includeLineNumbers']) { + if(!isset($meta['file']) || !isset($meta['line'])) { + + $trace = debug_backtrace(); + for( $i=0 ; $trace && $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' + || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { + /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ + } else + if(isset($trace[$i]['class']) + && isset($trace[$i+1]['file']) + && $trace[$i]['class']=='FirePHP' + && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip fb() */ + } else + if(isset($trace[$i]['file']) + && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip FB::fb() */ + } else { + $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; + $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; + break; + } + } + + } + } else { + unset($meta['file']); + unset($meta['line']); + } + + $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); + $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.self::VERSION); + + $structure_index = 1; + if($Type==self::DUMP) { + $structure_index = 2; + $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); + } else { + $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); + } + + if($Type==self::DUMP) { + $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; + } else { + $msg_meta = array('Type'=>$Type); + if($Label!==null) { + $msg_meta['Label'] = $Label; + } + if(isset($meta['file'])) { + $msg_meta['File'] = $meta['file']; + } + if(isset($meta['line'])) { + $msg_meta['Line'] = $meta['line']; + } + $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; + } + + $parts = explode("\n",chunk_split($msg, 5000, "\n")); + + for( $i=0 ; $i2) { + // Message needs to be split into multiple parts + $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, + (($i==0)?strlen($msg):'') + . '|' . $part . '|' + . (($isetHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, + strlen($part) . '|' . $part . '|'); + } + + $this->messageIndex++; + + if ($this->messageIndex > 99999) { + throw new Exception('Maximum number (99,999) of messages reached!'); + } + } + } + + $this->setHeader('X-Wf-1-Index',$this->messageIndex-1); + + return true; + } + + /** + * Standardizes path for windows systems. + * + * @param string $Path + * @return string + */ + protected function _standardizePath($Path) { + return preg_replace('/\\\\+/','/',$Path); + } + + /** + * Escape trace path for windows systems + * + * @param array $Trace + * @return array + */ + protected function _escapeTrace($Trace) { + if(!$Trace) return $Trace; + for( $i=0 ; $i_escapeTraceFile($Trace[$i]['file']); + } + if(isset($Trace[$i]['args'])) { + $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); + } + } + return $Trace; + } + + /** + * Escape file information of trace for windows systems + * + * @param string $File + * @return string + */ + protected function _escapeTraceFile($File) { + /* Check if we have a windows filepath */ + if(strpos($File,'\\')) { + /* First strip down to single \ */ + + $file = preg_replace('/\\\\+/','\\',$File); + + return $file; + } + return $File; + } + + /** + * Send header + * + * @param string $Name + * @param string_type $Value + */ + protected function setHeader($Name, $Value) { + return header($Name.': '.$Value); + } + + /** + * Get user agent + * + * @return string|false + */ + protected function getUserAgent() { + if(!isset($_SERVER['HTTP_USER_AGENT'])) return false; + return $_SERVER['HTTP_USER_AGENT']; + } + + /** + * Returns a new exception + * + * @param string $Message + * @return Exception + */ + protected function newException($Message) { + return new Exception($Message); + } + + /** + * Encode an object into a JSON string + * + * Uses PHP's jeson_encode() if available + * + * @param object $Object The object to be encoded + * @return string The JSON string + */ + protected function jsonEncode($Object, $skipObjectEncode=false) + { + if(!$skipObjectEncode) { + $Object = $this->encodeObject($Object); + } + + if(function_exists('json_encode') + && $this->options['useNativeJsonEncode']!=false) { + + return json_encode($Object); + } else { + return $this->json_encode($Object); + } + } + + /** + * Encodes a table by encoding each row and column with encodeObject() + * + * @param array $Table The table to be encoded + * @return array + */ + protected function encodeTable($Table) { + if(!$Table) return $Table; + for( $i=0 ; $iencodeObject($Table[$i][$j]); + } + } + } + return $Table; + } + + /** + * Encodes an object including members with + * protected and private visibility + * + * @param Object $Object The object to be encoded + * @param int $Depth The current traversal depth + * @return array All members of the object + */ + protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1) + { + $return = array(); + + if (is_object($Object)) { + + if ($ObjectDepth > $this->options['maxObjectDepth']) { + return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **'; + } + + foreach ($this->objectStack as $refVal) { + if ($refVal === $Object) { + return '** Recursion ('.get_class($Object).') **'; + } + } + array_push($this->objectStack, $Object); + + $return['__className'] = $class = get_class($Object); + + $reflectionClass = new ReflectionClass($class); + $properties = array(); + foreach( $reflectionClass->getProperties() as $property) { + $properties[$property->getName()] = $property; + } + + $members = (array)$Object; + + foreach( $properties as $raw_name => $property ) { + + $name = $raw_name; + if($property->isStatic()) { + $name = 'static:'.$name; + } + if($property->isPublic()) { + $name = 'public:'.$name; + } else + if($property->isPrivate()) { + $name = 'private:'.$name; + $raw_name = "\0".$class."\0".$raw_name; + } else + if($property->isProtected()) { + $name = 'protected:'.$name; + $raw_name = "\0".'*'."\0".$raw_name; + } + + if(!(isset($this->objectFilters[$class]) + && is_array($this->objectFilters[$class]) + && in_array($raw_name,$this->objectFilters[$class]))) { + + if(array_key_exists($raw_name,$members) + && !$property->isStatic()) { + + $return[$name] = $this->encodeObject($members[$raw_name], $ObjectDepth + 1, 1); + + } else { + if(method_exists($property,'setAccessible')) { + $property->setAccessible(true); + $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1); + } else + if($property->isPublic()) { + $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1); + } else { + $return[$name] = '** Need PHP 5.3 to get value **'; + } + } + } else { + $return[$name] = '** Excluded by Filter **'; + } + } + + // Include all members that are not defined in the class + // but exist in the object + foreach( $members as $raw_name => $value ) { + + $name = $raw_name; + + if ($name{0} == "\0") { + $parts = explode("\0", $name); + $name = $parts[2]; + } + + if(!isset($properties[$name])) { + $name = 'undeclared:'.$name; + + if(!(isset($this->objectFilters[$class]) + && is_array($this->objectFilters[$class]) + && in_array($raw_name,$this->objectFilters[$class]))) { + + $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1); + } else { + $return[$name] = '** Excluded by Filter **'; + } + } + } + + array_pop($this->objectStack); + + } elseif (is_array($Object)) { + + if ($ArrayDepth > $this->options['maxArrayDepth']) { + return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **'; + } + + foreach ($Object as $key => $val) { + + // Encoding the $GLOBALS PHP array causes an infinite loop + // if the recursion is not reset here as it contains + // a reference to itself. This is the only way I have come up + // with to stop infinite recursion in this case. + if($key=='GLOBALS' + && is_array($val) + && array_key_exists('GLOBALS',$val)) { + $val['GLOBALS'] = '** Recursion (GLOBALS) **'; + } + + $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1); + } + } else { + if(self::is_utf8($Object)) { + return $Object; + } else { + return utf8_encode($Object); + } + } + return $return; + } + + /** + * Returns true if $string is valid UTF-8 and false otherwise. + * + * @param mixed $str String to be tested + * @return boolean + */ + protected static function is_utf8($str) { + $c=0; $b=0; + $bits=0; + $len=strlen($str); + for($i=0; $i<$len; $i++){ + $c=ord($str[$i]); + if($c > 128){ + if(($c >= 254)) return false; + elseif($c >= 252) $bits=6; + elseif($c >= 248) $bits=5; + elseif($c >= 240) $bits=4; + elseif($c >= 224) $bits=3; + elseif($c >= 192) $bits=2; + else return false; + if(($i+$bits) > $len) return false; + while($bits > 1){ + $i++; + $b=ord($str[$i]); + if($b < 128 || $b > 191) return false; + $bits--; + } + } + } + return true; + } + + /** + * Converts to and from JSON format. + * + * JSON (JavaScript Object Notation) is a lightweight data-interchange + * format. It is easy for humans to read and write. It is easy for machines + * to parse and generate. It is based on a subset of the JavaScript + * Programming Language, Standard ECMA-262 3rd Edition - December 1999. + * This feature can also be found in Python. JSON is a text format that is + * completely language independent but uses conventions that are familiar + * to programmers of the C-family of languages, including C, C++, C#, Java, + * JavaScript, Perl, TCL, and many others. These properties make JSON an + * ideal data-interchange language. + * + * This package provides a simple encoder and decoder for JSON notation. It + * is intended for use with client-side Javascript applications that make + * use of HTTPRequest to perform server communication functions - data can + * be encoded into JSON notation for use in a client-side javascript, or + * decoded from incoming Javascript requests. JSON format is native to + * Javascript, and can be directly eval()'ed with no further parsing + * overhead + * + * All strings should be in ASCII or UTF-8 format! + * + * LICENSE: Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: Redistributions of source code must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * @category + * @package Services_JSON + * @author Michal Migurski + * @author Matt Knapp + * @author Brett Stimmerman + * @author Christoph Dorn + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + + + /** + * Keep a list of objects as we descend into the array so we can detect recursion. + */ + private $json_objectStack = array(); + + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + private function json_utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + private function json_encode($var) + { + + if(is_object($var)) { + if(in_array($var,$this->json_objectStack)) { + return '"** Recursion **"'; + } + } + + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + + $this->json_objectStack[] = $var; + + $properties = array_map(array($this, 'json_name_value'), + array_keys($var), + array_values($var)); + + array_pop($this->json_objectStack); + + foreach($properties as $property) { + if($property instanceof Exception) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + $this->json_objectStack[] = $var; + + // treat it like a regular array + $elements = array_map(array($this, 'json_encode'), $var); + + array_pop($this->json_objectStack); + + foreach($elements as $element) { + if($element instanceof Exception) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = self::encodeObject($var); + + $this->json_objectStack[] = $var; + + $properties = array_map(array($this, 'json_name_value'), + array_keys($vars), + array_values($vars)); + + array_pop($this->json_objectStack); + + foreach($properties as $property) { + if($property instanceof Exception) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return null; + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + private function json_name_value($name, $value) + { + // Encoding the $GLOBALS PHP array causes an infinite loop + // if the recursion is not reset here as it contains + // a reference to itself. This is the only way I have come up + // with to stop infinite recursion in this case. + if($name=='GLOBALS' + && is_array($value) + && array_key_exists('GLOBALS',$value)) { + $value['GLOBALS'] = '** Recursion **'; + } + + $encoded_value = $this->json_encode($value); + + if($encoded_value instanceof Exception) { + return $encoded_value; + } + + return $this->json_encode(strval($name)) . ':' . $encoded_value; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/HTTP/ConditionalGet.php b/plugins/Minify/extlib/minify/min/lib/HTTP/ConditionalGet.php new file mode 100644 index 000000000..823db058f --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/HTTP/ConditionalGet.php @@ -0,0 +1,348 @@ + + * list($updateTime, $content) = getDbUpdateAndContent(); + * $cg = new HTTP_ConditionalGet(array( + * 'lastModifiedTime' => $updateTime + * ,'isPublic' => true + * )); + * $cg->sendHeaders(); + * if ($cg->cacheIsValid) { + * exit(); + * } + * echo $content; + * + * + * E.g. Shortcut for the above + * + * HTTP_ConditionalGet::check($updateTime, true); // exits if client has cache + * echo $content; + * + * + * E.g. Content from DB with no update time: + * + * $content = getContentFromDB(); + * $cg = new HTTP_ConditionalGet(array( + * 'contentHash' => md5($content) + * )); + * $cg->sendHeaders(); + * if ($cg->cacheIsValid) { + * exit(); + * } + * echo $content; + * + * + * E.g. Static content with some static includes: + * + * // before content + * $cg = new HTTP_ConditionalGet(array( + * 'lastUpdateTime' => max( + * filemtime(__FILE__) + * ,filemtime('/path/to/header.inc') + * ,filemtime('/path/to/footer.inc') + * ) + * )); + * $cg->sendHeaders(); + * if ($cg->cacheIsValid) { + * exit(); + * } + * + * @package Minify + * @subpackage HTTP + * @author Stephen Clay + */ +class HTTP_ConditionalGet { + + /** + * Does the client have a valid copy of the requested resource? + * + * You'll want to check this after instantiating the object. If true, do + * not send content, just call sendHeaders() if you haven't already. + * + * @var bool + */ + public $cacheIsValid = null; + + /** + * @param array $spec options + * + * 'isPublic': (bool) if true, the Cache-Control header will contain + * "public", allowing proxies to cache the content. Otherwise "private" will + * be sent, allowing only browser caching. (default false) + * + * 'lastModifiedTime': (int) if given, both ETag AND Last-Modified headers + * will be sent with content. This is recommended. + * + * 'encoding': (string) if set, the header "Vary: Accept-Encoding" will + * always be sent and a truncated version of the encoding will be appended + * to the ETag. E.g. "pub123456;gz". This will also trigger a more lenient + * checking of the client's If-None-Match header, as the encoding portion of + * the ETag will be stripped before comparison. + * + * 'contentHash': (string) if given, only the ETag header can be sent with + * content (only HTTP1.1 clients can conditionally GET). The given string + * should be short with no quote characters and always change when the + * resource changes (recommend md5()). This is not needed/used if + * lastModifiedTime is given. + * + * 'eTag': (string) if given, this will be used as the ETag header rather + * than values based on lastModifiedTime or contentHash. Also the encoding + * string will not be appended to the given value as described above. + * + * 'invalidate': (bool) if true, the client cache will be considered invalid + * without testing. Effectively this disables conditional GET. + * (default false) + * + * 'maxAge': (int) if given, this will set the Cache-Control max-age in + * seconds, and also set the Expires header to the equivalent GMT date. + * After the max-age period has passed, the browser will again send a + * conditional GET to revalidate its cache. + * + * @return null + */ + public function __construct($spec) + { + $scope = (isset($spec['isPublic']) && $spec['isPublic']) + ? 'public' + : 'private'; + $maxAge = 0; + // backwards compatibility (can be removed later) + if (isset($spec['setExpires']) + && is_numeric($spec['setExpires']) + && ! isset($spec['maxAge'])) { + $spec['maxAge'] = $spec['setExpires'] - $_SERVER['REQUEST_TIME']; + } + if (isset($spec['maxAge'])) { + $maxAge = $spec['maxAge']; + $this->_headers['Expires'] = self::gmtDate( + $_SERVER['REQUEST_TIME'] + $spec['maxAge'] + ); + } + $etagAppend = ''; + if (isset($spec['encoding'])) { + $this->_stripEtag = true; + $this->_headers['Vary'] = 'Accept-Encoding'; + if ('' !== $spec['encoding']) { + if (0 === strpos($spec['encoding'], 'x-')) { + $spec['encoding'] = substr($spec['encoding'], 2); + } + $etagAppend = ';' . substr($spec['encoding'], 0, 2); + } + } + if (isset($spec['lastModifiedTime'])) { + $this->_setLastModified($spec['lastModifiedTime']); + if (isset($spec['eTag'])) { // Use it + $this->_setEtag($spec['eTag'], $scope); + } else { // base both headers on time + $this->_setEtag($spec['lastModifiedTime'] . $etagAppend, $scope); + } + } elseif (isset($spec['eTag'])) { // Use it + $this->_setEtag($spec['eTag'], $scope); + } elseif (isset($spec['contentHash'])) { // Use the hash as the ETag + $this->_setEtag($spec['contentHash'] . $etagAppend, $scope); + } + $this->_headers['Cache-Control'] = "max-age={$maxAge}, {$scope}"; + // invalidate cache if disabled, otherwise check + $this->cacheIsValid = (isset($spec['invalidate']) && $spec['invalidate']) + ? false + : $this->_isCacheValid(); + } + + /** + * Get array of output headers to be sent + * + * In the case of 304 responses, this array will only contain the response + * code header: array('_responseCode' => 'HTTP/1.0 304 Not Modified') + * + * Otherwise something like: + * + * array( + * 'Cache-Control' => 'max-age=0, public' + * ,'ETag' => '"foobar"' + * ) + * + * + * @return array + */ + public function getHeaders() + { + return $this->_headers; + } + + /** + * Set the Content-Length header in bytes + * + * With most PHP configs, as long as you don't flush() output, this method + * is not needed and PHP will buffer all output and set Content-Length for + * you. Otherwise you'll want to call this to let the client know up front. + * + * @param int $bytes + * + * @return int copy of input $bytes + */ + public function setContentLength($bytes) + { + return $this->_headers['Content-Length'] = $bytes; + } + + /** + * Send headers + * + * @see getHeaders() + * + * Note this doesn't "clear" the headers. Calling sendHeaders() will + * call header() again (but probably have not effect) and getHeaders() will + * still return the headers. + * + * @return null + */ + public function sendHeaders() + { + $headers = $this->_headers; + if (array_key_exists('_responseCode', $headers)) { + header($headers['_responseCode']); + unset($headers['_responseCode']); + } + foreach ($headers as $name => $val) { + header($name . ': ' . $val); + } + } + + /** + * Exit if the client's cache is valid for this resource + * + * This is a convenience method for common use of the class + * + * @param int $lastModifiedTime if given, both ETag AND Last-Modified headers + * will be sent with content. This is recommended. + * + * @param bool $isPublic (default false) if true, the Cache-Control header + * will contain "public", allowing proxies to cache the content. Otherwise + * "private" will be sent, allowing only browser caching. + * + * @param array $options (default empty) additional options for constructor + * + * @return null + */ + public static function check($lastModifiedTime = null, $isPublic = false, $options = array()) + { + if (null !== $lastModifiedTime) { + $options['lastModifiedTime'] = (int)$lastModifiedTime; + } + $options['isPublic'] = (bool)$isPublic; + $cg = new HTTP_ConditionalGet($options); + $cg->sendHeaders(); + if ($cg->cacheIsValid) { + exit(); + } + } + + + /** + * Get a GMT formatted date for use in HTTP headers + * + * + * header('Expires: ' . HTTP_ConditionalGet::gmtdate($time)); + * + * + * @param int $time unix timestamp + * + * @return string + */ + public static function gmtDate($time) + { + return gmdate('D, d M Y H:i:s \G\M\T', $time); + } + + protected $_headers = array(); + protected $_lmTime = null; + protected $_etag = null; + protected $_stripEtag = false; + + protected function _setEtag($hash, $scope) + { + $this->_etag = '"' . substr($scope, 0, 3) . $hash . '"'; + $this->_headers['ETag'] = $this->_etag; + } + + protected function _setLastModified($time) + { + $this->_lmTime = (int)$time; + $this->_headers['Last-Modified'] = self::gmtDate($time); + } + + /** + * Determine validity of client cache and queue 304 header if valid + */ + protected function _isCacheValid() + { + if (null === $this->_etag) { + // lmTime is copied to ETag, so this condition implies that the + // server sent neither ETag nor Last-Modified, so the client can't + // possibly has a valid cache. + return false; + } + $isValid = ($this->resourceMatchedEtag() || $this->resourceNotModified()); + if ($isValid) { + $this->_headers['_responseCode'] = 'HTTP/1.0 304 Not Modified'; + } + return $isValid; + } + + protected function resourceMatchedEtag() + { + if (!isset($_SERVER['HTTP_IF_NONE_MATCH'])) { + return false; + } + $clientEtagList = get_magic_quotes_gpc() + ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) + : $_SERVER['HTTP_IF_NONE_MATCH']; + $clientEtags = explode(',', $clientEtagList); + + $compareTo = $this->normalizeEtag($this->_etag); + foreach ($clientEtags as $clientEtag) { + if ($this->normalizeEtag($clientEtag) === $compareTo) { + // respond with the client's matched ETag, even if it's not what + // we would've sent by default + $this->_headers['ETag'] = trim($clientEtag); + return true; + } + } + return false; + } + + protected function normalizeEtag($etag) { + $etag = trim($etag); + return $this->_stripEtag + ? preg_replace('/;\\w\\w"$/', '"', $etag) + : $etag; + } + + protected function resourceNotModified() + { + if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { + return false; + } + $ifModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE']; + if (false !== ($semicolon = strrpos($ifModifiedSince, ';'))) { + // IE has tacked on extra data to this header, strip it + $ifModifiedSince = substr($ifModifiedSince, 0, $semicolon); + } + if ($ifModifiedSince == self::gmtDate($this->_lmTime)) { + // Apache 2.2's behavior. If there was no ETag match, send the + // non-encoded version of the ETag value. + $this->_headers['ETag'] = $this->normalizeEtag($this->_etag); + return true; + } + return false; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/HTTP/Encoder.php b/plugins/Minify/extlib/minify/min/lib/HTTP/Encoder.php new file mode 100644 index 000000000..66c26789c --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/HTTP/Encoder.php @@ -0,0 +1,326 @@ + + * // Send a CSS file, compressed if possible + * $he = new HTTP_Encoder(array( + * 'content' => file_get_contents($cssFile) + * ,'type' => 'text/css' + * )); + * $he->encode(); + * $he->sendAll(); + * + * + * + * // Shortcut to encoding output + * header('Content-Type: text/css'); // needed if not HTML + * HTTP_Encoder::output($css); + * + * + * + * // Just sniff for the accepted encoding + * $encoding = HTTP_Encoder::getAcceptedEncoding(); + * + * + * For more control over headers, use getHeaders() and getData() and send your + * own output. + * + * Note: If you don't need header mgmt, use PHP's native gzencode, gzdeflate, + * and gzcompress functions for gzip, deflate, and compress-encoding + * respectively. + * + * @package Minify + * @subpackage HTTP + * @author Stephen Clay + */ +class HTTP_Encoder { + + /** + * Should the encoder allow HTTP encoding to IE6? + * + * If you have many IE6 users and the bandwidth savings is worth troubling + * some of them, set this to true. + * + * By default, encoding is only offered to IE7+. When this is true, + * getAcceptedEncoding() will return an encoding for IE6 if its user agent + * string contains "SV1". This has been documented in many places as "safe", + * but there seem to be remaining, intermittent encoding bugs in patched + * IE6 on the wild web. + * + * @var bool + */ + public static $encodeToIe6 = false; + + + /** + * Default compression level for zlib operations + * + * This level is used if encode() is not given a $compressionLevel + * + * @var int + */ + public static $compressionLevel = 6; + + + /** + * Get an HTTP Encoder object + * + * @param array $spec options + * + * 'content': (string required) content to be encoded + * + * 'type': (string) if set, the Content-Type header will have this value. + * + * 'method: (string) only set this if you are forcing a particular encoding + * method. If not set, the best method will be chosen by getAcceptedEncoding() + * The available methods are 'gzip', 'deflate', 'compress', and '' (no + * encoding) + * + * @return null + */ + public function __construct($spec) + { + $this->_content = $spec['content']; + $this->_headers['Content-Length'] = (string)strlen($this->_content); + if (isset($spec['type'])) { + $this->_headers['Content-Type'] = $spec['type']; + } + if (isset($spec['method']) + && in_array($spec['method'], array('gzip', 'deflate', 'compress', ''))) + { + $this->_encodeMethod = array($spec['method'], $spec['method']); + } else { + $this->_encodeMethod = self::getAcceptedEncoding(); + } + } + + /** + * Get content in current form + * + * Call after encode() for encoded content. + * + * return string + */ + public function getContent() + { + return $this->_content; + } + + /** + * Get array of output headers to be sent + * + * E.g. + * + * array( + * 'Content-Length' => '615' + * ,'Content-Encoding' => 'x-gzip' + * ,'Vary' => 'Accept-Encoding' + * ) + * + * + * @return array + */ + public function getHeaders() + { + return $this->_headers; + } + + /** + * Send output headers + * + * You must call this before headers are sent and it probably cannot be + * used in conjunction with zlib output buffering / mod_gzip. Errors are + * not handled purposefully. + * + * @see getHeaders() + * + * @return null + */ + public function sendHeaders() + { + foreach ($this->_headers as $name => $val) { + header($name . ': ' . $val); + } + } + + /** + * Send output headers and content + * + * A shortcut for sendHeaders() and echo getContent() + * + * You must call this before headers are sent and it probably cannot be + * used in conjunction with zlib output buffering / mod_gzip. Errors are + * not handled purposefully. + * + * @return null + */ + public function sendAll() + { + $this->sendHeaders(); + echo $this->_content; + } + + /** + * Determine the client's best encoding method from the HTTP Accept-Encoding + * header. + * + * If no Accept-Encoding header is set, or the browser is IE before v6 SP2, + * this will return ('', ''), the "identity" encoding. + * + * A syntax-aware scan is done of the Accept-Encoding, so the method must + * be non 0. The methods are favored in order of gzip, deflate, then + * compress. Deflate is always smallest and generally faster, but is + * rarely sent by servers, so client support could be buggier. + * + * @param bool $allowCompress allow the older compress encoding + * + * @param bool $allowDeflate allow the more recent deflate encoding + * + * @return array two values, 1st is the actual encoding method, 2nd is the + * alias of that method to use in the Content-Encoding header (some browsers + * call gzip "x-gzip" etc.) + */ + public static function getAcceptedEncoding($allowCompress = true, $allowDeflate = true) + { + // @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html + + if (! isset($_SERVER['HTTP_ACCEPT_ENCODING']) + || self::_isBuggyIe()) + { + return array('', ''); + } + $ae = $_SERVER['HTTP_ACCEPT_ENCODING']; + // gzip checks (quick) + if (0 === strpos($ae, 'gzip,') // most browsers + || 0 === strpos($ae, 'deflate, gzip,') // opera + ) { + return array('gzip', 'gzip'); + } + // gzip checks (slow) + if (preg_match( + '@(?:^|,)\\s*((?:x-)?gzip)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@' + ,$ae + ,$m)) { + return array('gzip', $m[1]); + } + if ($allowDeflate) { + // deflate checks + $aeRev = strrev($ae); + if (0 === strpos($aeRev, 'etalfed ,') // ie, webkit + || 0 === strpos($aeRev, 'etalfed,') // gecko + || 0 === strpos($ae, 'deflate,') // opera + // slow parsing + || preg_match( + '@(?:^|,)\\s*deflate\\s*(?:$|,|;\\s*q=(?:0\\.|1))@', $ae)) { + return array('deflate', 'deflate'); + } + } + if ($allowCompress && preg_match( + '@(?:^|,)\\s*((?:x-)?compress)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@' + ,$ae + ,$m)) { + return array('compress', $m[1]); + } + return array('', ''); + } + + /** + * Encode (compress) the content + * + * If the encode method is '' (none) or compression level is 0, or the 'zlib' + * extension isn't loaded, we return false. + * + * Then the appropriate gz_* function is called to compress the content. If + * this fails, false is returned. + * + * The header "Vary: Accept-Encoding" is added. If encoding is successful, + * the Content-Length header is updated, and Content-Encoding is also added. + * + * @param int $compressionLevel given to zlib functions. If not given, the + * class default will be used. + * + * @return bool success true if the content was actually compressed + */ + public function encode($compressionLevel = null) + { + $this->_headers['Vary'] = 'Accept-Encoding'; + if (null === $compressionLevel) { + $compressionLevel = self::$compressionLevel; + } + if ('' === $this->_encodeMethod[0] + || ($compressionLevel == 0) + || !extension_loaded('zlib')) + { + return false; + } + if ($this->_encodeMethod[0] === 'deflate') { + $encoded = gzdeflate($this->_content, $compressionLevel); + } elseif ($this->_encodeMethod[0] === 'gzip') { + $encoded = gzencode($this->_content, $compressionLevel); + } else { + $encoded = gzcompress($this->_content, $compressionLevel); + } + if (false === $encoded) { + return false; + } + $this->_headers['Content-Length'] = strlen($encoded); + $this->_headers['Content-Encoding'] = $this->_encodeMethod[1]; + $this->_content = $encoded; + return true; + } + + /** + * Encode and send appropriate headers and content + * + * This is a convenience method for common use of the class + * + * @param string $content + * + * @param int $compressionLevel given to zlib functions. If not given, the + * class default will be used. + * + * @return bool success true if the content was actually compressed + */ + public static function output($content, $compressionLevel = null) + { + if (null === $compressionLevel) { + $compressionLevel = self::$compressionLevel; + } + $he = new HTTP_Encoder(array('content' => $content)); + $ret = $he->encode($compressionLevel); + $he->sendAll(); + return $ret; + } + + protected $_content = ''; + protected $_headers = array(); + protected $_encodeMethod = array('', ''); + + /** + * Is the browser an IE version earlier than 6 SP2? + */ + protected static function _isBuggyIe() + { + $ua = $_SERVER['HTTP_USER_AGENT']; + // quick escape for non-IEs + if (0 !== strpos($ua, 'Mozilla/4.0 (compatible; MSIE ') + || false !== strpos($ua, 'Opera')) { + return false; + } + // no regex = faaast + $version = (float)substr($ua, 30); + return self::$encodeToIe6 + ? ($version < 6 || ($version == 6 && false === strpos($ua, 'SV1'))) + : ($version < 7); + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/JSMin.php b/plugins/Minify/extlib/minify/min/lib/JSMin.php new file mode 100644 index 000000000..770e1c610 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/JSMin.php @@ -0,0 +1,314 @@ + (PHP port) + * @author Steve Clay (modifications + cleanup) + * @author Andrea Giammarchi (spaceBeforeRegExp) + * @copyright 2002 Douglas Crockford (jsmin.c) + * @copyright 2008 Ryan Grove (PHP port) + * @license http://opensource.org/licenses/mit-license.php MIT License + * @link http://code.google.com/p/jsmin-php/ + */ + +class JSMin { + const ORD_LF = 10; + const ORD_SPACE = 32; + const ACTION_KEEP_A = 1; + const ACTION_DELETE_A = 2; + const ACTION_DELETE_A_B = 3; + + protected $a = "\n"; + protected $b = ''; + protected $input = ''; + protected $inputIndex = 0; + protected $inputLength = 0; + protected $lookAhead = null; + protected $output = ''; + + /** + * Minify Javascript + * + * @param string $js Javascript to be minified + * @return string + */ + public static function minify($js) + { + $jsmin = new JSMin($js); + return $jsmin->min(); + } + + /** + * Setup process + */ + public function __construct($input) + { + $this->input = str_replace("\r\n", "\n", $input); + $this->inputLength = strlen($this->input); + } + + /** + * Perform minification, return result + */ + public function min() + { + if ($this->output !== '') { // min already run + return $this->output; + } + $this->action(self::ACTION_DELETE_A_B); + + while ($this->a !== null) { + // determine next command + $command = self::ACTION_KEEP_A; // default + if ($this->a === ' ') { + if (! $this->isAlphaNum($this->b)) { + $command = self::ACTION_DELETE_A; + } + } elseif ($this->a === "\n") { + if ($this->b === ' ') { + $command = self::ACTION_DELETE_A_B; + } elseif (false === strpos('{[(+-', $this->b) + && ! $this->isAlphaNum($this->b)) { + $command = self::ACTION_DELETE_A; + } + } elseif (! $this->isAlphaNum($this->a)) { + if ($this->b === ' ' + || ($this->b === "\n" + && (false === strpos('}])+-"\'', $this->a)))) { + $command = self::ACTION_DELETE_A_B; + } + } + $this->action($command); + } + $this->output = trim($this->output); + return $this->output; + } + + /** + * ACTION_KEEP_A = Output A. Copy B to A. Get the next B. + * ACTION_DELETE_A = Copy B to A. Get the next B. + * ACTION_DELETE_A_B = Get the next B. + */ + protected function action($command) + { + switch ($command) { + case self::ACTION_KEEP_A: + $this->output .= $this->a; + // fallthrough + case self::ACTION_DELETE_A: + $this->a = $this->b; + if ($this->a === "'" || $this->a === '"') { // string literal + $str = $this->a; // in case needed for exception + while (true) { + $this->output .= $this->a; + $this->a = $this->get(); + if ($this->a === $this->b) { // end quote + break; + } + if (ord($this->a) <= self::ORD_LF) { + throw new JSMin_UnterminatedStringException( + 'Unterminated String: ' . var_export($str, true)); + } + $str .= $this->a; + if ($this->a === '\\') { + $this->output .= $this->a; + $this->a = $this->get(); + $str .= $this->a; + } + } + } + // fallthrough + case self::ACTION_DELETE_A_B: + $this->b = $this->next(); + if ($this->b === '/' && $this->isRegexpLiteral()) { // RegExp literal + $this->output .= $this->a . $this->b; + $pattern = '/'; // in case needed for exception + while (true) { + $this->a = $this->get(); + $pattern .= $this->a; + if ($this->a === '/') { // end pattern + break; // while (true) + } elseif ($this->a === '\\') { + $this->output .= $this->a; + $this->a = $this->get(); + $pattern .= $this->a; + } elseif (ord($this->a) <= self::ORD_LF) { + throw new JSMin_UnterminatedRegExpException( + 'Unterminated RegExp: '. var_export($pattern, true)); + } + $this->output .= $this->a; + } + $this->b = $this->next(); + } + // end case ACTION_DELETE_A_B + } + } + + protected function isRegexpLiteral() + { + if (false !== strpos("\n{;(,=:[!&|?", $this->a)) { // we aren't dividing + return true; + } + if (' ' === $this->a) { + $length = strlen($this->output); + if ($length < 2) { // weird edge case + return true; + } + // you can't divide a keyword + if (preg_match('/(?:case|else|in|return|typeof)$/', $this->output, $m)) { + if ($this->output === $m[0]) { // odd but could happen + return true; + } + // make sure it's a keyword, not end of an identifier + $charBeforeKeyword = substr($this->output, $length - strlen($m[0]) - 1, 1); + if (! $this->isAlphaNum($charBeforeKeyword)) { + return true; + } + } + } + return false; + } + + /** + * Get next char. Convert ctrl char to space. + */ + protected function get() + { + $c = $this->lookAhead; + $this->lookAhead = null; + if ($c === null) { + if ($this->inputIndex < $this->inputLength) { + $c = $this->input[$this->inputIndex]; + $this->inputIndex += 1; + } else { + return null; + } + } + if ($c === "\r" || $c === "\n") { + return "\n"; + } + if (ord($c) < self::ORD_SPACE) { // control char + return ' '; + } + return $c; + } + + /** + * Get next char. If is ctrl character, translate to a space or newline. + */ + protected function peek() + { + $this->lookAhead = $this->get(); + return $this->lookAhead; + } + + /** + * Is $c a letter, digit, underscore, dollar sign, escape, or non-ASCII? + */ + protected function isAlphaNum($c) + { + return (preg_match('/^[0-9a-zA-Z_\\$\\\\]$/', $c) || ord($c) > 126); + } + + protected function singleLineComment() + { + $comment = ''; + while (true) { + $get = $this->get(); + $comment .= $get; + if (ord($get) <= self::ORD_LF) { // EOL reached + // if IE conditional comment + if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment)) { + return "/{$comment}"; + } + return $get; + } + } + } + + protected function multipleLineComment() + { + $this->get(); + $comment = ''; + while (true) { + $get = $this->get(); + if ($get === '*') { + if ($this->peek() === '/') { // end of comment reached + $this->get(); + // if comment preserved by YUI Compressor + if (0 === strpos($comment, '!')) { + return "\n/*" . substr($comment, 1) . "*/\n"; + } + // if IE conditional comment + if (preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment)) { + return "/*{$comment}*/"; + } + return ' '; + } + } elseif ($get === null) { + throw new JSMin_UnterminatedCommentException('Unterminated Comment: ' . var_export('/*' . $comment, true)); + } + $comment .= $get; + } + } + + /** + * Get the next character, skipping over comments. + * Some comments may be preserved. + */ + protected function next() + { + $get = $this->get(); + if ($get !== '/') { + return $get; + } + switch ($this->peek()) { + case '/': return $this->singleLineComment(); + case '*': return $this->multipleLineComment(); + default: return $get; + } + } +} + +class JSMin_UnterminatedStringException extends Exception {} +class JSMin_UnterminatedCommentException extends Exception {} +class JSMin_UnterminatedRegExpException extends Exception {} diff --git a/plugins/Minify/extlib/minify/min/lib/JSMinPlus.php b/plugins/Minify/extlib/minify/min/lib/JSMinPlus.php new file mode 100644 index 000000000..31a1a5cb4 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/JSMinPlus.php @@ -0,0 +1,1872 @@ + + * + * Usage: $minified = JSMinPlus::minify($script [, $filename]) + * + * Versionlog (see also changelog.txt): + * 12-04-2009 - some small bugfixes and performance improvements + * 09-04-2009 - initial open sourced version 1.0 + * + * Latest version of this script: http://files.tweakers.net/jsminplus/jsminplus.zip + * + */ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Tino Zijdel + * PHP port, modifications and minifier routine are (C) 2009 + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define('TOKEN_END', 1); +define('TOKEN_NUMBER', 2); +define('TOKEN_IDENTIFIER', 3); +define('TOKEN_STRING', 4); +define('TOKEN_REGEXP', 5); +define('TOKEN_NEWLINE', 6); +define('TOKEN_CONDCOMMENT_MULTILINE', 7); + +define('JS_SCRIPT', 100); +define('JS_BLOCK', 101); +define('JS_LABEL', 102); +define('JS_FOR_IN', 103); +define('JS_CALL', 104); +define('JS_NEW_WITH_ARGS', 105); +define('JS_INDEX', 106); +define('JS_ARRAY_INIT', 107); +define('JS_OBJECT_INIT', 108); +define('JS_PROPERTY_INIT', 109); +define('JS_GETTER', 110); +define('JS_SETTER', 111); +define('JS_GROUP', 112); +define('JS_LIST', 113); + +define('DECLARED_FORM', 0); +define('EXPRESSED_FORM', 1); +define('STATEMENT_FORM', 2); + +class JSMinPlus +{ + private $parser; + private $reserved = array( + 'break', 'case', 'catch', 'continue', 'default', 'delete', 'do', + 'else', 'finally', 'for', 'function', 'if', 'in', 'instanceof', + 'new', 'return', 'switch', 'this', 'throw', 'try', 'typeof', 'var', + 'void', 'while', 'with', + // Words reserved for future use + 'abstract', 'boolean', 'byte', 'char', 'class', 'const', 'debugger', + 'double', 'enum', 'export', 'extends', 'final', 'float', 'goto', + 'implements', 'import', 'int', 'interface', 'long', 'native', + 'package', 'private', 'protected', 'public', 'short', 'static', + 'super', 'synchronized', 'throws', 'transient', 'volatile', + // These are not reserved, but should be taken into account + // in isValidIdentifier (See jslint source code) + 'arguments', 'eval', 'true', 'false', 'Infinity', 'NaN', 'null', 'undefined' + ); + + private function __construct() + { + $this->parser = new JSParser(); + } + + public static function minify($js, $filename='') + { + static $instance; + + // this is a singleton + if(!$instance) + $instance = new JSMinPlus(); + + return $instance->min($js, $filename); + } + + private function min($js, $filename) + { + try + { + $n = $this->parser->parse($js, $filename, 1); + return $this->parseTree($n); + } + catch(Exception $e) + { + echo $e->getMessage() . "\n"; + } + + return false; + } + + private function parseTree($n, $noBlockGrouping = false) + { + $s = ''; + + switch ($n->type) + { + case KEYWORD_FUNCTION: + $s .= 'function' . ($n->name ? ' ' . $n->name : '') . '('; + $params = $n->params; + for ($i = 0, $j = count($params); $i < $j; $i++) + $s .= ($i ? ',' : '') . $params[$i]; + $s .= '){' . $this->parseTree($n->body, true) . '}'; + break; + + case JS_SCRIPT: + // we do nothing with funDecls or varDecls + $noBlockGrouping = true; + // fall through + case JS_BLOCK: + $childs = $n->treeNodes; + for ($c = 0, $i = 0, $j = count($childs); $i < $j; $i++) + { + $t = $this->parseTree($childs[$i]); + if (strlen($t)) + { + if ($c) + { + if ($childs[$i]->type == KEYWORD_FUNCTION && $childs[$i]->functionForm == DECLARED_FORM) + $s .= "\n"; // put declared functions on a new line + else + $s .= ';'; + } + + $s .= $t; + + $c++; + } + } + + if ($c > 1 && !$noBlockGrouping) + { + $s = '{' . $s . '}'; + } + break; + + case KEYWORD_IF: + $s = 'if(' . $this->parseTree($n->condition) . ')'; + $thenPart = $this->parseTree($n->thenPart); + $elsePart = $n->elsePart ? $this->parseTree($n->elsePart) : null; + + // quite a rancid hack to see if we should enclose the thenpart in brackets + if ($thenPart[0] != '{') + { + if (strpos($thenPart, 'if(') !== false) + $thenPart = '{' . $thenPart . '}'; + elseif ($elsePart) + $thenPart .= ';'; + } + + $s .= $thenPart; + + if ($elsePart) + { + $s .= 'else'; + + if ($elsePart[0] != '{') + $s .= ' '; + + $s .= $elsePart; + } + break; + + case KEYWORD_SWITCH: + $s = 'switch(' . $this->parseTree($n->discriminant) . '){'; + $cases = $n->cases; + for ($i = 0, $j = count($cases); $i < $j; $i++) + { + $case = $cases[$i]; + if ($case->type == KEYWORD_CASE) + $s .= 'case' . ($case->caseLabel->type != TOKEN_STRING ? ' ' : '') . $this->parseTree($case->caseLabel) . ':'; + else + $s .= 'default:'; + + $statement = $this->parseTree($case->statements); + if ($statement) + $s .= $statement . ';'; + } + $s = rtrim($s, ';') . '}'; + break; + + case KEYWORD_FOR: + $s = 'for(' . ($n->setup ? $this->parseTree($n->setup) : '') + . ';' . ($n->condition ? $this->parseTree($n->condition) : '') + . ';' . ($n->update ? $this->parseTree($n->update) : '') . ')' + . $this->parseTree($n->body); + break; + + case KEYWORD_WHILE: + $s = 'while(' . $this->parseTree($n->condition) . ')' . $this->parseTree($n->body); + break; + + case JS_FOR_IN: + $s = 'for(' . ($n->varDecl ? $this->parseTree($n->varDecl) : $this->parseTree($n->iterator)) . ' in ' . $this->parseTree($n->object) . ')' . $this->parseTree($n->body); + break; + + case KEYWORD_DO: + $s = 'do{' . $this->parseTree($n->body, true) . '}while(' . $this->parseTree($n->condition) . ')'; + break; + + case KEYWORD_BREAK: + case KEYWORD_CONTINUE: + $s = $n->value . ($n->label ? ' ' . $n->label : ''); + break; + + case KEYWORD_TRY: + $s = 'try{' . $this->parseTree($n->tryBlock, true) . '}'; + $catchClauses = $n->catchClauses; + for ($i = 0, $j = count($catchClauses); $i < $j; $i++) + { + $t = $catchClauses[$i]; + $s .= 'catch(' . $t->varName . ($t->guard ? ' if ' . $this->parseTree($t->guard) : '') . '){' . $this->parseTree($t->block, true) . '}'; + } + if ($n->finallyBlock) + $s .= 'finally{' . $this->parseTree($n->finallyBlock, true) . '}'; + break; + + case KEYWORD_THROW: + $s = 'throw ' . $this->parseTree($n->exception); + break; + + case KEYWORD_RETURN: + $s = 'return' . ($n->value ? ' ' . $this->parseTree($n->value) : ''); + break; + + case KEYWORD_WITH: + $s = 'with(' . $this->parseTree($n->object) . ')' . $this->parseTree($n->body); + break; + + case KEYWORD_VAR: + case KEYWORD_CONST: + $s = $n->value . ' '; + $childs = $n->treeNodes; + for ($i = 0, $j = count($childs); $i < $j; $i++) + { + $t = $childs[$i]; + $s .= ($i ? ',' : '') . $t->name; + $u = $t->initializer; + if ($u) + $s .= '=' . $this->parseTree($u); + } + break; + + case KEYWORD_DEBUGGER: + throw new Exception('NOT IMPLEMENTED: DEBUGGER'); + break; + + case TOKEN_CONDCOMMENT_MULTILINE: + $s = $n->value . ' '; + $childs = $n->treeNodes; + for ($i = 0, $j = count($childs); $i < $j; $i++) + $s .= $this->parseTree($childs[$i]); + break; + + case OP_SEMICOLON: + if ($expression = $n->expression) + $s = $this->parseTree($expression); + break; + + case JS_LABEL: + $s = $n->label . ':' . $this->parseTree($n->statement); + break; + + case OP_COMMA: + $childs = $n->treeNodes; + for ($i = 0, $j = count($childs); $i < $j; $i++) + $s .= ($i ? ',' : '') . $this->parseTree($childs[$i]); + break; + + case OP_ASSIGN: + $s = $this->parseTree($n->treeNodes[0]) . $n->value . $this->parseTree($n->treeNodes[1]); + break; + + case OP_HOOK: + $s = $this->parseTree($n->treeNodes[0]) . '?' . $this->parseTree($n->treeNodes[1]) . ':' . $this->parseTree($n->treeNodes[2]); + break; + + case OP_OR: case OP_AND: + case OP_BITWISE_OR: case OP_BITWISE_XOR: case OP_BITWISE_AND: + case OP_EQ: case OP_NE: case OP_STRICT_EQ: case OP_STRICT_NE: + case OP_LT: case OP_LE: case OP_GE: case OP_GT: + case OP_LSH: case OP_RSH: case OP_URSH: + case OP_MUL: case OP_DIV: case OP_MOD: + $s = $this->parseTree($n->treeNodes[0]) . $n->type . $this->parseTree($n->treeNodes[1]); + break; + + case OP_PLUS: + case OP_MINUS: + $s = $this->parseTree($n->treeNodes[0]) . $n->type; + $nextTokenType = $n->treeNodes[1]->type; + if ( $nextTokenType == OP_PLUS || $nextTokenType == OP_MINUS || + $nextTokenType == OP_INCREMENT || $nextTokenType == OP_DECREMENT || + $nextTokenType == OP_UNARY_PLUS || $nextTokenType == OP_UNARY_MINUS + ) + $s .= ' '; + $s .= $this->parseTree($n->treeNodes[1]); + break; + + case KEYWORD_IN: + $s = $this->parseTree($n->treeNodes[0]) . ' in ' . $this->parseTree($n->treeNodes[1]); + break; + + case KEYWORD_INSTANCEOF: + $s = $this->parseTree($n->treeNodes[0]) . ' instanceof ' . $this->parseTree($n->treeNodes[1]); + break; + + case KEYWORD_DELETE: + $s = 'delete ' . $this->parseTree($n->treeNodes[0]); + break; + + case KEYWORD_VOID: + $s = 'void(' . $this->parseTree($n->treeNodes[0]) . ')'; + break; + + case KEYWORD_TYPEOF: + $s = 'typeof ' . $this->parseTree($n->treeNodes[0]); + break; + + case OP_NOT: + case OP_BITWISE_NOT: + case OP_UNARY_PLUS: + case OP_UNARY_MINUS: + $s = $n->value . $this->parseTree($n->treeNodes[0]); + break; + + case OP_INCREMENT: + case OP_DECREMENT: + if ($n->postfix) + $s = $this->parseTree($n->treeNodes[0]) . $n->value; + else + $s = $n->value . $this->parseTree($n->treeNodes[0]); + break; + + case OP_DOT: + $s = $this->parseTree($n->treeNodes[0]) . '.' . $this->parseTree($n->treeNodes[1]); + break; + + case JS_INDEX: + $s = $this->parseTree($n->treeNodes[0]); + // See if we can replace named index with a dot saving 3 bytes + if ( $n->treeNodes[0]->type == TOKEN_IDENTIFIER && + $n->treeNodes[1]->type == TOKEN_STRING && + $this->isValidIdentifier(substr($n->treeNodes[1]->value, 1, -1)) + ) + $s .= '.' . substr($n->treeNodes[1]->value, 1, -1); + else + $s .= '[' . $this->parseTree($n->treeNodes[1]) . ']'; + break; + + case JS_LIST: + $childs = $n->treeNodes; + for ($i = 0, $j = count($childs); $i < $j; $i++) + $s .= ($i ? ',' : '') . $this->parseTree($childs[$i]); + break; + + case JS_CALL: + $s = $this->parseTree($n->treeNodes[0]) . '(' . $this->parseTree($n->treeNodes[1]) . ')'; + break; + + case KEYWORD_NEW: + case JS_NEW_WITH_ARGS: + $s = 'new ' . $this->parseTree($n->treeNodes[0]) . '(' . ($n->type == JS_NEW_WITH_ARGS ? $this->parseTree($n->treeNodes[1]) : '') . ')'; + break; + + case JS_ARRAY_INIT: + $s = '['; + $childs = $n->treeNodes; + for ($i = 0, $j = count($childs); $i < $j; $i++) + { + $s .= ($i ? ',' : '') . $this->parseTree($childs[$i]); + } + $s .= ']'; + break; + + case JS_OBJECT_INIT: + $s = '{'; + $childs = $n->treeNodes; + for ($i = 0, $j = count($childs); $i < $j; $i++) + { + $t = $childs[$i]; + if ($i) + $s .= ','; + if ($t->type == JS_PROPERTY_INIT) + { + // Ditch the quotes when the index is a valid identifier + if ( $t->treeNodes[0]->type == TOKEN_STRING && + $this->isValidIdentifier(substr($t->treeNodes[0]->value, 1, -1)) + ) + $s .= substr($t->treeNodes[0]->value, 1, -1); + else + $s .= $t->treeNodes[0]->value; + + $s .= ':' . $this->parseTree($t->treeNodes[1]); + } + else + { + $s .= $t->type == JS_GETTER ? 'get' : 'set'; + $s .= ' ' . $t->name . '('; + $params = $t->params; + for ($i = 0, $j = count($params); $i < $j; $i++) + $s .= ($i ? ',' : '') . $params[$i]; + $s .= '){' . $this->parseTree($t->body, true) . '}'; + } + } + $s .= '}'; + break; + + case KEYWORD_NULL: case KEYWORD_THIS: case KEYWORD_TRUE: case KEYWORD_FALSE: + case TOKEN_IDENTIFIER: case TOKEN_NUMBER: case TOKEN_STRING: case TOKEN_REGEXP: + $s = $n->value; + break; + + case JS_GROUP: + $s = '(' . $this->parseTree($n->treeNodes[0]) . ')'; + break; + + default: + throw new Exception('UNKNOWN TOKEN TYPE: ' . $n->type); + } + + return $s; + } + + private function isValidIdentifier($string) + { + return preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $string) && !in_array($string, $this->reserved); + } +} + +class JSParser +{ + private $t; + + private $opPrecedence = array( + ';' => 0, + ',' => 1, + '=' => 2, '?' => 2, ':' => 2, + // The above all have to have the same precedence, see bug 330975. + '||' => 4, + '&&' => 5, + '|' => 6, + '^' => 7, + '&' => 8, + '==' => 9, '!=' => 9, '===' => 9, '!==' => 9, + '<' => 10, '<=' => 10, '>=' => 10, '>' => 10, 'in' => 10, 'instanceof' => 10, + '<<' => 11, '>>' => 11, '>>>' => 11, + '+' => 12, '-' => 12, + '*' => 13, '/' => 13, '%' => 13, + 'delete' => 14, 'void' => 14, 'typeof' => 14, + '!' => 14, '~' => 14, 'U+' => 14, 'U-' => 14, + '++' => 15, '--' => 15, + 'new' => 16, + '.' => 17, + JS_NEW_WITH_ARGS => 0, JS_INDEX => 0, JS_CALL => 0, + JS_ARRAY_INIT => 0, JS_OBJECT_INIT => 0, JS_GROUP => 0 + ); + + private $opArity = array( + ',' => -2, + '=' => 2, + '?' => 3, + '||' => 2, + '&&' => 2, + '|' => 2, + '^' => 2, + '&' => 2, + '==' => 2, '!=' => 2, '===' => 2, '!==' => 2, + '<' => 2, '<=' => 2, '>=' => 2, '>' => 2, 'in' => 2, 'instanceof' => 2, + '<<' => 2, '>>' => 2, '>>>' => 2, + '+' => 2, '-' => 2, + '*' => 2, '/' => 2, '%' => 2, + 'delete' => 1, 'void' => 1, 'typeof' => 1, + '!' => 1, '~' => 1, 'U+' => 1, 'U-' => 1, + '++' => 1, '--' => 1, + 'new' => 1, + '.' => 2, + JS_NEW_WITH_ARGS => 2, JS_INDEX => 2, JS_CALL => 2, + JS_ARRAY_INIT => 1, JS_OBJECT_INIT => 1, JS_GROUP => 1, + TOKEN_CONDCOMMENT_MULTILINE => 1 + ); + + public function __construct() + { + $this->t = new JSTokenizer(); + } + + public function parse($s, $f, $l) + { + // initialize tokenizer + $this->t->init($s, $f, $l); + + $x = new JSCompilerContext(false); + $n = $this->Script($x); + if (!$this->t->isDone()) + throw $this->t->newSyntaxError('Syntax error'); + + return $n; + } + + private function Script($x) + { + $n = $this->Statements($x); + $n->type = JS_SCRIPT; + $n->funDecls = $x->funDecls; + $n->varDecls = $x->varDecls; + + return $n; + } + + private function Statements($x) + { + $n = new JSNode($this->t, JS_BLOCK); + array_push($x->stmtStack, $n); + + while (!$this->t->isDone() && $this->t->peek() != OP_RIGHT_CURLY) + $n->addNode($this->Statement($x)); + + array_pop($x->stmtStack); + + return $n; + } + + private function Block($x) + { + $this->t->mustMatch(OP_LEFT_CURLY); + $n = $this->Statements($x); + $this->t->mustMatch(OP_RIGHT_CURLY); + + return $n; + } + + private function Statement($x) + { + $tt = $this->t->get(); + $n2 = null; + + // Cases for statements ending in a right curly return early, avoiding the + // common semicolon insertion magic after this switch. + switch ($tt) + { + case KEYWORD_FUNCTION: + return $this->FunctionDefinition( + $x, + true, + count($x->stmtStack) > 1 ? STATEMENT_FORM : DECLARED_FORM + ); + break; + + case OP_LEFT_CURLY: + $n = $this->Statements($x); + $this->t->mustMatch(OP_RIGHT_CURLY); + return $n; + + case KEYWORD_IF: + $n = new JSNode($this->t); + $n->condition = $this->ParenExpression($x); + array_push($x->stmtStack, $n); + $n->thenPart = $this->Statement($x); + $n->elsePart = $this->t->match(KEYWORD_ELSE) ? $this->Statement($x) : null; + array_pop($x->stmtStack); + return $n; + + case KEYWORD_SWITCH: + $n = new JSNode($this->t); + $this->t->mustMatch(OP_LEFT_PAREN); + $n->discriminant = $this->Expression($x); + $this->t->mustMatch(OP_RIGHT_PAREN); + $n->cases = array(); + $n->defaultIndex = -1; + + array_push($x->stmtStack, $n); + + $this->t->mustMatch(OP_LEFT_CURLY); + + while (($tt = $this->t->get()) != OP_RIGHT_CURLY) + { + switch ($tt) + { + case KEYWORD_DEFAULT: + if ($n->defaultIndex >= 0) + throw $this->t->newSyntaxError('More than one switch default'); + // FALL THROUGH + case KEYWORD_CASE: + $n2 = new JSNode($this->t); + if ($tt == KEYWORD_DEFAULT) + $n->defaultIndex = count($n->cases); + else + $n2->caseLabel = $this->Expression($x, OP_COLON); + break; + default: + throw $this->t->newSyntaxError('Invalid switch case'); + } + + $this->t->mustMatch(OP_COLON); + $n2->statements = new JSNode($this->t, JS_BLOCK); + while (($tt = $this->t->peek()) != KEYWORD_CASE && $tt != KEYWORD_DEFAULT && $tt != OP_RIGHT_CURLY) + $n2->statements->addNode($this->Statement($x)); + + array_push($n->cases, $n2); + } + + array_pop($x->stmtStack); + return $n; + + case KEYWORD_FOR: + $n = new JSNode($this->t); + $n->isLoop = true; + $this->t->mustMatch(OP_LEFT_PAREN); + + if (($tt = $this->t->peek()) != OP_SEMICOLON) + { + $x->inForLoopInit = true; + if ($tt == KEYWORD_VAR || $tt == KEYWORD_CONST) + { + $this->t->get(); + $n2 = $this->Variables($x); + } + else + { + $n2 = $this->Expression($x); + } + $x->inForLoopInit = false; + } + + if ($n2 && $this->t->match(KEYWORD_IN)) + { + $n->type = JS_FOR_IN; + if ($n2->type == KEYWORD_VAR) + { + if (count($n2->treeNodes) != 1) + { + throw $this->t->SyntaxError( + 'Invalid for..in left-hand side', + $this->t->filename, + $n2->lineno + ); + } + + // NB: n2[0].type == IDENTIFIER and n2[0].value == n2[0].name. + $n->iterator = $n2->treeNodes[0]; + $n->varDecl = $n2; + } + else + { + $n->iterator = $n2; + $n->varDecl = null; + } + + $n->object = $this->Expression($x); + } + else + { + $n->setup = $n2 ? $n2 : null; + $this->t->mustMatch(OP_SEMICOLON); + $n->condition = $this->t->peek() == OP_SEMICOLON ? null : $this->Expression($x); + $this->t->mustMatch(OP_SEMICOLON); + $n->update = $this->t->peek() == OP_RIGHT_PAREN ? null : $this->Expression($x); + } + + $this->t->mustMatch(OP_RIGHT_PAREN); + $n->body = $this->nest($x, $n); + return $n; + + case KEYWORD_WHILE: + $n = new JSNode($this->t); + $n->isLoop = true; + $n->condition = $this->ParenExpression($x); + $n->body = $this->nest($x, $n); + return $n; + + case KEYWORD_DO: + $n = new JSNode($this->t); + $n->isLoop = true; + $n->body = $this->nest($x, $n, KEYWORD_WHILE); + $n->condition = $this->ParenExpression($x); + if (!$x->ecmaStrictMode) + { + // "; + * $link = ""; + * + * // in min.php + * Minify::serve('Groups', array( + * 'groups' => $groupSources + * ,'setExpires' => (time() + 86400 * 365) + * )); + * + * + * @package Minify + * @author Stephen Clay + */ +class Minify_Build { + + /** + * Last modification time of all files in the build + * + * @var int + */ + public $lastModified = 0; + + /** + * String to use as ampersand in uri(). Set this to '&' if + * you are not HTML-escaping URIs. + * + * @var string + */ + public static $ampersand = '&'; + + /** + * Get a time-stamped URI + * + * + * echo $b->uri('/site.js'); + * // outputs "/site.js?1678242" + * + * echo $b->uri('/scriptaculous.js?load=effects'); + * // outputs "/scriptaculous.js?load=effects&1678242" + * + * + * @param string $uri + * @param boolean $forceAmpersand (default = false) Force the use of ampersand to + * append the timestamp to the URI. + * @return string + */ + public function uri($uri, $forceAmpersand = false) { + $sep = ($forceAmpersand || strpos($uri, '?') !== false) + ? self::$ampersand + : '?'; + return "{$uri}{$sep}{$this->lastModified}"; + } + + /** + * Create a build object + * + * @param array $sources array of Minify_Source objects and/or file paths + * + * @return null + */ + public function __construct($sources) + { + $max = 0; + foreach ((array)$sources as $source) { + if ($source instanceof Minify_Source) { + $max = max($max, $source->lastModified); + } elseif (is_string($source)) { + if (0 === strpos($source, '//')) { + $source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1); + } + if (is_file($source)) { + $max = max($max, filemtime($source)); + } + } + } + $this->lastModified = $max; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/CSS.php b/plugins/Minify/extlib/minify/min/lib/Minify/CSS.php new file mode 100644 index 000000000..2220cf221 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/CSS.php @@ -0,0 +1,83 @@ + + * @author http://code.google.com/u/1stvamp/ (Issue 64 patch) + */ +class Minify_CSS { + + /** + * Minify a CSS string + * + * @param string $css + * + * @param array $options available options: + * + * 'preserveComments': (default true) multi-line comments that begin + * with "/*!" will be preserved with newlines before and after to + * enhance readability. + * + * 'prependRelativePath': (default null) if given, this string will be + * prepended to all relative URIs in import/url declarations + * + * 'currentDir': (default null) if given, this is assumed to be the + * directory of the current CSS file. Using this, minify will rewrite + * all relative URIs in import/url declarations to correctly point to + * the desired files. For this to work, the files *must* exist and be + * visible by the PHP process. + * + * 'symlinks': (default = array()) If the CSS file is stored in + * a symlink-ed directory, provide an array of link paths to + * target paths, where the link paths are within the document root. Because + * paths need to be normalized for this to work, use "//" to substitute + * the doc root in the link paths (the array keys). E.g.: + * + * array('//symlink' => '/real/target/path') // unix + * array('//static' => 'D:\\staticStorage') // Windows + * + * + * @return string + */ + public static function minify($css, $options = array()) + { + require_once 'Minify/CSS/Compressor.php'; + if (isset($options['preserveComments']) + && !$options['preserveComments']) { + $css = Minify_CSS_Compressor::process($css, $options); + } else { + require_once 'Minify/CommentPreserver.php'; + $css = Minify_CommentPreserver::process( + $css + ,array('Minify_CSS_Compressor', 'process') + ,array($options) + ); + } + if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) { + return $css; + } + require_once 'Minify/CSS/UriRewriter.php'; + if (isset($options['currentDir'])) { + return Minify_CSS_UriRewriter::rewrite( + $css + ,$options['currentDir'] + ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT'] + ,isset($options['symlinks']) ? $options['symlinks'] : array() + ); + } else { + return Minify_CSS_UriRewriter::prepend( + $css + ,$options['prependRelativePath'] + ); + } + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/CSS/Compressor.php b/plugins/Minify/extlib/minify/min/lib/Minify/CSS/Compressor.php new file mode 100644 index 000000000..a34828681 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/CSS/Compressor.php @@ -0,0 +1,250 @@ + + * @author http://code.google.com/u/1stvamp/ (Issue 64 patch) + */ +class Minify_CSS_Compressor { + + /** + * Minify a CSS string + * + * @param string $css + * + * @param array $options (currently ignored) + * + * @return string + */ + public static function process($css, $options = array()) + { + $obj = new Minify_CSS_Compressor($options); + return $obj->_process($css); + } + + /** + * @var array options + */ + protected $_options = null; + + /** + * @var bool Are we "in" a hack? + * + * I.e. are some browsers targetted until the next comment? + */ + protected $_inHack = false; + + + /** + * Constructor + * + * @param array $options (currently ignored) + * + * @return null + */ + private function __construct($options) { + $this->_options = $options; + } + + /** + * Minify a CSS string + * + * @param string $css + * + * @return string + */ + protected function _process($css) + { + $css = str_replace("\r\n", "\n", $css); + + // preserve empty comment after '>' + // http://www.webdevout.net/css-hacks#in_css-selectors + $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css); + + // preserve empty comment between property and value + // http://css-discuss.incutio.com/?page=BoxModelHack + $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css); + $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css); + + // apply callback to all valid comments (and strip out surrounding ws + $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@' + ,array($this, '_commentCB'), $css); + + // remove ws around { } and last semicolon in declaration block + $css = preg_replace('/\\s*{\\s*/', '{', $css); + $css = preg_replace('/;?\\s*}\\s*/', '}', $css); + + // remove ws surrounding semicolons + $css = preg_replace('/\\s*;\\s*/', ';', $css); + + // remove ws around urls + $css = preg_replace('/ + url\\( # url( + \\s* + ([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis) + \\s* + \\) # ) + /x', 'url($1)', $css); + + // remove ws between rules and colons + $css = preg_replace('/ + \\s* + ([{;]) # 1 = beginning of block or rule separator + \\s* + ([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter) + \\s* + : + \\s* + (\\b|[#\'"]) # 3 = first character of a value + /x', '$1$2:$3', $css); + + // remove ws in selectors + $css = preg_replace_callback('/ + (?: # non-capture + \\s* + [^~>+,\\s]+ # selector part + \\s* + [,>+~] # combinators + )+ + \\s* + [^~>+,\\s]+ # selector part + { # open declaration block + /x' + ,array($this, '_selectorsCB'), $css); + + // minimize hex colors + $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i' + , '$1#$2$3$4$5', $css); + + // remove spaces between font families + $css = preg_replace_callback('/font-family:([^;}]+)([;}])/' + ,array($this, '_fontFamilyCB'), $css); + + $css = preg_replace('/@import\\s+url/', '@import url', $css); + + // replace any ws involving newlines with a single newline + $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css); + + // separate common descendent selectors w/ newlines (to limit line lengths) + $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css); + + // Use newline after 1st numeric value (to limit line lengths). + $css = preg_replace('/ + ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value + \\s+ + /x' + ,"$1\n", $css); + + // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/ + $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css); + + return trim($css); + } + + /** + * Replace what looks like a set of selectors + * + * @param array $m regex matches + * + * @return string + */ + protected function _selectorsCB($m) + { + // remove ws around the combinators + return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]); + } + + /** + * Process a comment and return a replacement + * + * @param array $m regex matches + * + * @return string + */ + protected function _commentCB($m) + { + $hasSurroundingWs = (trim($m[0]) !== $m[1]); + $m = $m[1]; + // $m is the comment content w/o the surrounding tokens, + // but the return value will replace the entire comment. + if ($m === 'keep') { + return '/**/'; + } + if ($m === '" "') { + // component of http://tantek.com/CSS/Examples/midpass.html + return '/*" "*/'; + } + if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) { + // component of http://tantek.com/CSS/Examples/midpass.html + return '/*";}}/* */'; + } + if ($this->_inHack) { + // inversion: feeding only to one browser + if (preg_match('@ + ^/ # comment started like /*/ + \\s* + (\\S[\\s\\S]+?) # has at least some non-ws content + \\s* + /\\* # ends like /*/ or /**/ + @x', $m, $n)) { + // end hack mode after this comment, but preserve the hack and comment content + $this->_inHack = false; + return "/*/{$n[1]}/**/"; + } + } + if (substr($m, -1) === '\\') { // comment ends like \*/ + // begin hack mode and preserve hack + $this->_inHack = true; + return '/*\\*/'; + } + if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */ + // begin hack mode and preserve hack + $this->_inHack = true; + return '/*/*/'; + } + if ($this->_inHack) { + // a regular comment ends hack mode but should be preserved + $this->_inHack = false; + return '/**/'; + } + // Issue 107: if there's any surrounding whitespace, it may be important, so + // replace the comment with a single space + return $hasSurroundingWs // remove all other comments + ? ' ' + : ''; + } + + /** + * Process a font-family listing and return a replacement + * + * @param array $m regex matches + * + * @return string + */ + protected function _fontFamilyCB($m) + { + $m[1] = preg_replace('/ + \\s* + ( + "[^"]+" # 1 = family in double qutoes + |\'[^\']+\' # or 1 = family in single quotes + |[\\w\\-]+ # or 1 = unquoted family + ) + \\s* + /x', '$1', $m[1]); + return 'font-family:' . $m[1] . $m[2]; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/CSS/UriRewriter.php b/plugins/Minify/extlib/minify/min/lib/Minify/CSS/UriRewriter.php new file mode 100644 index 000000000..824c6bb2a --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/CSS/UriRewriter.php @@ -0,0 +1,270 @@ + + */ +class Minify_CSS_UriRewriter { + + /** + * Defines which class to call as part of callbacks, change this + * if you extend Minify_CSS_UriRewriter + * @var string + */ + protected static $className = 'Minify_CSS_UriRewriter'; + + /** + * rewrite() and rewriteRelative() append debugging information here + * @var string + */ + public static $debugText = ''; + + /** + * Rewrite file relative URIs as root relative in CSS files + * + * @param string $css + * + * @param string $currentDir The directory of the current CSS file. + * + * @param string $docRoot The document root of the web site in which + * the CSS file resides (default = $_SERVER['DOCUMENT_ROOT']). + * + * @param array $symlinks (default = array()) If the CSS file is stored in + * a symlink-ed directory, provide an array of link paths to + * target paths, where the link paths are within the document root. Because + * paths need to be normalized for this to work, use "//" to substitute + * the doc root in the link paths (the array keys). E.g.: + * + * array('//symlink' => '/real/target/path') // unix + * array('//static' => 'D:\\staticStorage') // Windows + * + * + * @return string + */ + public static function rewrite($css, $currentDir, $docRoot = null, $symlinks = array()) + { + self::$_docRoot = self::_realpath( + $docRoot ? $docRoot : $_SERVER['DOCUMENT_ROOT'] + ); + self::$_currentDir = self::_realpath($currentDir); + self::$_symlinks = array(); + + // normalize symlinks + foreach ($symlinks as $link => $target) { + $link = ($link === '//') + ? self::$_docRoot + : str_replace('//', self::$_docRoot . '/', $link); + $link = strtr($link, '/', DIRECTORY_SEPARATOR); + self::$_symlinks[$link] = self::_realpath($target); + } + + self::$debugText .= "docRoot : " . self::$_docRoot . "\n" + . "currentDir : " . self::$_currentDir . "\n"; + if (self::$_symlinks) { + self::$debugText .= "symlinks : " . var_export(self::$_symlinks, 1) . "\n"; + } + self::$debugText .= "\n"; + + $css = self::_trimUrls($css); + + // rewrite + $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/' + ,array(self::$className, '_processUriCB'), $css); + $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/' + ,array(self::$className, '_processUriCB'), $css); + + return $css; + } + + /** + * Prepend a path to relative URIs in CSS files + * + * @param string $css + * + * @param string $path The path to prepend. + * + * @return string + */ + public static function prepend($css, $path) + { + self::$_prependPath = $path; + + $css = self::_trimUrls($css); + + // append + $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/' + ,array(self::$className, '_processUriCB'), $css); + $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/' + ,array(self::$className, '_processUriCB'), $css); + + self::$_prependPath = null; + return $css; + } + + + /** + * @var string directory of this stylesheet + */ + private static $_currentDir = ''; + + /** + * @var string DOC_ROOT + */ + private static $_docRoot = ''; + + /** + * @var array directory replacements to map symlink targets back to their + * source (within the document root) E.g. '/var/www/symlink' => '/var/realpath' + */ + private static $_symlinks = array(); + + /** + * @var string path to prepend + */ + private static $_prependPath = null; + + private static function _trimUrls($css) + { + return preg_replace('/ + url\\( # url( + \\s* + ([^\\)]+?) # 1 = URI (assuming does not contain ")") + \\s* + \\) # ) + /x', 'url($1)', $css); + } + + private static function _processUriCB($m) + { + // $m matched either '/@import\\s+([\'"])(.*?)[\'"]/' or '/url\\(\\s*([^\\)\\s]+)\\s*\\)/' + $isImport = ($m[0][0] === '@'); + // determine URI and the quote character (if any) + if ($isImport) { + $quoteChar = $m[1]; + $uri = $m[2]; + } else { + // $m[1] is either quoted or not + $quoteChar = ($m[1][0] === "'" || $m[1][0] === '"') + ? $m[1][0] + : ''; + $uri = ($quoteChar === '') + ? $m[1] + : substr($m[1], 1, strlen($m[1]) - 2); + } + // analyze URI + if ('/' !== $uri[0] // root-relative + && false === strpos($uri, '//') // protocol (non-data) + && 0 !== strpos($uri, 'data:') // data protocol + ) { + // URI is file-relative: rewrite depending on options + $uri = (self::$_prependPath !== null) + ? (self::$_prependPath . $uri) + : self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks); + } + return $isImport + ? "@import {$quoteChar}{$uri}{$quoteChar}" + : "url({$quoteChar}{$uri}{$quoteChar})"; + } + + /** + * Rewrite a file relative URI as root relative + * + * + * Minify_CSS_UriRewriter::rewriteRelative( + * '../img/hello.gif' + * , '/home/user/www/css' // path of CSS file + * , '/home/user/www' // doc root + * ); + * // returns '/img/hello.gif' + * + * // example where static files are stored in a symlinked directory + * Minify_CSS_UriRewriter::rewriteRelative( + * 'hello.gif' + * , '/var/staticFiles/theme' + * , '/home/user/www' + * , array('/home/user/www/static' => '/var/staticFiles') + * ); + * // returns '/static/theme/hello.gif' + * + * + * @param string $uri file relative URI + * + * @param string $realCurrentDir realpath of the current file's directory. + * + * @param string $realDocRoot realpath of the site document root. + * + * @param array $symlinks (default = array()) If the file is stored in + * a symlink-ed directory, provide an array of link paths to + * real target paths, where the link paths "appear" to be within the document + * root. E.g.: + * + * array('/home/foo/www/not/real/path' => '/real/target/path') // unix + * array('C:\\htdocs\\not\\real' => 'D:\\real\\target\\path') // Windows + * + * + * @return string + */ + public static function rewriteRelative($uri, $realCurrentDir, $realDocRoot, $symlinks = array()) + { + // prepend path with current dir separator (OS-independent) + $path = strtr($realCurrentDir, '/', DIRECTORY_SEPARATOR) + . DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR); + + self::$debugText .= "file-relative URI : {$uri}\n" + . "path prepended : {$path}\n"; + + // "unresolve" a symlink back to doc root + foreach ($symlinks as $link => $target) { + if (0 === strpos($path, $target)) { + // replace $target with $link + $path = $link . substr($path, strlen($target)); + + self::$debugText .= "symlink unresolved : {$path}\n"; + + break; + } + } + // strip doc root + $path = substr($path, strlen($realDocRoot)); + + self::$debugText .= "docroot stripped : {$path}\n"; + + // fix to root-relative URI + + $uri = strtr($path, '/\\', '//'); + + // remove /./ and /../ where possible + $uri = str_replace('/./', '/', $uri); + // inspired by patch from Oleg Cherniy + do { + $uri = preg_replace('@/[^/]+/\\.\\./@', '/', $uri, 1, $changed); + } while ($changed); + + self::$debugText .= "traversals removed : {$uri}\n\n"; + + return $uri; + } + + /** + * Get realpath with any trailing slash removed. If realpath() fails, + * just remove the trailing slash. + * + * @param string $path + * + * @return mixed path with no trailing slash + */ + protected static function _realpath($path) + { + $realPath = realpath($path); + if ($realPath !== false) { + $path = $realPath; + } + return rtrim($path, '/\\'); + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Cache/APC.php b/plugins/Minify/extlib/minify/min/lib/Minify/Cache/APC.php new file mode 100644 index 000000000..ca84d2998 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Cache/APC.php @@ -0,0 +1,130 @@ + + * Minify::setCache(new Minify_Cache_APC()); + * + * + * @package Minify + * @author Chris Edwards + **/ +class Minify_Cache_APC { + + /** + * Create a Minify_Cache_APC object, to be passed to + * Minify::setCache(). + * + * + * @param int $expire seconds until expiration (default = 0 + * meaning the item will not get an expiration date) + * + * @return null + */ + public function __construct($expire = 0) + { + $this->_exp = $expire; + } + + /** + * Write data to cache. + * + * @param string $id cache id + * + * @param string $data + * + * @return bool success + */ + public function store($id, $data) + { + return apc_store($id, "{$_SERVER['REQUEST_TIME']}|{$data}", $this->_exp); + } + + /** + * Get the size of a cache entry + * + * @param string $id cache id + * + * @return int size in bytes + */ + public function getSize($id) + { + return $this->_fetch($id) + ? strlen($this->_data) + : false; + } + + /** + * Does a valid cache entry exist? + * + * @param string $id cache id + * + * @param int $srcMtime mtime of the original source file(s) + * + * @return bool exists + */ + public function isValid($id, $srcMtime) + { + return ($this->_fetch($id) && ($this->_lm >= $srcMtime)); + } + + /** + * Send the cached content to output + * + * @param string $id cache id + */ + public function display($id) + { + echo $this->_fetch($id) + ? $this->_data + : ''; + } + + /** + * Fetch the cached content + * + * @param string $id cache id + * + * @return string + */ + public function fetch($id) + { + return $this->_fetch($id) + ? $this->_data + : ''; + } + + private $_exp = null; + + // cache of most recently fetched id + private $_lm = null; + private $_data = null; + private $_id = null; + + /** + * Fetch data and timestamp from apc, store in instance + * + * @param string $id + * + * @return bool success + */ + private function _fetch($id) + { + if ($this->_id === $id) { + return true; + } + $ret = apc_fetch($id); + if (false === $ret) { + $this->_id = null; + return false; + } + list($this->_lm, $this->_data) = explode('|', $ret, 2); + $this->_id = $id; + return true; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Cache/File.php b/plugins/Minify/extlib/minify/min/lib/Minify/Cache/File.php new file mode 100644 index 000000000..8744a7e04 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Cache/File.php @@ -0,0 +1,125 @@ +_locking = $fileLocking; + $this->_path = $path; + } + + /** + * Write data to cache. + * + * @param string $id cache id (e.g. a filename) + * + * @param string $data + * + * @return bool success + */ + public function store($id, $data) + { + $flag = $this->_locking + ? LOCK_EX + : null; + if (is_file($this->_path . '/' . $id)) { + @unlink($this->_path . '/' . $id); + } + if (! @file_put_contents($this->_path . '/' . $id, $data, $flag)) { + return false; + } + // write control + if ($data !== $this->fetch($id)) { + @unlink($file); + return false; + } + return true; + } + + /** + * Get the size of a cache entry + * + * @param string $id cache id (e.g. a filename) + * + * @return int size in bytes + */ + public function getSize($id) + { + return filesize($this->_path . '/' . $id); + } + + /** + * Does a valid cache entry exist? + * + * @param string $id cache id (e.g. a filename) + * + * @param int $srcMtime mtime of the original source file(s) + * + * @return bool exists + */ + public function isValid($id, $srcMtime) + { + $file = $this->_path . '/' . $id; + return (is_file($file) && (filemtime($file) >= $srcMtime)); + } + + /** + * Send the cached content to output + * + * @param string $id cache id (e.g. a filename) + */ + public function display($id) + { + if ($this->_locking) { + $fp = fopen($this->_path . '/' . $id, 'rb'); + flock($fp, LOCK_SH); + fpassthru($fp); + flock($fp, LOCK_UN); + fclose($fp); + } else { + readfile($this->_path . '/' . $id); + } + } + + /** + * Fetch the cached content + * + * @param string $id cache id (e.g. a filename) + * + * @return string + */ + public function fetch($id) + { + if ($this->_locking) { + $fp = fopen($this->_path . '/' . $id, 'rb'); + flock($fp, LOCK_SH); + $ret = stream_get_contents($fp); + flock($fp, LOCK_UN); + fclose($fp); + return $ret; + } else { + return file_get_contents($this->_path . '/' . $id); + } + } + + /** + * Fetch the cache path used + * + * @return string + */ + public function getPath() + { + return $this->_path; + } + + private $_path = null; + private $_locking = null; +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Cache/Memcache.php b/plugins/Minify/extlib/minify/min/lib/Minify/Cache/Memcache.php new file mode 100644 index 000000000..2b81e7a32 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Cache/Memcache.php @@ -0,0 +1,137 @@ + + * // fall back to disk caching if memcache can't connect + * $memcache = new Memcache; + * if ($memcache->connect('localhost', 11211)) { + * Minify::setCache(new Minify_Cache_Memcache($memcache)); + * } else { + * Minify::setCache(); + * } + * + **/ +class Minify_Cache_Memcache { + + /** + * Create a Minify_Cache_Memcache object, to be passed to + * Minify::setCache(). + * + * @param Memcache $memcache already-connected instance + * + * @param int $expire seconds until expiration (default = 0 + * meaning the item will not get an expiration date) + * + * @return null + */ + public function __construct($memcache, $expire = 0) + { + $this->_mc = $memcache; + $this->_exp = $expire; + } + + /** + * Write data to cache. + * + * @param string $id cache id + * + * @param string $data + * + * @return bool success + */ + public function store($id, $data) + { + return $this->_mc->set($id, "{$_SERVER['REQUEST_TIME']}|{$data}", 0, $this->_exp); + } + + + /** + * Get the size of a cache entry + * + * @param string $id cache id + * + * @return int size in bytes + */ + public function getSize($id) + { + return $this->_fetch($id) + ? strlen($this->_data) + : false; + } + + /** + * Does a valid cache entry exist? + * + * @param string $id cache id + * + * @param int $srcMtime mtime of the original source file(s) + * + * @return bool exists + */ + public function isValid($id, $srcMtime) + { + return ($this->_fetch($id) && ($this->_lm >= $srcMtime)); + } + + /** + * Send the cached content to output + * + * @param string $id cache id + */ + public function display($id) + { + echo $this->_fetch($id) + ? $this->_data + : ''; + } + + /** + * Fetch the cached content + * + * @param string $id cache id + * + * @return string + */ + public function fetch($id) + { + return $this->_fetch($id) + ? $this->_data + : ''; + } + + private $_mc = null; + private $_exp = null; + + // cache of most recently fetched id + private $_lm = null; + private $_data = null; + private $_id = null; + + /** + * Fetch data and timestamp from memcache, store in instance + * + * @param string $id + * + * @return bool success + */ + private function _fetch($id) + { + if ($this->_id === $id) { + return true; + } + $ret = $this->_mc->get($id); + if (false === $ret) { + $this->_id = null; + return false; + } + list($this->_lm, $this->_data) = explode('|', $ret, 2); + $this->_id = $id; + return true; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/CommentPreserver.php b/plugins/Minify/extlib/minify/min/lib/Minify/CommentPreserver.php new file mode 100644 index 000000000..f56eb3461 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/CommentPreserver.php @@ -0,0 +1,90 @@ + + */ +class Minify_CommentPreserver { + + /** + * String to be prepended to each preserved comment + * + * @var string + */ + public static $prepend = "\n"; + + /** + * String to be appended to each preserved comment + * + * @var string + */ + public static $append = "\n"; + + /** + * Process a string outside of C-style comments that begin with "/*!" + * + * On each non-empty string outside these comments, the given processor + * function will be called. The first "!" will be removed from the + * preserved comments, and the comments will be surrounded by + * Minify_CommentPreserver::$preprend and Minify_CommentPreserver::$append. + * + * @param string $content + * @param callback $processor function + * @param array $args array of extra arguments to pass to the processor + * function (default = array()) + * @return string + */ + public static function process($content, $processor, $args = array()) + { + $ret = ''; + while (true) { + list($beforeComment, $comment, $afterComment) = self::_nextComment($content); + if ('' !== $beforeComment) { + $callArgs = $args; + array_unshift($callArgs, $beforeComment); + $ret .= call_user_func_array($processor, $callArgs); + } + if (false === $comment) { + break; + } + $ret .= $comment; + $content = $afterComment; + } + return $ret; + } + + /** + * Extract comments that YUI Compressor preserves. + * + * @param string $in input + * + * @return array 3 elements are returned. If a YUI comment is found, the + * 2nd element is the comment and the 1st and 2nd are the surrounding + * strings. If no comment is found, the entire string is returned as the + * 1st element and the other two are false. + */ + private static function _nextComment($in) + { + if ( + false === ($start = strpos($in, '/*!')) + || false === ($end = strpos($in, '*/', $start + 3)) + ) { + return array($in, false, false); + } + $ret = array( + substr($in, 0, $start) + ,self::$prepend . '/*' . substr($in, $start + 3, $end - $start - 1) . self::$append + ); + $endChars = (strlen($in) - $end - 2); + $ret[] = (0 === $endChars) + ? '' + : substr($in, -$endChars); + return $ret; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Base.php b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Base.php new file mode 100644 index 000000000..84889b3f0 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Base.php @@ -0,0 +1,202 @@ + + */ +abstract class Minify_Controller_Base { + + /** + * Setup controller sources and set an needed options for Minify::source + * + * You must override this method in your subclass controller to set + * $this->sources. If the request is NOT valid, make sure $this->sources + * is left an empty array. Then strip any controller-specific options from + * $options and return it. To serve files, $this->sources must be an array of + * Minify_Source objects. + * + * @param array $options controller and Minify options + * + * return array $options Minify::serve options + */ + abstract public function setupSources($options); + + /** + * Get default Minify options for this controller. + * + * Override in subclass to change defaults + * + * @return array options for Minify + */ + public function getDefaultMinifyOptions() { + return array( + 'isPublic' => true + ,'encodeOutput' => function_exists('gzdeflate') + ,'encodeMethod' => null // determine later + ,'encodeLevel' => 9 + ,'minifierOptions' => array() // no minifier options + ,'contentTypeCharset' => 'utf-8' + ,'maxAge' => 1800 // 30 minutes + ,'rewriteCssUris' => true + ,'bubbleCssImports' => false + ,'quiet' => false // serve() will send headers and output + ,'debug' => false + + // if you override this, the response code MUST be directly after + // the first space. + ,'badRequestHeader' => 'HTTP/1.0 400 Bad Request' + + // callback function to see/modify content of all sources + ,'postprocessor' => null + // file to require to load preprocessor + ,'postprocessorRequire' => null + ); + } + + /** + * Get default minifiers for this controller. + * + * Override in subclass to change defaults + * + * @return array minifier callbacks for common types + */ + public function getDefaultMinifers() { + $ret[Minify::TYPE_JS] = array('JSMin', 'minify'); + $ret[Minify::TYPE_CSS] = array('Minify_CSS', 'minify'); + $ret[Minify::TYPE_HTML] = array('Minify_HTML', 'minify'); + return $ret; + } + + /** + * Load any code necessary to execute the given minifier callback. + * + * The controller is responsible for loading minification code on demand + * via this method. This built-in function will only load classes for + * static method callbacks where the class isn't already defined. It uses + * the PEAR convention, so, given array('Jimmy_Minifier', 'minCss'), this + * function will include 'Jimmy/Minifier.php'. + * + * If you need code loaded on demand and this doesn't suit you, you'll need + * to override this function in your subclass. + * @see Minify_Controller_Page::loadMinifier() + * + * @param callback $minifierCallback callback of minifier function + * + * @return null + */ + public function loadMinifier($minifierCallback) + { + if (is_array($minifierCallback) + && is_string($minifierCallback[0]) + && !class_exists($minifierCallback[0], false)) { + + require str_replace('_', '/', $minifierCallback[0]) . '.php'; + } + } + + /** + * Is a user-given file within an allowable directory, existing, + * and having an extension js/css/html/txt ? + * + * This is a convenience function for controllers that have to accept + * user-given paths + * + * @param string $file full file path (already processed by realpath()) + * + * @param array $safeDirs directories where files are safe to serve. Files can also + * be in subdirectories of these directories. + * + * @return bool file is safe + */ + public static function _fileIsSafe($file, $safeDirs) + { + $pathOk = false; + foreach ((array)$safeDirs as $safeDir) { + if (strpos($file, $safeDir) === 0) { + $pathOk = true; + break; + } + } + $base = basename($file); + if (! $pathOk || ! is_file($file) || $base[0] === '.') { + return false; + } + list($revExt) = explode('.', strrev($base)); + return in_array(strrev($revExt), array('js', 'css', 'html', 'txt')); + } + + /** + * @var array instances of Minify_Source, which provide content and + * any individual minification needs. + * + * @see Minify_Source + */ + public $sources = array(); + + /** + * Mix in default controller options with user-given options + * + * @param array $options user options + * + * @return array mixed options + */ + public final function mixInDefaultOptions($options) + { + $ret = array_merge( + $this->getDefaultMinifyOptions(), $options + ); + if (! isset($options['minifiers'])) { + $options['minifiers'] = array(); + } + $ret['minifiers'] = array_merge( + $this->getDefaultMinifers(), $options['minifiers'] + ); + return $ret; + } + + /** + * Analyze sources (if there are any) and set $options 'contentType' + * and 'lastModifiedTime' if they already aren't. + * + * @param array $options options for Minify + * + * @return array options for Minify + */ + public final function analyzeSources($options = array()) + { + if ($this->sources) { + if (! isset($options['contentType'])) { + $options['contentType'] = Minify_Source::getContentType($this->sources); + } + // last modified is needed for caching, even if setExpires is set + if (! isset($options['lastModifiedTime'])) { + $max = 0; + foreach ($this->sources as $source) { + $max = max($source->lastModified, $max); + } + $options['lastModifiedTime'] = $max; + } + } + return $options; + } + + /** + * Send message to the Minify logger + * @param string $msg + * @return null + */ + protected function log($msg) { + require_once 'Minify/Logger.php'; + Minify_Logger::log($msg); + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Files.php b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Files.php new file mode 100644 index 000000000..83f028adf --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Files.php @@ -0,0 +1,78 @@ + + * Minify::serve('Files', array( + * 'files' => array( + * '//js/jquery.js' + * ,'//js/plugins.js' + * ,'/home/username/file.js' + * ) + * )); + * + * + * As a shortcut, the controller will replace "//" at the beginning + * of a filename with $_SERVER['DOCUMENT_ROOT'] . '/'. + * + * @package Minify + * @author Stephen Clay + */ +class Minify_Controller_Files extends Minify_Controller_Base { + + /** + * Set up file sources + * + * @param array $options controller and Minify options + * @return array Minify options + * + * Controller options: + * + * 'files': (required) array of complete file paths, or a single path + */ + public function setupSources($options) { + // strip controller options + + $files = $options['files']; + // if $files is a single object, casting will break it + if (is_object($files)) { + $files = array($files); + } elseif (! is_array($files)) { + $files = (array)$files; + } + unset($options['files']); + + $sources = array(); + foreach ($files as $file) { + if ($file instanceof Minify_Source) { + $sources[] = $file; + continue; + } + if (0 === strpos($file, '//')) { + $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1); + } + $realPath = realpath($file); + if (is_file($realPath)) { + $sources[] = new Minify_Source(array( + 'filepath' => $realPath + )); + } else { + $this->log("The path \"{$file}\" could not be found (or was not a file)"); + return $options; + } + } + if ($sources) { + $this->sources = $sources; + } + return $options; + } +} + diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Groups.php b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Groups.php new file mode 100644 index 000000000..1ac57703a --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Groups.php @@ -0,0 +1,94 @@ + + * Minify::serve('Groups', array( + * 'groups' => array( + * 'css' => array('//css/type.css', '//css/layout.css') + * ,'js' => array('//js/jquery.js', '//js/site.js') + * ) + * )); + * + * + * If the above code were placed in /serve.php, it would enable the URLs + * /serve.php/js and /serve.php/css + * + * As a shortcut, the controller will replace "//" at the beginning + * of a filename with $_SERVER['DOCUMENT_ROOT'] . '/'. + * + * @package Minify + * @author Stephen Clay + */ +class Minify_Controller_Groups extends Minify_Controller_Base { + + /** + * Set up groups of files as sources + * + * @param array $options controller and Minify options + * @return array Minify options + * + * Controller options: + * + * 'groups': (required) array mapping PATH_INFO strings to arrays + * of complete file paths. @see Minify_Controller_Groups + */ + public function setupSources($options) { + // strip controller options + $groups = $options['groups']; + unset($options['groups']); + + // mod_fcgid places PATH_INFO in ORIG_PATH_INFO + $pi = isset($_SERVER['ORIG_PATH_INFO']) + ? substr($_SERVER['ORIG_PATH_INFO'], 1) + : (isset($_SERVER['PATH_INFO']) + ? substr($_SERVER['PATH_INFO'], 1) + : false + ); + if (false === $pi || ! isset($groups[$pi])) { + // no PATH_INFO or not a valid group + $this->log("Missing PATH_INFO or no group set for \"$pi\""); + return $options; + } + $sources = array(); + + $files = $groups[$pi]; + // if $files is a single object, casting will break it + if (is_object($files)) { + $files = array($files); + } elseif (! is_array($files)) { + $files = (array)$files; + } + foreach ($files as $file) { + if ($file instanceof Minify_Source) { + $sources[] = $file; + continue; + } + if (0 === strpos($file, '//')) { + $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1); + } + $realPath = realpath($file); + if (is_file($realPath)) { + $sources[] = new Minify_Source(array( + 'filepath' => $realPath + )); + } else { + $this->log("The path \"{$file}\" could not be found (or was not a file)"); + return $options; + } + } + if ($sources) { + $this->sources = $sources; + } + return $options; + } +} + diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Controller/MinApp.php b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/MinApp.php new file mode 100644 index 000000000..9582d292c --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/MinApp.php @@ -0,0 +1,132 @@ + + */ +class Minify_Controller_MinApp extends Minify_Controller_Base { + + /** + * Set up groups of files as sources + * + * @param array $options controller and Minify options + * @return array Minify options + * + */ + public function setupSources($options) { + // filter controller options + $cOptions = array_merge( + array( + 'allowDirs' => '//' + ,'groupsOnly' => false + ,'groups' => array() + ,'maxFiles' => 10 + ) + ,(isset($options['minApp']) ? $options['minApp'] : array()) + ); + unset($options['minApp']); + $sources = array(); + if (isset($_GET['g'])) { + // try groups + if (! isset($cOptions['groups'][$_GET['g']])) { + $this->log("A group configuration for \"{$_GET['g']}\" was not set"); + return $options; + } + + $files = $cOptions['groups'][$_GET['g']]; + // if $files is a single object, casting will break it + if (is_object($files)) { + $files = array($files); + } elseif (! is_array($files)) { + $files = (array)$files; + } + foreach ($files as $file) { + if ($file instanceof Minify_Source) { + $sources[] = $file; + continue; + } + if (0 === strpos($file, '//')) { + $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1); + } + $file = realpath($file); + if (is_file($file)) { + $sources[] = new Minify_Source(array( + 'filepath' => $file + )); + } else { + $this->log("The path \"{$file}\" could not be found (or was not a file)"); + return $options; + } + } + } elseif (! $cOptions['groupsOnly'] && isset($_GET['f'])) { + // try user files + // The following restrictions are to limit the URLs that minify will + // respond to. Ideally there should be only one way to reference a file. + if (// verify at least one file, files are single comma separated, + // and are all same extension + ! preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $_GET['f']) + // no "//" + || strpos($_GET['f'], '//') !== false + // no "\" + || strpos($_GET['f'], '\\') !== false + // no "./" + || preg_match('/(?:^|[^\\.])\\.\\//', $_GET['f']) + ) { + $this->log("GET param 'f' invalid (see MinApp.php line 63)"); + return $options; + } + $files = explode(',', $_GET['f']); + if (count($files) > $cOptions['maxFiles'] || $files != array_unique($files)) { + $this->log("Too many or duplicate files specified"); + return $options; + } + if (isset($_GET['b'])) { + // check for validity + if (preg_match('@^[^/]+(?:/[^/]+)*$@', $_GET['b']) + && false === strpos($_GET['b'], '..') + && $_GET['b'] !== '.') { + // valid base + $base = "/{$_GET['b']}/"; + } else { + $this->log("GET param 'b' invalid (see MinApp.php line 84)"); + return $options; + } + } else { + $base = '/'; + } + $allowDirs = array(); + foreach ((array)$cOptions['allowDirs'] as $allowDir) { + $allowDirs[] = realpath(str_replace('//', $_SERVER['DOCUMENT_ROOT'] . '/', $allowDir)); + } + foreach ($files as $file) { + $path = $_SERVER['DOCUMENT_ROOT'] . $base . $file; + $file = realpath($path); + if (false === $file) { + $this->log("Path \"{$path}\" failed realpath()"); + return $options; + } elseif (! parent::_fileIsSafe($file, $allowDirs)) { + $this->log("Path \"{$path}\" failed Minify_Controller_Base::_fileIsSafe()"); + return $options; + } else { + $sources[] = new Minify_Source(array( + 'filepath' => $file + )); + } + } + } + if ($sources) { + $this->sources = $sources; + } else { + $this->log("No sources to serve"); + } + return $options; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Page.php b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Page.php new file mode 100644 index 000000000..fa4599abd --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Page.php @@ -0,0 +1,82 @@ + + */ +class Minify_Controller_Page extends Minify_Controller_Base { + + /** + * Set up source of HTML content + * + * @param array $options controller and Minify options + * @return array Minify options + * + * Controller options: + * + * 'content': (required) HTML markup + * + * 'id': (required) id of page (string for use in server-side caching) + * + * 'lastModifiedTime': timestamp of when this content changed. This + * is recommended to allow both server and client-side caching. + * + * 'minifyAll': should all CSS and Javascript blocks be individually + * minified? (default false) + * + * @todo Add 'file' option to read HTML file. + */ + public function setupSources($options) { + if (isset($options['file'])) { + $sourceSpec = array( + 'filepath' => $options['file'] + ); + } else { + // strip controller options + $sourceSpec = array( + 'content' => $options['content'] + ,'id' => $options['id'] + ); + unset($options['content'], $options['id']); + } + if (isset($options['minifyAll'])) { + // this will be the 2nd argument passed to Minify_HTML::minify() + $sourceSpec['minifyOptions'] = array( + 'cssMinifier' => array('Minify_CSS', 'minify') + ,'jsMinifier' => array('JSMin', 'minify') + ); + $this->_loadCssJsMinifiers = true; + unset($options['minifyAll']); + } + $this->sources[] = new Minify_Source($sourceSpec); + + $options['contentType'] = Minify::TYPE_HTML; + return $options; + } + + protected $_loadCssJsMinifiers = false; + + /** + * @see Minify_Controller_Base::loadMinifier() + */ + public function loadMinifier($minifierCallback) + { + if ($this->_loadCssJsMinifiers) { + // Minify will not call for these so we must manually load + // them when Minify/HTML.php is called for. + require_once 'Minify/CSS.php'; + require_once 'JSMin.php'; + } + parent::loadMinifier($minifierCallback); // load Minify/HTML.php + } +} + diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Version1.php b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Version1.php new file mode 100644 index 000000000..1861aabc1 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Controller/Version1.php @@ -0,0 +1,118 @@ + + * Minify::serve('Version1'); + * + * + * @package Minify + * @author Stephen Clay + */ +class Minify_Controller_Version1 extends Minify_Controller_Base { + + /** + * Set up groups of files as sources + * + * @param array $options controller and Minify options + * @return array Minify options + * + */ + public function setupSources($options) { + self::_setupDefines(); + if (MINIFY_USE_CACHE) { + $cacheDir = defined('MINIFY_CACHE_DIR') + ? MINIFY_CACHE_DIR + : ''; + Minify::setCache($cacheDir); + } + $options['badRequestHeader'] = 'HTTP/1.0 404 Not Found'; + $options['contentTypeCharset'] = MINIFY_ENCODING; + + // The following restrictions are to limit the URLs that minify will + // respond to. Ideally there should be only one way to reference a file. + if (! isset($_GET['files']) + // verify at least one file, files are single comma separated, + // and are all same extension + || ! preg_match('/^[^,]+\\.(css|js)(,[^,]+\\.\\1)*$/', $_GET['files'], $m) + // no "//" (makes URL rewriting easier) + || strpos($_GET['files'], '//') !== false + // no "\" + || strpos($_GET['files'], '\\') !== false + // no "./" + || preg_match('/(?:^|[^\\.])\\.\\//', $_GET['files']) + ) { + return $options; + } + $extension = $m[1]; + + $files = explode(',', $_GET['files']); + if (count($files) > MINIFY_MAX_FILES) { + return $options; + } + + // strings for prepending to relative/absolute paths + $prependRelPaths = dirname($_SERVER['SCRIPT_FILENAME']) + . DIRECTORY_SEPARATOR; + $prependAbsPaths = $_SERVER['DOCUMENT_ROOT']; + + $sources = array(); + $goodFiles = array(); + $hasBadSource = false; + + $allowDirs = isset($options['allowDirs']) + ? $options['allowDirs'] + : MINIFY_BASE_DIR; + + foreach ($files as $file) { + // prepend appropriate string for abs/rel paths + $file = ($file[0] === '/' ? $prependAbsPaths : $prependRelPaths) . $file; + // make sure a real file! + $file = realpath($file); + // don't allow unsafe or duplicate files + if (parent::_fileIsSafe($file, $allowDirs) + && !in_array($file, $goodFiles)) + { + $goodFiles[] = $file; + $srcOptions = array( + 'filepath' => $file + ); + $this->sources[] = new Minify_Source($srcOptions); + } else { + $hasBadSource = true; + break; + } + } + if ($hasBadSource) { + $this->sources = array(); + } + if (! MINIFY_REWRITE_CSS_URLS) { + $options['rewriteCssUris'] = false; + } + return $options; + } + + private static function _setupDefines() + { + $defaults = array( + 'MINIFY_BASE_DIR' => realpath($_SERVER['DOCUMENT_ROOT']) + ,'MINIFY_ENCODING' => 'utf-8' + ,'MINIFY_MAX_FILES' => 16 + ,'MINIFY_REWRITE_CSS_URLS' => true + ,'MINIFY_USE_CACHE' => true + ); + foreach ($defaults as $const => $val) { + if (! defined($const)) { + define($const, $val); + } + } + } +} + diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/HTML.php b/plugins/Minify/extlib/minify/min/lib/Minify/HTML.php new file mode 100644 index 000000000..fb5c1e982 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/HTML.php @@ -0,0 +1,245 @@ + + */ +class Minify_HTML { + + /** + * "Minify" an HTML page + * + * @param string $html + * + * @param array $options + * + * 'cssMinifier' : (optional) callback function to process content of STYLE + * elements. + * + * 'jsMinifier' : (optional) callback function to process content of SCRIPT + * elements. Note: the type attribute is ignored. + * + * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If + * unset, minify will sniff for an XHTML doctype. + * + * @return string + */ + public static function minify($html, $options = array()) { + $min = new Minify_HTML($html, $options); + return $min->process(); + } + + + /** + * Create a minifier object + * + * @param string $html + * + * @param array $options + * + * 'cssMinifier' : (optional) callback function to process content of STYLE + * elements. + * + * 'jsMinifier' : (optional) callback function to process content of SCRIPT + * elements. Note: the type attribute is ignored. + * + * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If + * unset, minify will sniff for an XHTML doctype. + * + * @return null + */ + public function __construct($html, $options = array()) + { + $this->_html = str_replace("\r\n", "\n", trim($html)); + if (isset($options['xhtml'])) { + $this->_isXhtml = (bool)$options['xhtml']; + } + if (isset($options['cssMinifier'])) { + $this->_cssMinifier = $options['cssMinifier']; + } + if (isset($options['jsMinifier'])) { + $this->_jsMinifier = $options['jsMinifier']; + } + } + + + /** + * Minify the markeup given in the constructor + * + * @return string + */ + public function process() + { + if ($this->_isXhtml === null) { + $this->_isXhtml = (false !== strpos($this->_html, '_replacementHash = 'MINIFYHTML' . md5($_SERVER['REQUEST_TIME']); + $this->_placeholders = array(); + + // replace SCRIPTs (and minify) with placeholders + $this->_html = preg_replace_callback( + '/(\\s*)(]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i' + ,array($this, '_removeScriptCB') + ,$this->_html); + + // replace STYLEs (and minify) with placeholders + $this->_html = preg_replace_callback( + '/\\s*(]*?>)([\\s\\S]*?)<\\/style>\\s*/i' + ,array($this, '_removeStyleCB') + ,$this->_html); + + // remove HTML comments (not containing IE conditional comments). + $this->_html = preg_replace_callback( + '//' + ,array($this, '_commentCB') + ,$this->_html); + + // replace PREs with placeholders + $this->_html = preg_replace_callback('/\\s*(]*?>[\\s\\S]*?<\\/pre>)\\s*/i' + ,array($this, '_removePreCB') + ,$this->_html); + + // replace TEXTAREAs with placeholders + $this->_html = preg_replace_callback( + '/\\s*(]*?>[\\s\\S]*?<\\/textarea>)\\s*/i' + ,array($this, '_removeTextareaCB') + ,$this->_html); + + // trim each line. + // @todo take into account attribute values that span multiple lines. + $this->_html = preg_replace('/^\\s+|\\s+$/m', '', $this->_html); + + // remove ws around block/undisplayed elements + $this->_html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body' + .'|caption|center|cite|col(?:group)?|dd|dir|div|dl|dt|fieldset|form' + .'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta' + .'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)' + .'|ul)\\b[^>]*>)/i', '$1', $this->_html); + + // remove ws outside of all elements + $this->_html = preg_replace_callback( + '/>([^<]+)_html); + + // use newlines before 1st attribute in open tags (to limit line lengths) + $this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html); + + // fill placeholders + $this->_html = str_replace( + array_keys($this->_placeholders) + ,array_values($this->_placeholders) + ,$this->_html + ); + return $this->_html; + } + + protected function _commentCB($m) + { + return (0 === strpos($m[1], '[') || false !== strpos($m[1], '_replacementHash . count($this->_placeholders) . '%'; + $this->_placeholders[$placeholder] = $content; + return $placeholder; + } + + protected $_isXhtml = null; + protected $_replacementHash = null; + protected $_placeholders = array(); + protected $_cssMinifier = null; + protected $_jsMinifier = null; + + protected function _outsideTagCB($m) + { + return '>' . preg_replace('/^\\s+|\\s+$/', ' ', $m[1]) . '<'; + } + + protected function _removePreCB($m) + { + return $this->_reservePlace($m[1]); + } + + protected function _removeTextareaCB($m) + { + return $this->_reservePlace($m[1]); + } + + protected function _removeStyleCB($m) + { + $openStyle = $m[1]; + $css = $m[2]; + // remove HTML comments + $css = preg_replace('/(?:^\\s*\\s*$)/', '', $css); + + // remove CDATA section markers + $css = $this->_removeCdata($css); + + // minify + $minifier = $this->_cssMinifier + ? $this->_cssMinifier + : 'trim'; + $css = call_user_func($minifier, $css); + + return $this->_reservePlace($this->_needsCdata($css) + ? "{$openStyle}/**/" + : "{$openStyle}{$css}" + ); + } + + protected function _removeScriptCB($m) + { + $openScript = $m[2]; + $js = $m[3]; + + // whitespace surrounding? preserve at least one space + $ws1 = ($m[1] === '') ? '' : ' '; + $ws2 = ($m[4] === '') ? '' : ' '; + + // remove HTML comments (and ending "//" if present) + $js = preg_replace('/(?:^\\s*\\s*$)/', '', $js); + + // remove CDATA section markers + $js = $this->_removeCdata($js); + + // minify + $minifier = $this->_jsMinifier + ? $this->_jsMinifier + : 'trim'; + $js = call_user_func($minifier, $js); + + return $this->_reservePlace($this->_needsCdata($js) + ? "{$ws1}{$openScript}/**/{$ws2}" + : "{$ws1}{$openScript}{$js}{$ws2}" + ); + } + + protected function _removeCdata($str) + { + return (false !== strpos($str, ''), '', $str) + : $str; + } + + protected function _needsCdata($str) + { + return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str)); + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/ImportProcessor.php b/plugins/Minify/extlib/minify/min/lib/Minify/ImportProcessor.php new file mode 100644 index 000000000..0d6d90a81 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/ImportProcessor.php @@ -0,0 +1,157 @@ + + */ +class Minify_ImportProcessor { + + public static $filesIncluded = array(); + + public static function process($file) + { + self::$filesIncluded = array(); + self::$_isCss = (strtolower(substr($file, -4)) === '.css'); + $obj = new Minify_ImportProcessor(dirname($file)); + return $obj->_getContent($file); + } + + // allows callback funcs to know the current directory + private $_currentDir = null; + + // allows _importCB to write the fetched content back to the obj + private $_importedContent = ''; + + private static $_isCss = null; + + private function __construct($currentDir) + { + $this->_currentDir = $currentDir; + } + + private function _getContent($file) + { + $file = realpath($file); + if (! $file + || in_array($file, self::$filesIncluded) + || false === ($content = @file_get_contents($file)) + ) { + // file missing, already included, or failed read + return ''; + } + self::$filesIncluded[] = realpath($file); + $this->_currentDir = dirname($file); + + // remove UTF-8 BOM if present + if (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) { + $content = substr($content, 3); + } + // ensure uniform EOLs + $content = str_replace("\r\n", "\n", $content); + + // process @imports + $content = preg_replace_callback( + '/ + @import\\s+ + (?:url\\(\\s*)? # maybe url( + [\'"]? # maybe quote + (.*?) # 1 = URI + [\'"]? # maybe end quote + (?:\\s*\\))? # maybe ) + ([a-zA-Z,\\s]*)? # 2 = media list + ; # end token + /x' + ,array($this, '_importCB') + ,$content + ); + + if (self::$_isCss) { + // rewrite remaining relative URIs + $content = preg_replace_callback( + '/url\\(\\s*([^\\)\\s]+)\\s*\\)/' + ,array($this, '_urlCB') + ,$content + ); + } + + return $this->_importedContent . $content; + } + + private function _importCB($m) + { + $url = $m[1]; + $mediaList = preg_replace('/\\s+/', '', $m[2]); + + if (strpos($url, '://') > 0) { + // protocol, leave in place for CSS, comment for JS + return self::$_isCss + ? $m[0] + : "/* Minify_ImportProcessor will not include remote content */"; + } + if ('/' === $url[0]) { + // protocol-relative or root path + $url = ltrim($url, '/'); + $file = realpath($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR + . strtr($url, '/', DIRECTORY_SEPARATOR); + } else { + // relative to current path + $file = $this->_currentDir . DIRECTORY_SEPARATOR + . strtr($url, '/', DIRECTORY_SEPARATOR); + } + $obj = new Minify_ImportProcessor(dirname($file)); + $content = $obj->_getContent($file); + if ('' === $content) { + // failed. leave in place for CSS, comment for JS + return self::$_isCss + ? $m[0] + : "/* Minify_ImportProcessor could not fetch '{$file}' */";; + } + return (!self::$_isCss || preg_match('@(?:^$|\\ball\\b)@', $mediaList)) + ? $content + : "@media {$mediaList} {\n{$content}\n}\n"; + } + + private function _urlCB($m) + { + // $m[1] is either quoted or not + $quote = ($m[1][0] === "'" || $m[1][0] === '"') + ? $m[1][0] + : ''; + $url = ($quote === '') + ? $m[1] + : substr($m[1], 1, strlen($m[1]) - 2); + if ('/' !== $url[0]) { + if (strpos($url, '//') > 0) { + // probably starts with protocol, do not alter + } else { + // prepend path with current dir separator (OS-independent) + $path = $this->_currentDir + . DIRECTORY_SEPARATOR . strtr($url, '/', DIRECTORY_SEPARATOR); + // strip doc root + $path = substr($path, strlen(realpath($_SERVER['DOCUMENT_ROOT']))); + // fix to absolute URL + $url = strtr($path, '/\\', '//'); + // remove /./ and /../ where possible + $url = str_replace('/./', '/', $url); + // inspired by patch from Oleg Cherniy + do { + $url = preg_replace('@/[^/]+/\\.\\./@', '/', $url, 1, $changed); + } while ($changed); + } + } + return "url({$quote}{$url}{$quote})"; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Lines.php b/plugins/Minify/extlib/minify/min/lib/Minify/Lines.php new file mode 100644 index 000000000..6f94fb63c --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Lines.php @@ -0,0 +1,131 @@ + + * @author Adam Pedersen (Issue 55 fix) + */ +class Minify_Lines { + + /** + * Add line numbers in C-style comments + * + * This uses a very basic parser easily fooled by comment tokens inside + * strings or regexes, but, otherwise, generally clean code will not be + * mangled. URI rewriting can also be performed. + * + * @param string $content + * + * @param array $options available options: + * + * 'id': (optional) string to identify file. E.g. file name/path + * + * 'currentDir': (default null) if given, this is assumed to be the + * directory of the current CSS file. Using this, minify will rewrite + * all relative URIs in import/url declarations to correctly point to + * the desired files, and prepend a comment with debugging information about + * this process. + * + * @return string + */ + public static function minify($content, $options = array()) + { + $id = (isset($options['id']) && $options['id']) + ? $options['id'] + : ''; + $content = str_replace("\r\n", "\n", $content); + $lines = explode("\n", $content); + $numLines = count($lines); + // determine left padding + $padTo = strlen($numLines); + $inComment = false; + $i = 0; + $newLines = array(); + while (null !== ($line = array_shift($lines))) { + if (('' !== $id) && (0 == $i % 50)) { + array_push($newLines, '', "/* {$id} */", ''); + } + ++$i; + $newLines[] = self::_addNote($line, $i, $inComment, $padTo); + $inComment = self::_eolInComment($line, $inComment); + } + $content = implode("\n", $newLines) . "\n"; + + // check for desired URI rewriting + if (isset($options['currentDir'])) { + require_once 'Minify/CSS/UriRewriter.php'; + Minify_CSS_UriRewriter::$debugText = ''; + $content = Minify_CSS_UriRewriter::rewrite( + $content + ,$options['currentDir'] + ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT'] + ,isset($options['symlinks']) ? $options['symlinks'] : array() + ); + $content = "/* Minify_CSS_UriRewriter::\$debugText\n\n" + . Minify_CSS_UriRewriter::$debugText . "*/\n" + . $content; + } + + return $content; + } + + /** + * Is the parser within a C-style comment at the end of this line? + * + * @param string $line current line of code + * + * @param bool $inComment was the parser in a comment at the + * beginning of the line? + * + * @return bool + */ + private static function _eolInComment($line, $inComment) + { + while (strlen($line)) { + $search = $inComment + ? '*/' + : '/*'; + $pos = strpos($line, $search); + if (false === $pos) { + return $inComment; + } else { + if ($pos == 0 + || ($inComment + ? substr($line, $pos, 3) + : substr($line, $pos-1, 3)) != '*/*') + { + $inComment = ! $inComment; + } + $line = substr($line, $pos + 2); + } + } + return $inComment; + } + + /** + * Prepend a comment (or note) to the given line + * + * @param string $line current line of code + * + * @param string $note content of note/comment + * + * @param bool $inComment was the parser in a comment at the + * beginning of the line? + * + * @param int $padTo minimum width of comment + * + * @return string + */ + private static function _addNote($line, $note, $inComment, $padTo) + { + return $inComment + ? '/* ' . str_pad($note, $padTo, ' ', STR_PAD_RIGHT) . ' *| ' . $line + : '/* ' . str_pad($note, $padTo, ' ', STR_PAD_RIGHT) . ' */ ' . $line; + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Logger.php b/plugins/Minify/extlib/minify/min/lib/Minify/Logger.php new file mode 100644 index 000000000..7844eea35 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Logger.php @@ -0,0 +1,45 @@ + + */ +class Minify_Logger { + + /** + * Set logger object. + * + * The object should have a method "log" that accepts a value as 1st argument and + * an optional string label as the 2nd. + * + * @param mixed $obj or a "falsey" value to disable + * @return null + */ + public static function setLogger($obj = null) { + self::$_logger = $obj + ? $obj + : null; + } + + /** + * Pass a message to the logger (if set) + * + * @param string $msg message to log + * @return null + */ + public static function log($msg, $label = 'Minify') { + if (! self::$_logger) return; + self::$_logger->log($msg, $label); + } + + /** + * @var mixed logger object (like FirePHP) or null (i.e. no logger available) + */ + private static $_logger = null; +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Packer.php b/plugins/Minify/extlib/minify/min/lib/Minify/Packer.php new file mode 100644 index 000000000..949c3eef0 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Packer.php @@ -0,0 +1,37 @@ +pack()); + } +} diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/Source.php b/plugins/Minify/extlib/minify/min/lib/Minify/Source.php new file mode 100644 index 000000000..5a85d10d0 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/Source.php @@ -0,0 +1,187 @@ + + */ +class Minify_Source { + + /** + * @var int time of last modification + */ + public $lastModified = null; + + /** + * @var callback minifier function specifically for this source. + */ + public $minifier = null; + + /** + * @var array minification options specific to this source. + */ + public $minifyOptions = null; + + /** + * @var string full path of file + */ + public $filepath = null; + + /** + * @var string HTTP Content Type (Minify requires one of the constants Minify::TYPE_*) + */ + public $contentType = null; + + /** + * Create a Minify_Source + * + * In the $spec array(), you can either provide a 'filepath' to an existing + * file (existence will not be checked!) or give 'id' (unique string for + * the content), 'content' (the string content) and 'lastModified' + * (unixtime of last update). + * + * As a shortcut, the controller will replace "//" at the beginning + * of a filepath with $_SERVER['DOCUMENT_ROOT'] . '/'. + * + * @param array $spec options + */ + public function __construct($spec) + { + if (isset($spec['filepath'])) { + if (0 === strpos($spec['filepath'], '//')) { + $spec['filepath'] = $_SERVER['DOCUMENT_ROOT'] . substr($spec['filepath'], 1); + } + $segments = explode('.', $spec['filepath']); + $ext = strtolower(array_pop($segments)); + switch ($ext) { + case 'js' : $this->contentType = 'application/x-javascript'; + break; + case 'css' : $this->contentType = 'text/css'; + break; + case 'htm' : // fallthrough + case 'html' : $this->contentType = 'text/html'; + break; + } + $this->filepath = $spec['filepath']; + $this->_id = $spec['filepath']; + $this->lastModified = filemtime($spec['filepath']) + // offset for Windows uploaders with out of sync clocks + + round(Minify::$uploaderHoursBehind * 3600); + } elseif (isset($spec['id'])) { + $this->_id = 'id::' . $spec['id']; + if (isset($spec['content'])) { + $this->_content = $spec['content']; + } else { + $this->_getContentFunc = $spec['getContentFunc']; + } + $this->lastModified = isset($spec['lastModified']) + ? $spec['lastModified'] + : time(); + } + if (isset($spec['contentType'])) { + $this->contentType = $spec['contentType']; + } + if (isset($spec['minifier'])) { + $this->minifier = $spec['minifier']; + } + if (isset($spec['minifyOptions'])) { + $this->minifyOptions = $spec['minifyOptions']; + } + } + + /** + * Get content + * + * @return string + */ + public function getContent() + { + $content = (null !== $this->filepath) + ? file_get_contents($this->filepath) + : ((null !== $this->_content) + ? $this->_content + : call_user_func($this->_getContentFunc, $this->_id) + ); + // remove UTF-8 BOM if present + return (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) + ? substr($content, 3) + : $content; + } + + /** + * Get id + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Verifies a single minification call can handle all sources + * + * @param array $sources Minify_Source instances + * + * @return bool true iff there no sources with specific minifier preferences. + */ + public static function haveNoMinifyPrefs($sources) + { + foreach ($sources as $source) { + if (null !== $source->minifier + || null !== $source->minifyOptions) { + return false; + } + } + return true; + } + + /** + * Get unique string for a set of sources + * + * @param array $sources Minify_Source instances + * + * @return string + */ + public static function getDigest($sources) + { + foreach ($sources as $source) { + $info[] = array( + $source->_id, $source->minifier, $source->minifyOptions + ); + } + return md5(serialize($info)); + } + + /** + * Get content type from a group of sources + * + * This is called if the user doesn't pass in a 'contentType' options + * + * @param array $sources Minify_Source instances + * + * @return string content type. e.g. 'text/css' + */ + public static function getContentType($sources) + { + foreach ($sources as $source) { + if ($source->contentType !== null) { + return $source->contentType; + } + } + return 'text/plain'; + } + + protected $_content = null; + protected $_getContentFunc = null; + protected $_id = null; +} + diff --git a/plugins/Minify/extlib/minify/min/lib/Minify/YUICompressor.php b/plugins/Minify/extlib/minify/min/lib/Minify/YUICompressor.php new file mode 100644 index 000000000..7cb61adbe --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Minify/YUICompressor.php @@ -0,0 +1,139 @@ + + * Minify_YUICompressor::$jarFile = '/path/to/yuicompressor-2.3.5.jar'; + * Minify_YUICompressor::$tempDir = '/tmp'; + * $code = Minify_YUICompressor::minifyJs( + * $code + * ,array('nomunge' => true, 'line-break' => 1000) + * ); + * + * + * @todo unit tests, $options docs + * + * @package Minify + * @author Stephen Clay + */ +class Minify_YUICompressor { + + /** + * Filepath of the YUI Compressor jar file. This must be set before + * calling minifyJs() or minifyCss(). + * + * @var string + */ + public static $jarFile = null; + + /** + * Writable temp directory. This must be set before calling minifyJs() + * or minifyCss(). + * + * @var string + */ + public static $tempDir = null; + + /** + * Filepath of "java" executable (may be needed if not in shell's PATH) + * + * @var string + */ + public static $javaExecutable = 'java'; + + /** + * Minify a Javascript string + * + * @param string $js + * + * @param array $options (verbose is ignored) + * + * @see http://www.julienlecomte.net/yuicompressor/README + * + * @return string + */ + public static function minifyJs($js, $options = array()) + { + return self::_minify('js', $js, $options); + } + + /** + * Minify a CSS string + * + * @param string $css + * + * @param array $options (verbose is ignored) + * + * @see http://www.julienlecomte.net/yuicompressor/README + * + * @return string + */ + public static function minifyCss($css, $options = array()) + { + return self::_minify('css', $css, $options); + } + + private static function _minify($type, $content, $options) + { + self::_prepare(); + if (! ($tmpFile = tempnam(self::$tempDir, 'yuic_'))) { + throw new Exception('Minify_YUICompressor : could not create temp file.'); + } + file_put_contents($tmpFile, $content); + exec(self::_getCmd($options, $type, $tmpFile), $output); + unlink($tmpFile); + return implode("\n", $output); + } + + private static function _getCmd($userOptions, $type, $tmpFile) + { + $o = array_merge( + array( + 'charset' => '' + ,'line-break' => 5000 + ,'type' => $type + ,'nomunge' => false + ,'preserve-semi' => false + ,'disable-optimizations' => false + ) + ,$userOptions + ); + $cmd = self::$javaExecutable . ' -jar ' . escapeshellarg(self::$jarFile) + . " --type {$type}" + . (preg_match('/^[a-zA-Z\\-]+$/', $o['charset']) + ? " --charset {$o['charset']}" + : '') + . (is_numeric($o['line-break']) && $o['line-break'] >= 0 + ? ' --line-break ' . (int)$o['line-break'] + : ''); + if ($type === 'js') { + foreach (array('nomunge', 'preserve-semi', 'disable-optimizations') as $opt) { + $cmd .= $o[$opt] + ? " --{$opt}" + : ''; + } + } + return $cmd . ' ' . escapeshellarg($tmpFile); + } + + private static function _prepare() + { + if (! is_file(self::$jarFile) + || ! is_dir(self::$tempDir) + || ! is_writable(self::$tempDir) + ) { + throw new Exception('Minify_YUICompressor : $jarFile and $tempDir must be set.'); + } + } +} + diff --git a/plugins/Minify/extlib/minify/min/lib/Solar/Dir.php b/plugins/Minify/extlib/minify/min/lib/Solar/Dir.php new file mode 100644 index 000000000..37f716962 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/lib/Solar/Dir.php @@ -0,0 +1,199 @@ + + * + * @license http://opensource.org/licenses/bsd-license.php BSD + * + * @version $Id: Dir.php 2926 2007-11-09 16:25:44Z pmjones $ + * + */ +class Solar_Dir { + + /** + * + * The OS-specific temporary directory location. + * + * @var string + * + */ + protected static $_tmp; + + /** + * + * Hack for [[php::is_dir() | ]] that checks the include_path. + * + * Use this to see if a directory exists anywhere in the include_path. + * + * {{code: php + * $dir = Solar_Dir::exists('path/to/dir') + * if ($dir) { + * $files = scandir($dir); + * } else { + * echo "Not found in the include-path."; + * } + * }} + * + * @param string $dir Check for this directory in the include_path. + * + * @return mixed If the directory exists in the include_path, returns the + * absolute path; if not, returns boolean false. + * + */ + public static function exists($dir) + { + // no file requested? + $dir = trim($dir); + if (! $dir) { + return false; + } + + // using an absolute path for the file? + // dual check for Unix '/' and Windows '\', + // or Windows drive letter and a ':'. + $abs = ($dir[0] == '/' || $dir[0] == '\\' || $dir[1] == ':'); + if ($abs && is_dir($dir)) { + return $dir; + } + + // using a relative path on the file + $path = explode(PATH_SEPARATOR, ini_get('include_path')); + foreach ($path as $base) { + // strip Unix '/' and Windows '\' + $target = rtrim($base, '\\/') . DIRECTORY_SEPARATOR . $dir; + if (is_dir($target)) { + return $target; + } + } + + // never found it + return false; + } + + /** + * + * "Fixes" a directory string for the operating system. + * + * Use slashes anywhere you need a directory separator. Then run the + * string through fixdir() and the slashes will be converted to the + * proper separator (for example '\' on Windows). + * + * Always adds a final trailing separator. + * + * @param string $dir The directory string to 'fix'. + * + * @return string The "fixed" directory string. + * + */ + public static function fix($dir) + { + $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir); + return rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + } + + /** + * + * Convenience method for dirname() and higher-level directories. + * + * @param string $file Get the dirname() of this file. + * + * @param int $up Move up in the directory structure this many + * times, default 0. + * + * @return string The dirname() of the file. + * + */ + public static function name($file, $up = 0) + { + $dir = dirname($file); + while ($up --) { + $dir = dirname($dir); + } + return $dir; + } + + /** + * + * Returns the OS-specific directory for temporary files. + * + * @param string $sub Add this subdirectory to the returned temporary + * directory name. + * + * @return string The temporary directory path. + * + */ + public static function tmp($sub = '') + { + // find the tmp dir if needed + if (! Solar_Dir::$_tmp) { + + // use the system if we can + if (function_exists('sys_get_temp_dir')) { + $tmp = sys_get_temp_dir(); + } else { + $tmp = Solar_Dir::_tmp(); + } + + // remove trailing separator and save + Solar_Dir::$_tmp = rtrim($tmp, DIRECTORY_SEPARATOR); + } + + // do we have a subdirectory request? + $sub = trim($sub); + if ($sub) { + // remove leading and trailing separators, and force exactly + // one trailing separator + $sub = trim($sub, DIRECTORY_SEPARATOR) + . DIRECTORY_SEPARATOR; + } + + return Solar_Dir::$_tmp . DIRECTORY_SEPARATOR . $sub; + } + + /** + * + * Returns the OS-specific temporary directory location. + * + * @return string The temp directory path. + * + */ + protected static function _tmp() + { + // non-Windows system? + if (strtolower(substr(PHP_OS, 0, 3)) != 'win') { + $tmp = empty($_ENV['TMPDIR']) ? getenv('TMPDIR') : $_ENV['TMPDIR']; + if ($tmp) { + return $tmp; + } else { + return '/tmp'; + } + } + + // Windows 'TEMP' + $tmp = empty($_ENV['TEMP']) ? getenv('TEMP') : $_ENV['TEMP']; + if ($tmp) { + return $tmp; + } + + // Windows 'TMP' + $tmp = empty($_ENV['TMP']) ? getenv('TMP') : $_ENV['TMP']; + if ($tmp) { + return $tmp; + } + + // Windows 'windir' + $tmp = empty($_ENV['windir']) ? getenv('windir') : $_ENV['windir']; + if ($tmp) { + return $tmp; + } + + // final fallback for Windows + return getenv('SystemRoot') . '\\temp'; + } +} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min/utils.php b/plugins/Minify/extlib/minify/min/utils.php new file mode 100644 index 000000000..c73594152 --- /dev/null +++ b/plugins/Minify/extlib/minify/min/utils.php @@ -0,0 +1,90 @@ + + * + * + * + * + * If you do not want ampersands as HTML entities, set Minify_Build::$ampersand = "&" + * before using this function. + * + * @param string $group a key from groupsConfig.php + * @param boolean $forceAmpersand (default false) Set to true if the RewriteRule + * directives in .htaccess are functional. This will remove the "?" from URIs, making them + * more cacheable by proxies. + * @return string + */ +function Minify_groupUri($group, $forceAmpersand = false) +{ + $path = $forceAmpersand + ? "/g={$group}" + : "/?g={$group}"; + return _Minify_getBuild($group)->uri( + '/' . basename(dirname(__FILE__)) . $path + ,$forceAmpersand + ); +} + + +/** + * Get the last modification time of the source js/css files used by Minify to + * build the page. + * + * If you're caching the output of Minify_groupUri(), you'll want to rebuild + * the cache if it's older than this timestamp. + * + * + * // simplistic HTML cache system + * $file = '/path/to/cache/file'; + * if (! file_exists($file) || filemtime($file) < Minify_groupsMtime(array('js', 'css'))) { + * // (re)build cache + * $page = buildPage(); // this calls Minify_groupUri() for js and css + * file_put_contents($file, $page); + * echo $page; + * exit(); + * } + * readfile($file); + * + * + * @param array $groups an array of keys from groupsConfig.php + * @return int Unix timestamp of the latest modification + */ +function Minify_groupsMtime($groups) +{ + $max = 0; + foreach ((array)$groups as $group) { + $max = max($max, _Minify_getBuild($group)->lastModified); + } + return $max; +} + +/** + * @param string $group a key from groupsConfig.php + * @return Minify_Build + * @private + */ +function _Minify_getBuild($group) +{ + static $builds = array(); + static $gc = false; + if (false === $gc) { + $gc = (require dirname(__FILE__) . '/groupsConfig.php'); + } + if (! isset($builds[$group])) { + $builds[$group] = new Minify_Build($gc[$group]); + } + return $builds[$group]; +} diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/2.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/2.php new file mode 100644 index 000000000..9b66f2493 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/2.php @@ -0,0 +1,44 @@ + $lastModified +)); +if ($cg->cacheIsValid) { + $cg->sendHeaders(); + // we're done + exit(); +} + +// generate content +$title = 'Last-Modified is known : add Content-Length'; +$explain = ' +

    Here, like the first example, we know the Last-Modified time, +but we also want to set the Content-Length to increase cacheability and allow +HTTP persistent connections. Instead of sending headers immediately, we first +generate our content, then use setContentLength(strlen($content)) +to add the header. Then finally call sendHeaders() and send the +content.

    +

    Note: This is not required if your PHP config buffers all +output and your script doesn\'t do any incremental flushing of the output +buffer. PHP will generally set Content-Length for you if it can.

    +

    This script emulates a document that changes every ' .$every. ' seconds. +
    This is version: ' . date('r', $lastModified) . '

    +'; + +require '_include.php'; +$content = get_content(array( + 'title' => $title + ,'explain' => $explain +)); + +$cg->setContentLength(strlen($content)); +$cg->sendHeaders(); +send_slowly($content); + diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/3.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/3.php new file mode 100644 index 000000000..8f5482ba8 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/3.php @@ -0,0 +1,40 @@ +When Last-Modified is unknown, you can still use ETags, but you need a short +string that is unique for that content. In the worst case, you have to generate +all the content first, then instantiate HTTP_ConditionalGet, setting +the array key contentHash to the output of a hash function of the +content. Since we have the full content, we might as well also use +setContentLength(strlen($content)) in the case where we need to +send it.

    +

    This script emulates a document that changes every ' .$every. ' seconds. +
    This is version: ' . date('r', $lastModified) . '

    +'; +require '_include.php'; +$content = get_content(array( + 'title' => $title + ,'explain' => $explain +)); + +$cg = new HTTP_ConditionalGet(array( + 'contentHash' => substr(md5($content), 7) +)); +if ($cg->cacheIsValid) { + $cg->sendHeaders(); + // we're done + exit(); +} +$cg->setContentLength(strlen($content)); +$cg->sendHeaders(); + +send_slowly($content); + diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/4.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/4.php new file mode 100644 index 000000000..4b77d2084 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/4.php @@ -0,0 +1,49 @@ + $lastModified + ,'encoding' => $enc +)); +$cg->sendHeaders(); +if ($cg->cacheIsValid) { + // we're done + exit(); +} + +// output encoded content + +$title = 'ConditionalGet + Encoder'; +$explain = ' +

    Using ConditionalGet and Encoder is straightforward. First impliment the +ConditionalGet, then if the cache is not valid, encode and send the content

    +

    This script emulates a document that changes every ' .$every. ' seconds. +
    This is version: ' . date('r', $lastModified) . '

    +'; +require '_include.php'; +$content = get_content(array( + 'title' => $title + ,'explain' => $explain +)); + +$he = new HTTP_Encoder(array( + 'content' => get_content(array( + 'title' => $title + ,'explain' => $explain + )) +)); +$he->encode(); + +// usually you would just $he->sendAll(), but here we want to emulate slow +// connection +$he->sendHeaders(); +send_slowly($he->getContent()); diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/5.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/5.php new file mode 100644 index 000000000..b443c1973 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/5.php @@ -0,0 +1,27 @@ + 20 + ,'lastModifiedTime' => filemtime(__FILE__) +)); +$cg->sendHeaders(); + +// generate, send content +$title = 'Last-Modified + Expires'; +$explain = ' +

    Here we set a static "lastModifiedTime" and "maxAge" to 20. The browser +will consider this document fresh for 20 seconds, then revalidate its cache. After +the 304 response, the cache will be good for another 20 seconds. Unless you force +a reload, there will only be 304 responses for this page after the initial download. +'; + +require '_include.php'; +echo get_content(array( + 'title' => $title + ,'explain' => $explain +)); + diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/_include.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/_include.php new file mode 100644 index 000000000..9b65ae12e --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/_include.php @@ -0,0 +1,64 @@ + + + + + +HTTP_ConditionalGet : <?php echo $data['title']; ?> + + +

    HTTP_ConditionalGet

    +

    + + +

    Notes

    +

    How to distinguish 200 and 304 responses

    +

    For these pages all 200 responses are sent in chunks a second apart, so you +should notice that 304 responses are quicker. You can also use HTTP sniffers +like Fiddler (win) and +LiveHTTPHeaders (Firefox add-on) +to verify headers and content being sent.

    +

    Browser notes

    +
    +
    Opera
    +
    Opera has a couple behaviors against the HTTP spec: Manual refreshes (F5) + prevents the ETag/If-Modified-Since headers from being sent; it only sends + them when following a link or bookmark. Also, Opera will not honor the + must-revalidate Cache-Control value unless max-age + is set. To get Opera to follow the spec, ConditionalGet will send Opera max-age=0 + (if one is not already set).
    +
    Safari
    +
    ETag validation is unsupported, but Safari supports HTTP/1.0 validation via + If-Modified-Since headers as long as the cache is explicitly marked + "public" or "private" ("private" is default in ConditionalGet).
    +
    + + + $lastModified +)); +$cg->sendHeaders(); +if ($cg->cacheIsValid) { + // we're done + exit(); +} + +$title = 'Last-Modified is known : simple usage'; +$explain = ' +

    If your content has not changed since a certain timestamp, set this via the +the lastModifiedTime array key when instantiating HTTP_ConditionalGet. +You can immediately call the method sendHeaders() to set the +Last-Modified, ETag, and Cache-Control headers. The, if cacheIsValid +property is false, you echo the content.

    +

    This script emulates a document that changes every ' .$every. ' seconds. +
    This is version: ' . date('r', $lastModified) . '

    +'; + +require '_include.php'; + +echo send_slowly(get_content(array( + 'title' => $title + ,'explain' => $explain +))); + diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/green.png b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/green.png new file mode 100644 index 000000000..d9d3a308a Binary files /dev/null and b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/green.png differ diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/index.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/index.php new file mode 100644 index 000000000..c9a391d07 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/index.php @@ -0,0 +1,60 @@ + + + + +HTTP_Encoder Test + + + +

    HTTP_Encoder test

    +

    HTML

    +

    CSS

    +

    Javascript

    +

    image

    + + + + $content + ,'type' => $type +)); +$he->encode(); +$he->sendAll(); + +?> \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_inc.php b/plugins/Minify/extlib/minify/min_unit_tests/_inc.php new file mode 100644 index 000000000..bf416d4bb --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_inc.php @@ -0,0 +1,50 @@ +0, 'fail'=>0, 'total'=>0); + + $mode = $test ? 'pass' : 'fail'; + $outMode = $test ? 'PASS' : '!FAIL'; + printf("%s: %s (%d of %d tests run so far have %sed)\n", + $outMode, $message, ++$count[$mode], ++$count['total'], $mode); + + return (bool)$test; +} + +ob_start(); \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.css new file mode 100644 index 000000000..2ef9fac49 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.css @@ -0,0 +1,9 @@ + +/* block comments get removed */ + +/*! YUI Compressor style comments are preserved */ + +/* but all other comments are removed */ + +/* comments that have any surrounding whitespace are replaced by a single space. */ +body{ background:#fff/*eef*/ url(/path/to/image.gif) repeat-y; } diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.min.css new file mode 100644 index 000000000..3ea5c61a6 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.min.css @@ -0,0 +1,3 @@ + +/* YUI Compressor style comments are preserved */ +body{background:#fff url(/path/to/image.gif) repeat-y} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.css new file mode 100644 index 000000000..fccd32166 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.css @@ -0,0 +1,66 @@ +/* hide from ie5/mac \*/ a{} +.foo {color:red} +/* necessary comment */ + +/* comment to attempt to confuse parser */ + +/* feed to ie5/mac \*//*/ +@import "ie5mac.css"; +/* necessary comment */ + +/* comment to attempt to confuse parser */ + +/*/ hide from nav4 */ +.foo {display:block;} +/* necessary comment */ + +/* comment to attempt to confuse parser */ + +/*/ feed to nav *//*/ +.foo {display:crazy;} +/* necessary comment */ + +/* hide props from various IE/win */ +div { + width: 140px; + width/* */:/**/100px; + width: /**/100px; +} + +html>/**/body {} + +/* Tantek's box model hack */ +div { + width:400px; + voice-family: "\"}\""; + voice-family:inherit; + width:300px; +} + +/* don't minimize hex colors in filters */ +div { + filter:chroma(color=#aabbcc); + filter:mask(color=#000000) shadow(color=#9BAD71, direction=135) chroma(color=#000000); +} + +@media screen { + /* for IE 5.x-6, hidden from IE 5 Mac */ /*\*/ + * html div#page { + height: 1%; + } + /**/ /* end hidden from IE 5 Mac */ +} + +foo { /* filters for IE */ + _height : 20px; + *height : 15px; +} + +/* http://tantek.com/CSS/Examples/midpass.html */ +@media tty { + i{content:"\";/*" "*/}} @import 'midpassafter.css'; /*";} +}/* */ + +/* leave at least 1 space between these pseudo elements and "{" for IE6: http://www.crankygeek.com/ie6pebug/ */ +p:first-letter {color:red;} +p:first-line {color:red;} diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.min.css new file mode 100644 index 000000000..68be2ee89 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.min.css @@ -0,0 +1,4 @@ +/*\*/a{}.foo{color:red}/**/ /*\*//*/@import "ie5mac.css";/**/ /*/*/.foo{display:block}/**/ /*/*//*/.foo{display:crazy}/**/ div{width:140px;width/**/:/**/100px;width:/**/100px}html>/**/body{}div{width:400px;voice-family:"\"}\"";voice-family:inherit;width:300px}div{filter:chroma(color=#aabbcc);filter:mask(color=#000000) shadow(color=#9BAD71, direction=135) chroma(color=#000000)}@media +screen{/*\*/* html +div#page{height:1%}/**/}foo{_height:20px;*height:15px}@media +tty{i{content:"\";/*" "*/}}@import 'midpassafter.css';/*"}}/* */ p:first-letter {color:red}p:first-line {color:red} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.css new file mode 100644 index 000000000..006c7a22f --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.css @@ -0,0 +1,890 @@ +/* +* DEFINITION DES STYLES DE TEXTE +*/ + /*-----------------------------------------------------------------------------------*/ +h1 { + color: #339933; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + font-weight: bold; + text-decoration: none; +} + +h2 { + color: #339933; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + font-weight: bold; + text-decoration: none; +} + +h1,h2,h3,h4,h5 { + margin: 0px; + padding: 0px; +} + +.txt_10_noir { + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_noir:link,.txt_10_noir:visited,.txt_10_noir:active { + color: black; +} + +.txt_10_noir:hover { + color: red; +} + +.txt_11_noir { + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_noir:link,.txt_11_noir:visited,.txt_11_noir:active { + color: black; +} + +.txt_11_noir:hover { + color: red; +} + +.txt_12_noir { + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_noir:link,.txt_12_noir:visited,.txt_12_noir:active { + color: black; +} + +.txt_12_noir:hover { + color: red; +} + +.txt_14_noir { + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_noir:link,.txt_14_noir:visited,.txt_14_noir:active { + color: black; +} + +.txt_14_noir:hover { + color: red; +} + +/*-----------------------------------------------------------------------------------*/ +.txt_10_gris { + color: grey; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_gris:link,.txt_10_gris:visited,.txt_10_gris:active { + color: grey; +} + +.txt_10_gris:hover { + color: red; +} + +.txt_11_gris { + color: grey; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_gris:link,.txt_11_gris:visited,.txt_11_gris:active { + color: grey; +} + +.txt_11_gris:hover { + color: red; +} + +.txt_12_gris { + color: grey; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_gris:link,.txt_12_gris:visited,.txt_12_gris:active { + color: grey; +} + +.txt_12_gris:hover { + color: red; +} + +.txt_14_gris { + color: grey; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_gris:link,.txt_14_gris:visited,.txt_14_gris:active { + color: grey; +} + +.txt_14_gris:hover { + color: red; +} + +/*-----------------------------------------------------------------------------------*/ +.txt_10_blanc { + color: #FFFFFF; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_blanc:link,.txt_10_blanc:visited,.txt_10_blanc:active { + color: #FFFFFF; +} + +.txt_10_blanc:hover { + color: #FF8800; /*ORANGE*/ +} + +.txt_11_blanc { + color: #FFFFFF; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_blanc:link,.txt_11_blanc:visited,.txt_11_blanc:active { + color: #FFFFFF; +} + +.txt_11_blanc:hover { + color: #FF8800; +} + +.txt_12_blanc { + color: #FFFFFF; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_blanc:link,.txt_12_blanc:visited,.txt_12_blanc:active { + color: #FFFFFF; +} + +.txt_12_blanc:hover { + color: #FFAA00; +} + +.txt_14_blanc { + color: #FFFFFF; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_blanc:link,.txt_14_blanc:visited,.txt_14_blanc:active { + color: #FFFFFF; +} + +.txt_14_blanc:hover { + color: #FF8800; +} + +/*-----------------------------------------------------------------------------------*/ +.txt_10_orange { + color: #FF8800; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_orange:link,.txt_10_orange:visited,.txt_10_orange:active { + color: #FF8800; +} + +.txt_10_orange:hover { + color: darkblue +} + +.txt_11_orange { + color: #FF8800; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_orange:link,.txt_11_orange:visited,.txt_11_orange:active { + color: #FF8800; +} + +.txt_11_orange:hover { + color: darkblue; +} + +.txt_12_orange { + color: #FF8800; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_orange:link,.txt_12_orange:visited,.txt_12_orange:active { + color: #FF8800; +} + +.txt_12_orange:hover { + color: darkblue; +} + +.txt_14_orange { + color: #FF8800; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_orange:link,.txt_14_orange:visited,.txt_14_orange:active { + color: #FF8800; +} + +.txt_14_orange:hover { + color: darkblue; +} + +/*-----------------------------------------------------------------------------------*/ +.txt_10_rouge { + color: red; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_rouge:link,.txt_10_rouge:visited,.txt_10_rouge:active { + color: red; +} + +.txt_10_rouge:hover { + color: darkblue; +} + +.txt_11_rouge { + color: red; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_rouge:link,.txt_11_rouge:visited,.txt_11_rouge:active { + color: red; +} + +.txt_11_rouge:hover { + color: darkblue; +} + +.txt_12_rouge { + color: red; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_rouge:link,.txt_12_rouge:visited,.txt_12_rouge:active { + color: red; +} + +.txt_12_rouge:hover { + color: darkblue; +} + +.txt_14_rouge { + color: red; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_rouge:link,.txt_14_rouge:visited,.txt_14_rouge:active { + color: red; +} + +.txt_14_rouge:hover { + color: darkblue; +} + +/*-----------------------------------------------------------------------------------*/ +.txt_10_bleu { + color: blue; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_bleu:link,.txt_10_bleu:visited,.txt_10_bleu:active { + color: blue; +} + +.txt_10_bleu:hover { + color: red; +} + +.txt_11_bleu { + color: blue; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_bleu:link,.txt_11_bleu:visited,.txt_11_bleu:active { + color: blue; +} + +.txt_11_bleu:hover { + color: red; +} + +.txt_12_bleu { + color: blue; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_bleu:link,.txt_12_bleu:visited,.txt_12_bleu:active { + color: blue; +} + +.txt_12_bleu:hover { + color: red; +} + +.txt_14_bleu { + color: blue; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_bleu:link,.txt_14_bleu:visited,.txt_14_bleu:active { + color: blue; +} + +.txt_14_bleu:hover { + color: red; +} + +/*-----------------------------------------------------------------------------------*/ +.txt_10_bleu_f { + color: darkblue; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_bleu_f:link,.txt_10_bleu_f:visited,.txt_10_bleu_f:active { + color: darkblue; +} + +.txt_10_bleu_f:hover { + color: red; +} + +.txt_11_bleu_f { + color: darkblue; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_bleu_f:link,.txt_11_bleu_f:visited,.txt_11_bleu_f:active { + color: darkblue; +} + +.txt_11_bleu_f:hover { + color: red; +} + +.txt_12_bleu_f { + color: darkblue; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_bleu_f:link,.txt_12_bleu_f:visited,.txt_12_bleu_f:active { + color: darkblue; +} + +.txt_12_bleu_f:hover { + color: red; +} + +.txt_14_bleu_f { + color: darkblue; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_bleu_f:link,.txt_14_bleu_f:visited,.txt_14_bleu_f:active { + color: darkblue; +} + +.txt_14_bleu_f:hover { + color: red; +} + +/*-----------------------------------------------------------------------------------*/ +.txt_10_vert_f { + color: darkgreen; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_vert_f:link,.txt_10_vert_f:visited,.txt_10_vert_f:active { + color: darkgreen; +} + +.txt_10_vert_f:hover { + color: red; +} + +.txt_11_vert_f { + color: darkgreen; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_vert_f:link,.txt_11_vert_f:visited,.txt_11_vert_f:active { + color: darkgreen; +} + +.txt_11_vert_f:hover { + color: red; +} + +.txt_12_vert_f { + color: darkgreen; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_vert_f:link,.txt_12_vertf:visited,.txt_12_vert_f:active { + color: darkgreen; +} + +.txt_12_vert_f:hover { + color: red; +} + +.txt_14_vert_f { + color: darkgreen; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_vert_f:link,.txt_14_vert_f:visited,.txt_14_vert_f:active { + color: darkgreen; +} + +.txt_14_vert_f:hover { + color: red; +} + +/*-----------------------------------------------------------------------------------*/ +.txt_10_vert { + color: green; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.txt_10_vert:link,.txt_10_vert:visited,.txt_10_vert:active { + color: green; +} + +.txt_10_vert:hover { + color: red; +} + +.txt_11_vert { + color: green; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.txt_11_vert:link,.txt_11_vert:visited,.txt_11_vert:active { + color: green; +} + +.txt_11_vert:hover { + color: red; +} + +.txt_12_vert { + color: green; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + text-decoration: none; +} + +.txt_12_vert:link,.txt_12_vert:visited,.txt_12_vert:active { + color: green; +} + +.txt_12_vert:hover { + color: red; +} + +.txt_14_vert { + color: green; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 14px; + text-decoration: none; +} + +.txt_14_vert:link,.txt_14_vert:visited,.txt_14_vert:active { + color: green; +} + +.txt_14_vert:hover { + color: red; +} + +/*-----------------------------------------------------------------------------------*/ +.fond_blanc { + background-color: #FFFFFF; + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.fond_gris_c, .fond_gris_c tr { + background-color: #FFFFFF; + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; + background-image: url(../images/fond_4.bmp); + background-repeat: repeat-x; +} + +.fond_gris_c2, .fond_gris_c2 tr { + background-color: #FBFBFB; + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.fond_bleu_c, .fond_bleu_c tr { + background-color: #D9EEF9; + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; + background-image: url(../images/fond_1.bmp); +} + +.fond_bleu_c2 { + background-color: #ECF4FF; + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.fond_bleu_f { + background-color: #003366; + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.fond_orange { + background-color: #FEEFE7; + color: darkgreen; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + font-weight: bold; + text-decoration: none; + background-image: url(../images/fond_3.jpg); +} + +.fond_orange_2 { + background-color: #FFF8F4; + color: darkgreen; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + font-weight: bold; + text-decoration: none; + border: 1px solid orange; + border-collapse: collapse; +} + +.vccDlgBody { + border: 3px solid #336699; + border-collapse: collapse; + color: black; + background-color: #EEFFEE; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +/* DEFINITION DES STYLES DE TABLEAUX */ +.bordure_0 { + border: 0px solid; + color: black; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.bordure_1_bleu { + border: 1px solid green; + border-collapse: collapse; + color: black; + background-color: #FFFFFF; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.bordure_3_bleu { + border: 3px solid #336699; + border-collapse: collapse; + color: black; + background-color: #FFFFFF; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 11px; + text-decoration: none; +} + +.indent { + margin-left: 20px; +} + +/* DEFINITION DES STYLES D'OBJETS DE FORMULAIRE */ +.Btn { + color: #003366; + text-align: center; + font-weight: bold; + background-color: #FFFFFF; + background-image: url(../images/ongletStyle1.jpg); + background-repeat: no-repeat; + background-position: center center; +} + +.Btn:hover { + color: red; +} + +.menu1h { + background-color: #003366; + color: white; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + font-weight: bold; + text-decoration: none; + border-top: 1px solid #003366; + border-bottom: 1px solid #003366; + border-left: 1px solid #003366; + border-right: 1px solid white; + border-collapse: collapse; + display: block; +} + +.menu1h:hover { + background-color: white; + color: red; + border: 1px solid darkgreen; + border-collapse: collapse; +} + +.menu1h_f { + background-color: #003366; + color: white; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + font-weight: bold; + text-decoration: none; + border: 1px solid #003366; + display: block; +} + +.menu1h_f:hover { + background-color: white; + color: red; + border: 1px solid darkgreen; + border-collapse: collapse; +} + +.menu1v { + background-color: #003366; + color: white; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + font-weight: bold; + text-decoration: none; + border: 1px solid #003366; + border-collapse: collapse; + display: block; +} + +.menu1v:hover { + background-color: white; + color: red; + border: 1px solid darkgreen; + border-collapse: collapse; +} + +.menu2v { + background-color: #5588BB; + color: white; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 12px; + font-weight: bold; + text-decoration: none; + border: 1px solid #4277AB; + border-collapse: collapse; + float: left; + display: block; +} + +.menu2v:hover { + background-color: white; + color: red; + border: 1px solid darkgreen; + border-collapse: collapse; +} + +.menuEDF { + background-color: #003366; + color: white; + font-family: Verdana, Arial, Lucida, Tahoma; + font-size: 10px; + text-decoration: none; +} + +.menuEDF:hover { + color: #FF8800; +} + +/*bouton bleu sur blanc*/ +.Bouton { + color: #003366; + text-align: center; + font-weight: bold; + /* Ricardo cursor: hand; */ + cursor: pointer; + background-color: #FFFFFF; +} + +input { + border: 2px solid green; + color: #003366; + background-color: #FFFFFF; + background-image: url(../images/fond_4.bmp); + background-repeat: repeat-x; +} + +.disabled_input { + border: 1px solid gray; + color: grey; + background-color: #FFFFFF; + background-image: url(../images/fond_4.bmp); + background-repeat: repeat-x; +} + +.input0 { + border: 0px; + color: #003366; + background-color: #FFFFFF; + background-image: url(../images/fond_4.bmp); +} + +.input2 { + border: 1px solid green; + color: #003366; + background-color: #FFFFFF; + background-image: url(../images/fond_4.bmp); + background-repeat: repeat-x; +} + +.input3 { + border: 1px solid black; + color: #003366; + background-color: #EEEEEE; + background-image: url(); +} + +.input4 { + border: 1px solid blue; + color: #003366; + background-color: #FFFFFF; + background-image: url(../images/fond_4.bmp); + background-repeat: repeat-x; +} + +.input5 { + border: 1px solid darkblue; + color: #003366; + background-color: #FFFFFF; + background-image: url(../images/fond_4.bmp); + background-repeat: repeat-x; +} + +.input_btn { + border: 0px; + /* cursor: hand; */ + cursor: pointer; +} + +textarea { + border: 2px solid green; + color: #003366; + background-color: #FFFFFF; + background-image: url(../images/fond_5.bmp); +} + +.TEXTAREA3 { + border: 1px solid green; + color: #003366; + background-color: #FFFFFF; + background-image: url(); +} + +.TEXTAREA4 { + border: 1px solid green; + color: #003366; + background-color: #EEEEEE; + background-image: url(); +} + +.hand { + cursor: hand; + cursor: pointer; +} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.min.css new file mode 100644 index 000000000..5eb198228 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.min.css @@ -0,0 +1,25 @@ +h1{color:#393;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;font-weight:bold;text-decoration:none}h2{color:#393;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;font-weight:bold;text-decoration:none}h1,h2,h3,h4,h5{margin:0px;padding:0px}.txt_10_noir{color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_noir:link,.txt_10_noir:visited,.txt_10_noir:active{color:black}.txt_10_noir:hover{color:red}.txt_11_noir{color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_noir:link,.txt_11_noir:visited,.txt_11_noir:active{color:black}.txt_11_noir:hover{color:red}.txt_12_noir{color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_noir:link,.txt_12_noir:visited,.txt_12_noir:active{color:black}.txt_12_noir:hover{color:red}.txt_14_noir{color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_noir:link,.txt_14_noir:visited,.txt_14_noir:active{color:black}.txt_14_noir:hover{color:red}.txt_10_gris{color:grey;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_gris:link,.txt_10_gris:visited,.txt_10_gris:active{color:grey}.txt_10_gris:hover{color:red}.txt_11_gris{color:grey;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_gris:link,.txt_11_gris:visited,.txt_11_gris:active{color:grey}.txt_11_gris:hover{color:red}.txt_12_gris{color:grey;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_gris:link,.txt_12_gris:visited,.txt_12_gris:active{color:grey}.txt_12_gris:hover{color:red}.txt_14_gris{color:grey;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_gris:link,.txt_14_gris:visited,.txt_14_gris:active{color:grey}.txt_14_gris:hover{color:red}.txt_10_blanc{color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_blanc:link,.txt_10_blanc:visited,.txt_10_blanc:active{color:#FFF}.txt_10_blanc:hover{color:#F80}.txt_11_blanc{color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_blanc:link,.txt_11_blanc:visited,.txt_11_blanc:active{color:#FFF}.txt_11_blanc:hover{color:#F80}.txt_12_blanc{color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_blanc:link,.txt_12_blanc:visited,.txt_12_blanc:active{color:#FFF}.txt_12_blanc:hover{color:#FA0}.txt_14_blanc{color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_blanc:link,.txt_14_blanc:visited,.txt_14_blanc:active{color:#FFF}.txt_14_blanc:hover{color:#F80}.txt_10_orange{color:#F80;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_orange:link,.txt_10_orange:visited,.txt_10_orange:active{color:#F80}.txt_10_orange:hover{color:darkblue}.txt_11_orange{color:#F80;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_orange:link,.txt_11_orange:visited,.txt_11_orange:active{color:#F80}.txt_11_orange:hover{color:darkblue}.txt_12_orange{color:#F80;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_orange:link,.txt_12_orange:visited,.txt_12_orange:active{color:#F80}.txt_12_orange:hover{color:darkblue}.txt_14_orange{color:#F80;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_orange:link,.txt_14_orange:visited,.txt_14_orange:active{color:#F80}.txt_14_orange:hover{color:darkblue}.txt_10_rouge{color:red;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_rouge:link,.txt_10_rouge:visited,.txt_10_rouge:active{color:red}.txt_10_rouge:hover{color:darkblue}.txt_11_rouge{color:red;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_rouge:link,.txt_11_rouge:visited,.txt_11_rouge:active{color:red}.txt_11_rouge:hover{color:darkblue}.txt_12_rouge{color:red;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_rouge:link,.txt_12_rouge:visited,.txt_12_rouge:active{color:red}.txt_12_rouge:hover{color:darkblue}.txt_14_rouge{color:red;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_rouge:link,.txt_14_rouge:visited,.txt_14_rouge:active{color:red}.txt_14_rouge:hover{color:darkblue}.txt_10_bleu{color:blue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_bleu:link,.txt_10_bleu:visited,.txt_10_bleu:active{color:blue}.txt_10_bleu:hover{color:red}.txt_11_bleu{color:blue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_bleu:link,.txt_11_bleu:visited,.txt_11_bleu:active{color:blue}.txt_11_bleu:hover{color:red}.txt_12_bleu{color:blue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_bleu:link,.txt_12_bleu:visited,.txt_12_bleu:active{color:blue}.txt_12_bleu:hover{color:red}.txt_14_bleu{color:blue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_bleu:link,.txt_14_bleu:visited,.txt_14_bleu:active{color:blue}.txt_14_bleu:hover{color:red}.txt_10_bleu_f{color:darkblue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_bleu_f:link,.txt_10_bleu_f:visited,.txt_10_bleu_f:active{color:darkblue}.txt_10_bleu_f:hover{color:red}.txt_11_bleu_f{color:darkblue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_bleu_f:link,.txt_11_bleu_f:visited,.txt_11_bleu_f:active{color:darkblue}.txt_11_bleu_f:hover{color:red}.txt_12_bleu_f{color:darkblue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_bleu_f:link,.txt_12_bleu_f:visited,.txt_12_bleu_f:active{color:darkblue}.txt_12_bleu_f:hover{color:red}.txt_14_bleu_f{color:darkblue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_bleu_f:link,.txt_14_bleu_f:visited,.txt_14_bleu_f:active{color:darkblue}.txt_14_bleu_f:hover{color:red}.txt_10_vert_f{color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_vert_f:link,.txt_10_vert_f:visited,.txt_10_vert_f:active{color:darkgreen}.txt_10_vert_f:hover{color:red}.txt_11_vert_f{color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_vert_f:link,.txt_11_vert_f:visited,.txt_11_vert_f:active{color:darkgreen}.txt_11_vert_f:hover{color:red}.txt_12_vert_f{color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_vert_f:link,.txt_12_vertf:visited,.txt_12_vert_f:active{color:darkgreen}.txt_12_vert_f:hover{color:red}.txt_14_vert_f{color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_vert_f:link,.txt_14_vert_f:visited,.txt_14_vert_f:active{color:darkgreen}.txt_14_vert_f:hover{color:red}.txt_10_vert{color:green;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_vert:link,.txt_10_vert:visited,.txt_10_vert:active{color:green}.txt_10_vert:hover{color:red}.txt_11_vert{color:green;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_vert:link,.txt_11_vert:visited,.txt_11_vert:active{color:green}.txt_11_vert:hover{color:red}.txt_12_vert{color:green;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_vert:link,.txt_12_vert:visited,.txt_12_vert:active{color:green}.txt_12_vert:hover{color:red}.txt_14_vert{color:green;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_vert:link,.txt_14_vert:visited,.txt_14_vert:active{color:green}.txt_14_vert:hover{color:red}.fond_blanc{background-color:#FFF;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.fond_gris_c, .fond_gris_c +tr{background-color:#FFF;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.fond_gris_c2, .fond_gris_c2 +tr{background-color:#FBFBFB;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.fond_bleu_c, .fond_bleu_c +tr{background-color:#D9EEF9;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none;background-image:url(../images/fond_1.bmp)}.fond_bleu_c2{background-color:#ECF4FF;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.fond_bleu_f{background-color:#036;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.fond_orange{background-color:#FEEFE7;color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;font-weight:bold;text-decoration:none;background-image:url(../images/fond_3.jpg)}.fond_orange_2{background-color:#FFF8F4;color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;font-weight:bold;text-decoration:none;border:1px +solid orange;border-collapse:collapse}.vccDlgBody{border:3px +solid #369;border-collapse:collapse;color:black;background-color:#EFE;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.bordure_0{border:0px +solid;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.bordure_1_bleu{border:1px +solid green;border-collapse:collapse;color:black;background-color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.bordure_3_bleu{border:3px +solid #369;border-collapse:collapse;color:black;background-color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.indent{margin-left:20px}.Btn{color:#036;text-align:center;font-weight:bold;background-color:#FFF;background-image:url(../images/ongletStyle1.jpg);background-repeat:no-repeat;background-position:center center}.Btn:hover{color:red}.menu1h{background-color:#036;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;font-weight:bold;text-decoration:none;border-top:1px solid #036;border-bottom:1px solid #036;border-left:1px solid #036;border-right:1px solid white;border-collapse:collapse;display:block}.menu1h:hover{background-color:white;color:red;border:1px +solid darkgreen;border-collapse:collapse}.menu1h_f{background-color:#036;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;font-weight:bold;text-decoration:none;border:1px +solid #036;display:block}.menu1h_f:hover{background-color:white;color:red;border:1px +solid darkgreen;border-collapse:collapse}.menu1v{background-color:#036;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;font-weight:bold;text-decoration:none;border:1px +solid #036;border-collapse:collapse;display:block}.menu1v:hover{background-color:white;color:red;border:1px +solid darkgreen;border-collapse:collapse}.menu2v{background-color:#58B;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;font-weight:bold;text-decoration:none;border:1px +solid #4277AB;border-collapse:collapse;float:left;display:block}.menu2v:hover{background-color:white;color:red;border:1px +solid darkgreen;border-collapse:collapse}.menuEDF{background-color:#036;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.menuEDF:hover{color:#F80}.Bouton{color:#036;text-align:center;font-weight:bold;cursor:pointer;background-color:#FFF}input{border:2px +solid green;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.disabled_input{border:1px +solid gray;color:grey;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.input0{border:0px;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp)}.input2{border:1px +solid green;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.input3{border:1px +solid black;color:#036;background-color:#EEE;background-image:url()}.input4{border:1px +solid blue;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.input5{border:1px +solid darkblue;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.input_btn{border:0px;cursor:pointer}textarea{border:2px +solid green;color:#036;background-color:#FFF;background-image:url(../images/fond_5.bmp)}.TEXTAREA3{border:1px +solid green;color:#036;background-color:#FFF;background-image:url()}.TEXTAREA4{border:1px +solid green;color:#036;background-color:#EEE;background-image:url()}.hand{cursor:hand;cursor:pointer} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.css new file mode 100644 index 000000000..da7cfca20 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.css @@ -0,0 +1,12 @@ +@import "foo.css"; +@import 'bar/foo.css' print; +@import '/css/foo.css'; /* abs, should not alter */ +@import 'http://foo.com/css/foo.css'; /* abs, should not alter */ +@import url(../foo.css) tv, projection; +@import url("/css/foo.css"); /* abs, should not alter */ +@import url(/css2/foo.css); /* abs, should not alter */ +@import url(data:image/gif;base64,AAAA); /* data, should not alter */ +foo {background:url('bar/foo.png')} +foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */ +foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */ +foo {background:url(data:image/gif;base64,AAAA);} /* data, should not alter */ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.min.css new file mode 100644 index 000000000..ffb94e216 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.min.css @@ -0,0 +1 @@ +@import "../foo.css";@import '../bar/foo.css' print;@import '/css/foo.css';@import 'http://foo.com/css/foo.css';@import url(../../foo.css) tv, projection;@import url("/css/foo.css");@import url(/css2/foo.css);@import url(data:image/gif;base64,AAAA);foo{background:url('../bar/foo.png')}foo{background:url('http://foo.com/css/foo.css')}foo{background:url("//foo.com/css/foo.css")}foo{background:url(data:image/gif;base64,AAAA)} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.css new file mode 100644 index 000000000..aa41d0a91 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.css @@ -0,0 +1,14 @@ +@import "foo.css"; +@import 'bar/foo.css' print; +@import '../bar/foo.css' print; +@import '../../foo.css' print; +@import '/css/foo.css'; /* abs, should not alter */ +@import 'http://foo.com/css/foo.css'; /* abs, should not alter */ +@import url(../foo.css) tv, projection; +@import url("/css/foo.css"); /* abs, should not alter */ +@import url(/css2/foo.css); /* abs, should not alter */ +@import url(data:image/gif;base64,AAAA); /* data, should not alter */ +foo {background:url('bar/foo.png')} +foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */ +foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */ +foo {background:url(data:image/gif;base64,AAAA);} /* data, should not alter */ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.min.css new file mode 100644 index 000000000..34936155a --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.min.css @@ -0,0 +1 @@ +@import "/_test_files/css/foo.css";@import '/_test_files/css/bar/foo.css' print;@import '/_test_files/bar/foo.css' print;@import '/foo.css' print;@import '/css/foo.css';@import 'http://foo.com/css/foo.css';@import url(/_test_files/foo.css) tv, projection;@import url("/css/foo.css");@import url(/css2/foo.css);@import url(data:image/gif;base64,AAAA);foo{background:url('/_test_files/css/bar/foo.png')}foo{background:url('http://foo.com/css/foo.css')}foo{background:url("//foo.com/css/foo.css")}foo{background:url(data:image/gif;base64,AAAA)} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/readme.txt b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/readme.txt new file mode 100644 index 000000000..018175529 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/readme.txt @@ -0,0 +1 @@ +Test suite from http://search.cpan.org/~gtermars/CSS-Minifier-XS/ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.css new file mode 100644 index 000000000..d74c9aa02 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.css @@ -0,0 +1,42 @@ +/* http://www.w3.org/TR/css3-selectors/ */ + +* +E[foo] +E[foo="bar"] +E[foo~="bar"] +E[foo^="bar"] +E[foo$="bar"] +E[foo*="bar"] +E[hreflang|="en"] +E:root +E:nth-child(n) +E:nth-last-child(n) +E:nth-of-type(n) +E:nth-last-of-type(n) +E:first-child +E:last-child +E:first-of-type +E:last-of-type +E:only-child +E:only-of-type +E:empty +E:link +E:visited +E:active +E:hover +E:focus +E:target +E:lang(fr) +E:enabled +E:disabled +E:checked +E::first-line +E::first-letter +E::selection +E::before +E::after +E.warning#myid +E:not(s) + > F + + F + ~ F {color: red;} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.min.css new file mode 100644 index 000000000..643089fcf --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.min.css @@ -0,0 +1,37 @@ +* +E[foo] +E[foo="bar"] +E[foo~="bar"] +E[foo^="bar"] +E[foo$="bar"] +E[foo*="bar"] +E[hreflang|="en"] +E:root +E:nth-child(n) +E:nth-last-child(n) +E:nth-of-type(n) +E:nth-last-of-type(n) +E:first-child +E:last-child +E:first-of-type +E:last-of-type +E:only-child +E:only-of-type +E:empty +E:link +E:visited +E:active +E:hover +E:focus +E:target +E:lang(fr) +E:enabled +E:disabled +E:checked +E::first-line +E::first-letter +E::selection +E::before +E::after +E.warning#myid +E:not(s)>F+F~F{color:red} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.css new file mode 100644 index 000000000..bf46c0af0 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.css @@ -0,0 +1,31 @@ +/* some CSS to try to exercise things in general */ + +@import url( /more.css ); + + body, td, th { + font-family: Verdana , "Bitstream Vera Sans" , sans-serif ; + + font-size : 12px; +} + +.nav { + margin-left: 20%; +} +#main-nav { + background-color: red; + border: 1px solid #00ff77; +} + +div#content +h1 + p { + padding-top: 0; + margin-top: 0; +} + +@media all and (min-width: 640px) { + #media-queries-1 { background-color: #0f0; } +} + +@media screen and (max-width: 2000px) { + #media-queries-2 { background-color: #0f0; } +} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.min.css new file mode 100644 index 000000000..a823b0550 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.min.css @@ -0,0 +1,3 @@ +@import url(/more.css);body,td,th{font-family:Verdana,"Bitstream Vera Sans",sans-serif;font-size:12px}.nav{margin-left:20%}#main-nav{background-color:red;border:1px +solid #0f7}div#content +h1+p{padding-top:0;margin-top:0}@media all and (min-width: 640px){#media-queries-1{background-color:#0f0}}@media screen and (max-width: 2000px){#media-queries-2{background-color:#0f0}} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.css new file mode 100644 index 000000000..79d34ec4a --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.css @@ -0,0 +1,434 @@ +/* Based on the original Style Sheet for the fisubsilver v2 Theme for phpBB version 2+ +Edited by Daz - http://www.forumimages.com - last updated 26-06-03 */ +/* The content of the posts (body of text) */ +/* General page style */ + + + + /* begin suggest post */ + .float-l{ + float: left; + } + + .form-suggest{ + height:200px; + background:#DEE2D0; + vertical-align: top; + } + + .form-input input{ + font-size: 10px; + } + + .hide{ + display:none; + } + + .form-input textarea{ + font-size: 11px; + width: 350px; + } + + .form-label{ + font-size: 10px; + font-weight: bold; + line-height: 25px; + padding-right: 10px; + text-align: right; + width: 100px; + color: #39738F; + } + + .font-9{ + font-size: 9px; + } + + .form-topic{ + font-weight:bold; + + } + + .form-error{ + color:red; + } + + .inline{ + display: inline; + } + + .space-10{ + clear: both; + font-size: 10px; + height: 10px; + line-height: 10px; + } + + .suggest-success{ + color:green; + padding-left:10px; + font-size:11px; + font-weight:bold; + } + + .top{ + vertical-align: top; + } + /* end suggest post */ + +table td{ + padding:3px; +} + +a:link,a:active,a:visited,a.postlink{ + color: #006699; + text-decoration: none; +} + +a:hover{ + color: #DD6900; +} + +a.admin:hover,a.mod:hover{ + color: #DD6900; +} + +a.but,a.but:hover,a.but:visited{ + color: #000000; + text-decoration: none; +} + +a.topictitle:visited{ + color: #5493B4; +} + +a.topictitle:hover{ + color: #DD6900; +} + + + +body{ + color: #000000; + font: 11px Verdana,Arial,Helvetica,sans-serif; + margin: 0 10px 10px 10px; + padding: 0; + overflow:auto; +} + +/* General font families for common tags */ +font,th,td,p{ + font: 12px Verdana,Arial,Helvetica,sans-serif; +} + +/* Form elements */ +form{ + display: inline; +} + +hr{ + border: 0px solid #FFFFFF; + border-top-width: 1px; + height: 0px; +} + +/* Gets rid of the need for border="0" on hyperlinked images */ +img{ + border: 0 solid; +} + +input{ + font: 11px Verdana,Arial,Helvetica,sans-serif; +} + +input.button,input.liteoption,.fakebut{ + background: #FAFAFA; + border: 1px solid #000000; + font-size: 11px; +} + +input.catbutton{ + background: #FAFAFA; + border: 1px solid #000000; + font-size: 10px; +} + +input.mainoption{ + background: #FAFAFA; + border: 1px solid #000000; + font-size: 11px; + font-weight: bold; +} + +input.post,textarea.post{ + background: #FFFFFF; + border: 1px solid #000000; + font: 11px Verdana,Arial,Helvetica,sans-serif; + padding-bottom: 2px; + padding-left: 2px; +} + +select{ + background: #FFFFFF; + font: 11px Verdana,Arial,Helvetica,sans-serif; +} + +table{ + text-align: left; +} + +td{ + vertical-align: middle; +} + +/* Category gradients*/ +td.cat{ + background-color: #C2C6BA; + font-weight: bold; + height: 20px; + letter-spacing: 1px; + text-indent: 4px; +} + +td.genmed,.genmed{ + font-size: 11px; +} + +/* This is for the table cell above the Topics,Post & Last posts on the index.php */ +td.rowpic{ + background: #C2C6BA; +} + +td.spacerow{ + background: #E5E6E2; +} + +/* Table Header cells */ +th{ + background-color: #FADD31; + background-image: url(images/cellpic3.gif); + background-repeat: repeat-x; + color: #68685E; + font-size: 11px; + font-weight: bold; + line-height:16px; + height: 16px; + padding-left: 8px; + padding-right: 8px; + text-align: center; + white-space: nowrap; +} + +/* Admin & Moderator Colours MODification */ +.admin,.mod{ + font-size: 11px; + font-weight: bold; +} + +.admin,a.admin,a.admin:visited{ + color: #FFA34F; +} + +/* This is the border line & background colour round the entire page */ +.bodyline{ + background: #FFFFFF; + border: 1px solid #98AAB1; +} + +.center{ + text-align: center; +} + +/* Code blocks */ +.code{ + background: #FAFAFA; + border: 1px solid #D1D7DC; + color: #006600; + font: 12px Courier,"Courier New",sans-serif; + padding: 5px; +} + +/* This is for the error messages that pop up */ +.errorline{ + background: #E5E6E2; + border: 1px solid #8F8B8B; + color:#D92A2A; +} + +.explaintitle{ + color: #5C81B1; + font-size: 11px; + font-weight: bold; +} + +/* This is the outline round the main forum tables */ +.forumline{ + background: #FFFFFF; +} + +/* General text */ +.gensmall{ + font-size: 10px; +} + +.h1-font{ + color: #006699; + display: inline; + font: bold 13px Verdana, Arial, Helvetica, sans-serif; + margin: 0; + text-decoration: none; +} + +.h2-font{ + display: inline; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; +} + +.height1{ + height: 1px; +} + +.height22{ + height: 22px; +} + +.height25{ + height: 25px; +} + +.height28{ + height: 28px; +} + +.height30{ + height: 30px; +} + +.height40{ + height: 40px; +} + +/* This is the line in the posting page which shows the rollover +help line. Colour value in row2 */ +.helpline{ + border: 0 solid; + font-size: 10px; +} + +.imgfolder{ + margin: 1px 4px 1px 4px; +} + +.imgspace{ + margin-left: 1px; + margin-right: 2px; +} + +/* Specify the space around images */ +.imgtopic,.imgicon{ + margin-left: 3px; +} + +.left{ + text-align: left; +} + +/* The largest text used in the index page title and toptic title etc. */ +.maintitle,h1,h2{ + color: #5C81B1; + font: bold 20px/120% "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif; + text-decoration: none; +} + +.maxwidth{ + width: 100%; +} + +.mod,a.mod,a.mod:visited{ + color: #006600; +} + +/* Name of poster in viewmsg.php and viewtopic.php and other places */ +.name{ + font-size: 11px; + font-weight: bold; +} + +/* Used for the navigation text,(Page 1,2,3 etc) and the navigation bar when in a forum */ +.nav{ + font-size: 11px; + font-weight: bold; +} + +.nowrap{ + white-space: nowrap; +} + +.postbody{ + font-size: 12px; + line-height: 125%; +} + +.postbody a{ + text-decoration: underline; +} + +/* Location,number of posts,post date etc */ +.postdetails{ + color: #00396A; + font-size: 10px; +} + +/* Quote blocks */ +.quote{ + background: #F3F3EF; + border: 1px solid #C2C6BA; + color: #006699; + font-size: 11px; + line-height: 125%; +} + +.right{ + text-align: right; +} + +/* Main table cell colours and backgrounds */ +.row1{ + background: #F0F0EB; +} + +.row2,.helpline{ + background: #E5E6E2; +} + +.row3{ + background: #DBDBD4; +} + +.subtitle,h2{ + font: bold 18px/180% "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif; + text-decoration: none; +} + +/* titles for the topics:could specify viewed link colour too */ +.topictitle { + color: #000000; + font-size: 11px; + font-weight: bold; +} + +.underline{ + text-decoration: underline; +} + +.top{ +vertical-align:top; +} + +.image-hspace{ +margin-right:3px; +} + +.clear{ +clear:both; +} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.min.css new file mode 100644 index 000000000..f59b15a92 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.min.css @@ -0,0 +1,18 @@ +.float-l{float:left}.form-suggest{height:200px;background:#DEE2D0;vertical-align:top}.form-input +input{font-size:10px}.hide{display:none}.form-input +textarea{font-size:11px;width:350px}.form-label{font-size:10px;font-weight:bold;line-height:25px;padding-right:10px;text-align:right;width:100px;color:#39738F}.font-9{font-size:9px}.form-topic{font-weight:bold}.form-error{color:red}.inline{display:inline}.space-10{clear:both;font-size:10px;height:10px;line-height:10px}.suggest-success{color:green;padding-left:10px;font-size:11px;font-weight:bold}.top{vertical-align:top}table +td{padding:3px}a:link,a:active,a:visited,a.postlink{color:#069;text-decoration:none}a:hover{color:#DD6900}a.admin:hover,a.mod:hover{color:#DD6900}a.but,a.but:hover,a.but:visited{color:#000;text-decoration:none}a.topictitle:visited{color:#5493B4}a.topictitle:hover{color:#DD6900}body{color:#000;font:11px Verdana,Arial,Helvetica,sans-serif;margin:0 +10px 10px 10px;padding:0;overflow:auto}font,th,td,p{font:12px Verdana,Arial,Helvetica,sans-serif}form{display:inline}hr{border:0px +solid #FFF;border-top-width:1px;height:0px}img{border:0 +solid}input{font:11px Verdana,Arial,Helvetica,sans-serif}input.button,input.liteoption,.fakebut{background:#FAFAFA;border:1px +solid #000;font-size:11px}input.catbutton{background:#FAFAFA;border:1px +solid #000;font-size:10px}input.mainoption{background:#FAFAFA;border:1px +solid #000;font-size:11px;font-weight:bold}input.post,textarea.post{background:#FFF;border:1px +solid #000;font:11px Verdana,Arial,Helvetica,sans-serif;padding-bottom:2px;padding-left:2px}select{background:#FFF;font:11px Verdana,Arial,Helvetica,sans-serif}table{text-align:left}td{vertical-align:middle}td.cat{background-color:#C2C6BA;font-weight:bold;height:20px;letter-spacing:1px;text-indent:4px}td.genmed,.genmed{font-size:11px}td.rowpic{background:#C2C6BA}td.spacerow{background:#E5E6E2}th{background-color:#FADD31;background-image:url(images/cellpic3.gif);background-repeat:repeat-x;color:#68685E;font-size:11px;font-weight:bold;line-height:16px;height:16px;padding-left:8px;padding-right:8px;text-align:center;white-space:nowrap}.admin,.mod{font-size:11px;font-weight:bold}.admin,a.admin,a.admin:visited{color:#FFA34F}.bodyline{background:#FFF;border:1px +solid #98AAB1}.center{text-align:center}.code{background:#FAFAFA;border:1px +solid #D1D7DC;color:#060;font:12px Courier,"Courier New",sans-serif;padding:5px}.errorline{background:#E5E6E2;border:1px +solid #8F8B8B;color:#D92A2A}.explaintitle{color:#5C81B1;font-size:11px;font-weight:bold}.forumline{background:#FFF}.gensmall{font-size:10px}.h1-font{color:#069;display:inline;font:bold 13px Verdana,Arial,Helvetica,sans-serif;margin:0;text-decoration:none}.h2-font{display:inline;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.height1{height:1px}.height22{height:22px}.height25{height:25px}.height28{height:28px}.height30{height:30px}.height40{height:40px}.helpline{border:0 +solid;font-size:10px}.imgfolder{margin:1px +4px 1px 4px}.imgspace{margin-left:1px;margin-right:2px}.imgtopic,.imgicon{margin-left:3px}.left{text-align:left}.maintitle,h1,h2{color:#5C81B1;font:bold 20px/120% "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;text-decoration:none}.maxwidth{width:100%}.mod,a.mod,a.mod:visited{color:#060}.name{font-size:11px;font-weight:bold}.nav{font-size:11px;font-weight:bold}.nowrap{white-space:nowrap}.postbody{font-size:12px;line-height:125%}.postbody +a{text-decoration:underline}.postdetails{color:#00396A;font-size:10px}.quote{background:#F3F3EF;border:1px +solid #C2C6BA;color:#069;font-size:11px;line-height:125%}.right{text-align:right}.row1{background:#F0F0EB}.row2,.helpline{background:#E5E6E2}.row3{background:#DBDBD4}.subtitle,h2{font:bold 18px/180% "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;text-decoration:none}.topictitle{color:#000;font-size:11px;font-weight:bold}.underline{text-decoration:underline}.top{vertical-align:top}.image-hspace{margin-right:3px}.clear{clear:both} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.css new file mode 100644 index 000000000..69fa756eb --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.css @@ -0,0 +1,10 @@ +/* test unusual, but valid strings in CSS */ + +foo[attr="multiple spaces"] { + content: "Hello World!"; +} + +foo[attr="Hel\ +lo"] { + content: " \"World\""; +} diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.min.css new file mode 100644 index 000000000..4b7d97e45 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.min.css @@ -0,0 +1,2 @@ +foo[attr="multiple spaces"]{content:"Hello World!"}foo[attr="Hel\ +lo"]{content:" \"World\""} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.css new file mode 100644 index 000000000..819835e58 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.css @@ -0,0 +1,658 @@ +/* from http://www.vladimirated.com/web-development-minify-css-using-php-and-cssmin-class */ + + #comments_inviter #close_me { + clear: both; + text-align: center; + border-top: 1px solid #eeeeee; + padding-top: 10px; + } + + #comments_inviter #close_me span { + color: #108eed; + cursor: pointer; + font-weight: bold; + } + + #comments_inviter img { + float: left; + margin-right: 3px; + margin-bottom: 10px; + } + + #comments_inviter { + width: 200px; + background-color: #FFFFFF; + border: 4px solid #eeeeee; + font-size: 10px; + font-family: verdana; + padding: 10px; + color: #333333; + } + + .one_com { + background-color: #FAFAFA; + padding: 10px; + margin-bottom: 20px; + border: 1px solid #EEEEEE; + } + + .one_com .com_says, .one_com .com_det { + text-transform: lowercase; + color: #333333; + padding: 0px; + font-family: verdana; + margin: 0px; + font-size: 13px; + font-weight: bold; + } + + .flvPlayer { + text-align: center; + border: 5px solid #dddddd; + width: 320px; + } + + .one_com .com_det { + font-size: 10px; + font-weight: normal; + margin-bottom: 20px; + padding-bottom: 10px; + border-bottom: 8px solid #eeeeee; + } + + .one_com .com_det a { + text-decoration: none; + } + + .one_com .com_txt { + background-color: #ffffff; + margin-bottom: 10px; + border-bottom: 2px solid #eeeeee + } + + .one_com .com_txt p { + font-family: verdana; + font-size: 13px; + color: #777777; + margin: 0px; + padding: 5px; + padding-bottom: 10px; + text-transform: lowercase; + } + + .one_com .com_says a { + color: #333333; + } + + .one_com .com_det a { + color: #333333; + } + + .post_box .related_posts { + + } + + .post_box .related_posts p { + padding: 0px; + margin: 0px; + padding-bottom: 20px; + padding-left: 35px; + font-family: verdana; + + } + + .post_box .related_posts a { + color: #108eed; + } + + .post_nav_2 p { + + text-align: center; + color: #cccccc; + font-family: verdana; + } + + .post_box .related_posts h3, #comments_box #respond, .comments_posted h3 { + padding: 0px; + margin: 0px; + font-size: 18px; + color: #FF8000; + padding-top: 30px; + margin-bottom: 20px; + width: 300px; + border-bottom: 5px solid #e0e0e0; + } + + .comments_posted { + + margin-bottom: 50px; + + } + + .comments_posted h3 { + padding: 0px; + margin: 0px; + margin-bottom: 20px; + + } + + .cmt_txtarea { + width: 300px; + height: 100px; + + } + + #comments_box #respond { + + padding-top: 0px; + margin-bottom: 0px; + + } + + .pagetitle { + color: #65DA33; + text-align: center; + } + + #searchform { + padding: 0px; + margin: 0px; + } + + .si { + background-color: #FFFFEE; + border: 1px solid #e0e0e0; + } + + #rightcol #r_news, #rightcol #linksbro, #rightcol #quick_tags { + margin-top: 30px; + padding-bottom: 10px; + } + + #post_nav p { + padding: 0px; + margin: 0px; + padding-bottom: 5px; + } + + #post_nav { + text-align: left; + padding-bottom: 15px; + } + + #post_nav a, .post_nav_2 p a { + text-decoration: none; + font-family: Verdana; + font-size: 12px; + color: #108eed; + } + + #post_nav a:hover, .post_nav_2 p a:hover { + text-decoration: underline; + color: #FF8000; + } + + #rightcol #about { + padding-bottom: 10px; + } + + #rightcol #r_news input { + color: #333333; + font-size: 12px; + } + + #header { + height: 200px; + width: 100%; + background-image: url('images/header_bg.jpg'); + background-repeat: x-repeat; + } + + #header img { + + float: right; + margin-right: -3px; + z-index: 100; + + } + + .tags { + text-transform: lowercase; + color: #333333; + font-family: arial; + font-size: 12px; + border-top: 2px dotted #EEEEEE; + width: 300px; + padding-top: 20px; + padding-bottom: 0px; + margin-top: 0px; + padding-left: 20px; + padding-right: 20px; + } + + .tags a { + color: #108eed; + } + + .tags p { + text-align: left; + margin: 0px; + padding: 0px; + } + + blockquote strong { + font-family: verdana; + display: block; + margin-top: 10px; + color: #FF0000; + font-style: italic; + text-align: right; + } + + blockquote { + margin: 0px; + background-color: #eeeeee; + border: 2px solid #dddddd; + padding: 24px; + padding-top: 10px; + padding-left: 60px; + padding-bottom: 10px; + font-size: 13px; + color: #333333; + margin-bottom: 30px; + margin-top: 10px; + } + + + html>body #header img { margin-right: 0px; } + + #subscribe h3 { + color: #ff0000; + margin-top: 30px; + padding: 20px; + } + + .post_actions a{ + color: #108eed; + } + + .post_actions { + border-top: 4px solid #DDDDDD; + border-bottom: 1px solid #EEEEEE; + text-align: center; + background-color: #FFFFDd; + color: #dddddd; + white-space: no-wrap; + padding-left: 20px; + padding-bottom: 5px; + text-transform: capitalize; + } + + #subscribe td { + color: #333333; + font-size: 12px; + text-transform: lowercase; + } + + #subscribe input { + font-size: 13px; + color: #333333; + } + + .post_content { + font-size: 13px; + margin-top: 10px; + padding-bottom: 10px; + text-align: justify; + font-family: verdana; + } + + .post_content p { + margin: 0px; + padding: 0px; + padding-bottom: 20px; + line-height: 20px; + } + + #header h1 { + z-index: 200; + margin: 0px; + position: absolute; + float: left; + text-transform: lowercase; + padding: 0px; + font-size: 45px; + margin-top: 70px; + margin-left: 40px; + + } + + #header h1 a { + white-space: no-wrap; + text-decoration: none; + color: #FAFAFA; + display: block + } + + #header h1 a:hover { + color: #FAFAFA; + border-bottom: 3px dotted #FAFAFA; + } + + html>body #header h1 { margin-left: 60px; } + + body { + margin: 0px; + padding: 0px; + height: 100%; + width: 100%; + font-family: 'Lucida Sans Unicode', 'Lucida Grande', Sans-Serif, Verdana, Arial; + font-size: 12px; + } + + #leftcol { + float: left; + width: 200px; + margin-left: 0px; + margin-top: 17px; + color: #000; + padding: 3px; + height: 100%; + } + + #leftcol .box_head h3 { + text-transform: uppercase; + padding: 0px; + margin: 0px; + font-family: georgia; + font-size: 18px; + color: #dddddd; + border-top: 4px solid #dddddd; + border-bottom: 4px solid #cccccc; + padding-left: 10px; + padding-top: 10px; + padding-bottom: 10px; + background-image: url('images/stripesbg.png'); + margin-bottom: 10px; + } + + #leftcol .box_head input { + text-transform: lowercase; + color: #333333; + } + + #leftcol .box_head { + margin-left: 7px; + background-color: #ffefd4; + border-bottom: 2px solid #eeeeee; + padding-bottom: 20px; + margin-bottom: 30px; + } + + #leftcol .box_head p a { + color: #0a2d4d; + display: block; + text-decoration: none; + border-bottom: 3px solid #fefefe; + padding-top: 20px; + text-transform: lowercase; + padding-bottom: 20px; + padding-left: 5px; + padding-right: 5px; + } + + #leftcol .box_head p a:hover { + background-color: #fafafa; + border-bottom: 3px solid #eeeeee; + color: #000000; + } + + #leftcol .box_head p { + text-align: left; + margin: 0px; + width: 170px; + padding-bottom: 0px; + padding-top: 0px; + font-size: 11px; + } + + #rightcol { + position: absolute; + left: 77%; + top: 278px; + border: 3px solid #eeeeee; + width: 200px; + z-index: 3; + color: #333333; + padding: 10px; + text-transform: lowercase; + + } + + #rightcol p { + padding: 0px; + marging: 0px; + text-align: justify; + } + + #rightcol #about img, #rightcol #linksbro img { + border: 5px solid #eeeeee; + } + + #rightcol #about h3, #rightcol #r_news h3, #rightcol #linksbro h3, #rightcol #quick_tags h3 { + background-color: #fafafa; + border: 1px dotted #e0e0e0; + font-size: 14px; + color: #104bbc; + padding: 5px; + padding-top: 10px; + font-family: Arial; + padding-bottom: 10px; + } + + #rightcol #about p a, #rightcol #r_news p a, #rightcol #linksbro p a { + color: #108eed; + } + + #rightcol #about p, #rightcol #r_news p, #rightcol #linksbro p { + font-size: 12px; + text-align: left; + } + + #content_warp { + margin: 20px 25% 0 215px; + padding: 3px; + color: #000; + background-color: #ededed; + } + + #content { + margin: 5px; + background-color: #FFFFFF; + padding: 10px; + } + + + #footer { + width: 99%; + margin-top: 30px; + height: 98px; + background-color: #101b1d; + } + + #footer td a { + color: #FF8000; + } + + #footer td a img { + border: 2px solid #108eed; + } + + #footer td p { + font-family: Verdana; + font-size: 10px; + color: #c0c0c0; + padding: 0px; + margin: 0px; + text-align: center; + padding-bottom: 10px; + } + + .s_offer { + color: #65DA33; + font-size: 20px; + font-weight: bold; + font-style: normal; + } + + .post_box { + text-transform: lowercase; + margin-bottom: 40px; + } + + #newsletter_box { + text-transform: lowercase; + margin-bottom: 10px; + margin-top: 30px; + font-style: normal; + background-color: #ffffff; + border: 5px solid #dddddd; + } + + #newsletter_head { + color: #EEEEEE; + font-family: Georgia; + background-image: url('images/stripesbg.png'); + padding: 10px; + padding-left: 30px; + border-bottom: 5px solid #dddddd; + } + + #newsletter_body { + color: #333333; + font-family: Verdana; + text-align: justify; + background-color: #FFFFFF; + padding: 10px; + font-size: 13px; + } + + .s_offer { + color: #65DA33; + font-size: 26px; + font-weight: bold; + font-style: normal; + } + + .post_title a { + color: #EEEEEE; + text-decoration: none; + } + + .post_title a:hover { + color: #c0c0c0; + } + + .post_title { + background-image: url('images/stripe_post.png'); + text-transform: uppercase; + font-size: 18px; + font-family: georgia; + padding: 10px; + border-top: 4px solid #c0c0c0; + margin: 0px; + border-bottom: 2px solid #ffffdd; + } + + .post_det { + text-transform: none; + margin: 0px; + border-top: 1px solid #f0f0f0; + padding: 0px; + padding-top: 5px; + color: #999999; + font-size: 10px; + font-family: verdana; + margin-bottom: 20px; + background-color: #eeeeee; + padding-bottom: 5px; + padding-left: 10px; + text-align: left; + border-bottom: 2px solid #dddddd; + } + + .post_det a { + color: #999999; + text-decoration: none; + } + + + .subtle { + text-transform: lowercase; + font-size: 10px; + font-family: verdana; + color: #108eed; + text-align: justify; + } + + #top_menu #navlist, #top_menu #navlist li { + padding:0px; + margin: 0px; + padding-top: 14px; + text-transform: lowercase; + padding-bottom: 17px; + padding-left: 30px; + border-left: 1px solid #65cdef; + } + + #top_menu #navlist, #top_menu #navlist li #first { + + border-left: 0px; + + } + + #top_menu #navlist { + padding-left: 30px; + background-color: #1dabd9; + border-top: 5px solid #0e96c3; + border-bottom: 5px solid #0e96c3; + } + + #top_menu #navlist li { + color: #444444; + font-size: 10px; + display: inline; + list-style-type: none; + padding-right: 30px; + } + + #top_menu #navlist li a { + text-decoration: none; + font-family: Verdana; + color: #fafafa; + font-size: 12px; + font-weight: bold; + } + + #top_menu #navlist li a:hover { + color: #333333; + } + + .post_content a { + color: #108eed; + } + + ul#tagcloud { padding:0; margin:0; text-align:center; list-style:none; } + ul#tagcloud li { display:inline; font-size:70%; color:#ccc; background: none; padding: 0;} + ul#tagcloud li a, ul#tagcloud li a:link { text-decoration:none; } + ul#tagcloud li a:hover { text-decoration:underline; } + ul#tagcloud li.t1 a { color:#797979; font-size: 120%; } + ul#tagcloud li.t2 a { color:#6d6d6d; font-size: 160%; } + ul#tagcloud li.t3 a { color:#616161; font-size: 190%; } + ul#tagcloud li.t4 a { color:#555555; font-size: 210%; } + ul#tagcloud li.t5 a { color:#484848; font-size: 230%; } + ul#tagcloud li.t6 a { color:#3c3c3c; font-size: 250%; } + ul#tagcloud li.t7 a { color:#303030; font-size: 270%; } + ul#tagcloud li.t8 a { color:#242424; font-size: 290%; } + ul#tagcloud li.t9 a { color:#181818; font-size: 310%; } + ul#tagcloud li.t10 a { color:#0c0c0c; font-size: 330%; } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.min.css new file mode 100644 index 000000000..eaffaee38 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.min.css @@ -0,0 +1,79 @@ +#comments_inviter +#close_me{clear:both;text-align:center;border-top:1px solid #eee;padding-top:10px}#comments_inviter #close_me +span{color:#108eed;cursor:pointer;font-weight:bold}#comments_inviter +img{float:left;margin-right:3px;margin-bottom:10px}#comments_inviter{width:200px;background-color:#FFF;border:4px +solid #eee;font-size:10px;font-family:verdana;padding:10px;color:#333}.one_com{background-color:#FAFAFA;padding:10px;margin-bottom:20px;border:1px +solid #EEE}.one_com .com_says, .one_com +.com_det{text-transform:lowercase;color:#333;padding:0px;font-family:verdana;margin:0px;font-size:13px;font-weight:bold}.flvPlayer{text-align:center;border:5px +solid #ddd;width:320px}.one_com +.com_det{font-size:10px;font-weight:normal;margin-bottom:20px;padding-bottom:10px;border-bottom:8px solid #eee}.one_com .com_det +a{text-decoration:none}.one_com +.com_txt{background-color:#fff;margin-bottom:10px;border-bottom:2px solid #eee}.one_com .com_txt +p{font-family:verdana;font-size:13px;color:#777;margin:0px;padding:5px;padding-bottom:10px;text-transform:lowercase}.one_com .com_says +a{color:#333}.one_com .com_det +a{color:#333}.post_box +.related_posts{}.post_box .related_posts +p{padding:0px;margin:0px;padding-bottom:20px;padding-left:35px;font-family:verdana}.post_box .related_posts +a{color:#108eed}.post_nav_2 +p{text-align:center;color:#ccc;font-family:verdana}.post_box .related_posts h3, #comments_box #respond, .comments_posted +h3{padding:0px;margin:0px;font-size:18px;color:#FF8000;padding-top:30px;margin-bottom:20px;width:300px;border-bottom:5px solid #e0e0e0}.comments_posted{margin-bottom:50px}.comments_posted +h3{padding:0px;margin:0px;margin-bottom:20px}.cmt_txtarea{width:300px;height:100px}#comments_box +#respond{padding-top:0px;margin-bottom:0px}.pagetitle{color:#65DA33;text-align:center}#searchform{padding:0px;margin:0px}.si{background-color:#FFE;border:1px +solid #e0e0e0}#rightcol #r_news, #rightcol #linksbro, #rightcol +#quick_tags{margin-top:30px;padding-bottom:10px}#post_nav +p{padding:0px;margin:0px;padding-bottom:5px}#post_nav{text-align:left;padding-bottom:15px}#post_nav a, .post_nav_2 p +a{text-decoration:none;font-family:Verdana;font-size:12px;color:#108eed}#post_nav a:hover, .post_nav_2 p a:hover{text-decoration:underline;color:#FF8000}#rightcol +#about{padding-bottom:10px}#rightcol #r_news +input{color:#333;font-size:12px}#header{height:200px;width:100%;background-image:url('images/header_bg.jpg');background-repeat:x-repeat}#header +img{float:right;margin-right: -3px;z-index:100}.tags{text-transform:lowercase;color:#333;font-family:arial;font-size:12px;border-top:2px dotted #EEE;width:300px;padding-top:20px;padding-bottom:0px;margin-top:0px;padding-left:20px;padding-right:20px}.tags +a{color:#108eed}.tags +p{text-align:left;margin:0px;padding:0px}blockquote +strong{font-family:verdana;display:block;margin-top:10px;color:#F00;font-style:italic;text-align:right}blockquote{margin:0px;background-color:#eee;border:2px +solid #ddd;padding:24px;padding-top:10px;padding-left:60px;padding-bottom:10px;font-size:13px;color:#333;margin-bottom:30px;margin-top:10px}html>body #header +img{margin-right:0px}#subscribe +h3{color:#f00;margin-top:30px;padding:20px}.post_actions +a{color:#108eed}.post_actions{border-top:4px solid #DDD;border-bottom:1px solid #EEE;text-align:center;background-color:#FFD;color:#ddd;white-space:no-wrap;padding-left:20px;padding-bottom:5px;text-transform:capitalize}#subscribe +td{color:#333;font-size:12px;text-transform:lowercase}#subscribe +input{font-size:13px;color:#333}.post_content{font-size:13px;margin-top:10px;padding-bottom:10px;text-align:justify;font-family:verdana}.post_content +p{margin:0px;padding:0px;padding-bottom:20px;line-height:20px}#header +h1{z-index:200;margin:0px;position:absolute;float:left;text-transform:lowercase;padding:0px;font-size:45px;margin-top:70px;margin-left:40px}#header h1 +a{white-space:no-wrap;text-decoration:none;color:#FAFAFA;display:block}#header h1 a:hover{color:#FAFAFA;border-bottom:3px dotted #FAFAFA}html>body #header +h1{margin-left:60px}body{margin:0px;padding:0px;height:100%;width:100%;font-family:'Lucida Sans Unicode','Lucida Grande',Sans-Serif,Verdana,Arial;font-size:12px}#leftcol{float:left;width:200px;margin-left:0px;margin-top:17px;color:#000;padding:3px;height:100%}#leftcol .box_head +h3{text-transform:uppercase;padding:0px;margin:0px;font-family:georgia;font-size:18px;color:#ddd;border-top:4px solid #ddd;border-bottom:4px solid #ccc;padding-left:10px;padding-top:10px;padding-bottom:10px;background-image:url('images/stripesbg.png');margin-bottom:10px}#leftcol .box_head +input{text-transform:lowercase;color:#333}#leftcol +.box_head{margin-left:7px;background-color:#ffefd4;border-bottom:2px solid #eee;padding-bottom:20px;margin-bottom:30px}#leftcol .box_head p +a{color:#0a2d4d;display:block;text-decoration:none;border-bottom:3px solid #fefefe;padding-top:20px;text-transform:lowercase;padding-bottom:20px;padding-left:5px;padding-right:5px}#leftcol .box_head p a:hover{background-color:#fafafa;border-bottom:3px solid #eee;color:#000}#leftcol .box_head +p{text-align:left;margin:0px;width:170px;padding-bottom:0px;padding-top:0px;font-size:11px}#rightcol{position:absolute;left:77%;top:278px;border:3px +solid #eee;width:200px;z-index:3;color:#333;padding:10px;text-transform:lowercase}#rightcol +p{padding:0px;marging:0px;text-align:justify}#rightcol #about img, #rightcol #linksbro +img{border:5px +solid #eee}#rightcol #about h3, #rightcol #r_news h3, #rightcol #linksbro h3, #rightcol #quick_tags +h3{background-color:#fafafa;border:1px +dotted #e0e0e0;font-size:14px;color:#104bbc;padding:5px;padding-top:10px;font-family:Arial;padding-bottom:10px}#rightcol #about p a, #rightcol #r_news p a, #rightcol #linksbro p +a{color:#108eed}#rightcol #about p, #rightcol #r_news p, #rightcol #linksbro +p{font-size:12px;text-align:left}#content_warp{margin:20px +25% 0 215px;padding:3px;color:#000;background-color:#ededed}#content{margin:5px;background-color:#FFF;padding:10px}#footer{width:99%;margin-top:30px;height:98px;background-color:#101b1d}#footer td +a{color:#FF8000}#footer td a +img{border:2px +solid #108eed}#footer td +p{font-family:Verdana;font-size:10px;color:#c0c0c0;padding:0px;margin:0px;text-align:center;padding-bottom:10px}.s_offer{color:#65DA33;font-size:20px;font-weight:bold;font-style:normal}.post_box{text-transform:lowercase;margin-bottom:40px}#newsletter_box{text-transform:lowercase;margin-bottom:10px;margin-top:30px;font-style:normal;background-color:#fff;border:5px +solid #ddd}#newsletter_head{color:#EEE;font-family:Georgia;background-image:url('images/stripesbg.png');padding:10px;padding-left:30px;border-bottom:5px solid #ddd}#newsletter_body{color:#333;font-family:Verdana;text-align:justify;background-color:#FFF;padding:10px;font-size:13px}.s_offer{color:#65DA33;font-size:26px;font-weight:bold;font-style:normal}.post_title +a{color:#EEE;text-decoration:none}.post_title a:hover{color:#c0c0c0}.post_title{background-image:url('images/stripe_post.png');text-transform:uppercase;font-size:18px;font-family:georgia;padding:10px;border-top:4px solid #c0c0c0;margin:0px;border-bottom:2px solid #ffd}.post_det{text-transform:none;margin:0px;border-top:1px solid #f0f0f0;padding:0px;padding-top:5px;color:#999;font-size:10px;font-family:verdana;margin-bottom:20px;background-color:#eee;padding-bottom:5px;padding-left:10px;text-align:left;border-bottom:2px solid #ddd}.post_det +a{color:#999;text-decoration:none}.subtle{text-transform:lowercase;font-size:10px;font-family:verdana;color:#108eed;text-align:justify}#top_menu #navlist, #top_menu #navlist +li{padding:0px;margin:0px;padding-top:14px;text-transform:lowercase;padding-bottom:17px;padding-left:30px;border-left:1px solid #65cdef}#top_menu #navlist, #top_menu #navlist li +#first{border-left:0px}#top_menu +#navlist{padding-left:30px;background-color:#1dabd9;border-top:5px solid #0e96c3;border-bottom:5px solid #0e96c3}#top_menu #navlist +li{color:#444;font-size:10px;display:inline;list-style-type:none;padding-right:30px}#top_menu #navlist li +a{text-decoration:none;font-family:Verdana;color:#fafafa;font-size:12px;font-weight:bold}#top_menu #navlist li a:hover{color:#333}.post_content +a{color:#108eed}ul#tagcloud{padding:0;margin:0;text-align:center;list-style:none}ul#tagcloud +li{display:inline;font-size:70%;color:#ccc;background:none;padding:0}ul#tagcloud li a, ul#tagcloud li a:link{text-decoration:none}ul#tagcloud li a:hover{text-decoration:underline}ul#tagcloud li.t1 +a{color:#797979;font-size:120%}ul#tagcloud li.t2 +a{color:#6d6d6d;font-size:160%}ul#tagcloud li.t3 +a{color:#616161;font-size:190%}ul#tagcloud li.t4 +a{color:#555;font-size:210%}ul#tagcloud li.t5 +a{color:#484848;font-size:230%}ul#tagcloud li.t6 +a{color:#3c3c3c;font-size:250%}ul#tagcloud li.t7 +a{color:#303030;font-size:270%}ul#tagcloud li.t8 +a{color:#242424;font-size:290%}ul#tagcloud li.t9 +a{color:#181818;font-size:310%}ul#tagcloud li.t10 +a{color:#0c0c0c;font-size:330%} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/exp.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/exp.css new file mode 100644 index 000000000..d749295b7 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/exp.css @@ -0,0 +1,14 @@ +@import "/_test_files/css_uriRewriter/foo.css"; +@import '/_test_files/css_uriRewriter/bar/foo.css' print; +@import '/_test_files/bar/foo.css' print; +@import '/foo.css' print; +@import '/css/foo.css'; /* abs, should not alter */ +@import 'http://foo.com/css/foo.css'; /* abs, should not alter */ +@import url(/_test_files/foo.css) tv, projection; +@import url("/css/foo.css"); /* abs, should not alter */ +@import url(/css2/foo.css); /* abs, should not alter */ +@import url(data:image/gif;base64,AAAA); /* data, should not alter */ +foo {background:url('/_test_files/css_uriRewriter/bar/foo.png')} +foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */ +foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */ +foo {background:url(data:image/gif;base64,AAAA);} /* data, should not alter */ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/in.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/in.css new file mode 100644 index 000000000..aa41d0a91 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/in.css @@ -0,0 +1,14 @@ +@import "foo.css"; +@import 'bar/foo.css' print; +@import '../bar/foo.css' print; +@import '../../foo.css' print; +@import '/css/foo.css'; /* abs, should not alter */ +@import 'http://foo.com/css/foo.css'; /* abs, should not alter */ +@import url(../foo.css) tv, projection; +@import url("/css/foo.css"); /* abs, should not alter */ +@import url(/css2/foo.css); /* abs, should not alter */ +@import url(data:image/gif;base64,AAAA); /* data, should not alter */ +foo {background:url('bar/foo.png')} +foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */ +foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */ +foo {background:url(data:image/gif;base64,AAAA);} /* data, should not alter */ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.html b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.html new file mode 100644 index 000000000..c22cc8f20 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.html @@ -0,0 +1,96 @@ + + + + + + + + + + + css Zen Garden: The Beauty in CSS Design + + + + + + + + + + + + +

    Browser != IE

    +
    + +
    +	White  space  is  important   here!
    +		
    +
    +

    A demonstration of what can be accomplished visually through CSS-based design. Select any style sheet from the list to load it into this page.

    +

    Download the sample html file and css file

    +
    + +
    + + \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.min.html b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.min.html new file mode 100644 index 000000000..58ba2bb98 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.min.html @@ -0,0 +1,36 @@ +css Zen Garden: The Beauty in CSS Design

    Browser != IE

    css Zen Garden

    The Beauty of CSS Design

    +	White  space  is  important   here!
    +		

    A demonstration of what can be accomplished visually through CSS-based design. Select any style sheet from the list to load it into this page.

    Download the sample html file and css file

    \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.html b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.html new file mode 100644 index 000000000..4ca7f199e --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.html @@ -0,0 +1,95 @@ + + + + + + + + + + + css Zen Garden: The Beauty in CSS Design + + + + + + + + + + + + +

    Browser != IE

    +
    + +
    +	White  space  is  important   here!
    +		
    +
    +

    A demonstration of what can be accomplished visually through CSS-based design. Select any style sheet from the list to load it into this page.

    +

    Download the sample html file and css file

    +
    + +Preserve at least 1 char of whitespace near scripts in case of document.write(). +
    + + \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.min.html b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.min.html new file mode 100644 index 000000000..ae28465bc --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.min.html @@ -0,0 +1,36 @@ +css Zen Garden: The Beauty in CSS Design

    Browser != IE

    css Zen Garden

    The Beauty of CSS Design

    +	White  space  is  important   here!
    +		

    A demonstration of what can be accomplished visually through CSS-based design. Select any style sheet from the list to load it into this page.

    Download the sample html file and css file

    Preserve at least 1 char of whitespace near scripts in case of document.write().
    \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/adjacent.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/adjacent.css new file mode 100644 index 000000000..da52c6949 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/adjacent.css @@ -0,0 +1,3 @@ +/* @import url('bad.css' ) bad; */ +adjacent2 foo { background: red url(/red.gif); } +adjacent2 bar { background: url('../green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/tv.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/tv.css new file mode 100644 index 000000000..69fa2f5ef --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/tv.css @@ -0,0 +1,4 @@ +@import url( adjacent.css ) all; +@import '../input.css'; +tv foo { background: red url(/red.gif); } +tv bar { background: url('../green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/adjacent.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/adjacent.css new file mode 100644 index 000000000..b452f473e --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/adjacent.css @@ -0,0 +1,4 @@ +@import url(../css/styles.css); +@import url(http://example.com/hello.css); +adjacent foo { background: red url(/red.gif); } +adjacent bar { background: url('../green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/input.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/input.css new file mode 100644 index 000000000..bb7b95951 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/input.css @@ -0,0 +1,4 @@ +@import url( adjacent.css ) screen; +@import "1/tv.css" tv, projection; +input foo { background: red url(/red.gif); } +input bar { background: url('../green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/output.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/output.css new file mode 100644 index 000000000..1e4358c25 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/output.css @@ -0,0 +1,48 @@ +@media screen { +/* some CSS to try to exercise things in general */ + +@import url(/more.css); + + body, td, th { + font-family: Verdana , "Bitstream Vera Sans" , sans-serif ; + + font-size : 12px; +} + +.nav { + margin-left: 20%; +} +#main-nav { + background-color: red; + border: 1px solid #00ff77; +} + +div#content +h1 + p { + padding-top: 0; + margin-top: 0; +} + +@media all and (min-width: 640px) { + #media-queries-1 { background-color: #0f0; } +} + +@media screen and (max-width: 2000px) { + #media-queries-2 { background-color: #0f0; } +} +@import url(http://example.com/hello.css); +adjacent foo { background: red url(/red.gif); } +adjacent bar { background: url('%TEST_FILES_URI%/green.gif') } +} + +@media tv,projection { +/* @import url('%TEST_FILES_URI%/importProcessor/1/bad.css') bad; */ +adjacent2 foo { background: red url(/red.gif); } +adjacent2 bar { background: url('%TEST_FILES_URI%/importProcessor/green.gif') } +@import '../input.css'; +tv foo { background: red url(/red.gif); } +tv bar { background: url('%TEST_FILES_URI%/importProcessor/green.gif') } +} + +input foo { background: red url(/red.gif); } +input bar { background: url('%TEST_FILES_URI%/green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.js new file mode 100644 index 000000000..cccdb9706 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.js @@ -0,0 +1,57 @@ +/*! is.js + + (c) 2001 Douglas Crockford + 2001 June 3 +*/ + +// is + +// The -is- object is used to identify the browser. Every browser edition +// identifies itself, but there is no standard way of doing it, and some of +// the identification is deceptive. This is because the authors of web +// browsers are liars. For example, Microsoft's IE browsers claim to be +// Mozilla 4. Netscape 6 claims to be version 5. + +var is = { + ie: navigator.appName == 'Microsoft Internet Explorer', + java: navigator.javaEnabled(), + ns: navigator.appName == 'Netscape', + ua: navigator.userAgent.toLowerCase(), + version: parseFloat(navigator.appVersion.substr(21)) || + parseFloat(navigator.appVersion), + win: navigator.platform == 'Win32' +} +/*!* + * preserve this comment, too + */ +is.mac = is.ua.indexOf('mac') >= 0; +if (is.ua.indexOf('opera') >= 0) { + is.ie = is.ns = false; + is.opera = true; +} +if (is.ua.indexOf('gecko') >= 0) { + is.ie = is.ns = false; + is.gecko = true; +} + +/*@cc_on + /*@if (@_win32) + if (is.ie && is.win) + document.write("PASS: IE/win honored conditional comment.
    "); + @else @*/ + if (is.ie && is.win) + document.write("FAIL: IE/win did not honor multi-line conditional comment.
    "); + else + document.write("PASS: Non-IE/win browser ignores multi-line conditional comment.
    "); + /*@end +@*/ + +var recognizesCondComm = true; +//@cc_on/* +recognizesCondComm = false; +//@cc_on*/ + +if ((is.ie && is.win) == recognizesCondComm) + document.write("PASS: IE/win honored single-line conditional comment.
    "); +else + document.write("FAIL: Non-IE/win browser did not ignore single-line conditional comment.
    "); diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min.js new file mode 100644 index 000000000..6f06c6e6c --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min.js @@ -0,0 +1,22 @@ +/* is.js + + (c) 2001 Douglas Crockford + 2001 June 3 +*/ +var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'} +/** + * preserve this comment, too + */ +is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;} +if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}/*@cc_on + /*@if (@_win32) + if (is.ie && is.win) + document.write("PASS: IE/win honored conditional comment.
    "); + @else @*/if(is.ie&&is.win) +document.write("FAIL: IE/win did not honor multi-line conditional comment.
    ");else +document.write("PASS: Non-IE/win browser ignores multi-line conditional comment.
    ");/*@end +@*/var recognizesCondComm=true;//@cc_on/* +recognizesCondComm=false;//@cc_on*/ +if((is.ie&&is.win)==recognizesCondComm) +document.write("PASS: IE/win honored single-line conditional comment.
    ");else +document.write("FAIL: Non-IE/win browser did not ignore single-line conditional comment.
    "); \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min_plus.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min_plus.js new file mode 100644 index 000000000..6f06c6e6c --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min_plus.js @@ -0,0 +1,22 @@ +/* is.js + + (c) 2001 Douglas Crockford + 2001 June 3 +*/ +var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'} +/** + * preserve this comment, too + */ +is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;} +if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}/*@cc_on + /*@if (@_win32) + if (is.ie && is.win) + document.write("PASS: IE/win honored conditional comment.
    "); + @else @*/if(is.ie&&is.win) +document.write("FAIL: IE/win did not honor multi-line conditional comment.
    ");else +document.write("PASS: Non-IE/win browser ignores multi-line conditional comment.
    ");/*@end +@*/var recognizesCondComm=true;//@cc_on/* +recognizesCondComm=false;//@cc_on*/ +if((is.ie&&is.win)==recognizesCondComm) +document.write("PASS: IE/win honored single-line conditional comment.
    ");else +document.write("FAIL: Non-IE/win browser did not ignore single-line conditional comment.
    "); \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.js new file mode 100644 index 000000000..28aa1268b --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.js @@ -0,0 +1,14 @@ +var isWin; +/*@cc_on + @if (@_win32) + isWin = true; + @else @*/ isWin = false; + /*@end +@*/ + +isWin = /*@cc_on!*/!1; + +var recognizesCondComm = true; +//@cc_on/* +recognizesCondComm = false; +//@cc_on*/ diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.min_plus.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.min_plus.js new file mode 100644 index 000000000..d8c1ed386 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.min_plus.js @@ -0,0 +1,13 @@ +var isWin; +/*@cc_on + @if (@_win32) + isWin = true; + @else @*/ + isWin = false; + /*@end +@*/ + +var recognizesCondComm = true; +//@cc_on/* +recognizesCondComm = false; +//@cc_on*/ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.js new file mode 100644 index 000000000..e12eaeb48 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.js @@ -0,0 +1,4 @@ + +function testIssue74() { + return /'/; +} diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min.js new file mode 100644 index 000000000..3442a73fc --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min.js @@ -0,0 +1 @@ +function testIssue74(){return /'/;} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min_plus.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min_plus.js new file mode 100644 index 000000000..9caaa899c --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min_plus.js @@ -0,0 +1 @@ +function testIssue74(){return /'/} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/jquery-1.2.3.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/jquery-1.2.3.js new file mode 100644 index 000000000..c5a333760 --- /dev/null +++ b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/jquery-1.2.3.js @@ -0,0 +1,3408 @@ +(function(){ +/*! + * jQuery 1.2.3 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ + * $Rev: 4663 $ + */ + +// Map over jQuery in case of overwrite +if ( window.jQuery ) + var _jQuery = window.jQuery; + +var jQuery = window.jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.prototype.init( selector, context ); +}; + +// Map over the $ in case of overwrite +if ( window.$ ) + var _$ = window.$; + +// Map the jQuery namespace to the '$' one +window.$ = jQuery; + +// A simple way to check for HTML strings or ID strings +// (both of which we optimize for) +var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/; + +// Is it a simple selector +var isSimple = /^.[^:#\[\.]*$/; + +jQuery.fn = jQuery.prototype = { + init: function( selector, context ) { + // Make sure that a selection was provided + selector = selector || document; + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this[0] = selector; + this.length = 1; + return this; + + // Handle HTML strings + } else if ( typeof selector == "string" ) { + // Are we dealing with HTML string or an ID? + var match = quickExpr.exec( selector ); + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) + selector = jQuery.clean( [ match[1] ], context ); + + // HANDLE: $("#id") + else { + var elem = document.getElementById( match[3] ); + + // Make sure an element was located + if ( elem ) + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id != match[3] ) + return jQuery().find( selector ); + + // Otherwise, we inject the element directly into the jQuery object + else { + this[0] = elem; + this.length = 1; + return this; + } + + else + selector = []; + } + + // HANDLE: $(expr, [context]) + // (which is just equivalent to: $(content).find(expr) + } else + return new jQuery( context ).find( selector ); + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) + return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); + + return this.setArray( + // HANDLE: $(array) + selector.constructor == Array && selector || + + // HANDLE: $(arraylike) + // Watch for when an array-like object, contains DOM nodes, is passed in as the selector + (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) || + + // HANDLE: $(*) + [ selector ] ); + }, + + // The current version of jQuery being used + jquery: "1.2.3", + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + // The number of elements contained in the matched element set + length: 0, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == undefined ? + + // Return a 'clean' array + jQuery.makeArray( this ) : + + // Return just the object + this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + // Build a new jQuery matched element set + var ret = jQuery( elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Force the current matched set of elements to become + // the specified array of elements (destroying the stack in the process) + // You should use pushStack() in order to do this, but maintain the stack + setArray: function( elems ) { + // Resetting the length to 0, then using the native Array push + // is a super-fast way to populate an object with array-like properties + this.length = 0; + Array.prototype.push.apply( this, elems ); + + return this; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + var ret = -1; + + // Locate the position of the desired element + this.each(function(i){ + if ( this == elem ) + ret = i; + }); + + return ret; + }, + + attr: function( name, value, type ) { + var options = name; + + // Look for the case where we're accessing a style value + if ( name.constructor == String ) + if ( value == undefined ) + return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined; + + else { + options = {}; + options[ name ] = value; + } + + // Check to see if we're setting style values + return this.each(function(i){ + // Set all the styles + for ( name in options ) + jQuery.attr( + type ? + this.style : + this, + name, jQuery.prop( this, options[ name ], type, i, name ) + ); + }); + }, + + css: function( key, value ) { + // ignore negative width and height values + if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) + value = undefined; + return this.attr( key, value, "curCSS" ); + }, + + text: function( text ) { + if ( typeof text != "object" && text != null ) + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); + + var ret = ""; + + jQuery.each( text || this, function(){ + jQuery.each( this.childNodes, function(){ + if ( this.nodeType != 8 ) + ret += this.nodeType != 1 ? + this.nodeValue : + jQuery.fn.text( [ this ] ); + }); + }); + + return ret; + }, + + wrapAll: function( html ) { + if ( this[0] ) + // The elements to wrap the target around + jQuery( html, this[0].ownerDocument ) + .clone() + .insertBefore( this[0] ) + .map(function(){ + var elem = this; + + while ( elem.firstChild ) + elem = elem.firstChild; + + return elem; + }) + .append(this); + + return this; + }, + + wrapInner: function( html ) { + return this.each(function(){ + jQuery( this ).contents().wrapAll( html ); + }); + }, + + wrap: function( html ) { + return this.each(function(){ + jQuery( this ).wrapAll( html ); + }); + }, + + append: function() { + return this.domManip(arguments, true, false, function(elem){ + if (this.nodeType == 1) + this.appendChild( elem ); + }); + }, + + prepend: function() { + return this.domManip(arguments, true, true, function(elem){ + if (this.nodeType == 1) + this.insertBefore( elem, this.firstChild ); + }); + }, + + before: function() { + return this.domManip(arguments, false, false, function(elem){ + this.parentNode.insertBefore( elem, this ); + }); + }, + + after: function() { + return this.domManip(arguments, false, true, function(elem){ + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + }, + + end: function() { + return this.prevObject || jQuery( [] ); + }, + + find: function( selector ) { + var elems = jQuery.map(this, function(elem){ + return jQuery.find( selector, elem ); + }); + + return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? + jQuery.unique( elems ) : + elems ); + }, + + clone: function( events ) { + // Do the clone + var ret = this.map(function(){ + if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { + // IE copies events bound via attachEvent when + // using cloneNode. Calling detachEvent on the + // clone will also remove the events from the orignal + // In order to get around this, we use innerHTML. + // Unfortunately, this means some modifications to + // attributes in IE that are actually only stored + // as properties will not be copied (such as the + // the name attribute on an input). + var clone = this.cloneNode(true), + container = document.createElement("div"); + container.appendChild(clone); + return jQuery.clean([container.innerHTML])[0]; + } else + return this.cloneNode(true); + }); + + // Need to set the expando to null on the cloned set if it exists + // removeData doesn't work here, IE removes it from the original as well + // this is primarily for IE but the data expando shouldn't be copied over in any browser + var clone = ret.find("*").andSelf().each(function(){ + if ( this[ expando ] != undefined ) + this[ expando ] = null; + }); + + // Copy the events from the original to the clone + if ( events === true ) + this.find("*").andSelf().each(function(i){ + if (this.nodeType == 3) + return; + var events = jQuery.data( this, "events" ); + + for ( var type in events ) + for ( var handler in events[ type ] ) + jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); + }); + + // Return the cloned set + return ret; + }, + + filter: function( selector ) { + return this.pushStack( + jQuery.isFunction( selector ) && + jQuery.grep(this, function(elem, i){ + return selector.call( elem, i ); + }) || + + jQuery.multiFilter( selector, this ) ); + }, + + not: function( selector ) { + if ( selector.constructor == String ) + // test special case where just one selector is passed in + if ( isSimple.test( selector ) ) + return this.pushStack( jQuery.multiFilter( selector, this, true ) ); + else + selector = jQuery.multiFilter( selector, this ); + + var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; + return this.filter(function() { + return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; + }); + }, + + add: function( selector ) { + return !selector ? this : this.pushStack( jQuery.merge( + this.get(), + selector.constructor == String ? + jQuery( selector ).get() : + selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ? + selector : [selector] ) ); + }, + + is: function( selector ) { + return selector ? + jQuery.multiFilter( selector, this ).length > 0 : + false; + }, + + hasClass: function( selector ) { + return this.is( "." + selector ); + }, + + val: function( value ) { + if ( value == undefined ) { + + if ( this.length ) { + var elem = this[0]; + + // We need to handle select boxes special + if ( jQuery.nodeName( elem, "select" ) ) { + var index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type == "select-one"; + + // Nothing was selected + if ( index < 0 ) + return null; + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + if ( option.selected ) { + // Get the specifc value for the option + value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; + + // We don't need an array for one selects + if ( one ) + return value; + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + + // Everything else, we just grab the value + } else + return (this[0].value || "").replace(/\r/g, ""); + + } + + return undefined; + } + + return this.each(function(){ + if ( this.nodeType != 1 ) + return; + + if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) + this.checked = (jQuery.inArray(this.value, value) >= 0 || + jQuery.inArray(this.name, value) >= 0); + + else if ( jQuery.nodeName( this, "select" ) ) { + var values = value.constructor == Array ? + value : + [ value ]; + + jQuery( "option", this ).each(function(){ + this.selected = (jQuery.inArray( this.value, values ) >= 0 || + jQuery.inArray( this.text, values ) >= 0); + }); + + if ( !values.length ) + this.selectedIndex = -1; + + } else + this.value = value; + }); + }, + + html: function( value ) { + return value == undefined ? + (this.length ? + this[0].innerHTML : + null) : + this.empty().append( value ); + }, + + replaceWith: function( value ) { + return this.after( value ).remove(); + }, + + eq: function( i ) { + return this.slice( i, i + 1 ); + }, + + slice: function() { + return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function(elem, i){ + return callback.call( elem, i, elem ); + })); + }, + + andSelf: function() { + return this.add( this.prevObject ); + }, + + data: function( key, value ){ + var parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value == null ) { + var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + if ( data == undefined && this.length ) + data = jQuery.data( this[0], key ); + + return data == null && parts[1] ? + this.data( parts[0] ) : + data; + } else + return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ + jQuery.data( this, key, value ); + }); + }, + + removeData: function( key ){ + return this.each(function(){ + jQuery.removeData( this, key ); + }); + }, + + domManip: function( args, table, reverse, callback ) { + var clone = this.length > 1, elems; + + return this.each(function(){ + if ( !elems ) { + elems = jQuery.clean( args, this.ownerDocument ); + + if ( reverse ) + elems.reverse(); + } + + var obj = this; + + if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) + obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); + + var scripts = jQuery( [] ); + + jQuery.each(elems, function(){ + var elem = clone ? + jQuery( this ).clone( true )[0] : + this; + + // execute all scripts after the elements have been injected + if ( jQuery.nodeName( elem, "script" ) ) { + scripts = scripts.add( elem ); + } else { + // Remove any inner scripts for later evaluation + if ( elem.nodeType == 1 ) + scripts = scripts.add( jQuery( "script", elem ).remove() ); + + // Inject the elements into the document + callback.call( obj, elem ); + } + }); + + scripts.each( evalScript ); + }); + } +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.prototype.init.prototype = jQuery.prototype; + +function evalScript( i, elem ) { + if ( elem.src ) + jQuery.ajax({ + url: elem.src, + async: false, + dataType: "script" + }); + + else + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); + + if ( elem.parentNode ) + elem.parentNode.removeChild( elem ); +} + +jQuery.extend = jQuery.fn.extend = function() { + // copy reference to target object + var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; + + // Handle a deep copy situation + if ( target.constructor == Boolean ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target != "object" && typeof target != "function" ) + target = {}; + + // extend jQuery itself if only one argument is passed + if ( length == 1 ) { + target = this; + i = 0; + } + + for ( ; i < length; i++ ) + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) + // Extend the base object + for ( var name in options ) { + // Prevent never-ending loop + if ( target === options[ name ] ) + continue; + + // Recurse if we're merging object values + if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType ) + target[ name ] = jQuery.extend( target[ name ], options[ name ] ); + + // Don't bring in undefined values + else if ( options[ name ] != undefined ) + target[ name ] = options[ name ]; + + } + + // Return the modified object + return target; +}; + +var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {}; + +// exclude the following css properties to add px +var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i; + +jQuery.extend({ + noConflict: function( deep ) { + window.$ = _$; + + if ( deep ) + window.jQuery = _jQuery; + + return jQuery; + }, + + // See test/unit/core.js for details concerning this function. + isFunction: function( fn ) { + return !!fn && typeof fn != "string" && !fn.nodeName && + fn.constructor != Array && /function/i.test( fn + "" ); + }, + + // check if an element is in a (or is an) XML document + isXMLDoc: function( elem ) { + return elem.documentElement && !elem.body || + elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; + }, + + // Evalulates a script in a global context + globalEval: function( data ) { + data = jQuery.trim( data ); + + if ( data ) { + // Inspired by code by Andrea Giammarchi + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html + var head = document.getElementsByTagName("head")[0] || document.documentElement, + script = document.createElement("script"); + + script.type = "text/javascript"; + if ( jQuery.browser.msie ) + script.text = data; + else + script.appendChild( document.createTextNode( data ) ); + + head.appendChild( script ); + head.removeChild( script ); + } + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); + }, + + cache: {}, + + data: function( elem, name, data ) { + elem = elem == window ? + windowData : + elem; + + var id = elem[ expando ]; + + // Compute a unique ID for the element + if ( !id ) + id = elem[ expando ] = ++uuid; + + // Only generate the data cache if we're + // trying to access or manipulate it + if ( name && !jQuery.cache[ id ] ) + jQuery.cache[ id ] = {}; + + // Prevent overriding the named cache with undefined values + if ( data != undefined ) + jQuery.cache[ id ][ name ] = data; + + // Return the named cache data, or the ID for the element + return name ? + jQuery.cache[ id ][ name ] : + id; + }, + + removeData: function( elem, name ) { + elem = elem == window ? + windowData : + elem; + + var id = elem[ expando ]; + + // If we want to remove a specific section of the element's data + if ( name ) { + if ( jQuery.cache[ id ] ) { + // Remove the section of cache data + delete jQuery.cache[ id ][ name ]; + + // If we've removed all the data, remove the element's cache + name = ""; + + for ( name in jQuery.cache[ id ] ) + break; + + if ( !name ) + jQuery.removeData( elem ); + } + + // Otherwise, we want to remove all of the element's data + } else { + // Clean up the element expando + try { + delete elem[ expando ]; + } catch(e){ + // IE has trouble directly removing the expando + // but it's ok with using removeAttribute + if ( elem.removeAttribute ) + elem.removeAttribute( expando ); + } + + // Completely remove the data cache + delete jQuery.cache[ id ]; + } + }, + + // args is for internal usage only + each: function( object, callback, args ) { + if ( args ) { + if ( object.length == undefined ) { + for ( var name in object ) + if ( callback.apply( object[ name ], args ) === false ) + break; + } else + for ( var i = 0, length = object.length; i < length; i++ ) + if ( callback.apply( object[ i ], args ) === false ) + break; + + // A special, fast, case for the most common use of each + } else { + if ( object.length == undefined ) { + for ( var name in object ) + if ( callback.call( object[ name ], name, object[ name ] ) === false ) + break; + } else + for ( var i = 0, length = object.length, value = object[0]; + i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} + } + + return object; + }, + + prop: function( elem, value, type, i, name ) { + // Handle executable functions + if ( jQuery.isFunction( value ) ) + value = value.call( elem, i ); + + // Handle passing in a number to a CSS property + return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? + value + "px" : + value; + }, + + className: { + // internal only, use addClass("class") + add: function( elem, classNames ) { + jQuery.each((classNames || "").split(/\s+/), function(i, className){ + if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) + elem.className += (elem.className ? " " : "") + className; + }); + }, + + // internal only, use removeClass("class") + remove: function( elem, classNames ) { + if (elem.nodeType == 1) + elem.className = classNames != undefined ? + jQuery.grep(elem.className.split(/\s+/), function(className){ + return !jQuery.className.has( classNames, className ); + }).join(" ") : + ""; + }, + + // internal only, use is(".class") + has: function( elem, className ) { + return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; + } + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var old = {}; + // Remember the old values, and insert the new ones + for ( var name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + callback.call( elem ); + + // Revert the old values + for ( var name in options ) + elem.style[ name ] = old[ name ]; + }, + + css: function( elem, name, force ) { + if ( name == "width" || name == "height" ) { + var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; + + function getWH() { + val = name == "width" ? elem.offsetWidth : elem.offsetHeight; + var padding = 0, border = 0; + jQuery.each( which, function() { + padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; + border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; + }); + val -= Math.round(padding + border); + } + + if ( jQuery(elem).is(":visible") ) + getWH(); + else + jQuery.swap( elem, props, getWH ); + + return Math.max(0, val); + } + + return jQuery.curCSS( elem, name, force ); + }, + + curCSS: function( elem, name, force ) { + var ret; + + // A helper method for determining if an element's values are broken + function color( elem ) { + if ( !jQuery.browser.safari ) + return false; + + var ret = document.defaultView.getComputedStyle( elem, null ); + return !ret || ret.getPropertyValue("color") == ""; + } + + // We need to handle opacity special in IE + if ( name == "opacity" && jQuery.browser.msie ) { + ret = jQuery.attr( elem.style, "opacity" ); + + return ret == "" ? + "1" : + ret; + } + // Opera sometimes will give the wrong display answer, this fixes it, see #2037 + if ( jQuery.browser.opera && name == "display" ) { + var save = elem.style.outline; + elem.style.outline = "0 solid black"; + elem.style.outline = save; + } + + // Make sure we're using the right name for getting the float value + if ( name.match( /float/i ) ) + name = styleFloat; + + if ( !force && elem.style && elem.style[ name ] ) + ret = elem.style[ name ]; + + else if ( document.defaultView && document.defaultView.getComputedStyle ) { + + // Only "float" is needed here + if ( name.match( /float/i ) ) + name = "float"; + + name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); + + var getComputedStyle = document.defaultView.getComputedStyle( elem, null ); + + if ( getComputedStyle && !color( elem ) ) + ret = getComputedStyle.getPropertyValue( name ); + + // If the element isn't reporting its values properly in Safari + // then some display: none elements are involved + else { + var swap = [], stack = []; + + // Locate all of the parent display: none elements + for ( var a = elem; a && color(a); a = a.parentNode ) + stack.unshift(a); + + // Go through and make them visible, but in reverse + // (It would be better if we knew the exact display type that they had) + for ( var i = 0; i < stack.length; i++ ) + if ( color( stack[ i ] ) ) { + swap[ i ] = stack[ i ].style.display; + stack[ i ].style.display = "block"; + } + + // Since we flip the display style, we have to handle that + // one special, otherwise get the value + ret = name == "display" && swap[ stack.length - 1 ] != null ? + "none" : + ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || ""; + + // Finally, revert the display styles back + for ( var i = 0; i < swap.length; i++ ) + if ( swap[ i ] != null ) + stack[ i ].style.display = swap[ i ]; + } + + // We should always get a number back from opacity + if ( name == "opacity" && ret == "" ) + ret = "1"; + + } else if ( elem.currentStyle ) { + var camelCase = name.replace(/\-(\w)/g, function(all, letter){ + return letter.toUpperCase(); + }); + + ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { + // Remember the original values + var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + elem.runtimeStyle.left = elem.currentStyle.left; + elem.style.left = ret || 0; + ret = elem.style.pixelLeft + "px"; + + // Revert the changed values + elem.style.left = style; + elem.runtimeStyle.left = runtimeStyle; + } + } + + return ret; + }, + + clean: function( elems, context ) { + var ret = []; + context = context || document; + // !context.createElement fails in IE with an error but returns typeof 'object' + if (typeof context.createElement == 'undefined') + context = context.ownerDocument || context[0] && context[0].ownerDocument || document; + + jQuery.each(elems, function(i, elem){ + if ( !elem ) + return; + + if ( elem.constructor == Number ) + elem = elem.toString(); + + // Convert html string into DOM nodes + if ( typeof elem == "string" ) { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ + return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? + all : + front + ">"; + }); + + // Trim whitespace, otherwise indexOf won't work as expected + var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); + + var wrap = + // option or optgroup + !tags.indexOf("", "" ] || + + !tags.indexOf("", "" ] || + + tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && + [ 1, "", "
    " ] || + + !tags.indexOf("", "" ] || + + // matched above + (!tags.indexOf("", "" ] || + + !tags.indexOf("", "" ] || + + // IE can't serialize and \ No newline at end of file diff --git a/plugins/Minify/minify.php b/plugins/Minify/minify.php new file mode 100644 index 000000000..2de2d6d26 --- /dev/null +++ b/plugins/Minify/minify.php @@ -0,0 +1,122 @@ +. + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } + +// We bundle the minify library... +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/minify/min/lib'); + +class MinifyAction extends Action +{ + const TYPE_CSS = 'text/css'; + const TYPE_HTML = 'text/html'; + // there is some debate over the ideal JS Content-Type, but this is the + // Apache default and what Yahoo! uses.. + const TYPE_JS = 'application/x-javascript'; + + const cacheKey = 'minify'; + + var $file; + + function isReadOnly($args) + { + return true; + } + + function prepare($args) + { + parent::prepare($args); + $this->v = $args['v']; + + $f = $this->arg('f'); + if(isset($f)) { + $this->file = INSTALLDIR.'/'.$f; + if(file_exists($this->file)) { + return true; + } else { + $this->clientError(_('f parameter is not a valid path'),404); + return false; + } + }else{ + $this->clientError(_('f parameter is required'),500); + return false; + } + } + + function etag() + { + if(isset($this->v)) { + return "\"" . crc32($this->file . $this->v) . "\""; + }else{ + $stat = stat($this->file); + return '"' . $stat['ino'] . '-' . $stat['size'] . '-' . $stat['mtime'] . '"'; + } + } + + function lastModified() + { + return filemtime($this->file); + } + + function handle($args) + { + parent::handle($args); + + $c = common_memcache(); + if (!empty($c)) { + $out = $c->get(common_cache_key(self::cacheKey . ':' . $this->file)); + } + if(empty($out)) { + $out = $this->minify($this->file); + } + if (!empty($c)) { + $c->set(common_cache_key(self::cacheKey . ':' . $this->file), $out); + } + + $sec = session_cache_expire() * 60; + header('Cache-Control: public, max-age=' . $sec); + header('Pragma: public'); + $this->raw($out); + } + + function minify($file) + { + $info = pathinfo($file); + switch(strtolower($info['extension'])){ + case 'js': + require_once('JSMin.php'); + $out = JSMin::minify(file_get_contents($file)); + header('Content-Type: ' . self::TYPE_JS); + break; + case 'css': + require_once('Minify/CSS.php'); + $options = array(); + $options['currentDir'] = dirname($file); + $options['docRoot'] = INSTALLDIR; + $out = Minify_CSS::minify(file_get_contents($file),$options); + header('Content-Type: ' . self::TYPE_CSS); + break; + default: + $this->clientError(_('File type not supported'),500); + return false; + } + return $out; + } +} + -- cgit v1.2.3-54-g00ecf From a92228c713c73b4015766b45eecd4769a57ae232 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 4 Dec 2009 14:31:19 -0500 Subject: Update Mapstraction to properly scrape data from notice-list pages Refactored the JavaScript for Mapstraction use so it scrapes data from the HTML of the page it's on, if possible, and otherwise generates a JSON array. --- plugins/Mapstraction/MapstractionPlugin.php | 22 +++++++- plugins/Mapstraction/map.php | 9 +-- plugins/Mapstraction/usermap.js | 87 +++++++++++++++-------------- 3 files changed, 67 insertions(+), 51 deletions(-) (limited to 'plugins') diff --git a/plugins/Mapstraction/MapstractionPlugin.php b/plugins/Mapstraction/MapstractionPlugin.php index c4f9cd77d..ba7827151 100644 --- a/plugins/Mapstraction/MapstractionPlugin.php +++ b/plugins/Mapstraction/MapstractionPlugin.php @@ -112,6 +112,11 @@ class MapstractionPlugin extends Plugin { $actionName = $action->trimmed('action'); + if (!in_array($actionName, + array('showstream', 'all', 'usermap', 'allmap'))) { + return true; + } + switch ($this->provider) { case 'cloudmade': @@ -143,9 +148,20 @@ class MapstractionPlugin extends Plugin $action->script(common_path('plugins/Mapstraction/usermap.js')); - $action->elementStart('script', array('type' => 'text/javascript')); - $action->raw(sprintf('var _provider = "%s";', $this->provider)); - $action->elementEnd('script'); + $action->inlineScript(sprintf('var _provider = "%s";', $this->provider)); + + // usermap and allmap handle this themselves + + if (in_array($actionName, + array('showstream', 'all'))) { + $action->inlineScript('$(document).ready(function() { '. + ' var user = null; '. + (($actionName == 'showstream') ? ' user = scrapeUser(); ' : '') . + ' var notices = scrapeNotices(user); ' . + ' console.log(notices); ' . + ' showMapstraction($("#map_canvas"), notices); '. + '});'); + } return true; } diff --git a/plugins/Mapstraction/map.php b/plugins/Mapstraction/map.php index 89723f43c..734e48088 100644 --- a/plugins/Mapstraction/map.php +++ b/plugins/Mapstraction/map.php @@ -128,12 +128,9 @@ class MapAction extends OwnerDesignAction } } - $this->elementStart('script', array('type' => 'text/javascript')); - $this->raw('/*raw('var _notices = ' . json_encode($jsonArray).'; '); - $this->raw('showMapstraction($("#map_canvas"),_notices);'); - $this->raw('/*]]>*/'); // XHTML compat for Safari - $this->elementEnd('script'); + $this->inlineScript('$(document).ready(function() { '. + ' var _notices = ' . json_encode($jsonArray).'; ' . + 'showMapstraction($("#map_canvas"), _notices); });'); return true; } diff --git a/plugins/Mapstraction/usermap.js b/plugins/Mapstraction/usermap.js index e667dd579..4b7a6c26b 100644 --- a/plugins/Mapstraction/usermap.js +++ b/plugins/Mapstraction/usermap.js @@ -1,40 +1,32 @@ -$(document).ready(function() { +function scrapeNotices(user) +{ var notices = []; $(".notice").each(function(){ - var notice = getNoticeFromElement($(this)); - if(notice['geo']) - notices.push(notice); + var notice = getNoticeFromElement($(this)); + if (user) { + notice['user'] = user; + } else { + notice['user'] = getUserFromElement($(this)); + } + if(notice['geo']) + notices.push(notice); }); - if($("#map_canvas").length && notices.length>0) - { - showMapstraction($("#map_canvas"), notices); - } - $('.geo').click(function(){ - var noticeElement = $(this).closest(".notice"); - notice = getNoticeFromElement(noticeElement); - - $.fn.jOverlay.options = { - color : '#000', - opacity : '0.6', - zIndex : 99, - center : false, - bgClickToClose : true, - autoHide : true, - css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'} - }; - var html="
    "; - html+=""; - html+=$("
    ").append($(this).clone()).html(); - $().jOverlay({ "html": html }); - $('#jOverlayContent').show(); - $('#jOverlayContent button').click($.closeOverlay); - - showMapstraction($("#map_canvas_popup"), notice); - - return false; - }); -}); + return notices; +} + +function scrapeUser() +{ + var avatarURL = $(".entity_profile .entity_depiction img.avatar").attr('src'); + var profileURL = $(".entity_profile .entity_nickname .url").attr('href'); + var nickname = $(".entity_profile .entity_nickname .nickname").text(); + + return { + 'profile_image_url': avatarURL, + 'profile_url': profileURL, + 'screen_name': nickname + }; +} function getMicroformatValue(element) { @@ -48,23 +40,34 @@ function getMicroformatValue(element) function getNoticeFromElement(noticeElement) { var notice = {}; - if(noticeElement.find(".geo").length){ + + if(noticeElement.find(".geo").length) { var latlon = noticeElement.find(".geo").attr('title').split(";"); notice['geo']={'coordinates': [ parseFloat(latlon[0]), parseFloat(latlon[1])] }; } - notice['user']={ - 'profile_image_url': noticeElement.find("img.avatar").attr('src'), - 'profile_url': noticeElement.find(".author a.url").attr('href'), - 'screen_name': noticeElement.find(".author .nickname").text() - }; - notice['html']=noticeElement.find(".entry-content").html(); - notice['url']=noticeElement.find("a.timestamp").attr('href'); - notice['created_at']=noticeElement.find("abbr.published").text(); + + notice['html'] = noticeElement.find(".entry-content").html(); + notice['url'] = noticeElement.find("a.timestamp").attr('href'); + notice['created_at'] = noticeElement.find("abbr.published").text(); + return notice; } +function getUserFromElement(noticeElement) +{ + var avatarURL = noticeElement.find("img.avatar").attr('src'); + var profileURL = noticeElement.find(".author a.url").attr('href'); + var nickname = noticeElement.find(".author .nickname").text(); + + return { + 'profile_image_url': avatarURL, + 'profile_url': profileURL, + 'screen_name': nickname + }; +} + function showMapstraction(element, notices) { if(element instanceof jQuery) element = element[0]; if(! $.isArray(notices)) notices = [notices]; -- cgit v1.2.3-54-g00ecf From e7e9dfceb4fd6db81bf266d71a3ec0b1933fbd02 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 4 Dec 2009 14:36:24 -0500 Subject: remove unnecessary debugging code from mapstraction output --- plugins/Mapstraction/MapstractionPlugin.php | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/Mapstraction/MapstractionPlugin.php b/plugins/Mapstraction/MapstractionPlugin.php index ba7827151..f20e81b0e 100644 --- a/plugins/Mapstraction/MapstractionPlugin.php +++ b/plugins/Mapstraction/MapstractionPlugin.php @@ -158,7 +158,6 @@ class MapstractionPlugin extends Plugin ' var user = null; '. (($actionName == 'showstream') ? ' user = scrapeUser(); ' : '') . ' var notices = scrapeNotices(user); ' . - ' console.log(notices); ' . ' showMapstraction($("#map_canvas"), notices); '. '});'); } -- cgit v1.2.3-54-g00ecf From cff12603cf13ddde59f82597cdf896bf0deaf596 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Fri, 4 Dec 2009 20:17:42 +0000 Subject: Make imported Twitter notices show up via real time plugins. --- plugins/TwitterBridge/TwitterBridgePlugin.php | 7 ++++++- plugins/TwitterBridge/daemons/twitterstatusfetcher.php | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/TwitterBridge/TwitterBridgePlugin.php b/plugins/TwitterBridge/TwitterBridgePlugin.php index ad3c2e551..adf9ceda3 100644 --- a/plugins/TwitterBridge/TwitterBridgePlugin.php +++ b/plugins/TwitterBridge/TwitterBridgePlugin.php @@ -127,7 +127,12 @@ class TwitterBridgePlugin extends Plugin */ function onStartEnqueueNotice($notice, &$transports) { - array_push($transports, 'twitter'); + // Avoid a possible loop + + if ($notice->source != 'twitter') { + array_push($transports, 'twitter'); + } + return true; } diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php index eba1d563b..d8901f47b 100755 --- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php +++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php @@ -209,7 +209,11 @@ class TwitterStatusFetcher extends ParallelizingDaemon continue; } - $this->saveStatus($status, $flink); + $notice = null; + + $notice = $this->saveStatus($status, $flink); + + common_broadcast_notice($notice); } // Okay, record the time we synced with Twitter for posterity @@ -235,12 +239,14 @@ class TwitterStatusFetcher extends ParallelizingDaemon $uri = 'http://twitter.com/' . $status->user->screen_name . '/status/' . $status->id; - $notice = Notice::staticGet('uri', $uri); - // check to see if we've already imported the status + $notice = Notice::staticGet('uri', $uri); + if (empty($notice)) { + // XXX: transaction here? + $notice = new Notice(); $notice->profile_id = $id; @@ -257,6 +263,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon $id = $notice->insert(); Event::handle('EndNoticeSave', array($notice)); } + } if (!Notice_inbox::pkeyGet(array('notice_id' => $notice->id, @@ -270,7 +277,12 @@ class TwitterStatusFetcher extends ParallelizingDaemon $inbox->source = NOTICE_INBOX_SOURCE_GATEWAY; // From a private source $inbox->insert(); + } + + $notice->blowCaches(); + + return $notice; } function ensureProfile($user) -- cgit v1.2.3-54-g00ecf From 99b23782ef871d774e0c4abffc3632ea70ee149a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 4 Dec 2009 15:30:43 -0500 Subject: let Geonames clients use commercial Web service --- plugins/GeonamesPlugin.php | 59 +++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'plugins') diff --git a/plugins/GeonamesPlugin.php b/plugins/GeonamesPlugin.php index 340a6f0bf..fdbf79e41 100644 --- a/plugins/GeonamesPlugin.php +++ b/plugins/GeonamesPlugin.php @@ -51,6 +51,10 @@ class GeonamesPlugin extends Plugin { const LOCATION_NS = 1; + public $host = 'ws.geonames.org'; + public $username = null; + public $token = null; + /** * convert a name into a Location object * @@ -75,12 +79,11 @@ class GeonamesPlugin extends Plugin // XXX: break down a name by commas, narrow by each - $str = http_build_query(array('maxRows' => 1, - 'q' => $name, - 'lang' => $language, - 'type' => 'json')); - - $result = $client->get('http://ws.geonames.org/search?'.$str); + $result = $client->get($this->wsUrl('search', + array('maxRows' => 1, + 'q' => $name, + 'lang' => $language, + 'type' => 'json'))); if ($result->isOk()) { $rj = json_decode($result->getBody()); @@ -135,10 +138,9 @@ class GeonamesPlugin extends Plugin $client = HTTPClient::start(); - $str = http_build_query(array('geonameId' => $id, - 'lang' => $language)); - - $result = $client->get('http://ws.geonames.org/hierarchyJSON?'.$str); + $result = $client->get($this->wsUrl('hierarchyJSON', + array('geonameId' => $id, + 'lang' => $language))); if ($result->isOk()) { @@ -205,12 +207,11 @@ class GeonamesPlugin extends Plugin $client = HTTPClient::start(); - $str = http_build_query(array('lat' => $lat, - 'lng' => $lon, - 'lang' => $language)); - $result = - $client->get('http://ws.geonames.org/findNearbyPlaceNameJSON?'.$str); + $client->get($this->wsUrl('findNearbyPlaceNameJSON', + array('lat' => $lat, + 'lng' => $lon, + 'lang' => $language))); if ($result->isOk()) { @@ -286,10 +287,9 @@ class GeonamesPlugin extends Plugin $client = HTTPClient::start(); - $str = http_build_query(array('geonameId' => $location->location_id, - 'lang' => $language)); - - $result = $client->get('http://ws.geonames.org/hierarchyJSON?'.$str); + $result = $client->get($this->wsUrl('hierarchyJSON', + array('geonameId' => $location->location_id, + 'lang' => $language))); if ($result->isOk()) { @@ -376,7 +376,7 @@ class GeonamesPlugin extends Plugin { $c = common_memcache(); - if (!$c) { + if (empty($c)) { return null; } @@ -387,7 +387,7 @@ class GeonamesPlugin extends Plugin { $c = common_memcache(); - if (!$c) { + if (empty($c)) { return null; } @@ -398,7 +398,7 @@ class GeonamesPlugin extends Plugin { $c = common_memcache(); - if (!$c) { + if (empty($c)) { return null; } @@ -411,4 +411,19 @@ class GeonamesPlugin extends Plugin implode(',', array_keys($attrs)) . ':'. common_keyize(implode(',', array_values($attrs)))); } + + function wsUrl($method, $params) + { + if (!empty($this->username)) { + $params['username'] = $this->username; + } + + if (!empty($this->token)) { + $params['token'] = $this->token; + } + + $str = http_build_query($params); + + return 'http://'.$this->host.'/'.$method.'?'.$str; + } } -- cgit v1.2.3-54-g00ecf From 41f10b742c4c3c21a8783050c6bb55dad17f050d Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 4 Dec 2009 15:34:41 -0500 Subject: remove duplicate log() function from RealtimePlugin --- plugins/Realtime/RealtimePlugin.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index cbfa6bae0..030df405b 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -120,7 +120,7 @@ class RealtimePlugin extends Plugin function onEndShowStatusNetStyles($action) { - $action->cssLink(common_path('plugins/Realtime/realtimeupdate.css'), + $action->cssLink(common_path('plugins/Realtime/realtimeupdate.css'), null, 'screen, projection, tv'); return true; } @@ -293,13 +293,6 @@ class RealtimePlugin extends Plugin return $tags; } - // Push this up to Plugin - - function log($level, $msg) - { - common_log($level, get_class($this) . ': '.$msg); - } - function _getScripts() { return array('plugins/Realtime/realtimeupdate.js', -- cgit v1.2.3-54-g00ecf From eb0a5977ff7e325022d460ae3cf540f3415bd33d Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Fri, 4 Dec 2009 20:39:50 +0000 Subject: Don't try to broadcast the notice if something went wrong. --- plugins/TwitterBridge/daemons/twitterstatusfetcher.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php index d8901f47b..b4ca12be2 100755 --- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php +++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php @@ -213,7 +213,9 @@ class TwitterStatusFetcher extends ParallelizingDaemon $notice = $this->saveStatus($status, $flink); - common_broadcast_notice($notice); + if (!empty($notice)) { + common_broadcast_notice($notice); + } } // Okay, record the time we synced with Twitter for posterity -- cgit v1.2.3-54-g00ecf From 098426cee901d264332c0ad0dd2155d30487d35f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 4 Dec 2009 16:25:05 -0500 Subject: configurable expiry for cached Geonames data defaults to 90 days --- plugins/GeonamesPlugin.php | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'plugins') diff --git a/plugins/GeonamesPlugin.php b/plugins/GeonamesPlugin.php index fdbf79e41..a750f1242 100644 --- a/plugins/GeonamesPlugin.php +++ b/plugins/GeonamesPlugin.php @@ -54,6 +54,7 @@ class GeonamesPlugin extends Plugin public $host = 'ws.geonames.org'; public $username = null; public $token = null; + public $expiry = 7776000; // 90-day expiry /** * convert a name into a Location object @@ -197,6 +198,9 @@ class GeonamesPlugin extends Plugin function onLocationFromLatLon($lat, $lon, $language, &$location) { + $lat = rtrim($lat, "0"); + $lon = rtrim($lon, "0"); + $loc = $this->getCache(array('lat' => $lat, 'lon' => $lon)); @@ -380,7 +384,11 @@ class GeonamesPlugin extends Plugin return null; } - return $c->get($this->cacheKey($attrs)); + $key = $this->cacheKey($attrs); + + $value = $c->get($key); + + return $value; } function setCache($attrs, $loc) @@ -391,18 +399,11 @@ class GeonamesPlugin extends Plugin return null; } - $c->set($this->cacheKey($attrs), $loc); - } - - function clearCache($attrs) - { - $c = common_memcache(); + $key = $this->cacheKey($attrs); - if (empty($c)) { - return null; - } + $result = $c->set($key, $loc, 0, time() + $this->expiry); - $c->delete($this->cacheKey($attrs)); + return $result; } function cacheKey($attrs) -- cgit v1.2.3-54-g00ecf From 4c8bed8ba0558c5834621331f253e05029fa4e43 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 4 Dec 2009 19:41:51 -0500 Subject: Use inlineScript() everywhere inline scripts are written --- lib/messageform.php | 3 +-- lib/noticeform.php | 3 +-- plugins/Facebook/FacebookPlugin.php | 4 +--- plugins/GoogleAnalyticsPlugin.php | 8 ++------ plugins/PiwikAnalyticsPlugin.php | 15 +++++---------- plugins/Realtime/RealtimePlugin.php | 6 +----- plugins/UserFlag/UserFlagPlugin.php | 4 +--- 7 files changed, 12 insertions(+), 31 deletions(-) (limited to 'plugins') diff --git a/lib/messageform.php b/lib/messageform.php index b034be312..4df193c6d 100644 --- a/lib/messageform.php +++ b/lib/messageform.php @@ -154,8 +154,7 @@ class MessageForm extends Form $contentLimit = Message::maxContent(); - $this->out->element('script', array('type' => 'text/javascript'), - 'maxLength = ' . $contentLimit . ';'); + $this->out->inlineScript('maxLength = ' . $contentLimit . ';'); if ($contentLimit > 0) { $this->out->elementStart('dl', 'form_note'); diff --git a/lib/noticeform.php b/lib/noticeform.php index ec8624597..0dd3f2d77 100644 --- a/lib/noticeform.php +++ b/lib/noticeform.php @@ -178,8 +178,7 @@ class NoticeForm extends Form $contentLimit = Notice::maxContent(); - $this->out->element('script', array('type' => 'text/javascript'), - 'maxLength = ' . $contentLimit . ';'); + $this->out->inlineScript('maxLength = ' . $contentLimit . ';'); if ($contentLimit > 0) { $this->out->elementStart('dl', 'form_note'); diff --git a/plugins/Facebook/FacebookPlugin.php b/plugins/Facebook/FacebookPlugin.php index 047477d9c..40c911cce 100644 --- a/plugins/Facebook/FacebookPlugin.php +++ b/plugins/Facebook/FacebookPlugin.php @@ -185,7 +185,6 @@ class FacebookPlugin extends Plugin // XXX: Facebook says we don't need this FB_RequireFeatures(), // but we actually do, for IE and Safari. Gar. - $js = ''; $js = sprintf($js, $apikey, $login_url, $logout_url); @@ -227,7 +225,7 @@ class FacebookPlugin extends Plugin $js = str_replace(' ', '', $js); - $action->raw(" $js"); // leading two spaces to make it line up + $action->inlineScript($js); } } diff --git a/plugins/GoogleAnalyticsPlugin.php b/plugins/GoogleAnalyticsPlugin.php index 7f3d209ee..6891ee6a7 100644 --- a/plugins/GoogleAnalyticsPlugin.php +++ b/plugins/GoogleAnalyticsPlugin.php @@ -67,11 +67,7 @@ class GoogleAnalyticsPlugin extends Plugin 'pageTracker._trackPageview();'. '} catch(err) {}', $this->code); - $action->elementStart('script', array('type' => 'text/javascript')); - $action->raw($js1); - $action->elementEnd('script'); - $action->elementStart('script', array('type' => 'text/javascript')); - $action->raw($js2); - $action->elementEnd('script'); + $action->inlineScript($js1); + $action->inlineScript($js2); } } diff --git a/plugins/PiwikAnalyticsPlugin.php b/plugins/PiwikAnalyticsPlugin.php index 54faa0bdb..fefd09867 100644 --- a/plugins/PiwikAnalyticsPlugin.php +++ b/plugins/PiwikAnalyticsPlugin.php @@ -81,25 +81,20 @@ class PiwikAnalyticsPlugin extends Plugin function onEndShowScripts($action) { - $piwikCode = << - - - - ENDOFPIWIK; - $action->raw($piwikCode); + $action->inlineScript($piwikCode1); + $action->inlineScript($piwikCode2); return true; } } diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index 030df405b..3e33fdaf1 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -105,15 +105,11 @@ class RealtimePlugin extends Plugin $realtimeUI = ' RealtimeUpdate.initActions("'.$url.'", "'.$timeline.'", "'. $pluginPath .'");'; } - $action->elementStart('script', array('type' => 'text/javascript')); - $script = ' $(document).ready(function() { '. $realtimeUI. $this->_updateInitialize($timeline, $user_id). '}); '; - $action->raw($script); - - $action->elementEnd('script'); + $action->inlineScript($script); return true; } diff --git a/plugins/UserFlag/UserFlagPlugin.php b/plugins/UserFlag/UserFlagPlugin.php index e13c2555a..75dcca4fc 100644 --- a/plugins/UserFlag/UserFlagPlugin.php +++ b/plugins/UserFlag/UserFlagPlugin.php @@ -145,9 +145,7 @@ class UserFlagPlugin extends Plugin function onEndShowScripts($action) { - $action->elementStart('script', array('type' => 'text/javascript')); - $action->raw('/* 0) { SN.U.FormXHR($(".form_entity_flag")); } /*]]>*/'); - $action->elementEnd('script'); + $action->inlineScript('if ($(".form_entity_flag").length > 0) { SN.U.FormXHR($(".form_entity_flag")); }'); return true; } } -- cgit v1.2.3-54-g00ecf From d31b1d774e5fcbb424ec60688ff4c76badc2b136 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 4 Dec 2009 20:20:44 -0500 Subject: use the new htmloutputter->style() function --- classes/Design.php | 2 +- plugins/Recaptcha/RecaptchaPlugin.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/classes/Design.php b/classes/Design.php index 89ae50c8c..4e7d7dfb2 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -101,7 +101,7 @@ class Design extends Memcached_DataObject } if (0 != mb_strlen($css)) { - $out->element('style', array('type' => 'text/css'), $css); + $out->style($css); } } diff --git a/plugins/Recaptcha/RecaptchaPlugin.php b/plugins/Recaptcha/RecaptchaPlugin.php index 1a51b16be..3a510ef11 100644 --- a/plugins/Recaptcha/RecaptchaPlugin.php +++ b/plugins/Recaptcha/RecaptchaPlugin.php @@ -69,7 +69,7 @@ class RecaptchaPlugin extends Plugin $action->startXML('html'); - $action->raw(''); + $action->style('#recaptcha_area{float:left;}'); return false; } -- cgit v1.2.3-54-g00ecf From 675e32ac9ac1bdcfbb6e293eb363d2b592140ae7 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 4 Dec 2009 20:21:05 -0500 Subject: use cssLink() instead of element() to write out references to CSS --- plugins/MobileProfile/MobileProfilePlugin.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/MobileProfile/MobileProfilePlugin.php b/plugins/MobileProfile/MobileProfilePlugin.php index 0b1e4de28..8b5e5f31d 100644 --- a/plugins/MobileProfile/MobileProfilePlugin.php +++ b/plugins/MobileProfile/MobileProfilePlugin.php @@ -243,19 +243,13 @@ class MobileProfilePlugin extends WAP20Plugin if (file_exists(Theme::file('css/mp-screen.css'))) { $action->cssLink('css/mp-screen.css', null, 'screen'); } else { - $action->element('link', array('rel' => 'stylesheet', - 'type' => 'text/css', - 'href' => common_path('plugins/MobileProfile/mp-screen.css') . '?version=' . STATUSNET_VERSION, - 'media' => 'screen')); + $action->cssLink('plugins/MobileProfile/mp-screen.css',null,'screen'); } if (file_exists(Theme::file('css/mp-handheld.css'))) { $action->cssLink('css/mp-handheld.css', null, 'handheld'); } else { - $action->element('link', array('rel' => 'stylesheet', - 'type' => 'text/css', - 'href' => common_path('plugins/MobileProfile/mp-handheld.css') . '?version=' . STATUSNET_VERSION, - 'media' => 'handheld')); + $action->cssLink('plugins/MobileProfile/mp-handheld.css',null,'handheld'); } return false; -- cgit v1.2.3-54-g00ecf From d41a0a5ed03b2f4bbf8e8b3984960103383090d1 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 4 Dec 2009 20:33:41 -0500 Subject: Use inlineScript() instead of element() to write inline javascript --- lib/htmloutputter.php | 7 ++----- plugins/MobileProfile/MobileProfilePlugin.php | 3 +-- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'plugins') diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php index a88a5b82c..cf93944e7 100644 --- a/lib/htmloutputter.php +++ b/lib/htmloutputter.php @@ -477,13 +477,10 @@ class HTMLOutputter extends XMLOutputter */ function autofocus($id) { - $this->elementStart('script', array('type' => 'text/javascript')); - $this->raw('/*inlineScript( ' $(document).ready(function() {'. ' var el = $("#' . $id . '");'. ' if (el.length) { el.focus(); }'. - ' });'. - ' /*]]>*/'); - $this->elementEnd('script'); + ' });'); } } diff --git a/plugins/MobileProfile/MobileProfilePlugin.php b/plugins/MobileProfile/MobileProfilePlugin.php index 8b5e5f31d..35678bedd 100644 --- a/plugins/MobileProfile/MobileProfilePlugin.php +++ b/plugins/MobileProfile/MobileProfilePlugin.php @@ -352,8 +352,7 @@ class MobileProfilePlugin extends WAP20Plugin $contentLimit = Notice::maxContent(); - $form->out->element('script', array('type' => 'text/javascript'), - 'maxLength = ' . $contentLimit . ';'); + $form->out->inlineScript('maxLength = ' . $contentLimit . ';'); if ($contentLimit > 0) { $form->out->element('div', array('id' => 'notice_text-count'), -- cgit v1.2.3-54-g00ecf From f4fc8481e24ce4bd7714022109d75b2a22198fdf Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 4 Dec 2009 23:17:19 -0500 Subject: Separate out some common code --- plugins/Minify/minify.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/Minify/minify.php b/plugins/Minify/minify.php index 2de2d6d26..f8c17767c 100644 --- a/plugins/Minify/minify.php +++ b/plugins/Minify/minify.php @@ -33,6 +33,7 @@ class MinifyAction extends Action const cacheKey = 'minify'; var $file; + var $v; function isReadOnly($args) { @@ -80,13 +81,14 @@ class MinifyAction extends Action $c = common_memcache(); if (!empty($c)) { - $out = $c->get(common_cache_key(self::cacheKey . ':' . $this->file)); + $cacheKey = common_cache_key(self::cacheKey . ':' . $this->file . '?v=' . empty($this->v)?'':$this->v); + $out = $c->get($cacheKey); } if(empty($out)) { $out = $this->minify($this->file); } if (!empty($c)) { - $c->set(common_cache_key(self::cacheKey . ':' . $this->file), $out); + $c->set($cacheKey, $out); } $sec = session_cache_expire() * 60; -- cgit v1.2.3-54-g00ecf From 88e50003ae7840358c2a520c6cb808231b958769 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 4 Dec 2009 23:17:46 -0500 Subject: If a theme server is being used, do not minify theme CSS (as doing so could cause 404s) --- plugins/Minify/MinifyPlugin.php | 26 ++++++++++++++++++-------- plugins/Minify/README | 5 +++-- 2 files changed, 21 insertions(+), 10 deletions(-) (limited to 'plugins') diff --git a/plugins/Minify/MinifyPlugin.php b/plugins/Minify/MinifyPlugin.php index 4d37fbc70..77fd76a84 100644 --- a/plugins/Minify/MinifyPlugin.php +++ b/plugins/Minify/MinifyPlugin.php @@ -79,23 +79,33 @@ class MinifyPlugin extends Plugin $url = parse_url($src); if( empty($url->scheme) && empty($url->host) && empty($url->query) && empty($url->fragment)) { - $src = common_path('main/min?f='.$src.'&v=' . STATUSNET_VERSION); + $src = $this->minifyUrl($src); } } function onStartCssLinkElement($action,&$src,&$theme,&$media) { + $allowThemeMinification = + is_null(common_config('theme', 'dir')) + && is_null(common_config('theme', 'path')) + && is_null(common_config('theme', 'server')); $url = parse_url($src); if( empty($url->scheme) && empty($url->host) && empty($url->query) && empty($url->fragment)) { - if(file_exists(Theme::file($src,$theme))){ - //src is a relative path, so we can do minification - if(isset($theme)) { - $src = common_path('main/min?f=theme/'.$theme.'/'.$src.'&v=' . STATUSNET_VERSION); - } else { - $src = common_path('main/min?f=theme/default/'.$src.'&v=' . STATUSNET_VERSION); - } + if(!isset($theme)) { + $theme = common_config('site', 'theme'); + } + if($allowThemeMinification && file_exists(INSTALLDIR.'/local/theme/'.$theme.'/'.$src)) { + $src = $this->minifyUrl('local/theme/'.$theme.'/'.$src); + } else if($allowThemeMinification && file_exists(INSTALLDIR.'/theme/'.$theme.'/'.$src)) { + $src = $this->minifyUrl('theme/'.$theme.'/'.$src); + }else if(file_exists(INSTALLDIR.'/'.$src)){ + $src = $this->minifyUrl($src); } } } + + function minifyUrl($src) { + return common_local_url('minify',null,array('f' => $src ,v => STATUSNET_VERSION)); + } } diff --git a/plugins/Minify/README b/plugins/Minify/README index 7fb7e239a..8f2eefa2c 100644 --- a/plugins/Minify/README +++ b/plugins/Minify/README @@ -1,7 +1,8 @@ The Minify plugin minifies your CSS and Javascript, removing whitespace and comments. -Note that if enabled this plugin and use a theme server - ($config['theme']['server']), your theme server will not be used. +Note that if enabled this plugin and use a theme server, + (if any of $config['theme']['server'], $config['theme']['path'], + $config['theme']['dir'] are set) theme CSS will not be minified. Installation ============ -- cgit v1.2.3-54-g00ecf From c08d7f1aa4ac235f524da3994c2f1aef3b0fd079 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Sat, 5 Dec 2009 00:41:22 -0500 Subject: Minify inline JS and CSS (can be disable in configuration) --- plugins/Minify/MinifyPlugin.php | 57 +++++++++++++++++++++++++++++++++++++++++ plugins/Minify/README | 15 ++++++++++- plugins/Minify/minify.php | 13 +++------- 3 files changed, 74 insertions(+), 11 deletions(-) (limited to 'plugins') diff --git a/plugins/Minify/MinifyPlugin.php b/plugins/Minify/MinifyPlugin.php index 77fd76a84..71fade19a 100644 --- a/plugins/Minify/MinifyPlugin.php +++ b/plugins/Minify/MinifyPlugin.php @@ -33,8 +33,15 @@ Author URI: http://candrews.integralblue.com/ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } +// We bundle the minify library... +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/minify/min/lib'); + class MinifyPlugin extends Plugin { + private $minifyInlineJs = true; + private $minifyInlineCss = true; + + const cacheKey = 'minify'; /** * Add Minification related paths to the router table @@ -104,8 +111,58 @@ class MinifyPlugin extends Plugin } } + function onStartInlineScriptElement($action,&$code,&$type) + { + if($this->minifyInlineJs && $type=='text/javascript'){ + $c = common_memcache(); + if (!empty($c)) { + $cacheKey = common_cache_key(self::cacheKey . ':' . crc32($code)); + $out = $c->get($cacheKey); + } + if(empty($out)) { + $out = $this->minifyJs($code); + } + if (!empty($c)) { + $c->set($cacheKey, $out); + } + if(!empty($out)) { + $code = $out; + } + } + } + + function onStartStyleElement($action,&$code,&$type,&$media) + { + if($this->minifyInlineCss && $type=='text/css'){ + $c = common_memcache(); + if (!empty($c)) { + $cacheKey = common_cache_key(self::cacheKey . ':' . crc32($code)); + $out = $c->get($cacheKey); + } + if(empty($out)) { + $out = $this->minifyCss($code); + } + if (!empty($c)) { + $c->set($cacheKey, $out); + } + if(!empty($out)) { + $code = $out; + } + } + } + function minifyUrl($src) { return common_local_url('minify',null,array('f' => $src ,v => STATUSNET_VERSION)); } + + static function minifyJs($code) { + require_once('JSMin.php'); + return JSMin::minify($code); + } + + static function minifyCss($code, $options = array()) { + require_once('Minify/CSS.php'); + return Minify_CSS::minify($code,$options); + } } diff --git a/plugins/Minify/README b/plugins/Minify/README index 8f2eefa2c..f7763735e 100644 --- a/plugins/Minify/README +++ b/plugins/Minify/README @@ -4,6 +4,10 @@ Note that if enabled this plugin and use a theme server, (if any of $config['theme']['server'], $config['theme']['path'], $config['theme']['dir'] are set) theme CSS will not be minified. +This plugin will use memcache, if it is available, for storing minified inline + and file javascript and css. Because minification is non-trivial, using + memcache is recommended. + Installation ============ add "addPlugin('minify', @@ -12,7 +16,16 @@ to the bottom of your config.php Settings ======== -None at the moment +minifyInlineJs (true): Minify inline javascript. + Because caching isn'tas effective for inline resources (due to its more + dynamic nature) than static files, minifying inline resources may adversely + affect performance for higher volume sites. Testing (and memcache usage) + are highly recommended. +minifyInlineCss (true): Minify inline CSS. + Because caching isn'tas effective for inline resources (due to its more + dynamic nature) than static files, minifying inline resources may adversely + affect performance for higher volume sites. Testing (and memcache usage) + are highly recommended. Example ======= diff --git a/plugins/Minify/minify.php b/plugins/Minify/minify.php index f8c17767c..64727f5e7 100644 --- a/plugins/Minify/minify.php +++ b/plugins/Minify/minify.php @@ -19,9 +19,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -// We bundle the minify library... -set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/minify/min/lib'); - class MinifyAction extends Action { const TYPE_CSS = 'text/css'; @@ -30,8 +27,6 @@ class MinifyAction extends Action // Apache default and what Yahoo! uses.. const TYPE_JS = 'application/x-javascript'; - const cacheKey = 'minify'; - var $file; var $v; @@ -81,7 +76,7 @@ class MinifyAction extends Action $c = common_memcache(); if (!empty($c)) { - $cacheKey = common_cache_key(self::cacheKey . ':' . $this->file . '?v=' . empty($this->v)?'':$this->v); + $cacheKey = common_cache_key(MinifyPlugin::cacheKey . ':' . $this->file . '?v=' . empty($this->v)?'':$this->v); $out = $c->get($cacheKey); } if(empty($out)) { @@ -102,16 +97,14 @@ class MinifyAction extends Action $info = pathinfo($file); switch(strtolower($info['extension'])){ case 'js': - require_once('JSMin.php'); - $out = JSMin::minify(file_get_contents($file)); + $out = MinifyPlugin::minifyJs(file_get_contents($file)); header('Content-Type: ' . self::TYPE_JS); break; case 'css': - require_once('Minify/CSS.php'); $options = array(); $options['currentDir'] = dirname($file); $options['docRoot'] = INSTALLDIR; - $out = Minify_CSS::minify(file_get_contents($file),$options); + $out = MinifyPlugin::minifyCss(file_get_contents($file),$options); header('Content-Type: ' . self::TYPE_CSS); break; default: -- cgit v1.2.3-54-g00ecf From 51f0dd5e37db0e8d2a8690655555d399249942df Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Sat, 5 Dec 2009 01:03:04 -0500 Subject: Add configuration option to toggle the indenting of the output HTML. Defaults to indent enabled. --- actions/twitapisearchatom.php | 2 +- config.php.sample | 5 +++++ lib/action.php | 2 +- lib/default.php | 1 + lib/error.php | 2 +- lib/htmloutputter.php | 2 +- lib/rssaction.php | 2 +- lib/xmloutputter.php | 5 ++++- plugins/Facebook/facebookaction.php | 2 +- plugins/Facebook/facebookutil.php | 2 +- 10 files changed, 17 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/actions/twitapisearchatom.php b/actions/twitapisearchatom.php index 526ca2ae8..1cb8d7efe 100644 --- a/actions/twitapisearchatom.php +++ b/actions/twitapisearchatom.php @@ -71,7 +71,7 @@ class TwitapisearchatomAction extends ApiAction * @see Action::__construct */ - function __construct($output='php://output', $indent=true) + function __construct($output='php://output', $indent=null) { parent::__construct($output, $indent); } diff --git a/config.php.sample b/config.php.sample index 9fccb84f3..473eb74e2 100644 --- a/config.php.sample +++ b/config.php.sample @@ -236,6 +236,11 @@ $config['sphinx']['port'] = 3312; // Use a different hostname for SSL-encrypted pages // $config['site']['sslserver'] = 'secure.example.org'; +// Indent HTML and XML +// Enable (default) for easier to read markup for developers, +// disable to save some bandwidth. +// $config['site']['indent'] = true; + // If you have a lot of status networks on the same server, you can // store the site data in a database and switch as follows // Status_network::setupDB('localhost', 'statusnet', 'statuspass', 'statusnet'); diff --git a/lib/action.php b/lib/action.php index 8ad391755..87d8a4399 100644 --- a/lib/action.php +++ b/lib/action.php @@ -68,7 +68,7 @@ class Action extends HTMLOutputter // lawsuit * @see XMLOutputter::__construct * @see HTMLOutputter::__construct */ - function __construct($output='php://output', $indent=true) + function __construct($output='php://output', $indent=null) { parent::__construct($output, $indent); } diff --git a/lib/default.php b/lib/default.php index d4ef045ea..db90aeca3 100644 --- a/lib/default.php +++ b/lib/default.php @@ -53,6 +53,7 @@ $default = 'shorturllength' => 30, 'dupelimit' => 60, # default for same person saying the same thing 'textlimit' => 140, + 'indent' => true, ), 'db' => array('database' => 'YOU HAVE TO SET THIS IN config.php', diff --git a/lib/error.php b/lib/error.php index 3162cfe65..87a4d913b 100644 --- a/lib/error.php +++ b/lib/error.php @@ -50,7 +50,7 @@ class ErrorAction extends Action var $message = null; var $default = null; - function __construct($message, $code, $output='php://output', $indent=true) + function __construct($message, $code, $output='php://output', $indent=null) { parent::__construct($output, $indent); diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php index fd448ced5..2091c6e2c 100644 --- a/lib/htmloutputter.php +++ b/lib/htmloutputter.php @@ -67,7 +67,7 @@ class HTMLOutputter extends XMLOutputter * @param boolean $indent Whether to indent output, default true */ - function __construct($output='php://output', $indent=true) + function __construct($output='php://output', $indent=null) { parent::__construct($output, $indent); } diff --git a/lib/rssaction.php b/lib/rssaction.php index d591c99ed..62e3f21b6 100644 --- a/lib/rssaction.php +++ b/lib/rssaction.php @@ -52,7 +52,7 @@ class Rss10Action extends Action * @see Action::__construct */ - function __construct($output='php://output', $indent=true) + function __construct($output='php://output', $indent=null) { parent::__construct($output, $indent); } diff --git a/lib/xmloutputter.php b/lib/xmloutputter.php index 5f06e491d..15b18e7d9 100644 --- a/lib/xmloutputter.php +++ b/lib/xmloutputter.php @@ -67,10 +67,13 @@ class XMLOutputter * @param boolean $indent Whether to indent output, default true */ - function __construct($output='php://output', $indent=true) + function __construct($output='php://output', $indent=null) { $this->xw = new XMLWriter(); $this->xw->openURI($output); + if(is_null($indent)) { + $indent = common_config('site', 'indent'); + } $this->xw->setIndent($indent); } diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php index c852bbf5e..b090e9bd9 100644 --- a/plugins/Facebook/facebookaction.php +++ b/plugins/Facebook/facebookaction.php @@ -44,7 +44,7 @@ class FacebookAction extends Action var $app_uri = null; var $app_name = null; - function __construct($output='php://output', $indent=true, $facebook=null, $flink=null) + function __construct($output='php://output', $indent=null, $facebook=null, $flink=null) { parent::__construct($output, $indent); diff --git a/plugins/Facebook/facebookutil.php b/plugins/Facebook/facebookutil.php index 6f50c173a..2abcbb14e 100644 --- a/plugins/Facebook/facebookutil.php +++ b/plugins/Facebook/facebookutil.php @@ -168,7 +168,7 @@ function facebookBroadcastNotice($notice) function updateProfileBox($facebook, $flink, $notice) { $fbaction = new FacebookAction($output = 'php://output', - $indent = true, $facebook, $flink); + $indent = null, $facebook, $flink); $fbaction->updateProfileBox($notice); } -- cgit v1.2.3-54-g00ecf From 9349d823ee744f4f2f7b9f36c00fc605acb728fd Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Sat, 5 Dec 2009 02:13:40 -0500 Subject: Add FirePHP plugin - uses FirePHP as an output method for logging --- plugins/FirePHP/FirePHPPlugin.php | 59 + plugins/FirePHP/README | 21 + plugins/FirePHP/extlib/FirePHP/CHANGELOG | 110 ++ plugins/FirePHP/extlib/FirePHP/CREDITS | 12 + plugins/FirePHP/extlib/FirePHP/README | 32 + .../FirePHP/lib/FirePHPCore/FirePHP.class.php | 1529 ++++++++++++++++++++ .../FirePHP/lib/FirePHPCore/FirePHP.class.php4 | 1292 +++++++++++++++++ .../FirePHP/extlib/FirePHP/lib/FirePHPCore/LICENSE | 29 + .../FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php | 261 ++++ .../FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php4 | 251 ++++ 10 files changed, 3596 insertions(+) create mode 100644 plugins/FirePHP/FirePHPPlugin.php create mode 100644 plugins/FirePHP/README create mode 100644 plugins/FirePHP/extlib/FirePHP/CHANGELOG create mode 100644 plugins/FirePHP/extlib/FirePHP/CREDITS create mode 100644 plugins/FirePHP/extlib/FirePHP/README create mode 100644 plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/FirePHP.class.php create mode 100644 plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/FirePHP.class.php4 create mode 100644 plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/LICENSE create mode 100644 plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php create mode 100644 plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php4 (limited to 'plugins') diff --git a/plugins/FirePHP/FirePHPPlugin.php b/plugins/FirePHP/FirePHPPlugin.php new file mode 100644 index 000000000..37b397796 --- /dev/null +++ b/plugins/FirePHP/FirePHPPlugin.php @@ -0,0 +1,59 @@ + +Author URI: http://candrews.integralblue.com/ +*/ + +/* + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2009, StatusNet, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @package MinifyPlugin + * @maintainer Craig Andrews + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } + +// We bundle the FirePHP library... +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/FirePHP/lib'); + +class FirePHPPlugin extends Plugin +{ + private $firephp; + + function onInitializePlugin() + { + //Output buffering has to be enabled so FirePHP can send the HTTP headers it needs + ob_start(); + require_once('FirePHPCore/FirePHP.class.php'); + $this->firephp = FirePHP::getInstance(true); + } + + function onStartLog(&$priority, &$msg, &$filename) + { + static $firephp_priorities = array(FirePHP::ERROR, FirePHP::ERROR, FirePHP::ERROR, FirePHP::ERROR, + FirePHP::WARN, FirePHP::LOG, FirePHP::LOG, FirePHP::INFO); + $priority = $firephp_priorities[$priority]; + $this->firephp->fb($msg, $priority); + } +} + diff --git a/plugins/FirePHP/README b/plugins/FirePHP/README new file mode 100644 index 000000000..ee22794d5 --- /dev/null +++ b/plugins/FirePHP/README @@ -0,0 +1,21 @@ +The FirePHP writes StatusNet's log output to FirePHP. + +Using FirePHP on production sites can expose sensitive information. + You must protect the security of your application by disabling FirePHP + logging on your live site. + +Installation +============ +add "addPlugin('FirePHP', + array('setting'=>'value', 'setting2'=>'value2', ...);" +to the bottom of your config.php + +Settings +======== +None at the moment. + +Example +======= + +addPlugin('FirePHP', array()); + diff --git a/plugins/FirePHP/extlib/FirePHP/CHANGELOG b/plugins/FirePHP/extlib/FirePHP/CHANGELOG new file mode 100644 index 000000000..619198079 --- /dev/null +++ b/plugins/FirePHP/extlib/FirePHP/CHANGELOG @@ -0,0 +1,110 @@ + +2008-06-14 - Release Version: 0.3.1 + + - (Issue 108) ignore class name case in object filter + +2009-05-11 - Release Version: 0.3 +2009-05-01 - Release Version: 0.3.rc.1 + + - (Issue 90) PHP4 compatible version of FirePHPCore + - (Issue 98) Thrown exceptions don't send an HTTP 500 if the FirePHP exception handler is enabled + - (Issue 85) Support associative arrays in encodeTable method in FirePHP.class.php + - (Issue 66) Add a new getOptions() public method in API + - (Issue 82) Define $this->options outside of __construct + - (Issue 72) Message error if group name is null + - (Issue 68) registerErrorHandler() and registerExceptionHandler() should returns previous handlers defined + - (Issue 69) Add the missing register handler in the triumvirate (error, exception, assert) + - (Issue 75) [Error & Exception Handling] Option to not exit script execution + - (Issue 83) Exception handler can't throw exceptions + - (Issue 80) Auto/Pre collapsing groups AND Custom group row colors + +2008-11-09 - Release Version: 0.2.1 + + - (Issue 70) Problem when logging resources + +2008-10-21 - Release Version: 0.2.0 + + - Updated version to 0.2.0 + - Switched to using __sleep instead of __wakeup + - Added support to exclude object members when encoding + - Add support to enable/disable logging + +2008-10-17 - Release Version: 0.2.b.8 + + - New implementation for is_utf8() + - (Issue 55) maxObjectDepth Option not working correctly when using TABLE and EXCEPTION Type + - Bugfix for max[Object|Array]Depth when encoding nested array/object graphs + - Bugfix for FB::setOptions() + +2008-10-16 - Release Version: 0.2.b.7 + + - (Issue 45) Truncate dump when string have non utf8 cars + - (Issue 52) logging will not work when firephp object gets stored in the session. + +2008-10-16 - Release Version: 0.2.b.6 + + - (Issue 37) Display file and line information for each log message + - (Issue 51) Limit output of object graphs + - Bugfix for encoding object members set to NULL|false|'' + +2008-10-14 - Release Version: 0.2.b.5 + + - Updated JsonStream wildfire protocol to be more robust + - (Issue 33) PHP error notices running demos + - (Issue 48) Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 0 given + +2008-10-08 - Release Version: 0.2.b.4 + + - Bugfix for logging objects with recursion + +2008-10-08 - Release Version: 0.2.b.3 + + - (Issue 43) Notice message in 0.2b2 + - Added support for PHP's native json_encode() if available + - Revised object encoder to detect object recursion + +2008-10-07 - Release Version: 0.2.b.2 + + - (Issue 28) Need solution for logging private and protected object variables + - Added trace() and table() aliases in FirePHP class + - (Issue 41) Use PHP doc in FirePHP + - (Issue 39) Static logging method for object oriented API + +2008-10-01 - Release Version: 0.2.b.1 + + - Added support for error and exception handling + - Updated min PHP version for PEAR package to 5.2 + - Added version constant for library + - Gave server library it's own wildfire plugin namespace + - Migrated communication protocol to Wildfire JsonStream + - Added support for console groups using "group" and "groupEnd" + - Added support for log, info, warn and error logging aliases + - (Issue 29) problem with TRACE when using with error_handler + - (Issue 33) PHP error notices running demos + - (Issue 12) undefined index php notice + - Removed closing ?> php tags + - (Issue 13) the code in the fb() function has a second return statement that will never be reached + +2008-07-30 - Release Version: 0.1.1.3 + + - Include __className property in JSON string if variable was an object + - Bugfix - Mis-spelt "Exception" in JSON encoding code + +2008-06-13 - Release Version: 0.1.1.1 + + - Bugfix - Standardize windows paths in stack traces + - Bugfix - Display correct stack trace info in windows environments + - Bugfix - Check $_SERVER['HTTP_USER_AGENT'] before returning + +2008-06-13 - Release Version: 0.1.1 + + - Added support for FirePHP::TRACE log style + - Changed license to New BSD License + +2008-06-06 - Release Version: 0.0.2 + + - Bugfix - Added usleep() to header writing loop to ensure unique index + - Bugfix - Ensure chunk_split does not generate trailing "\n" with empty data header + - Added support for FirePHP::TABLE log style + + \ No newline at end of file diff --git a/plugins/FirePHP/extlib/FirePHP/CREDITS b/plugins/FirePHP/extlib/FirePHP/CREDITS new file mode 100644 index 000000000..5f0d463d1 --- /dev/null +++ b/plugins/FirePHP/extlib/FirePHP/CREDITS @@ -0,0 +1,12 @@ + _______________________________ + F i r e P H P C o r e + + Current Development + ------------------- + + Christoph Dorn + Michael Day + + If you've done work on FirePHPCore and you are not listed here, + please feel free to add yourself. + diff --git a/plugins/FirePHP/extlib/FirePHP/README b/plugins/FirePHP/extlib/FirePHP/README new file mode 100644 index 000000000..033719fae --- /dev/null +++ b/plugins/FirePHP/extlib/FirePHP/README @@ -0,0 +1,32 @@ + +Version: 0.3.1 + +------------------------------------------------------ + Requirements +------------------------------------------------------ + +Client Side: + + - Firefox - http://www.getfirefox.com/ + - Firebug - http://www.getfirebug.com/ + - FirePHP - http://www.firephp.org/ + +Server Side: + + - PHP 5 (complete functionality) + - PHP 4 (most functionality) + + +------------------------------------------------------ + Install Tutorial +------------------------------------------------------ + + http://www.firephp.org/HQ/Install.htm + + +------------------------------------------------------ + Support +------------------------------------------------------ + + http://forum.firephp.org/ + diff --git a/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/FirePHP.class.php b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/FirePHP.class.php new file mode 100644 index 000000000..d8ae13f34 --- /dev/null +++ b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/FirePHP.class.php @@ -0,0 +1,1529 @@ + + * @license http://www.opensource.org/licenses/bsd-license.php + * @package FirePHP + */ + + +/** + * Sends the given data to the FirePHP Firefox Extension. + * The data can be displayed in the Firebug Console or in the + * "Server" request tab. + * + * For more information see: http://www.firephp.org/ + * + * @copyright Copyright (C) 2007-2009 Christoph Dorn + * @author Christoph Dorn + * @license http://www.opensource.org/licenses/bsd-license.php + * @package FirePHP + */ +class FirePHP { + + /** + * FirePHP version + * + * @var string + */ + const VERSION = '0.3'; + + /** + * Firebug LOG level + * + * Logs a message to firebug console. + * + * @var string + */ + const LOG = 'LOG'; + + /** + * Firebug INFO level + * + * Logs a message to firebug console and displays an info icon before the message. + * + * @var string + */ + const INFO = 'INFO'; + + /** + * Firebug WARN level + * + * Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise. + * + * @var string + */ + const WARN = 'WARN'; + + /** + * Firebug ERROR level + * + * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. + * + * @var string + */ + const ERROR = 'ERROR'; + + /** + * Dumps a variable to firebug's server panel + * + * @var string + */ + const DUMP = 'DUMP'; + + /** + * Displays a stack trace in firebug console + * + * @var string + */ + const TRACE = 'TRACE'; + + /** + * Displays an exception in firebug console + * + * Increments the firebug error count. + * + * @var string + */ + const EXCEPTION = 'EXCEPTION'; + + /** + * Displays an table in firebug console + * + * @var string + */ + const TABLE = 'TABLE'; + + /** + * Starts a group in firebug console + * + * @var string + */ + const GROUP_START = 'GROUP_START'; + + /** + * Ends a group in firebug console + * + * @var string + */ + const GROUP_END = 'GROUP_END'; + + /** + * Singleton instance of FirePHP + * + * @var FirePHP + */ + protected static $instance = null; + + /** + * Flag whether we are logging from within the exception handler + * + * @var boolean + */ + protected $inExceptionHandler = false; + + /** + * Flag whether to throw PHP errors that have been converted to ErrorExceptions + * + * @var boolean + */ + protected $throwErrorExceptions = true; + + /** + * Flag whether to convert PHP assertion errors to Exceptions + * + * @var boolean + */ + protected $convertAssertionErrorsToExceptions = true; + + /** + * Flag whether to throw PHP assertion errors that have been converted to Exceptions + * + * @var boolean + */ + protected $throwAssertionExceptions = false; + + /** + * Wildfire protocol message index + * + * @var int + */ + protected $messageIndex = 1; + + /** + * Options for the library + * + * @var array + */ + protected $options = array('maxObjectDepth' => 10, + 'maxArrayDepth' => 20, + 'useNativeJsonEncode' => true, + 'includeLineNumbers' => true); + + /** + * Filters used to exclude object members when encoding + * + * @var array + */ + protected $objectFilters = array(); + + /** + * A stack of objects used to detect recursion during object encoding + * + * @var object + */ + protected $objectStack = array(); + + /** + * Flag to enable/disable logging + * + * @var boolean + */ + protected $enabled = true; + + /** + * The object constructor + */ + function __construct() { + } + + /** + * When the object gets serialized only include specific object members. + * + * @return array + */ + public function __sleep() { + return array('options','objectFilters','enabled'); + } + + /** + * Gets singleton instance of FirePHP + * + * @param boolean $AutoCreate + * @return FirePHP + */ + public static function getInstance($AutoCreate=false) { + if($AutoCreate===true && !self::$instance) { + self::init(); + } + return self::$instance; + } + + /** + * Creates FirePHP object and stores it for singleton access + * + * @return FirePHP + */ + public static function init() { + return self::$instance = new self(); + } + + /** + * Enable and disable logging to Firebug + * + * @param boolean $Enabled TRUE to enable, FALSE to disable + * @return void + */ + public function setEnabled($Enabled) { + $this->enabled = $Enabled; + } + + /** + * Check if logging is enabled + * + * @return boolean TRUE if enabled + */ + public function getEnabled() { + return $this->enabled; + } + + /** + * Specify a filter to be used when encoding an object + * + * Filters are used to exclude object members. + * + * @param string $Class The class name of the object + * @param array $Filter An array of members to exclude + * @return void + */ + public function setObjectFilter($Class, $Filter) { + $this->objectFilters[strtolower($Class)] = $Filter; + } + + /** + * Set some options for the library + * + * Options: + * - maxObjectDepth: The maximum depth to traverse objects (default: 10) + * - maxArrayDepth: The maximum depth to traverse arrays (default: 20) + * - useNativeJsonEncode: If true will use json_encode() (default: true) + * - includeLineNumbers: If true will include line numbers and filenames (default: true) + * + * @param array $Options The options to be set + * @return void + */ + public function setOptions($Options) { + $this->options = array_merge($this->options,$Options); + } + + /** + * Get options from the library + * + * @return array The currently set options + */ + public function getOptions() { + return $this->options; + } + + /** + * Register FirePHP as your error handler + * + * Will throw exceptions for each php error. + * + * @return mixed Returns a string containing the previously defined error handler (if any) + */ + public function registerErrorHandler($throwErrorExceptions=true) + { + //NOTE: The following errors will not be caught by this error handler: + // E_ERROR, E_PARSE, E_CORE_ERROR, + // E_CORE_WARNING, E_COMPILE_ERROR, + // E_COMPILE_WARNING, E_STRICT + + $this->throwErrorExceptions = $throwErrorExceptions; + + return set_error_handler(array($this,'errorHandler')); + } + + /** + * FirePHP's error handler + * + * Throws exception for each php error that will occur. + * + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param int $errline + * @param array $errcontext + */ + public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) + { + // Don't throw exception if error reporting is switched off + if (error_reporting() == 0) { + return; + } + // Only throw exceptions for errors we are asking for + if (error_reporting() & $errno) { + + $exception = new ErrorException($errstr, 0, $errno, $errfile, $errline); + if($this->throwErrorExceptions) { + throw $exception; + } else { + $this->fb($exception); + } + } + } + + /** + * Register FirePHP as your exception handler + * + * @return mixed Returns the name of the previously defined exception handler, + * or NULL on error. + * If no previous handler was defined, NULL is also returned. + */ + public function registerExceptionHandler() + { + return set_exception_handler(array($this,'exceptionHandler')); + } + + /** + * FirePHP's exception handler + * + * Logs all exceptions to your firebug console and then stops the script. + * + * @param Exception $Exception + * @throws Exception + */ + function exceptionHandler($Exception) { + + $this->inExceptionHandler = true; + + header('HTTP/1.1 500 Internal Server Error'); + + $this->fb($Exception); + + $this->inExceptionHandler = false; + } + + /** + * Register FirePHP driver as your assert callback + * + * @param boolean $convertAssertionErrorsToExceptions + * @param boolean $throwAssertionExceptions + * @return mixed Returns the original setting or FALSE on errors + */ + public function registerAssertionHandler($convertAssertionErrorsToExceptions=true, $throwAssertionExceptions=false) + { + $this->convertAssertionErrorsToExceptions = $convertAssertionErrorsToExceptions; + $this->throwAssertionExceptions = $throwAssertionExceptions; + + if($throwAssertionExceptions && !$convertAssertionErrorsToExceptions) { + throw $this->newException('Cannot throw assertion exceptions as assertion errors are not being converted to exceptions!'); + } + + return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler')); + } + + /** + * FirePHP's assertion handler + * + * Logs all assertions to your firebug console and then stops the script. + * + * @param string $file File source of assertion + * @param int $line Line source of assertion + * @param mixed $code Assertion code + */ + public function assertionHandler($file, $line, $code) + { + + if($this->convertAssertionErrorsToExceptions) { + + $exception = new ErrorException('Assertion Failed - Code[ '.$code.' ]', 0, null, $file, $line); + + if($this->throwAssertionExceptions) { + throw $exception; + } else { + $this->fb($exception); + } + + } else { + + $this->fb($code, 'Assertion Failed', FirePHP::ERROR, array('File'=>$file,'Line'=>$line)); + + } + } + + /** + * Set custom processor url for FirePHP + * + * @param string $URL + */ + public function setProcessorUrl($URL) + { + $this->setHeader('X-FirePHP-ProcessorURL', $URL); + } + + /** + * Set custom renderer url for FirePHP + * + * @param string $URL + */ + public function setRendererUrl($URL) + { + $this->setHeader('X-FirePHP-RendererURL', $URL); + } + + /** + * Start a group for following messages. + * + * Options: + * Collapsed: [true|false] + * Color: [#RRGGBB|ColorName] + * + * @param string $Name + * @param array $Options OPTIONAL Instructions on how to log the group + * @return true + * @throws Exception + */ + public function group($Name, $Options=null) { + + if(!$Name) { + throw $this->newException('You must specify a label for the group!'); + } + + if($Options) { + if(!is_array($Options)) { + throw $this->newException('Options must be defined as an array!'); + } + if(array_key_exists('Collapsed', $Options)) { + $Options['Collapsed'] = ($Options['Collapsed'])?'true':'false'; + } + } + + return $this->fb(null, $Name, FirePHP::GROUP_START, $Options); + } + + /** + * Ends a group you have started before + * + * @return true + * @throws Exception + */ + public function groupEnd() { + return $this->fb(null, null, FirePHP::GROUP_END); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::LOG + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public function log($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP::LOG); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::INFO + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public function info($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP::INFO); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::WARN + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public function warn($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP::WARN); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::ERROR + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public function error($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP::ERROR); + } + + /** + * Dumps key and variable to firebug server panel + * + * @see FirePHP::DUMP + * @param string $Key + * @param mixed $Variable + * @return true + * @throws Exception + */ + public function dump($Key, $Variable) { + return $this->fb($Variable, $Key, FirePHP::DUMP); + } + + /** + * Log a trace in the firebug console + * + * @see FirePHP::TRACE + * @param string $Label + * @return true + * @throws Exception + */ + public function trace($Label) { + return $this->fb($Label, FirePHP::TRACE); + } + + /** + * Log a table in the firebug console + * + * @see FirePHP::TABLE + * @param string $Label + * @param string $Table + * @return true + * @throws Exception + */ + public function table($Label, $Table) { + return $this->fb($Table, $Label, FirePHP::TABLE); + } + + /** + * Check if FirePHP is installed on client + * + * @return boolean + */ + public function detectClientExtension() { + /* Check if FirePHP is installed on client */ + if(!@preg_match_all('/\sFirePHP\/([\.|\d]*)\s?/si',$this->getUserAgent(),$m) || + !version_compare($m[1][0],'0.0.6','>=')) { + return false; + } + return true; + } + + /** + * Log varible to Firebug + * + * @see http://www.firephp.org/Wiki/Reference/Fb + * @param mixed $Object The variable to be logged + * @return true Return TRUE if message was added to headers, FALSE otherwise + * @throws Exception + */ + public function fb($Object) { + + if(!$this->enabled) { + return false; + } + + if (headers_sent($filename, $linenum)) { + // If we are logging from within the exception handler we cannot throw another exception + if($this->inExceptionHandler) { + // Simply echo the error out to the page + echo '
    FirePHP ERROR: Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.
    '; + } else { + throw $this->newException('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); + } + } + + $Type = null; + $Label = null; + $Options = array(); + + if(func_num_args()==1) { + } else + if(func_num_args()==2) { + switch(func_get_arg(1)) { + case self::LOG: + case self::INFO: + case self::WARN: + case self::ERROR: + case self::DUMP: + case self::TRACE: + case self::EXCEPTION: + case self::TABLE: + case self::GROUP_START: + case self::GROUP_END: + $Type = func_get_arg(1); + break; + default: + $Label = func_get_arg(1); + break; + } + } else + if(func_num_args()==3) { + $Type = func_get_arg(2); + $Label = func_get_arg(1); + } else + if(func_num_args()==4) { + $Type = func_get_arg(2); + $Label = func_get_arg(1); + $Options = func_get_arg(3); + } else { + throw $this->newException('Wrong number of arguments to fb() function!'); + } + + + if(!$this->detectClientExtension()) { + return false; + } + + $meta = array(); + $skipFinalObjectEncode = false; + + if($Object instanceof Exception) { + + $meta['file'] = $this->_escapeTraceFile($Object->getFile()); + $meta['line'] = $Object->getLine(); + + $trace = $Object->getTrace(); + if($Object instanceof ErrorException + && isset($trace[0]['function']) + && $trace[0]['function']=='errorHandler' + && isset($trace[0]['class']) + && $trace[0]['class']=='FirePHP') { + + $severity = false; + switch($Object->getSeverity()) { + case E_WARNING: $severity = 'E_WARNING'; break; + case E_NOTICE: $severity = 'E_NOTICE'; break; + case E_USER_ERROR: $severity = 'E_USER_ERROR'; break; + case E_USER_WARNING: $severity = 'E_USER_WARNING'; break; + case E_USER_NOTICE: $severity = 'E_USER_NOTICE'; break; + case E_STRICT: $severity = 'E_STRICT'; break; + case E_RECOVERABLE_ERROR: $severity = 'E_RECOVERABLE_ERROR'; break; + case E_DEPRECATED: $severity = 'E_DEPRECATED'; break; + case E_USER_DEPRECATED: $severity = 'E_USER_DEPRECATED'; break; + } + + $Object = array('Class'=>get_class($Object), + 'Message'=>$severity.': '.$Object->getMessage(), + 'File'=>$this->_escapeTraceFile($Object->getFile()), + 'Line'=>$Object->getLine(), + 'Type'=>'trigger', + 'Trace'=>$this->_escapeTrace(array_splice($trace,2))); + $skipFinalObjectEncode = true; + } else { + $Object = array('Class'=>get_class($Object), + 'Message'=>$Object->getMessage(), + 'File'=>$this->_escapeTraceFile($Object->getFile()), + 'Line'=>$Object->getLine(), + 'Type'=>'throw', + 'Trace'=>$this->_escapeTrace($trace)); + $skipFinalObjectEncode = true; + } + $Type = self::EXCEPTION; + + } else + if($Type==self::TRACE) { + + $trace = debug_backtrace(); + if(!$trace) return false; + for( $i=0 ; $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' + || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { + /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ + } else + if(isset($trace[$i]['class']) + && isset($trace[$i+1]['file']) + && $trace[$i]['class']=='FirePHP' + && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip fb() */ + } else + if($trace[$i]['function']=='fb' + || $trace[$i]['function']=='trace' + || $trace[$i]['function']=='send') { + $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', + 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', + 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', + 'Message'=>$trace[$i]['args'][0], + 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', + 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', + 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', + 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); + + $skipFinalObjectEncode = true; + $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; + $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; + break; + } + } + + } else + if($Type==self::TABLE) { + + if(isset($Object[0]) && is_string($Object[0])) { + $Object[1] = $this->encodeTable($Object[1]); + } else { + $Object = $this->encodeTable($Object); + } + + $skipFinalObjectEncode = true; + + } else + if($Type==self::GROUP_START) { + + if(!$Label) { + throw $this->newException('You must specify a label for the group!'); + } + + } else { + if($Type===null) { + $Type = self::LOG; + } + } + + if($this->options['includeLineNumbers']) { + if(!isset($meta['file']) || !isset($meta['line'])) { + + $trace = debug_backtrace(); + for( $i=0 ; $trace && $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' + || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { + /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ + } else + if(isset($trace[$i]['class']) + && isset($trace[$i+1]['file']) + && $trace[$i]['class']=='FirePHP' + && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip fb() */ + } else + if(isset($trace[$i]['file']) + && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip FB::fb() */ + } else { + $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; + $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; + break; + } + } + + } + } else { + unset($meta['file']); + unset($meta['line']); + } + + $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); + $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.self::VERSION); + + $structure_index = 1; + if($Type==self::DUMP) { + $structure_index = 2; + $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); + } else { + $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); + } + + if($Type==self::DUMP) { + $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; + } else { + $msg_meta = $Options; + $msg_meta['Type'] = $Type; + if($Label!==null) { + $msg_meta['Label'] = $Label; + } + if(isset($meta['file']) && !isset($msg_meta['File'])) { + $msg_meta['File'] = $meta['file']; + } + if(isset($meta['line']) && !isset($msg_meta['Line'])) { + $msg_meta['Line'] = $meta['line']; + } + $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; + } + + $parts = explode("\n",chunk_split($msg, 5000, "\n")); + + for( $i=0 ; $i2) { + // Message needs to be split into multiple parts + $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, + (($i==0)?strlen($msg):'') + . '|' . $part . '|' + . (($isetHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, + strlen($part) . '|' . $part . '|'); + } + + $this->messageIndex++; + + if ($this->messageIndex > 99999) { + throw $this->newException('Maximum number (99,999) of messages reached!'); + } + } + } + + $this->setHeader('X-Wf-1-Index',$this->messageIndex-1); + + return true; + } + + /** + * Standardizes path for windows systems. + * + * @param string $Path + * @return string + */ + protected function _standardizePath($Path) { + return preg_replace('/\\\\+/','/',$Path); + } + + /** + * Escape trace path for windows systems + * + * @param array $Trace + * @return array + */ + protected function _escapeTrace($Trace) { + if(!$Trace) return $Trace; + for( $i=0 ; $i_escapeTraceFile($Trace[$i]['file']); + } + if(isset($Trace[$i]['args'])) { + $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); + } + } + return $Trace; + } + + /** + * Escape file information of trace for windows systems + * + * @param string $File + * @return string + */ + protected function _escapeTraceFile($File) { + /* Check if we have a windows filepath */ + if(strpos($File,'\\')) { + /* First strip down to single \ */ + + $file = preg_replace('/\\\\+/','\\',$File); + + return $file; + } + return $File; + } + + /** + * Send header + * + * @param string $Name + * @param string_type $Value + */ + protected function setHeader($Name, $Value) { + return header($Name.': '.$Value); + } + + /** + * Get user agent + * + * @return string|false + */ + protected function getUserAgent() { + if(!isset($_SERVER['HTTP_USER_AGENT'])) return false; + return $_SERVER['HTTP_USER_AGENT']; + } + + /** + * Returns a new exception + * + * @param string $Message + * @return Exception + */ + protected function newException($Message) { + return new Exception($Message); + } + + /** + * Encode an object into a JSON string + * + * Uses PHP's jeson_encode() if available + * + * @param object $Object The object to be encoded + * @return string The JSON string + */ + public function jsonEncode($Object, $skipObjectEncode=false) + { + if(!$skipObjectEncode) { + $Object = $this->encodeObject($Object); + } + + if(function_exists('json_encode') + && $this->options['useNativeJsonEncode']!=false) { + + return json_encode($Object); + } else { + return $this->json_encode($Object); + } + } + + /** + * Encodes a table by encoding each row and column with encodeObject() + * + * @param array $Table The table to be encoded + * @return array + */ + protected function encodeTable($Table) { + + if(!$Table) return $Table; + + $new_table = array(); + foreach($Table as $row) { + + if(is_array($row)) { + $new_row = array(); + + foreach($row as $item) { + $new_row[] = $this->encodeObject($item); + } + + $new_table[] = $new_row; + } + } + + return $new_table; + } + + /** + * Encodes an object including members with + * protected and private visibility + * + * @param Object $Object The object to be encoded + * @param int $Depth The current traversal depth + * @return array All members of the object + */ + protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1) + { + $return = array(); + + if (is_resource($Object)) { + + return '** '.(string)$Object.' **'; + + } else + if (is_object($Object)) { + + if ($ObjectDepth > $this->options['maxObjectDepth']) { + return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **'; + } + + foreach ($this->objectStack as $refVal) { + if ($refVal === $Object) { + return '** Recursion ('.get_class($Object).') **'; + } + } + array_push($this->objectStack, $Object); + + $return['__className'] = $class = get_class($Object); + $class_lower = strtolower($class); + + $reflectionClass = new ReflectionClass($class); + $properties = array(); + foreach( $reflectionClass->getProperties() as $property) { + $properties[$property->getName()] = $property; + } + + $members = (array)$Object; + + foreach( $properties as $raw_name => $property ) { + + $name = $raw_name; + if($property->isStatic()) { + $name = 'static:'.$name; + } + if($property->isPublic()) { + $name = 'public:'.$name; + } else + if($property->isPrivate()) { + $name = 'private:'.$name; + $raw_name = "\0".$class."\0".$raw_name; + } else + if($property->isProtected()) { + $name = 'protected:'.$name; + $raw_name = "\0".'*'."\0".$raw_name; + } + + if(!(isset($this->objectFilters[$class_lower]) + && is_array($this->objectFilters[$class_lower]) + && in_array($raw_name,$this->objectFilters[$class_lower]))) { + + if(array_key_exists($raw_name,$members) + && !$property->isStatic()) { + + $return[$name] = $this->encodeObject($members[$raw_name], $ObjectDepth + 1, 1); + + } else { + if(method_exists($property,'setAccessible')) { + $property->setAccessible(true); + $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1); + } else + if($property->isPublic()) { + $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1); + } else { + $return[$name] = '** Need PHP 5.3 to get value **'; + } + } + } else { + $return[$name] = '** Excluded by Filter **'; + } + } + + // Include all members that are not defined in the class + // but exist in the object + foreach( $members as $raw_name => $value ) { + + $name = $raw_name; + + if ($name{0} == "\0") { + $parts = explode("\0", $name); + $name = $parts[2]; + } + + if(!isset($properties[$name])) { + $name = 'undeclared:'.$name; + + if(!(isset($this->objectFilters[$class_lower]) + && is_array($this->objectFilters[$class_lower]) + && in_array($raw_name,$this->objectFilters[$class_lower]))) { + + $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1); + } else { + $return[$name] = '** Excluded by Filter **'; + } + } + } + + array_pop($this->objectStack); + + } elseif (is_array($Object)) { + + if ($ArrayDepth > $this->options['maxArrayDepth']) { + return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **'; + } + + foreach ($Object as $key => $val) { + + // Encoding the $GLOBALS PHP array causes an infinite loop + // if the recursion is not reset here as it contains + // a reference to itself. This is the only way I have come up + // with to stop infinite recursion in this case. + if($key=='GLOBALS' + && is_array($val) + && array_key_exists('GLOBALS',$val)) { + $val['GLOBALS'] = '** Recursion (GLOBALS) **'; + } + + $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1); + } + } else { + if(self::is_utf8($Object)) { + return $Object; + } else { + return utf8_encode($Object); + } + } + return $return; + } + + /** + * Returns true if $string is valid UTF-8 and false otherwise. + * + * @param mixed $str String to be tested + * @return boolean + */ + protected static function is_utf8($str) { + $c=0; $b=0; + $bits=0; + $len=strlen($str); + for($i=0; $i<$len; $i++){ + $c=ord($str[$i]); + if($c > 128){ + if(($c >= 254)) return false; + elseif($c >= 252) $bits=6; + elseif($c >= 248) $bits=5; + elseif($c >= 240) $bits=4; + elseif($c >= 224) $bits=3; + elseif($c >= 192) $bits=2; + else return false; + if(($i+$bits) > $len) return false; + while($bits > 1){ + $i++; + $b=ord($str[$i]); + if($b < 128 || $b > 191) return false; + $bits--; + } + } + } + return true; + } + + /** + * Converts to and from JSON format. + * + * JSON (JavaScript Object Notation) is a lightweight data-interchange + * format. It is easy for humans to read and write. It is easy for machines + * to parse and generate. It is based on a subset of the JavaScript + * Programming Language, Standard ECMA-262 3rd Edition - December 1999. + * This feature can also be found in Python. JSON is a text format that is + * completely language independent but uses conventions that are familiar + * to programmers of the C-family of languages, including C, C++, C#, Java, + * JavaScript, Perl, TCL, and many others. These properties make JSON an + * ideal data-interchange language. + * + * This package provides a simple encoder and decoder for JSON notation. It + * is intended for use with client-side Javascript applications that make + * use of HTTPRequest to perform server communication functions - data can + * be encoded into JSON notation for use in a client-side javascript, or + * decoded from incoming Javascript requests. JSON format is native to + * Javascript, and can be directly eval()'ed with no further parsing + * overhead + * + * All strings should be in ASCII or UTF-8 format! + * + * LICENSE: Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: Redistributions of source code must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * @category + * @package Services_JSON + * @author Michal Migurski + * @author Matt Knapp + * @author Brett Stimmerman + * @author Christoph Dorn + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + + + /** + * Keep a list of objects as we descend into the array so we can detect recursion. + */ + private $json_objectStack = array(); + + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + private function json_utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + private function json_encode($var) + { + + if(is_object($var)) { + if(in_array($var,$this->json_objectStack)) { + return '"** Recursion **"'; + } + } + + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + + $this->json_objectStack[] = $var; + + $properties = array_map(array($this, 'json_name_value'), + array_keys($var), + array_values($var)); + + array_pop($this->json_objectStack); + + foreach($properties as $property) { + if($property instanceof Exception) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + $this->json_objectStack[] = $var; + + // treat it like a regular array + $elements = array_map(array($this, 'json_encode'), $var); + + array_pop($this->json_objectStack); + + foreach($elements as $element) { + if($element instanceof Exception) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = self::encodeObject($var); + + $this->json_objectStack[] = $var; + + $properties = array_map(array($this, 'json_name_value'), + array_keys($vars), + array_values($vars)); + + array_pop($this->json_objectStack); + + foreach($properties as $property) { + if($property instanceof Exception) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return null; + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + private function json_name_value($name, $value) + { + // Encoding the $GLOBALS PHP array causes an infinite loop + // if the recursion is not reset here as it contains + // a reference to itself. This is the only way I have come up + // with to stop infinite recursion in this case. + if($name=='GLOBALS' + && is_array($value) + && array_key_exists('GLOBALS',$value)) { + $value['GLOBALS'] = '** Recursion **'; + } + + $encoded_value = $this->json_encode($value); + + if($encoded_value instanceof Exception) { + return $encoded_value; + } + + return $this->json_encode(strval($name)) . ':' . $encoded_value; + } +} diff --git a/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/FirePHP.class.php4 b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/FirePHP.class.php4 new file mode 100644 index 000000000..7cc4bfb04 --- /dev/null +++ b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/FirePHP.class.php4 @@ -0,0 +1,1292 @@ + + * @author Michael Day + * @license http://www.opensource.org/licenses/bsd-license.php + * @package FirePHP + */ + +/** + * FirePHP version + * + * @var string + */ +define('FirePHP_VERSION', '0.3'); + +/** + * Firebug LOG level + * + * Logs a message to firebug console + * + * @var string + */ +define('FirePHP_LOG', 'LOG'); + +/** + * Firebug INFO level + * + * Logs a message to firebug console and displays an info icon before the message + * + * @var string + */ +define('FirePHP_INFO', 'INFO'); + +/** + * Firebug WARN level + * + * Logs a message to firebug console, displays a warning icon before the message and colors the line turquoise + * + * @var string + */ +define('FirePHP_WARN', 'WARN'); + +/** + * Firebug ERROR level + * + * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. + * + * @var string + */ +define('FirePHP_ERROR', 'ERROR'); + +/** + * Dumps a variable to firebug's server panel + * + * @var string + */ +define('FirePHP_DUMP', 'DUMP'); + +/** + * Displays a stack trace in firebug console + * + * @var string + */ +define('FirePHP_TRACE', 'TRACE'); + +/** + * Displays a table in firebug console + * + * @var string + */ +define('FirePHP_TABLE', 'TABLE'); + +/** + * Starts a group in firebug console + * + * @var string + */ +define('FirePHP_GROUP_START', 'GROUP_START'); + +/** + * Ends a group in firebug console + * + * @var string + */ +define('FirePHP_GROUP_END', 'GROUP_END'); + +/** + * Sends the given data to the FirePHP Firefox Extension. + * The data can be displayed in the Firebug Console or in the + * "Server" request tab. + * + * For more information see: http://www.firephp.org/ + * + * @copyright Copyright (C) 2007-2009 Christoph Dorn + * @author Christoph Dorn + * @author Michael Day + * @license http://www.opensource.org/licenses/bsd-license.php + * @package FirePHP + */ +class FirePHP { + /** + * Wildfire protocol message index + * + * @var int + */ + var $messageIndex = 1; + + /** + * Options for the library + * + * @var array + */ + var $options = array('maxObjectDepth' => 10, + 'maxArrayDepth' => 20, + 'useNativeJsonEncode' => true, + 'includeLineNumbers' => true); + + /** + * Filters used to exclude object members when encoding + * + * @var array + */ + var $objectFilters = array(); + + /** + * A stack of objects used to detect recursion during object encoding + * + * @var object + */ + var $objectStack = array(); + + /** + * Flag to enable/disable logging + * + * @var boolean + */ + var $enabled = true; + + /** + * The object constructor + */ + function FirePHP() { + } + + + /** + * When the object gets serialized only include specific object members. + * + * @return array + */ + function __sleep() { + return array('options','objectFilters','enabled'); + } + + /** + * Gets singleton instance of FirePHP + * + * @param boolean $AutoCreate + * @return FirePHP + */ + function &getInstance($AutoCreate=false) { + global $FirePHP_Instance; + + if($AutoCreate===true && !$FirePHP_Instance) { + $FirePHP_Instance = new FirePHP(); + } + + return $FirePHP_Instance; + } + + /** + * Enable and disable logging to Firebug + * + * @param boolean $Enabled TRUE to enable, FALSE to disable + * @return void + */ + function setEnabled($Enabled) { + $this->enabled = $Enabled; + } + + /** + * Check if logging is enabled + * + * @return boolean TRUE if enabled + */ + function getEnabled() { + return $this->enabled; + } + + /** + * Specify a filter to be used when encoding an object + * + * Filters are used to exclude object members. + * + * @param string $Class The class name of the object + * @param array $Filter An array of members to exclude + * @return void + */ + function setObjectFilter($Class, $Filter) { + $this->objectFilters[strtolower($Class)] = $Filter; + } + + /** + * Set some options for the library + * + * Options: + * - maxObjectDepth: The maximum depth to traverse objects (default: 10) + * - maxArrayDepth: The maximum depth to traverse arrays (default: 20) + * - useNativeJsonEncode: If true will use json_encode() (default: true) + * - includeLineNumbers: If true will include line numbers and filenames (default: true) + * + * @param array $Options The options to be set + * @return void + */ + function setOptions($Options) { + $this->options = array_merge($this->options,$Options); + } + + /** + * Get options from the library + * + * @return array The currently set options + */ + function getOptions() { + return $this->options; + } + + /** + * Register FirePHP as your error handler + * + * Will use FirePHP to log each php error. + * + * @return mixed Returns a string containing the previously defined error handler (if any) + */ + function registerErrorHandler() + { + //NOTE: The following errors will not be caught by this error handler: + // E_ERROR, E_PARSE, E_CORE_ERROR, + // E_CORE_WARNING, E_COMPILE_ERROR, + // E_COMPILE_WARNING, E_STRICT + + return set_error_handler(array($this,'errorHandler')); + } + + /** + * FirePHP's error handler + * + * Logs each php error that will occur. + * + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param int $errline + * @param array $errcontext + */ + function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) + { + global $FirePHP_Instance; + // Don't log error if error reporting is switched off + if (error_reporting() == 0) { + return; + } + // Only log error for errors we are asking for + if (error_reporting() & $errno) { + $FirePHP_Instance->group($errstr); + $FirePHP_Instance->error("{$errfile}, line $errline"); + $FirePHP_Instance->groupEnd(); + } + } + + /** + * Register FirePHP driver as your assert callback + * + * @return mixed Returns the original setting + */ + function registerAssertionHandler() + { + return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler')); + } + + /** + * FirePHP's assertion handler + * + * Logs all assertions to your firebug console and then stops the script. + * + * @param string $file File source of assertion + * @param int $line Line source of assertion + * @param mixed $code Assertion code + */ + function assertionHandler($file, $line, $code) + { + $this->fb($code, 'Assertion Failed', FirePHP_ERROR, array('File'=>$file,'Line'=>$line)); + } + + /** + * Set custom processor url for FirePHP + * + * @param string $URL + */ + function setProcessorUrl($URL) + { + $this->setHeader('X-FirePHP-ProcessorURL', $URL); + } + + /** + * Set custom renderer url for FirePHP + * + * @param string $URL + */ + function setRendererUrl($URL) + { + $this->setHeader('X-FirePHP-RendererURL', $URL); + } + + /** + * Start a group for following messages. + * + * Options: + * Collapsed: [true|false] + * Color: [#RRGGBB|ColorName] + * + * @param string $Name + * @param array $Options OPTIONAL Instructions on how to log the group + * @return true + * @throws Exception + */ + function group($Name, $Options=null) { + + if(!$Name) { + trigger_error('You must specify a label for the group!'); + } + + if($Options) { + if(!is_array($Options)) { + trigger_error('Options must be defined as an array!'); + } + if(array_key_exists('Collapsed', $Options)) { + $Options['Collapsed'] = ($Options['Collapsed'])?'true':'false'; + } + } + + return $this->fb(null, $Name, FirePHP_GROUP_START, $Options); + } + + /** + * Ends a group you have started before + * + * @return true + * @throws Exception + */ + function groupEnd() { + return $this->fb(null, null, FirePHP_GROUP_END); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::LOG + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + function log($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP_LOG); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::INFO + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + function info($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP_INFO); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::WARN + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + function warn($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP_WARN); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::ERROR + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + function error($Object, $Label=null) { + return $this->fb($Object, $Label, FirePHP_ERROR); + } + + /** + * Dumps key and variable to firebug server panel + * + * @see FirePHP::DUMP + * @param string $Key + * @param mixed $Variable + * @return true + * @throws Exception + */ + function dump($Key, $Variable) { + return $this->fb($Variable, $Key, FirePHP_DUMP); + } + + /** + * Log a trace in the firebug console + * + * @see FirePHP::TRACE + * @param string $Label + * @return true + * @throws Exception + */ + function trace($Label) { + return $this->fb($Label, FirePHP_TRACE); + } + + /** + * Log a table in the firebug console + * + * @see FirePHP::TABLE + * @param string $Label + * @param string $Table + * @return true + * @throws Exception + */ + function table($Label, $Table) { + return $this->fb($Table, $Label, FirePHP_TABLE); + } + + /** + * Check if FirePHP is installed on client + * + * @return boolean + */ + function detectClientExtension() { + /* Check if FirePHP is installed on client */ + if(!@preg_match_all('/\sFirePHP\/([\.|\d]*)\s?/si',$this->getUserAgent(),$m) || + !version_compare($m[1][0],'0.0.6','>=')) { + return false; + } + return true; + } + + /** + * Log varible to Firebug + * + * @see http://www.firephp.org/Wiki/Reference/Fb + * @param mixed $Object The variable to be logged + * @return true Return TRUE if message was added to headers, FALSE otherwise + * @throws Exception + */ + function fb($Object) { + + if(!$this->enabled) { + return false; + } + + if (headers_sent($filename, $linenum)) { + trigger_error('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); + } + + $Type = null; + $Label = null; + $Options = array(); + + if(func_num_args()==1) { + } else + if(func_num_args()==2) { + switch(func_get_arg(1)) { + case FirePHP_LOG: + case FirePHP_INFO: + case FirePHP_WARN: + case FirePHP_ERROR: + case FirePHP_DUMP: + case FirePHP_TRACE: + case FirePHP_TABLE: + case FirePHP_GROUP_START: + case FirePHP_GROUP_END: + $Type = func_get_arg(1); + break; + default: + $Label = func_get_arg(1); + break; + } + } else + if(func_num_args()==3) { + $Type = func_get_arg(2); + $Label = func_get_arg(1); + } else + if(func_num_args()==4) { + $Type = func_get_arg(2); + $Label = func_get_arg(1); + $Options = func_get_arg(3); + } else { + trigger_error('Wrong number of arguments to fb() function!'); + } + + + if(!$this->detectClientExtension()) { + return false; + } + + $meta = array(); + $skipFinalObjectEncode = false; + + if($Type==FirePHP_TRACE) { + + $trace = debug_backtrace(); + if(!$trace) return false; + for( $i=0 ; $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' + || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { + /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ + } else + if(isset($trace[$i]['class']) + && isset($trace[$i+1]['file']) + && $trace[$i]['class']=='FirePHP' + && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip fb() */ + } else + if($trace[$i]['function']=='fb' + || $trace[$i]['function']=='trace' + || $trace[$i]['function']=='send') { + $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', + 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', + 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', + 'Message'=>$trace[$i]['args'][0], + 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', + 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', + 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', + 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); + + $skipFinalObjectEncode = true; + $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; + $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; + break; + } + } + + } else + if($Type==FirePHP_TABLE) { + + if(isset($Object[0]) && is_string($Object[0])) { + $Object[1] = $this->encodeTable($Object[1]); + } else { + $Object = $this->encodeTable($Object); + } + + $skipFinalObjectEncode = true; + + } else + if($Type==FirePHP_GROUP_START) { + + if(!$Label) { + trigger_error('You must specify a label for the group!'); + } + } else { + if($Type===null) { + $Type = FirePHP_LOG; + } + } + + if($this->options['includeLineNumbers']) { + if(!isset($meta['file']) || !isset($meta['line'])) { + + $trace = debug_backtrace(); + for( $i=0 ; $trace && $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' + || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { + /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ + } else + if(isset($trace[$i]['class']) + && isset($trace[$i+1]['file']) + && $trace[$i]['class']=='FirePHP' + && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip fb() */ + } else + if(isset($trace[$i]['file']) + && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { + /* Skip FB::fb() */ + } else { + $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; + $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; + break; + } + } + + } + } else { + unset($meta['file']); + unset($meta['line']); + } + + $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); + $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.FirePHP_VERSION); + + $structure_index = 1; + if($Type==FirePHP_DUMP) { + $structure_index = 2; + $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); + } else { + $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); + } + + if($Type==FirePHP_DUMP) { + $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; + } else { + $msg_meta = $Options; + $msg_meta['Type'] = $Type; + if($Label!==null) { + $msg_meta['Label'] = $Label; + } + if(isset($meta['file']) && !isset($msg_meta['File'])) { + $msg_meta['File'] = $meta['file']; + } + if(isset($meta['line']) && !isset($msg_meta['Line'])) { + $msg_meta['Line'] = $meta['line']; + } + $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; + } + + $parts = explode("\n",chunk_split($msg, 5000, "\n")); + + for( $i=0 ; $i2) { + // Message needs to be split into multiple parts + $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, + (($i==0)?strlen($msg):'') + . '|' . $part . '|' + . (($isetHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, + strlen($part) . '|' . $part . '|'); + } + + $this->messageIndex++; + + if ($this->messageIndex > 99999) { + trigger_error('Maximum number (99,999) of messages reached!'); + } + } + } + + $this->setHeader('X-Wf-1-Index',$this->messageIndex-1); + + return true; + } + + + /** + * Standardizes path for windows systems. + * + * @param string $Path + * @return string + */ + function _standardizePath($Path) { + return preg_replace('/\\\\+/','/',$Path); + } + + /** + * Escape trace path for windows systems + * + * @param array $Trace + * @return array + */ + function _escapeTrace($Trace) { + if(!$Trace) return $Trace; + for( $i=0 ; $i_escapeTraceFile($Trace[$i]['file']); + } + if(isset($Trace[$i]['args'])) { + $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); + } + } + return $Trace; + } + + /** + * Escape file information of trace for windows systems + * + * @param string $File + * @return string + */ + function _escapeTraceFile($File) { + /* Check if we have a windows filepath */ + if(strpos($File,'\\')) { + /* First strip down to single \ */ + + $file = preg_replace('/\\\\+/','\\',$File); + + return $file; + } + return $File; + } + + /** + * Send header + * + * @param string $Name + * @param string_type $Value + */ + function setHeader($Name, $Value) { + return header($Name.': '.$Value); + } + + /** + * Get user agent + * + * @return string|false + */ + function getUserAgent() { + if(!isset($_SERVER['HTTP_USER_AGENT'])) return false; + return $_SERVER['HTTP_USER_AGENT']; + } + + /** + * Encode an object into a JSON string + * + * Uses PHP's jeson_encode() if available + * + * @param object $Object The object to be encoded + * @return string The JSON string + */ + function jsonEncode($Object, $skipObjectEncode=false) + { + if(!$skipObjectEncode) { + $Object = $this->encodeObject($Object); + } + + if(function_exists('json_encode') + && $this->options['useNativeJsonEncode']!=false) { + + return json_encode($Object); + } else { + return $this->json_encode($Object); + } + } + + /** + * Encodes a table by encoding each row and column with encodeObject() + * + * @param array $Table The table to be encoded + * @return array + */ + function encodeTable($Table) { + + if(!$Table) return $Table; + + $new_table = array(); + foreach($Table as $row) { + + if(is_array($row)) { + $new_row = array(); + + foreach($row as $item) { + $new_row[] = $this->encodeObject($item); + } + + $new_table[] = $new_row; + } + } + + return $new_table; + } + + /** + * Encodes an object + * + * @param Object $Object The object to be encoded + * @param int $Depth The current traversal depth + * @return array All members of the object + */ + function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1) + { + $return = array(); + + if (is_resource($Object)) { + + return '** '.(string)$Object.' **'; + + } else + if (is_object($Object)) { + + if ($ObjectDepth > $this->options['maxObjectDepth']) { + return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **'; + } + + foreach ($this->objectStack as $refVal) { + if ($refVal === $Object) { + return '** Recursion ('.get_class($Object).') **'; + } + } + array_push($this->objectStack, $Object); + + $return['__className'] = $class = get_class($Object); + $class_lower = strtolower($class); + + $members = (array)$Object; + + // Include all members that are not defined in the class + // but exist in the object + foreach( $members as $raw_name => $value ) { + + $name = $raw_name; + + if ($name{0} == "\0") { + $parts = explode("\0", $name); + $name = $parts[2]; + } + + if(!isset($properties[$name])) { + $name = 'undeclared:'.$name; + + if(!(isset($this->objectFilters[$class_lower]) + && is_array($this->objectFilters[$class_lower]) + && in_array($raw_name,$this->objectFilters[$class_lower]))) { + + $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1); + } else { + $return[$name] = '** Excluded by Filter **'; + } + } + } + + array_pop($this->objectStack); + + } elseif (is_array($Object)) { + + if ($ArrayDepth > $this->options['maxArrayDepth']) { + return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **'; + } + + foreach ($Object as $key => $val) { + + // Encoding the $GLOBALS PHP array causes an infinite loop + // if the recursion is not reset here as it contains + // a reference to itself. This is the only way I have come up + // with to stop infinite recursion in this case. + if($key=='GLOBALS' + && is_array($val) + && array_key_exists('GLOBALS',$val)) { + $val['GLOBALS'] = '** Recursion (GLOBALS) **'; + } + + $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1); + } + } else { + if($this->is_utf8($Object)) { + return $Object; + } else { + return utf8_encode($Object); + } + } + return $return; + + } + + /** + * Returns true if $string is valid UTF-8 and false otherwise. + * + * @param mixed $str String to be tested + * @return boolean + */ + function is_utf8($str) { + $c=0; $b=0; + $bits=0; + $len=strlen($str); + for($i=0; $i<$len; $i++){ + $c=ord($str[$i]); + if($c > 128){ + if(($c >= 254)) return false; + elseif($c >= 252) $bits=6; + elseif($c >= 248) $bits=5; + elseif($c >= 240) $bits=4; + elseif($c >= 224) $bits=3; + elseif($c >= 192) $bits=2; + else return false; + if(($i+$bits) > $len) return false; + while($bits > 1){ + $i++; + $b=ord($str[$i]); + if($b < 128 || $b > 191) return false; + $bits--; + } + } + } + return true; + } + + /** + * Converts to and from JSON format. + * + * JSON (JavaScript Object Notation) is a lightweight data-interchange + * format. It is easy for humans to read and write. It is easy for machines + * to parse and generate. It is based on a subset of the JavaScript + * Programming Language, Standard ECMA-262 3rd Edition - December 1999. + * This feature can also be found in Python. JSON is a text format that is + * completely language independent but uses conventions that are familiar + * to programmers of the C-family of languages, including C, C++, C#, Java, + * JavaScript, Perl, TCL, and many others. These properties make JSON an + * ideal data-interchange language. + * + * This package provides a simple encoder and decoder for JSON notation. It + * is intended for use with client-side Javascript applications that make + * use of HTTPRequest to perform server communication functions - data can + * be encoded into JSON notation for use in a client-side javascript, or + * decoded from incoming Javascript requests. JSON format is native to + * Javascript, and can be directly eval()'ed with no further parsing + * overhead + * + * All strings should be in ASCII or UTF-8 format! + * + * LICENSE: Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: Redistributions of source code must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * @category + * @package Services_JSON + * @author Michal Migurski + * @author Matt Knapp + * @author Brett Stimmerman + * @author Christoph Dorn + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + + + /** + * Keep a list of objects as we descend into the array so we can detect recursion. + */ + var $json_objectStack = array(); + + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function json_utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function json_encode($var) + { + + if(is_object($var)) { + if(in_array($var,$this->json_objectStack)) { + return '"** Recursion **"'; + } + } + + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->json_utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + + $this->json_objectStack[] = $var; + + $properties = array_map(array($this, 'json_name_value'), + array_keys($var), + array_values($var)); + + array_pop($this->json_objectStack); + + return '{' . join(',', $properties) . '}'; + } + + $this->json_objectStack[] = $var; + + // treat it like a regular array + $elements = array_map(array($this, 'json_encode'), $var); + + array_pop($this->json_objectStack); + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = FirePHP::encodeObject($var); + + $this->json_objectStack[] = $var; + + $properties = array_map(array($this, 'json_name_value'), + array_keys($vars), + array_values($vars)); + + array_pop($this->json_objectStack); + + return '{' . join(',', $properties) . '}'; + + default: + return null; + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function json_name_value($name, $value) + { + // Encoding the $GLOBALS PHP array causes an infinite loop + // if the recursion is not reset here as it contains + // a reference to itself. This is the only way I have come up + // with to stop infinite recursion in this case. + if($name=='GLOBALS' + && is_array($value) + && array_key_exists('GLOBALS',$value)) { + $value['GLOBALS'] = '** Recursion **'; + } + + $encoded_value = $this->json_encode($value); + + return $this->json_encode(strval($name)) . ':' . $encoded_value; + } +} + diff --git a/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/LICENSE b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/LICENSE new file mode 100644 index 000000000..3e390f9d9 --- /dev/null +++ b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/LICENSE @@ -0,0 +1,29 @@ +Software License Agreement (New BSD License) + +Copyright (c) 2006-2009, Christoph Dorn +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Christoph Dorn nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php new file mode 100644 index 000000000..9d1857cbc --- /dev/null +++ b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php @@ -0,0 +1,261 @@ + + * @license http://www.opensource.org/licenses/bsd-license.php + * @package FirePHP + */ + +require_once dirname(__FILE__).'/FirePHP.class.php'; + +/** + * Sends the given data to the FirePHP Firefox Extension. + * The data can be displayed in the Firebug Console or in the + * "Server" request tab. + * + * @see http://www.firephp.org/Wiki/Reference/Fb + * @param mixed $Object + * @return true + * @throws Exception + */ +function fb() +{ + $instance = FirePHP::getInstance(true); + + $args = func_get_args(); + return call_user_func_array(array($instance,'fb'),$args); +} + + +class FB +{ + /** + * Enable and disable logging to Firebug + * + * @see FirePHP->setEnabled() + * @param boolean $Enabled TRUE to enable, FALSE to disable + * @return void + */ + public static function setEnabled($Enabled) { + $instance = FirePHP::getInstance(true); + $instance->setEnabled($Enabled); + } + + /** + * Check if logging is enabled + * + * @see FirePHP->getEnabled() + * @return boolean TRUE if enabled + */ + public static function getEnabled() { + $instance = FirePHP::getInstance(true); + return $instance->getEnabled(); + } + + /** + * Specify a filter to be used when encoding an object + * + * Filters are used to exclude object members. + * + * @see FirePHP->setObjectFilter() + * @param string $Class The class name of the object + * @param array $Filter An array or members to exclude + * @return void + */ + public static function setObjectFilter($Class, $Filter) { + $instance = FirePHP::getInstance(true); + $instance->setObjectFilter($Class, $Filter); + } + + /** + * Set some options for the library + * + * @see FirePHP->setOptions() + * @param array $Options The options to be set + * @return void + */ + public static function setOptions($Options) { + $instance = FirePHP::getInstance(true); + $instance->setOptions($Options); + } + + /** + * Get options for the library + * + * @see FirePHP->getOptions() + * @return array The options + */ + public static function getOptions() { + $instance = FirePHP::getInstance(true); + return $instance->getOptions(); + } + + /** + * Log object to firebug + * + * @see http://www.firephp.org/Wiki/Reference/Fb + * @param mixed $Object + * @return true + * @throws Exception + */ + public static function send() + { + $instance = FirePHP::getInstance(true); + $args = func_get_args(); + return call_user_func_array(array($instance,'fb'),$args); + } + + /** + * Start a group for following messages + * + * Options: + * Collapsed: [true|false] + * Color: [#RRGGBB|ColorName] + * + * @param string $Name + * @param array $Options OPTIONAL Instructions on how to log the group + * @return true + */ + public static function group($Name, $Options=null) { + $instance = FirePHP::getInstance(true); + return $instance->group($Name, $Options); + } + + /** + * Ends a group you have started before + * + * @return true + * @throws Exception + */ + public static function groupEnd() { + return self::send(null, null, FirePHP::GROUP_END); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::LOG + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public static function log($Object, $Label=null) { + return self::send($Object, $Label, FirePHP::LOG); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::INFO + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public static function info($Object, $Label=null) { + return self::send($Object, $Label, FirePHP::INFO); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::WARN + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public static function warn($Object, $Label=null) { + return self::send($Object, $Label, FirePHP::WARN); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::ERROR + * @param mixes $Object + * @param string $Label + * @return true + * @throws Exception + */ + public static function error($Object, $Label=null) { + return self::send($Object, $Label, FirePHP::ERROR); + } + + /** + * Dumps key and variable to firebug server panel + * + * @see FirePHP::DUMP + * @param string $Key + * @param mixed $Variable + * @return true + * @throws Exception + */ + public static function dump($Key, $Variable) { + return self::send($Variable, $Key, FirePHP::DUMP); + } + + /** + * Log a trace in the firebug console + * + * @see FirePHP::TRACE + * @param string $Label + * @return true + * @throws Exception + */ + public static function trace($Label) { + return self::send($Label, FirePHP::TRACE); + } + + /** + * Log a table in the firebug console + * + * @see FirePHP::TABLE + * @param string $Label + * @param string $Table + * @return true + * @throws Exception + */ + public static function table($Label, $Table) { + return self::send($Table, $Label, FirePHP::TABLE); + } + +} + diff --git a/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php4 b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php4 new file mode 100644 index 000000000..5b69e3487 --- /dev/null +++ b/plugins/FirePHP/extlib/FirePHP/lib/FirePHPCore/fb.php4 @@ -0,0 +1,251 @@ + + * @author Michael Day + * @license http://www.opensource.org/licenses/bsd-license.php + * @package FirePHP + */ + +require_once dirname(__FILE__).'/FirePHP.class.php4'; + +/** + * Sends the given data to the FirePHP Firefox Extension. + * The data can be displayed in the Firebug Console or in the + * "Server" request tab. + * + * @see http://www.firephp.org/Wiki/Reference/Fb + * @param mixed $Object + * @return true + * @throws Exception + */ +function fb() +{ + $instance =& FirePHP::getInstance(true); + + $args = func_get_args(); + return call_user_func_array(array(&$instance,'fb'),$args); +} + + +class FB +{ + /** + * Enable and disable logging to Firebug + * + * @see FirePHP->setEnabled() + * @param boolean $Enabled TRUE to enable, FALSE to disable + * @return void + */ + function setEnabled($Enabled) { + $instance =& FirePHP::getInstance(true); + $instance->setEnabled($Enabled); + } + + /** + * Check if logging is enabled + * + * @see FirePHP->getEnabled() + * @return boolean TRUE if enabled + */ + function getEnabled() { + $instance =& FirePHP::getInstance(true); + return $instance->getEnabled(); + } + + /** + * Specify a filter to be used when encoding an object + * + * Filters are used to exclude object members. + * + * @see FirePHP->setObjectFilter() + * @param string $Class The class name of the object + * @param array $Filter An array or members to exclude + * @return void + */ + function setObjectFilter($Class, $Filter) { + $instance =& FirePHP::getInstance(true); + $instance->setObjectFilter($Class, $Filter); + } + + /** + * Set some options for the library + * + * @see FirePHP->setOptions() + * @param array $Options The options to be set + * @return void + */ + function setOptions($Options) { + $instance =& FirePHP::getInstance(true); + $instance->setOptions($Options); + } + + /** + * Get options for the library + * + * @see FirePHP->getOptions() + * @return array The options + */ + function getOptions() { + $instance =& FirePHP::getInstance(true); + return $instance->getOptions(); + } + + /** + * Log object to firebug + * + * @see http://www.firephp.org/Wiki/Reference/Fb + * @param mixed $Object + * @return true + */ + function send() + { + $instance =& FirePHP::getInstance(true); + $args = func_get_args(); + return call_user_func_array(array(&$instance,'fb'),$args); + } + + /** + * Start a group for following messages + * + * Options: + * Collapsed: [true|false] + * Color: [#RRGGBB|ColorName] + * + * @param string $Name + * @param array $Options OPTIONAL Instructions on how to log the group + * @return true + */ + function group($Name, $Options=null) { + $instance =& FirePHP::getInstance(true); + return $instance->group($Name, $Options); + } + + /** + * Ends a group you have started before + * + * @return true + */ + function groupEnd() { + return FB::send(null, null, FirePHP_GROUP_END); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::LOG + * @param mixes $Object + * @param string $Label + * @return true + */ + function log($Object, $Label=null) { + return FB::send($Object, $Label, FirePHP_LOG); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::INFO + * @param mixes $Object + * @param string $Label + * @return true + */ + function info($Object, $Label=null) { + return FB::send($Object, $Label, FirePHP_INFO); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::WARN + * @param mixes $Object + * @param string $Label + * @return true + */ + function warn($Object, $Label=null) { + return FB::send($Object, $Label, FirePHP_WARN); + } + + /** + * Log object with label to firebug console + * + * @see FirePHP::ERROR + * @param mixes $Object + * @param string $Label + * @return true + */ + function error($Object, $Label=null) { + return FB::send($Object, $Label, FirePHP_ERROR); + } + + /** + * Dumps key and variable to firebug server panel + * + * @see FirePHP::DUMP + * @param string $Key + * @param mixed $Variable + * @return true + */ + function dump($Key, $Variable) { + return FB::send($Variable, $Key, FirePHP_DUMP); + } + + /** + * Log a trace in the firebug console + * + * @see FirePHP::TRACE + * @param string $Label + * @return true + */ + function trace($Label) { + return FB::send($Label, FirePHP_TRACE); + } + + /** + * Log a table in the firebug console + * + * @see FirePHP::TABLE + * @param string $Label + * @param string $Table + * @return true + */ + function table($Label, $Table) { + return FB::send($Table, $Label, FirePHP_TABLE); + } +} -- cgit v1.2.3-54-g00ecf From a555963f979a26e1276e28b56f2cab048155d7fd Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Sat, 5 Dec 2009 23:12:56 +0000 Subject: Preliminary UI for Play/Pause behaviour on hover state for notices --- plugins/Realtime/realtimeupdate.js | 57 ++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 21 deletions(-) (limited to 'plugins') diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index ce0297339..a760158b0 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -191,13 +191,13 @@ RealtimeUpdate = { initActions: function(url, timeline, path) { - var NP = $('#notices_primary'); - NP.prepend('
    '); + $('#notices_primary').prepend('
    '); RealtimeUpdate._pluginPath = path; RealtimeUpdate.initPlayPause(); RealtimeUpdate.initAddPopup(url, timeline, RealtimeUpdate._pluginPath); + RealtimeUpdate.addNoticesHover(); }, initPlayPause: function() @@ -207,14 +207,14 @@ RealtimeUpdate = { showPause: function() { - RT_PP = $('#realtime_playpause'); - RT_PP.empty(); - RT_PP.append(''); + RealtimeUpdate._paused = false; + RealtimeUpdate.showQueuedNotices(); - RT_P = $('#realtime_pause'); - RT_P.bind('click', function() { - RealtimeUpdate._paused = true; + $('#realtime_playpause').remove(); + $('#realtime_actions').prepend('
  • '); + $('#realtime_pause').bind('click', function() { + RealtimeUpdate.removeNoticesHover(); RealtimeUpdate.showPlay(); return false; }); @@ -222,18 +222,14 @@ RealtimeUpdate = { showPlay: function() { - RT_PP = $('#realtime_playpause'); - RT_PP.empty(); - RT_PP.append(' '); + RealtimeUpdate._paused = true; - RT_P = $('#realtime_play'); - RT_P.bind('click', function() { - RealtimeUpdate._paused = false; + $('#realtime_playpause').remove(); + $('#realtime_actions').prepend('
  • '); + $('#realtime_play').bind('click', function() { + RealtimeUpdate.addNoticesHover(); RealtimeUpdate.showPause(); - - RealtimeUpdate.showQueuedNotices(); - return false; }); }, @@ -259,13 +255,32 @@ RealtimeUpdate = { $('#realtime_playpause #queued_counter').empty(); }, + addNoticesHover: function() + { + $('#notices_primary .notices').hover( + function() { + if (RealtimeUpdate._paused === false) { + RealtimeUpdate.showPlay(); + } + }, + function() { + if (RealtimeUpdate._paused === true) { + RealtimeUpdate.showPause(); + } + } + ); + }, + + removeNoticesHover: function() + { + $('#notices_primary .notices').unbind('hover'); + }, + initAddPopup: function(url, timeline, path) { - var NP = $('#realtime_timeline'); - NP.append(''); + $('#realtime_timeline').append(''); - var PP = $('#realtime_popup'); - PP.bind('click', function() { + $('#realtime_popup').bind('click', function() { window.open(url, '', 'toolbar=no,resizable=yes,scrollbars=yes,status=no,menubar=no,personalbar=no,location=no,width=500,height=550'); -- cgit v1.2.3-54-g00ecf From 49005881bd31a022e59574277866aada41e4b76d Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Sun, 6 Dec 2009 22:07:49 +0000 Subject: Minor fix for play/pause mouseleave --- plugins/Realtime/realtimeupdate.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index a760158b0..577499bf7 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -197,7 +197,6 @@ RealtimeUpdate = { RealtimeUpdate.initPlayPause(); RealtimeUpdate.initAddPopup(url, timeline, RealtimeUpdate._pluginPath); - RealtimeUpdate.addNoticesHover(); }, initPlayPause: function() @@ -209,6 +208,7 @@ RealtimeUpdate = { { RealtimeUpdate._paused = false; RealtimeUpdate.showQueuedNotices(); + RealtimeUpdate.addNoticesHover(); $('#realtime_playpause').remove(); $('#realtime_actions').prepend('
  • '); @@ -228,7 +228,6 @@ RealtimeUpdate = { $('#realtime_actions').prepend('
  • '); $('#realtime_play').bind('click', function() { - RealtimeUpdate.addNoticesHover(); RealtimeUpdate.showPause(); return false; }); @@ -273,7 +272,7 @@ RealtimeUpdate = { removeNoticesHover: function() { - $('#notices_primary .notices').unbind('hover'); + $('#notices_primary .notices').unbind(); }, initAddPopup: function(url, timeline, path) -- cgit v1.2.3-54-g00ecf From 189296c5a0130c151bed5e96367bcf33e7ac1b2f Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Mon, 7 Dec 2009 11:44:43 +0000 Subject: Using localStorage to keep the play/pause state of RealtimeUpdate --- plugins/Realtime/realtimeupdate.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 577499bf7..13b723589 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -201,12 +201,19 @@ RealtimeUpdate = { initPlayPause: function() { - RealtimeUpdate.showPause(); + if (typeof(localStorage) != 'undefined') { + if (localStorage.getItem('RealtimeUpdate_paused') === 'true') { + RealtimeUpdate.showPlay(); + } + else { + RealtimeUpdate.showPause(); + } + } }, showPause: function() { - RealtimeUpdate._paused = false; + RealtimeUpdate.setPause(false); RealtimeUpdate.showQueuedNotices(); RealtimeUpdate.addNoticesHover(); @@ -222,8 +229,7 @@ RealtimeUpdate = { showPlay: function() { - RealtimeUpdate._paused = true; - + RealtimeUpdate.setPause(true); $('#realtime_playpause').remove(); $('#realtime_actions').prepend('
  • '); @@ -233,6 +239,14 @@ RealtimeUpdate = { }); }, + setPause: function(state) + { + RealtimeUpdate._paused = state; + if (typeof(localStorage) != 'undefined') { + localStorage.setItem('RealtimeUpdate_paused', RealtimeUpdate._paused); + } + }, + showQueuedNotices: function() { $.each(RealtimeUpdate._queuedNotices, function(i, n) { -- cgit v1.2.3-54-g00ecf From 11dab47e2d91c7f88819a1576609d7ef7f63ee64 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Mon, 7 Dec 2009 12:12:32 +0000 Subject: If localStorage is not supported, showPause as usual --- plugins/Realtime/realtimeupdate.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 13b723589..56a52433f 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -201,7 +201,10 @@ RealtimeUpdate = { initPlayPause: function() { - if (typeof(localStorage) != 'undefined') { + if (typeof(localStorage) == 'undefined') { + RealtimeUpdate.showPause(); + } + else { if (localStorage.getItem('RealtimeUpdate_paused') === 'true') { RealtimeUpdate.showPlay(); } -- cgit v1.2.3-54-g00ecf From 0c955b7c88b41fa28d079eb639abb748583ab4eb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 7 Dec 2009 12:13:42 -0500 Subject: remove unit tests for minify --- .../min_unit_tests/HTTP_ConditionalGet/2.php | 44 - .../min_unit_tests/HTTP_ConditionalGet/3.php | 40 - .../min_unit_tests/HTTP_ConditionalGet/4.php | 49 - .../min_unit_tests/HTTP_ConditionalGet/5.php | 27 - .../HTTP_ConditionalGet/_include.php | 64 - .../min_unit_tests/HTTP_ConditionalGet/index.php | 36 - .../minify/min_unit_tests/HTTP_Encoder/green.png | Bin 202 -> 0 bytes .../minify/min_unit_tests/HTTP_Encoder/index.php | 60 - .../Minify/extlib/minify/min_unit_tests/_inc.php | 50 - .../min_unit_tests/_test_files/css/comments.css | 9 - .../_test_files/css/comments.min.css | 3 - .../min_unit_tests/_test_files/css/hacks.css | 66 - .../min_unit_tests/_test_files/css/hacks.min.css | 4 - .../min_unit_tests/_test_files/css/issue62.css | 890 ----- .../min_unit_tests/_test_files/css/issue62.min.css | 25 - .../_test_files/css/paths_prepend.css | 12 - .../_test_files/css/paths_prepend.min.css | 1 - .../_test_files/css/paths_rewrite.css | 14 - .../_test_files/css/paths_rewrite.min.css | 1 - .../min_unit_tests/_test_files/css/readme.txt | 1 - .../min_unit_tests/_test_files/css/selectors.css | 42 - .../_test_files/css/selectors.min.css | 37 - .../min_unit_tests/_test_files/css/styles.css | 31 - .../min_unit_tests/_test_files/css/styles.min.css | 3 - .../min_unit_tests/_test_files/css/subsilver.css | 434 --- .../_test_files/css/subsilver.min.css | 18 - .../_test_files/css/unusual_strings.css | 10 - .../_test_files/css/unusual_strings.min.css | 2 - .../min_unit_tests/_test_files/css/vladmirated.css | 658 ---- .../_test_files/css/vladmirated.min.css | 79 - .../_test_files/css_uriRewriter/exp.css | 14 - .../_test_files/css_uriRewriter/in.css | 14 - .../min_unit_tests/_test_files/html/before.html | 96 - .../_test_files/html/before.min.html | 36 - .../min_unit_tests/_test_files/html/before2.html | 95 - .../_test_files/html/before2.min.html | 36 - .../_test_files/importProcessor/1/adjacent.css | 3 - .../_test_files/importProcessor/1/tv.css | 4 - .../_test_files/importProcessor/adjacent.css | 4 - .../_test_files/importProcessor/input.css | 4 - .../_test_files/importProcessor/output.css | 48 - .../minify/min_unit_tests/_test_files/js/before.js | 57 - .../min_unit_tests/_test_files/js/before.min.js | 22 - .../_test_files/js/before.min_plus.js | 22 - .../min_unit_tests/_test_files/js/condcomm.js | 14 - .../_test_files/js/condcomm.min_plus.js | 13 - .../min_unit_tests/_test_files/js/issue74.js | 4 - .../min_unit_tests/_test_files/js/issue74.min.js | 1 - .../_test_files/js/issue74.min_plus.js | 1 - .../min_unit_tests/_test_files/js/jquery-1.2.3.js | 3408 -------------------- .../_test_files/minify/QueryString.js | 168 - .../min_unit_tests/_test_files/minify/email.js | 24 - .../min_unit_tests/_test_files/minify/issue73_1.js | 2 - .../min_unit_tests/_test_files/minify/issue73_2.js | 3 - .../_test_files/minify/issue89_1.css | 7 - .../_test_files/minify/issue89_2.css | 7 - .../_test_files/minify/issue89_out.min.css | 1 - .../_test_files/minify/lines_bugs.js | 2 - .../_test_files/minify/lines_output.js | 280 -- .../min_unit_tests/_test_files/minify/minified.css | 5 - .../min_unit_tests/_test_files/minify/minified.js | 12 - .../min_unit_tests/test_HTTP_ConditionalGet.php | 137 - .../minify/min_unit_tests/test_HTTP_Encoder.php | 260 -- .../extlib/minify/min_unit_tests/test_JSMin.php | 63 - .../minify/min_unit_tests/test_JSMinPlus.php | 80 - .../extlib/minify/min_unit_tests/test_Minify.php | 213 -- .../minify/min_unit_tests/test_Minify_Build.php | 36 - .../minify/min_unit_tests/test_Minify_CSS.php | 53 - .../min_unit_tests/test_Minify_CSS_UriRewriter.php | 56 - .../min_unit_tests/test_Minify_Cache_APC.php | 33 - .../min_unit_tests/test_Minify_Cache_File.php | 54 - .../min_unit_tests/test_Minify_Cache_Memcache.php | 38 - .../test_Minify_CommentPreserver.php | 37 - .../minify/min_unit_tests/test_Minify_HTML.php | 59 - .../min_unit_tests/test_Minify_ImportProcessor.php | 48 - .../minify/min_unit_tests/test_Minify_Lines.php | 36 - .../extlib/minify/min_unit_tests/test_all.php | 17 - .../minify/min_unit_tests/test_environment.php | 100 - .../minify/min_unit_tests/test_js_in_browser.html | 4 - 79 files changed, 8441 deletions(-) delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/2.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/3.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/4.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/5.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/_include.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/index.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/green.png delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/index.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_inc.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/readme.txt delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/exp.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/in.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.html delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.min.html delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.html delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.min.html delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/adjacent.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/tv.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/adjacent.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/input.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/output.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min_plus.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.min_plus.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min_plus.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/jquery-1.2.3.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/QueryString.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/email.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue73_1.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue73_2.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue89_1.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue89_2.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/issue89_out.min.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/lines_bugs.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/lines_output.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/minified.css delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/_test_files/minify/minified.js delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_HTTP_ConditionalGet.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_HTTP_Encoder.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_JSMin.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_JSMinPlus.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Build.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_CSS.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_CSS_UriRewriter.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Cache_APC.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Cache_File.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Cache_Memcache.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_CommentPreserver.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_HTML.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_ImportProcessor.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_Minify_Lines.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_all.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_environment.php delete mode 100644 plugins/Minify/extlib/minify/min_unit_tests/test_js_in_browser.html (limited to 'plugins') diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/2.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/2.php deleted file mode 100644 index 9b66f2493..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/2.php +++ /dev/null @@ -1,44 +0,0 @@ - $lastModified -)); -if ($cg->cacheIsValid) { - $cg->sendHeaders(); - // we're done - exit(); -} - -// generate content -$title = 'Last-Modified is known : add Content-Length'; -$explain = ' -

    Here, like the first example, we know the Last-Modified time, -but we also want to set the Content-Length to increase cacheability and allow -HTTP persistent connections. Instead of sending headers immediately, we first -generate our content, then use setContentLength(strlen($content)) -to add the header. Then finally call sendHeaders() and send the -content.

    -

    Note: This is not required if your PHP config buffers all -output and your script doesn\'t do any incremental flushing of the output -buffer. PHP will generally set Content-Length for you if it can.

    -

    This script emulates a document that changes every ' .$every. ' seconds. -
    This is version: ' . date('r', $lastModified) . '

    -'; - -require '_include.php'; -$content = get_content(array( - 'title' => $title - ,'explain' => $explain -)); - -$cg->setContentLength(strlen($content)); -$cg->sendHeaders(); -send_slowly($content); - diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/3.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/3.php deleted file mode 100644 index 8f5482ba8..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/3.php +++ /dev/null @@ -1,40 +0,0 @@ -When Last-Modified is unknown, you can still use ETags, but you need a short -string that is unique for that content. In the worst case, you have to generate -all the content first, then instantiate HTTP_ConditionalGet, setting -the array key contentHash to the output of a hash function of the -content. Since we have the full content, we might as well also use -setContentLength(strlen($content)) in the case where we need to -send it.

    -

    This script emulates a document that changes every ' .$every. ' seconds. -
    This is version: ' . date('r', $lastModified) . '

    -'; -require '_include.php'; -$content = get_content(array( - 'title' => $title - ,'explain' => $explain -)); - -$cg = new HTTP_ConditionalGet(array( - 'contentHash' => substr(md5($content), 7) -)); -if ($cg->cacheIsValid) { - $cg->sendHeaders(); - // we're done - exit(); -} -$cg->setContentLength(strlen($content)); -$cg->sendHeaders(); - -send_slowly($content); - diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/4.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/4.php deleted file mode 100644 index 4b77d2084..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/4.php +++ /dev/null @@ -1,49 +0,0 @@ - $lastModified - ,'encoding' => $enc -)); -$cg->sendHeaders(); -if ($cg->cacheIsValid) { - // we're done - exit(); -} - -// output encoded content - -$title = 'ConditionalGet + Encoder'; -$explain = ' -

    Using ConditionalGet and Encoder is straightforward. First impliment the -ConditionalGet, then if the cache is not valid, encode and send the content

    -

    This script emulates a document that changes every ' .$every. ' seconds. -
    This is version: ' . date('r', $lastModified) . '

    -'; -require '_include.php'; -$content = get_content(array( - 'title' => $title - ,'explain' => $explain -)); - -$he = new HTTP_Encoder(array( - 'content' => get_content(array( - 'title' => $title - ,'explain' => $explain - )) -)); -$he->encode(); - -// usually you would just $he->sendAll(), but here we want to emulate slow -// connection -$he->sendHeaders(); -send_slowly($he->getContent()); diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/5.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/5.php deleted file mode 100644 index b443c1973..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/5.php +++ /dev/null @@ -1,27 +0,0 @@ - 20 - ,'lastModifiedTime' => filemtime(__FILE__) -)); -$cg->sendHeaders(); - -// generate, send content -$title = 'Last-Modified + Expires'; -$explain = ' -

    Here we set a static "lastModifiedTime" and "maxAge" to 20. The browser -will consider this document fresh for 20 seconds, then revalidate its cache. After -the 304 response, the cache will be good for another 20 seconds. Unless you force -a reload, there will only be 304 responses for this page after the initial download. -'; - -require '_include.php'; -echo get_content(array( - 'title' => $title - ,'explain' => $explain -)); - diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/_include.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/_include.php deleted file mode 100644 index 9b65ae12e..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_ConditionalGet/_include.php +++ /dev/null @@ -1,64 +0,0 @@ - - - - - -HTTP_ConditionalGet : <?php echo $data['title']; ?> - - -

    HTTP_ConditionalGet

    -

    - - -

    Notes

    -

    How to distinguish 200 and 304 responses

    -

    For these pages all 200 responses are sent in chunks a second apart, so you -should notice that 304 responses are quicker. You can also use HTTP sniffers -like Fiddler (win) and -LiveHTTPHeaders (Firefox add-on) -to verify headers and content being sent.

    -

    Browser notes

    -
    -
    Opera
    -
    Opera has a couple behaviors against the HTTP spec: Manual refreshes (F5) - prevents the ETag/If-Modified-Since headers from being sent; it only sends - them when following a link or bookmark. Also, Opera will not honor the - must-revalidate Cache-Control value unless max-age - is set. To get Opera to follow the spec, ConditionalGet will send Opera max-age=0 - (if one is not already set).
    -
    Safari
    -
    ETag validation is unsupported, but Safari supports HTTP/1.0 validation via - If-Modified-Since headers as long as the cache is explicitly marked - "public" or "private" ("private" is default in ConditionalGet).
    -
    - - - $lastModified -)); -$cg->sendHeaders(); -if ($cg->cacheIsValid) { - // we're done - exit(); -} - -$title = 'Last-Modified is known : simple usage'; -$explain = ' -

    If your content has not changed since a certain timestamp, set this via the -the lastModifiedTime array key when instantiating HTTP_ConditionalGet. -You can immediately call the method sendHeaders() to set the -Last-Modified, ETag, and Cache-Control headers. The, if cacheIsValid -property is false, you echo the content.

    -

    This script emulates a document that changes every ' .$every. ' seconds. -
    This is version: ' . date('r', $lastModified) . '

    -'; - -require '_include.php'; - -echo send_slowly(get_content(array( - 'title' => $title - ,'explain' => $explain -))); - diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/green.png b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/green.png deleted file mode 100644 index d9d3a308a..000000000 Binary files a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/green.png and /dev/null differ diff --git a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/index.php b/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/index.php deleted file mode 100644 index c9a391d07..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/HTTP_Encoder/index.php +++ /dev/null @@ -1,60 +0,0 @@ - - - - -HTTP_Encoder Test - - - -

    HTTP_Encoder test

    -

    HTML

    -

    CSS

    -

    Javascript

    -

    image

    - - - - $content - ,'type' => $type -)); -$he->encode(); -$he->sendAll(); - -?> \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_inc.php b/plugins/Minify/extlib/minify/min_unit_tests/_inc.php deleted file mode 100644 index bf416d4bb..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_inc.php +++ /dev/null @@ -1,50 +0,0 @@ -0, 'fail'=>0, 'total'=>0); - - $mode = $test ? 'pass' : 'fail'; - $outMode = $test ? 'PASS' : '!FAIL'; - printf("%s: %s (%d of %d tests run so far have %sed)\n", - $outMode, $message, ++$count[$mode], ++$count['total'], $mode); - - return (bool)$test; -} - -ob_start(); \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.css deleted file mode 100644 index 2ef9fac49..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.css +++ /dev/null @@ -1,9 +0,0 @@ - -/* block comments get removed */ - -/*! YUI Compressor style comments are preserved */ - -/* but all other comments are removed */ - -/* comments that have any surrounding whitespace are replaced by a single space. */ -body{ background:#fff/*eef*/ url(/path/to/image.gif) repeat-y; } diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.min.css deleted file mode 100644 index 3ea5c61a6..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/comments.min.css +++ /dev/null @@ -1,3 +0,0 @@ - -/* YUI Compressor style comments are preserved */ -body{background:#fff url(/path/to/image.gif) repeat-y} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.css deleted file mode 100644 index fccd32166..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.css +++ /dev/null @@ -1,66 +0,0 @@ -/* hide from ie5/mac \*/ a{} -.foo {color:red} -/* necessary comment */ - -/* comment to attempt to confuse parser */ - -/* feed to ie5/mac \*//*/ -@import "ie5mac.css"; -/* necessary comment */ - -/* comment to attempt to confuse parser */ - -/*/ hide from nav4 */ -.foo {display:block;} -/* necessary comment */ - -/* comment to attempt to confuse parser */ - -/*/ feed to nav *//*/ -.foo {display:crazy;} -/* necessary comment */ - -/* hide props from various IE/win */ -div { - width: 140px; - width/* */:/**/100px; - width: /**/100px; -} - -html>/**/body {} - -/* Tantek's box model hack */ -div { - width:400px; - voice-family: "\"}\""; - voice-family:inherit; - width:300px; -} - -/* don't minimize hex colors in filters */ -div { - filter:chroma(color=#aabbcc); - filter:mask(color=#000000) shadow(color=#9BAD71, direction=135) chroma(color=#000000); -} - -@media screen { - /* for IE 5.x-6, hidden from IE 5 Mac */ /*\*/ - * html div#page { - height: 1%; - } - /**/ /* end hidden from IE 5 Mac */ -} - -foo { /* filters for IE */ - _height : 20px; - *height : 15px; -} - -/* http://tantek.com/CSS/Examples/midpass.html */ -@media tty { - i{content:"\";/*" "*/}} @import 'midpassafter.css'; /*";} -}/* */ - -/* leave at least 1 space between these pseudo elements and "{" for IE6: http://www.crankygeek.com/ie6pebug/ */ -p:first-letter {color:red;} -p:first-line {color:red;} diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.min.css deleted file mode 100644 index 68be2ee89..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/hacks.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*\*/a{}.foo{color:red}/**/ /*\*//*/@import "ie5mac.css";/**/ /*/*/.foo{display:block}/**/ /*/*//*/.foo{display:crazy}/**/ div{width:140px;width/**/:/**/100px;width:/**/100px}html>/**/body{}div{width:400px;voice-family:"\"}\"";voice-family:inherit;width:300px}div{filter:chroma(color=#aabbcc);filter:mask(color=#000000) shadow(color=#9BAD71, direction=135) chroma(color=#000000)}@media -screen{/*\*/* html -div#page{height:1%}/**/}foo{_height:20px;*height:15px}@media -tty{i{content:"\";/*" "*/}}@import 'midpassafter.css';/*"}}/* */ p:first-letter {color:red}p:first-line {color:red} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.css deleted file mode 100644 index 006c7a22f..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.css +++ /dev/null @@ -1,890 +0,0 @@ -/* -* DEFINITION DES STYLES DE TEXTE -*/ - /*-----------------------------------------------------------------------------------*/ -h1 { - color: #339933; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - font-weight: bold; - text-decoration: none; -} - -h2 { - color: #339933; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - font-weight: bold; - text-decoration: none; -} - -h1,h2,h3,h4,h5 { - margin: 0px; - padding: 0px; -} - -.txt_10_noir { - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_noir:link,.txt_10_noir:visited,.txt_10_noir:active { - color: black; -} - -.txt_10_noir:hover { - color: red; -} - -.txt_11_noir { - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_noir:link,.txt_11_noir:visited,.txt_11_noir:active { - color: black; -} - -.txt_11_noir:hover { - color: red; -} - -.txt_12_noir { - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_noir:link,.txt_12_noir:visited,.txt_12_noir:active { - color: black; -} - -.txt_12_noir:hover { - color: red; -} - -.txt_14_noir { - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_noir:link,.txt_14_noir:visited,.txt_14_noir:active { - color: black; -} - -.txt_14_noir:hover { - color: red; -} - -/*-----------------------------------------------------------------------------------*/ -.txt_10_gris { - color: grey; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_gris:link,.txt_10_gris:visited,.txt_10_gris:active { - color: grey; -} - -.txt_10_gris:hover { - color: red; -} - -.txt_11_gris { - color: grey; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_gris:link,.txt_11_gris:visited,.txt_11_gris:active { - color: grey; -} - -.txt_11_gris:hover { - color: red; -} - -.txt_12_gris { - color: grey; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_gris:link,.txt_12_gris:visited,.txt_12_gris:active { - color: grey; -} - -.txt_12_gris:hover { - color: red; -} - -.txt_14_gris { - color: grey; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_gris:link,.txt_14_gris:visited,.txt_14_gris:active { - color: grey; -} - -.txt_14_gris:hover { - color: red; -} - -/*-----------------------------------------------------------------------------------*/ -.txt_10_blanc { - color: #FFFFFF; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_blanc:link,.txt_10_blanc:visited,.txt_10_blanc:active { - color: #FFFFFF; -} - -.txt_10_blanc:hover { - color: #FF8800; /*ORANGE*/ -} - -.txt_11_blanc { - color: #FFFFFF; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_blanc:link,.txt_11_blanc:visited,.txt_11_blanc:active { - color: #FFFFFF; -} - -.txt_11_blanc:hover { - color: #FF8800; -} - -.txt_12_blanc { - color: #FFFFFF; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_blanc:link,.txt_12_blanc:visited,.txt_12_blanc:active { - color: #FFFFFF; -} - -.txt_12_blanc:hover { - color: #FFAA00; -} - -.txt_14_blanc { - color: #FFFFFF; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_blanc:link,.txt_14_blanc:visited,.txt_14_blanc:active { - color: #FFFFFF; -} - -.txt_14_blanc:hover { - color: #FF8800; -} - -/*-----------------------------------------------------------------------------------*/ -.txt_10_orange { - color: #FF8800; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_orange:link,.txt_10_orange:visited,.txt_10_orange:active { - color: #FF8800; -} - -.txt_10_orange:hover { - color: darkblue -} - -.txt_11_orange { - color: #FF8800; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_orange:link,.txt_11_orange:visited,.txt_11_orange:active { - color: #FF8800; -} - -.txt_11_orange:hover { - color: darkblue; -} - -.txt_12_orange { - color: #FF8800; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_orange:link,.txt_12_orange:visited,.txt_12_orange:active { - color: #FF8800; -} - -.txt_12_orange:hover { - color: darkblue; -} - -.txt_14_orange { - color: #FF8800; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_orange:link,.txt_14_orange:visited,.txt_14_orange:active { - color: #FF8800; -} - -.txt_14_orange:hover { - color: darkblue; -} - -/*-----------------------------------------------------------------------------------*/ -.txt_10_rouge { - color: red; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_rouge:link,.txt_10_rouge:visited,.txt_10_rouge:active { - color: red; -} - -.txt_10_rouge:hover { - color: darkblue; -} - -.txt_11_rouge { - color: red; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_rouge:link,.txt_11_rouge:visited,.txt_11_rouge:active { - color: red; -} - -.txt_11_rouge:hover { - color: darkblue; -} - -.txt_12_rouge { - color: red; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_rouge:link,.txt_12_rouge:visited,.txt_12_rouge:active { - color: red; -} - -.txt_12_rouge:hover { - color: darkblue; -} - -.txt_14_rouge { - color: red; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_rouge:link,.txt_14_rouge:visited,.txt_14_rouge:active { - color: red; -} - -.txt_14_rouge:hover { - color: darkblue; -} - -/*-----------------------------------------------------------------------------------*/ -.txt_10_bleu { - color: blue; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_bleu:link,.txt_10_bleu:visited,.txt_10_bleu:active { - color: blue; -} - -.txt_10_bleu:hover { - color: red; -} - -.txt_11_bleu { - color: blue; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_bleu:link,.txt_11_bleu:visited,.txt_11_bleu:active { - color: blue; -} - -.txt_11_bleu:hover { - color: red; -} - -.txt_12_bleu { - color: blue; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_bleu:link,.txt_12_bleu:visited,.txt_12_bleu:active { - color: blue; -} - -.txt_12_bleu:hover { - color: red; -} - -.txt_14_bleu { - color: blue; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_bleu:link,.txt_14_bleu:visited,.txt_14_bleu:active { - color: blue; -} - -.txt_14_bleu:hover { - color: red; -} - -/*-----------------------------------------------------------------------------------*/ -.txt_10_bleu_f { - color: darkblue; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_bleu_f:link,.txt_10_bleu_f:visited,.txt_10_bleu_f:active { - color: darkblue; -} - -.txt_10_bleu_f:hover { - color: red; -} - -.txt_11_bleu_f { - color: darkblue; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_bleu_f:link,.txt_11_bleu_f:visited,.txt_11_bleu_f:active { - color: darkblue; -} - -.txt_11_bleu_f:hover { - color: red; -} - -.txt_12_bleu_f { - color: darkblue; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_bleu_f:link,.txt_12_bleu_f:visited,.txt_12_bleu_f:active { - color: darkblue; -} - -.txt_12_bleu_f:hover { - color: red; -} - -.txt_14_bleu_f { - color: darkblue; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_bleu_f:link,.txt_14_bleu_f:visited,.txt_14_bleu_f:active { - color: darkblue; -} - -.txt_14_bleu_f:hover { - color: red; -} - -/*-----------------------------------------------------------------------------------*/ -.txt_10_vert_f { - color: darkgreen; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_vert_f:link,.txt_10_vert_f:visited,.txt_10_vert_f:active { - color: darkgreen; -} - -.txt_10_vert_f:hover { - color: red; -} - -.txt_11_vert_f { - color: darkgreen; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_vert_f:link,.txt_11_vert_f:visited,.txt_11_vert_f:active { - color: darkgreen; -} - -.txt_11_vert_f:hover { - color: red; -} - -.txt_12_vert_f { - color: darkgreen; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_vert_f:link,.txt_12_vertf:visited,.txt_12_vert_f:active { - color: darkgreen; -} - -.txt_12_vert_f:hover { - color: red; -} - -.txt_14_vert_f { - color: darkgreen; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_vert_f:link,.txt_14_vert_f:visited,.txt_14_vert_f:active { - color: darkgreen; -} - -.txt_14_vert_f:hover { - color: red; -} - -/*-----------------------------------------------------------------------------------*/ -.txt_10_vert { - color: green; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.txt_10_vert:link,.txt_10_vert:visited,.txt_10_vert:active { - color: green; -} - -.txt_10_vert:hover { - color: red; -} - -.txt_11_vert { - color: green; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.txt_11_vert:link,.txt_11_vert:visited,.txt_11_vert:active { - color: green; -} - -.txt_11_vert:hover { - color: red; -} - -.txt_12_vert { - color: green; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - text-decoration: none; -} - -.txt_12_vert:link,.txt_12_vert:visited,.txt_12_vert:active { - color: green; -} - -.txt_12_vert:hover { - color: red; -} - -.txt_14_vert { - color: green; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 14px; - text-decoration: none; -} - -.txt_14_vert:link,.txt_14_vert:visited,.txt_14_vert:active { - color: green; -} - -.txt_14_vert:hover { - color: red; -} - -/*-----------------------------------------------------------------------------------*/ -.fond_blanc { - background-color: #FFFFFF; - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.fond_gris_c, .fond_gris_c tr { - background-color: #FFFFFF; - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; - background-image: url(../images/fond_4.bmp); - background-repeat: repeat-x; -} - -.fond_gris_c2, .fond_gris_c2 tr { - background-color: #FBFBFB; - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.fond_bleu_c, .fond_bleu_c tr { - background-color: #D9EEF9; - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; - background-image: url(../images/fond_1.bmp); -} - -.fond_bleu_c2 { - background-color: #ECF4FF; - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.fond_bleu_f { - background-color: #003366; - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.fond_orange { - background-color: #FEEFE7; - color: darkgreen; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - font-weight: bold; - text-decoration: none; - background-image: url(../images/fond_3.jpg); -} - -.fond_orange_2 { - background-color: #FFF8F4; - color: darkgreen; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - font-weight: bold; - text-decoration: none; - border: 1px solid orange; - border-collapse: collapse; -} - -.vccDlgBody { - border: 3px solid #336699; - border-collapse: collapse; - color: black; - background-color: #EEFFEE; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -/* DEFINITION DES STYLES DE TABLEAUX */ -.bordure_0 { - border: 0px solid; - color: black; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.bordure_1_bleu { - border: 1px solid green; - border-collapse: collapse; - color: black; - background-color: #FFFFFF; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.bordure_3_bleu { - border: 3px solid #336699; - border-collapse: collapse; - color: black; - background-color: #FFFFFF; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 11px; - text-decoration: none; -} - -.indent { - margin-left: 20px; -} - -/* DEFINITION DES STYLES D'OBJETS DE FORMULAIRE */ -.Btn { - color: #003366; - text-align: center; - font-weight: bold; - background-color: #FFFFFF; - background-image: url(../images/ongletStyle1.jpg); - background-repeat: no-repeat; - background-position: center center; -} - -.Btn:hover { - color: red; -} - -.menu1h { - background-color: #003366; - color: white; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - font-weight: bold; - text-decoration: none; - border-top: 1px solid #003366; - border-bottom: 1px solid #003366; - border-left: 1px solid #003366; - border-right: 1px solid white; - border-collapse: collapse; - display: block; -} - -.menu1h:hover { - background-color: white; - color: red; - border: 1px solid darkgreen; - border-collapse: collapse; -} - -.menu1h_f { - background-color: #003366; - color: white; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - font-weight: bold; - text-decoration: none; - border: 1px solid #003366; - display: block; -} - -.menu1h_f:hover { - background-color: white; - color: red; - border: 1px solid darkgreen; - border-collapse: collapse; -} - -.menu1v { - background-color: #003366; - color: white; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - font-weight: bold; - text-decoration: none; - border: 1px solid #003366; - border-collapse: collapse; - display: block; -} - -.menu1v:hover { - background-color: white; - color: red; - border: 1px solid darkgreen; - border-collapse: collapse; -} - -.menu2v { - background-color: #5588BB; - color: white; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 12px; - font-weight: bold; - text-decoration: none; - border: 1px solid #4277AB; - border-collapse: collapse; - float: left; - display: block; -} - -.menu2v:hover { - background-color: white; - color: red; - border: 1px solid darkgreen; - border-collapse: collapse; -} - -.menuEDF { - background-color: #003366; - color: white; - font-family: Verdana, Arial, Lucida, Tahoma; - font-size: 10px; - text-decoration: none; -} - -.menuEDF:hover { - color: #FF8800; -} - -/*bouton bleu sur blanc*/ -.Bouton { - color: #003366; - text-align: center; - font-weight: bold; - /* Ricardo cursor: hand; */ - cursor: pointer; - background-color: #FFFFFF; -} - -input { - border: 2px solid green; - color: #003366; - background-color: #FFFFFF; - background-image: url(../images/fond_4.bmp); - background-repeat: repeat-x; -} - -.disabled_input { - border: 1px solid gray; - color: grey; - background-color: #FFFFFF; - background-image: url(../images/fond_4.bmp); - background-repeat: repeat-x; -} - -.input0 { - border: 0px; - color: #003366; - background-color: #FFFFFF; - background-image: url(../images/fond_4.bmp); -} - -.input2 { - border: 1px solid green; - color: #003366; - background-color: #FFFFFF; - background-image: url(../images/fond_4.bmp); - background-repeat: repeat-x; -} - -.input3 { - border: 1px solid black; - color: #003366; - background-color: #EEEEEE; - background-image: url(); -} - -.input4 { - border: 1px solid blue; - color: #003366; - background-color: #FFFFFF; - background-image: url(../images/fond_4.bmp); - background-repeat: repeat-x; -} - -.input5 { - border: 1px solid darkblue; - color: #003366; - background-color: #FFFFFF; - background-image: url(../images/fond_4.bmp); - background-repeat: repeat-x; -} - -.input_btn { - border: 0px; - /* cursor: hand; */ - cursor: pointer; -} - -textarea { - border: 2px solid green; - color: #003366; - background-color: #FFFFFF; - background-image: url(../images/fond_5.bmp); -} - -.TEXTAREA3 { - border: 1px solid green; - color: #003366; - background-color: #FFFFFF; - background-image: url(); -} - -.TEXTAREA4 { - border: 1px solid green; - color: #003366; - background-color: #EEEEEE; - background-image: url(); -} - -.hand { - cursor: hand; - cursor: pointer; -} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.min.css deleted file mode 100644 index 5eb198228..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/issue62.min.css +++ /dev/null @@ -1,25 +0,0 @@ -h1{color:#393;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;font-weight:bold;text-decoration:none}h2{color:#393;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;font-weight:bold;text-decoration:none}h1,h2,h3,h4,h5{margin:0px;padding:0px}.txt_10_noir{color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_noir:link,.txt_10_noir:visited,.txt_10_noir:active{color:black}.txt_10_noir:hover{color:red}.txt_11_noir{color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_noir:link,.txt_11_noir:visited,.txt_11_noir:active{color:black}.txt_11_noir:hover{color:red}.txt_12_noir{color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_noir:link,.txt_12_noir:visited,.txt_12_noir:active{color:black}.txt_12_noir:hover{color:red}.txt_14_noir{color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_noir:link,.txt_14_noir:visited,.txt_14_noir:active{color:black}.txt_14_noir:hover{color:red}.txt_10_gris{color:grey;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_gris:link,.txt_10_gris:visited,.txt_10_gris:active{color:grey}.txt_10_gris:hover{color:red}.txt_11_gris{color:grey;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_gris:link,.txt_11_gris:visited,.txt_11_gris:active{color:grey}.txt_11_gris:hover{color:red}.txt_12_gris{color:grey;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_gris:link,.txt_12_gris:visited,.txt_12_gris:active{color:grey}.txt_12_gris:hover{color:red}.txt_14_gris{color:grey;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_gris:link,.txt_14_gris:visited,.txt_14_gris:active{color:grey}.txt_14_gris:hover{color:red}.txt_10_blanc{color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_blanc:link,.txt_10_blanc:visited,.txt_10_blanc:active{color:#FFF}.txt_10_blanc:hover{color:#F80}.txt_11_blanc{color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_blanc:link,.txt_11_blanc:visited,.txt_11_blanc:active{color:#FFF}.txt_11_blanc:hover{color:#F80}.txt_12_blanc{color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_blanc:link,.txt_12_blanc:visited,.txt_12_blanc:active{color:#FFF}.txt_12_blanc:hover{color:#FA0}.txt_14_blanc{color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_blanc:link,.txt_14_blanc:visited,.txt_14_blanc:active{color:#FFF}.txt_14_blanc:hover{color:#F80}.txt_10_orange{color:#F80;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_orange:link,.txt_10_orange:visited,.txt_10_orange:active{color:#F80}.txt_10_orange:hover{color:darkblue}.txt_11_orange{color:#F80;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_orange:link,.txt_11_orange:visited,.txt_11_orange:active{color:#F80}.txt_11_orange:hover{color:darkblue}.txt_12_orange{color:#F80;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_orange:link,.txt_12_orange:visited,.txt_12_orange:active{color:#F80}.txt_12_orange:hover{color:darkblue}.txt_14_orange{color:#F80;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_orange:link,.txt_14_orange:visited,.txt_14_orange:active{color:#F80}.txt_14_orange:hover{color:darkblue}.txt_10_rouge{color:red;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_rouge:link,.txt_10_rouge:visited,.txt_10_rouge:active{color:red}.txt_10_rouge:hover{color:darkblue}.txt_11_rouge{color:red;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_rouge:link,.txt_11_rouge:visited,.txt_11_rouge:active{color:red}.txt_11_rouge:hover{color:darkblue}.txt_12_rouge{color:red;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_rouge:link,.txt_12_rouge:visited,.txt_12_rouge:active{color:red}.txt_12_rouge:hover{color:darkblue}.txt_14_rouge{color:red;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_rouge:link,.txt_14_rouge:visited,.txt_14_rouge:active{color:red}.txt_14_rouge:hover{color:darkblue}.txt_10_bleu{color:blue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_bleu:link,.txt_10_bleu:visited,.txt_10_bleu:active{color:blue}.txt_10_bleu:hover{color:red}.txt_11_bleu{color:blue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_bleu:link,.txt_11_bleu:visited,.txt_11_bleu:active{color:blue}.txt_11_bleu:hover{color:red}.txt_12_bleu{color:blue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_bleu:link,.txt_12_bleu:visited,.txt_12_bleu:active{color:blue}.txt_12_bleu:hover{color:red}.txt_14_bleu{color:blue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_bleu:link,.txt_14_bleu:visited,.txt_14_bleu:active{color:blue}.txt_14_bleu:hover{color:red}.txt_10_bleu_f{color:darkblue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_bleu_f:link,.txt_10_bleu_f:visited,.txt_10_bleu_f:active{color:darkblue}.txt_10_bleu_f:hover{color:red}.txt_11_bleu_f{color:darkblue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_bleu_f:link,.txt_11_bleu_f:visited,.txt_11_bleu_f:active{color:darkblue}.txt_11_bleu_f:hover{color:red}.txt_12_bleu_f{color:darkblue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_bleu_f:link,.txt_12_bleu_f:visited,.txt_12_bleu_f:active{color:darkblue}.txt_12_bleu_f:hover{color:red}.txt_14_bleu_f{color:darkblue;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_bleu_f:link,.txt_14_bleu_f:visited,.txt_14_bleu_f:active{color:darkblue}.txt_14_bleu_f:hover{color:red}.txt_10_vert_f{color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_vert_f:link,.txt_10_vert_f:visited,.txt_10_vert_f:active{color:darkgreen}.txt_10_vert_f:hover{color:red}.txt_11_vert_f{color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_vert_f:link,.txt_11_vert_f:visited,.txt_11_vert_f:active{color:darkgreen}.txt_11_vert_f:hover{color:red}.txt_12_vert_f{color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_vert_f:link,.txt_12_vertf:visited,.txt_12_vert_f:active{color:darkgreen}.txt_12_vert_f:hover{color:red}.txt_14_vert_f{color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_vert_f:link,.txt_14_vert_f:visited,.txt_14_vert_f:active{color:darkgreen}.txt_14_vert_f:hover{color:red}.txt_10_vert{color:green;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.txt_10_vert:link,.txt_10_vert:visited,.txt_10_vert:active{color:green}.txt_10_vert:hover{color:red}.txt_11_vert{color:green;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.txt_11_vert:link,.txt_11_vert:visited,.txt_11_vert:active{color:green}.txt_11_vert:hover{color:red}.txt_12_vert{color:green;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;text-decoration:none}.txt_12_vert:link,.txt_12_vert:visited,.txt_12_vert:active{color:green}.txt_12_vert:hover{color:red}.txt_14_vert{color:green;font-family:Verdana,Arial,Lucida,Tahoma;font-size:14px;text-decoration:none}.txt_14_vert:link,.txt_14_vert:visited,.txt_14_vert:active{color:green}.txt_14_vert:hover{color:red}.fond_blanc{background-color:#FFF;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.fond_gris_c, .fond_gris_c -tr{background-color:#FFF;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.fond_gris_c2, .fond_gris_c2 -tr{background-color:#FBFBFB;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.fond_bleu_c, .fond_bleu_c -tr{background-color:#D9EEF9;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none;background-image:url(../images/fond_1.bmp)}.fond_bleu_c2{background-color:#ECF4FF;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.fond_bleu_f{background-color:#036;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.fond_orange{background-color:#FEEFE7;color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;font-weight:bold;text-decoration:none;background-image:url(../images/fond_3.jpg)}.fond_orange_2{background-color:#FFF8F4;color:darkgreen;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;font-weight:bold;text-decoration:none;border:1px -solid orange;border-collapse:collapse}.vccDlgBody{border:3px -solid #369;border-collapse:collapse;color:black;background-color:#EFE;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.bordure_0{border:0px -solid;color:black;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.bordure_1_bleu{border:1px -solid green;border-collapse:collapse;color:black;background-color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.bordure_3_bleu{border:3px -solid #369;border-collapse:collapse;color:black;background-color:#FFF;font-family:Verdana,Arial,Lucida,Tahoma;font-size:11px;text-decoration:none}.indent{margin-left:20px}.Btn{color:#036;text-align:center;font-weight:bold;background-color:#FFF;background-image:url(../images/ongletStyle1.jpg);background-repeat:no-repeat;background-position:center center}.Btn:hover{color:red}.menu1h{background-color:#036;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;font-weight:bold;text-decoration:none;border-top:1px solid #036;border-bottom:1px solid #036;border-left:1px solid #036;border-right:1px solid white;border-collapse:collapse;display:block}.menu1h:hover{background-color:white;color:red;border:1px -solid darkgreen;border-collapse:collapse}.menu1h_f{background-color:#036;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;font-weight:bold;text-decoration:none;border:1px -solid #036;display:block}.menu1h_f:hover{background-color:white;color:red;border:1px -solid darkgreen;border-collapse:collapse}.menu1v{background-color:#036;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;font-weight:bold;text-decoration:none;border:1px -solid #036;border-collapse:collapse;display:block}.menu1v:hover{background-color:white;color:red;border:1px -solid darkgreen;border-collapse:collapse}.menu2v{background-color:#58B;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:12px;font-weight:bold;text-decoration:none;border:1px -solid #4277AB;border-collapse:collapse;float:left;display:block}.menu2v:hover{background-color:white;color:red;border:1px -solid darkgreen;border-collapse:collapse}.menuEDF{background-color:#036;color:white;font-family:Verdana,Arial,Lucida,Tahoma;font-size:10px;text-decoration:none}.menuEDF:hover{color:#F80}.Bouton{color:#036;text-align:center;font-weight:bold;cursor:pointer;background-color:#FFF}input{border:2px -solid green;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.disabled_input{border:1px -solid gray;color:grey;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.input0{border:0px;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp)}.input2{border:1px -solid green;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.input3{border:1px -solid black;color:#036;background-color:#EEE;background-image:url()}.input4{border:1px -solid blue;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.input5{border:1px -solid darkblue;color:#036;background-color:#FFF;background-image:url(../images/fond_4.bmp);background-repeat:repeat-x}.input_btn{border:0px;cursor:pointer}textarea{border:2px -solid green;color:#036;background-color:#FFF;background-image:url(../images/fond_5.bmp)}.TEXTAREA3{border:1px -solid green;color:#036;background-color:#FFF;background-image:url()}.TEXTAREA4{border:1px -solid green;color:#036;background-color:#EEE;background-image:url()}.hand{cursor:hand;cursor:pointer} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.css deleted file mode 100644 index da7cfca20..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.css +++ /dev/null @@ -1,12 +0,0 @@ -@import "foo.css"; -@import 'bar/foo.css' print; -@import '/css/foo.css'; /* abs, should not alter */ -@import 'http://foo.com/css/foo.css'; /* abs, should not alter */ -@import url(../foo.css) tv, projection; -@import url("/css/foo.css"); /* abs, should not alter */ -@import url(/css2/foo.css); /* abs, should not alter */ -@import url(data:image/gif;base64,AAAA); /* data, should not alter */ -foo {background:url('bar/foo.png')} -foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */ -foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */ -foo {background:url(data:image/gif;base64,AAAA);} /* data, should not alter */ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.min.css deleted file mode 100644 index ffb94e216..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_prepend.min.css +++ /dev/null @@ -1 +0,0 @@ -@import "../foo.css";@import '../bar/foo.css' print;@import '/css/foo.css';@import 'http://foo.com/css/foo.css';@import url(../../foo.css) tv, projection;@import url("/css/foo.css");@import url(/css2/foo.css);@import url(data:image/gif;base64,AAAA);foo{background:url('../bar/foo.png')}foo{background:url('http://foo.com/css/foo.css')}foo{background:url("//foo.com/css/foo.css")}foo{background:url(data:image/gif;base64,AAAA)} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.css deleted file mode 100644 index aa41d0a91..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.css +++ /dev/null @@ -1,14 +0,0 @@ -@import "foo.css"; -@import 'bar/foo.css' print; -@import '../bar/foo.css' print; -@import '../../foo.css' print; -@import '/css/foo.css'; /* abs, should not alter */ -@import 'http://foo.com/css/foo.css'; /* abs, should not alter */ -@import url(../foo.css) tv, projection; -@import url("/css/foo.css"); /* abs, should not alter */ -@import url(/css2/foo.css); /* abs, should not alter */ -@import url(data:image/gif;base64,AAAA); /* data, should not alter */ -foo {background:url('bar/foo.png')} -foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */ -foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */ -foo {background:url(data:image/gif;base64,AAAA);} /* data, should not alter */ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.min.css deleted file mode 100644 index 34936155a..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/paths_rewrite.min.css +++ /dev/null @@ -1 +0,0 @@ -@import "/_test_files/css/foo.css";@import '/_test_files/css/bar/foo.css' print;@import '/_test_files/bar/foo.css' print;@import '/foo.css' print;@import '/css/foo.css';@import 'http://foo.com/css/foo.css';@import url(/_test_files/foo.css) tv, projection;@import url("/css/foo.css");@import url(/css2/foo.css);@import url(data:image/gif;base64,AAAA);foo{background:url('/_test_files/css/bar/foo.png')}foo{background:url('http://foo.com/css/foo.css')}foo{background:url("//foo.com/css/foo.css")}foo{background:url(data:image/gif;base64,AAAA)} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/readme.txt b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/readme.txt deleted file mode 100644 index 018175529..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/readme.txt +++ /dev/null @@ -1 +0,0 @@ -Test suite from http://search.cpan.org/~gtermars/CSS-Minifier-XS/ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.css deleted file mode 100644 index d74c9aa02..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.css +++ /dev/null @@ -1,42 +0,0 @@ -/* http://www.w3.org/TR/css3-selectors/ */ - -* -E[foo] -E[foo="bar"] -E[foo~="bar"] -E[foo^="bar"] -E[foo$="bar"] -E[foo*="bar"] -E[hreflang|="en"] -E:root -E:nth-child(n) -E:nth-last-child(n) -E:nth-of-type(n) -E:nth-last-of-type(n) -E:first-child -E:last-child -E:first-of-type -E:last-of-type -E:only-child -E:only-of-type -E:empty -E:link -E:visited -E:active -E:hover -E:focus -E:target -E:lang(fr) -E:enabled -E:disabled -E:checked -E::first-line -E::first-letter -E::selection -E::before -E::after -E.warning#myid -E:not(s) - > F - + F - ~ F {color: red;} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.min.css deleted file mode 100644 index 643089fcf..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/selectors.min.css +++ /dev/null @@ -1,37 +0,0 @@ -* -E[foo] -E[foo="bar"] -E[foo~="bar"] -E[foo^="bar"] -E[foo$="bar"] -E[foo*="bar"] -E[hreflang|="en"] -E:root -E:nth-child(n) -E:nth-last-child(n) -E:nth-of-type(n) -E:nth-last-of-type(n) -E:first-child -E:last-child -E:first-of-type -E:last-of-type -E:only-child -E:only-of-type -E:empty -E:link -E:visited -E:active -E:hover -E:focus -E:target -E:lang(fr) -E:enabled -E:disabled -E:checked -E::first-line -E::first-letter -E::selection -E::before -E::after -E.warning#myid -E:not(s)>F+F~F{color:red} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.css deleted file mode 100644 index bf46c0af0..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.css +++ /dev/null @@ -1,31 +0,0 @@ -/* some CSS to try to exercise things in general */ - -@import url( /more.css ); - - body, td, th { - font-family: Verdana , "Bitstream Vera Sans" , sans-serif ; - - font-size : 12px; -} - -.nav { - margin-left: 20%; -} -#main-nav { - background-color: red; - border: 1px solid #00ff77; -} - -div#content -h1 + p { - padding-top: 0; - margin-top: 0; -} - -@media all and (min-width: 640px) { - #media-queries-1 { background-color: #0f0; } -} - -@media screen and (max-width: 2000px) { - #media-queries-2 { background-color: #0f0; } -} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.min.css deleted file mode 100644 index a823b0550..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/styles.min.css +++ /dev/null @@ -1,3 +0,0 @@ -@import url(/more.css);body,td,th{font-family:Verdana,"Bitstream Vera Sans",sans-serif;font-size:12px}.nav{margin-left:20%}#main-nav{background-color:red;border:1px -solid #0f7}div#content -h1+p{padding-top:0;margin-top:0}@media all and (min-width: 640px){#media-queries-1{background-color:#0f0}}@media screen and (max-width: 2000px){#media-queries-2{background-color:#0f0}} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.css deleted file mode 100644 index 79d34ec4a..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.css +++ /dev/null @@ -1,434 +0,0 @@ -/* Based on the original Style Sheet for the fisubsilver v2 Theme for phpBB version 2+ -Edited by Daz - http://www.forumimages.com - last updated 26-06-03 */ -/* The content of the posts (body of text) */ -/* General page style */ - - - - /* begin suggest post */ - .float-l{ - float: left; - } - - .form-suggest{ - height:200px; - background:#DEE2D0; - vertical-align: top; - } - - .form-input input{ - font-size: 10px; - } - - .hide{ - display:none; - } - - .form-input textarea{ - font-size: 11px; - width: 350px; - } - - .form-label{ - font-size: 10px; - font-weight: bold; - line-height: 25px; - padding-right: 10px; - text-align: right; - width: 100px; - color: #39738F; - } - - .font-9{ - font-size: 9px; - } - - .form-topic{ - font-weight:bold; - - } - - .form-error{ - color:red; - } - - .inline{ - display: inline; - } - - .space-10{ - clear: both; - font-size: 10px; - height: 10px; - line-height: 10px; - } - - .suggest-success{ - color:green; - padding-left:10px; - font-size:11px; - font-weight:bold; - } - - .top{ - vertical-align: top; - } - /* end suggest post */ - -table td{ - padding:3px; -} - -a:link,a:active,a:visited,a.postlink{ - color: #006699; - text-decoration: none; -} - -a:hover{ - color: #DD6900; -} - -a.admin:hover,a.mod:hover{ - color: #DD6900; -} - -a.but,a.but:hover,a.but:visited{ - color: #000000; - text-decoration: none; -} - -a.topictitle:visited{ - color: #5493B4; -} - -a.topictitle:hover{ - color: #DD6900; -} - - - -body{ - color: #000000; - font: 11px Verdana,Arial,Helvetica,sans-serif; - margin: 0 10px 10px 10px; - padding: 0; - overflow:auto; -} - -/* General font families for common tags */ -font,th,td,p{ - font: 12px Verdana,Arial,Helvetica,sans-serif; -} - -/* Form elements */ -form{ - display: inline; -} - -hr{ - border: 0px solid #FFFFFF; - border-top-width: 1px; - height: 0px; -} - -/* Gets rid of the need for border="0" on hyperlinked images */ -img{ - border: 0 solid; -} - -input{ - font: 11px Verdana,Arial,Helvetica,sans-serif; -} - -input.button,input.liteoption,.fakebut{ - background: #FAFAFA; - border: 1px solid #000000; - font-size: 11px; -} - -input.catbutton{ - background: #FAFAFA; - border: 1px solid #000000; - font-size: 10px; -} - -input.mainoption{ - background: #FAFAFA; - border: 1px solid #000000; - font-size: 11px; - font-weight: bold; -} - -input.post,textarea.post{ - background: #FFFFFF; - border: 1px solid #000000; - font: 11px Verdana,Arial,Helvetica,sans-serif; - padding-bottom: 2px; - padding-left: 2px; -} - -select{ - background: #FFFFFF; - font: 11px Verdana,Arial,Helvetica,sans-serif; -} - -table{ - text-align: left; -} - -td{ - vertical-align: middle; -} - -/* Category gradients*/ -td.cat{ - background-color: #C2C6BA; - font-weight: bold; - height: 20px; - letter-spacing: 1px; - text-indent: 4px; -} - -td.genmed,.genmed{ - font-size: 11px; -} - -/* This is for the table cell above the Topics,Post & Last posts on the index.php */ -td.rowpic{ - background: #C2C6BA; -} - -td.spacerow{ - background: #E5E6E2; -} - -/* Table Header cells */ -th{ - background-color: #FADD31; - background-image: url(images/cellpic3.gif); - background-repeat: repeat-x; - color: #68685E; - font-size: 11px; - font-weight: bold; - line-height:16px; - height: 16px; - padding-left: 8px; - padding-right: 8px; - text-align: center; - white-space: nowrap; -} - -/* Admin & Moderator Colours MODification */ -.admin,.mod{ - font-size: 11px; - font-weight: bold; -} - -.admin,a.admin,a.admin:visited{ - color: #FFA34F; -} - -/* This is the border line & background colour round the entire page */ -.bodyline{ - background: #FFFFFF; - border: 1px solid #98AAB1; -} - -.center{ - text-align: center; -} - -/* Code blocks */ -.code{ - background: #FAFAFA; - border: 1px solid #D1D7DC; - color: #006600; - font: 12px Courier,"Courier New",sans-serif; - padding: 5px; -} - -/* This is for the error messages that pop up */ -.errorline{ - background: #E5E6E2; - border: 1px solid #8F8B8B; - color:#D92A2A; -} - -.explaintitle{ - color: #5C81B1; - font-size: 11px; - font-weight: bold; -} - -/* This is the outline round the main forum tables */ -.forumline{ - background: #FFFFFF; -} - -/* General text */ -.gensmall{ - font-size: 10px; -} - -.h1-font{ - color: #006699; - display: inline; - font: bold 13px Verdana, Arial, Helvetica, sans-serif; - margin: 0; - text-decoration: none; -} - -.h2-font{ - display: inline; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.height1{ - height: 1px; -} - -.height22{ - height: 22px; -} - -.height25{ - height: 25px; -} - -.height28{ - height: 28px; -} - -.height30{ - height: 30px; -} - -.height40{ - height: 40px; -} - -/* This is the line in the posting page which shows the rollover -help line. Colour value in row2 */ -.helpline{ - border: 0 solid; - font-size: 10px; -} - -.imgfolder{ - margin: 1px 4px 1px 4px; -} - -.imgspace{ - margin-left: 1px; - margin-right: 2px; -} - -/* Specify the space around images */ -.imgtopic,.imgicon{ - margin-left: 3px; -} - -.left{ - text-align: left; -} - -/* The largest text used in the index page title and toptic title etc. */ -.maintitle,h1,h2{ - color: #5C81B1; - font: bold 20px/120% "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif; - text-decoration: none; -} - -.maxwidth{ - width: 100%; -} - -.mod,a.mod,a.mod:visited{ - color: #006600; -} - -/* Name of poster in viewmsg.php and viewtopic.php and other places */ -.name{ - font-size: 11px; - font-weight: bold; -} - -/* Used for the navigation text,(Page 1,2,3 etc) and the navigation bar when in a forum */ -.nav{ - font-size: 11px; - font-weight: bold; -} - -.nowrap{ - white-space: nowrap; -} - -.postbody{ - font-size: 12px; - line-height: 125%; -} - -.postbody a{ - text-decoration: underline; -} - -/* Location,number of posts,post date etc */ -.postdetails{ - color: #00396A; - font-size: 10px; -} - -/* Quote blocks */ -.quote{ - background: #F3F3EF; - border: 1px solid #C2C6BA; - color: #006699; - font-size: 11px; - line-height: 125%; -} - -.right{ - text-align: right; -} - -/* Main table cell colours and backgrounds */ -.row1{ - background: #F0F0EB; -} - -.row2,.helpline{ - background: #E5E6E2; -} - -.row3{ - background: #DBDBD4; -} - -.subtitle,h2{ - font: bold 18px/180% "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif; - text-decoration: none; -} - -/* titles for the topics:could specify viewed link colour too */ -.topictitle { - color: #000000; - font-size: 11px; - font-weight: bold; -} - -.underline{ - text-decoration: underline; -} - -.top{ -vertical-align:top; -} - -.image-hspace{ -margin-right:3px; -} - -.clear{ -clear:both; -} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.min.css deleted file mode 100644 index f59b15a92..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/subsilver.min.css +++ /dev/null @@ -1,18 +0,0 @@ -.float-l{float:left}.form-suggest{height:200px;background:#DEE2D0;vertical-align:top}.form-input -input{font-size:10px}.hide{display:none}.form-input -textarea{font-size:11px;width:350px}.form-label{font-size:10px;font-weight:bold;line-height:25px;padding-right:10px;text-align:right;width:100px;color:#39738F}.font-9{font-size:9px}.form-topic{font-weight:bold}.form-error{color:red}.inline{display:inline}.space-10{clear:both;font-size:10px;height:10px;line-height:10px}.suggest-success{color:green;padding-left:10px;font-size:11px;font-weight:bold}.top{vertical-align:top}table -td{padding:3px}a:link,a:active,a:visited,a.postlink{color:#069;text-decoration:none}a:hover{color:#DD6900}a.admin:hover,a.mod:hover{color:#DD6900}a.but,a.but:hover,a.but:visited{color:#000;text-decoration:none}a.topictitle:visited{color:#5493B4}a.topictitle:hover{color:#DD6900}body{color:#000;font:11px Verdana,Arial,Helvetica,sans-serif;margin:0 -10px 10px 10px;padding:0;overflow:auto}font,th,td,p{font:12px Verdana,Arial,Helvetica,sans-serif}form{display:inline}hr{border:0px -solid #FFF;border-top-width:1px;height:0px}img{border:0 -solid}input{font:11px Verdana,Arial,Helvetica,sans-serif}input.button,input.liteoption,.fakebut{background:#FAFAFA;border:1px -solid #000;font-size:11px}input.catbutton{background:#FAFAFA;border:1px -solid #000;font-size:10px}input.mainoption{background:#FAFAFA;border:1px -solid #000;font-size:11px;font-weight:bold}input.post,textarea.post{background:#FFF;border:1px -solid #000;font:11px Verdana,Arial,Helvetica,sans-serif;padding-bottom:2px;padding-left:2px}select{background:#FFF;font:11px Verdana,Arial,Helvetica,sans-serif}table{text-align:left}td{vertical-align:middle}td.cat{background-color:#C2C6BA;font-weight:bold;height:20px;letter-spacing:1px;text-indent:4px}td.genmed,.genmed{font-size:11px}td.rowpic{background:#C2C6BA}td.spacerow{background:#E5E6E2}th{background-color:#FADD31;background-image:url(images/cellpic3.gif);background-repeat:repeat-x;color:#68685E;font-size:11px;font-weight:bold;line-height:16px;height:16px;padding-left:8px;padding-right:8px;text-align:center;white-space:nowrap}.admin,.mod{font-size:11px;font-weight:bold}.admin,a.admin,a.admin:visited{color:#FFA34F}.bodyline{background:#FFF;border:1px -solid #98AAB1}.center{text-align:center}.code{background:#FAFAFA;border:1px -solid #D1D7DC;color:#060;font:12px Courier,"Courier New",sans-serif;padding:5px}.errorline{background:#E5E6E2;border:1px -solid #8F8B8B;color:#D92A2A}.explaintitle{color:#5C81B1;font-size:11px;font-weight:bold}.forumline{background:#FFF}.gensmall{font-size:10px}.h1-font{color:#069;display:inline;font:bold 13px Verdana,Arial,Helvetica,sans-serif;margin:0;text-decoration:none}.h2-font{display:inline;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.height1{height:1px}.height22{height:22px}.height25{height:25px}.height28{height:28px}.height30{height:30px}.height40{height:40px}.helpline{border:0 -solid;font-size:10px}.imgfolder{margin:1px -4px 1px 4px}.imgspace{margin-left:1px;margin-right:2px}.imgtopic,.imgicon{margin-left:3px}.left{text-align:left}.maintitle,h1,h2{color:#5C81B1;font:bold 20px/120% "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;text-decoration:none}.maxwidth{width:100%}.mod,a.mod,a.mod:visited{color:#060}.name{font-size:11px;font-weight:bold}.nav{font-size:11px;font-weight:bold}.nowrap{white-space:nowrap}.postbody{font-size:12px;line-height:125%}.postbody -a{text-decoration:underline}.postdetails{color:#00396A;font-size:10px}.quote{background:#F3F3EF;border:1px -solid #C2C6BA;color:#069;font-size:11px;line-height:125%}.right{text-align:right}.row1{background:#F0F0EB}.row2,.helpline{background:#E5E6E2}.row3{background:#DBDBD4}.subtitle,h2{font:bold 18px/180% "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;text-decoration:none}.topictitle{color:#000;font-size:11px;font-weight:bold}.underline{text-decoration:underline}.top{vertical-align:top}.image-hspace{margin-right:3px}.clear{clear:both} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.css deleted file mode 100644 index 69fa756eb..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.css +++ /dev/null @@ -1,10 +0,0 @@ -/* test unusual, but valid strings in CSS */ - -foo[attr="multiple spaces"] { - content: "Hello World!"; -} - -foo[attr="Hel\ -lo"] { - content: " \"World\""; -} diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.min.css deleted file mode 100644 index 4b7d97e45..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/unusual_strings.min.css +++ /dev/null @@ -1,2 +0,0 @@ -foo[attr="multiple spaces"]{content:"Hello World!"}foo[attr="Hel\ -lo"]{content:" \"World\""} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.css deleted file mode 100644 index 819835e58..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.css +++ /dev/null @@ -1,658 +0,0 @@ -/* from http://www.vladimirated.com/web-development-minify-css-using-php-and-cssmin-class */ - - #comments_inviter #close_me { - clear: both; - text-align: center; - border-top: 1px solid #eeeeee; - padding-top: 10px; - } - - #comments_inviter #close_me span { - color: #108eed; - cursor: pointer; - font-weight: bold; - } - - #comments_inviter img { - float: left; - margin-right: 3px; - margin-bottom: 10px; - } - - #comments_inviter { - width: 200px; - background-color: #FFFFFF; - border: 4px solid #eeeeee; - font-size: 10px; - font-family: verdana; - padding: 10px; - color: #333333; - } - - .one_com { - background-color: #FAFAFA; - padding: 10px; - margin-bottom: 20px; - border: 1px solid #EEEEEE; - } - - .one_com .com_says, .one_com .com_det { - text-transform: lowercase; - color: #333333; - padding: 0px; - font-family: verdana; - margin: 0px; - font-size: 13px; - font-weight: bold; - } - - .flvPlayer { - text-align: center; - border: 5px solid #dddddd; - width: 320px; - } - - .one_com .com_det { - font-size: 10px; - font-weight: normal; - margin-bottom: 20px; - padding-bottom: 10px; - border-bottom: 8px solid #eeeeee; - } - - .one_com .com_det a { - text-decoration: none; - } - - .one_com .com_txt { - background-color: #ffffff; - margin-bottom: 10px; - border-bottom: 2px solid #eeeeee - } - - .one_com .com_txt p { - font-family: verdana; - font-size: 13px; - color: #777777; - margin: 0px; - padding: 5px; - padding-bottom: 10px; - text-transform: lowercase; - } - - .one_com .com_says a { - color: #333333; - } - - .one_com .com_det a { - color: #333333; - } - - .post_box .related_posts { - - } - - .post_box .related_posts p { - padding: 0px; - margin: 0px; - padding-bottom: 20px; - padding-left: 35px; - font-family: verdana; - - } - - .post_box .related_posts a { - color: #108eed; - } - - .post_nav_2 p { - - text-align: center; - color: #cccccc; - font-family: verdana; - } - - .post_box .related_posts h3, #comments_box #respond, .comments_posted h3 { - padding: 0px; - margin: 0px; - font-size: 18px; - color: #FF8000; - padding-top: 30px; - margin-bottom: 20px; - width: 300px; - border-bottom: 5px solid #e0e0e0; - } - - .comments_posted { - - margin-bottom: 50px; - - } - - .comments_posted h3 { - padding: 0px; - margin: 0px; - margin-bottom: 20px; - - } - - .cmt_txtarea { - width: 300px; - height: 100px; - - } - - #comments_box #respond { - - padding-top: 0px; - margin-bottom: 0px; - - } - - .pagetitle { - color: #65DA33; - text-align: center; - } - - #searchform { - padding: 0px; - margin: 0px; - } - - .si { - background-color: #FFFFEE; - border: 1px solid #e0e0e0; - } - - #rightcol #r_news, #rightcol #linksbro, #rightcol #quick_tags { - margin-top: 30px; - padding-bottom: 10px; - } - - #post_nav p { - padding: 0px; - margin: 0px; - padding-bottom: 5px; - } - - #post_nav { - text-align: left; - padding-bottom: 15px; - } - - #post_nav a, .post_nav_2 p a { - text-decoration: none; - font-family: Verdana; - font-size: 12px; - color: #108eed; - } - - #post_nav a:hover, .post_nav_2 p a:hover { - text-decoration: underline; - color: #FF8000; - } - - #rightcol #about { - padding-bottom: 10px; - } - - #rightcol #r_news input { - color: #333333; - font-size: 12px; - } - - #header { - height: 200px; - width: 100%; - background-image: url('images/header_bg.jpg'); - background-repeat: x-repeat; - } - - #header img { - - float: right; - margin-right: -3px; - z-index: 100; - - } - - .tags { - text-transform: lowercase; - color: #333333; - font-family: arial; - font-size: 12px; - border-top: 2px dotted #EEEEEE; - width: 300px; - padding-top: 20px; - padding-bottom: 0px; - margin-top: 0px; - padding-left: 20px; - padding-right: 20px; - } - - .tags a { - color: #108eed; - } - - .tags p { - text-align: left; - margin: 0px; - padding: 0px; - } - - blockquote strong { - font-family: verdana; - display: block; - margin-top: 10px; - color: #FF0000; - font-style: italic; - text-align: right; - } - - blockquote { - margin: 0px; - background-color: #eeeeee; - border: 2px solid #dddddd; - padding: 24px; - padding-top: 10px; - padding-left: 60px; - padding-bottom: 10px; - font-size: 13px; - color: #333333; - margin-bottom: 30px; - margin-top: 10px; - } - - - html>body #header img { margin-right: 0px; } - - #subscribe h3 { - color: #ff0000; - margin-top: 30px; - padding: 20px; - } - - .post_actions a{ - color: #108eed; - } - - .post_actions { - border-top: 4px solid #DDDDDD; - border-bottom: 1px solid #EEEEEE; - text-align: center; - background-color: #FFFFDd; - color: #dddddd; - white-space: no-wrap; - padding-left: 20px; - padding-bottom: 5px; - text-transform: capitalize; - } - - #subscribe td { - color: #333333; - font-size: 12px; - text-transform: lowercase; - } - - #subscribe input { - font-size: 13px; - color: #333333; - } - - .post_content { - font-size: 13px; - margin-top: 10px; - padding-bottom: 10px; - text-align: justify; - font-family: verdana; - } - - .post_content p { - margin: 0px; - padding: 0px; - padding-bottom: 20px; - line-height: 20px; - } - - #header h1 { - z-index: 200; - margin: 0px; - position: absolute; - float: left; - text-transform: lowercase; - padding: 0px; - font-size: 45px; - margin-top: 70px; - margin-left: 40px; - - } - - #header h1 a { - white-space: no-wrap; - text-decoration: none; - color: #FAFAFA; - display: block - } - - #header h1 a:hover { - color: #FAFAFA; - border-bottom: 3px dotted #FAFAFA; - } - - html>body #header h1 { margin-left: 60px; } - - body { - margin: 0px; - padding: 0px; - height: 100%; - width: 100%; - font-family: 'Lucida Sans Unicode', 'Lucida Grande', Sans-Serif, Verdana, Arial; - font-size: 12px; - } - - #leftcol { - float: left; - width: 200px; - margin-left: 0px; - margin-top: 17px; - color: #000; - padding: 3px; - height: 100%; - } - - #leftcol .box_head h3 { - text-transform: uppercase; - padding: 0px; - margin: 0px; - font-family: georgia; - font-size: 18px; - color: #dddddd; - border-top: 4px solid #dddddd; - border-bottom: 4px solid #cccccc; - padding-left: 10px; - padding-top: 10px; - padding-bottom: 10px; - background-image: url('images/stripesbg.png'); - margin-bottom: 10px; - } - - #leftcol .box_head input { - text-transform: lowercase; - color: #333333; - } - - #leftcol .box_head { - margin-left: 7px; - background-color: #ffefd4; - border-bottom: 2px solid #eeeeee; - padding-bottom: 20px; - margin-bottom: 30px; - } - - #leftcol .box_head p a { - color: #0a2d4d; - display: block; - text-decoration: none; - border-bottom: 3px solid #fefefe; - padding-top: 20px; - text-transform: lowercase; - padding-bottom: 20px; - padding-left: 5px; - padding-right: 5px; - } - - #leftcol .box_head p a:hover { - background-color: #fafafa; - border-bottom: 3px solid #eeeeee; - color: #000000; - } - - #leftcol .box_head p { - text-align: left; - margin: 0px; - width: 170px; - padding-bottom: 0px; - padding-top: 0px; - font-size: 11px; - } - - #rightcol { - position: absolute; - left: 77%; - top: 278px; - border: 3px solid #eeeeee; - width: 200px; - z-index: 3; - color: #333333; - padding: 10px; - text-transform: lowercase; - - } - - #rightcol p { - padding: 0px; - marging: 0px; - text-align: justify; - } - - #rightcol #about img, #rightcol #linksbro img { - border: 5px solid #eeeeee; - } - - #rightcol #about h3, #rightcol #r_news h3, #rightcol #linksbro h3, #rightcol #quick_tags h3 { - background-color: #fafafa; - border: 1px dotted #e0e0e0; - font-size: 14px; - color: #104bbc; - padding: 5px; - padding-top: 10px; - font-family: Arial; - padding-bottom: 10px; - } - - #rightcol #about p a, #rightcol #r_news p a, #rightcol #linksbro p a { - color: #108eed; - } - - #rightcol #about p, #rightcol #r_news p, #rightcol #linksbro p { - font-size: 12px; - text-align: left; - } - - #content_warp { - margin: 20px 25% 0 215px; - padding: 3px; - color: #000; - background-color: #ededed; - } - - #content { - margin: 5px; - background-color: #FFFFFF; - padding: 10px; - } - - - #footer { - width: 99%; - margin-top: 30px; - height: 98px; - background-color: #101b1d; - } - - #footer td a { - color: #FF8000; - } - - #footer td a img { - border: 2px solid #108eed; - } - - #footer td p { - font-family: Verdana; - font-size: 10px; - color: #c0c0c0; - padding: 0px; - margin: 0px; - text-align: center; - padding-bottom: 10px; - } - - .s_offer { - color: #65DA33; - font-size: 20px; - font-weight: bold; - font-style: normal; - } - - .post_box { - text-transform: lowercase; - margin-bottom: 40px; - } - - #newsletter_box { - text-transform: lowercase; - margin-bottom: 10px; - margin-top: 30px; - font-style: normal; - background-color: #ffffff; - border: 5px solid #dddddd; - } - - #newsletter_head { - color: #EEEEEE; - font-family: Georgia; - background-image: url('images/stripesbg.png'); - padding: 10px; - padding-left: 30px; - border-bottom: 5px solid #dddddd; - } - - #newsletter_body { - color: #333333; - font-family: Verdana; - text-align: justify; - background-color: #FFFFFF; - padding: 10px; - font-size: 13px; - } - - .s_offer { - color: #65DA33; - font-size: 26px; - font-weight: bold; - font-style: normal; - } - - .post_title a { - color: #EEEEEE; - text-decoration: none; - } - - .post_title a:hover { - color: #c0c0c0; - } - - .post_title { - background-image: url('images/stripe_post.png'); - text-transform: uppercase; - font-size: 18px; - font-family: georgia; - padding: 10px; - border-top: 4px solid #c0c0c0; - margin: 0px; - border-bottom: 2px solid #ffffdd; - } - - .post_det { - text-transform: none; - margin: 0px; - border-top: 1px solid #f0f0f0; - padding: 0px; - padding-top: 5px; - color: #999999; - font-size: 10px; - font-family: verdana; - margin-bottom: 20px; - background-color: #eeeeee; - padding-bottom: 5px; - padding-left: 10px; - text-align: left; - border-bottom: 2px solid #dddddd; - } - - .post_det a { - color: #999999; - text-decoration: none; - } - - - .subtle { - text-transform: lowercase; - font-size: 10px; - font-family: verdana; - color: #108eed; - text-align: justify; - } - - #top_menu #navlist, #top_menu #navlist li { - padding:0px; - margin: 0px; - padding-top: 14px; - text-transform: lowercase; - padding-bottom: 17px; - padding-left: 30px; - border-left: 1px solid #65cdef; - } - - #top_menu #navlist, #top_menu #navlist li #first { - - border-left: 0px; - - } - - #top_menu #navlist { - padding-left: 30px; - background-color: #1dabd9; - border-top: 5px solid #0e96c3; - border-bottom: 5px solid #0e96c3; - } - - #top_menu #navlist li { - color: #444444; - font-size: 10px; - display: inline; - list-style-type: none; - padding-right: 30px; - } - - #top_menu #navlist li a { - text-decoration: none; - font-family: Verdana; - color: #fafafa; - font-size: 12px; - font-weight: bold; - } - - #top_menu #navlist li a:hover { - color: #333333; - } - - .post_content a { - color: #108eed; - } - - ul#tagcloud { padding:0; margin:0; text-align:center; list-style:none; } - ul#tagcloud li { display:inline; font-size:70%; color:#ccc; background: none; padding: 0;} - ul#tagcloud li a, ul#tagcloud li a:link { text-decoration:none; } - ul#tagcloud li a:hover { text-decoration:underline; } - ul#tagcloud li.t1 a { color:#797979; font-size: 120%; } - ul#tagcloud li.t2 a { color:#6d6d6d; font-size: 160%; } - ul#tagcloud li.t3 a { color:#616161; font-size: 190%; } - ul#tagcloud li.t4 a { color:#555555; font-size: 210%; } - ul#tagcloud li.t5 a { color:#484848; font-size: 230%; } - ul#tagcloud li.t6 a { color:#3c3c3c; font-size: 250%; } - ul#tagcloud li.t7 a { color:#303030; font-size: 270%; } - ul#tagcloud li.t8 a { color:#242424; font-size: 290%; } - ul#tagcloud li.t9 a { color:#181818; font-size: 310%; } - ul#tagcloud li.t10 a { color:#0c0c0c; font-size: 330%; } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.min.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.min.css deleted file mode 100644 index eaffaee38..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css/vladmirated.min.css +++ /dev/null @@ -1,79 +0,0 @@ -#comments_inviter -#close_me{clear:both;text-align:center;border-top:1px solid #eee;padding-top:10px}#comments_inviter #close_me -span{color:#108eed;cursor:pointer;font-weight:bold}#comments_inviter -img{float:left;margin-right:3px;margin-bottom:10px}#comments_inviter{width:200px;background-color:#FFF;border:4px -solid #eee;font-size:10px;font-family:verdana;padding:10px;color:#333}.one_com{background-color:#FAFAFA;padding:10px;margin-bottom:20px;border:1px -solid #EEE}.one_com .com_says, .one_com -.com_det{text-transform:lowercase;color:#333;padding:0px;font-family:verdana;margin:0px;font-size:13px;font-weight:bold}.flvPlayer{text-align:center;border:5px -solid #ddd;width:320px}.one_com -.com_det{font-size:10px;font-weight:normal;margin-bottom:20px;padding-bottom:10px;border-bottom:8px solid #eee}.one_com .com_det -a{text-decoration:none}.one_com -.com_txt{background-color:#fff;margin-bottom:10px;border-bottom:2px solid #eee}.one_com .com_txt -p{font-family:verdana;font-size:13px;color:#777;margin:0px;padding:5px;padding-bottom:10px;text-transform:lowercase}.one_com .com_says -a{color:#333}.one_com .com_det -a{color:#333}.post_box -.related_posts{}.post_box .related_posts -p{padding:0px;margin:0px;padding-bottom:20px;padding-left:35px;font-family:verdana}.post_box .related_posts -a{color:#108eed}.post_nav_2 -p{text-align:center;color:#ccc;font-family:verdana}.post_box .related_posts h3, #comments_box #respond, .comments_posted -h3{padding:0px;margin:0px;font-size:18px;color:#FF8000;padding-top:30px;margin-bottom:20px;width:300px;border-bottom:5px solid #e0e0e0}.comments_posted{margin-bottom:50px}.comments_posted -h3{padding:0px;margin:0px;margin-bottom:20px}.cmt_txtarea{width:300px;height:100px}#comments_box -#respond{padding-top:0px;margin-bottom:0px}.pagetitle{color:#65DA33;text-align:center}#searchform{padding:0px;margin:0px}.si{background-color:#FFE;border:1px -solid #e0e0e0}#rightcol #r_news, #rightcol #linksbro, #rightcol -#quick_tags{margin-top:30px;padding-bottom:10px}#post_nav -p{padding:0px;margin:0px;padding-bottom:5px}#post_nav{text-align:left;padding-bottom:15px}#post_nav a, .post_nav_2 p -a{text-decoration:none;font-family:Verdana;font-size:12px;color:#108eed}#post_nav a:hover, .post_nav_2 p a:hover{text-decoration:underline;color:#FF8000}#rightcol -#about{padding-bottom:10px}#rightcol #r_news -input{color:#333;font-size:12px}#header{height:200px;width:100%;background-image:url('images/header_bg.jpg');background-repeat:x-repeat}#header -img{float:right;margin-right: -3px;z-index:100}.tags{text-transform:lowercase;color:#333;font-family:arial;font-size:12px;border-top:2px dotted #EEE;width:300px;padding-top:20px;padding-bottom:0px;margin-top:0px;padding-left:20px;padding-right:20px}.tags -a{color:#108eed}.tags -p{text-align:left;margin:0px;padding:0px}blockquote -strong{font-family:verdana;display:block;margin-top:10px;color:#F00;font-style:italic;text-align:right}blockquote{margin:0px;background-color:#eee;border:2px -solid #ddd;padding:24px;padding-top:10px;padding-left:60px;padding-bottom:10px;font-size:13px;color:#333;margin-bottom:30px;margin-top:10px}html>body #header -img{margin-right:0px}#subscribe -h3{color:#f00;margin-top:30px;padding:20px}.post_actions -a{color:#108eed}.post_actions{border-top:4px solid #DDD;border-bottom:1px solid #EEE;text-align:center;background-color:#FFD;color:#ddd;white-space:no-wrap;padding-left:20px;padding-bottom:5px;text-transform:capitalize}#subscribe -td{color:#333;font-size:12px;text-transform:lowercase}#subscribe -input{font-size:13px;color:#333}.post_content{font-size:13px;margin-top:10px;padding-bottom:10px;text-align:justify;font-family:verdana}.post_content -p{margin:0px;padding:0px;padding-bottom:20px;line-height:20px}#header -h1{z-index:200;margin:0px;position:absolute;float:left;text-transform:lowercase;padding:0px;font-size:45px;margin-top:70px;margin-left:40px}#header h1 -a{white-space:no-wrap;text-decoration:none;color:#FAFAFA;display:block}#header h1 a:hover{color:#FAFAFA;border-bottom:3px dotted #FAFAFA}html>body #header -h1{margin-left:60px}body{margin:0px;padding:0px;height:100%;width:100%;font-family:'Lucida Sans Unicode','Lucida Grande',Sans-Serif,Verdana,Arial;font-size:12px}#leftcol{float:left;width:200px;margin-left:0px;margin-top:17px;color:#000;padding:3px;height:100%}#leftcol .box_head -h3{text-transform:uppercase;padding:0px;margin:0px;font-family:georgia;font-size:18px;color:#ddd;border-top:4px solid #ddd;border-bottom:4px solid #ccc;padding-left:10px;padding-top:10px;padding-bottom:10px;background-image:url('images/stripesbg.png');margin-bottom:10px}#leftcol .box_head -input{text-transform:lowercase;color:#333}#leftcol -.box_head{margin-left:7px;background-color:#ffefd4;border-bottom:2px solid #eee;padding-bottom:20px;margin-bottom:30px}#leftcol .box_head p -a{color:#0a2d4d;display:block;text-decoration:none;border-bottom:3px solid #fefefe;padding-top:20px;text-transform:lowercase;padding-bottom:20px;padding-left:5px;padding-right:5px}#leftcol .box_head p a:hover{background-color:#fafafa;border-bottom:3px solid #eee;color:#000}#leftcol .box_head -p{text-align:left;margin:0px;width:170px;padding-bottom:0px;padding-top:0px;font-size:11px}#rightcol{position:absolute;left:77%;top:278px;border:3px -solid #eee;width:200px;z-index:3;color:#333;padding:10px;text-transform:lowercase}#rightcol -p{padding:0px;marging:0px;text-align:justify}#rightcol #about img, #rightcol #linksbro -img{border:5px -solid #eee}#rightcol #about h3, #rightcol #r_news h3, #rightcol #linksbro h3, #rightcol #quick_tags -h3{background-color:#fafafa;border:1px -dotted #e0e0e0;font-size:14px;color:#104bbc;padding:5px;padding-top:10px;font-family:Arial;padding-bottom:10px}#rightcol #about p a, #rightcol #r_news p a, #rightcol #linksbro p -a{color:#108eed}#rightcol #about p, #rightcol #r_news p, #rightcol #linksbro -p{font-size:12px;text-align:left}#content_warp{margin:20px -25% 0 215px;padding:3px;color:#000;background-color:#ededed}#content{margin:5px;background-color:#FFF;padding:10px}#footer{width:99%;margin-top:30px;height:98px;background-color:#101b1d}#footer td -a{color:#FF8000}#footer td a -img{border:2px -solid #108eed}#footer td -p{font-family:Verdana;font-size:10px;color:#c0c0c0;padding:0px;margin:0px;text-align:center;padding-bottom:10px}.s_offer{color:#65DA33;font-size:20px;font-weight:bold;font-style:normal}.post_box{text-transform:lowercase;margin-bottom:40px}#newsletter_box{text-transform:lowercase;margin-bottom:10px;margin-top:30px;font-style:normal;background-color:#fff;border:5px -solid #ddd}#newsletter_head{color:#EEE;font-family:Georgia;background-image:url('images/stripesbg.png');padding:10px;padding-left:30px;border-bottom:5px solid #ddd}#newsletter_body{color:#333;font-family:Verdana;text-align:justify;background-color:#FFF;padding:10px;font-size:13px}.s_offer{color:#65DA33;font-size:26px;font-weight:bold;font-style:normal}.post_title -a{color:#EEE;text-decoration:none}.post_title a:hover{color:#c0c0c0}.post_title{background-image:url('images/stripe_post.png');text-transform:uppercase;font-size:18px;font-family:georgia;padding:10px;border-top:4px solid #c0c0c0;margin:0px;border-bottom:2px solid #ffd}.post_det{text-transform:none;margin:0px;border-top:1px solid #f0f0f0;padding:0px;padding-top:5px;color:#999;font-size:10px;font-family:verdana;margin-bottom:20px;background-color:#eee;padding-bottom:5px;padding-left:10px;text-align:left;border-bottom:2px solid #ddd}.post_det -a{color:#999;text-decoration:none}.subtle{text-transform:lowercase;font-size:10px;font-family:verdana;color:#108eed;text-align:justify}#top_menu #navlist, #top_menu #navlist -li{padding:0px;margin:0px;padding-top:14px;text-transform:lowercase;padding-bottom:17px;padding-left:30px;border-left:1px solid #65cdef}#top_menu #navlist, #top_menu #navlist li -#first{border-left:0px}#top_menu -#navlist{padding-left:30px;background-color:#1dabd9;border-top:5px solid #0e96c3;border-bottom:5px solid #0e96c3}#top_menu #navlist -li{color:#444;font-size:10px;display:inline;list-style-type:none;padding-right:30px}#top_menu #navlist li -a{text-decoration:none;font-family:Verdana;color:#fafafa;font-size:12px;font-weight:bold}#top_menu #navlist li a:hover{color:#333}.post_content -a{color:#108eed}ul#tagcloud{padding:0;margin:0;text-align:center;list-style:none}ul#tagcloud -li{display:inline;font-size:70%;color:#ccc;background:none;padding:0}ul#tagcloud li a, ul#tagcloud li a:link{text-decoration:none}ul#tagcloud li a:hover{text-decoration:underline}ul#tagcloud li.t1 -a{color:#797979;font-size:120%}ul#tagcloud li.t2 -a{color:#6d6d6d;font-size:160%}ul#tagcloud li.t3 -a{color:#616161;font-size:190%}ul#tagcloud li.t4 -a{color:#555;font-size:210%}ul#tagcloud li.t5 -a{color:#484848;font-size:230%}ul#tagcloud li.t6 -a{color:#3c3c3c;font-size:250%}ul#tagcloud li.t7 -a{color:#303030;font-size:270%}ul#tagcloud li.t8 -a{color:#242424;font-size:290%}ul#tagcloud li.t9 -a{color:#181818;font-size:310%}ul#tagcloud li.t10 -a{color:#0c0c0c;font-size:330%} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/exp.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/exp.css deleted file mode 100644 index d749295b7..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/exp.css +++ /dev/null @@ -1,14 +0,0 @@ -@import "/_test_files/css_uriRewriter/foo.css"; -@import '/_test_files/css_uriRewriter/bar/foo.css' print; -@import '/_test_files/bar/foo.css' print; -@import '/foo.css' print; -@import '/css/foo.css'; /* abs, should not alter */ -@import 'http://foo.com/css/foo.css'; /* abs, should not alter */ -@import url(/_test_files/foo.css) tv, projection; -@import url("/css/foo.css"); /* abs, should not alter */ -@import url(/css2/foo.css); /* abs, should not alter */ -@import url(data:image/gif;base64,AAAA); /* data, should not alter */ -foo {background:url('/_test_files/css_uriRewriter/bar/foo.png')} -foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */ -foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */ -foo {background:url(data:image/gif;base64,AAAA);} /* data, should not alter */ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/in.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/in.css deleted file mode 100644 index aa41d0a91..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/css_uriRewriter/in.css +++ /dev/null @@ -1,14 +0,0 @@ -@import "foo.css"; -@import 'bar/foo.css' print; -@import '../bar/foo.css' print; -@import '../../foo.css' print; -@import '/css/foo.css'; /* abs, should not alter */ -@import 'http://foo.com/css/foo.css'; /* abs, should not alter */ -@import url(../foo.css) tv, projection; -@import url("/css/foo.css"); /* abs, should not alter */ -@import url(/css2/foo.css); /* abs, should not alter */ -@import url(data:image/gif;base64,AAAA); /* data, should not alter */ -foo {background:url('bar/foo.png')} -foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */ -foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */ -foo {background:url(data:image/gif;base64,AAAA);} /* data, should not alter */ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.html b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.html deleted file mode 100644 index c22cc8f20..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - css Zen Garden: The Beauty in CSS Design - - - - - - - - - - - - -

    Browser != IE

    -
    - -
    -	White  space  is  important   here!
    -		
    -
    -

    A demonstration of what can be accomplished visually through CSS-based design. Select any style sheet from the list to load it into this page.

    -

    Download the sample html file and css file

    -
    - -
    - - \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.min.html b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.min.html deleted file mode 100644 index 58ba2bb98..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before.min.html +++ /dev/null @@ -1,36 +0,0 @@ -css Zen Garden: The Beauty in CSS Design

    Browser != IE

    css Zen Garden

    The Beauty of CSS Design

    -	White  space  is  important   here!
    -		

    A demonstration of what can be accomplished visually through CSS-based design. Select any style sheet from the list to load it into this page.

    Download the sample html file and css file

    \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.html b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.html deleted file mode 100644 index 4ca7f199e..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - css Zen Garden: The Beauty in CSS Design - - - - - - - - - - - - -

    Browser != IE

    -
    - -
    -	White  space  is  important   here!
    -		
    -
    -

    A demonstration of what can be accomplished visually through CSS-based design. Select any style sheet from the list to load it into this page.

    -

    Download the sample html file and css file

    -
    - -Preserve at least 1 char of whitespace near scripts in case of document.write(). -
    - - \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.min.html b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.min.html deleted file mode 100644 index ae28465bc..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/html/before2.min.html +++ /dev/null @@ -1,36 +0,0 @@ -css Zen Garden: The Beauty in CSS Design

    Browser != IE

    css Zen Garden

    The Beauty of CSS Design

    -	White  space  is  important   here!
    -		

    A demonstration of what can be accomplished visually through CSS-based design. Select any style sheet from the list to load it into this page.

    Download the sample html file and css file

    Preserve at least 1 char of whitespace near scripts in case of document.write().
    \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/adjacent.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/adjacent.css deleted file mode 100644 index da52c6949..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/adjacent.css +++ /dev/null @@ -1,3 +0,0 @@ -/* @import url('bad.css' ) bad; */ -adjacent2 foo { background: red url(/red.gif); } -adjacent2 bar { background: url('../green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/tv.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/tv.css deleted file mode 100644 index 69fa2f5ef..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/1/tv.css +++ /dev/null @@ -1,4 +0,0 @@ -@import url( adjacent.css ) all; -@import '../input.css'; -tv foo { background: red url(/red.gif); } -tv bar { background: url('../green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/adjacent.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/adjacent.css deleted file mode 100644 index b452f473e..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/adjacent.css +++ /dev/null @@ -1,4 +0,0 @@ -@import url(../css/styles.css); -@import url(http://example.com/hello.css); -adjacent foo { background: red url(/red.gif); } -adjacent bar { background: url('../green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/input.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/input.css deleted file mode 100644 index bb7b95951..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/input.css +++ /dev/null @@ -1,4 +0,0 @@ -@import url( adjacent.css ) screen; -@import "1/tv.css" tv, projection; -input foo { background: red url(/red.gif); } -input bar { background: url('../green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/output.css b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/output.css deleted file mode 100644 index 1e4358c25..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/importProcessor/output.css +++ /dev/null @@ -1,48 +0,0 @@ -@media screen { -/* some CSS to try to exercise things in general */ - -@import url(/more.css); - - body, td, th { - font-family: Verdana , "Bitstream Vera Sans" , sans-serif ; - - font-size : 12px; -} - -.nav { - margin-left: 20%; -} -#main-nav { - background-color: red; - border: 1px solid #00ff77; -} - -div#content -h1 + p { - padding-top: 0; - margin-top: 0; -} - -@media all and (min-width: 640px) { - #media-queries-1 { background-color: #0f0; } -} - -@media screen and (max-width: 2000px) { - #media-queries-2 { background-color: #0f0; } -} -@import url(http://example.com/hello.css); -adjacent foo { background: red url(/red.gif); } -adjacent bar { background: url('%TEST_FILES_URI%/green.gif') } -} - -@media tv,projection { -/* @import url('%TEST_FILES_URI%/importProcessor/1/bad.css') bad; */ -adjacent2 foo { background: red url(/red.gif); } -adjacent2 bar { background: url('%TEST_FILES_URI%/importProcessor/green.gif') } -@import '../input.css'; -tv foo { background: red url(/red.gif); } -tv bar { background: url('%TEST_FILES_URI%/importProcessor/green.gif') } -} - -input foo { background: red url(/red.gif); } -input bar { background: url('%TEST_FILES_URI%/green.gif') } \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.js deleted file mode 100644 index cccdb9706..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.js +++ /dev/null @@ -1,57 +0,0 @@ -/*! is.js - - (c) 2001 Douglas Crockford - 2001 June 3 -*/ - -// is - -// The -is- object is used to identify the browser. Every browser edition -// identifies itself, but there is no standard way of doing it, and some of -// the identification is deceptive. This is because the authors of web -// browsers are liars. For example, Microsoft's IE browsers claim to be -// Mozilla 4. Netscape 6 claims to be version 5. - -var is = { - ie: navigator.appName == 'Microsoft Internet Explorer', - java: navigator.javaEnabled(), - ns: navigator.appName == 'Netscape', - ua: navigator.userAgent.toLowerCase(), - version: parseFloat(navigator.appVersion.substr(21)) || - parseFloat(navigator.appVersion), - win: navigator.platform == 'Win32' -} -/*!* - * preserve this comment, too - */ -is.mac = is.ua.indexOf('mac') >= 0; -if (is.ua.indexOf('opera') >= 0) { - is.ie = is.ns = false; - is.opera = true; -} -if (is.ua.indexOf('gecko') >= 0) { - is.ie = is.ns = false; - is.gecko = true; -} - -/*@cc_on - /*@if (@_win32) - if (is.ie && is.win) - document.write("PASS: IE/win honored conditional comment.
    "); - @else @*/ - if (is.ie && is.win) - document.write("FAIL: IE/win did not honor multi-line conditional comment.
    "); - else - document.write("PASS: Non-IE/win browser ignores multi-line conditional comment.
    "); - /*@end -@*/ - -var recognizesCondComm = true; -//@cc_on/* -recognizesCondComm = false; -//@cc_on*/ - -if ((is.ie && is.win) == recognizesCondComm) - document.write("PASS: IE/win honored single-line conditional comment.
    "); -else - document.write("FAIL: Non-IE/win browser did not ignore single-line conditional comment.
    "); diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min.js deleted file mode 100644 index 6f06c6e6c..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/* is.js - - (c) 2001 Douglas Crockford - 2001 June 3 -*/ -var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'} -/** - * preserve this comment, too - */ -is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;} -if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}/*@cc_on - /*@if (@_win32) - if (is.ie && is.win) - document.write("PASS: IE/win honored conditional comment.
    "); - @else @*/if(is.ie&&is.win) -document.write("FAIL: IE/win did not honor multi-line conditional comment.
    ");else -document.write("PASS: Non-IE/win browser ignores multi-line conditional comment.
    ");/*@end -@*/var recognizesCondComm=true;//@cc_on/* -recognizesCondComm=false;//@cc_on*/ -if((is.ie&&is.win)==recognizesCondComm) -document.write("PASS: IE/win honored single-line conditional comment.
    ");else -document.write("FAIL: Non-IE/win browser did not ignore single-line conditional comment.
    "); \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min_plus.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min_plus.js deleted file mode 100644 index 6f06c6e6c..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/before.min_plus.js +++ /dev/null @@ -1,22 +0,0 @@ -/* is.js - - (c) 2001 Douglas Crockford - 2001 June 3 -*/ -var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'} -/** - * preserve this comment, too - */ -is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;} -if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}/*@cc_on - /*@if (@_win32) - if (is.ie && is.win) - document.write("PASS: IE/win honored conditional comment.
    "); - @else @*/if(is.ie&&is.win) -document.write("FAIL: IE/win did not honor multi-line conditional comment.
    ");else -document.write("PASS: Non-IE/win browser ignores multi-line conditional comment.
    ");/*@end -@*/var recognizesCondComm=true;//@cc_on/* -recognizesCondComm=false;//@cc_on*/ -if((is.ie&&is.win)==recognizesCondComm) -document.write("PASS: IE/win honored single-line conditional comment.
    ");else -document.write("FAIL: Non-IE/win browser did not ignore single-line conditional comment.
    "); \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.js deleted file mode 100644 index 28aa1268b..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.js +++ /dev/null @@ -1,14 +0,0 @@ -var isWin; -/*@cc_on - @if (@_win32) - isWin = true; - @else @*/ isWin = false; - /*@end -@*/ - -isWin = /*@cc_on!*/!1; - -var recognizesCondComm = true; -//@cc_on/* -recognizesCondComm = false; -//@cc_on*/ diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.min_plus.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.min_plus.js deleted file mode 100644 index d8c1ed386..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/condcomm.min_plus.js +++ /dev/null @@ -1,13 +0,0 @@ -var isWin; -/*@cc_on - @if (@_win32) - isWin = true; - @else @*/ - isWin = false; - /*@end -@*/ - -var recognizesCondComm = true; -//@cc_on/* -recognizesCondComm = false; -//@cc_on*/ \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.js deleted file mode 100644 index e12eaeb48..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.js +++ /dev/null @@ -1,4 +0,0 @@ - -function testIssue74() { - return /'/; -} diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min.js deleted file mode 100644 index 3442a73fc..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min.js +++ /dev/null @@ -1 +0,0 @@ -function testIssue74(){return /'/;} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min_plus.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min_plus.js deleted file mode 100644 index 9caaa899c..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/issue74.min_plus.js +++ /dev/null @@ -1 +0,0 @@ -function testIssue74(){return /'/} \ No newline at end of file diff --git a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/jquery-1.2.3.js b/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/jquery-1.2.3.js deleted file mode 100644 index c5a333760..000000000 --- a/plugins/Minify/extlib/minify/min_unit_tests/_test_files/js/jquery-1.2.3.js +++ /dev/null @@ -1,3408 +0,0 @@ -(function(){ -/*! - * jQuery 1.2.3 - New Wave Javascript - * - * Copyright (c) 2008 John Resig (jquery.com) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ - * $Rev: 4663 $ - */ - -// Map over jQuery in case of overwrite -if ( window.jQuery ) - var _jQuery = window.jQuery; - -var jQuery = window.jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.prototype.init( selector, context ); -}; - -// Map over the $ in case of overwrite -if ( window.$ ) - var _$ = window.$; - -// Map the jQuery namespace to the '$' one -window.$ = jQuery; - -// A simple way to check for HTML strings or ID strings -// (both of which we optimize for) -var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/; - -// Is it a simple selector -var isSimple = /^.[^:#\[\.]*$/; - -jQuery.fn = jQuery.prototype = { - init: function( selector, context ) { - // Make sure that a selection was provided - selector = selector || document; - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this[0] = selector; - this.length = 1; - return this; - - // Handle HTML strings - } else if ( typeof selector == "string" ) { - // Are we dealing with HTML string or an ID? - var match = quickExpr.exec( selector ); - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) - selector = jQuery.clean( [ match[1] ], context ); - - // HANDLE: $("#id") - else { - var elem = document.getElementById( match[3] ); - - // Make sure an element was located - if ( elem ) - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id != match[3] ) - return jQuery().find( selector ); - - // Otherwise, we inject the element directly into the jQuery object - else { - this[0] = elem; - this.length = 1; - return this; - } - - else - selector = []; - } - - // HANDLE: $(expr, [context]) - // (which is just equivalent to: $(content).find(expr) - } else - return new jQuery( context ).find( selector ); - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) - return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); - - return this.setArray( - // HANDLE: $(array) - selector.constructor == Array && selector || - - // HANDLE: $(arraylike) - // Watch for when an array-like object, contains DOM nodes, is passed in as the selector - (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) || - - // HANDLE: $(*) - [ selector ] ); - }, - - // The current version of jQuery being used - jquery: "1.2.3", - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - // The number of elements contained in the matched element set - length: 0, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == undefined ? - - // Return a 'clean' array - jQuery.makeArray( this ) : - - // Return just the object - this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - // Build a new jQuery matched element set - var ret = jQuery( elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Force the current matched set of elements to become - // the specified array of elements (destroying the stack in the process) - // You should use pushStack() in order to do this, but maintain the stack - setArray: function( elems ) { - // Resetting the length to 0, then using the native Array push - // is a super-fast way to populate an object with array-like properties - this.length = 0; - Array.prototype.push.apply( this, elems ); - - return this; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - var ret = -1; - - // Locate the position of the desired element - this.each(function(i){ - if ( this == elem ) - ret = i; - }); - - return ret; - }, - - attr: function( name, value, type ) { - var options = name; - - // Look for the case where we're accessing a style value - if ( name.constructor == String ) - if ( value == undefined ) - return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined; - - else { - options = {}; - options[ name ] = value; - } - - // Check to see if we're setting style values - return this.each(function(i){ - // Set all the styles - for ( name in options ) - jQuery.attr( - type ? - this.style : - this, - name, jQuery.prop( this, options[ name ], type, i, name ) - ); - }); - }, - - css: function( key, value ) { - // ignore negative width and height values - if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) - value = undefined; - return this.attr( key, value, "curCSS" ); - }, - - text: function( text ) { - if ( typeof text != "object" && text != null ) - return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); - - var ret = ""; - - jQuery.each( text || this, function(){ - jQuery.each( this.childNodes, function(){ - if ( this.nodeType != 8 ) - ret += this.nodeType != 1 ? - this.nodeValue : - jQuery.fn.text( [ this ] ); - }); - }); - - return ret; - }, - - wrapAll: function( html ) { - if ( this[0] ) - // The elements to wrap the target around - jQuery( html, this[0].ownerDocument ) - .clone() - .insertBefore( this[0] ) - .map(function(){ - var elem = this; - - while ( elem.firstChild ) - elem = elem.firstChild; - - return elem; - }) - .append(this); - - return this; - }, - - wrapInner: function( html ) { - return this.each(function(){ - jQuery( this ).contents().wrapAll( html ); - }); - }, - - wrap: function( html ) { - return this.each(function(){ - jQuery( this ).wrapAll( html ); - }); - }, - - append: function() { - return this.domManip(arguments, true, false, function(elem){ - if (this.nodeType == 1) - this.appendChild( elem ); - }); - }, - - prepend: function() { - return this.domManip(arguments, true, true, function(elem){ - if (this.nodeType == 1) - this.insertBefore( elem, this.firstChild ); - }); - }, - - before: function() { - return this.domManip(arguments, false, false, function(elem){ - this.parentNode.insertBefore( elem, this ); - }); - }, - - after: function() { - return this.domManip(arguments, false, true, function(elem){ - this.parentNode.insertBefore( elem, this.nextSibling ); - }); - }, - - end: function() { - return this.prevObject || jQuery( [] ); - }, - - find: function( selector ) { - var elems = jQuery.map(this, function(elem){ - return jQuery.find( selector, elem ); - }); - - return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? - jQuery.unique( elems ) : - elems ); - }, - - clone: function( events ) { - // Do the clone - var ret = this.map(function(){ - if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { - // IE copies events bound via attachEvent when - // using cloneNode. Calling detachEvent on the - // clone will also remove the events from the orignal - // In order to get around this, we use innerHTML. - // Unfortunately, this means some modifications to - // attributes in IE that are actually only stored - // as properties will not be copied (such as the - // the name attribute on an input). - var clone = this.cloneNode(true), - container = document.createElement("div"); - container.appendChild(clone); - return jQuery.clean([container.innerHTML])[0]; - } else - return this.cloneNode(true); - }); - - // Need to set the expando to null on the cloned set if it exists - // removeData doesn't work here, IE removes it from the original as well - // this is primarily for IE but the data expando shouldn't be copied over in any browser - var clone = ret.find("*").andSelf().each(function(){ - if ( this[ expando ] != undefined ) - this[ expando ] = null; - }); - - // Copy the events from the original to the clone - if ( events === true ) - this.find("*").andSelf().each(function(i){ - if (this.nodeType == 3) - return; - var events = jQuery.data( this, "events" ); - - for ( var type in events ) - for ( var handler in events[ type ] ) - jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); - }); - - // Return the cloned set - return ret; - }, - - filter: function( selector ) { - return this.pushStack( - jQuery.isFunction( selector ) && - jQuery.grep(this, function(elem, i){ - return selector.call( elem, i ); - }) || - - jQuery.multiFilter( selector, this ) ); - }, - - not: function( selector ) { - if ( selector.constructor == String ) - // test special case where just one selector is passed in - if ( isSimple.test( selector ) ) - return this.pushStack( jQuery.multiFilter( selector, this, true ) ); - else - selector = jQuery.multiFilter( selector, this ); - - var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; - return this.filter(function() { - return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; - }); - }, - - add: function( selector ) { - return !selector ? this : this.pushStack( jQuery.merge( - this.get(), - selector.constructor == String ? - jQuery( selector ).get() : - selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ? - selector : [selector] ) ); - }, - - is: function( selector ) { - return selector ? - jQuery.multiFilter( selector, this ).length > 0 : - false; - }, - - hasClass: function( selector ) { - return this.is( "." + selector ); - }, - - val: function( value ) { - if ( value == undefined ) { - - if ( this.length ) { - var elem = this[0]; - - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type == "select-one"; - - // Nothing was selected - if ( index < 0 ) - return null; - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - if ( option.selected ) { - // Get the specifc value for the option - value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; - - // We don't need an array for one selects - if ( one ) - return value; - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - - // Everything else, we just grab the value - } else - return (this[0].value || "").replace(/\r/g, ""); - - } - - return undefined; - } - - return this.each(function(){ - if ( this.nodeType != 1 ) - return; - - if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) - this.checked = (jQuery.inArray(this.value, value) >= 0 || - jQuery.inArray(this.name, value) >= 0); - - else if ( jQuery.nodeName( this, "select" ) ) { - var values = value.constructor == Array ? - value : - [ value ]; - - jQuery( "option", this ).each(function(){ - this.selected = (jQuery.inArray( this.value, values ) >= 0 || - jQuery.inArray( this.text, values ) >= 0); - }); - - if ( !values.length ) - this.selectedIndex = -1; - - } else - this.value = value; - }); - }, - - html: function( value ) { - return value == undefined ? - (this.length ? - this[0].innerHTML : - null) : - this.empty().append( value ); - }, - - replaceWith: function( value ) { - return this.after( value ).remove(); - }, - - eq: function( i ) { - return this.slice( i, i + 1 ); - }, - - slice: function() { - return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function(elem, i){ - return callback.call( elem, i, elem ); - })); - }, - - andSelf: function() { - return this.add( this.prevObject ); - }, - - data: function( key, value ){ - var parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value == null ) { - var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - if ( data == undefined && this.length ) - data = jQuery.data( this[0], key ); - - return data == null && parts[1] ? - this.data( parts[0] ) : - data; - } else - return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ - jQuery.data( this, key, value ); - }); - }, - - removeData: function( key ){ - return this.each(function(){ - jQuery.removeData( this, key ); - }); - }, - - domManip: function( args, table, reverse, callback ) { - var clone = this.length > 1, elems; - - return this.each(function(){ - if ( !elems ) { - elems = jQuery.clean( args, this.ownerDocument ); - - if ( reverse ) - elems.reverse(); - } - - var obj = this; - - if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) - obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); - - var scripts = jQuery( [] ); - - jQuery.each(elems, function(){ - var elem = clone ? - jQuery( this ).clone( true )[0] : - this; - - // execute all scripts after the elements have been injected - if ( jQuery.nodeName( elem, "script" ) ) { - scripts = scripts.add( elem ); - } else { - // Remove any inner scripts for later evaluation - if ( elem.nodeType == 1 ) - scripts = scripts.add( jQuery( "script", elem ).remove() ); - - // Inject the elements into the document - callback.call( obj, elem ); - } - }); - - scripts.each( evalScript ); - }); - } -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.prototype.init.prototype = jQuery.prototype; - -function evalScript( i, elem ) { - if ( elem.src ) - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - - else - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); - - if ( elem.parentNode ) - elem.parentNode.removeChild( elem ); -} - -jQuery.extend = jQuery.fn.extend = function() { - // copy reference to target object - var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; - - // Handle a deep copy situation - if ( target.constructor == Boolean ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target != "object" && typeof target != "function" ) - target = {}; - - // extend jQuery itself if only one argument is passed - if ( length == 1 ) { - target = this; - i = 0; - } - - for ( ; i < length; i++ ) - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) - // Extend the base object - for ( var name in options ) { - // Prevent never-ending loop - if ( target === options[ name ] ) - continue; - - // Recurse if we're merging object values - if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType ) - target[ name ] = jQuery.extend( target[ name ], options[ name ] ); - - // Don't bring in undefined values - else if ( options[ name ] != undefined ) - target[ name ] = options[ name ]; - - } - - // Return the modified object - return target; -}; - -var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {}; - -// exclude the following css properties to add px -var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i; - -jQuery.extend({ - noConflict: function( deep ) { - window.$ = _$; - - if ( deep ) - window.jQuery = _jQuery; - - return jQuery; - }, - - // See test/unit/core.js for details concerning this function. - isFunction: function( fn ) { - return !!fn && typeof fn != "string" && !fn.nodeName && - fn.constructor != Array && /function/i.test( fn + "" ); - }, - - // check if an element is in a (or is an) XML document - isXMLDoc: function( elem ) { - return elem.documentElement && !elem.body || - elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; - }, - - // Evalulates a script in a global context - globalEval: function( data ) { - data = jQuery.trim( data ); - - if ( data ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; - if ( jQuery.browser.msie ) - script.text = data; - else - script.appendChild( document.createTextNode( data ) ); - - head.appendChild( script ); - head.removeChild( script ); - } - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); - }, - - cache: {}, - - data: function( elem, name, data ) { - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ]; - - // Compute a unique ID for the element - if ( !id ) - id = elem[ expando ] = ++uuid; - - // Only generate the data cache if we're - // trying to access or manipulate it - if ( name && !jQuery.cache[ id ] ) - jQuery.cache[ id ] = {}; - - // Prevent overriding the named cache with undefined values - if ( data != undefined ) - jQuery.cache[ id ][ name ] = data; - - // Return the named cache data, or the ID for the element - return name ? - jQuery.cache[ id ][ name ] : - id; - }, - - removeData: function( elem, name ) { - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ]; - - // If we want to remove a specific section of the element's data - if ( name ) { - if ( jQuery.cache[ id ] ) { - // Remove the section of cache data - delete jQuery.cache[ id ][ name ]; - - // If we've removed all the data, remove the element's cache - name = ""; - - for ( name in jQuery.cache[ id ] ) - break; - - if ( !name ) - jQuery.removeData( elem ); - } - - // Otherwise, we want to remove all of the element's data - } else { - // Clean up the element expando - try { - delete elem[ expando ]; - } catch(e){ - // IE has trouble directly removing the expando - // but it's ok with using removeAttribute - if ( elem.removeAttribute ) - elem.removeAttribute( expando ); - } - - // Completely remove the data cache - delete jQuery.cache[ id ]; - } - }, - - // args is for internal usage only - each: function( object, callback, args ) { - if ( args ) { - if ( object.length == undefined ) { - for ( var name in object ) - if ( callback.apply( object[ name ], args ) === false ) - break; - } else - for ( var i = 0, length = object.length; i < length; i++ ) - if ( callback.apply( object[ i ], args ) === false ) - break; - - // A special, fast, case for the most common use of each - } else { - if ( object.length == undefined ) { - for ( var name in object ) - if ( callback.call( object[ name ], name, object[ name ] ) === false ) - break; - } else - for ( var i = 0, length = object.length, value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} - } - - return object; - }, - - prop: function( elem, value, type, i, name ) { - // Handle executable functions - if ( jQuery.isFunction( value ) ) - value = value.call( elem, i ); - - // Handle passing in a number to a CSS property - return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? - value + "px" : - value; - }, - - className: { - // internal only, use addClass("class") - add: function( elem, classNames ) { - jQuery.each((classNames || "").split(/\s+/), function(i, className){ - if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) - elem.className += (elem.className ? " " : "") + className; - }); - }, - - // internal only, use removeClass("class") - remove: function( elem, classNames ) { - if (elem.nodeType == 1) - elem.className = classNames != undefined ? - jQuery.grep(elem.className.split(/\s+/), function(className){ - return !jQuery.className.has( classNames, className ); - }).join(" ") : - ""; - }, - - // internal only, use is(".class") - has: function( elem, className ) { - return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; - } - }, - - // A method for quickly swapping in/out CSS properties to get correct calculations - swap: function( elem, options, callback ) { - var old = {}; - // Remember the old values, and insert the new ones - for ( var name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - callback.call( elem ); - - // Revert the old values - for ( var name in options ) - elem.style[ name ] = old[ name ]; - }, - - css: function( elem, name, force ) { - if ( name == "width" || name == "height" ) { - var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; - - function getWH() { - val = name == "width" ? elem.offsetWidth : elem.offsetHeight; - var padding = 0, border = 0; - jQuery.each( which, function() { - padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; - border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; - }); - val -= Math.round(padding + border); - } - - if ( jQuery(elem).is(":visible") ) - getWH(); - else - jQuery.swap( elem, props, getWH ); - - return Math.max(0, val); - } - - return jQuery.curCSS( elem, name, force ); - }, - - curCSS: function( elem, name, force ) { - var ret; - - // A helper method for determining if an element's values are broken - function color( elem ) { - if ( !jQuery.browser.safari ) - return false; - - var ret = document.defaultView.getComputedStyle( elem, null ); - return !ret || ret.getPropertyValue("color") == ""; - } - - // We need to handle opacity special in IE - if ( name == "opacity" && jQuery.browser.msie ) { - ret = jQuery.attr( elem.style, "opacity" ); - - return ret == "" ? - "1" : - ret; - } - // Opera sometimes will give the wrong display answer, this fixes it, see #2037 - if ( jQuery.browser.opera && name == "display" ) { - var save = elem.style.outline; - elem.style.outline = "0 solid black"; - elem.style.outline = save; - } - - // Make sure we're using the right name for getting the float value - if ( name.match( /float/i ) ) - name = styleFloat; - - if ( !force && elem.style && elem.style[ name ] ) - ret = elem.style[ name ]; - - else if ( document.defaultView && document.defaultView.getComputedStyle ) { - - // Only "float" is needed here - if ( name.match( /float/i ) ) - name = "float"; - - name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); - - var getComputedStyle = document.defaultView.getComputedStyle( elem, null ); - - if ( getComputedStyle && !color( elem ) ) - ret = getComputedStyle.getPropertyValue( name ); - - // If the element isn't reporting its values properly in Safari - // then some display: none elements are involved - else { - var swap = [], stack = []; - - // Locate all of the parent display: none elements - for ( var a = elem; a && color(a); a = a.parentNode ) - stack.unshift(a); - - // Go through and make them visible, but in reverse - // (It would be better if we knew the exact display type that they had) - for ( var i = 0; i < stack.length; i++ ) - if ( color( stack[ i ] ) ) { - swap[ i ] = stack[ i ].style.display; - stack[ i ].style.display = "block"; - } - - // Since we flip the display style, we have to handle that - // one special, otherwise get the value - ret = name == "display" && swap[ stack.length - 1 ] != null ? - "none" : - ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || ""; - - // Finally, revert the display styles back - for ( var i = 0; i < swap.length; i++ ) - if ( swap[ i ] != null ) - stack[ i ].style.display = swap[ i ]; - } - - // We should always get a number back from opacity - if ( name == "opacity" && ret == "" ) - ret = "1"; - - } else if ( elem.currentStyle ) { - var camelCase = name.replace(/\-(\w)/g, function(all, letter){ - return letter.toUpperCase(); - }); - - ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; - - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - - // If we're not dealing with a regular pixel number - // but a number that has a weird ending, we need to convert it to pixels - if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { - // Remember the original values - var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left; - - // Put in the new values to get a computed value out - elem.runtimeStyle.left = elem.currentStyle.left; - elem.style.left = ret || 0; - ret = elem.style.pixelLeft + "px"; - - // Revert the changed values - elem.style.left = style; - elem.runtimeStyle.left = runtimeStyle; - } - } - - return ret; - }, - - clean: function( elems, context ) { - var ret = []; - context = context || document; - // !context.createElement fails in IE with an error but returns typeof 'object' - if (typeof context.createElement == 'undefined') - context = context.ownerDocument || context[0] && context[0].ownerDocument || document; - - jQuery.each(elems, function(i, elem){ - if ( !elem ) - return; - - if ( elem.constructor == Number ) - elem = elem.toString(); - - // Convert html string into DOM nodes - if ( typeof elem == "string" ) { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ - return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? - all : - front + ">"; - }); - - // Trim whitespace, otherwise indexOf won't work as expected - var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); - - var wrap = - // option or optgroup - !tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && - [ 1, "", "
    " ] || - - !tags.indexOf("", "" ] || - - // matched above - (!tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - // IE can't serialize and \ No newline at end of file -- cgit v1.2.3-54-g00ecf From cba114c8506d5740ca1df00711a46b6c303e2205 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 7 Dec 2009 11:29:18 -0800 Subject: Add a "grandfather" creation date cutoff to RequireValidatedEmail plugin; will allow us to use this for temporary emergency moderation of new registrations without affecting older accounts. --- plugins/RequireValidatedEmail/README | 21 +++++++++ .../RequireValidatedEmailPlugin.php | 52 +++++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 plugins/RequireValidatedEmail/README (limited to 'plugins') diff --git a/plugins/RequireValidatedEmail/README b/plugins/RequireValidatedEmail/README new file mode 100644 index 000000000..ccd94d271 --- /dev/null +++ b/plugins/RequireValidatedEmail/README @@ -0,0 +1,21 @@ +This plugin disables posting for accounts that do not have a +validated email address. + +Example: + + addPlugin('RequireValidatedEmail'); + +If you don't want to apply the validationr equirement to existing +accounts, you can specify a cutoff date to grandfather in users +registered prior to that timestamp. + + addPlugin('RequireValidatedEmail', + array('grandfatherCutoff' => 'Dec 7, 2009'); + + +Todo: +* make email field required on registration form +* add a more visible indicator that validation is still outstanding +* localization for UI strings +* test with XMPP, API posting + diff --git a/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php b/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php index 4806538a0..04adbf00e 100644 --- a/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php +++ b/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php @@ -21,7 +21,7 @@ * * @category Plugin * @package StatusNet - * @author Craig Andrews + * @author Craig Andrews , Brion Vibber * @copyright 2009 Craig Andrews http://candrews.integralblue.com * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ @@ -33,20 +33,68 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { class RequireValidatedEmailPlugin extends Plugin { + // Users created before this time will be grandfathered in + // without the validation requirement. + public $grandfatherCutoff=null; + function __construct() { parent::__construct(); } + /** + * Event handler for notice saves; rejects the notice + * if user's address isn't validated. + * + * @param Notice $notice + * @return bool hook result code + */ function onStartNoticeSave($notice) { $user = User::staticGet('id', $notice->profile_id); if (!empty($user)) { // it's a remote notice - if (empty($user->email)) { + if (!$this->validated($user)) { throw new ClientException(_("You must validate your email address before posting.")); } } return true; } + + /** + * Check if a user has a validated email address or has been + * otherwise grandfathered in. + * + * @param User $user + * @return bool + */ + protected function validated($user) + { + if ($this->grandfathered($user)) { + return true; + } + + // The email field is only stored after validation... + // Until then you'll find them in confirm_address. + return !empty($user->email); + } + + /** + * Check if a user was created before the grandfathering cutoff. + * If so, we won't need to check for validation. + * + * @param User $user + * @return bool + */ + protected function grandfathered($user) + { + if ($this->grandfatherCutoff) { + $created = strtotime($user->created . " GMT"); + $cutoff = strtotime($this->grandfatherCutoff); + if ($created < $cutoff) { + return true; + } + } + return false; + } } -- cgit v1.2.3-54-g00ecf From 684e65e3dea09fd8179f86d846b82540cc44e5dc Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Mon, 7 Dec 2009 14:53:17 -0500 Subject: Cleanup of recaptcha plugin remove xhtml hack --- plugins/Recaptcha/RecaptchaPlugin.php | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) (limited to 'plugins') diff --git a/plugins/Recaptcha/RecaptchaPlugin.php b/plugins/Recaptcha/RecaptchaPlugin.php index 3a510ef11..db118dbb8 100644 --- a/plugins/Recaptcha/RecaptchaPlugin.php +++ b/plugins/Recaptcha/RecaptchaPlugin.php @@ -44,11 +44,11 @@ class RecaptchaPlugin extends Plugin var $ssl; function onInitializePlugin(){ - if(!isset($this->private_key)){ - common_log(LOG_ERR, "Recaptcha: Must specify private_key in config.php"); + if(!isset($this->private_key)) { + common_log(LOG_ERR, 'Recaptcha: Must specify private_key in config.php'); } - if(!isset($this->public_key)){ - common_log(LOG_ERR, "Recaptcha: Must specify public_key in config.php"); + if(!isset($this->public_key)) { + common_log(LOG_ERR, 'Recaptcha: Must specify public_key in config.php'); } } @@ -59,25 +59,13 @@ class RecaptchaPlugin extends Plugin return false; } - function onStartShowHTML($action) - { - //XXX: Horrible hack to make Safari, FF2, and Chrome work with - //reChapcha. reChapcha beaks xhtml strict - header('Content-Type: text/html'); - - $action->extraHeaders(); - - $action->startXML('html'); - - $action->style('#recaptcha_area{float:left;}'); - return false; - } function onEndRegistrationFormData($action) { + $action->style('#recaptcha_area{float:left;}'); $action->elementStart('li'); $action->raw(''); - if($this->checkssl() === true){ + if($this->checkssl() === true) { $action->raw(recaptcha_get_html($this->public_key), null, true); } else { $action->raw(recaptcha_get_html($this->public_key)); @@ -93,11 +81,9 @@ class RecaptchaPlugin extends Plugin $action->trimmed('recaptcha_challenge_field'), $action->trimmed('recaptcha_response_field')); - if (!$resp->is_valid) - { - if($this->display_errors) - { - $action->showForm ("(reCAPTCHA said: " . $resp->error . ")"); + if (!$resp->is_valid) { + if($this->display_errors) { + $action->showForm ("(reCAPTCHA error: " . $resp->error . ")"); } $action->showForm("Captcha does not match!"); return false; -- cgit v1.2.3-54-g00ecf From 4b5e977a7b1c390555d880d3dc7f8b8c6744646c Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 8 Dec 2009 12:17:11 -0800 Subject: New _m() gettext wrapper with smart detection of plugin domains. Plugin base class registers your gettext files if present at initialization. update_pot.sh replaced with update_po_templates.php which can do core, plugins, or all (default). Top-level Makefile added to build .mo files for plugins as well as core. As described on list: http://lists.status.net/pipermail/statusnet-dev/2009-December/002869.html --- Makefile | 18 ++ lib/language.php | 125 ++++++- lib/plugin.php | 19 ++ plugins/Facebook/FBConnectAuth.php | 62 ++-- plugins/Facebook/FBConnectLogin.php | 6 +- plugins/Facebook/FBConnectSettings.php | 30 +- plugins/Facebook/FacebookPlugin.php | 10 +- plugins/Facebook/facebookaction.php | 34 +- plugins/Facebook/facebookhome.php | 20 +- plugins/Facebook/facebookinvite.php | 12 +- plugins/Facebook/facebooklogin.php | 2 +- plugins/Facebook/facebookremove.php | 2 +- plugins/Facebook/facebooksettings.php | 20 +- plugins/Facebook/facebookutil.php | 4 +- plugins/Facebook/locale/Facebook.po | 394 +++++++++++++++++++++++ plugins/FeedSub/FeedSubPlugin.php | 5 +- plugins/FeedSub/actions/feedsubsettings.php | 40 ++- plugins/FeedSub/feedmunger.php | 2 +- plugins/FeedSub/locale/FeedSub.po | 104 ++++++ plugins/FeedSub/locale/fr/LC_MESSAGES/FeedSub.po | 106 ++++++ plugins/FeedSub/tests/gettext-speedtest.php | 78 +++++ plugins/Mapstraction/MapstractionPlugin.php | 4 +- plugins/Mapstraction/allmap.php | 4 +- plugins/Mapstraction/locale/Mapstraction.po | 48 +++ plugins/Mapstraction/map.php | 4 +- plugins/Mapstraction/usermap.php | 2 +- plugins/OpenID/OpenIDPlugin.php | 8 +- plugins/OpenID/finishaddopenid.php | 16 +- plugins/OpenID/finishopenidlogin.php | 62 ++-- plugins/OpenID/locale/OpenID.po | 344 ++++++++++++++++++++ plugins/OpenID/openid.php | 18 +- plugins/OpenID/openidlogin.php | 22 +- plugins/OpenID/openidserver.php | 4 +- plugins/OpenID/openidsettings.php | 30 +- plugins/OpenID/openidtrust.php | 10 +- plugins/Sample/SamplePlugin.php | 59 ++++ plugins/TwitterBridge/TwitterBridgePlugin.php | 4 +- plugins/TwitterBridge/locale/TwitterBridge.po | 128 ++++++++ plugins/TwitterBridge/twitter.php | 4 +- plugins/TwitterBridge/twitterauthorization.php | 10 +- plugins/TwitterBridge/twittersettings.php | 42 +-- scripts/update_po_templates.php | 211 ++++++++++++ scripts/update_pot.sh | 13 - 43 files changed, 1873 insertions(+), 267 deletions(-) create mode 100644 Makefile create mode 100644 plugins/Facebook/locale/Facebook.po create mode 100644 plugins/FeedSub/locale/FeedSub.po create mode 100644 plugins/FeedSub/locale/fr/LC_MESSAGES/FeedSub.po create mode 100644 plugins/FeedSub/tests/gettext-speedtest.php create mode 100644 plugins/Mapstraction/locale/Mapstraction.po create mode 100644 plugins/OpenID/locale/OpenID.po create mode 100644 plugins/Sample/SamplePlugin.php create mode 100644 plugins/TwitterBridge/locale/TwitterBridge.po create mode 100755 scripts/update_po_templates.php delete mode 100755 scripts/update_pot.sh (limited to 'plugins') diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..6f45c1b83 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +# Warning: do not transform tabs to spaces in this file. + +all : translations + +core_mo = $(patsubst %.po,%.mo,$(wildcard locale/*/LC_MESSAGES/statusnet.po)) +plugin_mo = $(patsubst %.po,%.mo,$(wildcard plugins/*/locale/*/LC_MESSAGES/*.po)) + +translations : $(core_mo) $(plugin_mo) + +clean : + rm -f $(core_mo) $(plugin_mo) + +updatepo : + php scripts/update_po_templates.php --all + +%.mo : %.po + msgfmt -o $@ $< + diff --git a/lib/language.php b/lib/language.php index 4fc45bafe..ab46f1a65 100644 --- a/lib/language.php +++ b/lib/language.php @@ -36,6 +36,33 @@ if (!function_exists('gettext')) { require_once("php-gettext/gettext.inc"); } + +if (!function_exists('dpgettext')) { + /** + * Context-aware dgettext wrapper; use when messages in different contexts + * won't be distinguished from the English source but need different translations. + * The context string will appear as msgctxt in the .po files. + * + * Not currently exposed in PHP's gettext module; implemented to be compat + * with gettext.h's macros. + * + * @param string $domain domain identifier, or null for default domain + * @param string $context context identifier, should be some key like "menu|file" + * @param string $msgid English source text + * @return string original or translated message + */ + function dpgettext($domain, $context, $msg) + { + $msgid = $context . "\004" . $msg; + $out = dcgettext($domain, $msgid, LC_MESSAGES); + if ($out == $msgid) { + return $msg; + } else { + return $out; + } + } +} + if (!function_exists('pgettext')) { /** * Context-aware gettext wrapper; use when messages in different contexts @@ -50,9 +77,31 @@ if (!function_exists('pgettext')) { * @return string original or translated message */ function pgettext($context, $msg) + { + return dpgettext(textdomain(NULL), $context, $msg); + } +} + +if (!function_exists('dnpgettext')) { + /** + * Context-aware dngettext wrapper; use when messages in different contexts + * won't be distinguished from the English source but need different translations. + * The context string will appear as msgctxt in the .po files. + * + * Not currently exposed in PHP's gettext module; implemented to be compat + * with gettext.h's macros. + * + * @param string $domain domain identifier, or null for default domain + * @param string $context context identifier, should be some key like "menu|file" + * @param string $msg singular English source text + * @param string $plural plural English source text + * @param int $n number of items to control plural selection + * @return string original or translated message + */ + function dnpgettext($domain, $context, $msg, $plural, $n) { $msgid = $context . "\004" . $msg; - $out = dcgettext(textdomain(NULL), $msgid, LC_MESSAGES); + $out = dcngettext($domain, $msgid, $plural, $n, LC_MESSAGES); if ($out == $msgid) { return $msg; } else { @@ -78,14 +127,78 @@ if (!function_exists('npgettext')) { */ function npgettext($context, $msg, $plural, $n) { - $msgid = $context . "\004" . $msg; - $out = dcngettext(textdomain(NULL), $msgid, $plural, $n, LC_MESSAGES); - if ($out == $msgid) { - return $msg; + return dnpgettext(textdomain(NULL), $msgid, $plural, $n, LC_MESSAGES); + } +} + +/** + * Shortcut for *gettext functions with smart domain detection. + * + * If calling from a plugin, this function checks which plugin was + * being called from and uses that as text domain, which will have + * been set up during plugin initialization. + * + * Also handles plurals and contexts depending on what parameters + * are passed to it: + * + * gettext -> _m($msg) + * ngettext -> _m($msg1, $msg2, $n) + * pgettext -> _m($ctx, $msg) + * npgettext -> _m($ctx, $msg1, $msg2, $n) + * + * @fixme may not work properly in eval'd code + * + * @param string $msg + * @return string + */ +function _m($msg/*, ...*/) +{ + $domain = _mdomain(debug_backtrace(false)); + $args = func_get_args(); + switch(count($args)) { + case 1: return dgettext($domain, $msg); + case 2: return dpgettext($domain, $args[0], $args[1]); + case 3: return dngettext($domain, $args[0], $args[1], $args[2]); + case 4: return dnpgettext($domain, $args[0], $args[1], $args[2], $args[3]); + default: throw new Exception("Bad parameter count to _m()"); + } +} + +/** + * Looks for which plugin we've been called from to set the gettext domain. + * + * @param array $backtrace debug_backtrace() output + * @return string + * @private + * @fixme could explode if SN is under a 'plugins' folder or share name. + */ +function _mdomain($backtrace) +{ + /* + 0 => + array + 'file' => string '/var/www/mublog/plugins/FeedSub/FeedSubPlugin.php' (length=49) + 'line' => int 77 + 'function' => string '_m' (length=2) + 'args' => + array + 0 => &string 'Feeds' (length=5) + */ + static $cached; + $path = $backtrace[0]['file']; + if (!isset($cached[$path])) { + if (DIRECTORY_SEPARATOR !== '/') { + $path = strtr($path, DIRECTORY_SEPARATOR, '/'); + } + $cut = strpos($path, '/plugins/') + 9; + $cut2 = strpos($path, '/', $cut); + if ($cut && $cut2) { + $cached[$path] = substr($path, $cut, $cut2 - $cut); } else { - return $out; + return null; } } + return $cached[$path]; } diff --git a/lib/plugin.php b/lib/plugin.php index 2c77c3e12..de7313e59 100644 --- a/lib/plugin.php +++ b/lib/plugin.php @@ -65,6 +65,8 @@ class Plugin Event::addHandler(mb_substr($method, 2), array($this, $method)); } } + + $this->setupGettext(); } function initialize() @@ -77,6 +79,22 @@ class Plugin return true; } + /** + * Checks if this plugin has localization that needs to be set up. + * Gettext localizations can be called via the _m() helper function. + */ + protected function setupGettext() + { + $class = get_class($this); + if (substr($class, -6) == 'Plugin') { + $name = substr($class, 0, -6); + $path = INSTALLDIR . "/plugins/$name/locale"; + if (file_exists($path) && is_dir($path)) { + bindtextdomain($name, $path); + } + } + } + protected function log($level, $msg) { common_log($level, get_class($this) . ': '.$msg); @@ -87,3 +105,4 @@ class Plugin $this->log(LOG_DEBUG, $msg); } } + diff --git a/plugins/Facebook/FBConnectAuth.php b/plugins/Facebook/FBConnectAuth.php index b909a4977..51bfc3865 100644 --- a/plugins/Facebook/FBConnectAuth.php +++ b/plugins/Facebook/FBConnectAuth.php @@ -48,8 +48,8 @@ class FBConnectauthAction extends Action common_log(LOG_WARNING, 'Facebook Connect Plugin - ' . "Failed auth attempt, proxy = $proxy, ip = $ip."); - $this->clientError(_('You must be logged into Facebook to ' . - 'use Facebook Connect.')); + $this->clientError(_m('You must be logged into Facebook to ' . + 'use Facebook Connect.')); } return true; @@ -74,7 +74,7 @@ class FBConnectauthAction extends Action // We don't want these cookies getFacebook()->clear_cookie_state(); - $this->clientError(_('There is already a local user linked with this Facebook.')); + $this->clientError(_m('There is already a local user linked with this Facebook.')); } else { @@ -87,12 +87,12 @@ class FBConnectauthAction extends Action $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. Try again, please.')); + $this->showForm(_m('There was a problem with your session token. Try again, please.')); return; } if ($this->arg('create')) { if (!$this->boolean('license')) { - $this->showForm(_('You can\'t register if you don\'t agree to the license.'), + $this->showForm(_m('You can\'t register if you don\'t agree to the license.'), $this->trimmed('newname')); return; } @@ -102,7 +102,7 @@ class FBConnectauthAction extends Action } else { common_debug('Facebook Connect Plugin - ' . print_r($this->args, true)); - $this->showForm(_('Something weird happened.'), + $this->showForm(_m('Something weird happened.'), $this->trimmed('newname')); } } else { @@ -116,13 +116,13 @@ class FBConnectauthAction extends Action $this->element('div', array('class' => 'error'), $this->error); } else { $this->element('div', 'instructions', - sprintf(_('This is the first time you\'ve logged into %s so we must connect your Facebook to a local account. You can either create a new account, or connect with your existing account, if you have one.'), common_config('site', 'name'))); + sprintf(_m('This is the first time you\'ve logged into %s so we must connect your Facebook to a local account. You can either create a new account, or connect with your existing account, if you have one.'), common_config('site', 'name'))); } } function title() { - return _('Facebook Account Setup'); + return _m('Facebook Account Setup'); } function showForm($error=null, $username=null) @@ -150,7 +150,7 @@ class FBConnectauthAction extends Action 'class' => 'form_settings', 'action' => common_local_url('FBConnectAuth'))); $this->elementStart('fieldset', array('id' => 'settings_facebook_connect_options')); - $this->element('legend', null, _('Connection options')); + $this->element('legend', null, _m('Connection options')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->element('input', array('type' => 'checkbox', @@ -159,10 +159,10 @@ class FBConnectauthAction extends Action 'name' => 'license', 'value' => 'true')); $this->elementStart('label', array('class' => 'checkbox', 'for' => 'license')); - $this->text(_('My text and files are available under ')); + $this->text(_m('My text and files are available under ')); $this->element('a', array('href' => common_config('license', 'url')), common_config('license', 'title')); - $this->text(_(' except this private data: password, email address, IM address, phone number.')); + $this->text(_m(' except this private data: password, email address, IM address, phone number.')); $this->elementEnd('label'); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -170,33 +170,33 @@ class FBConnectauthAction extends Action $this->elementStart('fieldset'); $this->hidden('token', common_session_token()); $this->element('legend', null, - _('Create new account')); + _m('Create new account')); $this->element('p', null, - _('Create a new user with this nickname.')); + _m('Create a new user with this nickname.')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->input('newname', _('New nickname'), + $this->input('newname', _m('New nickname'), ($this->username) ? $this->username : '', - _('1-64 lowercase letters or numbers, no punctuation or spaces')); + _m('1-64 lowercase letters or numbers, no punctuation or spaces')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('create', _('Create')); + $this->submit('create', _m('Create')); $this->elementEnd('fieldset'); $this->elementStart('fieldset'); $this->element('legend', null, - _('Connect existing account')); + _m('Connect existing account')); $this->element('p', null, - _('If you already have an account, login with your username and password to connect it to your Facebook.')); + _m('If you already have an account, login with your username and password to connect it to your Facebook.')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->input('nickname', _('Existing nickname')); + $this->input('nickname', _m('Existing nickname')); $this->elementEnd('li'); $this->elementStart('li'); - $this->password('password', _('Password')); + $this->password('password', _m('Password')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('connect', _('Connect')); + $this->submit('connect', _m('Connect')); $this->elementEnd('fieldset'); $this->elementEnd('fieldset'); @@ -212,7 +212,7 @@ class FBConnectauthAction extends Action function createNewUser() { if (common_config('site', 'closed')) { - $this->clientError(_('Registration not allowed.')); + $this->clientError(_m('Registration not allowed.')); return; } @@ -221,14 +221,14 @@ class FBConnectauthAction extends Action if (common_config('site', 'inviteonly')) { $code = $_SESSION['invitecode']; if (empty($code)) { - $this->clientError(_('Registration not allowed.')); + $this->clientError(_m('Registration not allowed.')); return; } $invite = Invitation::staticGet($code); if (empty($invite)) { - $this->clientError(_('Not a valid invitation code.')); + $this->clientError(_m('Not a valid invitation code.')); return; } } @@ -238,17 +238,17 @@ class FBConnectauthAction extends Action if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, 'format' => NICKNAME_FMT))) { - $this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.')); + $this->showForm(_m('Nickname must have only lowercase letters and numbers and no spaces.')); return; } if (!User::allowed_nickname($nickname)) { - $this->showForm(_('Nickname not allowed.')); + $this->showForm(_m('Nickname not allowed.')); return; } if (User::staticGet('nickname', $nickname)) { - $this->showForm(_('Nickname already in use. Try another one.')); + $this->showForm(_m('Nickname already in use. Try another one.')); return; } @@ -266,7 +266,7 @@ class FBConnectauthAction extends Action $result = $this->flinkUser($user->id, $this->fbuid); if (!$result) { - $this->serverError(_('Error connecting user to Facebook.')); + $this->serverError(_m('Error connecting user to Facebook.')); return; } @@ -286,7 +286,7 @@ class FBConnectauthAction extends Action $password = $this->trimmed('password'); if (!common_check_user($nickname, $password)) { - $this->showForm(_('Invalid username or password.')); + $this->showForm(_m('Invalid username or password.')); return; } @@ -300,7 +300,7 @@ class FBConnectauthAction extends Action $result = $this->flinkUser($user->id, $this->fbuid); if (!$result) { - $this->serverError(_('Error connecting user to Facebook.')); + $this->serverError(_m('Error connecting user to Facebook.')); return; } @@ -320,7 +320,7 @@ class FBConnectauthAction extends Action $result = $this->flinkUser($user->id, $this->fbuid); if (empty($result)) { - $this->serverError(_('Error connecting user to Facebook.')); + $this->serverError(_m('Error connecting user to Facebook.')); return; } diff --git a/plugins/Facebook/FBConnectLogin.php b/plugins/Facebook/FBConnectLogin.php index d2bb8054c..20c409f3e 100644 --- a/plugins/Facebook/FBConnectLogin.php +++ b/plugins/Facebook/FBConnectLogin.php @@ -30,7 +30,7 @@ class FBConnectLoginAction extends Action parent::handle($args); if (common_is_real_login()) { - $this->clientError(_('Already logged in.')); + $this->clientError(_m('Already logged in.')); } $this->showPage(); @@ -38,7 +38,7 @@ class FBConnectLoginAction extends Action function getInstructions() { - return _('Login with your Facebook Account'); + return _m('Login with your Facebook Account'); } function showPageNotice() @@ -52,7 +52,7 @@ class FBConnectLoginAction extends Action function title() { - return _('Facebook Login'); + return _m('Facebook Login'); } function showContent() { diff --git a/plugins/Facebook/FBConnectSettings.php b/plugins/Facebook/FBConnectSettings.php index 911c56787..590dffd8a 100644 --- a/plugins/Facebook/FBConnectSettings.php +++ b/plugins/Facebook/FBConnectSettings.php @@ -53,7 +53,7 @@ class FBConnectSettingsAction extends ConnectSettingsAction function title() { - return _('Facebook Connect Settings'); + return _m('Facebook Connect Settings'); } /** @@ -64,7 +64,7 @@ class FBConnectSettingsAction extends ConnectSettingsAction function getInstructions() { - return _('Manage how your account connects to Facebook'); + return _m('Manage how your account connects to Facebook'); } /** @@ -89,7 +89,7 @@ class FBConnectSettingsAction extends ConnectSettingsAction if (!$flink) { $this->element('p', 'instructions', - _('There is no Facebook user connected to this account.')); + _m('There is no Facebook user connected to this account.')); $this->element('fb:login-button', array('onlogin' => 'goto_login()', 'length' => 'long')); @@ -97,7 +97,7 @@ class FBConnectSettingsAction extends ConnectSettingsAction } else { $this->element('p', 'form_note', - _('Connected Facebook user')); + _m('Connected Facebook user')); $this->elementStart('p', array('class' => 'facebook-user-display')); $this->elementStart('fb:profile-pic', @@ -116,18 +116,18 @@ class FBConnectSettingsAction extends ConnectSettingsAction $this->elementStart('fieldset'); - $this->element('legend', null, _('Disconnect my account from Facebook')); + $this->element('legend', null, _m('Disconnect my account from Facebook')); if (!$user->password) { $this->elementStart('p', array('class' => 'form_guide')); - $this->text(_('Disconnecting your Faceboook ' . - 'would make it impossible to log in! Please ')); + $this->text(_m('Disconnecting your Faceboook ' . + 'would make it impossible to log in! Please ')); $this->element('a', array('href' => common_local_url('passwordsettings')), - _('set a password')); + _m('set a password')); - $this->text(_(' first.')); + $this->text(_m(' first.')); $this->elementEnd('p'); } else { @@ -139,7 +139,7 @@ class FBConnectSettingsAction extends ConnectSettingsAction $this->element('p', 'instructions', sprintf($note, $site, $site)); - $this->submit('disconnect', _('Disconnect')); + $this->submit('disconnect', _m('Disconnect')); } $this->elementEnd('fieldset'); @@ -161,8 +161,8 @@ class FBConnectSettingsAction extends ConnectSettingsAction // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. '. - 'Try again, please.')); + $this->showForm(_m('There was a problem with your session token. '. + 'Try again, please.')); return; } @@ -175,7 +175,7 @@ class FBConnectSettingsAction extends ConnectSettingsAction if ($result === false) { common_log_db_error($user, 'DELETE', __FILE__); - $this->serverError(_('Couldn\'t delete link to Facebook.')); + $this->serverError(_m('Couldn\'t delete link to Facebook.')); return; } @@ -191,10 +191,10 @@ class FBConnectSettingsAction extends ConnectSettingsAction $e->getMessage()); } - $this->showForm(_('You have disconnected from Facebook.'), true); + $this->showForm(_m('You have disconnected from Facebook.'), true); } else { - $this->showForm(_('Not sure what you\'re trying to do.')); + $this->showForm(_m('Not sure what you\'re trying to do.')); return; } diff --git a/plugins/Facebook/FacebookPlugin.php b/plugins/Facebook/FacebookPlugin.php index 40c911cce..39b2ef287 100644 --- a/plugins/Facebook/FacebookPlugin.php +++ b/plugins/Facebook/FacebookPlugin.php @@ -406,9 +406,9 @@ class FacebookPlugin extends Plugin $action_name = $action->trimmed('action'); $action->menuItem(common_local_url('FBConnectLogin'), - _('Facebook'), - _('Login or register using Facebook'), - 'FBConnectLogin' === $action_name); + _m('Facebook'), + _m('Login or register using Facebook'), + 'FBConnectLogin' === $action_name); return true; } @@ -426,8 +426,8 @@ class FacebookPlugin extends Plugin $action_name = $action->trimmed('action'); $action->menuItem(common_local_url('FBConnectSettings'), - _('Facebook'), - _('Facebook Connect Settings'), + _m('Facebook'), + _m('Facebook Connect Settings'), $action_name === 'FBConnectSettings'); return true; diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php index b090e9bd9..705bb2780 100644 --- a/plugins/Facebook/facebookaction.php +++ b/plugins/Facebook/facebookaction.php @@ -168,7 +168,7 @@ class FacebookAction extends Action $this->elementStart('li', array('class' => ($this->action == 'facebookhome') ? 'current' : 'facebook_home')); $this->element('a', - array('href' => 'index.php', 'title' => _('Home')), _('Home')); + array('href' => 'index.php', 'title' => _m('Home')), _m('Home')); $this->elementEnd('li'); if (common_config('invite', 'enabled')) { @@ -176,7 +176,7 @@ class FacebookAction extends Action array('class' => ($this->action == 'facebookinvite') ? 'current' : 'facebook_invite')); $this->element('a', - array('href' => 'invite.php', 'title' => _('Invite')), _('Invite')); + array('href' => 'invite.php', 'title' => _m('Invite')), _m('Invite')); $this->elementEnd('li'); } @@ -185,7 +185,7 @@ class FacebookAction extends Action ($this->action == 'facebooksettings') ? 'current' : 'facebook_settings')); $this->element('a', array('href' => 'settings.php', - 'title' => _('Settings')), _('Settings')); + 'title' => _m('Settings')), _m('Settings')); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -225,15 +225,15 @@ class FacebookAction extends Action $this->elementStart('dl', array('class' => 'system_notice')); $this->element('dt', null, 'Page Notice'); - $loginmsg_part1 = _('To use the %s Facebook Application you need to login ' . + $loginmsg_part1 = _m('To use the %s Facebook Application you need to login ' . 'with your username and password. Don\'t have a username yet? '); - $loginmsg_part2 = _(' a new account.'); + $loginmsg_part2 = _m(' a new account.'); $this->elementStart('dd'); $this->elementStart('p'); $this->text(sprintf($loginmsg_part1, common_config('site', 'name'))); $this->element('a', - array('href' => common_local_url('register')), _('Register')); + array('href' => common_local_url('register')), _m('Register')); $this->text($loginmsg_part2); $this->elementEnd('p'); $this->elementEnd('dd'); @@ -246,7 +246,7 @@ class FacebookAction extends Action { $this->elementStart('div', array('id' => 'content')); - $this->element('h1', null, _('Login')); + $this->element('h1', null, _m('Login')); if ($msg) { $this->element('fb:error', array('message' => $msg)); @@ -265,20 +265,20 @@ class FacebookAction extends Action $this->elementStart('ul', array('class' => 'form_datas')); $this->elementStart('li'); - $this->input('nickname', _('Nickname')); + $this->input('nickname', _m('Nickname')); $this->elementEnd('li'); $this->elementStart('li'); - $this->password('password', _('Password')); + $this->password('password', _m('Password')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('submit', _('Login')); + $this->submit('submit', _m('Login')); $this->elementEnd('fieldset'); $this->elementEnd('form'); $this->elementStart('p'); $this->element('a', array('href' => common_local_url('recoverpassword')), - _('Lost or forgotten password?')); + _m('Lost or forgotten password?')); $this->elementEnd('p'); $this->elementEnd('div'); @@ -383,7 +383,7 @@ class FacebookAction extends Action // Does a little before-after block for next/prev page if ($have_before || $have_after) { $this->elementStart('dl', 'pagination'); - $this->element('dt', null, _('Pagination')); + $this->element('dt', null, _m('Pagination')); $this->elementStart('dd', null); $this->elementStart('ul', array('class' => 'nav')); } @@ -392,7 +392,7 @@ class FacebookAction extends Action $newargs = $args ? array_merge($args, $pargs) : $pargs; $this->elementStart('li', array('class' => 'nav_prev')); $this->element('a', array('href' => "$this->app_uri/$action?page=$newargs[page]", 'rel' => 'prev'), - _('After')); + _m('After')); $this->elementEnd('li'); } if ($have_after) { @@ -400,7 +400,7 @@ class FacebookAction extends Action $newargs = $args ? array_merge($args, $pargs) : $pargs; $this->elementStart('li', array('class' => 'nav_next')); $this->element('a', array('href' => "$this->app_uri/$action?page=$newargs[page]", 'rel' => 'next'), - _('Before')); + _m('Before')); $this->elementEnd('li'); } if ($have_before || $have_after) { @@ -418,13 +418,13 @@ class FacebookAction extends Action $content = $this->trimmed('status_textarea'); if (!$content) { - $this->showPage(_('No notice content!')); + $this->showPage(_m('No notice content!')); return; } else { $content_shortened = common_shorten_links($content); if (Notice::contentTooLong($content_shortened)) { - $this->showPage(sprintf(_('That\'s too long. Max notice size is %d chars.'), + $this->showPage(sprintf(_m('That\'s too long. Max notice size is %d chars.'), Notice::maxContent())); return; } @@ -520,7 +520,7 @@ class FacebookNoticeList extends NoticeList function show() { $this->out->elementStart('div', array('id' =>'notices_primary')); - $this->out->element('h2', null, _('Notices')); + $this->out->element('h2', null, _m('Notices')); $this->out->elementStart('ul', array('class' => 'notices')); $cnt = 0; diff --git a/plugins/Facebook/facebookhome.php b/plugins/Facebook/facebookhome.php index ea141c2c2..60782f63c 100644 --- a/plugins/Facebook/facebookhome.php +++ b/plugins/Facebook/facebookhome.php @@ -108,7 +108,7 @@ class FacebookhomeAction extends FacebookAction $user = User::staticGet('nickname', $nickname); if (!$user) { - $this->showLoginForm(_("Server error - couldn't get user!")); + $this->showLoginForm(_m("Server error - couldn't get user!")); } $flink = DB_DataObject::factory('foreign_link'); @@ -128,7 +128,7 @@ class FacebookhomeAction extends FacebookAction return; } else { - $msg = _('Incorrect username or password.'); + $msg = _m('Incorrect username or password.'); } } @@ -155,9 +155,9 @@ class FacebookhomeAction extends FacebookAction function title() { if ($this->page > 1) { - return sprintf(_("%s and friends, page %d"), $this->user->nickname, $this->page); + return sprintf(_m("%s and friends, page %d"), $this->user->nickname, $this->page); } else { - return sprintf(_("%s and friends"), $this->user->nickname); + return sprintf(_m("%s and friends"), $this->user->nickname); } } @@ -186,7 +186,7 @@ class FacebookhomeAction extends FacebookAction $this->elementStart('div', array('class' => 'facebook_guide')); - $instructions = sprintf(_('If you would like the %s app to automatically update ' . + $instructions = sprintf(_m('If you would like the %s app to automatically update ' . 'your Facebook status with your latest notice, you need ' . 'to give it permission.'), $this->app_name); @@ -210,13 +210,13 @@ class FacebookhomeAction extends FacebookAction $this->elementStart('span', array('class' => 'facebook-button')); $this->element('a', array('href' => $auth_url), - sprintf(_('Okay, do it!'), $this->app_name)); + sprintf(_m('Okay, do it!'), $this->app_name)); $this->elementEnd('span'); $this->elementEnd('li'); $this->elementStart('li', array('id' => 'fb-permissions-item')); - $this->submit('skip', _('Skip')); + $this->submit('skip', _m('Skip')); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -245,7 +245,7 @@ class FacebookhomeAction extends FacebookAction if ($have_before || $have_after) { $this->elementStart('dl', 'pagination'); - $this->element('dt', null, _('Pagination')); + $this->element('dt', null, _m('Pagination')); $this->elementStart('dd', null); $this->elementStart('ul', array('class' => 'nav')); } @@ -254,7 +254,7 @@ class FacebookhomeAction extends FacebookAction $newargs = $args ? array_merge($args, $pargs) : $pargs; $this->elementStart('li', array('class' => 'nav_prev')); $this->element('a', array('href' => "$action?page=$newargs[page]", 'rel' => 'prev'), - _('After')); + _m('After')); $this->elementEnd('li'); } if ($have_after) { @@ -262,7 +262,7 @@ class FacebookhomeAction extends FacebookAction $newargs = $args ? array_merge($args, $pargs) : $pargs; $this->elementStart('li', array('class' => 'nav_next')); $this->element('a', array('href' => "$action?page=$newargs[page]", 'rel' => 'next'), - _('Before')); + _m('Before')); $this->elementEnd('li'); } if ($have_before || $have_after) { diff --git a/plugins/Facebook/facebookinvite.php b/plugins/Facebook/facebookinvite.php index 3380b4c85..e02c7bf3e 100644 --- a/plugins/Facebook/facebookinvite.php +++ b/plugins/Facebook/facebookinvite.php @@ -69,9 +69,9 @@ class FacebookinviteAction extends FacebookAction function showSuccessContent() { - $this->element('h2', null, sprintf(_('Thanks for inviting your friends to use %s'), + $this->element('h2', null, sprintf(_m('Thanks for inviting your friends to use %s'), common_config('site', 'name'))); - $this->element('p', null, _('Invitations have been sent to the following users:')); + $this->element('p', null, _m('Invitations have been sent to the following users:')); $friend_ids = $_POST['ids']; // XXX: Hmm... is this the best way to access the list? @@ -91,7 +91,7 @@ class FacebookinviteAction extends FacebookAction function showFormContent() { - $content = sprintf(_('You have been invited to %s'), common_config('site', 'name')) . + $content = sprintf(_m('You have been invited to %s'), common_config('site', 'name')) . htmlentities(''); $this->elementStart('fb:request-form', array('action' => 'invite.php', @@ -100,7 +100,7 @@ class FacebookinviteAction extends FacebookAction 'type' => common_config('site', 'name'), 'content' => $content)); $this->hidden('invite', 'true'); - $actiontext = sprintf(_('Invite your friends to use %s'), common_config('site', 'name')); + $actiontext = sprintf(_m('Invite your friends to use %s'), common_config('site', 'name')); $multi_params = array('showborder' => 'false'); $multi_params['actiontext'] = $actiontext; @@ -122,7 +122,7 @@ class FacebookinviteAction extends FacebookAction if ($exclude_ids) { - $this->element('h2', null, sprintf(_('Friends already using %s:'), + $this->element('h2', null, sprintf(_m('Friends already using %s:'), common_config('site', 'name'))); $this->elementStart('ul', array('id' => 'facebook-friends')); @@ -140,7 +140,7 @@ class FacebookinviteAction extends FacebookAction function title() { - return sprintf(_('Send invitations')); + return sprintf(_m('Send invitations')); } } diff --git a/plugins/Facebook/facebooklogin.php b/plugins/Facebook/facebooklogin.php index f77aecca3..7a173ddae 100644 --- a/plugins/Facebook/facebooklogin.php +++ b/plugins/Facebook/facebooklogin.php @@ -88,7 +88,7 @@ class FacebookinviteAction extends FacebookAction function title() { - return sprintf(_('Login')); + return sprintf(_m('Login')); } function redirectHome() diff --git a/plugins/Facebook/facebookremove.php b/plugins/Facebook/facebookremove.php index 8531a8e6e..09cb33342 100644 --- a/plugins/Facebook/facebookremove.php +++ b/plugins/Facebook/facebookremove.php @@ -55,7 +55,7 @@ class FacebookremoveAction extends FacebookAction if (!$result) { common_log_db_error($flink, 'DELETE', __FILE__); - $this->serverError(_('Couldn\'t remove Facebook user.')); + $this->serverError(_m('Couldn\'t remove Facebook user.')); return; } diff --git a/plugins/Facebook/facebooksettings.php b/plugins/Facebook/facebooksettings.php index d1269f101..766d0e199 100644 --- a/plugins/Facebook/facebooksettings.php +++ b/plugins/Facebook/facebooksettings.php @@ -71,9 +71,9 @@ class FacebooksettingsAction extends FacebookAction $trimmed); if ($result === false) { - $this->showForm(_('There was a problem saving your sync preferences!')); + $this->showForm(_m('There was a problem saving your sync preferences!')); } else { - $this->showForm(_('Sync preferences saved.'), true); + $this->showForm(_m('Sync preferences saved.'), true); } } @@ -96,14 +96,14 @@ class FacebooksettingsAction extends FacebookAction $this->elementStart('li'); - $this->checkbox('noticesync', _('Automatically update my Facebook status with my notices.'), + $this->checkbox('noticesync', _m('Automatically update my Facebook status with my notices.'), ($this->flink) ? ($this->flink->noticesync & FOREIGN_NOTICE_SEND) : true); $this->elementEnd('li'); $this->elementStart('li'); - $this->checkbox('replysync', _('Send "@" replies to Facebook.'), + $this->checkbox('replysync', _m('Send "@" replies to Facebook.'), ($this->flink) ? ($this->flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) : true); $this->elementEnd('li'); @@ -112,15 +112,15 @@ class FacebooksettingsAction extends FacebookAction $prefix = trim($this->facebook->api_client->data_getUserPreference(FACEBOOK_NOTICE_PREFIX)); - $this->input('prefix', _('Prefix'), + $this->input('prefix', _m('Prefix'), ($prefix) ? $prefix : null, - _('A string to prefix notices with.')); + _m('A string to prefix notices with.')); $this->elementEnd('li'); $this->elementStart('li'); - $this->submit('save', _('Save')); + $this->submit('save', _m('Save')); $this->elementEnd('li'); @@ -130,7 +130,7 @@ class FacebooksettingsAction extends FacebookAction } else { - $instructions = sprintf(_('If you would like %s to automatically update ' . + $instructions = sprintf(_m('If you would like %s to automatically update ' . 'your Facebook status with your latest notice, you need ' . 'to give it permission.'), $this->app_name); @@ -143,7 +143,7 @@ class FacebooksettingsAction extends FacebookAction $this->elementStart('fb:prompt-permission', array('perms' => 'publish_stream', 'next_fbjs' => 'document.setLocation(\'' . "$this->app_uri/settings.php" . '\')')); $this->element('span', array('class' => 'facebook-button'), - sprintf(_('Allow %s to update my Facebook status'), common_config('site', 'name'))); + sprintf(_m('Allow %s to update my Facebook status'), common_config('site', 'name'))); $this->elementEnd('fb:prompt-permission'); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -153,7 +153,7 @@ class FacebooksettingsAction extends FacebookAction function title() { - return _('Sync preferences'); + return _m('Sync preferences'); } } diff --git a/plugins/Facebook/facebookutil.php b/plugins/Facebook/facebookutil.php index 2abcbb14e..2ec6db6b8 100644 --- a/plugins/Facebook/facebookutil.php +++ b/plugins/Facebook/facebookutil.php @@ -277,10 +277,10 @@ function mail_facebook_app_removed($user) $site_name = common_config('site', 'name'); $subject = sprintf( - _('Your %1$s Facebook application access has been disabled.', + _m('Your %1$s Facebook application access has been disabled.', $site_name)); - $body = sprintf(_("Hi, %1\$s. We're sorry to inform you that we are " . + $body = sprintf(_m("Hi, %1\$s. We're sorry to inform you that we are " . 'unable to update your Facebook status from %2$s, and have disabled ' . 'the Facebook application for your account. This may be because ' . 'you have removed the Facebook application\'s authorization, or ' . diff --git a/plugins/Facebook/locale/Facebook.po b/plugins/Facebook/locale/Facebook.po new file mode 100644 index 000000000..5b313c8c5 --- /dev/null +++ b/plugins/Facebook/locale/Facebook.po @@ -0,0 +1,394 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-07 20:38-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: facebookaction.php:171 +msgid "Home" +msgstr "" + +#: facebookaction.php:179 +msgid "Invite" +msgstr "" + +#: facebookaction.php:188 +msgid "Settings" +msgstr "" + +#: facebookaction.php:228 +#, php-format +msgid "" +"To use the %s Facebook Application you need to login with your username and " +"password. Don't have a username yet? " +msgstr "" + +#: facebookaction.php:230 +msgid " a new account." +msgstr "" + +#: facebookaction.php:236 +msgid "Register" +msgstr "" + +#: facebookaction.php:249 facebookaction.php:275 facebooklogin.php:91 +msgid "Login" +msgstr "" + +#: facebookaction.php:268 +msgid "Nickname" +msgstr "" + +#: facebookaction.php:271 FBConnectAuth.php:196 +msgid "Password" +msgstr "" + +#: facebookaction.php:281 +msgid "Lost or forgotten password?" +msgstr "" + +#: facebookaction.php:386 facebookhome.php:248 +msgid "Pagination" +msgstr "" + +#: facebookaction.php:395 facebookhome.php:257 +msgid "After" +msgstr "" + +#: facebookaction.php:403 facebookhome.php:265 +msgid "Before" +msgstr "" + +#: facebookaction.php:421 +msgid "No notice content!" +msgstr "" + +#: facebookaction.php:427 +#, php-format +msgid "That's too long. Max notice size is %d chars." +msgstr "" + +#: facebookaction.php:523 +msgid "Notices" +msgstr "" + +#: facebookutil.php:280 +#, php-format +msgid "Your %1$s Facebook application access has been disabled." +msgstr "" + +#: facebookutil.php:283 +#, php-format +msgid "" +"Hi, %1$s. We're sorry to inform you that we are unable to update your " +"Facebook status from %2$s, and have disabled the Facebook application for " +"your account. This may be because you have removed the Facebook " +"application's authorization, or have deleted your Facebook account. You can " +"re-enable the Facebook application and automatic status updating by re-" +"installing the %2$s Facebook application.\n" +"\n" +"Regards,\n" +"\n" +"%2$s" +msgstr "" + +#: FBConnectLogin.php:33 +msgid "Already logged in." +msgstr "" + +#: FBConnectLogin.php:41 +msgid "Login with your Facebook Account" +msgstr "" + +#: FBConnectLogin.php:55 +msgid "Facebook Login" +msgstr "" + +#: facebookhome.php:111 +msgid "Server error - couldn't get user!" +msgstr "" + +#: facebookhome.php:131 +msgid "Incorrect username or password." +msgstr "" + +#: facebookhome.php:158 +#, php-format +msgid "%s and friends, page %d" +msgstr "" + +#: facebookhome.php:160 +#, php-format +msgid "%s and friends" +msgstr "" + +#: facebookhome.php:189 +#, php-format +msgid "" +"If you would like the %s app to automatically update your Facebook status " +"with your latest notice, you need to give it permission." +msgstr "" + +#: facebookhome.php:213 +msgid "Okay, do it!" +msgstr "" + +#: facebookhome.php:219 +msgid "Skip" +msgstr "" + +#: facebooksettings.php:74 +msgid "There was a problem saving your sync preferences!" +msgstr "" + +#: facebooksettings.php:76 +msgid "Sync preferences saved." +msgstr "" + +#: facebooksettings.php:99 +msgid "Automatically update my Facebook status with my notices." +msgstr "" + +#: facebooksettings.php:106 +msgid "Send \"@\" replies to Facebook." +msgstr "" + +#: facebooksettings.php:115 +msgid "Prefix" +msgstr "" + +#: facebooksettings.php:117 +msgid "A string to prefix notices with." +msgstr "" + +#: facebooksettings.php:123 +msgid "Save" +msgstr "" + +#: facebooksettings.php:133 +#, php-format +msgid "" +"If you would like %s to automatically update your Facebook status with your " +"latest notice, you need to give it permission." +msgstr "" + +#: facebooksettings.php:146 +#, php-format +msgid "Allow %s to update my Facebook status" +msgstr "" + +#: facebooksettings.php:156 +msgid "Sync preferences" +msgstr "" + +#: facebookinvite.php:72 +#, php-format +msgid "Thanks for inviting your friends to use %s" +msgstr "" + +#: facebookinvite.php:74 +msgid "Invitations have been sent to the following users:" +msgstr "" + +#: facebookinvite.php:94 +#, php-format +msgid "You have been invited to %s" +msgstr "" + +#: facebookinvite.php:103 +#, php-format +msgid "Invite your friends to use %s" +msgstr "" + +#: facebookinvite.php:125 +#, php-format +msgid "Friends already using %s:" +msgstr "" + +#: facebookinvite.php:143 +msgid "Send invitations" +msgstr "" + +#: facebookremove.php:58 +msgid "Couldn't remove Facebook user." +msgstr "" + +#: FBConnectSettings.php:56 FacebookPlugin.php:430 +msgid "Facebook Connect Settings" +msgstr "" + +#: FBConnectSettings.php:67 +msgid "Manage how your account connects to Facebook" +msgstr "" + +#: FBConnectSettings.php:92 +msgid "There is no Facebook user connected to this account." +msgstr "" + +#: FBConnectSettings.php:100 +msgid "Connected Facebook user" +msgstr "" + +#: FBConnectSettings.php:119 +msgid "Disconnect my account from Facebook" +msgstr "" + +#: FBConnectSettings.php:124 +msgid "" +"Disconnecting your Faceboook would make it impossible to log in! Please " +msgstr "" + +#: FBConnectSettings.php:128 +msgid "set a password" +msgstr "" + +#: FBConnectSettings.php:130 +msgid " first." +msgstr "" + +#: FBConnectSettings.php:142 +msgid "Disconnect" +msgstr "" + +#: FBConnectSettings.php:164 FBConnectAuth.php:90 +msgid "There was a problem with your session token. Try again, please." +msgstr "" + +#: FBConnectSettings.php:178 +msgid "Couldn't delete link to Facebook." +msgstr "" + +#: FBConnectSettings.php:194 +msgid "You have disconnected from Facebook." +msgstr "" + +#: FBConnectSettings.php:197 +msgid "Not sure what you're trying to do." +msgstr "" + +#: FBConnectAuth.php:51 +msgid "You must be logged into Facebook to use Facebook Connect." +msgstr "" + +#: FBConnectAuth.php:77 +msgid "There is already a local user linked with this Facebook." +msgstr "" + +#: FBConnectAuth.php:95 +msgid "You can't register if you don't agree to the license." +msgstr "" + +#: FBConnectAuth.php:105 +msgid "Something weird happened." +msgstr "" + +#: FBConnectAuth.php:119 +#, php-format +msgid "" +"This is the first time you've logged into %s so we must connect your " +"Facebook to a local account. You can either create a new account, or connect " +"with your existing account, if you have one." +msgstr "" + +#: FBConnectAuth.php:125 +msgid "Facebook Account Setup" +msgstr "" + +#: FBConnectAuth.php:153 +msgid "Connection options" +msgstr "" + +#: FBConnectAuth.php:162 +msgid "My text and files are available under " +msgstr "" + +#: FBConnectAuth.php:165 +msgid "" +" except this private data: password, email address, IM address, phone number." +msgstr "" + +#: FBConnectAuth.php:173 +msgid "Create new account" +msgstr "" + +#: FBConnectAuth.php:175 +msgid "Create a new user with this nickname." +msgstr "" + +#: FBConnectAuth.php:178 +msgid "New nickname" +msgstr "" + +#: FBConnectAuth.php:180 +msgid "1-64 lowercase letters or numbers, no punctuation or spaces" +msgstr "" + +#: FBConnectAuth.php:183 +msgid "Create" +msgstr "" + +#: FBConnectAuth.php:188 +msgid "Connect existing account" +msgstr "" + +#: FBConnectAuth.php:190 +msgid "" +"If you already have an account, login with your username and password to " +"connect it to your Facebook." +msgstr "" + +#: FBConnectAuth.php:193 +msgid "Existing nickname" +msgstr "" + +#: FBConnectAuth.php:199 +msgid "Connect" +msgstr "" + +#: FBConnectAuth.php:215 FBConnectAuth.php:224 +msgid "Registration not allowed." +msgstr "" + +#: FBConnectAuth.php:231 +msgid "Not a valid invitation code." +msgstr "" + +#: FBConnectAuth.php:241 +msgid "Nickname must have only lowercase letters and numbers and no spaces." +msgstr "" + +#: FBConnectAuth.php:246 +msgid "Nickname not allowed." +msgstr "" + +#: FBConnectAuth.php:251 +msgid "Nickname already in use. Try another one." +msgstr "" + +#: FBConnectAuth.php:269 FBConnectAuth.php:303 FBConnectAuth.php:323 +msgid "Error connecting user to Facebook." +msgstr "" + +#: FBConnectAuth.php:289 +msgid "Invalid username or password." +msgstr "" + +#: FacebookPlugin.php:409 FacebookPlugin.php:429 +msgid "Facebook" +msgstr "" + +#: FacebookPlugin.php:410 +msgid "Login or register using Facebook" +msgstr "" diff --git a/plugins/FeedSub/FeedSubPlugin.php b/plugins/FeedSub/FeedSubPlugin.php index 36d4e7802..857a9794d 100644 --- a/plugins/FeedSub/FeedSubPlugin.php +++ b/plugins/FeedSub/FeedSubPlugin.php @@ -51,7 +51,6 @@ class FeedSubPlugin extends Plugin * @param Net_URL_Mapper $m path-to-action mapper * @return boolean hook return */ - function onRouterInitialized($m) { $m->connect('feedsub/callback/:feed', @@ -74,8 +73,8 @@ class FeedSubPlugin extends Plugin $action_name = $action->trimmed('action'); $action->menuItem(common_local_url('feedsubsettings'), - dgettext('FeebSubPlugin', 'Feeds'), - dgettext('FeedSubPlugin', 'Feed subscription options'), + _m('Feeds'), + _m('Feed subscription options'), $action_name === 'feedsubsettings'); return true; diff --git a/plugins/FeedSub/actions/feedsubsettings.php b/plugins/FeedSub/actions/feedsubsettings.php index 242224fac..0fba20a39 100644 --- a/plugins/FeedSub/actions/feedsubsettings.php +++ b/plugins/FeedSub/actions/feedsubsettings.php @@ -38,7 +38,7 @@ class FeedSubSettingsAction extends ConnectSettingsAction function title() { - return dgettext('FeedSubPlugin', 'Feed subscriptions'); + return _m('Feed subscriptions'); } /** @@ -49,9 +49,8 @@ class FeedSubSettingsAction extends ConnectSettingsAction function getInstructions() { - return dgettext('FeedSubPlugin', - 'You can subscribe to feeds from other sites; ' . - 'updates will appear in your personal timeline.'); + return _m('You can subscribe to feeds from other sites; ' . + 'updates will appear in your personal timeline.'); } /** @@ -94,9 +93,9 @@ class FeedSubSettingsAction extends ConnectSettingsAction $this->elementEnd('ul'); if ($this->preview) { - $this->submit('subscribe', dgettext('FeedSubPlugin', 'Subscribe')); + $this->submit('subscribe', _m('Subscribe')); } else { - $this->submit('validate', dgettext('FeedSubPlugin', 'Continue')); + $this->submit('validate', _m('Continue')); } $this->elementEnd('fieldset'); @@ -149,8 +148,7 @@ class FeedSubSettingsAction extends ConnectSettingsAction $feedurl = trim($this->arg('feedurl')); if ($feedurl == '') { - $this->showForm(dgettext('FeedSubPlugin', - 'Empty feed URL!')); + $this->showForm(_m('Empty feed URL!')); return; } $this->feedurl = $feedurl; @@ -160,26 +158,26 @@ class FeedSubSettingsAction extends ConnectSettingsAction $discover = new FeedDiscovery(); $uri = $discover->discoverFromURL($feedurl); } catch (FeedSubBadURLException $e) { - $this->showForm(dgettext('FeedSubPlugin', 'Invalid URL or could not reach server.')); + $this->showForm(_m('Invalid URL or could not reach server.')); return false; } catch (FeedSubBadResponseException $e) { - $this->showForm(dgettext('FeedSubPlugin', 'Cannot read feed; server returned error.')); + $this->showForm(_m('Cannot read feed; server returned error.')); return false; } catch (FeedSubEmptyException $e) { - $this->showForm(dgettext('FeedSubPlugin', 'Cannot read feed; server returned an empty page.')); + $this->showForm(_m('Cannot read feed; server returned an empty page.')); return false; } catch (FeedSubBadHTMLException $e) { - $this->showForm(dgettext('FeedSubPlugin', 'Bad HTML, could not find feed link.')); + $this->showForm(_m('Bad HTML, could not find feed link.')); return false; } catch (FeedSubNoFeedException $e) { - $this->showForm(dgettext('FeedSubPlugin', 'Could not find a feed linked from this URL.')); + $this->showForm(_m('Could not find a feed linked from this URL.')); return false; } catch (FeedSubUnrecognizedTypeException $e) { - $this->showForm(dgettext('FeedSubPlugin', 'Not a recognized feed type.')); + $this->showForm(_m('Not a recognized feed type.')); return false; } catch (FeedSubException $e) { // Any new ones we forgot about - $this->showForm(dgettext('FeedSubPlugin', 'Bad feed URL.')); + $this->showForm(_m('Bad feed URL.')); return false; } @@ -187,7 +185,7 @@ class FeedSubSettingsAction extends ConnectSettingsAction $this->feedinfo = $this->munger->feedInfo(); if ($this->feedinfo->huburi == '') { - $this->showForm(dgettext('FeedSubPlugin', 'Feed is not PuSH-enabled; cannot subscribe.')); + $this->showForm(_m('Feed is not PuSH-enabled; cannot subscribe.')); return false; } @@ -207,7 +205,7 @@ class FeedSubSettingsAction extends ConnectSettingsAction $ok = $this->feedinfo->subscribe(); common_log(LOG_INFO, __METHOD__ . ": sub was $ok"); if (!$ok) { - $this->showForm(dgettext('FeedSubPlugin', 'Feed subscription failed! Bad response from hub.')); + $this->showForm(_m('Feed subscription failed! Bad response from hub.')); return; } } @@ -217,11 +215,11 @@ class FeedSubSettingsAction extends ConnectSettingsAction $profile = $this->feedinfo->getProfile(); if ($user->isSubscribed($profile)) { - $this->showForm(dgettext('FeedSubPlugin', 'Already subscribed!')); + $this->showForm(_m('Already subscribed!')); } elseif ($user->subscribeTo($profile)) { - $this->showForm(dgettext('FeedSubPlugin', 'Feed subscribed!')); + $this->showForm(_m('Feed subscribed!')); } else { - $this->showForm(dgettext('FeedSubPlugin', 'Feed subscription failed!')); + $this->showForm(_m('Feed subscription failed!')); } } } @@ -230,7 +228,7 @@ class FeedSubSettingsAction extends ConnectSettingsAction { if ($this->validateFeed()) { $this->preview = true; - $this->showForm(dgettext('FeedSubPlugin', 'Previewing feed:')); + $this->showForm(_m('Previewing feed:')); } } diff --git a/plugins/FeedSub/feedmunger.php b/plugins/FeedSub/feedmunger.php index bb8075da9..f3618b8eb 100644 --- a/plugins/FeedSub/feedmunger.php +++ b/plugins/FeedSub/feedmunger.php @@ -212,7 +212,7 @@ class FeedMunger // try adding #hashtags from the categories/tags on a post. // @todo Should we force a language here? - $format = dgettext("FeedSubPlugin", 'New post: "%1$s" %2$s'); + $format = _m('New post: "%1$s" %2$s'); $title = $entry->title; $link = $this->getAltLink($entry); $out = sprintf($format, $title, $link); diff --git a/plugins/FeedSub/locale/FeedSub.po b/plugins/FeedSub/locale/FeedSub.po new file mode 100644 index 000000000..dedc018e3 --- /dev/null +++ b/plugins/FeedSub/locale/FeedSub.po @@ -0,0 +1,104 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-07 20:38-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: tests/gettext-speedtest.php:57 FeedSubPlugin.php:76 +msgid "Feeds" +msgstr "" + +#: FeedSubPlugin.php:77 +msgid "Feed subscription options" +msgstr "" + +#: feedmunger.php:215 +#, php-format +msgid "New post: \"%1$s\" %2$s" +msgstr "" + +#: actions/feedsubsettings.php:41 +msgid "Feed subscriptions" +msgstr "" + +#: actions/feedsubsettings.php:52 +msgid "" +"You can subscribe to feeds from other sites; updates will appear in your " +"personal timeline." +msgstr "" + +#: actions/feedsubsettings.php:96 +msgid "Subscribe" +msgstr "" + +#: actions/feedsubsettings.php:98 +msgid "Continue" +msgstr "" + +#: actions/feedsubsettings.php:151 +msgid "Empty feed URL!" +msgstr "" + +#: actions/feedsubsettings.php:161 +msgid "Invalid URL or could not reach server." +msgstr "" + +#: actions/feedsubsettings.php:164 +msgid "Cannot read feed; server returned error." +msgstr "" + +#: actions/feedsubsettings.php:167 +msgid "Cannot read feed; server returned an empty page." +msgstr "" + +#: actions/feedsubsettings.php:170 +msgid "Bad HTML, could not find feed link." +msgstr "" + +#: actions/feedsubsettings.php:173 +msgid "Could not find a feed linked from this URL." +msgstr "" + +#: actions/feedsubsettings.php:176 +msgid "Not a recognized feed type." +msgstr "" + +#: actions/feedsubsettings.php:180 +msgid "Bad feed URL." +msgstr "" + +#: actions/feedsubsettings.php:188 +msgid "Feed is not PuSH-enabled; cannot subscribe." +msgstr "" + +#: actions/feedsubsettings.php:208 +msgid "Feed subscription failed! Bad response from hub." +msgstr "" + +#: actions/feedsubsettings.php:218 +msgid "Already subscribed!" +msgstr "" + +#: actions/feedsubsettings.php:220 +msgid "Feed subscribed!" +msgstr "" + +#: actions/feedsubsettings.php:222 +msgid "Feed subscription failed!" +msgstr "" + +#: actions/feedsubsettings.php:231 +msgid "Previewing feed:" +msgstr "" diff --git a/plugins/FeedSub/locale/fr/LC_MESSAGES/FeedSub.po b/plugins/FeedSub/locale/fr/LC_MESSAGES/FeedSub.po new file mode 100644 index 000000000..f17dfa50a --- /dev/null +++ b/plugins/FeedSub/locale/fr/LC_MESSAGES/FeedSub.po @@ -0,0 +1,106 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-07 14:14-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: FeedSubPlugin.php:77 +msgid "Feeds" +msgstr "Flux" + +#: FeedSubPlugin.php:78 +msgid "Feed subscription options" +msgstr "Préférences pour abonnement flux" + +#: feedmunger.php:215 +#, php-format +msgid "New post: \"%1$s\" %2$s" +msgstr "Nouveau: \"%1$s\" %2$s" + +#: actions/feedsubsettings.php:41 +msgid "Feed subscriptions" +msgstr "Abonnements aux fluxes" + +#: actions/feedsubsettings.php:52 +msgid "" +"You can subscribe to feeds from other sites; updates will appear in your " +"personal timeline." +msgstr "" +"Abonner aux fluxes RSS ou Atom des autres sites web; les temps se trouverair" +"en votre flux personnel." + +#: actions/feedsubsettings.php:96 +msgid "Subscribe" +msgstr "Abonner" + +#: actions/feedsubsettings.php:98 +msgid "Continue" +msgstr "Prochaine" + +#: actions/feedsubsettings.php:151 +msgid "Empty feed URL!" +msgstr "" + +#: actions/feedsubsettings.php:161 +msgid "Invalid URL or could not reach server." +msgstr "" + +#: actions/feedsubsettings.php:164 +msgid "Cannot read feed; server returned error." +msgstr "" + +#: actions/feedsubsettings.php:167 +msgid "Cannot read feed; server returned an empty page." +msgstr "" + +#: actions/feedsubsettings.php:170 +msgid "Bad HTML, could not find feed link." +msgstr "" + +#: actions/feedsubsettings.php:173 +msgid "Could not find a feed linked from this URL." +msgstr "" + +#: actions/feedsubsettings.php:176 +msgid "Not a recognized feed type." +msgstr "" + +#: actions/feedsubsettings.php:180 +msgid "Bad feed URL." +msgstr "" + +#: actions/feedsubsettings.php:188 +msgid "Feed is not PuSH-enabled; cannot subscribe." +msgstr "" + +#: actions/feedsubsettings.php:208 +msgid "Feed subscription failed! Bad response from hub." +msgstr "" + +#: actions/feedsubsettings.php:218 +msgid "Already subscribed!" +msgstr "" + +#: actions/feedsubsettings.php:220 +msgid "Feed subscribed!" +msgstr "" + +#: actions/feedsubsettings.php:222 +msgid "Feed subscription failed!" +msgstr "" + +#: actions/feedsubsettings.php:231 +msgid "Previewing feed:" +msgstr "" diff --git a/plugins/FeedSub/tests/gettext-speedtest.php b/plugins/FeedSub/tests/gettext-speedtest.php new file mode 100644 index 000000000..8bbdf5e89 --- /dev/null +++ b/plugins/FeedSub/tests/gettext-speedtest.php @@ -0,0 +1,78 @@ + $bits) { + list($time, $result) = $bits; + $ms = $time * 1000.0; + printf("%10s %2.4fms %s\n", $func, $ms, $result); +} + + +function fake($str) { + return $str; +} + diff --git a/plugins/Mapstraction/MapstractionPlugin.php b/plugins/Mapstraction/MapstractionPlugin.php index f20e81b0e..93679e56c 100644 --- a/plugins/Mapstraction/MapstractionPlugin.php +++ b/plugins/Mapstraction/MapstractionPlugin.php @@ -177,7 +177,7 @@ class MapstractionPlugin extends Plugin $action->elementStart('div', array('id' => 'entity_map', 'class' => 'section')); - $action->element('h2', null, _('Map')); + $action->element('h2', null, _m('Map')); $action->element('div', array('id' => 'map_canvas', 'class' => 'gray smallmap', @@ -188,7 +188,7 @@ class MapstractionPlugin extends Plugin array('nickname' => $action->trimmed('nickname'))); $action->element('a', array('href' => $mapUrl), - _("Full size")); + _m("Full size")); $action->elementEnd('div'); } diff --git a/plugins/Mapstraction/allmap.php b/plugins/Mapstraction/allmap.php index 0c4f03b31..e73aa76e8 100644 --- a/plugins/Mapstraction/allmap.php +++ b/plugins/Mapstraction/allmap.php @@ -68,10 +68,10 @@ class AllmapAction extends MapAction } if ($this->page == 1) { - return sprintf(_("%s friends map"), + return sprintf(_m("%s friends map"), $base); } else { - return sprintf(_("%s friends map, page %d"), + return sprintf(_m("%s friends map, page %d"), $base, $this->page); } diff --git a/plugins/Mapstraction/locale/Mapstraction.po b/plugins/Mapstraction/locale/Mapstraction.po new file mode 100644 index 000000000..c1c50bf50 --- /dev/null +++ b/plugins/Mapstraction/locale/Mapstraction.po @@ -0,0 +1,48 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-07 20:38-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: allmap.php:71 +#, php-format +msgid "%s friends map" +msgstr "" + +#: allmap.php:74 +#, php-format +msgid "%s friends map, page %d" +msgstr "" + +#: map.php:72 +msgid "No such user." +msgstr "" + +#: map.php:79 +msgid "User has no profile." +msgstr "" + +#: usermap.php:71 +#, php-format +msgid "%s map, page %d" +msgstr "" + +#: MapstractionPlugin.php:180 +msgid "Map" +msgstr "" + +#: MapstractionPlugin.php:191 +msgid "Full size" +msgstr "" diff --git a/plugins/Mapstraction/map.php b/plugins/Mapstraction/map.php index 734e48088..a33dfc736 100644 --- a/plugins/Mapstraction/map.php +++ b/plugins/Mapstraction/map.php @@ -69,14 +69,14 @@ class MapAction extends OwnerDesignAction $this->user = User::staticGet('nickname', $nickname); if (!$this->user) { - $this->clientError(_('No such user.'), 404); + $this->clientError(_m('No such user.'), 404); return false; } $this->profile = $this->user->getProfile(); if (!$this->profile) { - $this->serverError(_('User has no profile.')); + $this->serverError(_m('User has no profile.')); return false; } diff --git a/plugins/Mapstraction/usermap.php b/plugins/Mapstraction/usermap.php index 3e517ee86..ff47b6ada 100644 --- a/plugins/Mapstraction/usermap.php +++ b/plugins/Mapstraction/usermap.php @@ -68,7 +68,7 @@ class UsermapAction extends MapAction if ($this->page == 1) { return $base; } else { - return sprintf(_("%s map, page %d"), + return sprintf(_m("%s map, page %d"), $base, $this->page); } diff --git a/plugins/OpenID/OpenIDPlugin.php b/plugins/OpenID/OpenIDPlugin.php index e86725d70..a37d5465e 100644 --- a/plugins/OpenID/OpenIDPlugin.php +++ b/plugins/OpenID/OpenIDPlugin.php @@ -120,8 +120,8 @@ class OpenIDPlugin extends Plugin $action_name = $action->trimmed('action'); $action->menuItem(common_local_url('openidlogin'), - _('OpenID'), - _('Login or register with OpenID'), + _m('OpenID'), + _m('Login or register with OpenID'), $action_name === 'openidlogin'); return true; @@ -132,8 +132,8 @@ class OpenIDPlugin extends Plugin $action_name = $action->trimmed('action'); $action->menuItem(common_local_url('openidsettings'), - _('OpenID'), - _('Add or remove OpenIDs'), + _m('OpenID'), + _m('Add or remove OpenIDs'), $action_name === 'openidsettings'); return true; diff --git a/plugins/OpenID/finishaddopenid.php b/plugins/OpenID/finishaddopenid.php index 7cd916523..991e6584e 100644 --- a/plugins/OpenID/finishaddopenid.php +++ b/plugins/OpenID/finishaddopenid.php @@ -64,7 +64,7 @@ class FinishaddopenidAction extends Action { parent::handle($args); if (!common_logged_in()) { - $this->clientError(_('Not logged in.')); + $this->clientError(_m('Not logged in.')); } else { $this->tryLogin(); } @@ -85,11 +85,11 @@ class FinishaddopenidAction extends Action $response = $consumer->complete(common_local_url('finishaddopenid')); if ($response->status == Auth_OpenID_CANCEL) { - $this->message(_('OpenID authentication cancelled.')); + $this->message(_m('OpenID authentication cancelled.')); return; } else if ($response->status == Auth_OpenID_FAILURE) { // Authentication failed; display the error message. - $this->message(sprintf(_('OpenID authentication failed: %s'), + $this->message(sprintf(_m('OpenID authentication failed: %s'), $response->message)); } else if ($response->status == Auth_OpenID_SUCCESS) { @@ -109,9 +109,9 @@ class FinishaddopenidAction extends Action if ($other) { if ($other->id == $cur->id) { - $this->message(_('You already have this OpenID!')); + $this->message(_m('You already have this OpenID!')); } else { - $this->message(_('Someone else already has this OpenID.')); + $this->message(_m('Someone else already has this OpenID.')); } return; } @@ -123,12 +123,12 @@ class FinishaddopenidAction extends Action $result = oid_link_user($cur->id, $canonical, $display); if (!$result) { - $this->message(_('Error connecting user.')); + $this->message(_m('Error connecting user.')); return; } if ($sreg) { if (!oid_update_user($cur, $sreg)) { - $this->message(_('Error updating profile')); + $this->message(_m('Error updating profile')); return; } } @@ -167,7 +167,7 @@ class FinishaddopenidAction extends Action function title() { - return _('OpenID Login'); + return _m('OpenID Login'); } /** diff --git a/plugins/OpenID/finishopenidlogin.php b/plugins/OpenID/finishopenidlogin.php index e5551b412..987fa9213 100644 --- a/plugins/OpenID/finishopenidlogin.php +++ b/plugins/OpenID/finishopenidlogin.php @@ -31,16 +31,16 @@ class FinishopenidloginAction extends Action { parent::handle($args); if (common_is_real_login()) { - $this->clientError(_('Already logged in.')); + $this->clientError(_m('Already logged in.')); } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. Try again, please.')); + $this->showForm(_m('There was a problem with your session token. Try again, please.')); return; } if ($this->arg('create')) { if (!$this->boolean('license')) { - $this->showForm(_('You can\'t register if you don\'t agree to the license.'), + $this->showForm(_m('You can\'t register if you don\'t agree to the license.'), $this->trimmed('newname')); return; } @@ -49,7 +49,7 @@ class FinishopenidloginAction extends Action $this->connectUser(); } else { common_debug(print_r($this->args, true), __FILE__); - $this->showForm(_('Something weird happened.'), + $this->showForm(_m('Something weird happened.'), $this->trimmed('newname')); } } else { @@ -63,13 +63,13 @@ class FinishopenidloginAction extends Action $this->element('div', array('class' => 'error'), $this->error); } else { $this->element('div', 'instructions', - sprintf(_('This is the first time you\'ve logged into %s so we must connect your OpenID to a local account. You can either create a new account, or connect with your existing account, if you have one.'), common_config('site', 'name'))); + sprintf(_m('This is the first time you\'ve logged into %s so we must connect your OpenID to a local account. You can either create a new account, or connect with your existing account, if you have one.'), common_config('site', 'name'))); } } function title() { - return _('OpenID Account Setup'); + return _m('OpenID Account Setup'); } function showForm($error=null, $username=null) @@ -94,14 +94,14 @@ class FinishopenidloginAction extends Action $this->hidden('token', common_session_token()); $this->elementStart('fieldset', array('id' => 'form_openid_createaccount')); $this->element('legend', null, - _('Create new account')); + _m('Create new account')); $this->element('p', null, - _('Create a new user with this nickname.')); + _m('Create a new user with this nickname.')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->input('newname', _('New nickname'), + $this->input('newname', _m('New nickname'), ($this->username) ? $this->username : '', - _('1-64 lowercase letters or numbers, no punctuation or spaces')); + _m('1-64 lowercase letters or numbers, no punctuation or spaces')); $this->elementEnd('li'); $this->elementStart('li'); $this->element('input', array('type' => 'checkbox', @@ -111,30 +111,30 @@ class FinishopenidloginAction extends Action 'value' => 'true')); $this->elementStart('label', array('for' => 'license', 'class' => 'checkbox')); - $this->text(_('My text and files are available under ')); + $this->text(_m('My text and files are available under ')); $this->element('a', array('href' => common_config('license', 'url')), common_config('license', 'title')); - $this->text(_(' except this private data: password, email address, IM address, phone number.')); + $this->text(_m(' except this private data: password, email address, IM address, phone number.')); $this->elementEnd('label'); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('create', _('Create')); + $this->submit('create', _m('Create')); $this->elementEnd('fieldset'); $this->elementStart('fieldset', array('id' => 'form_openid_createaccount')); $this->element('legend', null, - _('Connect existing account')); + _m('Connect existing account')); $this->element('p', null, - _('If you already have an account, login with your username and password to connect it to your OpenID.')); + _m('If you already have an account, login with your username and password to connect it to your OpenID.')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->input('nickname', _('Existing nickname')); + $this->input('nickname', _m('Existing nickname')); $this->elementEnd('li'); $this->elementStart('li'); - $this->password('password', _('Password')); + $this->password('password', _m('Password')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('connect', _('Connect')); + $this->submit('connect', _m('Connect')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } @@ -146,11 +146,11 @@ class FinishopenidloginAction extends Action $response = $consumer->complete(common_local_url('finishopenidlogin')); if ($response->status == Auth_OpenID_CANCEL) { - $this->message(_('OpenID authentication cancelled.')); + $this->message(_m('OpenID authentication cancelled.')); return; } else if ($response->status == Auth_OpenID_FAILURE) { // Authentication failed; display the error message. - $this->message(sprintf(_('OpenID authentication failed: %s'), $response->message)); + $this->message(sprintf(_m('OpenID authentication failed: %s'), $response->message)); } else if ($response->status == Auth_OpenID_SUCCESS) { // This means the authentication succeeded; extract the // identity URL and Simple Registration data (if it was @@ -212,7 +212,7 @@ class FinishopenidloginAction extends Action # FIXME: save invite code before redirect, and check here if (common_config('site', 'closed')) { - $this->clientError(_('Registration not allowed.')); + $this->clientError(_m('Registration not allowed.')); return; } @@ -221,14 +221,14 @@ class FinishopenidloginAction extends Action if (common_config('site', 'inviteonly')) { $code = $_SESSION['invitecode']; if (empty($code)) { - $this->clientError(_('Registration not allowed.')); + $this->clientError(_m('Registration not allowed.')); return; } $invite = Invitation::staticGet($code); if (empty($invite)) { - $this->clientError(_('Not a valid invitation code.')); + $this->clientError(_m('Not a valid invitation code.')); return; } } @@ -238,24 +238,24 @@ class FinishopenidloginAction extends Action if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, 'format' => NICKNAME_FMT))) { - $this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.')); + $this->showForm(_m('Nickname must have only lowercase letters and numbers and no spaces.')); return; } if (!User::allowed_nickname($nickname)) { - $this->showForm(_('Nickname not allowed.')); + $this->showForm(_m('Nickname not allowed.')); return; } if (User::staticGet('nickname', $nickname)) { - $this->showForm(_('Nickname already in use. Try another one.')); + $this->showForm(_m('Nickname already in use. Try another one.')); return; } list($display, $canonical, $sreg) = $this->getSavedValues(); if (!$display || !$canonical) { - $this->serverError(_('Stored OpenID not found.')); + $this->serverError(_m('Stored OpenID not found.')); return; } @@ -264,7 +264,7 @@ class FinishopenidloginAction extends Action $other = oid_get_user($canonical); if ($other) { - $this->serverError(_('Creating new account for OpenID that already has a user.')); + $this->serverError(_m('Creating new account for OpenID that already has a user.')); return; } @@ -324,7 +324,7 @@ class FinishopenidloginAction extends Action $password = $this->trimmed('password'); if (!common_check_user($nickname, $password)) { - $this->showForm(_('Invalid username or password.')); + $this->showForm(_m('Invalid username or password.')); return; } @@ -335,14 +335,14 @@ class FinishopenidloginAction extends Action list($display, $canonical, $sreg) = $this->getSavedValues(); if (!$display || !$canonical) { - $this->serverError(_('Stored OpenID not found.')); + $this->serverError(_m('Stored OpenID not found.')); return; } $result = oid_link_user($user->id, $canonical, $display); if (!$result) { - $this->serverError(_('Error connecting user to OpenID.')); + $this->serverError(_m('Error connecting user to OpenID.')); return; } diff --git a/plugins/OpenID/locale/OpenID.po b/plugins/OpenID/locale/OpenID.po new file mode 100644 index 000000000..34738bc75 --- /dev/null +++ b/plugins/OpenID/locale/OpenID.po @@ -0,0 +1,344 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-07 20:38-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: openidlogin.php:30 finishopenidlogin.php:34 +msgid "Already logged in." +msgstr "" + +#: openidlogin.php:37 openidsettings.php:194 finishopenidlogin.php:38 +msgid "There was a problem with your session token. Try again, please." +msgstr "" + +#: openidlogin.php:66 +#, php-format +msgid "" +"For security reasons, please re-login with your [OpenID](%%doc.openid%%) " +"before changing your settings." +msgstr "" + +#: openidlogin.php:70 +#, php-format +msgid "Login with an [OpenID](%%doc.openid%%) account." +msgstr "" + +#: openidlogin.php:95 finishaddopenid.php:170 +msgid "OpenID Login" +msgstr "" + +#: openidlogin.php:112 +msgid "OpenID login" +msgstr "" + +#: openidlogin.php:117 openidsettings.php:107 +msgid "OpenID URL" +msgstr "" + +#: openidlogin.php:119 +msgid "Your OpenID URL" +msgstr "" + +#: openidlogin.php:122 +msgid "Remember me" +msgstr "" + +#: openidlogin.php:123 +msgid "Automatically login in the future; not for shared computers!" +msgstr "" + +#: openidlogin.php:127 +msgid "Login" +msgstr "" + +#: openidserver.php:106 +#, php-format +msgid "You are not authorized to use the identity %s" +msgstr "" + +#: openidserver.php:126 +msgid "Just an OpenID provider. Nothing to see here, move along..." +msgstr "" + +#: OpenIDPlugin.php:123 OpenIDPlugin.php:135 +msgid "OpenID" +msgstr "" + +#: OpenIDPlugin.php:124 +msgid "Login or register with OpenID" +msgstr "" + +#: OpenIDPlugin.php:136 +msgid "Add or remove OpenIDs" +msgstr "" + +#: openid.php:141 +msgid "Cannot instantiate OpenID consumer object." +msgstr "" + +#: openid.php:151 +msgid "Not a valid OpenID." +msgstr "" + +#: openid.php:153 +#, php-format +msgid "OpenID failure: %s" +msgstr "" + +#: openid.php:180 +#, php-format +msgid "Could not redirect to server: %s" +msgstr "" + +#: openid.php:198 +#, php-format +msgid "Could not create OpenID form: %s" +msgstr "" + +#: openid.php:214 +msgid "" +"This form should automatically submit itself. If not, click the submit " +"button to go to your OpenID provider." +msgstr "" + +#: openid.php:246 +msgid "Error saving the profile." +msgstr "" + +#: openid.php:257 +msgid "Error saving the user." +msgstr "" + +#: openid.php:277 +msgid "OpenID Auto-Submit" +msgstr "" + +#: openidtrust.php:51 +msgid "OpenID Identity Verification" +msgstr "" + +#: openidtrust.php:69 +msgid "" +"This page should only be reached during OpenID processing, not directly." +msgstr "" + +#: openidtrust.php:118 +#, php-format +msgid "" +"%s has asked to verify your identity. Click Continue to verify your " +"identity and login without creating a new password." +msgstr "" + +#: openidtrust.php:136 +msgid "Continue" +msgstr "" + +#: openidtrust.php:137 +msgid "Cancel" +msgstr "" + +#: finishaddopenid.php:67 +msgid "Not logged in." +msgstr "" + +#: finishaddopenid.php:88 finishopenidlogin.php:149 +msgid "OpenID authentication cancelled." +msgstr "" + +#: finishaddopenid.php:92 finishopenidlogin.php:153 +#, php-format +msgid "OpenID authentication failed: %s" +msgstr "" + +#: finishaddopenid.php:112 +msgid "You already have this OpenID!" +msgstr "" + +#: finishaddopenid.php:114 +msgid "Someone else already has this OpenID." +msgstr "" + +#: finishaddopenid.php:126 +msgid "Error connecting user." +msgstr "" + +#: finishaddopenid.php:131 +msgid "Error updating profile" +msgstr "" + +#: openidsettings.php:59 +msgid "OpenID settings" +msgstr "" + +#: openidsettings.php:70 +#, php-format +msgid "" +"[OpenID](%%doc.openid%%) lets you log into many sites with the same user " +"account. Manage your associated OpenIDs from here." +msgstr "" + +#: openidsettings.php:99 +msgid "Add OpenID" +msgstr "" + +#: openidsettings.php:102 +msgid "" +"If you want to add an OpenID to your account, enter it in the box below and " +"click \"Add\"." +msgstr "" + +#: openidsettings.php:117 +msgid "Add" +msgstr "" + +#: openidsettings.php:129 +msgid "Remove OpenID" +msgstr "" + +#: openidsettings.php:134 +msgid "" +"Removing your only OpenID would make it impossible to log in! If you need to " +"remove it, add another OpenID first." +msgstr "" + +#: openidsettings.php:149 +msgid "" +"You can remove an OpenID from your account by clicking the button marked " +"\"Remove\"." +msgstr "" + +#: openidsettings.php:172 +msgid "Remove" +msgstr "" + +#: openidsettings.php:208 finishopenidlogin.php:52 +msgid "Something weird happened." +msgstr "" + +#: openidsettings.php:228 +msgid "No such OpenID." +msgstr "" + +#: openidsettings.php:233 +msgid "That OpenID does not belong to you." +msgstr "" + +#: openidsettings.php:237 +msgid "OpenID removed." +msgstr "" + +#: finishopenidlogin.php:43 +msgid "You can't register if you don't agree to the license." +msgstr "" + +#: finishopenidlogin.php:66 +#, php-format +msgid "" +"This is the first time you've logged into %s so we must connect your OpenID " +"to a local account. You can either create a new account, or connect with " +"your existing account, if you have one." +msgstr "" + +#: finishopenidlogin.php:72 +msgid "OpenID Account Setup" +msgstr "" + +#: finishopenidlogin.php:97 +msgid "Create new account" +msgstr "" + +#: finishopenidlogin.php:99 +msgid "Create a new user with this nickname." +msgstr "" + +#: finishopenidlogin.php:102 +msgid "New nickname" +msgstr "" + +#: finishopenidlogin.php:104 +msgid "1-64 lowercase letters or numbers, no punctuation or spaces" +msgstr "" + +#: finishopenidlogin.php:114 +msgid "My text and files are available under " +msgstr "" + +#: finishopenidlogin.php:117 +msgid "" +" except this private data: password, email address, IM address, phone number." +msgstr "" + +#: finishopenidlogin.php:121 +msgid "Create" +msgstr "" + +#: finishopenidlogin.php:126 +msgid "Connect existing account" +msgstr "" + +#: finishopenidlogin.php:128 +msgid "" +"If you already have an account, login with your username and password to " +"connect it to your OpenID." +msgstr "" + +#: finishopenidlogin.php:131 +msgid "Existing nickname" +msgstr "" + +#: finishopenidlogin.php:134 +msgid "Password" +msgstr "" + +#: finishopenidlogin.php:137 +msgid "Connect" +msgstr "" + +#: finishopenidlogin.php:215 finishopenidlogin.php:224 +msgid "Registration not allowed." +msgstr "" + +#: finishopenidlogin.php:231 +msgid "Not a valid invitation code." +msgstr "" + +#: finishopenidlogin.php:241 +msgid "Nickname must have only lowercase letters and numbers and no spaces." +msgstr "" + +#: finishopenidlogin.php:246 +msgid "Nickname not allowed." +msgstr "" + +#: finishopenidlogin.php:251 +msgid "Nickname already in use. Try another one." +msgstr "" + +#: finishopenidlogin.php:258 finishopenidlogin.php:338 +msgid "Stored OpenID not found." +msgstr "" + +#: finishopenidlogin.php:267 +msgid "Creating new account for OpenID that already has a user." +msgstr "" + +#: finishopenidlogin.php:327 +msgid "Invalid username or password." +msgstr "" + +#: finishopenidlogin.php:345 +msgid "Error connecting user to OpenID." +msgstr "" diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php index dd628e773..8f949c9c5 100644 --- a/plugins/OpenID/openid.php +++ b/plugins/OpenID/openid.php @@ -138,7 +138,7 @@ function oid_authenticate($openid_url, $returnto, $immediate=false) $consumer = oid_consumer(); if (!$consumer) { - common_server_error(_('Cannot instantiate OpenID consumer object.')); + common_server_error(_m('Cannot instantiate OpenID consumer object.')); return false; } @@ -148,9 +148,9 @@ function oid_authenticate($openid_url, $returnto, $immediate=false) // Handle failure status return values. if (!$auth_request) { - return _('Not a valid OpenID.'); + return _m('Not a valid OpenID.'); } else if (Auth_OpenID::isFailure($auth_request)) { - return sprintf(_('OpenID failure: %s'), $auth_request->message); + return sprintf(_m('OpenID failure: %s'), $auth_request->message); } $sreg_request = Auth_OpenID_SRegRequest::build(// Required @@ -177,7 +177,7 @@ function oid_authenticate($openid_url, $returnto, $immediate=false) $immediate); if (!$redirect_url) { } else if (Auth_OpenID::isFailure($redirect_url)) { - return sprintf(_('Could not redirect to server: %s'), $redirect_url->message); + return sprintf(_m('Could not redirect to server: %s'), $redirect_url->message); } else { common_redirect($redirect_url, 303); } @@ -195,7 +195,7 @@ function oid_authenticate($openid_url, $returnto, $immediate=false) // Display an error if the form markup couldn't be generated; // otherwise, render the HTML. if (Auth_OpenID::isFailure($form_html)) { - common_server_error(sprintf(_('Could not create OpenID form: %s'), $form_html->message)); + common_server_error(sprintf(_m('Could not create OpenID form: %s'), $form_html->message)); } else { $action = new AutosubmitAction(); // see below $action->form_html = $form_html; @@ -211,7 +211,7 @@ function oid_authenticate($openid_url, $returnto, $immediate=false) function _oid_print_instructions() { common_element('div', 'instructions', - _('This form should automatically submit itself. '. + _m('This form should automatically submit itself. '. 'If not, click the submit button to go to your '. 'OpenID provider.')); } @@ -243,7 +243,7 @@ function oid_update_user(&$user, &$sreg) # XXX save timezone if it's passed if (!$profile->update($orig_profile)) { - common_server_error(_('Error saving the profile.')); + common_server_error(_m('Error saving the profile.')); return false; } @@ -254,7 +254,7 @@ function oid_update_user(&$user, &$sreg) } if (!$user->update($orig_user)) { - common_server_error(_('Error saving the user.')); + common_server_error(_m('Error saving the user.')); return false; } @@ -274,7 +274,7 @@ class AutosubmitAction extends Action function title() { - return _('OpenID Auto-Submit'); + return _m('OpenID Auto-Submit'); } function showContent() diff --git a/plugins/OpenID/openidlogin.php b/plugins/OpenID/openidlogin.php index 29e89234e..9ba55911c 100644 --- a/plugins/OpenID/openidlogin.php +++ b/plugins/OpenID/openidlogin.php @@ -27,14 +27,14 @@ class OpenidloginAction extends Action { parent::handle($args); if (common_is_real_login()) { - $this->clientError(_('Already logged in.')); + $this->clientError(_m('Already logged in.')); } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { $openid_url = $this->trimmed('openid_url'); # CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. Try again, please.'), $openid_url); + $this->showForm(_m('There was a problem with your session token. Try again, please.'), $openid_url); return; } @@ -63,11 +63,11 @@ class OpenidloginAction extends Action common_get_returnto()) { // rememberme logins have to reauthenticate before // changing any profile settings (cookie-stealing protection) - return _('For security reasons, please re-login with your ' . + return _m('For security reasons, please re-login with your ' . '[OpenID](%%doc.openid%%) ' . 'before changing your settings.'); } else { - return _('Login with an [OpenID](%%doc.openid%%) account.'); + return _m('Login with an [OpenID](%%doc.openid%%) account.'); } } @@ -92,7 +92,7 @@ class OpenidloginAction extends Action function title() { - return _('OpenID Login'); + return _m('OpenID Login'); } function showForm($error=null, $openid_url) @@ -109,22 +109,22 @@ class OpenidloginAction extends Action 'class' => 'form_settings', 'action' => $formaction)); $this->elementStart('fieldset'); - $this->element('legend', null, _('OpenID login')); + $this->element('legend', null, _m('OpenID login')); $this->hidden('token', common_session_token()); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->input('openid_url', _('OpenID URL'), + $this->input('openid_url', _m('OpenID URL'), $this->openid_url, - _('Your OpenID URL')); + _m('Your OpenID URL')); $this->elementEnd('li'); $this->elementStart('li', array('id' => 'settings_rememberme')); - $this->checkbox('rememberme', _('Remember me'), false, - _('Automatically login in the future; ' . + $this->checkbox('rememberme', _m('Remember me'), false, + _m('Automatically login in the future; ' . 'not for shared computers!')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('submit', _('Login')); + $this->submit('submit', _m('Login')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/plugins/OpenID/openidserver.php b/plugins/OpenID/openidserver.php index dab97c93e..181cbdf45 100644 --- a/plugins/OpenID/openidserver.php +++ b/plugins/OpenID/openidserver.php @@ -103,7 +103,7 @@ class OpenidserverAction extends Action $response = $this->generateDenyResponse($request); } else { //invalid - $this->clientError(sprintf(_('You are not authorized to use the identity %s'),$request->identity),$code=403); + $this->clientError(sprintf(_m('You are not authorized to use the identity %s'),$request->identity),$code=403); } } else { $response = $this->oserver->handleRequest($request); @@ -123,7 +123,7 @@ class OpenidserverAction extends Action } $this->raw($response->body); }else{ - $this->clientError(_('Just an OpenID provider. Nothing to see here, move along...'),$code=500); + $this->clientError(_m('Just an OpenID provider. Nothing to see here, move along...'),$code=500); } } diff --git a/plugins/OpenID/openidsettings.php b/plugins/OpenID/openidsettings.php index 3ad46f5f5..3fc3d6128 100644 --- a/plugins/OpenID/openidsettings.php +++ b/plugins/OpenID/openidsettings.php @@ -56,7 +56,7 @@ class OpenidsettingsAction extends AccountSettingsAction function title() { - return _('OpenID settings'); + return _m('OpenID settings'); } /** @@ -67,7 +67,7 @@ class OpenidsettingsAction extends AccountSettingsAction function getInstructions() { - return _('[OpenID](%%doc.openid%%) lets you log into many sites' . + return _m('[OpenID](%%doc.openid%%) lets you log into many sites' . ' with the same user account.'. ' Manage your associated OpenIDs from here.'); } @@ -96,15 +96,15 @@ class OpenidsettingsAction extends AccountSettingsAction 'action' => common_local_url('openidsettings'))); $this->elementStart('fieldset', array('id' => 'settings_openid_add')); - $this->element('legend', null, _('Add OpenID')); + $this->element('legend', null, _m('Add OpenID')); $this->hidden('token', common_session_token()); $this->element('p', 'form_guide', - _('If you want to add an OpenID to your account, ' . + _m('If you want to add an OpenID to your account, ' . 'enter it in the box below and click "Add".')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->element('label', array('for' => 'openid_url'), - _('OpenID URL')); + _m('OpenID URL')); $this->element('input', array('name' => 'openid_url', 'type' => 'text', 'id' => 'openid_url')); @@ -114,7 +114,7 @@ class OpenidsettingsAction extends AccountSettingsAction 'id' => 'settings_openid_add_action-submit', 'name' => 'add', 'class' => 'submit', - 'value' => _('Add'))); + 'value' => _m('Add'))); $this->elementEnd('fieldset'); $this->elementEnd('form'); @@ -126,12 +126,12 @@ class OpenidsettingsAction extends AccountSettingsAction if ($cnt > 0) { - $this->element('h2', null, _('Remove OpenID')); + $this->element('h2', null, _m('Remove OpenID')); if ($cnt == 1 && !$user->password) { $this->element('p', 'form_guide', - _('Removing your only OpenID '. + _m('Removing your only OpenID '. 'would make it impossible to log in! ' . 'If you need to remove it, '. 'add another OpenID first.')); @@ -146,7 +146,7 @@ class OpenidsettingsAction extends AccountSettingsAction } else { $this->element('p', 'form_guide', - _('You can remove an OpenID from your account '. + _m('You can remove an OpenID from your account '. 'by clicking the button marked "Remove".')); $idx = 0; @@ -169,7 +169,7 @@ class OpenidsettingsAction extends AccountSettingsAction 'id' => 'remove'.$idx, 'name' => 'remove', 'class' => 'submit remove', - 'value' => _('Remove'))); + 'value' => _m('Remove'))); $this->elementEnd('fieldset'); $this->elementEnd('form'); $idx++; @@ -191,7 +191,7 @@ class OpenidsettingsAction extends AccountSettingsAction // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. '. + $this->showForm(_m('There was a problem with your session token. '. 'Try again, please.')); return; } @@ -205,7 +205,7 @@ class OpenidsettingsAction extends AccountSettingsAction } else if ($this->arg('remove')) { $this->removeOpenid(); } else { - $this->showForm(_('Something weird happened.')); + $this->showForm(_m('Something weird happened.')); } } @@ -225,16 +225,16 @@ class OpenidsettingsAction extends AccountSettingsAction $oid = User_openid::staticGet('canonical', $openid_url); if (!$oid) { - $this->showForm(_('No such OpenID.')); + $this->showForm(_m('No such OpenID.')); return; } $cur = common_current_user(); if (!$cur || $oid->user_id != $cur->id) { - $this->showForm(_('That OpenID does not belong to you.')); + $this->showForm(_m('That OpenID does not belong to you.')); return; } $oid->delete(); - $this->showForm(_('OpenID removed.'), true); + $this->showForm(_m('OpenID removed.'), true); return; } } diff --git a/plugins/OpenID/openidtrust.php b/plugins/OpenID/openidtrust.php index 29c7bdc23..fa7ea36e2 100644 --- a/plugins/OpenID/openidtrust.php +++ b/plugins/OpenID/openidtrust.php @@ -48,7 +48,7 @@ class OpenidtrustAction extends Action function title() { - return _('OpenID Identity Verification'); + return _m('OpenID Identity Verification'); } function prepare($args) @@ -66,7 +66,7 @@ class OpenidtrustAction extends Action $this->allowUrl = $_SESSION['openid_allow_url']; $this->denyUrl = $_SESSION['openid_deny_url']; if(empty($this->trust_root) || empty($this->allowUrl) || empty($this->denyUrl)){ - $this->clientError(_('This page should only be reached during OpenID processing, not directly.')); + $this->clientError(_m('This page should only be reached during OpenID processing, not directly.')); return; } return true; @@ -115,7 +115,7 @@ class OpenidtrustAction extends Action function showPageNotice() { - $this->element('p',null,sprintf(_('%s has asked to verify your identity. Click Continue to verify your identity and login without creating a new password.'),$this->trust_root)); + $this->element('p',null,sprintf(_m('%s has asked to verify your identity. Click Continue to verify your identity and login without creating a new password.'),$this->trust_root)); } /** @@ -133,8 +133,8 @@ class OpenidtrustAction extends Action 'class' => 'form_settings', 'action' => common_local_url('openidtrust'))); $this->elementStart('fieldset'); - $this->submit('allow', _('Continue')); - $this->submit('deny', _('Cancel')); + $this->submit('allow', _m('Continue')); + $this->submit('deny', _m('Cancel')); $this->elementEnd('fieldset'); $this->elementEnd('form'); diff --git a/plugins/Sample/SamplePlugin.php b/plugins/Sample/SamplePlugin.php new file mode 100644 index 000000000..6e361aafb --- /dev/null +++ b/plugins/Sample/SamplePlugin.php @@ -0,0 +1,59 @@ +. + */ + +/** + * @package SamplePlugin + * @maintainer Your Name + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +class SamplePlugin extends Plugin +{ + function onInitializePlugin() + { + // Event handlers normally return true to indicate that all is well. + // + // Returning false will cancel further processing of any other + // plugins or core code hooking the same event. + return true; + } + + /** + * Hook for RouterInitialized event. + * + * @param Net_URL_Mapper $m path-to-action mapper + * @return boolean hook return + */ + + function onRouterInitialized($m) + { + $m->connect(':nickname/samples', + array('action' => 'showsamples'), + array('feed' => '[A-Za-z0-9_-]+')); + $m->connect('settings/sample', + array('action' => 'samplesettings')); + return true; + } +} + diff --git a/plugins/TwitterBridge/TwitterBridgePlugin.php b/plugins/TwitterBridge/TwitterBridgePlugin.php index adf9ceda3..de1181903 100644 --- a/plugins/TwitterBridge/TwitterBridgePlugin.php +++ b/plugins/TwitterBridge/TwitterBridgePlugin.php @@ -86,8 +86,8 @@ class TwitterBridgePlugin extends Plugin $action_name = $action->trimmed('action'); $action->menuItem(common_local_url('twittersettings'), - _('Twitter'), - _('Twitter integration options'), + _m('Twitter'), + _m('Twitter integration options'), $action_name === 'twittersettings'); return true; diff --git a/plugins/TwitterBridge/locale/TwitterBridge.po b/plugins/TwitterBridge/locale/TwitterBridge.po new file mode 100644 index 000000000..14c30f1c9 --- /dev/null +++ b/plugins/TwitterBridge/locale/TwitterBridge.po @@ -0,0 +1,128 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-07 20:38-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: twitterauthorization.php:81 +msgid "Not logged in." +msgstr "" + +#: twitterauthorization.php:131 twitterauthorization.php:150 +#: twitterauthorization.php:170 twitterauthorization.php:217 +msgid "Couldn't link your Twitter account." +msgstr "" + +#: TwitterBridgePlugin.php:89 +msgid "Twitter" +msgstr "" + +#: TwitterBridgePlugin.php:90 +msgid "Twitter integration options" +msgstr "" + +#: twittersettings.php:59 +msgid "Twitter settings" +msgstr "" + +#: twittersettings.php:70 +msgid "" +"Connect your Twitter account to share your updates with your Twitter friends " +"and vice-versa." +msgstr "" + +#: twittersettings.php:118 +msgid "Twitter account" +msgstr "" + +#: twittersettings.php:123 +msgid "Connected Twitter account" +msgstr "" + +#: twittersettings.php:125 +msgid "Remove" +msgstr "" + +#: twittersettings.php:131 +msgid "Preferences" +msgstr "" + +#: twittersettings.php:135 +msgid "Automatically send my notices to Twitter." +msgstr "" + +#: twittersettings.php:142 +msgid "Send local \"@\" replies to Twitter." +msgstr "" + +#: twittersettings.php:149 +msgid "Subscribe to my Twitter friends here." +msgstr "" + +#: twittersettings.php:158 +msgid "Import my Friends Timeline." +msgstr "" + +#: twittersettings.php:174 +msgid "Save" +msgstr "" + +#: twittersettings.php:176 +msgid "Add" +msgstr "" + +#: twittersettings.php:201 +msgid "There was a problem with your session token. Try again, please." +msgstr "" + +#: twittersettings.php:211 +msgid "Unexpected form submission." +msgstr "" + +#: twittersettings.php:230 +msgid "Couldn't remove Twitter user." +msgstr "" + +#: twittersettings.php:234 +msgid "Twitter account removed." +msgstr "" + +#: twittersettings.php:255 twittersettings.php:265 +msgid "Couldn't save Twitter preferences." +msgstr "" + +#: twittersettings.php:269 +msgid "Twitter preferences saved." +msgstr "" + +#: twitter.php:333 +msgid "Your Twitter bridge has been disabled." +msgstr "" + +#: twitter.php:337 +#, php-format +msgid "" +"Hi, %1$s. We're sorry to inform you that your link to Twitter has been " +"disabled. We no longer seem to have permission to update your Twitter " +"status. (Did you revoke %3$s's access?)\n" +"\n" +"You can re-enable your Twitter bridge by visiting your Twitter settings " +"page:\n" +"\n" +"\t%2$s\n" +"\n" +"Regards,\n" +"%3$s\n" +msgstr "" diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php index fd5150638..b338a200d 100644 --- a/plugins/TwitterBridge/twitter.php +++ b/plugins/TwitterBridge/twitter.php @@ -330,11 +330,11 @@ function mail_twitter_bridge_removed($user) $profile = $user->getProfile(); - $subject = sprintf(_('Your Twitter bridge has been disabled.')); + $subject = sprintf(_m('Your Twitter bridge has been disabled.')); $site_name = common_config('site', 'name'); - $body = sprintf(_('Hi, %1$s. We\'re sorry to inform you that your ' . + $body = sprintf(_m('Hi, %1$s. We\'re sorry to inform you that your ' . 'link to Twitter has been disabled. We no longer seem to have ' . 'permission to update your Twitter status. (Did you revoke ' . '%3$s\'s access?)' . "\n\n" . diff --git a/plugins/TwitterBridge/twitterauthorization.php b/plugins/TwitterBridge/twitterauthorization.php index f1daefab1..4af2f0394 100644 --- a/plugins/TwitterBridge/twitterauthorization.php +++ b/plugins/TwitterBridge/twitterauthorization.php @@ -78,7 +78,7 @@ class TwitterauthorizationAction extends Action parent::handle($args); if (!common_logged_in()) { - $this->clientError(_('Not logged in.'), 403); + $this->clientError(_m('Not logged in.'), 403); } $user = common_current_user(); @@ -128,7 +128,7 @@ class TwitterauthorizationAction extends Action } catch (OAuthClientException $e) { $msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s', $e->getCode(), $e->getMessage()); - $this->serverError(_('Couldn\'t link your Twitter account.')); + $this->serverError(_m('Couldn\'t link your Twitter account.')); } common_redirect($auth_link); @@ -147,7 +147,7 @@ class TwitterauthorizationAction extends Action // token we sent them if ($_SESSION['twitter_request_token'] != $this->oauth_token) { - $this->serverError(_('Couldn\'t link your Twitter account.')); + $this->serverError(_m('Couldn\'t link your Twitter account.')); } try { @@ -167,7 +167,7 @@ class TwitterauthorizationAction extends Action } catch (OAuthClientException $e) { $msg = sprintf('OAuth client cURL error - code: %1$s, msg: %2$s', $e->getCode(), $e->getMessage()); - $this->serverError(_('Couldn\'t link your Twitter account.')); + $this->serverError(_m('Couldn\'t link your Twitter account.')); } // Save the access token and Twitter user info @@ -214,7 +214,7 @@ class TwitterauthorizationAction extends Action if (empty($flink_id)) { common_log_db_error($flink, 'INSERT', __FILE__); - $this->serverError(_('Couldn\'t link your Twitter account.')); + $this->serverError(_m('Couldn\'t link your Twitter account.')); } save_twitter_user($twitter_user->id, $twitter_user->screen_name); diff --git a/plugins/TwitterBridge/twittersettings.php b/plugins/TwitterBridge/twittersettings.php index ca22c9553..bc9a636a1 100644 --- a/plugins/TwitterBridge/twittersettings.php +++ b/plugins/TwitterBridge/twittersettings.php @@ -56,7 +56,7 @@ class TwittersettingsAction extends ConnectSettingsAction function title() { - return _('Twitter settings'); + return _m('Twitter settings'); } /** @@ -67,8 +67,8 @@ class TwittersettingsAction extends ConnectSettingsAction function getInstructions() { - return _('Connect your Twitter account to share your updates ' . - 'with your Twitter friends and vice-versa.'); + return _m('Connect your Twitter account to share your updates ' . + 'with your Twitter friends and vice-versa.'); } /** @@ -115,38 +115,38 @@ class TwittersettingsAction extends ConnectSettingsAction $this->elementEnd('fieldset'); } else { - $this->element('legend', null, _('Twitter account')); + $this->element('legend', null, _m('Twitter account')); $this->elementStart('p', array('id' => 'form_confirmed')); $this->element('a', array('href' => $fuser->uri), $fuser->nickname); $this->elementEnd('p'); $this->element('p', 'form_note', - _('Connected Twitter account')); + _m('Connected Twitter account')); - $this->submit('remove', _('Remove')); + $this->submit('remove', _m('Remove')); $this->elementEnd('fieldset'); $this->elementStart('fieldset', array('id' => 'settings_twitter_preferences')); - $this->element('legend', null, _('Preferences')); + $this->element('legend', null, _m('Preferences')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->checkbox('noticesend', - _('Automatically send my notices to Twitter.'), + _m('Automatically send my notices to Twitter.'), ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_SEND) : true); $this->elementEnd('li'); $this->elementStart('li'); $this->checkbox('replysync', - _('Send local "@" replies to Twitter.'), + _m('Send local "@" replies to Twitter.'), ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) : true); $this->elementEnd('li'); $this->elementStart('li'); $this->checkbox('friendsync', - _('Subscribe to my Twitter friends here.'), + _m('Subscribe to my Twitter friends here.'), ($flink) ? ($flink->friendsync & FOREIGN_FRIEND_RECV) : false); @@ -155,7 +155,7 @@ class TwittersettingsAction extends ConnectSettingsAction if (common_config('twitterimport','enabled')) { $this->elementStart('li'); $this->checkbox('noticerecv', - _('Import my Friends Timeline.'), + _m('Import my Friends Timeline.'), ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_RECV) : false); @@ -171,9 +171,9 @@ class TwittersettingsAction extends ConnectSettingsAction $this->elementEnd('ul'); if ($flink) { - $this->submit('save', _('Save')); + $this->submit('save', _m('Save')); } else { - $this->submit('add', _('Add')); + $this->submit('add', _m('Add')); } $this->elementEnd('fieldset'); @@ -198,8 +198,8 @@ class TwittersettingsAction extends ConnectSettingsAction // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. '. - 'Try again, please.')); + $this->showForm(_m('There was a problem with your session token. '. + 'Try again, please.')); return; } @@ -208,7 +208,7 @@ class TwittersettingsAction extends ConnectSettingsAction } else if ($this->arg('remove')) { $this->removeTwitterAccount(); } else { - $this->showForm(_('Unexpected form submission.')); + $this->showForm(_m('Unexpected form submission.')); } } @@ -227,11 +227,11 @@ class TwittersettingsAction extends ConnectSettingsAction if (empty($result)) { common_log_db_error($flink, 'DELETE', __FILE__); - $this->serverError(_('Couldn\'t remove Twitter user.')); + $this->serverError(_m('Couldn\'t remove Twitter user.')); return; } - $this->showForm(_('Twitter account removed.'), true); + $this->showForm(_m('Twitter account removed.'), true); } /** @@ -252,7 +252,7 @@ class TwittersettingsAction extends ConnectSettingsAction if (empty($flink)) { common_log_db_error($flink, 'SELECT', __FILE__); - $this->showForm(_('Couldn\'t save Twitter preferences.')); + $this->showForm(_m('Couldn\'t save Twitter preferences.')); return; } @@ -262,11 +262,11 @@ class TwittersettingsAction extends ConnectSettingsAction if ($result === false) { common_log_db_error($flink, 'UPDATE', __FILE__); - $this->showForm(_('Couldn\'t save Twitter preferences.')); + $this->showForm(_m('Couldn\'t save Twitter preferences.')); return; } - $this->showForm(_('Twitter preferences saved.'), true); + $this->showForm(_m('Twitter preferences saved.'), true); } } diff --git a/scripts/update_po_templates.php b/scripts/update_po_templates.php new file mode 100755 index 000000000..83bff6d80 --- /dev/null +++ b/scripts/update_po_templates.php @@ -0,0 +1,211 @@ +#!/usr/bin/env php +. + */ + +// Abort if called from a web server +if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) { + print "This script must be run from the command line\n"; + exit(); +} + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); + +function update_core($dir, $domain) +{ + $old = getcwd(); + chdir($dir); + passthru(<<isDir() && !$item->isDot()) { + $name = $item->getBasename(); + if (file_exists("$dir/plugins/$name/{$name}Plugin.php")) { + $plugins[] = $name; + } + } + } + return $plugins; +} + +function get_plugin_sources($dir) +{ + $files = array(); + + $dirs = new RecursiveDirectoryIterator($dir); + $iter = new RecursiveIteratorIterator($dirs); + foreach ($iter as $pathname => $item) { + if ($item->isFile() && preg_match('/\.php$/', $item->getBaseName())) { + $files[] = $pathname; + } + } + return $files; +} + +function plugin_using_gettext($dir) +{ + $files = get_plugin_sources($dir); + foreach ($files as $pathname) { + // Check if the file is using our _m gettext wrapper + $code = file_get_contents($pathname); + if (preg_match('/\b_m\(/', $code)) { + return true; + } + } + + return false; +} + +function update_plugin($basedir, $name) +{ + $dir = "$basedir/plugins/$name"; + if (plugin_using_gettext($dir)) { + do_update_plugin($dir, $name); + do_translatewiki_plugin($basedir, $name); + return true; + } else { + return false; + } +} + +$args = $_SERVER['argv']; +array_shift($args); + +$all = false; +$core = false; +$allplugins = false; +$plugins = array(); +if (count($args) == 0) { + $all = true; +} +foreach ($args as $arg) { + if ($arg == '--all') { + $all = true; + } elseif ($arg == "--core") { + $core = true; + } elseif ($arg == "--plugins") { + $allplugins = true; + } elseif (substr($arg, 0, 9) == "--plugin=") { + $plugins[] = substr($arg, 9); + } +} + + + +if ($all || $core) { + echo "core..."; + update_core(INSTALLDIR, 'statusnet'); + echo " ok\n"; +} +if ($all || $allplugins) { + $plugins = get_plugins(INSTALLDIR); +} +if ($plugins) { + foreach ($plugins as $plugin) { + echo "$plugin..."; + if (update_plugin(INSTALLDIR, $plugin)) { + echo " ok\n"; + } else { + echo " not localized\n"; + } + } +} + diff --git a/scripts/update_pot.sh b/scripts/update_pot.sh deleted file mode 100755 index de53fe7c9..000000000 --- a/scripts/update_pot.sh +++ /dev/null @@ -1,13 +0,0 @@ -cd `dirname $0` -cd .. -xgettext \ - --from-code=UTF-8 \ - --default-domain=statusnet \ - --output=locale/statusnet.po \ - --language=PHP \ - --keyword="pgettext:1c,2" \ - --keyword="npgettext:1c,2,3" \ - actions/*.php \ - classes/*.php \ - lib/*.php \ - scripts/*.php -- cgit v1.2.3-54-g00ecf From 559415826a234c9d993535bc30f132af1e247160 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 9 Dec 2009 11:00:30 +0100 Subject: Added a todo list for Realtime plugin --- plugins/Realtime/README | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 plugins/Realtime/README (limited to 'plugins') diff --git a/plugins/Realtime/README b/plugins/Realtime/README new file mode 100644 index 000000000..f5e4f91cf --- /dev/null +++ b/plugins/Realtime/README @@ -0,0 +1,9 @@ +== TODO == +* i18n +* Change in context URL to conversation (try not to construct the URL in JS) +* Update mark behaviour (on notice send) +* Pause, Send a notice ~ should not update counter +* Pause ~ retain up to 50-100 most recent notices +* Add geo data +* Make it work for Conversation page (perhaps a little tricky) +* IE is updating the counter in document title all the time (Not sure if this is still an issue) -- cgit v1.2.3-54-g00ecf From 83830c26e746f9bccb149940ce67904d7e536851 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 9 Dec 2009 11:37:53 +0100 Subject: Added todo item to Realtime plugin --- plugins/Realtime/README | 2 ++ 1 file changed, 2 insertions(+) (limited to 'plugins') diff --git a/plugins/Realtime/README b/plugins/Realtime/README index f5e4f91cf..524382696 100644 --- a/plugins/Realtime/README +++ b/plugins/Realtime/README @@ -7,3 +7,5 @@ * Add geo data * Make it work for Conversation page (perhaps a little tricky) * IE is updating the counter in document title all the time (Not sure if this is still an issue) +* Reconsider the timestamp approach + -- cgit v1.2.3-54-g00ecf From 155659dd1fee44c011962432a3e2ef6d523f1a7d Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Wed, 9 Dec 2009 22:32:57 -0500 Subject: Initial GravatarPlugin --- plugins/Gravatar/GravatarPlugin.php | 176 ++++++++++++++++++++++++++++++++++++ plugins/Gravatar/README | 13 +++ 2 files changed, 189 insertions(+) create mode 100644 plugins/Gravatar/GravatarPlugin.php create mode 100644 plugins/Gravatar/README (limited to 'plugins') diff --git a/plugins/Gravatar/GravatarPlugin.php b/plugins/Gravatar/GravatarPlugin.php new file mode 100644 index 000000000..b18f62726 --- /dev/null +++ b/plugins/Gravatar/GravatarPlugin.php @@ -0,0 +1,176 @@ +. + */ + +/** + * @package GravatarPlugin + * @maintainer Eric Helgeson + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +class GravatarPlugin extends Plugin +{ + function onInitializePlugin() { + return true; + } + + function onStartAvatarFormData($action) { + $user = common_current_user(); + $hasGravatar = $this->hasGravatar($user->id); + + if($hasGravatar) { + return false; + } + } + + function onEndAvatarFormData(&$action) { + $user = common_current_user(); + $hasGravatar = $this->hasGravatar($user->id); + + if(!empty($user->email) && !$hasGravatar) { //and not gravatar already set + $action->elementStart('form', array('method' => 'post', + 'id' => 'form_settings_gravatar_add', + 'class' => 'form_settings', + 'action' => + common_local_url('avatarsettings'))); + $action->elementStart('fieldset', array('id' => 'settings_gravatar_add')); + $action->element('legend', null, _m('Set Gravatar')); + $action->hidden('token', common_session_token()); + $action->element('p', 'form_guide', + _m('If you want to use your Gravatar image, click "Add".')); + $action->element('input', array('type' => 'submit', + 'id' => 'settings_gravatar_add_action-submit', + 'name' => 'add', + 'class' => 'submit', + 'value' => _m('Add'))); + $action->elementEnd('fieldset'); + $action->elementEnd('form'); + } elseif($hasGravatar) { + $action->elementStart('form', array('method' => 'post', + 'id' => 'form_settings_gravatar_remove', + 'class' => 'form_settings', + 'action' => + common_local_url('avatarsettings'))); + $action->elementStart('fieldset', array('id' => 'settings_gravatar_remove')); + $action->element('legend', null, _m('Remove Gravatar')); + $action->hidden('token', common_session_token()); + $action->element('p', 'form_guide', + _m('If you want to remove your Gravatar image, click "Remove".')); + $action->element('input', array('type' => 'submit', + 'id' => 'settings_gravatar_remove_action-submit', + 'name' => 'remove', + 'class' => 'submit', + 'value' => _m('Remove'))); + $action->elementEnd('fieldset'); + $action->elementEnd('form'); + } else { + $action->element('p', 'form_guide', + _m('To use a Gravatar first enter in an email address.')); + } + } + + function onStartAvatarSaveForm($action) { + if ($action->arg('add')) { + $result = $this->gravatar_save(); + $action->showForm($result['message'], $result['success']); + return false; + } else if ($action->arg('remove')) { + $result = $this->gravatar_remove(); + $action->showForm($result['message'], $result['success']); + return false; + } else { + return true; + } + } + + function hasGravatar($id) { + $avatar = new Avatar(); + $avatar->profile_id = $id; + if ($avatar->find()) { + while ($avatar->fetch()) { + if($avatar->filename == null) { + return true; + } + } + } + return false; + } + + + function gravatar_save() + { + $cur = common_current_user(); + + if(empty($cur->email)) { + return array('message' => _m('You do not have a email set in your profile.'), + 'success' => false); + } + //Get rid of previous Avatar + $this->gravatar_remove(); + + foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) { + $gravatar = new Avatar(); + $gravatar->profile_id = $cur->id; + $gravatar->width = $size; + $gravatar->height = $size; + $gravatar->original = false; //No file, so no original + $gravatar->mediatype = 'img';//XXX: Unsure what to put here + //$gravatar->filename = null;//No filename. Remote + $gravatar->url = $this->gravatar_url($cur->email, $size); + $gravatar->created = DB_DataObject_Cast::dateTime(); # current time + + if (!$gravatar->insert()) { + return array('message' => _m('Failed to save Gravatar to the DB.'), + 'success' => false); + } + } + return array('message' => _m('Gravatar added.'), + 'success' => true); + } + + function gravatar_remove() + { + $user = common_current_user(); + $profile = $user->getProfile(); + + $avatar = $profile->getOriginalAvatar(); + if($avatar) $avatar->delete(); + $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); + if($avatar) $avatar->delete(); + $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); + if($avatar) $avatar->delete(); + $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); + if($avatar) $avatar->delete(); + + return array('message' => _m('Gravatar removed.'), + 'success' => true); + } + + function gravatar_url($email, $size) { + $url = "http://www.gravatar.com/avatar.php?gravatar_id=". + md5(strtolower($email)). + "&default=".urlencode(Avatar::defaultImage($size)). + "&size=".$size; + return $url; + } +} diff --git a/plugins/Gravatar/README b/plugins/Gravatar/README new file mode 100644 index 000000000..9337e24a0 --- /dev/null +++ b/plugins/Gravatar/README @@ -0,0 +1,13 @@ +GravatarPlugin 0.1 + +About +This will allow users to use their Gravatar Avatar with your StatusNet install. + +Configuration +add this to your config.php: +addPlugin('Gravatar', array()); + +ToDo: +Site default all on for gravatar by default +Migration Script +Localize \ No newline at end of file -- cgit v1.2.3-54-g00ecf From 144faade3b3d366fc6f3a254ce6b1c36bd4f4cdb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 10 Dec 2009 13:31:16 -0500 Subject: move forwarding stuff to Repeat plugin --- actions/forward.php | 122 ------------------------------------------- classes/Forward.php | 127 --------------------------------------------- plugins/Repeat/Forward.php | 127 +++++++++++++++++++++++++++++++++++++++++++++ plugins/Repeat/forward.php | 122 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 249 insertions(+), 249 deletions(-) delete mode 100644 actions/forward.php delete mode 100644 classes/Forward.php create mode 100644 plugins/Repeat/Forward.php create mode 100644 plugins/Repeat/forward.php (limited to 'plugins') diff --git a/actions/forward.php b/actions/forward.php deleted file mode 100644 index 194833fe0..000000000 --- a/actions/forward.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ - * - * StatusNet - the distributed open-source microblogging tool - * Copyright (C) 2008, 2009, StatusNet, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -if (!defined('STATUSNET')) { - exit(1); -} - -/** - * Forward action - * - * @category Action - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ - */ - -class ForwardAction extends Action -{ - var $user = null; - var $notice = null; - - function prepare($args) - { - parent::prepare($args); - - $this->user = common_current_user(); - - if (empty($this->user)) { - $this->clientError(_("Only logged-in users can forward notices.")); - return false; - } - - $id = $this->trimmed('notice'); - - if (empty($id)) { - $this->clientError(_("No notice specified.")); - return false; - } - - $this->notice = Notice::staticGet('id', $id); - - if (empty($this->notice)) { - $this->clientError(_("No notice specified.")); - return false; - } - - if ($this->user->id == $this->notice->profile_id) { - $this->clientError(_("You can't forward your own notice.")); - return false; - } - - $token = $this->trimmed('token-'.$id); - - if (empty($token) || $token != common_session_token()) { - $this->clientError(_("There was a problem with your session token. Try again, please.")); - return false; - } - - $profile = $this->user->getProfile(); - - if ($profile->hasForwarded($id)) { - $this->clientError(_("You already forwarded that notice.")); - return false; - } - - return true; - } - - /** - * Class handler. - * - * @param array $args query arguments - * - * @return void - */ - - function handle($args) - { - $forward = Forward::saveNew($this->user->id, $this->notice->id); - - if ($this->boolean('ajax')) { - $this->startHTML('text/xml;charset=utf-8'); - $this->elementStart('head'); - $this->element('title', null, _('Forwarded')); - $this->elementEnd('head'); - $this->elementStart('body'); - $this->element('p', array('id' => 'forward_response'), _('Forwarded!')); - $this->elementEnd('body'); - $this->elementEnd('html'); - } else { - // FIXME! - } - } -} diff --git a/classes/Forward.php b/classes/Forward.php deleted file mode 100644 index 09b2d6a4e..000000000 --- a/classes/Forward.php +++ /dev/null @@ -1,127 +0,0 @@ -. - */ - -if (!defined('STATUSNET')) { - exit(1); -} - -/** - * Table Definition for location_namespace - */ - -require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; - -class Forward extends Memcached_DataObject -{ - ###START_AUTOCODE - /* the code below is auto generated do not remove the above tag */ - - public $__table = 'forward'; // table name - public $profile_id; // int(4) primary_key not_null - public $notice_id; // int(4) primary_key not_null - public $created; // datetime not_null default_0000-00-00%2000%3A00%3A00 - - /* Static get */ - function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Forward',$k,$v); } - - /* the code above is auto generated do not remove the tag below */ - ###END_AUTOCODE - - function &pkeyGet($kv) - { - return Memcached_DataObject::pkeyGet('Forward', $kv); - } - - static function saveNew($profile_id, $notice_id) - { - $forward = new Forward(); - - $forward->profile_id = $profile_id; - $forward->notice_id = $notice_id; - $forward->created = common_sql_now(); - - $forward->query('BEGIN'); - - if (!$forward->insert()) { - throw new ServerException(_("Couldn't insert forward.")); - } - - $ni = $forward->addToInboxes(); - - $forward->query('COMMIT'); - - $forward->blowCache($ni); - - return $forward; - } - - function addToInboxes() - { - $inbox = new Notice_inbox(); - - $user = new User(); - - $usertable = common_database_tablename('user'); - $user->query("SELECT $usertable.* FROM $usertable INNER JOIN subscription ON $usertable.id = subscription.subscriber ". - 'WHERE subscription.subscribed = '.$this->profile_id); - - $ni = array(); - - $notice = Notice::staticGet('id', $this->notice_id); - - $author = Profile::staticGet('id', $notice->profile_id); - - while ($user->fetch()) { - $inbox = Notice_inbox::pkeyGet(array('user_id' => $user->id, - 'notice_id' => $this->notice_id)); - - if (empty($inbox)) { - if (!$user->hasBlocked($author)) { - $ni[$user->id] = NOTICE_INBOX_SOURCE_FORWARD; - } - } else { - $inbox->free(); - } - } - - $user->free(); - $author->free(); - - unset($user); - unset($author); - - Notice_inbox::bulkInsert($this->notice_id, $this->created, $ni); - - return $ni; - } - - function blowCache($ni) - { - $cache = common_memcache(); - - if (!empty($cache)) { - foreach ($ni as $id => $source) { - $cache->delete(common_cache_key('notice_inbox:by_user:'.$id)); - $cache->delete(common_cache_key('notice_inbox:by_user_own:'.$id)); - $cache->delete(common_cache_key('notice_inbox:by_user:'.$id.';last')); - $cache->delete(common_cache_key('notice_inbox:by_user_own:'.$id.';last')); - } - } - } -} diff --git a/plugins/Repeat/Forward.php b/plugins/Repeat/Forward.php new file mode 100644 index 000000000..09b2d6a4e --- /dev/null +++ b/plugins/Repeat/Forward.php @@ -0,0 +1,127 @@ +. + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Table Definition for location_namespace + */ + +require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; + +class Forward extends Memcached_DataObject +{ + ###START_AUTOCODE + /* the code below is auto generated do not remove the above tag */ + + public $__table = 'forward'; // table name + public $profile_id; // int(4) primary_key not_null + public $notice_id; // int(4) primary_key not_null + public $created; // datetime not_null default_0000-00-00%2000%3A00%3A00 + + /* Static get */ + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Forward',$k,$v); } + + /* the code above is auto generated do not remove the tag below */ + ###END_AUTOCODE + + function &pkeyGet($kv) + { + return Memcached_DataObject::pkeyGet('Forward', $kv); + } + + static function saveNew($profile_id, $notice_id) + { + $forward = new Forward(); + + $forward->profile_id = $profile_id; + $forward->notice_id = $notice_id; + $forward->created = common_sql_now(); + + $forward->query('BEGIN'); + + if (!$forward->insert()) { + throw new ServerException(_("Couldn't insert forward.")); + } + + $ni = $forward->addToInboxes(); + + $forward->query('COMMIT'); + + $forward->blowCache($ni); + + return $forward; + } + + function addToInboxes() + { + $inbox = new Notice_inbox(); + + $user = new User(); + + $usertable = common_database_tablename('user'); + $user->query("SELECT $usertable.* FROM $usertable INNER JOIN subscription ON $usertable.id = subscription.subscriber ". + 'WHERE subscription.subscribed = '.$this->profile_id); + + $ni = array(); + + $notice = Notice::staticGet('id', $this->notice_id); + + $author = Profile::staticGet('id', $notice->profile_id); + + while ($user->fetch()) { + $inbox = Notice_inbox::pkeyGet(array('user_id' => $user->id, + 'notice_id' => $this->notice_id)); + + if (empty($inbox)) { + if (!$user->hasBlocked($author)) { + $ni[$user->id] = NOTICE_INBOX_SOURCE_FORWARD; + } + } else { + $inbox->free(); + } + } + + $user->free(); + $author->free(); + + unset($user); + unset($author); + + Notice_inbox::bulkInsert($this->notice_id, $this->created, $ni); + + return $ni; + } + + function blowCache($ni) + { + $cache = common_memcache(); + + if (!empty($cache)) { + foreach ($ni as $id => $source) { + $cache->delete(common_cache_key('notice_inbox:by_user:'.$id)); + $cache->delete(common_cache_key('notice_inbox:by_user_own:'.$id)); + $cache->delete(common_cache_key('notice_inbox:by_user:'.$id.';last')); + $cache->delete(common_cache_key('notice_inbox:by_user_own:'.$id.';last')); + } + } + } +} diff --git a/plugins/Repeat/forward.php b/plugins/Repeat/forward.php new file mode 100644 index 000000000..194833fe0 --- /dev/null +++ b/plugins/Repeat/forward.php @@ -0,0 +1,122 @@ + + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://status.net/ + * + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2008, 2009, StatusNet, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Forward action + * + * @category Action + * @package StatusNet + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://status.net/ + */ + +class ForwardAction extends Action +{ + var $user = null; + var $notice = null; + + function prepare($args) + { + parent::prepare($args); + + $this->user = common_current_user(); + + if (empty($this->user)) { + $this->clientError(_("Only logged-in users can forward notices.")); + return false; + } + + $id = $this->trimmed('notice'); + + if (empty($id)) { + $this->clientError(_("No notice specified.")); + return false; + } + + $this->notice = Notice::staticGet('id', $id); + + if (empty($this->notice)) { + $this->clientError(_("No notice specified.")); + return false; + } + + if ($this->user->id == $this->notice->profile_id) { + $this->clientError(_("You can't forward your own notice.")); + return false; + } + + $token = $this->trimmed('token-'.$id); + + if (empty($token) || $token != common_session_token()) { + $this->clientError(_("There was a problem with your session token. Try again, please.")); + return false; + } + + $profile = $this->user->getProfile(); + + if ($profile->hasForwarded($id)) { + $this->clientError(_("You already forwarded that notice.")); + return false; + } + + return true; + } + + /** + * Class handler. + * + * @param array $args query arguments + * + * @return void + */ + + function handle($args) + { + $forward = Forward::saveNew($this->user->id, $this->notice->id); + + if ($this->boolean('ajax')) { + $this->startHTML('text/xml;charset=utf-8'); + $this->elementStart('head'); + $this->element('title', null, _('Forwarded')); + $this->elementEnd('head'); + $this->elementStart('body'); + $this->element('p', array('id' => 'forward_response'), _('Forwarded!')); + $this->elementEnd('body'); + $this->elementEnd('html'); + } else { + // FIXME! + } + } +} -- cgit v1.2.3-54-g00ecf From 198e413a58f8aa3d07ce5da365f6c47ce98ab2c0 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 10 Dec 2009 13:34:11 -0500 Subject: move inbox notice list to repeat plugin --- actions/all.php | 86 +------------------------------------- plugins/Repeat/inboxnoticelist.php | 85 +++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 85 deletions(-) create mode 100644 plugins/Repeat/inboxnoticelist.php (limited to 'plugins') diff --git a/actions/all.php b/actions/all.php index 2c96298fa..08fbacaef 100644 --- a/actions/all.php +++ b/actions/all.php @@ -144,7 +144,7 @@ class AllAction extends ProfileAction function showContent() { - $nl = new InboxNoticeList($this->notice, $this->user, $this); + $nl = new NoticeList($this->notice, $this->user, $this); $cnt = $nl->show(); @@ -168,87 +168,3 @@ class AllAction extends ProfileAction } } } - -class InboxNoticeList extends NoticeList -{ - var $owner = null; - - function __construct($notice, $owner, $out=null) - { - parent::__construct($notice, $out); - $this->owner = $owner; - } - - function newListItem($notice) - { - return new InboxNoticeListItem($notice, $this->owner, $this->out); - } -} - -class InboxNoticeListItem extends NoticeListItem -{ - var $owner = null; - var $ib = null; - - function __construct($notice, $owner, $out=null) - { - parent::__construct($notice, $out); - $this->owner = $owner; - - $this->ib = Notice_inbox::pkeyGet(array('user_id' => $owner->id, - 'notice_id' => $notice->id)); - } - - function showAuthor() - { - parent::showAuthor(); - if ($this->ib->source == NOTICE_INBOX_SOURCE_FORWARD) { - $this->out->element('span', 'forward', _('Fwd')); - } - } - - function showEnd() - { - if ($this->ib->source == NOTICE_INBOX_SOURCE_FORWARD) { - - $forward = new Forward(); - - // FIXME: scary join! - - $forward->query('SELECT profile_id '. - 'FROM forward JOIN subscription ON forward.profile_id = subscription.subscribed '. - 'WHERE subscription.subscriber = ' . $this->owner->id . ' '. - 'AND forward.notice_id = ' . $this->notice->id . ' '. - 'ORDER BY forward.created '); - - $n = 0; - - $firstForwarder = null; - - while ($forward->fetch()) { - if (empty($firstForwarder)) { - $firstForwarder = Profile::staticGet('id', $forward->profile_id); - } - $n++; - } - - $forward->free(); - unset($forward); - - $this->out->elementStart('span', 'forwards'); - - $link = XMLStringer::estring('a', array('href' => $firstForwarder->profileurl), - $firstForwarder->nickname); - - if ($n == 1) { - $this->out->raw(sprintf(_('Forwarded by %s'), $link)); - } else { - // XXX: use that cool ngettext thing - $this->out->raw(sprintf(_('Forwarded by %s and %d other(s)'), $link, $n - 1)); - } - - $this->out->elementEnd('span'); - } - parent::showEnd(); - } -} diff --git a/plugins/Repeat/inboxnoticelist.php b/plugins/Repeat/inboxnoticelist.php new file mode 100644 index 000000000..809fbe8af --- /dev/null +++ b/plugins/Repeat/inboxnoticelist.php @@ -0,0 +1,85 @@ +owner = $owner; + } + + function newListItem($notice) + { + return new InboxNoticeListItem($notice, $this->owner, $this->out); + } +} + +class InboxNoticeListItem extends NoticeListItem +{ + var $owner = null; + var $ib = null; + + function __construct($notice, $owner, $out=null) + { + parent::__construct($notice, $out); + $this->owner = $owner; + + $this->ib = Notice_inbox::pkeyGet(array('user_id' => $owner->id, + 'notice_id' => $notice->id)); + } + + function showAuthor() + { + parent::showAuthor(); + if ($this->ib->source == NOTICE_INBOX_SOURCE_FORWARD) { + $this->out->element('span', 'forward', _('Fwd')); + } + } + + function showEnd() + { + if ($this->ib->source == NOTICE_INBOX_SOURCE_FORWARD) { + + $forward = new Forward(); + + // FIXME: scary join! + + $forward->query('SELECT profile_id '. + 'FROM forward JOIN subscription ON forward.profile_id = subscription.subscribed '. + 'WHERE subscription.subscriber = ' . $this->owner->id . ' '. + 'AND forward.notice_id = ' . $this->notice->id . ' '. + 'ORDER BY forward.created '); + + $n = 0; + + $firstForwarder = null; + + while ($forward->fetch()) { + if (empty($firstForwarder)) { + $firstForwarder = Profile::staticGet('id', $forward->profile_id); + } + $n++; + } + + $forward->free(); + unset($forward); + + $this->out->elementStart('span', 'forwards'); + + $link = XMLStringer::estring('a', array('href' => $firstForwarder->profileurl), + $firstForwarder->nickname); + + if ($n == 1) { + $this->out->raw(sprintf(_('Forwarded by %s'), $link)); + } else { + // XXX: use that cool ngettext thing + $this->out->raw(sprintf(_('Forwarded by %s and %d other(s)'), $link, $n - 1)); + } + + $this->out->elementEnd('span'); + } + parent::showEnd(); + } +} -- cgit v1.2.3-54-g00ecf From 37b0852fdb8b82741b327af57d898d4d89c2f177 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 10 Dec 2009 14:33:15 -0500 Subject: move forward form to plugin --- lib/forwardform.php | 147 ----------------------------------------- lib/noticelist.php | 21 ------ plugins/Repeat/forwardform.php | 147 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 168 deletions(-) delete mode 100644 lib/forwardform.php create mode 100644 plugins/Repeat/forwardform.php (limited to 'plugins') diff --git a/lib/forwardform.php b/lib/forwardform.php deleted file mode 100644 index 2052856ae..000000000 --- a/lib/forwardform.php +++ /dev/null @@ -1,147 +0,0 @@ -. - * - * @category Form - * @package StatusNet - * @author Evan Prodromou - * @copyright 2009 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/form.php'; - -/** - * Form for forwarding a notice - * - * @category Form - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - */ - -class ForwardForm extends Form -{ - /** - * Notice to forward - */ - - var $notice = null; - - /** - * Constructor - * - * @param HTMLOutputter $out output channel - * @param Notice $notice notice to forward - */ - - function __construct($out=null, $notice=null) - { - parent::__construct($out); - - $this->notice = $notice; - } - - /** - * ID of the form - * - * @return int ID of the form - */ - - function id() - { - return 'forward-' . $this->notice->id; - } - - /** - * Action of the form - * - * @return string URL of the action - */ - - function action() - { - return common_local_url('forward'); - } - - /** - * Include a session token for CSRF protection - * - * @return void - */ - - function sessionToken() - { - $this->out->hidden('token-' . $this->notice->id, - common_session_token()); - } - - /** - * Legend of the Form - * - * @return void - */ - function formLegend() - { - $this->out->element('legend', null, _('Forward this notice')); - } - - /** - * Data elements - * - * @return void - */ - - function formData() - { - $this->out->hidden('notice-n'.$this->notice->id, - $this->notice->id, - 'notice'); - } - - /** - * Action elements - * - * @return void - */ - - function formActions() - { - $this->out->submit('forward-submit-' . $this->notice->id, - _('Forward'), 'submit', null, _('Forward this notice')); - } - - /** - * Class of the form. - * - * @return string the form's class - */ - - function formClass() - { - return 'form_forward'; - } -} diff --git a/lib/noticelist.php b/lib/noticelist.php index d6ffc9ca9..21cec528f 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -212,7 +212,6 @@ class NoticeListItem extends Widget $this->out->elementStart('div', 'notice-options'); $this->showFaveForm(); $this->showReplyLink(); - $this->showForwardForm(); $this->showDeleteLink(); $this->out->elementEnd('div'); } @@ -531,26 +530,6 @@ class NoticeListItem extends Widget } } - /** - * show the form to forward a notice - * - * @return void - */ - - function showForwardForm() - { - $user = common_current_user(); - if ($user && $user->id != $this->notice->profile_id) { - $profile = $user->getProfile(); - if ($profile->hasForwarded($this->notice->id)) { - $this->out->text(_('Forwarded')); - } else { - $ff = new ForwardForm($this->out, $this->notice); - $ff->show(); - } - } - } - /** * if the user is the author, let them delete the notice * diff --git a/plugins/Repeat/forwardform.php b/plugins/Repeat/forwardform.php new file mode 100644 index 000000000..2052856ae --- /dev/null +++ b/plugins/Repeat/forwardform.php @@ -0,0 +1,147 @@ +. + * + * @category Form + * @package StatusNet + * @author Evan Prodromou + * @copyright 2009 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR.'/lib/form.php'; + +/** + * Form for forwarding a notice + * + * @category Form + * @package StatusNet + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +class ForwardForm extends Form +{ + /** + * Notice to forward + */ + + var $notice = null; + + /** + * Constructor + * + * @param HTMLOutputter $out output channel + * @param Notice $notice notice to forward + */ + + function __construct($out=null, $notice=null) + { + parent::__construct($out); + + $this->notice = $notice; + } + + /** + * ID of the form + * + * @return int ID of the form + */ + + function id() + { + return 'forward-' . $this->notice->id; + } + + /** + * Action of the form + * + * @return string URL of the action + */ + + function action() + { + return common_local_url('forward'); + } + + /** + * Include a session token for CSRF protection + * + * @return void + */ + + function sessionToken() + { + $this->out->hidden('token-' . $this->notice->id, + common_session_token()); + } + + /** + * Legend of the Form + * + * @return void + */ + function formLegend() + { + $this->out->element('legend', null, _('Forward this notice')); + } + + /** + * Data elements + * + * @return void + */ + + function formData() + { + $this->out->hidden('notice-n'.$this->notice->id, + $this->notice->id, + 'notice'); + } + + /** + * Action elements + * + * @return void + */ + + function formActions() + { + $this->out->submit('forward-submit-' . $this->notice->id, + _('Forward'), 'submit', null, _('Forward this notice')); + } + + /** + * Class of the form. + * + * @return string the form's class + */ + + function formClass() + { + return 'form_forward'; + } +} -- cgit v1.2.3-54-g00ecf From 14f7c784a6fa11625df128309c0f211ca36101c1 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Thu, 10 Dec 2009 14:40:26 -0500 Subject: Add table() and keys() overrides to User_username --- plugins/Authentication/User_username.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'plugins') diff --git a/plugins/Authentication/User_username.php b/plugins/Authentication/User_username.php index f30f60d83..853fd5cb8 100644 --- a/plugins/Authentication/User_username.php +++ b/plugins/Authentication/User_username.php @@ -43,4 +43,19 @@ class User_username extends Memcached_DataObject return false; } } + + function table() { + return array( + 'user_id' => DB_DATAOBJECT_INT, + 'username' => DB_DATAOBJECT_STR, + 'provider_name' => DB_DATAOBJECT_STR , + 'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + ); + } + + // now define the keys. + function keys() { + return array('provider_name', 'username'); + } + } -- cgit v1.2.3-54-g00ecf From c10fa99b04ef544e1ea082a694ad714f9246df86 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 10 Dec 2009 15:16:44 -0500 Subject: remove the Repeat plugin (for now) --- plugins/Repeat/Forward.php | 127 -------------------------------- plugins/Repeat/forward.php | 122 ------------------------------ plugins/Repeat/forwardform.php | 147 ------------------------------------- plugins/Repeat/inboxnoticelist.php | 85 --------------------- 4 files changed, 481 deletions(-) delete mode 100644 plugins/Repeat/Forward.php delete mode 100644 plugins/Repeat/forward.php delete mode 100644 plugins/Repeat/forwardform.php delete mode 100644 plugins/Repeat/inboxnoticelist.php (limited to 'plugins') diff --git a/plugins/Repeat/Forward.php b/plugins/Repeat/Forward.php deleted file mode 100644 index 09b2d6a4e..000000000 --- a/plugins/Repeat/Forward.php +++ /dev/null @@ -1,127 +0,0 @@ -. - */ - -if (!defined('STATUSNET')) { - exit(1); -} - -/** - * Table Definition for location_namespace - */ - -require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; - -class Forward extends Memcached_DataObject -{ - ###START_AUTOCODE - /* the code below is auto generated do not remove the above tag */ - - public $__table = 'forward'; // table name - public $profile_id; // int(4) primary_key not_null - public $notice_id; // int(4) primary_key not_null - public $created; // datetime not_null default_0000-00-00%2000%3A00%3A00 - - /* Static get */ - function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Forward',$k,$v); } - - /* the code above is auto generated do not remove the tag below */ - ###END_AUTOCODE - - function &pkeyGet($kv) - { - return Memcached_DataObject::pkeyGet('Forward', $kv); - } - - static function saveNew($profile_id, $notice_id) - { - $forward = new Forward(); - - $forward->profile_id = $profile_id; - $forward->notice_id = $notice_id; - $forward->created = common_sql_now(); - - $forward->query('BEGIN'); - - if (!$forward->insert()) { - throw new ServerException(_("Couldn't insert forward.")); - } - - $ni = $forward->addToInboxes(); - - $forward->query('COMMIT'); - - $forward->blowCache($ni); - - return $forward; - } - - function addToInboxes() - { - $inbox = new Notice_inbox(); - - $user = new User(); - - $usertable = common_database_tablename('user'); - $user->query("SELECT $usertable.* FROM $usertable INNER JOIN subscription ON $usertable.id = subscription.subscriber ". - 'WHERE subscription.subscribed = '.$this->profile_id); - - $ni = array(); - - $notice = Notice::staticGet('id', $this->notice_id); - - $author = Profile::staticGet('id', $notice->profile_id); - - while ($user->fetch()) { - $inbox = Notice_inbox::pkeyGet(array('user_id' => $user->id, - 'notice_id' => $this->notice_id)); - - if (empty($inbox)) { - if (!$user->hasBlocked($author)) { - $ni[$user->id] = NOTICE_INBOX_SOURCE_FORWARD; - } - } else { - $inbox->free(); - } - } - - $user->free(); - $author->free(); - - unset($user); - unset($author); - - Notice_inbox::bulkInsert($this->notice_id, $this->created, $ni); - - return $ni; - } - - function blowCache($ni) - { - $cache = common_memcache(); - - if (!empty($cache)) { - foreach ($ni as $id => $source) { - $cache->delete(common_cache_key('notice_inbox:by_user:'.$id)); - $cache->delete(common_cache_key('notice_inbox:by_user_own:'.$id)); - $cache->delete(common_cache_key('notice_inbox:by_user:'.$id.';last')); - $cache->delete(common_cache_key('notice_inbox:by_user_own:'.$id.';last')); - } - } - } -} diff --git a/plugins/Repeat/forward.php b/plugins/Repeat/forward.php deleted file mode 100644 index 194833fe0..000000000 --- a/plugins/Repeat/forward.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ - * - * StatusNet - the distributed open-source microblogging tool - * Copyright (C) 2008, 2009, StatusNet, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -if (!defined('STATUSNET')) { - exit(1); -} - -/** - * Forward action - * - * @category Action - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ - */ - -class ForwardAction extends Action -{ - var $user = null; - var $notice = null; - - function prepare($args) - { - parent::prepare($args); - - $this->user = common_current_user(); - - if (empty($this->user)) { - $this->clientError(_("Only logged-in users can forward notices.")); - return false; - } - - $id = $this->trimmed('notice'); - - if (empty($id)) { - $this->clientError(_("No notice specified.")); - return false; - } - - $this->notice = Notice::staticGet('id', $id); - - if (empty($this->notice)) { - $this->clientError(_("No notice specified.")); - return false; - } - - if ($this->user->id == $this->notice->profile_id) { - $this->clientError(_("You can't forward your own notice.")); - return false; - } - - $token = $this->trimmed('token-'.$id); - - if (empty($token) || $token != common_session_token()) { - $this->clientError(_("There was a problem with your session token. Try again, please.")); - return false; - } - - $profile = $this->user->getProfile(); - - if ($profile->hasForwarded($id)) { - $this->clientError(_("You already forwarded that notice.")); - return false; - } - - return true; - } - - /** - * Class handler. - * - * @param array $args query arguments - * - * @return void - */ - - function handle($args) - { - $forward = Forward::saveNew($this->user->id, $this->notice->id); - - if ($this->boolean('ajax')) { - $this->startHTML('text/xml;charset=utf-8'); - $this->elementStart('head'); - $this->element('title', null, _('Forwarded')); - $this->elementEnd('head'); - $this->elementStart('body'); - $this->element('p', array('id' => 'forward_response'), _('Forwarded!')); - $this->elementEnd('body'); - $this->elementEnd('html'); - } else { - // FIXME! - } - } -} diff --git a/plugins/Repeat/forwardform.php b/plugins/Repeat/forwardform.php deleted file mode 100644 index 2052856ae..000000000 --- a/plugins/Repeat/forwardform.php +++ /dev/null @@ -1,147 +0,0 @@ -. - * - * @category Form - * @package StatusNet - * @author Evan Prodromou - * @copyright 2009 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/form.php'; - -/** - * Form for forwarding a notice - * - * @category Form - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - */ - -class ForwardForm extends Form -{ - /** - * Notice to forward - */ - - var $notice = null; - - /** - * Constructor - * - * @param HTMLOutputter $out output channel - * @param Notice $notice notice to forward - */ - - function __construct($out=null, $notice=null) - { - parent::__construct($out); - - $this->notice = $notice; - } - - /** - * ID of the form - * - * @return int ID of the form - */ - - function id() - { - return 'forward-' . $this->notice->id; - } - - /** - * Action of the form - * - * @return string URL of the action - */ - - function action() - { - return common_local_url('forward'); - } - - /** - * Include a session token for CSRF protection - * - * @return void - */ - - function sessionToken() - { - $this->out->hidden('token-' . $this->notice->id, - common_session_token()); - } - - /** - * Legend of the Form - * - * @return void - */ - function formLegend() - { - $this->out->element('legend', null, _('Forward this notice')); - } - - /** - * Data elements - * - * @return void - */ - - function formData() - { - $this->out->hidden('notice-n'.$this->notice->id, - $this->notice->id, - 'notice'); - } - - /** - * Action elements - * - * @return void - */ - - function formActions() - { - $this->out->submit('forward-submit-' . $this->notice->id, - _('Forward'), 'submit', null, _('Forward this notice')); - } - - /** - * Class of the form. - * - * @return string the form's class - */ - - function formClass() - { - return 'form_forward'; - } -} diff --git a/plugins/Repeat/inboxnoticelist.php b/plugins/Repeat/inboxnoticelist.php deleted file mode 100644 index 809fbe8af..000000000 --- a/plugins/Repeat/inboxnoticelist.php +++ /dev/null @@ -1,85 +0,0 @@ -owner = $owner; - } - - function newListItem($notice) - { - return new InboxNoticeListItem($notice, $this->owner, $this->out); - } -} - -class InboxNoticeListItem extends NoticeListItem -{ - var $owner = null; - var $ib = null; - - function __construct($notice, $owner, $out=null) - { - parent::__construct($notice, $out); - $this->owner = $owner; - - $this->ib = Notice_inbox::pkeyGet(array('user_id' => $owner->id, - 'notice_id' => $notice->id)); - } - - function showAuthor() - { - parent::showAuthor(); - if ($this->ib->source == NOTICE_INBOX_SOURCE_FORWARD) { - $this->out->element('span', 'forward', _('Fwd')); - } - } - - function showEnd() - { - if ($this->ib->source == NOTICE_INBOX_SOURCE_FORWARD) { - - $forward = new Forward(); - - // FIXME: scary join! - - $forward->query('SELECT profile_id '. - 'FROM forward JOIN subscription ON forward.profile_id = subscription.subscribed '. - 'WHERE subscription.subscriber = ' . $this->owner->id . ' '. - 'AND forward.notice_id = ' . $this->notice->id . ' '. - 'ORDER BY forward.created '); - - $n = 0; - - $firstForwarder = null; - - while ($forward->fetch()) { - if (empty($firstForwarder)) { - $firstForwarder = Profile::staticGet('id', $forward->profile_id); - } - $n++; - } - - $forward->free(); - unset($forward); - - $this->out->elementStart('span', 'forwards'); - - $link = XMLStringer::estring('a', array('href' => $firstForwarder->profileurl), - $firstForwarder->nickname); - - if ($n == 1) { - $this->out->raw(sprintf(_('Forwarded by %s'), $link)); - } else { - // XXX: use that cool ngettext thing - $this->out->raw(sprintf(_('Forwarded by %s and %d other(s)'), $link, $n - 1)); - } - - $this->out->elementEnd('span'); - } - parent::showEnd(); - } -} -- cgit v1.2.3-54-g00ecf From 08901c98c4129c1d7707acb470e18f1056f2502e Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Thu, 10 Dec 2009 21:06:54 -0500 Subject: Changing avatar should broadcast the profile via OMB. --- plugins/Gravatar/GravatarPlugin.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'plugins') diff --git a/plugins/Gravatar/GravatarPlugin.php b/plugins/Gravatar/GravatarPlugin.php index b18f62726..3c61a682e 100644 --- a/plugins/Gravatar/GravatarPlugin.php +++ b/plugins/Gravatar/GravatarPlugin.php @@ -92,11 +92,23 @@ class GravatarPlugin extends Plugin function onStartAvatarSaveForm($action) { if ($action->arg('add')) { $result = $this->gravatar_save(); + + if($result['success']===true) { + common_broadcast_profile(common_current_user()->getProfile()); + } + $action->showForm($result['message'], $result['success']); + return false; } else if ($action->arg('remove')) { $result = $this->gravatar_remove(); + + if($result['success']===true) { + common_broadcast_profile(common_current_user()->getProfile()); + } + $action->showForm($result['message'], $result['success']); + return false; } else { return true; -- cgit v1.2.3-54-g00ecf From 79f81ad76d413908c097c121912eff233aebc483 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 11 Dec 2009 11:29:51 -0500 Subject: change Notice::saveNew() to use named arguments for little-used options --- actions/apistatusesupdate.php | 29 ++++++++++++++++------------- actions/newnotice.php | 10 ++++++---- classes/Notice.php | 15 ++++++++++++--- lib/command.php | 5 +++-- lib/oauthstore.php | 5 ++--- plugins/Facebook/facebookaction.php | 5 +++-- 6 files changed, 42 insertions(+), 27 deletions(-) (limited to 'plugins') diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index 85a7c8c08..10bbc5ace 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -231,19 +231,22 @@ class ApiStatusesUpdateAction extends ApiAuthAction } } - $this->notice = Notice::saveNew( - $this->user->id, - html_entity_decode($status_shortened, ENT_NOQUOTES, 'UTF-8'), - $this->source, - 1, - $reply_to, - null, - null, - empty($location) ? null : $location->lat, - empty($location) ? null : $location->lon, - empty($location) ? null : $location->location_id, - empty($location) ? null : $location->location_ns - ); + $content = html_entity_decode($status_shortened, ENT_NOQUOTES, 'UTF-8'), + + $options = array('reply_to' => $reply_to); + + if (!empty($location)) { + $options['lat'] = $location->lat; + $options['lon'] = $location->lon; + $options['location_id'] = $location->location_id; + $options['location_ns'] = $location->location_ns; + } + + $this->notice = + Notice::saveNew($this->user->id, + $content, + $this->source, + $options); if (isset($upload)) { $upload->attachToNotice($this->notice); diff --git a/actions/newnotice.php b/actions/newnotice.php index dd6da0b01..c6c70e326 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -187,10 +187,12 @@ class NewnoticeAction extends Action } } - $notice = Notice::saveNew($user->id, $content_shortened, 'web', 1, - ($replyto == 'false') ? null : $replyto, - null, null, - $lat, $lon, $location_id, $location_ns); + $notice = Notice::saveNew($user->id, $content_shortened, 'web', + array('reply_to' => ($replyto == 'false') ? null : $replyto, + 'lat' => $lat, + 'lon' => $lon, + 'location_id' => $location_id, + 'location_ns' => $location_ns)); if (isset($upload)) { $upload->attachToNotice($notice); diff --git a/classes/Notice.php b/classes/Notice.php index c36c5a9c6..4422866fa 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -167,9 +167,18 @@ class Notice extends Memcached_DataObject } } - static function saveNew($profile_id, $content, $source=null, - $is_local=Notice::LOCAL_PUBLIC, $reply_to=null, $uri=null, $created=null, - $lat=null, $lon=null, $location_id=null, $location_ns=null) { + static function saveNew($profile_id, $content, $source, $options=null) { + + if (!empty($options)) { + extract($options); + if (!isset($reply_to)) { + $reply_to = NULL; + } + } + + if (empty($is_local)) { + $is_local = Notice::LOCAL_PUBLIC; + } $profile = Profile::staticGet($profile_id); diff --git a/lib/command.php b/lib/command.php index 450db9da3..085331f82 100644 --- a/lib/command.php +++ b/lib/command.php @@ -433,8 +433,9 @@ class ReplyCommand extends Command return; } - $notice = Notice::saveNew($this->user->id, $this->text, $channel->source(), 1, - $notice->id); + $notice = Notice::saveNew($this->user->id, $this->text, $channel->source(), + array('reply_to' => $notice->id)); + if ($notice) { $channel->output($this->user, sprintf(_('Reply to %s sent'), $recipient->nickname)); } else { diff --git a/lib/oauthstore.php b/lib/oauthstore.php index e34bf8a5e..df63cc151 100644 --- a/lib/oauthstore.php +++ b/lib/oauthstore.php @@ -359,9 +359,8 @@ class StatusNetOAuthDataStore extends OAuthDataStore $notice = Notice::saveNew($author->id, $omb_notice->getContent(), 'omb', - false, - null, - $omb_notice->getIdentifierURI()); + array('is_local' => Notice::REMOTE_OMB, + 'uri' => $omb_notice->getIdentifierURI())); common_broadcast_notice($notice, true); } diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php index 705bb2780..24bf215fd 100644 --- a/plugins/Facebook/facebookaction.php +++ b/plugins/Facebook/facebookaction.php @@ -445,8 +445,9 @@ class FacebookAction extends Action $replyto = $this->trimmed('inreplyto'); try { - $notice = Notice::saveNew($user->id, $content, - 'web', 1, ($replyto == 'false') ? null : $replyto); + $notice = Notice::saveNew($user->id, $content, 'web', + array('reply_to' => ($replyto == 'false') ? null : $replyto)); + } catch (Exception $e) { $this->showPage($e->getMessage()); return; -- cgit v1.2.3-54-g00ecf From 2f77d47fd4dfb8c726b3a5184b149e7f72c3514f Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 11 Dec 2009 16:28:51 -0800 Subject: Build stub .po template for Gravatar plugin --- plugins/Gravatar/locale/Gravatar.po | 61 +++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 plugins/Gravatar/locale/Gravatar.po (limited to 'plugins') diff --git a/plugins/Gravatar/locale/Gravatar.po b/plugins/Gravatar/locale/Gravatar.po new file mode 100644 index 000000000..1df62b666 --- /dev/null +++ b/plugins/Gravatar/locale/Gravatar.po @@ -0,0 +1,61 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-11 16:27-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: GravatarPlugin.php:57 +msgid "Set Gravatar" +msgstr "" + +#: GravatarPlugin.php:60 +msgid "If you want to use your Gravatar image, click \"Add\"." +msgstr "" + +#: GravatarPlugin.php:65 +msgid "Add" +msgstr "" + +#: GravatarPlugin.php:75 +msgid "Remove Gravatar" +msgstr "" + +#: GravatarPlugin.php:78 +msgid "If you want to remove your Gravatar image, click \"Remove\"." +msgstr "" + +#: GravatarPlugin.php:83 +msgid "Remove" +msgstr "" + +#: GravatarPlugin.php:88 +msgid "To use a Gravatar first enter in an email address." +msgstr "" + +#: GravatarPlugin.php:137 +msgid "You do not have a email set in your profile." +msgstr "" + +#: GravatarPlugin.php:155 +msgid "Failed to save Gravatar to the DB." +msgstr "" + +#: GravatarPlugin.php:159 +msgid "Gravatar added." +msgstr "" + +#: GravatarPlugin.php:177 +msgid "Gravatar removed." +msgstr "" -- cgit v1.2.3-54-g00ecf From 745e35ac1fcee01298db09a8649f79f410138652 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 13 Dec 2009 18:55:17 +0100 Subject: (Puctuation) consistency in clientError() calls. --- actions/apistatusesretweet.php | 6 +++--- actions/apistatusesretweets.php | 2 +- actions/file.php | 8 ++++---- actions/grouprss.php | 4 ++-- actions/tagother.php | 4 ++-- actions/userbyid.php | 9 ++++----- lib/profileformaction.php | 4 ++-- plugins/OpenID/openidserver.php | 2 +- plugins/TemplatePlugin.php | 2 +- 9 files changed, 20 insertions(+), 21 deletions(-) (limited to 'plugins') diff --git a/actions/apistatusesretweet.php b/actions/apistatusesretweet.php index fc71d2274..85de79d5c 100644 --- a/actions/apistatusesretweet.php +++ b/actions/apistatusesretweet.php @@ -72,7 +72,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction $this->original = Notice::staticGet('id', $id); if (empty($this->original)) { - $this->clientError(_('No such notice'), + $this->clientError(_('No such notice.'), 400, $this->format); return false; } @@ -80,7 +80,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction $this->user = $this->auth_user; if ($this->user->id == $notice->profile_id) { - $this->clientError(_('Cannot repeat your own notice')); + $this->clientError(_('Cannot repeat your own notice.')); 400, $this->format); return false; } @@ -88,7 +88,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction $profile = $this->user->getProfile(); if ($profile->hasRepeated($id)) { - $this->clientError(_('Already repeated that notice'), + $this->clientError(_('Already repeated that notice.'), 400, $this->format); return false; } diff --git a/actions/apistatusesretweets.php b/actions/apistatusesretweets.php index c54a374e2..2efd59b37 100644 --- a/actions/apistatusesretweets.php +++ b/actions/apistatusesretweets.php @@ -69,7 +69,7 @@ class ApiStatusesRetweetsAction extends ApiAuthAction $this->original = Notice::staticGet('id', $id); if (empty($this->original)) { - $this->clientError(_('No such notice'), + $this->clientError(_('No such notice.'), 400, $this->format); return false; } diff --git a/actions/file.php b/actions/file.php index 10c59a961..c6f7b998a 100644 --- a/actions/file.php +++ b/actions/file.php @@ -31,15 +31,15 @@ class FileAction extends Action parent::prepare($args); $this->id = $this->trimmed('notice'); if (empty($this->id)) { - $this->clientError(_('No notice id')); + $this->clientError(_('No notice ID.')); } $notice = Notice::staticGet('id', $this->id); if (empty($notice)) { - $this->clientError(_('No notice')); + $this->clientError(_('No notice.')); } $atts = $notice->attachments(); if (empty($atts)) { - $this->clientError(_('No attachments')); + $this->clientError(_('No attachments.')); } foreach ($atts as $att) { if (!empty($att->filename)) { @@ -48,7 +48,7 @@ class FileAction extends Action } } if (empty($this->filerec)) { - $this->clientError(_('No uploaded attachments')); + $this->clientError(_('No uploaded attachments.')); } return true; } diff --git a/actions/grouprss.php b/actions/grouprss.php index 50e48a67e..866fc66eb 100644 --- a/actions/grouprss.php +++ b/actions/grouprss.php @@ -88,14 +88,14 @@ class groupRssAction extends Rss10Action } if (!$nickname) { - $this->clientError(_('No nickname'), 404); + $this->clientError(_('No nickname.'), 404); return false; } $this->group = User_group::staticGet('nickname', $nickname); if (!$this->group) { - $this->clientError(_('No such group'), 404); + $this->clientError(_('No such group.'), 404); return false; } diff --git a/actions/tagother.php b/actions/tagother.php index c3f43be8b..e9e13b939 100644 --- a/actions/tagother.php +++ b/actions/tagother.php @@ -30,13 +30,13 @@ class TagotherAction extends Action { parent::prepare($args); if (!common_logged_in()) { - $this->clientError(_('Not logged in'), 403); + $this->clientError(_('Not logged in.'), 403); return false; } $id = $this->trimmed('id'); if (!$id) { - $this->clientError(_('No id argument.')); + $this->clientError(_('No ID argument.')); return false; } diff --git a/actions/userbyid.php b/actions/userbyid.php index ebff7e4a7..f3e1556f3 100644 --- a/actions/userbyid.php +++ b/actions/userbyid.php @@ -47,17 +47,17 @@ class UserbyidAction extends Action { /** * Is read only? - * + * * @return boolean true */ function isReadOnly($args) - { + { return true; } /** * Class handler. - * + * * @param array $args array of arguments * * @return nothing @@ -67,7 +67,7 @@ class UserbyidAction extends Action parent::handle($args); $id = $this->trimmed('id'); if (!$id) { - $this->clientError(_('No id.')); + $this->clientError(_('No ID.')); } $user = User::staticGet($id); if (!$user) { @@ -88,4 +88,3 @@ class UserbyidAction extends Action common_redirect($url, 303); } } - diff --git a/lib/profileformaction.php b/lib/profileformaction.php index 8cb5f6a93..8a934666e 100644 --- a/lib/profileformaction.php +++ b/lib/profileformaction.php @@ -120,7 +120,7 @@ class ProfileFormAction extends Action if ($action) { common_redirect(common_local_url($action, $args), 303); } else { - $this->clientError(_("No return-to arguments")); + $this->clientError(_("No return-to arguments.")); } } @@ -134,6 +134,6 @@ class ProfileFormAction extends Action function handlePost() { - $this->serverError(_("unimplemented method")); + $this->serverError(_("Unimplemented method.")); } } diff --git a/plugins/OpenID/openidserver.php b/plugins/OpenID/openidserver.php index 181cbdf45..afbca553f 100644 --- a/plugins/OpenID/openidserver.php +++ b/plugins/OpenID/openidserver.php @@ -103,7 +103,7 @@ class OpenidserverAction extends Action $response = $this->generateDenyResponse($request); } else { //invalid - $this->clientError(sprintf(_m('You are not authorized to use the identity %s'),$request->identity),$code=403); + $this->clientError(sprintf(_m('You are not authorized to use the identity %s.'),$request->identity),$code=403); } } else { $response = $this->oserver->handleRequest($request); diff --git a/plugins/TemplatePlugin.php b/plugins/TemplatePlugin.php index 5f3ad81f5..18aa8034c 100644 --- a/plugins/TemplatePlugin.php +++ b/plugins/TemplatePlugin.php @@ -300,7 +300,7 @@ class TemplateAction extends Action // verify that user is admin if (!($user->id == 1)) - $this->clientError(_('only User #1 can update the template'), $code = 401); + $this->clientError(_('Only User #1 can update the template.'), $code = 401); // open the old template $tpl_file = $this->templateFolder() . '/index.html'; -- cgit v1.2.3-54-g00ecf From 656d29080a3369d3037959e3ecdd62d36a7cc5e1 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 14 Dec 2009 07:33:29 +0000 Subject: Fix Twitter bridge so it responds reasonably to authorization errors. --- plugins/TwitterBridge/twitter.php | 98 ++++++++++++++---------- plugins/TwitterBridge/twitterbasicauthclient.php | 23 +++++- 2 files changed, 78 insertions(+), 43 deletions(-) (limited to 'plugins') diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php index b338a200d..003b52682 100644 --- a/plugins/TwitterBridge/twitter.php +++ b/plugins/TwitterBridge/twitter.php @@ -179,7 +179,7 @@ function broadcast_oauth($notice, $flink) { try { $status = $client->statusesUpdate($statustxt); } catch (OAuthClientException $e) { - return process_error($e, $flink); + return process_error($e, $flink, $notice); } if (empty($status)) { @@ -188,8 +188,11 @@ function broadcast_oauth($notice, $flink) { // or the Twitter API might just be behaving flakey. $errmsg = sprintf('Twitter bridge - No data returned by Twitter API when ' . - 'trying to send update for %1$s (user id %2$s).', - $user->nickname, $user->id); + 'trying to post notice %d for User %s (user id %d).', + $notice->id, + $user->nickname, + $user->id); + common_log(LOG_WARNING, $errmsg); return false; @@ -197,8 +200,12 @@ function broadcast_oauth($notice, $flink) { // Notice crossed the great divide - $msg = sprintf('Twitter bridge - posted notice %s to Twitter using OAuth.', - $notice->id); + $msg = sprintf('Twitter bridge - posted notice %d to Twitter using ' . + 'OAuth for User %s (user id %d).', + $notice->id, + $user->nickname, + $user->id); + common_log(LOG_INFO, $msg); return true; @@ -215,62 +222,69 @@ function broadcast_basicauth($notice, $flink) try { $status = $client->statusesUpdate($statustxt); - } catch (HTTP_Request2_Exception $e) { - return process_error($e, $flink); + } catch (BasicAuthException $e) { + return process_error($e, $flink, $notice); } if (empty($status)) { $errmsg = sprintf('Twitter bridge - No data returned by Twitter API when ' . - 'trying to send update for %1$s (user id %2$s).', - $user->nickname, $user->id); + 'trying to post notice %d for %s (user id %d).', + $notice->id, + $user->nickname, + $user->id); + common_log(LOG_WARNING, $errmsg); - $errmsg = sprintf('No data returned by Twitter API when ' . - 'trying to send update for %1$s (user id %2$s).', - $user->nickname, $user->id); - common_log(LOG_WARNING, $errmsg); + $errmsg = sprintf('No data returned by Twitter API when ' . + 'trying to post notice %d for %s (user id %d).', + $notice->id, + $user->nickname, + $user->id); + common_log(LOG_WARNING, $errmsg); return false; } - $msg = sprintf('Twitter bridge - posted notice %s to Twitter using basic auth.', - $notice->id); + $msg = sprintf('Twitter bridge - posted notice %d to Twitter using ' . + 'HTTP basic auth for User %s (user id %d).', + $notice->id, + $user->nickname, + $user->id); + common_log(LOG_INFO, $msg); return true; } -function process_error($e, $flink) +function process_error($e, $flink, $notice) { - $user = $flink->getUser(); - $errmsg = $e->getMessage(); - $delivered = false; - - switch($errmsg) { - case 'The requested URL returned error: 401': - $logmsg = sprintf('Twiter bridge - User %1$s (user id: %2$s) has an invalid ' . - 'Twitter screen_name/password combo or an invalid acesss token.', - $user->nickname, $user->id); - $delivered = true; - remove_twitter_link($flink); - break; - case 'The requested URL returned error: 403': - $logmsg = sprintf('Twitter bridge - User %1$s (user id: %2$s) has exceeded ' . - 'his/her Twitter request limit.', - $user->nickname, $user->id); - break; - default: - $logmsg = sprintf('Twitter bridge - cURL error trying to send notice to Twitter ' . - 'for user %1$s (user id: %2$s) - ' . - 'code: %3$s message: %4$s.', - $user->nickname, $user->id, - $e->getCode(), $e->getMessage()); - break; - } + $user = $flink->getUser(); + $code = $e->getCode(); + + $logmsg = sprintf('Twitter bridge - %d posting notice %d for ' . + 'User %s (user id: %d): %s.', + $code, + $notice->id, + $user->nickname, + $user->id, + $e->getMessage()); common_log(LOG_WARNING, $logmsg); - return $delivered; + if ($code == 401) { + + // Probably a revoked or otherwise bad access token - nuke! + + remove_twitter_link($flink); + return true; + + } else { + + // For every other case, it's probably some flakiness so try + // sending the notice again later (requeue). + + return false; + } } function format_status($notice) diff --git a/plugins/TwitterBridge/twitterbasicauthclient.php b/plugins/TwitterBridge/twitterbasicauthclient.php index 7ee8d7d4c..fd26293f9 100644 --- a/plugins/TwitterBridge/twitterbasicauthclient.php +++ b/plugins/TwitterBridge/twitterbasicauthclient.php @@ -31,6 +31,20 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } +/** + * General Exception wrapper for HTTP basic auth errors + * + * @category Integration + * @package StatusNet + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + * + */ +class BasicAuthException extends Exception +{ +} + /** * Class for talking to the Twitter API with HTTP Basic Auth. * @@ -169,12 +183,13 @@ class TwitterBasicAuthClient } /** - * Make a HTTP request using cURL. + * Make an HTTP request * * @param string $url Where to make the request * @param array $params post parameters * * @return mixed the request + * @throws BasicAuthException */ function httpRequest($url, $params = null, $auth = true) { @@ -199,6 +214,12 @@ class TwitterBasicAuthClient $response = $request->get($url); } + $code = $response->getStatus(); + + if ($code < 200 || $code >= 400) { + throw new BasicAuthException($response->getBody(), $code); + } + return $response->getBody(); } -- cgit v1.2.3-54-g00ecf From 80b5a7fe600e9e30021f33e58cde7906e79663eb Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 15 Dec 2009 19:44:20 +0000 Subject: Added .form_repeat notice option to received notices in Realtime plugin --- plugins/Realtime/RealtimePlugin.php | 3 ++- plugins/Realtime/realtimeupdate.js | 25 +++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index 3e33fdaf1..d57438de2 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -59,6 +59,7 @@ class RealtimePlugin extends Plugin { $this->replyurl = common_local_url('newnotice'); $this->favorurl = common_local_url('favor'); + $this->repeaturl = common_local_url('repeat'); // FIXME: need to find a better way to pass this pattern in $this->deleteurl = common_local_url('deletenotice', array('notice' => '0000000000')); @@ -297,7 +298,7 @@ class RealtimePlugin extends Plugin function _updateInitialize($timeline, $user_id) { - return "RealtimeUpdate.init($user_id, \"$this->replyurl\", \"$this->favorurl\", \"$this->deleteurl\"); "; + return "RealtimeUpdate.init($user_id, \"$this->replyurl\", \"$this->favorurl\", \"$this->repeaturl\", \"$this->deleteurl\"); "; } function _connect() diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 56a52433f..2844aa580 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -32,6 +32,7 @@ RealtimeUpdate = { _userid: 0, _replyurl: '', _favorurl: '', + _repeaturl: '', _deleteurl: '', _updatecounter: 0, _maxnotices: 50, @@ -40,11 +41,12 @@ RealtimeUpdate = { _paused:false, _queuedNotices:[], - init: function(userid, replyurl, favorurl, deleteurl) + init: function(userid, replyurl, favorurl, repeaturl, deleteurl) { RealtimeUpdate._userid = userid; RealtimeUpdate._replyurl = replyurl; RealtimeUpdate._favorurl = favorurl; + RealtimeUpdate._repeaturl = repeaturl; RealtimeUpdate._deleteurl = deleteurl; RealtimeUpdate._documenttitle = document.title; @@ -95,6 +97,7 @@ RealtimeUpdate = { SN.U.FormXHR($('#'+noticeItemID+' .form_favor')); SN.U.NoticeReplyTo($('#'+noticeItemID)); + SN.U.FormXHR($('#'+noticeItemID+' .form_repeat')); SN.U.NoticeWithAttachment($('#'+noticeItemID)); }, @@ -150,6 +153,9 @@ RealtimeUpdate = { if (RealtimeUpdate._userid == data['user']['id']) { ni = ni+RealtimeUpdate.makeDeleteLink(data['id']); } + else { + ni = ni+RealtimeUpdate.makeRepeatForm(data['id'], session_key); + } } ni = ni+"
    "+ @@ -177,7 +183,22 @@ RealtimeUpdate = { var rl; rl = "Reply "+id+""; return rl; - }, + }, + + makeRepeatForm: function(id, session_key) + { + var rf; + rf = "
    "+ + "
    "+ + "Favor this notice"+ + ""+ + ""+ + ""+ + "
    "+ + "
    "; + + return rf; + }, makeDeleteLink: function(id) { -- cgit v1.2.3-54-g00ecf From d6873beb9b2f17d62b90933e5974117a2fd713f1 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 15 Dec 2009 15:47:37 -0500 Subject: make realtime plugin grok repeats --- plugins/Realtime/RealtimePlugin.php | 18 ++++++++++++++++++ plugins/Realtime/realtimeupdate.js | 35 +++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 6 deletions(-) (limited to 'plugins') diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index d57438de2..a810b7165 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -267,6 +267,24 @@ class RealtimePlugin extends Plugin $profile = $notice->getProfile(); $arr['user']['profile_url'] = $profile->profileurl; + // Add needed repeat data + + if (!empty($notice->repeat_of)) { + $original = Notice::staticGet('id', $notice->repeat_of); + if (!empty($original)) { + $arr['retweeted_status']['url'] = $original->bestUrl(); + $arr['retweeted_status']['html'] = htmlspecialchars($original->rendered); + $arr['retweeted_status']['source'] = htmlspecialchars($original->source); + $originalProfile = $original->getProfile(); + $arr['retweeted_status']['user']['profile_url'] = $originalProfile->profileurl; + if (!empty($original->reply_to)) { + $originalReply = Notice::staticGet('id', $original->reply_to); + $arr['retweeted_status']['in_reply_to_status_url'] = $originalReply->bestUrl(); + } + } + $original = null; + } + return $arr; } diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 2844aa580..18f00f22a 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -116,11 +116,24 @@ RealtimeUpdate = { makeNoticeItem: function(data) { + if (data.hasOwnProperty('retweeted_status')) { + original = data['retweeted_status']; + repeat = data; + data = original; + unique = repeat['id']; + responsible = repeat['user']; + } else { + original = null; + repeat = null; + unique = data['id']; + responsible = data['user']; + } + user = data['user']; html = data['html'].replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); source = data['source'].replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); - ni = "
  • "+ + ni = "
  • "+ ""+ - "
    "; + if (repeat) { + ru = repeat['user']; + ni = ni + "Repeated by " + + "" + + "\""" + + ""+ ru['screen_name'] + ""; + } + + ni = ni+"
    "; + + ni = ni + "
    "; if (RealtimeUpdate._userid != 0) { var input = $("form#form_notice fieldset input#token"); var session_key = input.val(); ni = ni+RealtimeUpdate.makeFavoriteForm(data['id'], session_key); ni = ni+RealtimeUpdate.makeReplyLink(data['id'], data['user']['screen_name']); - if (RealtimeUpdate._userid == data['user']['id']) { + if (RealtimeUpdate._userid == responsible['id']) { ni = ni+RealtimeUpdate.makeDeleteLink(data['id']); } else { @@ -158,7 +180,8 @@ RealtimeUpdate = { } } - ni = ni+"
    "+ + ni = ni+"
  • "; + ""; return ni; }, @@ -330,7 +353,7 @@ RealtimeUpdate = { { $('.notices .entry-title a, .notices .entry-content a').bind('click', function() { window.open(this.href, ''); - + return false; }); -- cgit v1.2.3-54-g00ecf From 608d1b206a01e1bd97e286a1003030ce89370913 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 15 Dec 2009 16:08:44 -0500 Subject: Don't show repeater avatar in notice lists --- lib/noticelist.php | 11 ----------- plugins/Realtime/realtimeupdate.js | 1 - 2 files changed, 12 deletions(-) (limited to 'plugins') diff --git a/lib/noticelist.php b/lib/noticelist.php index 2165222ee..4c11ceed6 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -551,17 +551,6 @@ class NoticeListItem extends Widget $this->out->elementStart('a', $attrs); - $this->out->element('img', array('src' => ($avatar) ? - $avatar->displayUrl() : - Avatar::defaultImage(AVATAR_MINI_SIZE), - 'class' => 'avatar photo', - 'width' => AVATAR_MINI_SIZE, - 'height' => AVATAR_MINI_SIZE, - 'alt' => - ($repeater->fullname) ? - $repeater->fullname : - $repeater->nickname)); - $this->out->element('span', 'nickname', $repeater->nickname); $this->out->elementEnd('a'); diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 18f00f22a..b57451e20 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -159,7 +159,6 @@ RealtimeUpdate = { ru = repeat['user']; ni = ni + "Repeated by " + "" + - "\""" + ""+ ru['screen_name'] + ""; } -- cgit v1.2.3-54-g00ecf From f3d27cc3ae92e2b7412dd998d7de7a2b58dc8e6a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 15 Dec 2009 16:19:11 -0500 Subject: can't repeat your own notice posted through realtime --- plugins/Realtime/realtimeupdate.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index b57451e20..281d3d82d 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -173,8 +173,7 @@ RealtimeUpdate = { ni = ni+RealtimeUpdate.makeReplyLink(data['id'], data['user']['screen_name']); if (RealtimeUpdate._userid == responsible['id']) { ni = ni+RealtimeUpdate.makeDeleteLink(data['id']); - } - else { + } else if (RealtimeUpdate._userid != user['id']) { ni = ni+RealtimeUpdate.makeRepeatForm(data['id'], session_key); } } -- cgit v1.2.3-54-g00ecf