Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adding min/pack detection and auto use.

  • Loading branch information...
commit 0c77cc98b58187802c0d9e5bdd60e912b4b006a2 1 parent 9022784
@markstory markstory authored
View
91 cake/libs/view/helpers/js.php
@@ -31,7 +31,7 @@
* @package cake
* @subpackage cake.cake.libs.view.helpers
*/
-class JsHelper extends Overloadable {
+class JsHelper extends AppHelper {
/**
* Base URL
*
@@ -85,7 +85,19 @@ class JsHelper extends Overloadable {
*
* @var array
**/
- public $helpers = array();
+ var $helpers = array();
+/**
+ * HTML tags used by this helper.
+ *
+ * @var array
+ * @access public
+ */
+ var $tags = array(
+ 'javascriptblock' => '<script type="text/javascript">%s</script>',
+ 'javascriptstart' => '<script type="text/javascript">',
+ 'javascriptlink' => '<script type="text/javascript" src="%s"></script>',
+ 'javascriptend' => '</script>'
+ );
/**
* Current Javascript Engine that is being used
*
@@ -94,6 +106,13 @@ class JsHelper extends Overloadable {
**/
var $__engineName;
/**
+ * Scripts that have already been included once, prevents duplicate script insertion
+ *
+ * @var array
+ * @access private
+ **/
+ var $__includedScriptNames = array();
+/**
* __objects
*
* @var array
@@ -160,6 +179,74 @@ function call__($method, $params) {
function alert_($message) {
return 'alert("' . $this->escape($message) . '");';
}
+/**
+ * Returns one or many <script> tags depending on the number of scripts given.
+ *
+ * If the filename is prefixed with "/", the path will be relative to the base path of your
+ * application. Otherwise, the path will be relative to your JavaScript path, usually webroot/js.
+ *
+ * Can include one or many Javascript files. If there are .min.js or .pack.js files
+ * and your debug level == 0 these files will be used instead of the non min/pack files.
+ *
+ * @param mixed $url String or array of javascript files to include
+ * @param boolean $inline Whether script should be output inline or into scripts_for_layout.
+ * @return mixed
+ **/
+ function uses($url, $inline = true) {
+ if (is_array($url)) {
+ $out = '';
+ foreach ($url as $i) {
+ $out .= "\n\t" . $this->uses($i, $inline);
+ }
+ if ($inline) {
+ return $out . "\n";
+ }
+ return;
+ }
+
+ if (strpos($url, '://') === false) {
+ if ($url[0] !== '/') {
+ $url = JS_URL . $url;
+ }
+ $url = $this->webroot($url);
+
+ if (strpos($url, '?') === false) {
+ if (Configure::read('debug') == 0) {
+ $suffixes = array('.min.js', '.pack.js');
+ foreach ($suffixes as $suffix) {
+ if (file_exists(WWW_ROOT . $url . $suffix)) {
+ $url .= $suffix;
+ break;
+ }
+ }
+ }
+ if (strpos($url, '.js') === false) {
+ $url .= '.js';
+ }
+ }
+
+ $timestampEnabled = (
+ (Configure::read('Asset.timestamp') === true && Configure::read() > 0) ||
+ Configure::read('Asset.timestamp') === 'force'
+ );
+
+ if (strpos($url, '?') === false && $timestampEnabled) {
+ $url .= '?' . @filemtime(WWW_ROOT . str_replace('/', DS, $url));
+ }
+
+ if (Configure::read('Asset.filter.js')) {
+ $url = str_replace(JS_URL, 'cjs/', $url);
+ }
+ }
+ $out = $this->output(sprintf($this->tags['javascriptlink'], $url));
+
+ if ($inline) {
+ return $out;
+ } else {
+ $view =& ClassRegistry::getObject('view');
+ $view->addScript($out);
+ }
+ }
function if_($if, $then, $else = null, $elseIf = array()) {
$len = strlen($if) - 1;
View
71 cake/tests/cases/libs/view/helpers/js.test.php
@@ -79,8 +79,12 @@ function testMethodDispatching() {
$js = new JsHelper(array('TestJs'));
$js->TestJsEngine = new TestJsEngineHelper();
$js->TestJsEngine->expectOnce('dispatchMethod', array('methodOne', array()));
-
+
$js->methodOne();
+
+ $js->TestEngine = new StdClass();
+ $this->expectError();
+ $js->someMethodThatSurelyDoesntExist();
}
/**
* test escape string skills
@@ -141,6 +145,71 @@ function testAlert() {
$this->assertEqual($result, $expected);
}
/**
+ * test script tag generation
+ *
+ * @return void
+ **/
+ function testUses() {
+ $result = $this->Js->uses('foo');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/foo.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Js->uses('jquery-1.3');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/jquery-1.3.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Js->uses('/plugin/js/jquery-1.3');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => '/plugin/js/jquery-1.3.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Js->uses('scriptaculous.js?load=effects');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/scriptaculous.js?load=effects')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Js->uses(array('foo', 'bar'));
+ $expected = array(
+ array('script' => array('type' => 'text/javascript', 'src' => 'js/foo.js')),
+ '/script',
+ array('script' => array('type' => 'text/javascript', 'src' => 'js/bar.js')),
+ '/script',
+ );
+ $this->assertTags($result, $expected);
+ }
+/**
+ * test Min/pack version autofinding
+ *
+ * @return void
+ **/
+ function testMinPackAutoUse() {
+ if ($this->skipIf(!is_writable(JS), 'webroot/js is not Writable, min/pack js testing is skipped')) {
+ return;
+ }
+ Configure::write('debug', 0);
+ touch(WWW_ROOT . 'js' . DS. '__cake_js_min_test.min.js');
+ touch(WWW_ROOT . 'js' . DS. '__cake_js_pack_test.pack.js');
+
+ $result = $this->Js->uses('__cake_js_min_test');
+ $this->assertPattern('/__cake_js_min_test\.min\.js/', $result);
+
+ $result = $this->Js->uses('__cake_js_pack_test');
+ $this->assertPattern('/__cake_js_pack_test\.pack\.js/', $result);
+
+ Configure::write('debug', 2);
+ $result = $this->Js->uses('__cake_js_pack_test');
+ $this->assertNoPattern('/pack\.js/', $result);
+
+ unlink(WWW_ROOT . 'js' . DS. '__cake_js_min_test.min.js');
+ unlink(WWW_ROOT . 'js' . DS. '__cake_js_pack_test.pack.js');
+ }
+/**
* test confirm generation
*
* @return void
Please sign in to comment.
Something went wrong with that request. Please try again.