Version Description
- Fixed an issue when you both add and delete Attachments prior to saving posts
- Cleaned up the JavaScript that powers the file browse interaction
- Swapped out some custom code for WordPress native function calls
- Better handling of asset inclusion
Download this release
Release Info
Developer | jchristopher |
Plugin | Attachments |
Version | 1.6.2 |
Comparing to | |
See all releases |
Code changes from version 1.6.1 to 1.6.2
- attachments.options.php +0 -13
- attachments.php +131 -177
- js/attachments.js +146 -14
- js/handlebars.js +1554 -0
- readme.txt +8 -18
attachments.options.php
CHANGED
@@ -1,22 +1,9 @@
|
|
1 |
-
<?php
|
2 |
-
if( isset( $_GET['dismisspro'] ) )
|
3 |
-
{
|
4 |
-
update_option( '_attachments_dismiss_pro', 1 );
|
5 |
-
}
|
6 |
-
?>
|
7 |
-
|
8 |
<div class="wrap">
|
9 |
|
10 |
<div id="icon-options-general" class="icon32"><br /></div>
|
11 |
|
12 |
<h2>Attachments Options</h2>
|
13 |
|
14 |
-
<?php $attachments_dismiss_pro = get_option( '_attachments_dismiss_pro' ); if( !$attachments_dismiss_pro ) : ?>
|
15 |
-
<div class="updated">
|
16 |
-
<?php _e( '<p><strong>Attachments Pro is now available!</strong> <a href="http://mondaybynoon.com/store/attachments-pro/">Find out more</a> about Attachments Pro. <a href="options-general.php?page=attachments/attachments.php&dismisspro=1">Dismiss</a>.</p>', 'attachments' ); ?>
|
17 |
-
</div>
|
18 |
-
<?php endif; ?>
|
19 |
-
|
20 |
<form action="options.php" method="post">
|
21 |
<div id="poststuff" class="metabox-holder">
|
22 |
<?php settings_fields( 'attachments_settings' ); ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<div class="wrap">
|
2 |
|
3 |
<div id="icon-options-general" class="icon32"><br /></div>
|
4 |
|
5 |
<h2>Attachments Options</h2>
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
<form action="options.php" method="post">
|
8 |
<div id="poststuff" class="metabox-holder">
|
9 |
<?php settings_fields( 'attachments_settings' ); ?>
|
attachments.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Attachments
|
4 |
Plugin URI: http://mondaybynoon.com/wordpress-attachments/
|
5 |
Description: Attachments gives the ability to append any number of Media Library items to Pages, Posts, and Custom Post Types
|
6 |
-
Version: 1.6.
|
7 |
Author: Jonathan Christopher
|
8 |
Author URI: http://mondaybynoon.com/
|
9 |
*/
|
@@ -30,8 +30,10 @@
|
|
30 |
if( !defined( 'IS_ADMIN' ) )
|
31 |
define( 'IS_ADMIN', is_admin() );
|
32 |
|
33 |
-
define( 'ATTACHMENTS_PREFIX',
|
34 |
-
define( 'ATTACHMENTS_VERSION',
|
|
|
|
|
35 |
|
36 |
|
37 |
// ===========
|
@@ -39,9 +41,6 @@ define( 'ATTACHMENTS_VERSION', '1.6' );
|
|
39 |
// ===========
|
40 |
|
41 |
global $wpdb;
|
42 |
-
global $units;
|
43 |
-
|
44 |
-
$units = array( ' bytes', ' KB', ' MB', ' GB', ' TB', ' PB' );
|
45 |
|
46 |
// environment check
|
47 |
$wp_version = get_bloginfo( 'version' );
|
@@ -67,21 +66,55 @@ if( !version_compare( PHP_VERSION, '5.2', '>=' ) || !version_compare( $wp_versio
|
|
67 |
|
68 |
if( IS_ADMIN )
|
69 |
{
|
70 |
-
|
71 |
-
|
72 |
-
add_action( '
|
73 |
-
|
74 |
-
|
75 |
-
add_action( '
|
76 |
-
add_action( '
|
77 |
-
|
78 |
-
|
79 |
-
add_action( '
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
83 |
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
|
86 |
// =============
|
87 |
// = FUNCTIONS =
|
@@ -153,34 +186,34 @@ function attachments_register_settings()
|
|
153 |
{
|
154 |
// flag our settings
|
155 |
register_setting(
|
156 |
-
ATTACHMENTS_PREFIX . 'settings',
|
157 |
-
ATTACHMENTS_PREFIX . 'settings',
|
158 |
-
'attachments_validate_settings'
|
159 |
);
|
160 |
|
161 |
add_settings_section(
|
162 |
-
ATTACHMENTS_PREFIX . 'options',
|
163 |
-
'Post Type Settings',
|
164 |
-
'attachments_edit_options',
|
165 |
-
'attachments_options'
|
166 |
);
|
167 |
|
168 |
// post types
|
169 |
add_settings_field(
|
170 |
-
ATTACHMENTS_PREFIX . 'post_types',
|
171 |
-
'Post Types',
|
172 |
-
'attachments_edit_post_types',
|
173 |
-
'attachments_options',
|
174 |
-
ATTACHMENTS_PREFIX . 'options'
|
175 |
);
|
176 |
|
177 |
// post_parent
|
178 |
add_settings_field(
|
179 |
-
ATTACHMENTS_PREFIX . 'post_parent',
|
180 |
-
'Set Post Parent',
|
181 |
-
'attachments_edit_post_parent',
|
182 |
-
'attachments_options',
|
183 |
-
ATTACHMENTS_PREFIX . 'options'
|
184 |
);
|
185 |
}
|
186 |
|
@@ -231,31 +264,6 @@ function attachments_edit_post_types()
|
|
231 |
<?php endforeach; endif; ?>
|
232 |
<?php }
|
233 |
|
234 |
-
/**
|
235 |
-
* Includes our plugin update message
|
236 |
-
*
|
237 |
-
* @return void
|
238 |
-
* @author Jonathan Christopher
|
239 |
-
*/
|
240 |
-
function attachments_update_message()
|
241 |
-
{ ?>
|
242 |
-
<div style="color: #f00;padding-top:4px;">Attachments Pro is now available!</div>
|
243 |
-
<div style="font-weight:normal;padding-top:8px;">
|
244 |
-
<p><a href="http://mondaybynoon.com/store/attachments-pro/">Attachments Pro</a> is Attachments' big brother. With it come a number of often-requested features such as:</p>
|
245 |
-
<ul style="list-style:disc;padding-left:20px;margin-bottom:13px;overflow:hidden;zoom:1;">
|
246 |
-
<li style="width:48%;padding-right:2%;float:left;">Multiple Attachments instances on edit screens</li>
|
247 |
-
<li style="width:48%;padding-right:2%;float:left;">Customizable field labels and meta box title</li>
|
248 |
-
<li style="width:48%;padding-right:2%;float:left;">Unlimited number of fields per Attachment</li>
|
249 |
-
<li style="width:48%;padding-right:2%;float:left;">Ability to define rules limiting the availability of Attachments on edit screens</li>
|
250 |
-
<li style="width:48%;padding-right:2%;float:left;">Limit the number of Attachments that can be added</li>
|
251 |
-
<li style="width:48%;padding-right:2%;float:left;">Limit Attach-able Media items by file/mime type</li>
|
252 |
-
<li style="width:48%;padding-right:2%;float:left;">Shortcode support</li>
|
253 |
-
<li style="width:48%;padding-right:2%;float:left;">Auto-inclusion of Attachments content within the_content()</li>
|
254 |
-
</ul>
|
255 |
-
<p>Attachments has always been and <em>will always be free</em>. <a href="http://mondaybynoon.com/store/attachments-pro/">Attachments Pro</a> is <strong>available now</strong>. To find out more about the new features already added, and to stay up-to-date on what's to come, <a href="http://mondaybynoon.com/store/attachments-pro/">have a look at the details</a>. From there, you can make formal support and feature requests.</p>
|
256 |
-
</div>
|
257 |
-
<?php }
|
258 |
-
|
259 |
|
260 |
/**
|
261 |
* Compares two array values with the same key "order"
|
@@ -316,7 +324,7 @@ function attachments_menu()
|
|
316 |
* @author Jonathan Christopher
|
317 |
*/
|
318 |
function attachments_add()
|
319 |
-
{?>
|
320 |
|
321 |
<div id="attachments-inner">
|
322 |
|
@@ -344,46 +352,70 @@ function attachments_add()
|
|
344 |
|
345 |
if( is_array($existing_attachments) && !empty($existing_attachments) )
|
346 |
{
|
347 |
-
$
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
<input type="text" id="attachment_title_<?php echo $attachment_index; ?>" name="attachment_title_<?php echo $attachment_index; ?>" value="<?php echo $attachment['title']; ?>" size="20" />
|
361 |
-
</div>
|
362 |
-
<div class="textfield" id="field_attachment_caption_<?php echo $attachment_index; ?>">
|
363 |
-
<label for="attachment_caption_<?php echo $attachment_index; ?>"><?php _e("Caption", "attachments")?></label>
|
364 |
-
<input type="text" id="attachment_caption_<?php echo $attachment_index; ?>" name="attachment_caption_<?php echo $attachment_index; ?>" value="<?php echo $attachment['caption']; ?>" size="20" />
|
365 |
-
</div>
|
366 |
-
</div>
|
367 |
-
<div class="attachments-data">
|
368 |
-
<input type="hidden" name="attachment_id_<?php echo $attachment_index; ?>" id="attachment_id_<?php echo $attachment_index; ?>" value="<?php echo $attachment['id']; ?>" />
|
369 |
-
<input type="hidden" class="attachment_order" name="attachment_order_<?php echo $attachment_index; ?>" id="attachment_order_<?php echo $attachment_index; ?>" value="<?php echo $attachment['order']; ?>" />
|
370 |
-
</div>
|
371 |
-
<div class="attachment-thumbnail">
|
372 |
-
<span class="attachments-thumbnail">
|
373 |
-
<?php echo wp_get_attachment_image( $attachment['id'], array(80, 60), 1 ); ?>
|
374 |
-
</span>
|
375 |
-
</div>
|
376 |
-
</li>
|
377 |
-
<?php endforeach;
|
378 |
}
|
379 |
}
|
380 |
?>
|
381 |
</ul>
|
382 |
</div>
|
383 |
</div>
|
|
|
|
|
|
|
384 |
<?php }
|
385 |
|
386 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
/**
|
388 |
* Creates meta box on all Posts and Pages
|
389 |
*
|
@@ -508,10 +540,10 @@ function attachments_save($post_id)
|
|
508 |
$attachment_id = intval( $_POST['attachment_id_' . $i] );
|
509 |
|
510 |
$attachment_details = array(
|
511 |
-
'id'
|
512 |
-
'title'
|
513 |
-
'caption'
|
514 |
-
'order'
|
515 |
);
|
516 |
|
517 |
// serialize data and encode
|
@@ -525,7 +557,7 @@ function attachments_save($post_id)
|
|
525 |
if( isset( $settings['post_parent'] ) && $settings['post_parent'] )
|
526 |
{
|
527 |
// need to first check to make sure we're not overwriting a native Attach
|
528 |
-
$attach_post_ref
|
529 |
|
530 |
if( $attach_post_ref->post_parent == 0 )
|
531 |
{
|
@@ -555,14 +587,10 @@ function attachments_save($post_id)
|
|
555 |
*/
|
556 |
function attachments_get_filesize_formatted( $path = NULL )
|
557 |
{
|
558 |
-
global $units;
|
559 |
$formatted = '0 bytes';
|
560 |
if( file_exists( $path ) )
|
561 |
{
|
562 |
-
$
|
563 |
-
$s = $units;
|
564 |
-
$e = floor( log( $bytes ) / log( 1024 ) );
|
565 |
-
$formatted = sprintf( '%.2f ' . $s[$e], ( $bytes / pow( 1024, floor( $e ) ) ) );
|
566 |
}
|
567 |
return $formatted;
|
568 |
}
|
@@ -621,78 +649,4 @@ function attachments_get_attachments( $post_id=null )
|
|
621 |
}
|
622 |
|
623 |
return $post_attachments;
|
624 |
-
}
|
625 |
-
|
626 |
-
|
627 |
-
/**
|
628 |
-
* Outputs Attachments JS into the footer
|
629 |
-
*
|
630 |
-
* @return void
|
631 |
-
* @author Jonathan Christopher
|
632 |
-
*/
|
633 |
-
function attachments_footer_js()
|
634 |
-
{
|
635 |
-
$uri = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : NULL ;
|
636 |
-
$file = basename( parse_url( $uri, PHP_URL_PATH ) );
|
637 |
-
|
638 |
-
if( $uri && in_array( $file, array( 'post.php', 'post-new.php' ) ) )
|
639 |
-
{
|
640 |
-
// we only want this to fire on edit screens
|
641 |
-
echo '<script type="text/javascript">';
|
642 |
-
include 'js/attachments.js';
|
643 |
-
echo '</script>';
|
644 |
-
}
|
645 |
-
}
|
646 |
-
|
647 |
-
|
648 |
-
/**
|
649 |
-
* This is the main initialization function, it will invoke the necessary meta_box
|
650 |
-
*
|
651 |
-
* @return void
|
652 |
-
* @author Jonathan Christopher
|
653 |
-
*/
|
654 |
-
function attachments_init()
|
655 |
-
{
|
656 |
-
wp_enqueue_script( 'jquery-ui-core' );
|
657 |
-
wp_enqueue_script( 'thickbox' );
|
658 |
-
|
659 |
-
wp_enqueue_style( 'thickbox' );
|
660 |
-
wp_enqueue_style( 'attachments', WP_PLUGIN_URL . '/attachments/css/attachments.css' );
|
661 |
-
|
662 |
-
if( function_exists( 'load_plugin_textdomain' ) )
|
663 |
-
{
|
664 |
-
if( !defined('WP_PLUGIN_DIR') )
|
665 |
-
{
|
666 |
-
load_plugin_textdomain( 'attachments', str_replace( ABSPATH, '', dirname( __FILE__ ) ) );
|
667 |
-
}
|
668 |
-
else
|
669 |
-
{
|
670 |
-
load_plugin_textdomain( 'attachments', false, dirname( plugin_basename( __FILE__ ) ) );
|
671 |
-
}
|
672 |
-
}
|
673 |
-
|
674 |
-
attachments_meta_box();
|
675 |
-
}
|
676 |
-
|
677 |
-
|
678 |
-
/**
|
679 |
-
* Modifies the plugin meta line on the WP Plugins page
|
680 |
-
*
|
681 |
-
* @param $plugin_meta
|
682 |
-
* @param $plugin_file
|
683 |
-
* @return array $plugin_meta Array of plugin meta data
|
684 |
-
* @author Jonathan Christopher
|
685 |
-
*/
|
686 |
-
function attachments_filter_plugin_row_meta( $plugin_meta, $plugin_file )
|
687 |
-
{
|
688 |
-
if( strstr( $plugin_file, 'attachments/attachments.php' ) )
|
689 |
-
{
|
690 |
-
$plugin_meta[2] = '<a title="Attachments Pro" href="http://mondaybynoon.com/store/attachments-pro/">Attachments Pro</a>';
|
691 |
-
$plugin_meta[3] = 'Visit <a title="Iron to Iron" href="http://irontoiron.com/">Iron to Iron</a>';
|
692 |
-
return $plugin_meta;
|
693 |
-
}
|
694 |
-
else
|
695 |
-
{
|
696 |
-
return $plugin_meta;
|
697 |
-
}
|
698 |
-
}
|
3 |
Plugin Name: Attachments
|
4 |
Plugin URI: http://mondaybynoon.com/wordpress-attachments/
|
5 |
Description: Attachments gives the ability to append any number of Media Library items to Pages, Posts, and Custom Post Types
|
6 |
+
Version: 1.6.2
|
7 |
Author: Jonathan Christopher
|
8 |
Author URI: http://mondaybynoon.com/
|
9 |
*/
|
30 |
if( !defined( 'IS_ADMIN' ) )
|
31 |
define( 'IS_ADMIN', is_admin() );
|
32 |
|
33 |
+
define( 'ATTACHMENTS_PREFIX', 'attachments_' );
|
34 |
+
define( 'ATTACHMENTS_VERSION', '1.6.2' );
|
35 |
+
define( 'ATTACHMENTS_URL', plugin_dir_url( __FILE__ ) );
|
36 |
+
define( 'ATTACHMENTS_DIR', plugin_dir_path( __FILE__ ) );
|
37 |
|
38 |
|
39 |
// ===========
|
41 |
// ===========
|
42 |
|
43 |
global $wpdb;
|
|
|
|
|
|
|
44 |
|
45 |
// environment check
|
46 |
$wp_version = get_bloginfo( 'version' );
|
66 |
|
67 |
if( IS_ADMIN )
|
68 |
{
|
69 |
+
|
70 |
+
// pre-flight check
|
71 |
+
add_action( 'init', 'attachments_pre_init' );
|
72 |
+
|
73 |
+
// get our assets in line
|
74 |
+
add_action( 'admin_enqueue_scripts', 'attachments_enqueues' );
|
75 |
+
add_action( 'admin_head', 'attachments_init_js' );
|
76 |
+
|
77 |
+
// get our menu in line
|
78 |
+
add_action( 'admin_menu', 'attachments_menu' );
|
79 |
+
|
80 |
+
// need our textdomain
|
81 |
+
add_action( 'plugins_loaded', 'attachments_localization' );
|
82 |
+
|
83 |
+
// make sure we've got our settings in place
|
84 |
+
add_action( 'admin_init', 'attachments_register_settings' );
|
85 |
+
|
86 |
+
// make sure we handle the save
|
87 |
+
add_action( 'save_post', 'attachments_save' );
|
88 |
+
|
89 |
+
// invoke our meta box
|
90 |
+
add_action( 'add_meta_boxes', 'attachments_meta_box' );
|
91 |
+
|
92 |
}
|
93 |
|
94 |
|
95 |
+
function attachments_localization()
|
96 |
+
{
|
97 |
+
load_plugin_textdomain( 'attachments', false, ATTACHMENTS_DIR . '/languages/' );
|
98 |
+
}
|
99 |
+
|
100 |
+
|
101 |
+
|
102 |
+
function attachments_enqueues( $hook )
|
103 |
+
{
|
104 |
+
|
105 |
+
wp_enqueue_style( 'attachments', trailingslashit( ATTACHMENTS_URL ) . 'css/attachments.css' );
|
106 |
+
|
107 |
+
if( 'edit.php' != $hook && 'post.php' != $hook && 'post-new.php' != $hook )
|
108 |
+
return;
|
109 |
+
|
110 |
+
wp_enqueue_script( 'handlebars', trailingslashit( ATTACHMENTS_URL ) . 'js/handlebars.js', null, '1.0.beta.6', false );
|
111 |
+
wp_enqueue_script( 'attachments', trailingslashit( ATTACHMENTS_URL ) . 'js/attachments.js', array( 'handlebars', 'jquery', 'thickbox' ), ATTACHMENTS_VERSION, true );
|
112 |
+
|
113 |
+
wp_enqueue_style( 'thickbox' );
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
|
118 |
|
119 |
// =============
|
120 |
// = FUNCTIONS =
|
186 |
{
|
187 |
// flag our settings
|
188 |
register_setting(
|
189 |
+
ATTACHMENTS_PREFIX . 'settings',
|
190 |
+
ATTACHMENTS_PREFIX . 'settings',
|
191 |
+
'attachments_validate_settings'
|
192 |
);
|
193 |
|
194 |
add_settings_section(
|
195 |
+
ATTACHMENTS_PREFIX . 'options',
|
196 |
+
'Post Type Settings',
|
197 |
+
'attachments_edit_options',
|
198 |
+
'attachments_options'
|
199 |
);
|
200 |
|
201 |
// post types
|
202 |
add_settings_field(
|
203 |
+
ATTACHMENTS_PREFIX . 'post_types',
|
204 |
+
'Post Types',
|
205 |
+
'attachments_edit_post_types',
|
206 |
+
'attachments_options',
|
207 |
+
ATTACHMENTS_PREFIX . 'options'
|
208 |
);
|
209 |
|
210 |
// post_parent
|
211 |
add_settings_field(
|
212 |
+
ATTACHMENTS_PREFIX . 'post_parent',
|
213 |
+
'Set Post Parent',
|
214 |
+
'attachments_edit_post_parent',
|
215 |
+
'attachments_options',
|
216 |
+
ATTACHMENTS_PREFIX . 'options'
|
217 |
);
|
218 |
}
|
219 |
|
264 |
<?php endforeach; endif; ?>
|
265 |
<?php }
|
266 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
|
268 |
/**
|
269 |
* Compares two array values with the same key "order"
|
324 |
* @author Jonathan Christopher
|
325 |
*/
|
326 |
function attachments_add()
|
327 |
+
{ ?>
|
328 |
|
329 |
<div id="attachments-inner">
|
330 |
|
352 |
|
353 |
if( is_array($existing_attachments) && !empty($existing_attachments) )
|
354 |
{
|
355 |
+
foreach ($existing_attachments as $attachment)
|
356 |
+
{
|
357 |
+
// TODO: Better handle this when examining Handlebars template
|
358 |
+
if( empty( $attachment['title'] ) )
|
359 |
+
{
|
360 |
+
$attachment['title'] = ' ';
|
361 |
+
}
|
362 |
+
if( empty( $attachment['caption'] ) )
|
363 |
+
{
|
364 |
+
$attachment['caption'] = ' ';
|
365 |
+
}
|
366 |
+
attachments_attachment_markup( $attachment['name'], $attachment['title'], $attachment['caption'], $attachment['id'], $attachment['order'] );
|
367 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
}
|
369 |
}
|
370 |
?>
|
371 |
</ul>
|
372 |
</div>
|
373 |
</div>
|
374 |
+
<script id="attachment-template" type="text/x-handlebars-template">
|
375 |
+
<?php attachments_attachment_markup(); ?>
|
376 |
+
</script>
|
377 |
<?php }
|
378 |
|
379 |
|
380 |
+
function attachments_attachment_markup( $name = null, $title = null, $caption = null, $id = null, $order = null )
|
381 |
+
{ ?>
|
382 |
+
<li class="attachments-file">
|
383 |
+
<h2>
|
384 |
+
<a href="#" class="attachment-handle">
|
385 |
+
<span class="attachment-handle-icon"><img src="<?php echo WP_PLUGIN_URL; ?>/attachments/images/handle.gif" alt="Drag" /></span>
|
386 |
+
</a>
|
387 |
+
<span class="attachment-name"><?php echo empty( $name ) ? '{{name}}' : $name; ?></span>
|
388 |
+
<span class="attachment-delete"><a href="#"><?php _e("Delete", "attachments")?></a></span>
|
389 |
+
</h2>
|
390 |
+
<div class="attachments-fields">
|
391 |
+
<div class="textfield" id="field_attachment_title_<?php echo empty( $id ) ? '{{id}}' : $id; ?>">
|
392 |
+
<label for="attachment_title_<?php echo empty( $id ) ? '{{id}}' : $id; ?>"><?php _e("Title", "attachments")?></label>
|
393 |
+
<input type="text" id="attachment_title_<?php echo empty( $id ) ? '{{id}}' : $id; ?>" name="attachment_title_<?php echo empty( $id ) ? '{{id}}' : $id; ?>" value="<?php echo empty( $title ) ? '{{title}}' : $title; ?>" size="20" />
|
394 |
+
</div>
|
395 |
+
<div class="textfield" id="field_attachment_caption_<?php echo empty( $id ) ? '{{id}}' : $id; ?>">
|
396 |
+
<label for="attachment_caption_<?php echo empty( $id ) ? '{{id}}' : $id; ?>"><?php _e("Caption", "attachments")?></label>
|
397 |
+
<input type="text" id="attachment_caption_<?php echo empty( $id ) ? '{{id}}' : $id; ?>" name="attachment_caption_<?php echo empty( $id ) ? '{{id}}' : $id; ?>" value="<?php echo empty( $caption ) ? '{{caption}}' : $caption; ?>" size="20" />
|
398 |
+
</div>
|
399 |
+
</div>
|
400 |
+
<div class="attachments-data">
|
401 |
+
<input type="hidden" name="attachment_id_<?php echo empty( $id ) ? '{{id}}' : $id; ?>" id="attachment_id_<?php echo empty( $id ) ? '{{id}}' : $id; ?>" value="<?php echo empty( $id ) ? '{{id}}' : $id; ?>" />
|
402 |
+
<input type="hidden" class="attachment_order" name="attachment_order_<?php echo empty( $id ) ? '{{id}}' : $id; ?>" id="attachment_order_<?php echo empty( $id ) ? '{{id}}' : $id; ?>" value="<?php echo empty( $order ) ? '{{order}}' : $order; ?>" />
|
403 |
+
</div>
|
404 |
+
<div class="attachment-thumbnail">
|
405 |
+
<span class="attachments-thumbnail">
|
406 |
+
<?php $thumb = wp_get_attachment_image( $id, array(80, 60), 1 ); ?>
|
407 |
+
<?php if( !empty( $thumb ) ) : ?>
|
408 |
+
<?php echo $thumb; ?>
|
409 |
+
<?php else: ?>
|
410 |
+
<img src="{{thumb}}" alt="Thumbnail" />
|
411 |
+
<?php endif; ?>
|
412 |
+
</span>
|
413 |
+
</div>
|
414 |
+
</li>
|
415 |
+
<?php }
|
416 |
+
|
417 |
+
|
418 |
+
|
419 |
/**
|
420 |
* Creates meta box on all Posts and Pages
|
421 |
*
|
540 |
$attachment_id = intval( $_POST['attachment_id_' . $i] );
|
541 |
|
542 |
$attachment_details = array(
|
543 |
+
'id' => $attachment_id,
|
544 |
+
'title' => str_replace( '"', '"', $_POST['attachment_title_' . $i] ),
|
545 |
+
'caption' => str_replace( '"', '"', $_POST['attachment_caption_' . $i] ),
|
546 |
+
'order' => intval( $_POST['attachment_order_' . $i] )
|
547 |
);
|
548 |
|
549 |
// serialize data and encode
|
557 |
if( isset( $settings['post_parent'] ) && $settings['post_parent'] )
|
558 |
{
|
559 |
// need to first check to make sure we're not overwriting a native Attach
|
560 |
+
$attach_post_ref = get_post( $attachment_id );
|
561 |
|
562 |
if( $attach_post_ref->post_parent == 0 )
|
563 |
{
|
587 |
*/
|
588 |
function attachments_get_filesize_formatted( $path = NULL )
|
589 |
{
|
|
|
590 |
$formatted = '0 bytes';
|
591 |
if( file_exists( $path ) )
|
592 |
{
|
593 |
+
$formatted = size_format( @filesize( $path ) );
|
|
|
|
|
|
|
594 |
}
|
595 |
return $formatted;
|
596 |
}
|
649 |
}
|
650 |
|
651 |
return $post_attachments;
|
652 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/attachments.js
CHANGED
@@ -1,14 +1,146 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
if(
|
7 |
-
|
8 |
-
|
9 |
-
function
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function($){
|
2 |
+
var context = false;
|
3 |
+
var thickbox_modder;
|
4 |
+
|
5 |
+
// init sortability
|
6 |
+
if($('div#attachments-list ul:data(sortable)').length==0&&$('div#attachments-list ul li').length>0){
|
7 |
+
$('div#attachments-list ul').sortable({
|
8 |
+
containment: 'parent',
|
9 |
+
stop: function(e, ui) {
|
10 |
+
$('#attachments-list ul li').each(function(i, id) {
|
11 |
+
$(this).find('input.attachment_order').val(i+1);
|
12 |
+
});
|
13 |
+
}
|
14 |
+
});
|
15 |
+
}
|
16 |
+
|
17 |
+
// delete link handler
|
18 |
+
function attachments_hook_delete_links(theparent){
|
19 |
+
attachment_parent = theparent.parent().parent().parent();
|
20 |
+
attachment_parent.slideUp(function() {
|
21 |
+
attachment_parent.remove();
|
22 |
+
$('#attachments-list ul li').each(function(i, id) {
|
23 |
+
$(this).find('input.attachment_order').val(i+1);
|
24 |
+
});
|
25 |
+
if($('div#attachments-list li').length == 0) {
|
26 |
+
$('#attachments-list').slideUp(function() {
|
27 |
+
$('#attachments-list').hide();
|
28 |
+
});
|
29 |
+
}
|
30 |
+
});
|
31 |
+
}
|
32 |
+
|
33 |
+
// Hook our delete links
|
34 |
+
if(parseFloat($.fn.jquery)>=1.7){
|
35 |
+
// 'live' is deprecated
|
36 |
+
$(document).on("click", "span.attachment-delete a", function(event){
|
37 |
+
theparent = $(this);
|
38 |
+
attachments_hook_delete_links(theparent);
|
39 |
+
return false;
|
40 |
+
});
|
41 |
+
}else{
|
42 |
+
$('span.attachment-delete a').live('click',function(event){
|
43 |
+
theparent = $(this);
|
44 |
+
attachments_hook_delete_links(theparent);
|
45 |
+
return false;
|
46 |
+
});
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
// thickbox handler
|
52 |
+
if(parseFloat($.fn.jquery)>=1.7){
|
53 |
+
// 'live' is deprecated
|
54 |
+
$(document).on("click", "a#attachments-thickbox", function(event){
|
55 |
+
event.preventDefault();
|
56 |
+
theparent = $(this);
|
57 |
+
attachments_handle_thickbox(event,theparent);
|
58 |
+
return false;
|
59 |
+
});
|
60 |
+
}else{
|
61 |
+
$('a#attachments-thickbox').live('click',function(event){
|
62 |
+
event.preventDefault();
|
63 |
+
theparent = $(this);
|
64 |
+
attachments_handle_thickbox(event,theparent);
|
65 |
+
return false;
|
66 |
+
});
|
67 |
+
}
|
68 |
+
|
69 |
+
function attachments_handle_thickbox(event,theparent){
|
70 |
+
var href = theparent.attr('href'), width = jQuery(window).width(), H = jQuery(window).height(), W = ( 720 < width ) ? 720 : width;
|
71 |
+
if ( ! href ) return;
|
72 |
+
href = href.replace(/&width=[0-9]+/g, '');
|
73 |
+
href = href.replace(/&height=[0-9]+/g, '');
|
74 |
+
theparent.attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 ) );
|
75 |
+
context = true;
|
76 |
+
thickbox_modder = setInterval( function(){
|
77 |
+
if( context ){
|
78 |
+
modify_thickbox();
|
79 |
+
}
|
80 |
+
}, 500 );
|
81 |
+
tb_show('Attach a file', event.target.href, false);
|
82 |
+
return false;
|
83 |
+
}
|
84 |
+
|
85 |
+
// handle the attachment process
|
86 |
+
function handle_attach(title,caption,id,thumb){
|
87 |
+
var source = $('#attachment-template').html();
|
88 |
+
var template = Handlebars.compile(source);
|
89 |
+
|
90 |
+
var order = $('#attachments-list > ul > li').length + 1;
|
91 |
+
|
92 |
+
$('div#attachments-list ul', top.document).append(template({title:title,caption:caption,id:id,thumb:thumb,order:order}));
|
93 |
+
|
94 |
+
$('#attachments-list > ul > li').each(function(i, id) {
|
95 |
+
$(this).find('input.attachment_order').val(i+1);
|
96 |
+
});
|
97 |
+
|
98 |
+
return false;
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
function modify_thickbox(){
|
103 |
+
|
104 |
+
the_thickbox = jQuery('#TB_iframeContent').contents();
|
105 |
+
|
106 |
+
// our new click handler for the attach button
|
107 |
+
the_thickbox.find('td.savesend input').unbind('click').click(function(e){
|
108 |
+
|
109 |
+
jQuery(this).after('<span class="attachments-attached">Attached!</span>');
|
110 |
+
|
111 |
+
// grab our meta as per the Media library
|
112 |
+
var wp_media_meta = $(this).parent().parent().parent();
|
113 |
+
var wp_media_title = wp_media_meta.find('tr.post_title td.field input').val();
|
114 |
+
var wp_media_caption = wp_media_meta.find('tr.post_excerpt td.field input').val();
|
115 |
+
var wp_media_id = wp_media_meta.find('td.imgedit-response').attr('id').replace('imgedit-response-','');
|
116 |
+
var wp_media_thumb = wp_media_meta.parent().find('img.thumbnail').attr('src');
|
117 |
+
|
118 |
+
handle_attach(wp_media_title,wp_media_caption,wp_media_id,wp_media_thumb);
|
119 |
+
|
120 |
+
the_thickbox.find('span.attachments-attached').delay(1000).fadeOut('fast');
|
121 |
+
return false;
|
122 |
+
});
|
123 |
+
// update button
|
124 |
+
if(the_thickbox.find('.media-item .savesend input[type=submit], #insertonlybutton').length){
|
125 |
+
the_thickbox.find('.media-item .savesend input[type=submit], #insertonlybutton').val('Attach');
|
126 |
+
}
|
127 |
+
if(the_thickbox.find('#tab-type_url').length){
|
128 |
+
the_thickbox.find('#tab-type_url').hide();
|
129 |
+
}
|
130 |
+
if(the_thickbox.find('tr.post_title').length){
|
131 |
+
// we need to ALWAYS get the fullsize since we're retrieving the guid
|
132 |
+
// if the user inserts an image somewhere else and chooses another size, everything breaks
|
133 |
+
the_thickbox.find('tr.image-size input[value="full"]').prop('checked', true);
|
134 |
+
the_thickbox.find('tr.post_title,tr.image_alt,tr.post_excerpt,tr.image-size,tr.post_content,tr.url,tr.align,tr.submit>td>a.del-link').hide();
|
135 |
+
}
|
136 |
+
|
137 |
+
// was the thickbox closed?
|
138 |
+
if(the_thickbox.length==0 && context){
|
139 |
+
clearInterval(thickbox_modder);
|
140 |
+
context = false;
|
141 |
+
}
|
142 |
+
}
|
143 |
+
|
144 |
+
});
|
145 |
+
|
146 |
+
|
js/handlebars.js
ADDED
@@ -0,0 +1,1554 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
if(jQuery.isPlainObject(Handlebars)) {
|
2 |
+
return;
|
3 |
+
}
|
4 |
+
|
5 |
+
// lib/handlebars/base.js
|
6 |
+
var Handlebars = {};
|
7 |
+
|
8 |
+
Handlebars.VERSION = "1.0.beta.6";
|
9 |
+
|
10 |
+
Handlebars.helpers = {};
|
11 |
+
Handlebars.partials = {};
|
12 |
+
|
13 |
+
Handlebars.registerHelper = function(name, fn, inverse) {
|
14 |
+
if(inverse) { fn.not = inverse; }
|
15 |
+
this.helpers[name] = fn;
|
16 |
+
};
|
17 |
+
|
18 |
+
Handlebars.registerPartial = function(name, str) {
|
19 |
+
this.partials[name] = str;
|
20 |
+
};
|
21 |
+
|
22 |
+
Handlebars.registerHelper('helperMissing', function(arg) {
|
23 |
+
if(arguments.length === 2) {
|
24 |
+
return undefined;
|
25 |
+
} else {
|
26 |
+
throw new Error("Could not find property '" + arg + "'");
|
27 |
+
}
|
28 |
+
});
|
29 |
+
|
30 |
+
var toString = Object.prototype.toString, functionType = "[object Function]";
|
31 |
+
|
32 |
+
Handlebars.registerHelper('blockHelperMissing', function(context, options) {
|
33 |
+
var inverse = options.inverse || function() {}, fn = options.fn;
|
34 |
+
|
35 |
+
|
36 |
+
var ret = "";
|
37 |
+
var type = toString.call(context);
|
38 |
+
|
39 |
+
if(type === functionType) { context = context.call(this); }
|
40 |
+
|
41 |
+
if(context === true) {
|
42 |
+
return fn(this);
|
43 |
+
} else if(context === false || context == null) {
|
44 |
+
return inverse(this);
|
45 |
+
} else if(type === "[object Array]") {
|
46 |
+
if(context.length > 0) {
|
47 |
+
for(var i=0, j=context.length; i<j; i++) {
|
48 |
+
ret = ret + fn(context[i]);
|
49 |
+
}
|
50 |
+
} else {
|
51 |
+
ret = inverse(this);
|
52 |
+
}
|
53 |
+
return ret;
|
54 |
+
} else {
|
55 |
+
return fn(context);
|
56 |
+
}
|
57 |
+
});
|
58 |
+
|
59 |
+
Handlebars.registerHelper('each', function(context, options) {
|
60 |
+
var fn = options.fn, inverse = options.inverse;
|
61 |
+
var ret = "";
|
62 |
+
|
63 |
+
if(context && context.length > 0) {
|
64 |
+
for(var i=0, j=context.length; i<j; i++) {
|
65 |
+
ret = ret + fn(context[i]);
|
66 |
+
}
|
67 |
+
} else {
|
68 |
+
ret = inverse(this);
|
69 |
+
}
|
70 |
+
return ret;
|
71 |
+
});
|
72 |
+
|
73 |
+
Handlebars.registerHelper('if', function(context, options) {
|
74 |
+
var type = toString.call(context);
|
75 |
+
if(type === functionType) { context = context.call(this); }
|
76 |
+
|
77 |
+
if(!context || Handlebars.Utils.isEmpty(context)) {
|
78 |
+
return options.inverse(this);
|
79 |
+
} else {
|
80 |
+
return options.fn(this);
|
81 |
+
}
|
82 |
+
});
|
83 |
+
|
84 |
+
Handlebars.registerHelper('unless', function(context, options) {
|
85 |
+
var fn = options.fn, inverse = options.inverse;
|
86 |
+
options.fn = inverse;
|
87 |
+
options.inverse = fn;
|
88 |
+
|
89 |
+
return Handlebars.helpers['if'].call(this, context, options);
|
90 |
+
});
|
91 |
+
|
92 |
+
Handlebars.registerHelper('with', function(context, options) {
|
93 |
+
return options.fn(context);
|
94 |
+
});
|
95 |
+
|
96 |
+
Handlebars.registerHelper('log', function(context) {
|
97 |
+
Handlebars.log(context);
|
98 |
+
});
|
99 |
+
;
|
100 |
+
// lib/handlebars/compiler/parser.js
|
101 |
+
/* Jison generated parser */
|
102 |
+
var handlebars = (function(){
|
103 |
+
|
104 |
+
var parser = {trace: function trace() { },
|
105 |
+
yy: {},
|
106 |
+
symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"INTEGER":29,"BOOLEAN":30,"hashSegments":31,"hashSegment":32,"ID":33,"EQUALS":34,"pathSegments":35,"SEP":36,"$accept":0,"$end":1},
|
107 |
+
terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",29:"INTEGER",30:"BOOLEAN",33:"ID",34:"EQUALS",36:"SEP"},
|
108 |
+
productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[26,1],[31,2],[31,1],[32,3],[32,3],[32,3],[32,3],[21,1],[35,3],[35,1]],
|
109 |
+
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
110 |
+
|
111 |
+
var $0 = $$.length - 1;
|
112 |
+
switch (yystate) {
|
113 |
+
case 1: return $$[$0-1]
|
114 |
+
break;
|
115 |
+
case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0])
|
116 |
+
break;
|
117 |
+
case 3: this.$ = new yy.ProgramNode($$[$0])
|
118 |
+
break;
|
119 |
+
case 4: this.$ = new yy.ProgramNode([])
|
120 |
+
break;
|
121 |
+
case 5: this.$ = [$$[$0]]
|
122 |
+
break;
|
123 |
+
case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
|
124 |
+
break;
|
125 |
+
case 7: this.$ = new yy.InverseNode($$[$0-2], $$[$0-1], $$[$0])
|
126 |
+
break;
|
127 |
+
case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0])
|
128 |
+
break;
|
129 |
+
case 9: this.$ = $$[$0]
|
130 |
+
break;
|
131 |
+
case 10: this.$ = $$[$0]
|
132 |
+
break;
|
133 |
+
case 11: this.$ = new yy.ContentNode($$[$0])
|
134 |
+
break;
|
135 |
+
case 12: this.$ = new yy.CommentNode($$[$0])
|
136 |
+
break;
|
137 |
+
case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
|
138 |
+
break;
|
139 |
+
case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
|
140 |
+
break;
|
141 |
+
case 15: this.$ = $$[$0-1]
|
142 |
+
break;
|
143 |
+
case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
|
144 |
+
break;
|
145 |
+
case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true)
|
146 |
+
break;
|
147 |
+
case 18: this.$ = new yy.PartialNode($$[$0-1])
|
148 |
+
break;
|
149 |
+
case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1])
|
150 |
+
break;
|
151 |
+
case 20:
|
152 |
+
break;
|
153 |
+
case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]
|
154 |
+
break;
|
155 |
+
case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null]
|
156 |
+
break;
|
157 |
+
case 23: this.$ = [[$$[$0-1]], $$[$0]]
|
158 |
+
break;
|
159 |
+
case 24: this.$ = [[$$[$0]], null]
|
160 |
+
break;
|
161 |
+
case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
162 |
+
break;
|
163 |
+
case 26: this.$ = [$$[$0]]
|
164 |
+
break;
|
165 |
+
case 27: this.$ = $$[$0]
|
166 |
+
break;
|
167 |
+
case 28: this.$ = new yy.StringNode($$[$0])
|
168 |
+
break;
|
169 |
+
case 29: this.$ = new yy.IntegerNode($$[$0])
|
170 |
+
break;
|
171 |
+
case 30: this.$ = new yy.BooleanNode($$[$0])
|
172 |
+
break;
|
173 |
+
case 31: this.$ = new yy.HashNode($$[$0])
|
174 |
+
break;
|
175 |
+
case 32: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
|
176 |
+
break;
|
177 |
+
case 33: this.$ = [$$[$0]]
|
178 |
+
break;
|
179 |
+
case 34: this.$ = [$$[$0-2], $$[$0]]
|
180 |
+
break;
|
181 |
+
case 35: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]
|
182 |
+
break;
|
183 |
+
case 36: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]
|
184 |
+
break;
|
185 |
+
case 37: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]
|
186 |
+
break;
|
187 |
+
case 38: this.$ = new yy.IdNode($$[$0])
|
188 |
+
break;
|
189 |
+
case 39: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
|
190 |
+
break;
|
191 |
+
case 40: this.$ = [$$[$0]]
|
192 |
+
break;
|
193 |
+
}
|
194 |
+
},
|
195 |
+
table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,33:[1,25],35:24},{17:26,21:23,33:[1,25],35:24},{17:27,21:23,33:[1,25],35:24},{17:28,21:23,33:[1,25],35:24},{21:29,33:[1,25],35:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,33:[1,25],35:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,38],28:[2,38],29:[2,38],30:[2,38],33:[2,38],36:[1,46]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],36:[2,40]},{18:[1,47]},{18:[1,48]},{18:[1,49]},{18:[1,50],21:51,33:[1,25],35:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:52,33:[1,25],35:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:53,27:54,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,23]},{18:[2,26],28:[2,26],29:[2,26],30:[2,26],33:[2,26]},{18:[2,31],32:55,33:[1,56]},{18:[2,27],28:[2,27],29:[2,27],30:[2,27],33:[2,27]},{18:[2,28],28:[2,28],29:[2,28],30:[2,28],33:[2,28]},{18:[2,29],28:[2,29],29:[2,29],30:[2,29],33:[2,29]},{18:[2,30],28:[2,30],29:[2,30],30:[2,30],33:[2,30]},{18:[2,33],33:[2,33]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],34:[1,57],36:[2,40]},{33:[1,58]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,59]},{18:[1,60]},{18:[2,21]},{18:[2,25],28:[2,25],29:[2,25],30:[2,25],33:[2,25]},{18:[2,32],33:[2,32]},{34:[1,57]},{21:61,28:[1,62],29:[1,63],30:[1,64],33:[1,25],35:24},{18:[2,39],28:[2,39],29:[2,39],30:[2,39],33:[2,39],36:[2,39]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,34],33:[2,34]},{18:[2,35],33:[2,35]},{18:[2,36],33:[2,36]},{18:[2,37],33:[2,37]}],
|
196 |
+
defaultActions: {16:[2,1],37:[2,23],53:[2,21]},
|
197 |
+
parseError: function parseError(str, hash) {
|
198 |
+
throw new Error(str);
|
199 |
+
},
|
200 |
+
parse: function parse(input) {
|
201 |
+
var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
|
202 |
+
this.lexer.setInput(input);
|
203 |
+
this.lexer.yy = this.yy;
|
204 |
+
this.yy.lexer = this.lexer;
|
205 |
+
if (typeof this.lexer.yylloc == "undefined")
|
206 |
+
this.lexer.yylloc = {};
|
207 |
+
var yyloc = this.lexer.yylloc;
|
208 |
+
lstack.push(yyloc);
|
209 |
+
if (typeof this.yy.parseError === "function")
|
210 |
+
this.parseError = this.yy.parseError;
|
211 |
+
function popStack(n) {
|
212 |
+
stack.length = stack.length - 2 * n;
|
213 |
+
vstack.length = vstack.length - n;
|
214 |
+
lstack.length = lstack.length - n;
|
215 |
+
}
|
216 |
+
function lex() {
|
217 |
+
var token;
|
218 |
+
token = self.lexer.lex() || 1;
|
219 |
+
if (typeof token !== "number") {
|
220 |
+
token = self.symbols_[token] || token;
|
221 |
+
}
|
222 |
+
return token;
|
223 |
+
}
|
224 |
+
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
|
225 |
+
while (true) {
|
226 |
+
state = stack[stack.length - 1];
|
227 |
+
if (this.defaultActions[state]) {
|
228 |
+
action = this.defaultActions[state];
|
229 |
+
} else {
|
230 |
+
if (symbol == null)
|
231 |
+
symbol = lex();
|
232 |
+
action = table[state] && table[state][symbol];
|
233 |
+
}
|
234 |
+
if (typeof action === "undefined" || !action.length || !action[0]) {
|
235 |
+
if (!recovering) {
|
236 |
+
expected = [];
|
237 |
+
for (p in table[state])
|
238 |
+
if (this.terminals_[p] && p > 2) {
|
239 |
+
expected.push("'" + this.terminals_[p] + "'");
|
240 |
+
}
|
241 |
+
var errStr = "";
|
242 |
+
if (this.lexer.showPosition) {
|
243 |
+
errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + this.terminals_[symbol] + "'";
|
244 |
+
} else {
|
245 |
+
errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
|
246 |
+
}
|
247 |
+
this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
|
248 |
+
}
|
249 |
+
}
|
250 |
+
if (action[0] instanceof Array && action.length > 1) {
|
251 |
+
throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
|
252 |
+
}
|
253 |
+
switch (action[0]) {
|
254 |
+
case 1:
|
255 |
+
stack.push(symbol);
|
256 |
+
vstack.push(this.lexer.yytext);
|
257 |
+
lstack.push(this.lexer.yylloc);
|
258 |
+
stack.push(action[1]);
|
259 |
+
symbol = null;
|
260 |
+
if (!preErrorSymbol) {
|
261 |
+
yyleng = this.lexer.yyleng;
|
262 |
+
yytext = this.lexer.yytext;
|
263 |
+
yylineno = this.lexer.yylineno;
|
264 |
+
yyloc = this.lexer.yylloc;
|
265 |
+
if (recovering > 0)
|
266 |
+
recovering--;
|
267 |
+
} else {
|
268 |
+
symbol = preErrorSymbol;
|
269 |
+
preErrorSymbol = null;
|
270 |
+
}
|
271 |
+
break;
|
272 |
+
case 2:
|
273 |
+
len = this.productions_[action[1]][1];
|
274 |
+
yyval.$ = vstack[vstack.length - len];
|
275 |
+
yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
|
276 |
+
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
|
277 |
+
if (typeof r !== "undefined") {
|
278 |
+
return r;
|
279 |
+
}
|
280 |
+
if (len) {
|
281 |
+
stack = stack.slice(0, -1 * len * 2);
|
282 |
+
vstack = vstack.slice(0, -1 * len);
|
283 |
+
lstack = lstack.slice(0, -1 * len);
|
284 |
+
}
|
285 |
+
stack.push(this.productions_[action[1]][0]);
|
286 |
+
vstack.push(yyval.$);
|
287 |
+
lstack.push(yyval._$);
|
288 |
+
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
|
289 |
+
stack.push(newState);
|
290 |
+
break;
|
291 |
+
case 3:
|
292 |
+
return true;
|
293 |
+
}
|
294 |
+
}
|
295 |
+
return true;
|
296 |
+
}
|
297 |
+
};/* Jison generated lexer */
|
298 |
+
var lexer = (function(){
|
299 |
+
|
300 |
+
var lexer = ({EOF:1,
|
301 |
+
parseError:function parseError(str, hash) {
|
302 |
+
if (this.yy.parseError) {
|
303 |
+
this.yy.parseError(str, hash);
|
304 |
+
} else {
|
305 |
+
throw new Error(str);
|
306 |
+
}
|
307 |
+
},
|
308 |
+
setInput:function (input) {
|
309 |
+
this._input = input;
|
310 |
+
this._more = this._less = this.done = false;
|
311 |
+
this.yylineno = this.yyleng = 0;
|
312 |
+
this.yytext = this.matched = this.match = '';
|
313 |
+
this.conditionStack = ['INITIAL'];
|
314 |
+
this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
|
315 |
+
return this;
|
316 |
+
},
|
317 |
+
input:function () {
|
318 |
+
var ch = this._input[0];
|
319 |
+
this.yytext+=ch;
|
320 |
+
this.yyleng++;
|
321 |
+
this.match+=ch;
|
322 |
+
this.matched+=ch;
|
323 |
+
var lines = ch.match(/\n/);
|
324 |
+
if (lines) this.yylineno++;
|
325 |
+
this._input = this._input.slice(1);
|
326 |
+
return ch;
|
327 |
+
},
|
328 |
+
unput:function (ch) {
|
329 |
+
this._input = ch + this._input;
|
330 |
+
return this;
|
331 |
+
},
|
332 |
+
more:function () {
|
333 |
+
this._more = true;
|
334 |
+
return this;
|
335 |
+
},
|
336 |
+
pastInput:function () {
|
337 |
+
var past = this.matched.substr(0, this.matched.length - this.match.length);
|
338 |
+
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
|
339 |
+
},
|
340 |
+
upcomingInput:function () {
|
341 |
+
var next = this.match;
|
342 |
+
if (next.length < 20) {
|
343 |
+
next += this._input.substr(0, 20-next.length);
|
344 |
+
}
|
345 |
+
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
|
346 |
+
},
|
347 |
+
showPosition:function () {
|
348 |
+
var pre = this.pastInput();
|
349 |
+
var c = new Array(pre.length + 1).join("-");
|
350 |
+
return pre + this.upcomingInput() + "\n" + c+"^";
|
351 |
+
},
|
352 |
+
next:function () {
|
353 |
+
if (this.done) {
|
354 |
+
return this.EOF;
|
355 |
+
}
|
356 |
+
if (!this._input) this.done = true;
|
357 |
+
|
358 |
+
var token,
|
359 |
+
match,
|
360 |
+
col,
|
361 |
+
lines;
|
362 |
+
if (!this._more) {
|
363 |
+
this.yytext = '';
|
364 |
+
this.match = '';
|
365 |
+
}
|
366 |
+
var rules = this._currentRules();
|
367 |
+
for (var i=0;i < rules.length; i++) {
|
368 |
+
match = this._input.match(this.rules[rules[i]]);
|
369 |
+
if (match) {
|
370 |
+
lines = match[0].match(/\n.*/g);
|
371 |
+
if (lines) this.yylineno += lines.length;
|
372 |
+
this.yylloc = {first_line: this.yylloc.last_line,
|
373 |
+
last_line: this.yylineno+1,
|
374 |
+
first_column: this.yylloc.last_column,
|
375 |
+
last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
|
376 |
+
this.yytext += match[0];
|
377 |
+
this.match += match[0];
|
378 |
+
this.matches = match;
|
379 |
+
this.yyleng = this.yytext.length;
|
380 |
+
this._more = false;
|
381 |
+
this._input = this._input.slice(match[0].length);
|
382 |
+
this.matched += match[0];
|
383 |
+
token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
|
384 |
+
if (token) return token;
|
385 |
+
else return;
|
386 |
+
}
|
387 |
+
}
|
388 |
+
if (this._input === "") {
|
389 |
+
return this.EOF;
|
390 |
+
} else {
|
391 |
+
this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
|
392 |
+
{text: "", token: null, line: this.yylineno});
|
393 |
+
}
|
394 |
+
},
|
395 |
+
lex:function lex() {
|
396 |
+
var r = this.next();
|
397 |
+
if (typeof r !== 'undefined') {
|
398 |
+
return r;
|
399 |
+
} else {
|
400 |
+
return this.lex();
|
401 |
+
}
|
402 |
+
},
|
403 |
+
begin:function begin(condition) {
|
404 |
+
this.conditionStack.push(condition);
|
405 |
+
},
|
406 |
+
popState:function popState() {
|
407 |
+
return this.conditionStack.pop();
|
408 |
+
},
|
409 |
+
_currentRules:function _currentRules() {
|
410 |
+
return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
|
411 |
+
},
|
412 |
+
topState:function () {
|
413 |
+
return this.conditionStack[this.conditionStack.length-2];
|
414 |
+
},
|
415 |
+
pushState:function begin(condition) {
|
416 |
+
this.begin(condition);
|
417 |
+
}});
|
418 |
+
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
419 |
+
|
420 |
+
var YYSTATE=YY_START
|
421 |
+
switch($avoiding_name_collisions) {
|
422 |
+
case 0:
|
423 |
+
if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
|
424 |
+
if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
|
425 |
+
if(yy_.yytext) return 14;
|
426 |
+
|
427 |
+
break;
|
428 |
+
case 1: return 14;
|
429 |
+
break;
|
430 |
+
case 2: this.popState(); return 14;
|
431 |
+
break;
|
432 |
+
case 3: return 24;
|
433 |
+
break;
|
434 |
+
case 4: return 16;
|
435 |
+
break;
|
436 |
+
case 5: return 20;
|
437 |
+
break;
|
438 |
+
case 6: return 19;
|
439 |
+
break;
|
440 |
+
case 7: return 19;
|
441 |
+
break;
|
442 |
+
case 8: return 23;
|
443 |
+
break;
|
444 |
+
case 9: return 23;
|
445 |
+
break;
|
446 |
+
case 10: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
|
447 |
+
break;
|
448 |
+
case 11: return 22;
|
449 |
+
break;
|
450 |
+
case 12: return 34;
|
451 |
+
break;
|
452 |
+
case 13: return 33;
|
453 |
+
break;
|
454 |
+
case 14: return 33;
|
455 |
+
break;
|
456 |
+
case 15: return 36;
|
457 |
+
break;
|
458 |
+
case 16: /*ignore whitespace*/
|
459 |
+
break;
|
460 |
+
case 17: this.popState(); return 18;
|
461 |
+
break;
|
462 |
+
case 18: this.popState(); return 18;
|
463 |
+
break;
|
464 |
+
case 19: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28;
|
465 |
+
break;
|
466 |
+
case 20: return 30;
|
467 |
+
break;
|
468 |
+
case 21: return 30;
|
469 |
+
break;
|
470 |
+
case 22: return 29;
|
471 |
+
break;
|
472 |
+
case 23: return 33;
|
473 |
+
break;
|
474 |
+
case 24: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 33;
|
475 |
+
break;
|
476 |
+
case 25: return 'INVALID';
|
477 |
+
break;
|
478 |
+
case 26: return 5;
|
479 |
+
break;
|
480 |
+
}
|
481 |
+
};
|
482 |
+
lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^[^\x00]{2,}?(?=(\{\{))/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[\/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s\/.])/,/^\[[^\]]*\]/,/^./,/^$/];
|
483 |
+
lexer.conditions = {"mu":{"rules":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"INITIAL":{"rules":[0,1,26],"inclusive":true}};return lexer;})()
|
484 |
+
parser.lexer = lexer;
|
485 |
+
return parser;
|
486 |
+
})();
|
487 |
+
if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
488 |
+
exports.parser = handlebars;
|
489 |
+
exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
|
490 |
+
exports.main = function commonjsMain(args) {
|
491 |
+
if (!args[1])
|
492 |
+
throw new Error('Usage: '+args[0]+' FILE');
|
493 |
+
if (typeof process !== 'undefined') {
|
494 |
+
var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
|
495 |
+
} else {
|
496 |
+
var cwd = require("file").path(require("file").cwd());
|
497 |
+
var source = cwd.join(args[1]).read({charset: "utf-8"});
|
498 |
+
}
|
499 |
+
return exports.parser.parse(source);
|
500 |
+
}
|
501 |
+
if (typeof module !== 'undefined' && require.main === module) {
|
502 |
+
exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
|
503 |
+
}
|
504 |
+
};
|
505 |
+
;
|
506 |
+
// lib/handlebars/compiler/base.js
|
507 |
+
Handlebars.Parser = handlebars;
|
508 |
+
|
509 |
+
Handlebars.parse = function(string) {
|
510 |
+
Handlebars.Parser.yy = Handlebars.AST;
|
511 |
+
return Handlebars.Parser.parse(string);
|
512 |
+
};
|
513 |
+
|
514 |
+
Handlebars.print = function(ast) {
|
515 |
+
return new Handlebars.PrintVisitor().accept(ast);
|
516 |
+
};
|
517 |
+
|
518 |
+
Handlebars.logger = {
|
519 |
+
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
|
520 |
+
|
521 |
+
// override in the host environment
|
522 |
+
log: function(level, str) {}
|
523 |
+
};
|
524 |
+
|
525 |
+
Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
|
526 |
+
;
|
527 |
+
// lib/handlebars/compiler/ast.js
|
528 |
+
(function() {
|
529 |
+
|
530 |
+
Handlebars.AST = {};
|
531 |
+
|
532 |
+
Handlebars.AST.ProgramNode = function(statements, inverse) {
|
533 |
+
this.type = "program";
|
534 |
+
this.statements = statements;
|
535 |
+
if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
|
536 |
+
};
|
537 |
+
|
538 |
+
Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
|
539 |
+
this.type = "mustache";
|
540 |
+
this.id = params[0];
|
541 |
+
this.params = params.slice(1);
|
542 |
+
this.hash = hash;
|
543 |
+
this.escaped = !unescaped;
|
544 |
+
};
|
545 |
+
|
546 |
+
Handlebars.AST.PartialNode = function(id, context) {
|
547 |
+
this.type = "partial";
|
548 |
+
|
549 |
+
// TODO: disallow complex IDs
|
550 |
+
|
551 |
+
this.id = id;
|
552 |
+
this.context = context;
|
553 |
+
};
|
554 |
+
|
555 |
+
var verifyMatch = function(open, close) {
|
556 |
+
if(open.original !== close.original) {
|
557 |
+
throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
|
558 |
+
}
|
559 |
+
};
|
560 |
+
|
561 |
+
Handlebars.AST.BlockNode = function(mustache, program, close) {
|
562 |
+
verifyMatch(mustache.id, close);
|
563 |
+
this.type = "block";
|
564 |
+
this.mustache = mustache;
|
565 |
+
this.program = program;
|
566 |
+
};
|
567 |
+
|
568 |
+
Handlebars.AST.InverseNode = function(mustache, program, close) {
|
569 |
+
verifyMatch(mustache.id, close);
|
570 |
+
this.type = "inverse";
|
571 |
+
this.mustache = mustache;
|
572 |
+
this.program = program;
|
573 |
+
};
|
574 |
+
|
575 |
+
Handlebars.AST.ContentNode = function(string) {
|
576 |
+
this.type = "content";
|
577 |
+
this.string = string;
|
578 |
+
};
|
579 |
+
|
580 |
+
Handlebars.AST.HashNode = function(pairs) {
|
581 |
+
this.type = "hash";
|
582 |
+
this.pairs = pairs;
|
583 |
+
};
|
584 |
+
|
585 |
+
Handlebars.AST.IdNode = function(parts) {
|
586 |
+
this.type = "ID";
|
587 |
+
this.original = parts.join(".");
|
588 |
+
|
589 |
+
var dig = [], depth = 0;
|
590 |
+
|
591 |
+
for(var i=0,l=parts.length; i<l; i++) {
|
592 |
+
var part = parts[i];
|
593 |
+
|
594 |
+
if(part === "..") { depth++; }
|
595 |
+
else if(part === "." || part === "this") { this.isScoped = true; }
|
596 |
+
else { dig.push(part); }
|
597 |
+
}
|
598 |
+
|
599 |
+
this.parts = dig;
|
600 |
+
this.string = dig.join('.');
|
601 |
+
this.depth = depth;
|
602 |
+
this.isSimple = (dig.length === 1) && (depth === 0);
|
603 |
+
};
|
604 |
+
|
605 |
+
Handlebars.AST.StringNode = function(string) {
|
606 |
+
this.type = "STRING";
|
607 |
+
this.string = string;
|
608 |
+
};
|
609 |
+
|
610 |
+
Handlebars.AST.IntegerNode = function(integer) {
|
611 |
+
this.type = "INTEGER";
|
612 |
+
this.integer = integer;
|
613 |
+
};
|
614 |
+
|
615 |
+
Handlebars.AST.BooleanNode = function(bool) {
|
616 |
+
this.type = "BOOLEAN";
|
617 |
+
this.bool = bool;
|
618 |
+
};
|
619 |
+
|
620 |
+
Handlebars.AST.CommentNode = function(comment) {
|
621 |
+
this.type = "comment";
|
622 |
+
this.comment = comment;
|
623 |
+
};
|
624 |
+
|
625 |
+
})();;
|
626 |
+
// lib/handlebars/utils.js
|
627 |
+
Handlebars.Exception = function(message) {
|
628 |
+
var tmp = Error.prototype.constructor.apply(this, arguments);
|
629 |
+
|
630 |
+
for (var p in tmp) {
|
631 |
+
if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
|
632 |
+
}
|
633 |
+
|
634 |
+
this.message = tmp.message;
|
635 |
+
};
|
636 |
+
Handlebars.Exception.prototype = new Error;
|
637 |
+
|
638 |
+
// Build out our basic SafeString type
|
639 |
+
Handlebars.SafeString = function(string) {
|
640 |
+
this.string = string;
|
641 |
+
};
|
642 |
+
Handlebars.SafeString.prototype.toString = function() {
|
643 |
+
return this.string.toString();
|
644 |
+
};
|
645 |
+
|
646 |
+
(function() {
|
647 |
+
var escape = {
|
648 |
+
"<": "<",
|
649 |
+
">": ">",
|
650 |
+
'"': """,
|
651 |
+
"'": "'",
|
652 |
+
"`": "`"
|
653 |
+
};
|
654 |
+
|
655 |
+
var badChars = /&(?!\w+;)|[<>"'`]/g;
|
656 |
+
var possible = /[&<>"'`]/;
|
657 |
+
|
658 |
+
var escapeChar = function(chr) {
|
659 |
+
return escape[chr] || "&";
|
660 |
+
};
|
661 |
+
|
662 |
+
Handlebars.Utils = {
|
663 |
+
escapeExpression: function(string) {
|
664 |
+
// don't escape SafeStrings, since they're already safe
|
665 |
+
if (string instanceof Handlebars.SafeString) {
|
666 |
+
return string.toString();
|
667 |
+
} else if (string == null || string === false) {
|
668 |
+
return "";
|
669 |
+
}
|
670 |
+
|
671 |
+
if(!possible.test(string)) { return string; }
|
672 |
+
return string.replace(badChars, escapeChar);
|
673 |
+
},
|
674 |
+
|
675 |
+
isEmpty: function(value) {
|
676 |
+
if (typeof value === "undefined") {
|
677 |
+
return true;
|
678 |
+
} else if (value === null) {
|
679 |
+
return true;
|
680 |
+
} else if (value === false) {
|
681 |
+
return true;
|
682 |
+
} else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
|
683 |
+
return true;
|
684 |
+
} else {
|
685 |
+
return false;
|
686 |
+
}
|
687 |
+
}
|
688 |
+
};
|
689 |
+
})();;
|
690 |
+
// lib/handlebars/compiler/compiler.js
|
691 |
+
Handlebars.Compiler = function() {};
|
692 |
+
Handlebars.JavaScriptCompiler = function() {};
|
693 |
+
|
694 |
+
(function(Compiler, JavaScriptCompiler) {
|
695 |
+
Compiler.OPCODE_MAP = {
|
696 |
+
appendContent: 1,
|
697 |
+
getContext: 2,
|
698 |
+
lookupWithHelpers: 3,
|
699 |
+
lookup: 4,
|
700 |
+
append: 5,
|
701 |
+
invokeMustache: 6,
|
702 |
+
appendEscaped: 7,
|
703 |
+
pushString: 8,
|
704 |
+
truthyOrFallback: 9,
|
705 |
+
functionOrFallback: 10,
|
706 |
+
invokeProgram: 11,
|
707 |
+
invokePartial: 12,
|
708 |
+
push: 13,
|
709 |
+
assignToHash: 15,
|
710 |
+
pushStringParam: 16
|
711 |
+
};
|
712 |
+
|
713 |
+
Compiler.MULTI_PARAM_OPCODES = {
|
714 |
+
appendContent: 1,
|
715 |
+
getContext: 1,
|
716 |
+
lookupWithHelpers: 2,
|
717 |
+
lookup: 1,
|
718 |
+
invokeMustache: 3,
|
719 |
+
pushString: 1,
|
720 |
+
truthyOrFallback: 1,
|
721 |
+
functionOrFallback: 1,
|
722 |
+
invokeProgram: 3,
|
723 |
+
invokePartial: 1,
|
724 |
+
push: 1,
|
725 |
+
assignToHash: 1,
|
726 |
+
pushStringParam: 1
|
727 |
+
};
|
728 |
+
|
729 |
+
Compiler.DISASSEMBLE_MAP = {};
|
730 |
+
|
731 |
+
for(var prop in Compiler.OPCODE_MAP) {
|
732 |
+
var value = Compiler.OPCODE_MAP[prop];
|
733 |
+
Compiler.DISASSEMBLE_MAP[value] = prop;
|
734 |
+
}
|
735 |
+
|
736 |
+
Compiler.multiParamSize = function(code) {
|
737 |
+
return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
|
738 |
+
};
|
739 |
+
|
740 |
+
Compiler.prototype = {
|
741 |
+
compiler: Compiler,
|
742 |
+
|
743 |
+
disassemble: function() {
|
744 |
+
var opcodes = this.opcodes, opcode, nextCode;
|
745 |
+
var out = [], str, name, value;
|
746 |
+
|
747 |
+
for(var i=0, l=opcodes.length; i<l; i++) {
|
748 |
+
opcode = opcodes[i];
|
749 |
+
|
750 |
+
if(opcode === 'DECLARE') {
|
751 |
+
name = opcodes[++i];
|
752 |
+
value = opcodes[++i];
|
753 |
+
out.push("DECLARE " + name + " = " + value);
|
754 |
+
} else {
|
755 |
+
str = Compiler.DISASSEMBLE_MAP[opcode];
|
756 |
+
|
757 |
+
var extraParams = Compiler.multiParamSize(opcode);
|
758 |
+
var codes = [];
|
759 |
+
|
760 |
+
for(var j=0; j<extraParams; j++) {
|
761 |
+
nextCode = opcodes[++i];
|
762 |
+
|
763 |
+
if(typeof nextCode === "string") {
|
764 |
+
nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
|
765 |
+
}
|
766 |
+
|
767 |
+
codes.push(nextCode);
|
768 |
+
}
|
769 |
+
|
770 |
+
str = str + " " + codes.join(" ");
|
771 |
+
|
772 |
+
out.push(str);
|
773 |
+
}
|
774 |
+
}
|
775 |
+
|
776 |
+
return out.join("\n");
|
777 |
+
},
|
778 |
+
|
779 |
+
guid: 0,
|
780 |
+
|
781 |
+
compile: function(program, options) {
|
782 |
+
this.children = [];
|
783 |
+
this.depths = {list: []};
|
784 |
+
this.options = options;
|
785 |
+
|
786 |
+
// These changes will propagate to the other compiler components
|
787 |
+
var knownHelpers = this.options.knownHelpers;
|
788 |
+
this.options.knownHelpers = {
|
789 |
+
'helperMissing': true,
|
790 |
+
'blockHelperMissing': true,
|
791 |
+
'each': true,
|
792 |
+
'if': true,
|
793 |
+
'unless': true,
|
794 |
+
'with': true,
|
795 |
+
'log': true
|
796 |
+
};
|
797 |
+
if (knownHelpers) {
|
798 |
+
for (var name in knownHelpers) {
|
799 |
+
this.options.knownHelpers[name] = knownHelpers[name];
|
800 |
+
}
|
801 |
+
}
|
802 |
+
|
803 |
+
return this.program(program);
|
804 |
+
},
|
805 |
+
|
806 |
+
accept: function(node) {
|
807 |
+
return this[node.type](node);
|
808 |
+
},
|
809 |
+
|
810 |
+
program: function(program) {
|
811 |
+
var statements = program.statements, statement;
|
812 |
+
this.opcodes = [];
|
813 |
+
|
814 |
+
for(var i=0, l=statements.length; i<l; i++) {
|
815 |
+
statement = statements[i];
|
816 |
+
this[statement.type](statement);
|
817 |
+
}
|
818 |
+
this.isSimple = l === 1;
|
819 |
+
|
820 |
+
this.depths.list = this.depths.list.sort(function(a, b) {
|
821 |
+
return a - b;
|
822 |
+
});
|
823 |
+
|
824 |
+
return this;
|
825 |
+
},
|
826 |
+
|
827 |
+
compileProgram: function(program) {
|
828 |
+
var result = new this.compiler().compile(program, this.options);
|
829 |
+
var guid = this.guid++;
|
830 |
+
|
831 |
+
this.usePartial = this.usePartial || result.usePartial;
|
832 |
+
|
833 |
+
this.children[guid] = result;
|
834 |
+
|
835 |
+
for(var i=0, l=result.depths.list.length; i<l; i++) {
|
836 |
+
depth = result.depths.list[i];
|
837 |
+
|
838 |
+
if(depth < 2) { continue; }
|
839 |
+
else { this.addDepth(depth - 1); }
|
840 |
+
}
|
841 |
+
|
842 |
+
return guid;
|
843 |
+
},
|
844 |
+
|
845 |
+
block: function(block) {
|
846 |
+
var mustache = block.mustache;
|
847 |
+
var depth, child, inverse, inverseGuid;
|
848 |
+
|
849 |
+
var params = this.setupStackForMustache(mustache);
|
850 |
+
|
851 |
+
var programGuid = this.compileProgram(block.program);
|
852 |
+
|
853 |
+
if(block.program.inverse) {
|
854 |
+
inverseGuid = this.compileProgram(block.program.inverse);
|
855 |
+
this.declare('inverse', inverseGuid);
|
856 |
+
}
|
857 |
+
|
858 |
+
this.opcode('invokeProgram', programGuid, params.length, !!mustache.hash);
|
859 |
+
this.declare('inverse', null);
|
860 |
+
this.opcode('append');
|
861 |
+
},
|
862 |
+
|
863 |
+
inverse: function(block) {
|
864 |
+
var params = this.setupStackForMustache(block.mustache);
|
865 |
+
|
866 |
+
var programGuid = this.compileProgram(block.program);
|
867 |
+
|
868 |
+
this.declare('inverse', programGuid);
|
869 |
+
|
870 |
+
this.opcode('invokeProgram', null, params.length, !!block.mustache.hash);
|
871 |
+
this.declare('inverse', null);
|
872 |
+
this.opcode('append');
|
873 |
+
},
|
874 |
+
|
875 |
+
hash: function(hash) {
|
876 |
+
var pairs = hash.pairs, pair, val;
|
877 |
+
|
878 |
+
this.opcode('push', '{}');
|
879 |
+
|
880 |
+
for(var i=0, l=pairs.length; i<l; i++) {
|
881 |
+
pair = pairs[i];
|
882 |
+
val = pair[1];
|
883 |
+
|
884 |
+
this.accept(val);
|
885 |
+
this.opcode('assignToHash', pair[0]);
|
886 |
+
}
|
887 |
+
},
|
888 |
+
|
889 |
+
partial: function(partial) {
|
890 |
+
var id = partial.id;
|
891 |
+
this.usePartial = true;
|
892 |
+
|
893 |
+
if(partial.context) {
|
894 |
+
this.ID(partial.context);
|
895 |
+
} else {
|
896 |
+
this.opcode('push', 'depth0');
|
897 |
+
}
|
898 |
+
|
899 |
+
this.opcode('invokePartial', id.original);
|
900 |
+
this.opcode('append');
|
901 |
+
},
|
902 |
+
|
903 |
+
content: function(content) {
|
904 |
+
this.opcode('appendContent', content.string);
|
905 |
+
},
|
906 |
+
|
907 |
+
mustache: function(mustache) {
|
908 |
+
var params = this.setupStackForMustache(mustache);
|
909 |
+
|
910 |
+
this.opcode('invokeMustache', params.length, mustache.id.original, !!mustache.hash);
|
911 |
+
|
912 |
+
if(mustache.escaped && !this.options.noEscape) {
|
913 |
+
this.opcode('appendEscaped');
|
914 |
+
} else {
|
915 |
+
this.opcode('append');
|
916 |
+
}
|
917 |
+
},
|
918 |
+
|
919 |
+
ID: function(id) {
|
920 |
+
this.addDepth(id.depth);
|
921 |
+
|
922 |
+
this.opcode('getContext', id.depth);
|
923 |
+
|
924 |
+
this.opcode('lookupWithHelpers', id.parts[0] || null, id.isScoped || false);
|
925 |
+
|
926 |
+
for(var i=1, l=id.parts.length; i<l; i++) {
|
927 |
+
this.opcode('lookup', id.parts[i]);
|
928 |
+
}
|
929 |
+
},
|
930 |
+
|
931 |
+
STRING: function(string) {
|
932 |
+
this.opcode('pushString', string.string);
|
933 |
+
},
|
934 |
+
|
935 |
+
INTEGER: function(integer) {
|
936 |
+
this.opcode('push', integer.integer);
|
937 |
+
},
|
938 |
+
|
939 |
+
BOOLEAN: function(bool) {
|
940 |
+
this.opcode('push', bool.bool);
|
941 |
+
},
|
942 |
+
|
943 |
+
comment: function() {},
|
944 |
+
|
945 |
+
// HELPERS
|
946 |
+
pushParams: function(params) {
|
947 |
+
var i = params.length, param;
|
948 |
+
|
949 |
+
while(i--) {
|
950 |
+
param = params[i];
|
951 |
+
|
952 |
+
if(this.options.stringParams) {
|
953 |
+
if(param.depth) {
|
954 |
+
this.addDepth(param.depth);
|
955 |
+
}
|
956 |
+
|
957 |
+
this.opcode('getContext', param.depth || 0);
|
958 |
+
this.opcode('pushStringParam', param.string);
|
959 |
+
} else {
|
960 |
+
this[param.type](param);
|
961 |
+
}
|
962 |
+
}
|
963 |
+
},
|
964 |
+
|
965 |
+
opcode: function(name, val1, val2, val3) {
|
966 |
+
this.opcodes.push(Compiler.OPCODE_MAP[name]);
|
967 |
+
if(val1 !== undefined) { this.opcodes.push(val1); }
|
968 |
+
if(val2 !== undefined) { this.opcodes.push(val2); }
|
969 |
+
if(val3 !== undefined) { this.opcodes.push(val3); }
|
970 |
+
},
|
971 |
+
|
972 |
+
declare: function(name, value) {
|
973 |
+
this.opcodes.push('DECLARE');
|
974 |
+
this.opcodes.push(name);
|
975 |
+
this.opcodes.push(value);
|
976 |
+
},
|
977 |
+
|
978 |
+
addDepth: function(depth) {
|
979 |
+
if(depth === 0) { return; }
|
980 |
+
|
981 |
+
if(!this.depths[depth]) {
|
982 |
+
this.depths[depth] = true;
|
983 |
+
this.depths.list.push(depth);
|
984 |
+
}
|
985 |
+
},
|
986 |
+
|
987 |
+
setupStackForMustache: function(mustache) {
|
988 |
+
var params = mustache.params;
|
989 |
+
|
990 |
+
this.pushParams(params);
|
991 |
+
|
992 |
+
if(mustache.hash) {
|
993 |
+
this.hash(mustache.hash);
|
994 |
+
}
|
995 |
+
|
996 |
+
this.ID(mustache.id);
|
997 |
+
|
998 |
+
return params;
|
999 |
+
}
|
1000 |
+
};
|
1001 |
+
|
1002 |
+
JavaScriptCompiler.prototype = {
|
1003 |
+
// PUBLIC API: You can override these methods in a subclass to provide
|
1004 |
+
// alternative compiled forms for name lookup and buffering semantics
|
1005 |
+
nameLookup: function(parent, name, type) {
|
1006 |
+
if (/^[0-9]+$/.test(name)) {
|
1007 |
+
return parent + "[" + name + "]";
|
1008 |
+
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
1009 |
+
return parent + "." + name;
|
1010 |
+
}
|
1011 |
+
else {
|
1012 |
+
return parent + "['" + name + "']";
|
1013 |
+
}
|
1014 |
+
},
|
1015 |
+
|
1016 |
+
appendToBuffer: function(string) {
|
1017 |
+
if (this.environment.isSimple) {
|
1018 |
+
return "return " + string + ";";
|
1019 |
+
} else {
|
1020 |
+
return "buffer += " + string + ";";
|
1021 |
+
}
|
1022 |
+
},
|
1023 |
+
|
1024 |
+
initializeBuffer: function() {
|
1025 |
+
return this.quotedString("");
|
1026 |
+
},
|
1027 |
+
|
1028 |
+
namespace: "Handlebars",
|
1029 |
+
// END PUBLIC API
|
1030 |
+
|
1031 |
+
compile: function(environment, options, context, asObject) {
|
1032 |
+
this.environment = environment;
|
1033 |
+
this.options = options || {};
|
1034 |
+
|
1035 |
+
this.name = this.environment.name;
|
1036 |
+
this.isChild = !!context;
|
1037 |
+
this.context = context || {
|
1038 |
+
programs: [],
|
1039 |
+
aliases: { self: 'this' },
|
1040 |
+
registers: {list: []}
|
1041 |
+
};
|
1042 |
+
|
1043 |
+
this.preamble();
|
1044 |
+
|
1045 |
+
this.stackSlot = 0;
|
1046 |
+
this.stackVars = [];
|
1047 |
+
|
1048 |
+
this.compileChildren(environment, options);
|
1049 |
+
|
1050 |
+
var opcodes = environment.opcodes, opcode;
|
1051 |
+
|
1052 |
+
this.i = 0;
|
1053 |
+
|
1054 |
+
for(l=opcodes.length; this.i<l; this.i++) {
|
1055 |
+
opcode = this.nextOpcode(0);
|
1056 |
+
|
1057 |
+
if(opcode[0] === 'DECLARE') {
|
1058 |
+
this.i = this.i + 2;
|
1059 |
+
this[opcode[1]] = opcode[2];
|
1060 |
+
} else {
|
1061 |
+
this.i = this.i + opcode[1].length;
|
1062 |
+
this[opcode[0]].apply(this, opcode[1]);
|
1063 |
+
}
|
1064 |
+
}
|
1065 |
+
|
1066 |
+
return this.createFunctionContext(asObject);
|
1067 |
+
},
|
1068 |
+
|
1069 |
+
nextOpcode: function(n) {
|
1070 |
+
var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
|
1071 |
+
var extraParams, codes;
|
1072 |
+
|
1073 |
+
if(opcode === 'DECLARE') {
|
1074 |
+
name = opcodes[this.i + 1];
|
1075 |
+
val = opcodes[this.i + 2];
|
1076 |
+
return ['DECLARE', name, val];
|
1077 |
+
} else {
|
1078 |
+
name = Compiler.DISASSEMBLE_MAP[opcode];
|
1079 |
+
|
1080 |
+
extraParams = Compiler.multiParamSize(opcode);
|
1081 |
+
codes = [];
|
1082 |
+
|
1083 |
+
for(var j=0; j<extraParams; j++) {
|
1084 |
+
codes.push(opcodes[this.i + j + 1 + n]);
|
1085 |
+
}
|
1086 |
+
|
1087 |
+
return [name, codes];
|
1088 |
+
}
|
1089 |
+
},
|
1090 |
+
|
1091 |
+
eat: function(opcode) {
|
1092 |
+
this.i = this.i + opcode.length;
|
1093 |
+
},
|
1094 |
+
|
1095 |
+
preamble: function() {
|
1096 |
+
var out = [];
|
1097 |
+
|
1098 |
+
// this register will disambiguate helper lookup from finding a function in
|
1099 |
+
// a context. This is necessary for mustache compatibility, which requires
|
1100 |
+
// that context functions in blocks are evaluated by blockHelperMissing, and
|
1101 |
+
// then proceed as if the resulting value was provided to blockHelperMissing.
|
1102 |
+
this.useRegister('foundHelper');
|
1103 |
+
|
1104 |
+
if (!this.isChild) {
|
1105 |
+
var namespace = this.namespace;
|
1106 |
+
var copies = "helpers = helpers || " + namespace + ".helpers;";
|
1107 |
+
if(this.environment.usePartial) { copies = copies + " partials = partials || " + namespace + ".partials;"; }
|
1108 |
+
out.push(copies);
|
1109 |
+
} else {
|
1110 |
+
out.push('');
|
1111 |
+
}
|
1112 |
+
|
1113 |
+
if (!this.environment.isSimple) {
|
1114 |
+
out.push(", buffer = " + this.initializeBuffer());
|
1115 |
+
} else {
|
1116 |
+
out.push("");
|
1117 |
+
}
|
1118 |
+
|
1119 |
+
// track the last context pushed into place to allow skipping the
|
1120 |
+
// getContext opcode when it would be a noop
|
1121 |
+
this.lastContext = 0;
|
1122 |
+
this.source = out;
|
1123 |
+
},
|
1124 |
+
|
1125 |
+
createFunctionContext: function(asObject) {
|
1126 |
+
var locals = this.stackVars;
|
1127 |
+
if (!this.isChild) {
|
1128 |
+
locals = locals.concat(this.context.registers.list);
|
1129 |
+
}
|
1130 |
+
|
1131 |
+
if(locals.length > 0) {
|
1132 |
+
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
1133 |
+
}
|
1134 |
+
|
1135 |
+
// Generate minimizer alias mappings
|
1136 |
+
if (!this.isChild) {
|
1137 |
+
var aliases = []
|
1138 |
+
for (var alias in this.context.aliases) {
|
1139 |
+
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
1140 |
+
}
|
1141 |
+
}
|
1142 |
+
|
1143 |
+
if (this.source[1]) {
|
1144 |
+
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
1145 |
+
}
|
1146 |
+
|
1147 |
+
// Merge children
|
1148 |
+
if (!this.isChild) {
|
1149 |
+
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
1150 |
+
}
|
1151 |
+
|
1152 |
+
if (!this.environment.isSimple) {
|
1153 |
+
this.source.push("return buffer;");
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
|
1157 |
+
|
1158 |
+
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
1159 |
+
params.push("depth" + this.environment.depths.list[i]);
|
1160 |
+
}
|
1161 |
+
|
1162 |
+
if (asObject) {
|
1163 |
+
params.push(this.source.join("\n "));
|
1164 |
+
|
1165 |
+
return Function.apply(this, params);
|
1166 |
+
} else {
|
1167 |
+
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
|
1168 |
+
Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
|
1169 |
+
return functionSource;
|
1170 |
+
}
|
1171 |
+
},
|
1172 |
+
|
1173 |
+
appendContent: function(content) {
|
1174 |
+
this.source.push(this.appendToBuffer(this.quotedString(content)));
|
1175 |
+
},
|
1176 |
+
|
1177 |
+
append: function() {
|
1178 |
+
var local = this.popStack();
|
1179 |
+
this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
1180 |
+
if (this.environment.isSimple) {
|
1181 |
+
this.source.push("else { " + this.appendToBuffer("''") + " }");
|
1182 |
+
}
|
1183 |
+
},
|
1184 |
+
|
1185 |
+
appendEscaped: function() {
|
1186 |
+
var opcode = this.nextOpcode(1), extra = "";
|
1187 |
+
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
1188 |
+
|
1189 |
+
if(opcode[0] === 'appendContent') {
|
1190 |
+
extra = " + " + this.quotedString(opcode[1][0]);
|
1191 |
+
this.eat(opcode);
|
1192 |
+
}
|
1193 |
+
|
1194 |
+
this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
|
1195 |
+
},
|
1196 |
+
|
1197 |
+
getContext: function(depth) {
|
1198 |
+
if(this.lastContext !== depth) {
|
1199 |
+
this.lastContext = depth;
|
1200 |
+
}
|
1201 |
+
},
|
1202 |
+
|
1203 |
+
lookupWithHelpers: function(name, isScoped) {
|
1204 |
+
if(name) {
|
1205 |
+
var topStack = this.nextStack();
|
1206 |
+
|
1207 |
+
this.usingKnownHelper = false;
|
1208 |
+
|
1209 |
+
var toPush;
|
1210 |
+
if (!isScoped && this.options.knownHelpers[name]) {
|
1211 |
+
toPush = topStack + " = " + this.nameLookup('helpers', name, 'helper');
|
1212 |
+
this.usingKnownHelper = true;
|
1213 |
+
} else if (isScoped || this.options.knownHelpersOnly) {
|
1214 |
+
toPush = topStack + " = " + this.nameLookup('depth' + this.lastContext, name, 'context');
|
1215 |
+
} else {
|
1216 |
+
this.register('foundHelper', this.nameLookup('helpers', name, 'helper'));
|
1217 |
+
toPush = topStack + " = foundHelper || " + this.nameLookup('depth' + this.lastContext, name, 'context');
|
1218 |
+
}
|
1219 |
+
|
1220 |
+
toPush += ';';
|
1221 |
+
this.source.push(toPush);
|
1222 |
+
} else {
|
1223 |
+
this.pushStack('depth' + this.lastContext);
|
1224 |
+
}
|
1225 |
+
},
|
1226 |
+
|
1227 |
+
lookup: function(name) {
|
1228 |
+
var topStack = this.topStack();
|
1229 |
+
this.source.push(topStack + " = (" + topStack + " === null || " + topStack + " === undefined || " + topStack + " === false ? " +
|
1230 |
+
topStack + " : " + this.nameLookup(topStack, name, 'context') + ");");
|
1231 |
+
},
|
1232 |
+
|
1233 |
+
pushStringParam: function(string) {
|
1234 |
+
this.pushStack('depth' + this.lastContext);
|
1235 |
+
this.pushString(string);
|
1236 |
+
},
|
1237 |
+
|
1238 |
+
pushString: function(string) {
|
1239 |
+
this.pushStack(this.quotedString(string));
|
1240 |
+
},
|
1241 |
+
|
1242 |
+
push: function(name) {
|
1243 |
+
this.pushStack(name);
|
1244 |
+
},
|
1245 |
+
|
1246 |
+
invokeMustache: function(paramSize, original, hasHash) {
|
1247 |
+
this.populateParams(paramSize, this.quotedString(original), "{}", null, hasHash, function(nextStack, helperMissingString, id) {
|
1248 |
+
if (!this.usingKnownHelper) {
|
1249 |
+
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
1250 |
+
this.context.aliases.undef = 'void 0';
|
1251 |
+
this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
|
1252 |
+
if (nextStack !== id) {
|
1253 |
+
this.source.push("else { " + nextStack + " = " + id + "; }");
|
1254 |
+
}
|
1255 |
+
}
|
1256 |
+
});
|
1257 |
+
},
|
1258 |
+
|
1259 |
+
invokeProgram: function(guid, paramSize, hasHash) {
|
1260 |
+
var inverse = this.programExpression(this.inverse);
|
1261 |
+
var mainProgram = this.programExpression(guid);
|
1262 |
+
|
1263 |
+
this.populateParams(paramSize, null, mainProgram, inverse, hasHash, function(nextStack, helperMissingString, id) {
|
1264 |
+
if (!this.usingKnownHelper) {
|
1265 |
+
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
1266 |
+
this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
|
1267 |
+
}
|
1268 |
+
});
|
1269 |
+
},
|
1270 |
+
|
1271 |
+
populateParams: function(paramSize, helperId, program, inverse, hasHash, fn) {
|
1272 |
+
var needsRegister = hasHash || this.options.stringParams || inverse || this.options.data;
|
1273 |
+
var id = this.popStack(), nextStack;
|
1274 |
+
var params = [], param, stringParam, stringOptions;
|
1275 |
+
|
1276 |
+
if (needsRegister) {
|
1277 |
+
this.register('tmp1', program);
|
1278 |
+
stringOptions = 'tmp1';
|
1279 |
+
} else {
|
1280 |
+
stringOptions = '{ hash: {} }';
|
1281 |
+
}
|
1282 |
+
|
1283 |
+
if (needsRegister) {
|
1284 |
+
var hash = (hasHash ? this.popStack() : '{}');
|
1285 |
+
this.source.push('tmp1.hash = ' + hash + ';');
|
1286 |
+
}
|
1287 |
+
|
1288 |
+
if(this.options.stringParams) {
|
1289 |
+
this.source.push('tmp1.contexts = [];');
|
1290 |
+
}
|
1291 |
+
|
1292 |
+
for(var i=0; i<paramSize; i++) {
|
1293 |
+
param = this.popStack();
|
1294 |
+
params.push(param);
|
1295 |
+
|
1296 |
+
if(this.options.stringParams) {
|
1297 |
+
this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
|
1298 |
+
}
|
1299 |
+
}
|
1300 |
+
|
1301 |
+
if(inverse) {
|
1302 |
+
this.source.push('tmp1.fn = tmp1;');
|
1303 |
+
this.source.push('tmp1.inverse = ' + inverse + ';');
|
1304 |
+
}
|
1305 |
+
|
1306 |
+
if(this.options.data) {
|
1307 |
+
this.source.push('tmp1.data = data;');
|
1308 |
+
}
|
1309 |
+
|
1310 |
+
params.push(stringOptions);
|
1311 |
+
|
1312 |
+
this.populateCall(params, id, helperId || id, fn, program !== '{}');
|
1313 |
+
},
|
1314 |
+
|
1315 |
+
populateCall: function(params, id, helperId, fn, program) {
|
1316 |
+
var paramString = ["depth0"].concat(params).join(", ");
|
1317 |
+
var helperMissingString = ["depth0"].concat(helperId).concat(params).join(", ");
|
1318 |
+
|
1319 |
+
var nextStack = this.nextStack();
|
1320 |
+
|
1321 |
+
if (this.usingKnownHelper) {
|
1322 |
+
this.source.push(nextStack + " = " + id + ".call(" + paramString + ");");
|
1323 |
+
} else {
|
1324 |
+
this.context.aliases.functionType = '"function"';
|
1325 |
+
var condition = program ? "foundHelper && " : ""
|
1326 |
+
this.source.push("if(" + condition + "typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
|
1327 |
+
}
|
1328 |
+
fn.call(this, nextStack, helperMissingString, id);
|
1329 |
+
this.usingKnownHelper = false;
|
1330 |
+
},
|
1331 |
+
|
1332 |
+
invokePartial: function(context) {
|
1333 |
+
params = [this.nameLookup('partials', context, 'partial'), "'" + context + "'", this.popStack(), "helpers", "partials"];
|
1334 |
+
|
1335 |
+
if (this.options.data) {
|
1336 |
+
params.push("data");
|
1337 |
+
}
|
1338 |
+
|
1339 |
+
this.pushStack("self.invokePartial(" + params.join(", ") + ");");
|
1340 |
+
},
|
1341 |
+
|
1342 |
+
assignToHash: function(key) {
|
1343 |
+
var value = this.popStack();
|
1344 |
+
var hash = this.topStack();
|
1345 |
+
|
1346 |
+
this.source.push(hash + "['" + key + "'] = " + value + ";");
|
1347 |
+
},
|
1348 |
+
|
1349 |
+
// HELPERS
|
1350 |
+
|
1351 |
+
compiler: JavaScriptCompiler,
|
1352 |
+
|
1353 |
+
compileChildren: function(environment, options) {
|
1354 |
+
var children = environment.children, child, compiler;
|
1355 |
+
|
1356 |
+
for(var i=0, l=children.length; i<l; i++) {
|
1357 |
+
child = children[i];
|
1358 |
+
compiler = new this.compiler();
|
1359 |
+
|
1360 |
+
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
|
1361 |
+
var index = this.context.programs.length;
|
1362 |
+
child.index = index;
|
1363 |
+
child.name = 'program' + index;
|
1364 |
+
this.context.programs[index] = compiler.compile(child, options, this.context);
|
1365 |
+
}
|
1366 |
+
},
|
1367 |
+
|
1368 |
+
programExpression: function(guid) {
|
1369 |
+
if(guid == null) { return "self.noop"; }
|
1370 |
+
|
1371 |
+
var child = this.environment.children[guid],
|
1372 |
+
depths = child.depths.list;
|
1373 |
+
var programParams = [child.index, child.name, "data"];
|
1374 |
+
|
1375 |
+
for(var i=0, l = depths.length; i<l; i++) {
|
1376 |
+
depth = depths[i];
|
1377 |
+
|
1378 |
+
if(depth === 1) { programParams.push("depth0"); }
|
1379 |
+
else { programParams.push("depth" + (depth - 1)); }
|
1380 |
+
}
|
1381 |
+
|
1382 |
+
if(depths.length === 0) {
|
1383 |
+
return "self.program(" + programParams.join(", ") + ")";
|
1384 |
+
} else {
|
1385 |
+
programParams.shift();
|
1386 |
+
return "self.programWithDepth(" + programParams.join(", ") + ")";
|
1387 |
+
}
|
1388 |
+
},
|
1389 |
+
|
1390 |
+
register: function(name, val) {
|
1391 |
+
this.useRegister(name);
|
1392 |
+
this.source.push(name + " = " + val + ";");
|
1393 |
+
},
|
1394 |
+
|
1395 |
+
useRegister: function(name) {
|
1396 |
+
if(!this.context.registers[name]) {
|
1397 |
+
this.context.registers[name] = true;
|
1398 |
+
this.context.registers.list.push(name);
|
1399 |
+
}
|
1400 |
+
},
|
1401 |
+
|
1402 |
+
pushStack: function(item) {
|
1403 |
+
this.source.push(this.nextStack() + " = " + item + ";");
|
1404 |
+
return "stack" + this.stackSlot;
|
1405 |
+
},
|
1406 |
+
|
1407 |
+
nextStack: function() {
|
1408 |
+
this.stackSlot++;
|
1409 |
+
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
1410 |
+
return "stack" + this.stackSlot;
|
1411 |
+
},
|
1412 |
+
|
1413 |
+
popStack: function() {
|
1414 |
+
return "stack" + this.stackSlot--;
|
1415 |
+
},
|
1416 |
+
|
1417 |
+
topStack: function() {
|
1418 |
+
return "stack" + this.stackSlot;
|
1419 |
+
},
|
1420 |
+
|
1421 |
+
quotedString: function(str) {
|
1422 |
+
return '"' + str
|
1423 |
+
.replace(/\\/g, '\\\\')
|
1424 |
+
.replace(/"/g, '\\"')
|
1425 |
+
.replace(/\n/g, '\\n')
|
1426 |
+
.replace(/\r/g, '\\r') + '"';
|
1427 |
+
}
|
1428 |
+
};
|
1429 |
+
|
1430 |
+
var reservedWords = (
|
1431 |
+
"break else new var" +
|
1432 |
+
" case finally return void" +
|
1433 |
+
" catch for switch while" +
|
1434 |
+
" continue function this with" +
|
1435 |
+
" default if throw" +
|
1436 |
+
" delete in try" +
|
1437 |
+
" do instanceof typeof" +
|
1438 |
+
" abstract enum int short" +
|
1439 |
+
" boolean export interface static" +
|
1440 |
+
" byte extends long super" +
|
1441 |
+
" char final native synchronized" +
|
1442 |
+
" class float package throws" +
|
1443 |
+
" const goto private transient" +
|
1444 |
+
" debugger implements protected volatile" +
|
1445 |
+
" double import public let yield"
|
1446 |
+
).split(" ");
|
1447 |
+
|
1448 |
+
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
|
1449 |
+
|
1450 |
+
for(var i=0, l=reservedWords.length; i<l; i++) {
|
1451 |
+
compilerWords[reservedWords[i]] = true;
|
1452 |
+
}
|
1453 |
+
|
1454 |
+
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
1455 |
+
if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
|
1456 |
+
return true;
|
1457 |
+
}
|
1458 |
+
return false;
|
1459 |
+
}
|
1460 |
+
|
1461 |
+
})(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
|
1462 |
+
|
1463 |
+
Handlebars.precompile = function(string, options) {
|
1464 |
+
options = options || {};
|
1465 |
+
|
1466 |
+
var ast = Handlebars.parse(string);
|
1467 |
+
var environment = new Handlebars.Compiler().compile(ast, options);
|
1468 |
+
return new Handlebars.JavaScriptCompiler().compile(environment, options);
|
1469 |
+
};
|
1470 |
+
|
1471 |
+
Handlebars.compile = function(string, options) {
|
1472 |
+
options = options || {};
|
1473 |
+
|
1474 |
+
var compiled;
|
1475 |
+
function compile() {
|
1476 |
+
var ast = Handlebars.parse(string);
|
1477 |
+
var environment = new Handlebars.Compiler().compile(ast, options);
|
1478 |
+
var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
|
1479 |
+
return Handlebars.template(templateSpec);
|
1480 |
+
}
|
1481 |
+
|
1482 |
+
// Template is only compiled on first use and cached after that point.
|
1483 |
+
return function(context, options) {
|
1484 |
+
if (!compiled) {
|
1485 |
+
compiled = compile();
|
1486 |
+
}
|
1487 |
+
return compiled.call(this, context, options);
|
1488 |
+
};
|
1489 |
+
};
|
1490 |
+
;
|
1491 |
+
// lib/handlebars/runtime.js
|
1492 |
+
Handlebars.VM = {
|
1493 |
+
template: function(templateSpec) {
|
1494 |
+
// Just add water
|
1495 |
+
var container = {
|
1496 |
+
escapeExpression: Handlebars.Utils.escapeExpression,
|
1497 |
+
invokePartial: Handlebars.VM.invokePartial,
|
1498 |
+
programs: [],
|
1499 |
+
program: function(i, fn, data) {
|
1500 |
+
var programWrapper = this.programs[i];
|
1501 |
+
if(data) {
|
1502 |
+
return Handlebars.VM.program(fn, data);
|
1503 |
+
} else if(programWrapper) {
|
1504 |
+
return programWrapper;
|
1505 |
+
} else {
|
1506 |
+
programWrapper = this.programs[i] = Handlebars.VM.program(fn);
|
1507 |
+
return programWrapper;
|
1508 |
+
}
|
1509 |
+
},
|
1510 |
+
programWithDepth: Handlebars.VM.programWithDepth,
|
1511 |
+
noop: Handlebars.VM.noop
|
1512 |
+
};
|
1513 |
+
|
1514 |
+
return function(context, options) {
|
1515 |
+
options = options || {};
|
1516 |
+
return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
|
1517 |
+
};
|
1518 |
+
},
|
1519 |
+
|
1520 |
+
programWithDepth: function(fn, data, $depth) {
|
1521 |
+
var args = Array.prototype.slice.call(arguments, 2);
|
1522 |
+
|
1523 |
+
return function(context, options) {
|
1524 |
+
options = options || {};
|
1525 |
+
|
1526 |
+
return fn.apply(this, [context, options.data || data].concat(args));
|
1527 |
+
};
|
1528 |
+
},
|
1529 |
+
program: function(fn, data) {
|
1530 |
+
return function(context, options) {
|
1531 |
+
options = options || {};
|
1532 |
+
|
1533 |
+
return fn(context, options.data || data);
|
1534 |
+
};
|
1535 |
+
},
|
1536 |
+
noop: function() { return ""; },
|
1537 |
+
invokePartial: function(partial, name, context, helpers, partials, data) {
|
1538 |
+
options = { helpers: helpers, partials: partials, data: data };
|
1539 |
+
|
1540 |
+
if(partial === undefined) {
|
1541 |
+
throw new Handlebars.Exception("The partial " + name + " could not be found");
|
1542 |
+
} else if(partial instanceof Function) {
|
1543 |
+
return partial(context, options);
|
1544 |
+
} else if (!Handlebars.compile) {
|
1545 |
+
throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
1546 |
+
} else {
|
1547 |
+
partials[name] = Handlebars.compile(partial);
|
1548 |
+
return partials[name](context, options);
|
1549 |
+
}
|
1550 |
+
}
|
1551 |
+
};
|
1552 |
+
|
1553 |
+
Handlebars.template = Handlebars.VM.template;
|
1554 |
+
;
|
readme.txt
CHANGED
@@ -3,29 +3,13 @@ Contributors: jchristopher
|
|
3 |
Donate link: http://mondaybynoon.com/donate/
|
4 |
Tags: post, page, posts, pages, images, PDF, doc, Word, image, jpg, jpeg, picture, pictures, photos, attachment
|
5 |
Requires at least: 3.0
|
6 |
-
Tested up to: 3.
|
7 |
-
Stable tag: 1.6.
|
8 |
|
9 |
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types
|
10 |
|
11 |
== Description ==
|
12 |
|
13 |
-
= Attachments Pro Now Available! =
|
14 |
-
|
15 |
-
Attachments Pro brings a number of frequently requested features:
|
16 |
-
|
17 |
-
* Multiple Attachments instances on edit screens
|
18 |
-
* Customizable, limitless fields and labels
|
19 |
-
* Ability to define rules limiting the availability of Attachments on edit screens
|
20 |
-
* Limit the number of Attachments that can be added
|
21 |
-
* Limit Attach-able Media items by file/mime type
|
22 |
-
* Shortcode support
|
23 |
-
* Auto-inclusion of Attachments content within `the_content()`
|
24 |
-
|
25 |
-
**Much more information** available about [Attachments Pro](http://mondaybynoon.com/store/attachments-pro/)
|
26 |
-
|
27 |
-
= About Attachments =
|
28 |
-
|
29 |
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types. This plugin *does not* directly interact with your theme, you will need to edit your template files.
|
30 |
|
31 |
== Installation ==
|
@@ -62,6 +46,12 @@ Attachments uses WordPress' built in Media library for uploads and storage.
|
|
62 |
|
63 |
== Changelog ==
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
= 1.6.1 =
|
66 |
* Fixed a conflict with WP-Ecommerce
|
67 |
|
3 |
Donate link: http://mondaybynoon.com/donate/
|
4 |
Tags: post, page, posts, pages, images, PDF, doc, Word, image, jpg, jpeg, picture, pictures, photos, attachment
|
5 |
Requires at least: 3.0
|
6 |
+
Tested up to: 3.4.1
|
7 |
+
Stable tag: 1.6.2
|
8 |
|
9 |
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types
|
10 |
|
11 |
== Description ==
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types. This plugin *does not* directly interact with your theme, you will need to edit your template files.
|
14 |
|
15 |
== Installation ==
|
46 |
|
47 |
== Changelog ==
|
48 |
|
49 |
+
= 1.6.2 =
|
50 |
+
* Fixed an issue when you both add and delete Attachments prior to saving posts
|
51 |
+
* Cleaned up the JavaScript that powers the file browse interaction
|
52 |
+
* Swapped out some custom code for WordPress native function calls
|
53 |
+
* Better handling of asset inclusion
|
54 |
+
|
55 |
= 1.6.1 =
|
56 |
* Fixed a conflict with WP-Ecommerce
|
57 |
|