Commit: b8a51ba8c1b3d2ace3925be6ee3f270e0a4c0e36
Author: Jon Adams | Date: 2010-03-09 02:38:51 -0800
diff --git a/config/bootstrap.php b/config/bootstrap.php
index 6a89fc8..5af1f2a 100644
--- a/config/bootstrap.php
+++ b/config/bootstrap.php
@@ -2,23 +2,17 @@
/**
* Lithium: the most rad php framework
*
- * @copyright Copyright 2009, Union of RAD (http://union-of-rad.org)
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
* @license http://opensource.org/licenses/bsd-license.php The BSD License
*/
-namespace lithium;
-
-use \lithium\core\Environment;
-use \lithium\core\Libraries;
-use \lithium\storage\Session;
-
/**
* This is the path to the class libraries used by your application, and must contain a copy of the
* Lithium core. By default, this directory is named 'libraries', and resides in the same
* directory as your application. If you use the same libraries in multiple applications, you can
* set this to a shared path on your server.
*/
-define('LITHIUM_LIBRARY_PATH', dirname(dirname(__DIR__)) . '/lithium/libraries');
+define('LITHIUM_LIBRARY_PATH', dirname(dirname(__DIR__)) . '/libraries');
/**
* This is the path to your application's directory. It contains all the sub-folders for your
@@ -39,43 +33,33 @@ if (!include LITHIUM_LIBRARY_PATH . '/lithium/core/Libraries.php') {
}
/**
- * Add the Lithium core library. This sets default paths and initializes the autoloader. You
- * generally should not need to override any settings.
+ * This file contains the loading instructions for all class libraries used in the application,
+ * including the Lithium core, and the application itself. These instructions include library names,
+ * paths to files, and any applicable class-loading rules. Also includes any statically-loaded
+ * classes to improve bootstrap performance.
*/
-Libraries::add('lithium');
+require __DIR__ . '/bootstrap/libraries.php';
/**
- * Optimize default request cycle by loading common classes. If you're implementing custom
- * request/response or dispatch classes, you can safely remove these. Actually, you can safely
- * remove them anyway, they're just there to give slightly you better out-of-the-box performance.
+ * Include this file if your application uses a database connection.
*/
-require LITHIUM_LIBRARY_PATH . '/lithium/core/Object.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/core/StaticObject.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/util/Collection.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/util/collection/Filters.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/util/Inflector.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/util/Set.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/util/String.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/core/Environment.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/http/Base.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/http/Media.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/http/Request.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/http/Response.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/http/Route.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/action/Controller.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/action/Dispatcher.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/action/Request.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/action/Response.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/template/View.php';
-require LITHIUM_LIBRARY_PATH . '/lithium/template/view/Renderer.php';
-
+require __DIR__ . '/connections.php';
+/**
+ * This file defines bindings between classes which are triggered during the request cycle, and
+ * allow the framework to automatically configure its environmental settings. You can add your own
+ * behavior and modify the dispatch cycle to suit your needs.
+ */
+require __DIR__ . '/bootstrap/action.php';
/**
- * Add the application. You can pass a `'path'` key here if this bootstrap file is outside of
- * your main application, but generally you should not need to change any settings.
+ * This file contains configurations for connecting to external caching resources, as well as
+ * default caching rules for various systems within your application
*/
-Libraries::add('app');
+require __DIR__ . '/bootstrap/cache.php';
+
+
+use \lithium\storage\Session;
Session::config(array('default' => array('adapter' => 'Cookie')));
diff --git a/config/bootstrap/action.php b/config/bootstrap/action.php
new file mode 100644
index 0000000..6139e86
--- /dev/null
+++ b/config/bootstrap/action.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+/**
+ * This file contains a series of method filters that allow you to intercept different parts of
+ * Lithium's dispatch cycle. The filters below are used for on-demand loading of routing
+ * configuration, and automatically configuring the correct environment in which the application
+ * runs.
+ *
+ * For more information on in the filters system, see `lithium\util\collection\Filters`.
+ *
+ * @see lithium\util\collection\Filters
+ */
+
+use \lithium\core\Libraries;
+use \lithium\net\http\Router;
+use \lithium\core\Environment;
+use \lithium\action\Dispatcher;
+
+/**
+ * This filter loads all application routes in all plugins, loading the default application routes
+ * last. Change this code if plugin routes must be loaded in a specific order, or if application
+ * routes must be loaded first (in which case the catch-all routes should be removed). If
+ * `Dispatcher::run()` is called multiple times in the course of a single request, change the
+ * `include`s to `include_once`.
+ *
+ * @see lithium\net\http\Router
+ */
+Dispatcher::applyFilter('run', function($self, $params, $chain) {
+ foreach (array_reverse(Libraries::get()) as $name => $config) {
+ if ($name === 'lithium') continue;
+ $file = "{$config['path']}/config/routes.php";
+ file_exists($file) ? include $file : null;
+ }
+ return $chain->next($self, $params, $chain);
+});
+
+/**
+ * Intercepts the `Dispatcher` as it finds a controller object, and passes the `'request'` parameter
+ * to the `Environment` class to detect which environment the application is running in.
+ *
+ * @see lithium\action\Request
+ * @see lithium\core\Environment
+ */
+Dispatcher::applyFilter('_callable', function($self, $params, $chain) {
+ Environment::set($params['request']);
+ return $chain->next($self, $params, $chain);
+});
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/cache.php b/config/bootstrap/cache.php
new file mode 100644
index 0000000..2039220
--- /dev/null
+++ b/config/bootstrap/cache.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+/**
+ * This file creates a default cache configuration using the most optimized adapter available, and
+ * uses it to provide default caching for high-overhead operations.
+ */
+use lithium\storage\Cache;
+use lithium\core\Libraries;
+use lithium\action\Dispatcher;
+use lithium\storage\cache\adapter\Apc;
+
+/**
+ * If APC is not available and the cache directory is not writeable, bail out.
+ */
+if (!$apcEnabled = Apc::enabled() && !is_writable(LITHIUM_APP_PATH . '/resources/tmp/cache')) {
+ return;
+}
+
+Cache::config(array(
+ 'default' => array(
+ 'adapter' => '\lithium\storage\cache\adapter\\' . ($apcEnabled ? 'Apc' : 'File')
+ )
+));
+
+Dispatcher::applyFilter('run', function($self, $params, $chain) {
+ if ($cache = Cache::read('default', 'core.libraries')) {
+ $cache = (array) unserialize($cache) + Libraries::cache();
+ Libraries::cache($cache);
+ }
+ $result = $chain->next($self, $params, $chain);
+
+ if ($cache != Libraries::cache()) {
+ Cache::write('default', 'core.libraries', serialize(Libraries::cache()), '+1 day');
+ }
+ return $result;
+});
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/libraries.php b/config/bootstrap/libraries.php
new file mode 100644
index 0000000..e103df1
--- /dev/null
+++ b/config/bootstrap/libraries.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+use lithium\core\Libraries;
+
+/**
+ * Optimize default request cycle by loading common classes. If you're implementing custom
+ * request/response or dispatch classes, you can safely remove these. Actually, you can safely
+ * remove them anyway, they're just there to give slightly you better out-of-the-box performance.
+ */
+require LITHIUM_LIBRARY_PATH . '/lithium/core/Object.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/core/StaticObject.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/util/Collection.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/util/collection/Filters.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/util/Inflector.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/util/String.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/core/Adaptable.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/core/Environment.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Base.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Media.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Request.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Response.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Route.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Router.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/action/Controller.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/action/Dispatcher.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/action/Request.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/action/Response.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/template/View.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/template/view/Renderer.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/template/view/Compiler.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/template/view/adapter/File.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/storage/Cache.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/storage/cache/adapter/Apc.php';
+
+/**
+ * Add the Lithium core library. This sets default paths and initializes the autoloader. You
+ * generally should not need to override any settings.
+ */
+Libraries::add('lithium');
+
+/**
+ * Add the application. You can pass a `'path'` key here if this bootstrap file is outside of
+ * your main application, but generally you should not need to change any settings.
+ */
+Libraries::add('app', array('default' => true));
+
+?>
\ No newline at end of file
diff --git a/config/connections.php b/config/connections.php
index fa5f99f..5ea54ea 100644
--- a/config/connections.php
+++ b/config/connections.php
@@ -8,10 +8,11 @@
use \lithium\data\Connections;
-Connections::add('default', 'http', array(
+Connections::add('default', array(
+ 'type' => 'Http',
'adapter' => 'CouchDb',
- 'host' => '127.0.0.1',
- 'port' => 5984,
+ 'database' => 'anologue',
+ 'host' => 'localhost'
));
?>
diff --git a/config/routes.php b/config/routes.php
index 6512c18..e2c4d4b 100644
--- a/config/routes.php
+++ b/config/routes.php
@@ -1,6 +1,6 @@
<?php
-use \lithium\http\Router;
+use \lithium\net\http\Router;
/**
* Connect the testing routes.
diff --git a/config/switchboard.php b/config/switchboard.php
deleted file mode 100644
index bd5adcf..0000000
--- a/config/switchboard.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright Copyright 2009, Union of RAD (http://union-of-rad.org)
- * @license http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-/**
- * Welcome to the switchboard. This file contains a series of method filters that allow you to
- * intercept different parts of Lithium's request cycle as they happen. You can apply filters to
- * any object method that has a `@filter` flag in its API documentation.
- *
- * For more information on in the filters system, see `lithium\util\collection\Filters`.
- *
- * @see lithium\util\collection\Filters
- */
-
-use \lithium\http\Router;
-use \lithium\core\Environment;
-use \lithium\action\Dispatcher;
-
-/**
- * Loads application routes before the request is dispatched. Change this to `include_once` if
- * more than one request cycle is executed per HTTP request.
- *
- * @see lithium\http\Router
- */
-Dispatcher::applyFilter('run', function($self, $params, $chain) {
- include __DIR__ . '/routes.php';
- return $chain->next($self, $params, $chain);
-});
-
-/**
- * Intercepts the `Dispatcher` as it finds a controller object, and passes the `'request'` parameter
- * to the `Environment` class to detect which environment the application is running in.
- *
- * @see lithium\action\Request
- * @see lithium\core\Environment
- */
-Dispatcher::applyFilter('_callable', function($self, $params, $chain) {
- Environment::set($params['request']);
- return $chain->next($self, $params, $chain);
-});
-
-?>
diff --git a/extensions/helper/Oembed.php b/extensions/helper/Oembed.php
new file mode 100644
index 0000000..dbfc80f
--- /dev/null
+++ b/extensions/helper/Oembed.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace app\extensions\helper;
+
+class Oembed extends \lithium\template\Helper {
+
+ /**
+ * Method to wrap urls within a string with an html anchor tag with a class for use with oEmbed.
+ *
+ * @param string $string string to search for urls
+ * @param array|string $options if string, assumed classname to use for anchors. otherwise,
+ * array used to merge against default options.
+ */
+ public static function classify($string = null, $options = array()) {
+ $defaults = array(
+ 'class' => 'oembed',
+ 'markdown' => false
+ );
+
+ if (!empty($options) && is_string($options)) {
+ $options = array('class' => $options);
+ }
+
+ extract($options + $defaults);
+
+ if (!$options['markdown']) {
+ $link = "<a href=\"$1\" class=\"{$class}\">$1</a>";
+ } else {
+ $link = "[$1]($1)";
+ }
+ $string = preg_replace(
+ '@((?<![\[\(])https?://([-\w\.]+)+(:\d+)?(/([-\w/_\.]*(#?)([-\w]+)(\?\S+)?)?)?)@',
+ $link,
+ $string
+ );
+ return $string;
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/models/Anologue.php b/models/Anologue.php
index e4f46d4..975cbdc 100644
--- a/models/Anologue.php
+++ b/models/Anologue.php
@@ -3,6 +3,7 @@
namespace app\models;
use \lithium\data\model\Document;
+use \app\extensions\helper\Oembed;
/**
* The core model and messages container for Anologue.
@@ -28,6 +29,7 @@ class Anologue extends \lithium\data\Model {
*
* @var array
* @see app\models\Anologue::addMessage()
+ * @todo move to Message model
*/
protected static $_defaultMessage = array(
'author' => 'anonymous',
@@ -38,13 +40,13 @@ class Anologue extends \lithium\data\Model {
);
/**
- * Create a new analogue using schema.
+ * Create a new anologue using schema.
*
* @param array $data
* @return void
* @see lithium\data\Model::create()
*/
- public static function create($data = array()) {
+ public static function create(array $data = array()) {
$default = array(
'messages' => null
);
@@ -61,13 +63,15 @@ class Anologue extends \lithium\data\Model {
*/
public static function addMessage($id, $message = array()) {
$anologue = static::find($id);
-
+
+ $message['text'] = Oembed::classify($message['text'], array('markdown' => true));
+
if (!empty($message['email'])) {
$message['email'] = md5($message['email']);
}
-
+
$message = $message + array('timestamp' => time()) + static::$_defaultMessage;
-
+
if (!$anologue->messages) {
$anologue->messages = array($message);
} else {
diff --git a/resources/tmp/cache/empty b/resources/tmp/cache/empty
new file mode 100755
index 0000000..e69de29
diff --git a/resources/tmp/cache/templates/empty b/resources/tmp/cache/templates/empty
new file mode 100644
index 0000000..e69de29
diff --git a/resources/tmp/logs/empty b/resources/tmp/logs/empty
new file mode 100755
index 0000000..e69de29
diff --git a/tmp/cache/empty b/tmp/cache/empty
deleted file mode 100644
index e69de29..0000000
diff --git a/tmp/logs/empty b/tmp/logs/empty
deleted file mode 100755
index e69de29..0000000
diff --git a/views/anologue/view.html.php b/views/anologue/view.html.php
index 35b48f9..910245b 100644
--- a/views/anologue/view.html.php
+++ b/views/anologue/view.html.php
@@ -11,7 +11,7 @@
<h1 class="smaller-title">
<?php
echo $this->html->link(
- 'anologue',
+ 'anologue',
array('controller' => 'anologue', 'action' => 'index')
);
?>
@@ -19,8 +19,8 @@
<h3 class="hash">
<?php
echo $this->html->link(
- $data->id,
- array('controller' => 'anologue', 'action' => 'view', 'id' => $data->id),
+ $data->id,
+ array('controller' => 'anologue', 'action' => 'view', 'id' => $data->id),
array('title' => 'Copy this url and give it to others')
);
?>
@@ -52,7 +52,7 @@
</li>
<li class="text">
<div class="markdown">
- <pre><?php echo $this->html->escape($message->text); ?></pre>
+ <pre><?php echo $h($message->text); ?></pre>
</div>
</li>
</ul>
@@ -85,7 +85,7 @@
<div class="about">
<?php
echo $this->html->link(
- 'what is anologue?',
+ 'what is anologue?',
array('controller' => 'anologue', 'action' => 'index')
);
?>
@@ -112,8 +112,8 @@
<audio id="anologue-speaker"></audio>
<?php echo $this->html->script(array(
- 'http://code.jquery.com/jquery-1.4.min.js',
- 'md5.jquery.js', 'showdown.js', 'pretty.js', 'anologue.js',
+ 'http://code.jquery.com/jquery-1.4.2.min.js',
+ 'md5.jquery', 'showdown', 'pretty', 'jquery.oembed', 'anologue',
)); ?>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
@@ -121,7 +121,8 @@
id: '<?=$data->id?>',
base: '<?php echo $this->_request->env('base') ?>',
line: <?php echo count($data->messages); ?>,
- icon: '<?php echo $avatar; ?>'
+ icon: '<?php echo $avatar; ?>',
+ intro: <?php echo (!empty($user['email']) || !empty($user['author'])) ? 'false' : 'true'; ?>
});
});
</script>
diff --git a/webroot/css/anologue.css b/webroot/css/anologue.css
index 11d32d7..ba8dd09 100644
--- a/webroot/css/anologue.css
+++ b/webroot/css/anologue.css
@@ -53,6 +53,7 @@ p.last { padding:.5em 0 4em 0; }
/** Anologue Messages **/
+ .anologue h1, .anologue h2, .anologue h3, .anologue h4, .anologue h5, .anologue h6 { margin: .5em 0; font-family: Helvetica, Arial, sans-serif; text-transform: none; }
.anologue .message { position:relative; display:block; background:#fafafa; border-bottom:3px solid white; vertical-align:top; font-size:.85em; min-height:3em; }
.anologue .message:hover { background:white; }
.anologue .data { position:relative; }
@@ -70,8 +71,11 @@ p.last { padding:.5em 0 4em 0; }
.anologue li.text { position:relative; padding:.25em .5em 0 2em; margin:0 0 0 19.90em; background:url(../img/pointer.png) no-repeat top left; min-height:2.75em; }
.anologue .text a { border-bottom:1px dotted #77458c; }
.anologue .text .markdown { }
- .anologue .text .markdown ul { padding:.25em 1em; }
-
+ .anologue .text .markdown ul, .anologue .text .markdown ol { margin: .5em 0; padding:0 1em 0 2em; font-size: 0.95em; }
+ .anologue .text .markdown li { margin: .25em 0;}
+ .anologue .text .markdown code { background:#454545; color:white; padding: .75em; -moz-box-shadow:0 0 4px black; -webkit-box-shadow: 0 0 4px black; box-shadow: 0 0 4px black; }
+ .anologue .text .markdown .oembed-container a { border-bottom: none; }
+ .anologue .text .markdown .oembed-container img, .anologue .text .markdown .oembed-container object { border: 1px solid #454545; -moz-box-shadow:0 0 4px black; -webkit-box-shadow: 0 0 4px black; box-shadow: 0 0 4px black; }
/** Anologue Footer "Speech" Bar **/
#anologue-speech-bar { position:fixed; z-index:50; bottom:-200px; left:0; display:block; width:100%; min-width:1006px; clear:both; background:black; background-color:rgba(0,0,0,.85); color:white; }
diff --git a/webroot/index.php b/webroot/index.php
index 6735be4..3b79fa0 100644
--- a/webroot/index.php
+++ b/webroot/index.php
@@ -2,23 +2,37 @@
/**
* Lithium: the most rad php framework
*
- * @copyright Copyright 2009, Union of Rad, Inc. (http://union-of-rad.org)
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
* @license http://opensource.org/licenses/bsd-license.php The BSD License
*/
/**
- * Welcome to Lithium! This front-controller file is the gateway to your application. It is
- * responsible for intercepting requests, and handing them off to the Dispatcher for processing.
+ * Welcome to Lithium! This front-controller file is the gateway to your application. It is
+ * responsible for intercepting requests, and handing them off to the `Dispatcher` for processing.
*
* If you're sharing a single Lithium core install or other libraries among multiple
- * applications, you may need to manually set things like LITHIUM_LIBRARY_PATH. You can do that in
- * app/config/bootstrap.php, which is loaded below:
+ * applications, you may need to manually set things like `LITHIUM_LIBRARY_PATH`. You can do that in
+ * `config/bootstrap.php`, which is loaded below:
*/
require dirname(__DIR__) . '/config/bootstrap.php';
/**
- * Dispatch a new request with the default settings.
+ * The following will instantiate a new `Request` object and pass it off to the `Dispatcher` class.
+ * By default, the `Request` will automatically aggregate all the server / environment settings, URL
+ * and query string parameters, request content (i.e. POST or PUT data), and HTTP method and header
+ * information.
+ *
+ * The `Request` is then used by the `Dispatcher` (in conjunction with the `Router`) to determine
+ * the correct controller to dispatch to, and the correct response type to render. The response
+ * information is then encapsulated in a `Response` object, which is returned from the controller
+ * to the `Dispatcher`, and finally echoed below. Echoing a `Response` object causes its headers to
+ * be written, and its response body to be written in a buffer loop.
+ *
+ * @see lithium\action\Request
+ * @see lithium\action\Response
+ * @see lithium\action\Dispatcher
+ * @see lithium\net\http\Router
*/
-echo lithium\action\Dispatcher::run();
+echo lithium\action\Dispatcher::run(new lithium\action\Request());
?>
\ No newline at end of file
diff --git a/webroot/js/anologue.js b/webroot/js/anologue.js
index 45532b3..92298db 100644
--- a/webroot/js/anologue.js
+++ b/webroot/js/anologue.js
@@ -3,12 +3,13 @@ var anologue = {
id: 0,
base : null,
line: 0,
- icon: null
+ icon: null,
+ intro: true,
},
shiftDown: false,
setup: function(config) {
- this._config = config;
+ this._config = $.extend(this._config, config);
$(".sound label").click(function() {
anologue.toggleIcon('.sound');
});
@@ -26,7 +27,7 @@ var anologue = {
anologue.markdownHelp();
return false;
});
-
+
this.setupSubmit();
this.markdown();
this.fireworks();
@@ -34,7 +35,7 @@ var anologue = {
this.listener();
this.humanizeTimes();
this.humanizeTimesTimer();
-
+
$('body').focusin(function() {
anologue.resetTitle();
});
@@ -42,13 +43,17 @@ var anologue = {
anologue.resetTitle();
});
},
-
+
fireworks: function() {
- $("#anologue-help").animate({bottom: 0}, 2500);
+ if (this._config.intro) {
+ $("#anologue-help").animate({bottom: 0}, 2500);
+ } else {
+ this.closeHelp();
+ }
$("#anologue-speech-bar").animate({bottom: 0}, 1500);
$("#anologue-author").focus();
},
-
+
setupSubmit: function() {
$("#anologue-form").submit(function() {
anologue.say();
@@ -141,13 +146,13 @@ var anologue = {
var id = 'message-' + $.md5(message.timestamp + message.author);
var html = '<li class="message" id="' + id + '" style="display:none;"><ul class="data"><li class="time"><span class="timestamp">' + message.timestamp + '</span><span class="human-time">' + this.humanizeTime(message.timestamp) + '</span></li><li class="ip">' + message.ip + '</li><li class="author"><img class="gravatar" src="http://gravatar.com/avatar/' + message.email + '?s=16&d=' + this._config.icon + '" border="0" /> <span title="' + $('<div/>').text(message.author).html() + '">' + $('<div/>').text(message.author).html() + '</span> </li><li class="text"><div class="markdown"><pre>' + $('<div/>').text(message.text).html() + '</pre></div></li></ul></li>';
$("#anologue").append(html);
-
+
var docTitle = message.author+' posted a new message';
-
+
var soundDisabled = $('.anologue-settings .sound .icon').hasClass('disabled');
-
+
var user = $('#anologue-author').val();
-
+
if (!soundDisabled) {
// lazy check to not trigger sound on your message
if (message.author != user && user != '') {
@@ -158,11 +163,11 @@ var anologue = {
}
}
}
-
+
if (message.author != user) {
this.updateTitle(docTitle);
}
-
+
$('#'+id).animate({
opacity: 'show'
}, 1000);
@@ -207,10 +212,15 @@ var anologue = {
var showdown = new Showdown.converter();
var text = showdown.makeHtml($(this).children('pre').html());
$(this).html(text).addClass('marked');
+ $(this).find("a").oembed(null, {
+ embedMethod: 'annotate',
+ maxWidth: 425,
+ maxHeight: 425
+ });
}
});
},
-
+
toggleIcon: function(parentClass) {
var disabled = $('.anologue-settings '+parentClass+' .icon').hasClass('disabled');
if (!disabled) {
@@ -219,7 +229,7 @@ var anologue = {
$(parentClass+' .icon').removeClass('disabled');
}
},
-
+
closeHelp: function() {
if (!$("#anologue-help").hasClass('closed')) {
$("#anologue-help").animate({bottom: '-500px'}, 1000);
@@ -227,14 +237,14 @@ var anologue = {
}
return false;
},
-
+
getOption: function(parentClass) {
var disabled = $('.anologue-settings '+parentClass+' .icon').hasClass('disabled');
return !disabled;
},
-
+
humanizeTimesTimeout: null,
-
+
humanizeTimesTimer: function() {
clearTimeout(this.humanizeTimesTimeout);
anologue.humanizeTimes();
@@ -242,7 +252,7 @@ var anologue = {
anologue.humanizeTimesTimer();
}, 15000);
},
-
+
humanizeTimes: function() {
$('li.time').each(function() {
var time = $(this).children('.timestamp').first().text();
@@ -250,19 +260,19 @@ var anologue = {
$(this).children('.human-time').first().text(prettyTime);
});
},
-
+
humanizeTime: function(timestamp) {
return PrettyDate.convert(timestamp);
},
-
+
resetTitle: function() {
document.title = 'anologue';
},
-
+
updateTitle: function(msg) {
document.title = msg + ' - anologue';
},
-
+
markdownHelp: function() {
if (!$('#anologue-help .padding').hasClass("markdown-help")) {
var html = '<h2>Markdown Syntax</h2><p># header 1 ## header 2 <em>*italic*</em> <strong>**bold**</strong> - unordered list 1. ordered list [a link](http://example.com/) </p>';
@@ -280,11 +290,15 @@ var anologue = {
this.showMarkdownHelp();
}
},
-
+
showMarkdownHelp: function() {
- $("#anologue-help").animate({bottom: 0}, 1000, function() {
- $("#anologue-help").removeClass('closed');
- });
+ if ($("#anologue-help").hasClass('closed')) {
+ $("#anologue-help").animate({bottom: 0}, 1000, function() {
+ $("#anologue-help").removeClass('closed');
+ });
+ } else {
+ this.closeHelp();
+ }
}
-
+
}
diff --git a/webroot/js/jquery.oembed.js b/webroot/js/jquery.oembed.js
new file mode 100644
index 0000000..f6283d1
--- /dev/null
+++ b/webroot/js/jquery.oembed.js
@@ -0,0 +1,236 @@
+(function($) {
+ $.fn.oembed = function(url, options, callback) {
+
+ options = $.extend(true, $.fn.oembed.defaults, options);
+
+ return this.each(function() {
+
+ var container = $(this),
+ resourceURL = (url != null) ? url : container.attr("href"),
+ provider;
+
+ if (!callback) callback = function(container, oembed) {
+ $.fn.oembed.insertCode(container, options.embedMethod, oembed);
+ };
+
+ if (resourceURL != null) {
+ provider = getOEmbedProvider(resourceURL);
+
+ if (provider != null) {
+ provider.params = getNormalizedParams(options[provider.name]) || {};
+ provider.maxWidth = options.maxWidth;
+ provider.maxHeight = options.maxHeight;
+ provider.embedCode(container, resourceURL, callback);
+ return;
+ }
+ }
+
+ callback(container, null);
+ });
+ };
+
+ // Plugin defaults
+ $.fn.oembed.defaults = {
+ maxWidth: null,
+ maxHeight: null,
+ embedMethod: "replace" // "auto", "append", "fill"
+ };
+
+ $.fn.oembed.insertCode = function(container, embedMethod, oembed) {
+ if (oembed == null)
+ return;
+ switch(embedMethod)
+ {
+ case "auto":
+ if (container.attr("href") != null) {
+ insertCode(container, "append", oembed);
+ }
+ else {
+ insertCode(container, "replace", oembed);
+ };
+ break;
+ case "replace":
+ container.replaceWith(oembed.code);
+ break;
+ case "fill":
+ container.html(oembed.code);
+ break;
+ case "append":
+ var oembedContainer = this.getOembedContainer(container, oembed);
+ oembedContainer.html(oembed.code);
+ break;
+ case "annotate":
+ if (!$(container).hasClass('open')) {
+ var oembedContainer = this.getOembedContainer(container, oembed);
+ oembedContainer.html(oembed.code);
+ container.before(oembedContainer);
+ container.addClass('open');
+ }
+ break;
+ }
+ }
+
+ $.fn.oembed.getOembedContainer = function(container, oembed) {
+ var oembedContainer = container.next();
+ if (oembedContainer == null || !oembedContainer.hasClass("oembed-container")) {
+ oembedContainer = container
+ .after('<div class="oembed-container"></div>')
+ .next(".oembed-container");
+ if (oembed != null && oembed.provider_name != null)
+ oembedContainer.toggleClass("oembed-container-" + oembed.provider_name);
+ }
+ return oembedContainer;
+ }
+
+ $.fn.oembed.getPhotoCode = function(url, data) {
+ var alt = data.title ? data.title : '';
+ alt += data.author_name ? ' - ' + data.author_name : '';
+ alt += data.provider_name ? ' - ' +data.provider_name : '';
+ var code = '<div><a href="' + url + '" target="_blank"><img src="' + data.url + '" alt="' + alt + '"/></a></div>';
+ if (data.html)
+ code += "<div>" + data.html + "</div>";
+ return code;
+ };
+
+ $.fn.oembed.getVideoCode = function(url, data) {
+ var code = data.html;
+ return code;
+ };
+
+ $.fn.oembed.getRichCode = function(url, data) {
+ var code = data.html;
+ return code;
+ };
+
+ $.fn.oembed.getGenericCode = function(url, data) {
+ var title = (data.title != null) ? data.title : url,
+ code = '<a href="' + url + '">' + title + '</a>';
+ if (data.html)
+ code += "<div>" + data.html + "</div>";
+ return code;
+ };
+
+ $.fn.oembed.isAvailable = function(url) {
+ var provider = getOEmbedProvider(url);
+ return (provider != null);
+ };
+
+ /* Private Methods */
+ function getOEmbedProvider(url) {
+ for (var i = 0; i < providers.length; i++) {
+ if (providers[i].matches(url))
+ return providers[i];
+ }
+ return null;
+ }
+
+ function getNormalizedParams(params) {
+ if (params == null)
+ return null;
+ var normalizedParams = {};
+ for (var key in params) {
+ if (key != null)
+ normalizedParams[key.toLowerCase()] = params[key];
+ }
+ return normalizedParams;
+ }
+
+ var providers = [
+ new OEmbedProvider("fivemin", "5min.com"),
+ new OEmbedProvider("amazon", "amazon.com"),
+ new OEmbedProvider("flickr", "flickr", "http://flickr.com/services/oembed", "jsoncallback"),
+ new OEmbedProvider("googlevideo", "video.google."),
+ new OEmbedProvider("hulu", "hulu.com"),
+ new OEmbedProvider("imdb", "imdb.com"),
+ new OEmbedProvider("metacafe", "metacafe.com"),
+ new OEmbedProvider("qik", "qik.com"),
+ new OEmbedProvider("revision3", "slideshare"),
+ new OEmbedProvider("slideshare", "5min.com"),
+ new OEmbedProvider("twitpic", "twitpic.com"),
+ new OEmbedProvider("viddler", "viddler.com"),
+ new OEmbedProvider("vimeo", "vimeo.com", "http://vimeo.com/api/oembed.json"),
+ new OEmbedProvider("wikipedia", "wikipedia.org"),
+ new OEmbedProvider("wordpress", "wordpress.com"),
+ new OEmbedProvider("youtube", "youtube.com"),
+ new OEmbedProvider("vids.myspace.com", "vids.myspace.com", "http://vids.myspace.com/index.cfm?fuseaction=oembed"),
+ new OEmbedProvider("screenr", "screenr.com", "http://screenr.com/api/oembed.json")
+ ];
+
+ function OEmbedProvider(name, urlPattern, oEmbedUrl, callbackparameter) {
+ this.name = name;
+ this.urlPattern = urlPattern;
+ this.oEmbedUrl = (oEmbedUrl != null) ? oEmbedUrl : "http://oohembed.com/oohembed/";
+ this.callbackparameter = (callbackparameter != null) ? callbackparameter : "callback";
+ this.maxWidth = 500;
+ this.maxHeight = 400;
+
+ this.matches = function(externalUrl) {
+ // TODO: Convert to Regex
+ return externalUrl.indexOf(this.urlPattern) >= 0;
+ };
+
+ this.getRequestUrl = function(externalUrl) {
+
+ var url = this.oEmbedUrl;
+
+ if (url.indexOf("?") <= 0)
+ url = url + "?";
+ else
+ url = url + "&";
+
+ var qs = "";
+
+ if (this.maxWidth != null && this.params["maxwidth"] == null)
+ this.params["maxwidth"] = this.maxWidth;
+
+ if (this.maxHeight != null && this.params["maxheight"] == null)
+ this.params["maxheight"] = this.maxHeight;
+
+ for (var i in this.params) {
+ // We don't want them to jack everything up by changing the callback parameter
+ if (i == this.callbackparameter)
+ continue;
+
+ // allows the options to be set to null, don't send null values to the server as parameters
+ if (this.params[i] != null)
+ qs += "&" + escape(i) + "=" + this.params[i];
+ }
+
+
+ url += "format=json&url=" + escape(externalUrl) +
+ qs +
+ "&" + this.callbackparameter + "=?";
+
+ return url;
+ }
+
+ this.embedCode = function(container, externalUrl, callback) {
+
+ var request = this.getRequestUrl(externalUrl);
+
+ $.getJSON(request, function(data) {
+
+ var oembed = $.extend(data);
+
+ var code, type = data.type;
+
+ switch (type) {
+ case "photo":
+ oembed.code = $.fn.oembed.getPhotoCode(externalUrl, data);
+ break;
+ case "video":
+ oembed.code = $.fn.oembed.getVideoCode(externalUrl, data);
+ break;
+ case "rich":
+ oembed.code = $.fn.oembed.getRichCode(externalUrl, data);
+ break;
+ default:
+ oembed.code = $.fn.oembed.getGenericCode(externalUrl, data);
+ break;
+ }
+
+ callback(container, oembed);
+ });
+ }
+ }
+})(jQuery);
\ No newline at end of file