Version Description
Release Date: May 26, 2016
- Important security update. Please upgrade immediately.
Download this release
Release Info
Developer | samhotchkiss |
Plugin | Jetpack by WordPress.com |
Version | 2.4.5 |
Comparing to | |
See all releases |
Code changes from version 2.3.8 to 2.4.5
- _inc/gallery-settings.js +1 -1
- _inc/images/module-icons-sprite-2x.png +0 -0
- _inc/images/module-icons-sprite.png +0 -0
- _inc/jetpack.css +27 -19
- class.jetpack-debugger.php +337 -336
- class.jetpack-heartbeat.php +3 -3
- class.jetpack-options.php +1 -0
- class.jetpack.php +89 -79
- class.json-api-endpoints.php +7 -0
- class.photon.php +1 -1
- functions.twitter-cards.php +67 -0
- jetpack.php +21 -4
- languages/jetpack-ar.mo +0 -0
- languages/jetpack-az.mo +0 -0
- languages/jetpack-bs_BA.mo +0 -0
- languages/jetpack-ca.mo +0 -0
- languages/jetpack-cs_CZ.mo +0 -0
- languages/jetpack-da_DK.mo +0 -0
- languages/jetpack-de_DE.mo +0 -0
- languages/jetpack-el.mo +0 -0
- languages/jetpack-es_ES.mo +0 -0
- languages/jetpack-fa_IR.mo +0 -0
- languages/jetpack-fi.mo +0 -0
- languages/jetpack-fr_FR.mo +0 -0
- languages/jetpack-gl_ES.mo +0 -0
- languages/jetpack-he_IL.mo +0 -0
- languages/jetpack-hr.mo +0 -0
- languages/jetpack-hu_HU.mo +0 -0
- languages/jetpack-id_ID.mo +0 -0
- languages/jetpack-it_IT.mo +0 -0
- languages/jetpack-ja.mo +0 -0
- languages/jetpack-ko_KR.mo +0 -0
- languages/jetpack-lt_LT.mo +0 -0
- languages/jetpack-mk_MK.mo +0 -0
- languages/jetpack-my_MM.mo +0 -0
- languages/jetpack-nb_NO.mo +0 -0
- languages/jetpack-nl_NL.mo +0 -0
- languages/jetpack-nn_NO.mo +0 -0
- languages/jetpack-pl_PL.mo +0 -0
- languages/jetpack-pt_BR.mo +0 -0
- languages/jetpack-pt_PT.mo +0 -0
- languages/jetpack-ro_RO.mo +0 -0
- languages/jetpack-ru_RU.mo +0 -0
- languages/jetpack-sa_IN.mo +0 -0
- languages/jetpack-sk_SK.mo +0 -0
- languages/jetpack-sq.mo +0 -0
- languages/jetpack-sr_RS.mo +0 -0
- languages/jetpack-sv_SE.mo +0 -0
- languages/jetpack-th.mo +0 -0
- languages/jetpack-tr_TR.mo +0 -0
- languages/jetpack-uk.mo +0 -0
- languages/jetpack-ur.mo +0 -0
- languages/jetpack-zh_CN.mo +0 -0
- languages/jetpack-zh_TW.mo +0 -0
- modules/after-the-deadline.php +1 -0
- modules/after-the-deadline/config-unignore.php +3 -0
- modules/carousel.php +1 -0
- modules/comments.php +1 -0
- modules/contact-form.php +1 -0
- modules/contact-form/admin.php +6 -1
- modules/contact-form/css/menu-alter.css +2 -2
- modules/contact-form/css/rtl/menu-alter-rtl.css +3 -3
- modules/contact-form/grunion-contact-form.php +1 -1
- modules/custom-css.php +1 -0
- modules/custom-css/custom-css.php +15 -4
- modules/custom-css/custom-css/css/css-editor.css +3 -0
- modules/custom-css/custom-css/preprocessors/lessc.inc.php +438 -123
- modules/custom-css/custom-css/preprocessors/scss.inc.php +829 -235
- modules/custom-post-types/comics.php +12 -12
- modules/custom-post-types/testimonial.php +3 -3
- modules/debug.php +6 -0
- modules/enhanced-distribution.php +1 -0
- modules/gravatar-hovercards.php +1 -0
- modules/holiday-snow.php +1 -0
- modules/infinite-scroll.php +1 -0
- modules/json-api.php +1 -0
- modules/latex.php +1 -0
- modules/likes.php +13 -12
- modules/likes/post-count-jetpack.js +18 -0
- modules/likes/post-count.js +4 -16
- modules/likes/style.css +1 -1
- modules/minileven.php +1 -0
- modules/minileven/theme/pub/minileven/functions.php +5 -5
- modules/minileven/theme/pub/minileven/style.css +7 -4
- modules/mobile-push.php +1 -0
- modules/module-extras.php +9 -50
- modules/module-info.php +41 -24
- modules/notes.php +1 -0
- modules/omnisearch.php +1 -0
- modules/omnisearch/omnisearch-core.php +5 -0
- modules/omnisearch/omnisearch-media.php +46 -0
- modules/omnisearch/omnisearch.css +16 -3
- modules/omnisearch/rtl/omnisearch-rtl.css +17 -4
- modules/photon.php +1 -0
- modules/post-by-email.php +1 -0
- modules/publicize.php +1 -0
- modules/publicize/assets/publicize.js +1 -1
- modules/publicize/assets/rtl/publicize-rtl.css +2 -1
- modules/publicize/ui.php +10 -6
- modules/random-redirect.php +43 -0
- modules/sharedaddy.php +1 -0
- modules/sharedaddy/images/facebook.png +0 -0
- modules/sharedaddy/images/facebook@2x.png +0 -0
- modules/sharedaddy/images/icon-facebook-2x.png +0 -0
- modules/sharedaddy/images/icon-facebook.png +0 -0
- modules/sharedaddy/sharing-service.php +1 -1
- modules/sharedaddy/sharing.php +2 -1
- modules/shortcodes.php +1 -0
- modules/shortcodes/css/rtl/slideshow-shortcode-rtl.css +2 -1
- modules/shortcodes/css/slideshow-shortcode.css +1 -0
- modules/shortcodes/css/style.css +140 -0
- modules/shortcodes/images/collapse.png +0 -0
- modules/shortcodes/images/expand.png +0 -0
- modules/shortcodes/images/slide-nav.png +0 -0
- modules/shortcodes/js/jmpress.js +2721 -0
- modules/shortcodes/js/jmpress.min.js +13 -0
- modules/shortcodes/js/main.js +197 -0
- modules/shortcodes/presentations.php +382 -0
- modules/shortcodes/twitter-timeline.php +31 -0
- modules/shortcodes/vine.php +65 -0
- modules/shortlinks.php +1 -0
- modules/stats.php +1 -0
- modules/subscriptions.php +32 -12
- modules/theme-tools.php +62 -0
- modules/tiled-gallery.php +1 -0
- modules/tiled-gallery/tiled-gallery.php +5 -0
- modules/vaultpress.php +1 -0
- modules/widget-visibility.php +11 -0
- modules/widget-visibility/widget-conditions.php +379 -0
- modules/widget-visibility/widget-conditions/rtl/widget-conditions-rtl.css +41 -0
- modules/widget-visibility/widget-conditions/widget-conditions.css +39 -0
- modules/widget-visibility/widget-conditions/widget-conditions.js +112 -0
- modules/widgets.php +1 -0
- modules/widgets/top-posts.php +1 -1
- modules/widgets/twitter-timeline.php +12 -3
- modules/wpcc.php +24 -0
- modules/wpcc/wpcc-sign-on.css +11 -0
- modules/wpcc/wpcc-sign-on.js +4 -0
- modules/wpcc/wpcc-sign-on.php +437 -0
- readme.txt +54 -6
_inc/gallery-settings.js
CHANGED
@@ -29,4 +29,4 @@
|
|
29 |
return this;
|
30 |
}
|
31 |
});
|
32 |
-
})(jQuery);
|
29 |
return this;
|
30 |
}
|
31 |
});
|
32 |
+
})(jQuery);
|
_inc/images/module-icons-sprite-2x.png
CHANGED
Binary file
|
_inc/images/module-icons-sprite.png
CHANGED
Binary file
|
_inc/jetpack.css
CHANGED
@@ -30,17 +30,17 @@
|
|
30 |
*/
|
31 |
|
32 |
/* Force the menu not to be sticky, so we can color the arrow. */
|
33 |
-
.toplevel_page_jetpack.
|
34 |
-
body[class*=" jetpack_page_jetpack_"].
|
35 |
position: relative;
|
36 |
z-index: auto;
|
37 |
top: 0;
|
38 |
}
|
39 |
|
40 |
-
.toplevel_page_jetpack.
|
41 |
-
.toplevel_page_jetpack.
|
42 |
-
body[class*=" jetpack_page_jetpack_"].
|
43 |
-
body[class*=" jetpack_page_jetpack_"].
|
44 |
border-right-color:#8fad4b;
|
45 |
}
|
46 |
|
@@ -49,8 +49,8 @@ body[class*=" jetpack_page_jetpack_"].jetpack-disconnected #wpwrap {
|
|
49 |
background: url(images/header-clouds.png) -150px -60px repeat-x;
|
50 |
}
|
51 |
|
52 |
-
.toplevel_page_jetpack.jetpack-disconnected.
|
53 |
-
body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.
|
54 |
background-position: -143px -60px;
|
55 |
}
|
56 |
|
@@ -59,8 +59,8 @@ body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.folded #wpwrap {
|
|
59 |
background-position: -263px -60px;
|
60 |
}
|
61 |
|
62 |
-
.toplevel_page_jetpack.jetpack-disconnected.
|
63 |
-
body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.
|
64 |
background-position: -257px -60px;
|
65 |
}
|
66 |
|
@@ -69,8 +69,8 @@ body[class*=" jetpack_page_jetpack_"].jetpack-connected #wpwrap {
|
|
69 |
background: url(images/header-clouds-small.png) 45px 0 repeat-x;
|
70 |
}
|
71 |
|
72 |
-
.toplevel_page_jetpack.jetpack-connected.
|
73 |
-
body[class*=" jetpack_page_jetpack_"].jetpack-connected.
|
74 |
background-position: 52px 0;
|
75 |
}
|
76 |
|
@@ -79,8 +79,8 @@ body[class*=" jetpack_page_jetpack_"].jetpack-connected.folded #wpwrap {
|
|
79 |
background-position: -68px 0;
|
80 |
}
|
81 |
|
82 |
-
.toplevel_page_jetpack.jetpack-connected.
|
83 |
-
body[class*=" jetpack_page_jetpack_"].jetpack-connected.
|
84 |
background-position: -62px 0;
|
85 |
}
|
86 |
|
@@ -91,8 +91,8 @@ body[class*=" jetpack_page_jetpack_"].jetpack-connected.admin-color-mp6.folded #
|
|
91 |
background-position: -263px -60px;
|
92 |
}
|
93 |
|
94 |
-
.toplevel_page_jetpack.jetpack-disconnected.
|
95 |
-
body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.
|
96 |
background-position: -257px -60px;
|
97 |
}
|
98 |
|
@@ -101,8 +101,8 @@ body[class*=" jetpack_page_jetpack_"].jetpack-connected.admin-color-mp6.folded #
|
|
101 |
background-position: -68px 0;
|
102 |
}
|
103 |
|
104 |
-
.toplevel_page_jetpack.jetpack-connected.
|
105 |
-
body[class*=" jetpack_page_jetpack_"].jetpack-connected.
|
106 |
background-position: -62px 0;
|
107 |
}
|
108 |
|
@@ -667,7 +667,7 @@ p.jp-help {
|
|
667 |
border-bottom-left-radius: 3px;
|
668 |
background-repeat: no-repeat;
|
669 |
background-image: url(images/module-icons-sprite.png);
|
670 |
-
background-size:
|
671 |
}
|
672 |
|
673 |
@media only screen and (-moz-min-device-pixel-ratio: 1.5),
|
@@ -789,6 +789,14 @@ p.jp-help {
|
|
789 |
background-position: -2625px 5px;
|
790 |
}
|
791 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
792 |
.jetpack-module div.module-image p {
|
793 |
background-color: #b4d278;
|
794 |
color: #fff;
|
30 |
*/
|
31 |
|
32 |
/* Force the menu not to be sticky, so we can color the arrow. */
|
33 |
+
.toplevel_page_jetpack.mp6.sticky-menu #adminmenuwrap,
|
34 |
+
body[class*=" jetpack_page_jetpack_"].mp6.sticky-menu #adminmenuwrap {
|
35 |
position: relative;
|
36 |
z-index: auto;
|
37 |
top: 0;
|
38 |
}
|
39 |
|
40 |
+
.toplevel_page_jetpack.mp6 ul#adminmenu a.wp-has-current-submenu:after,
|
41 |
+
.toplevel_page_jetpack.mp6 ul#adminmenu > li.current > a.current:after,
|
42 |
+
body[class*=" jetpack_page_jetpack_"].mp6 ul#adminmenu a.wp-has-current-submenu:after,
|
43 |
+
body[class*=" jetpack_page_jetpack_"].mp6 ul#adminmenu > li.current > a.current:after {
|
44 |
border-right-color:#8fad4b;
|
45 |
}
|
46 |
|
49 |
background: url(images/header-clouds.png) -150px -60px repeat-x;
|
50 |
}
|
51 |
|
52 |
+
.toplevel_page_jetpack.jetpack-disconnected.mp6 #wpwrap,
|
53 |
+
body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.mp6 #wpwrap {
|
54 |
background-position: -143px -60px;
|
55 |
}
|
56 |
|
59 |
background-position: -263px -60px;
|
60 |
}
|
61 |
|
62 |
+
.toplevel_page_jetpack.jetpack-disconnected.mp6.folded #wpwrap,
|
63 |
+
body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.mp6.folded #wpwrap {
|
64 |
background-position: -257px -60px;
|
65 |
}
|
66 |
|
69 |
background: url(images/header-clouds-small.png) 45px 0 repeat-x;
|
70 |
}
|
71 |
|
72 |
+
.toplevel_page_jetpack.jetpack-connected.mp6 #wpwrap,
|
73 |
+
body[class*=" jetpack_page_jetpack_"].jetpack-connected.mp6 #wpwrap {
|
74 |
background-position: 52px 0;
|
75 |
}
|
76 |
|
79 |
background-position: -68px 0;
|
80 |
}
|
81 |
|
82 |
+
.toplevel_page_jetpack.jetpack-connected.mp6.folded #wpwrap,
|
83 |
+
body[class*=" jetpack_page_jetpack_"].jetpack-connected.mp6.folded #wpwrap {
|
84 |
background-position: -62px 0;
|
85 |
}
|
86 |
|
91 |
background-position: -263px -60px;
|
92 |
}
|
93 |
|
94 |
+
.toplevel_page_jetpack.jetpack-disconnected.mp6.auto-fold #wpwrap,
|
95 |
+
body[class*=" jetpack_page_jetpack_"].jetpack-disconnected.mp6.auto-fold #wpwrap {
|
96 |
background-position: -257px -60px;
|
97 |
}
|
98 |
|
101 |
background-position: -68px 0;
|
102 |
}
|
103 |
|
104 |
+
.toplevel_page_jetpack.jetpack-connected.mp6.auto-fold #wpwrap,
|
105 |
+
body[class*=" jetpack_page_jetpack_"].jetpack-connected.mp6.auto-fold #wpwrap {
|
106 |
background-position: -62px 0;
|
107 |
}
|
108 |
|
667 |
border-bottom-left-radius: 3px;
|
668 |
background-repeat: no-repeat;
|
669 |
background-image: url(images/module-icons-sprite.png);
|
670 |
+
background-size: 2885px 50px; /* remember to update this every time a new module is added! */
|
671 |
}
|
672 |
|
673 |
@media only screen and (-moz-min-device-pixel-ratio: 1.5),
|
789 |
background-position: -2625px 5px;
|
790 |
}
|
791 |
|
792 |
+
#wpcc.jetpack-module div.module-image {
|
793 |
+
background-position: -2710px 5px;
|
794 |
+
}
|
795 |
+
|
796 |
+
#widget-visibility.jetpack-module div.module-image {
|
797 |
+
background-position: -2800px 5px;
|
798 |
+
}
|
799 |
+
|
800 |
.jetpack-module div.module-image p {
|
801 |
background-color: #b4d278;
|
802 |
color: #fff;
|
class.jetpack-debugger.php
CHANGED
@@ -1,353 +1,354 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
try {
|
5 |
-
$response = wp_remote_request( "http://jetpack.me/is-support-open" );
|
6 |
-
$body = wp_remote_retrieve_body( $response );
|
7 |
-
$json = json_decode( $body );
|
8 |
-
return ( ( bool )$json->is_support_open );
|
9 |
-
}
|
10 |
-
catch ( Exception $e ) {
|
11 |
-
return true;
|
12 |
-
}
|
13 |
-
}
|
14 |
-
|
15 |
-
function jetpack_increase_timeout($time) {
|
16 |
-
$time = 20; //seconds
|
17 |
-
return $time;
|
18 |
-
}
|
19 |
-
|
20 |
-
|
21 |
-
function jetpack_debug_display_handler() {
|
22 |
-
if ( ! current_user_can( 'manage_options' ) )
|
23 |
-
wp_die( esc_html__('You do not have sufficient permissions to access this page.', 'jetpack' ) );
|
24 |
-
|
25 |
-
global $current_user;
|
26 |
-
get_currentuserinfo();
|
27 |
-
|
28 |
-
$user_id = get_current_user_id();
|
29 |
-
$user_tokens = Jetpack::get_option( 'user_tokens' );
|
30 |
-
if ( is_array( $user_tokens ) && array_key_exists( $user_id, $user_tokens ) ) {
|
31 |
-
$user_token = $user_tokens[$user_id];
|
32 |
-
} else {
|
33 |
-
$user_token = '[this user has no token]';
|
34 |
-
}
|
35 |
-
unset( $user_tokens );
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
) as $label => $option_name ) {
|
48 |
-
$debug_info .= "\r\n" . esc_html( $label . ": " . Jetpack::get_option( $option_name ) );
|
49 |
}
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
$debug_info .= "\r\n" . esc_html( "JETPACK__VERSION: " . JETPACK__VERSION );
|
56 |
-
$debug_info .= "\r\n" . esc_html( "JETPACK__PLUGIN_DIR: " . JETPACK__PLUGIN_DIR );
|
57 |
-
$debug_info .= "\r\n" . esc_html( "SITE_URL: " . site_url() );
|
58 |
-
$debug_info .= "\r\n" . esc_html( "HOME_URL: " . home_url() );
|
59 |
-
|
60 |
-
$debug_info .= "\r\n\r\nTEST RESULTS:\r\n\r\n";
|
61 |
-
$debug_raw_info = '';
|
62 |
-
|
63 |
-
|
64 |
-
$tests = array();
|
65 |
-
|
66 |
-
$tests['HTTP']['result'] = wp_remote_get( preg_replace( '/^https:/', 'http:', JETPACK__API_BASE ) . 'test/1/' );
|
67 |
-
$tests['HTTP']['fail_message'] = esc_html__( 'Your site isn’t reaching the Jetpack servers.', 'jetpack' );
|
68 |
-
|
69 |
-
$tests['HTTPS']['result'] = wp_remote_get( preg_replace( '/^http:/', 'https:', JETPACK__API_BASE ) . 'test/1/' );
|
70 |
-
$tests['HTTPS']['fail_message'] = esc_html__( 'Your site isn’t securely reaching the Jetpack servers.', 'jetpack' );
|
71 |
-
|
72 |
-
|
73 |
-
$self_xml_rpc_url = site_url( 'xmlrpc.php' );
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
add_filter( 'http_request_timeout', 'jetpack_increase_timeout' );
|
79 |
-
|
80 |
-
$tests['SELF']['result'] = wp_remote_get( $testsite_url . $self_xml_rpc_url );
|
81 |
-
$tests['SELF']['fail_message'] = esc_html__( 'It looks like your site can not communicate properly with Jetpack.', 'jetpack' );
|
82 |
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
foreach ( $tests as $test_name => $test_info ) :
|
93 |
-
if ( is_wp_error( $test_info['result'] ) ||
|
94 |
-
false == ( $response_code = wp_remote_retrieve_response_code( $test_info['result'] ) ) ||
|
95 |
-
'200' != $response_code ) {
|
96 |
-
$debug_info .= $test_name . ": FAIL\r\n";
|
97 |
-
?>
|
98 |
-
<div class="jetpack-test-error">
|
99 |
-
<p>
|
100 |
-
<a class="jetpack-test-heading" href="#"><?php echo $test_info['fail_message']; ?>
|
101 |
-
<span class="noticon noticon-collapse"></span>
|
102 |
-
</a>
|
103 |
-
</p>
|
104 |
-
<pre class="jetpack-test-details"><?php esc_html_e( $test_name , 'jetpack'); ?>:
|
105 |
-
<?php esc_html_e( is_wp_error( $test_info['result'] ) ? $test_info['result']->get_error_message() : print_r( $test_info['result'], 1 ) ); ?></pre>
|
106 |
-
</div><?php
|
107 |
-
} else {
|
108 |
-
$debug_info .= $test_name . ": PASS\r\n";
|
109 |
-
}
|
110 |
-
$debug_raw_info .= "\r\n\r\n" . $test_name . "\r\n" . esc_html( print_r( $test_info['result'], 1 ) );
|
111 |
-
?>
|
112 |
-
<?php endforeach;
|
113 |
-
$html = ob_get_clean();
|
114 |
-
|
115 |
-
if ( '' == trim( $html ) ) {
|
116 |
-
echo '<div class="jetpack-tests-succed">' . esc_html__( 'Your Jetpack setup looks a-okay!', 'jetpack' ) . '</div>';
|
117 |
}
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
122 |
-
$debug_info .= "\r\n\r\nRAW TEST RESULTS:" . $debug_raw_info ."\r\n";
|
123 |
-
?>
|
124 |
-
</div>
|
125 |
-
<div class="entry-content">
|
126 |
-
<h3><?php esc_html_e( 'Trouble with Jetpack?', 'jetpack' ); ?></h3>
|
127 |
-
<h4><?php esc_html_e( 'It may be caused by one of these issues, which you can diagnose yourself:', 'jetpack' ); ?></h4>
|
128 |
-
<ol>
|
129 |
-
<li><b><em><?php esc_html_e( 'A known issue.', 'jetpack' ); ?></em></b> <?php echo sprintf( __( 'Some themes and plugins have <a href="%1$s" target="_blank">known conflicts</a> with Jetpack – check the <a href="%2$s" target="_blank">list</a>. (You can also browse the <a href="%3$s">Jetpack support pages</a> or <a href="%4$s">Jetpack support forum</a> to see if others have experienced and solved the problem.)', 'jetpack' ), 'http://jetpack.me/known-issues/', 'http://jetpack.me/known-issues/', 'http://jetpack.me/support/', 'http://wordpress.org/support/plugin/jetpack' ); ?></li>
|
130 |
-
<li><b><em><?php esc_html_e( 'An incompatible plugin.', 'jetpack' ); ?></em></b> <?php esc_html_e( "Find out by disabling all plugins except Jetpack. If the problem persists, it's not a plugin issue. If the problem is solved, turn your plugins on one by one until the problem pops up again – there's the culprit! Let us know, and we'll try to help.", 'jetpack' ); ?></li>
|
131 |
-
<li><b><em><?php esc_html_e( 'A theme conflict.', 'jetpack' ); ?></em></b> <?php esc_html_e( "If your problem isn't known or caused by a plugin, try activating Twenty Twelve (the default WordPress theme). If this solves the problem, something in your theme is probably broken – let the theme's author know.", 'jetpack' ); ?></li>
|
132 |
-
<li><b><em><?php esc_html_e( 'A problem with your XMLRPC file.', 'jetpack' ); ?></em></b> <?php echo sprintf( __( 'Load your <a href="%s">XMLRPC file</a>. It should say “XML-RPC server accepts POST requests only.” on a line by itself.', 'jetpack' ), site_url( 'xmlrpc.php' ) ); ?>
|
133 |
-
<ul>
|
134 |
-
<li>- <?php esc_html_e( "If it's not by itself, a theme or plugin is displaying extra characters. Try steps 2 and 3.", 'jetpack' ); ?></li>
|
135 |
-
<li>- <?php esc_html_e( "If you get a 404 message, contact your web host. Their security may block XMLRPC.", 'jetpack' ); ?></li>
|
136 |
-
</ul>
|
137 |
-
</li>
|
138 |
-
</ol>
|
139 |
-
<p class="jetpack-show-contact-form"><?php _e( 'If none of these help you find a solution, <a href="#">click here to contact Jetpack support</a>. Tell us as much as you can about the issue and what steps you\'ve tried to resolve it, and one of our Happiness Engineers will be in touch to help.', 'jetpack' ); ?>
|
140 |
-
</p>
|
141 |
-
</div>
|
142 |
-
<div id="contact-message" style="display:none">
|
143 |
-
<?php if ( is_jetpack_support_open() ): ?>
|
144 |
-
<form id="contactme" method="post" action="http://jetpack.me/contact-support/">
|
145 |
-
<input type="hidden" name="action" value="submit">
|
146 |
-
<input type="hidden" name="jetpack" value="needs-service">
|
147 |
-
|
148 |
-
<input type="hidden" name="contact_form" id="contact_form" value="1">
|
149 |
-
<input type="hidden" name="blog_url" id="blog_url" value="<?php echo esc_attr( site_url() ); ?>">
|
150 |
-
<input type="hidden" name="subject" id="subject" value="from: <?php echo esc_attr( site_url() ); ?> Jetpack contact form">
|
151 |
-
<div class="formbox">
|
152 |
-
<label for="message" class="h"><?php esc_html_e( 'Please describe the problem you are having.', 'jetpack' ); ?></label>
|
153 |
-
<textarea name="message" cols="40" rows="7" id="did"></textarea>
|
154 |
-
</div>
|
155 |
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
<p><?php _e( 'The test results and some other useful debug information will be sent to the support team. Please feel free to <a href="#">review/modify</a> this information.', 'jetpack' ); ?></p>
|
170 |
-
</div>
|
171 |
-
|
172 |
-
<div id="debug_info_div" class="formbox" style="display:none">
|
173 |
-
<label class="h" for="debug_info"><?php esc_html_e( 'Debug Info', 'jetpack' ); ?></label>
|
174 |
-
<textarea name="debug_info" cols="40" rows="7" id="debug_info"><?php echo esc_attr( $debug_info ); ?></textarea>
|
175 |
-
</div>
|
176 |
-
|
177 |
-
<div style="clear: both;"></div>
|
178 |
|
179 |
-
|
180 |
-
|
181 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
</div>
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
</div>
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
margin-bottom: 30px;
|
199 |
-
}
|
200 |
-
|
201 |
-
.jetpack-tests-succed {
|
202 |
-
font-size: large;
|
203 |
-
color: #8BAB3E;
|
204 |
-
}
|
205 |
-
|
206 |
-
.jetpack-test-details {
|
207 |
-
margin: 4px 6px;
|
208 |
-
padding: 10px;
|
209 |
-
overflow: auto;
|
210 |
-
display: none;
|
211 |
-
}
|
212 |
-
|
213 |
-
.jetpack-test-error {
|
214 |
-
margin-bottom: 10px;
|
215 |
-
background: #FFEBE8;
|
216 |
-
border: solid 1px #C00;
|
217 |
-
border-radius: 3px;
|
218 |
-
}
|
219 |
-
|
220 |
-
.jetpack-test-error p {
|
221 |
-
margin: 0;
|
222 |
-
padding: 0;
|
223 |
-
}
|
224 |
-
|
225 |
-
.jetpack-test-error a.jetpack-test-heading {
|
226 |
-
padding: 4px 6px;
|
227 |
-
display: block;
|
228 |
-
text-decoration: none;
|
229 |
-
color: inherit;
|
230 |
-
}
|
231 |
-
|
232 |
-
.jetpack-test-error .noticon {
|
233 |
-
float: right;
|
234 |
-
}
|
235 |
-
|
236 |
-
form#contactme {
|
237 |
-
border: 1px solid #dfdfdf;
|
238 |
-
background: #eaf3fa;
|
239 |
-
padding: 20px;
|
240 |
-
margin: 10px;
|
241 |
-
background-color: #eaf3fa;
|
242 |
-
border-radius: 5px;
|
243 |
-
font-size: 15px;
|
244 |
-
font-family: "Open Sans", "Helvetica Neue", sans-serif;
|
245 |
-
}
|
246 |
-
|
247 |
-
form#contactme label.h {
|
248 |
-
color: #444;
|
249 |
-
display: block;
|
250 |
-
font-weight: bold;
|
251 |
-
margin: 0 0 7px 10px;
|
252 |
-
text-shadow: 1px 1px 0 #fff;
|
253 |
-
}
|
254 |
-
|
255 |
-
.formbox {
|
256 |
-
margin: 0 0 25px 0;
|
257 |
-
}
|
258 |
-
|
259 |
-
.formbox input[type="text"], .formbox input[type="email"], .formbox input[type="url"], .formbox textarea {
|
260 |
-
border: 1px solid #e5e5e5;
|
261 |
-
border-radius: 11px;
|
262 |
-
box-shadow: inset 0 1px 1px rgba(0,0,0,0.1);
|
263 |
-
color: #666;
|
264 |
-
font-size: 14px;
|
265 |
-
padding: 10px;
|
266 |
-
width: 97%;
|
267 |
-
}
|
268 |
-
.formbox .contact-support input[type="submit"] {
|
269 |
-
float: right;
|
270 |
-
margin: 0 !important;
|
271 |
-
border-radius: 20px !important;
|
272 |
-
cursor: pointer;
|
273 |
-
font-size: 13pt !important;
|
274 |
-
height: auto !important;
|
275 |
-
margin: 0 0 2em 10px !important;
|
276 |
-
padding: 8px 16px !important;
|
277 |
-
background-color: #ddd;
|
278 |
-
border: 1px solid rgba(0,0,0,0.05);
|
279 |
-
border-top-color: rgba(255,255,255,0.1);
|
280 |
-
border-bottom-color: rgba(0,0,0,0.15);
|
281 |
-
color: #333;
|
282 |
-
font-weight: 400;
|
283 |
-
display: inline-block;
|
284 |
-
text-align: center;
|
285 |
-
text-decoration: none;
|
286 |
-
}
|
287 |
-
|
288 |
-
.formbox span.errormsg {
|
289 |
-
margin: 0 0 10px 10px;
|
290 |
-
color: #d00;
|
291 |
-
display: none;
|
292 |
-
}
|
293 |
-
|
294 |
-
.formbox.error span.errormsg {
|
295 |
-
display: block;
|
296 |
-
}
|
297 |
-
|
298 |
-
#contact-message ul {
|
299 |
-
margin: 0 0 20px 10px;
|
300 |
-
}
|
301 |
-
|
302 |
-
#contact-message li {
|
303 |
-
margin: 0 0 10px 10px;
|
304 |
-
list-style: disc;
|
305 |
-
display: list-item;
|
306 |
-
}
|
307 |
-
|
308 |
-
</style>
|
309 |
-
<script type="text/javascript">
|
310 |
-
jQuery( document ).ready( function($) {
|
311 |
-
|
312 |
-
$('#debug_info').prepend('jQuery version: ' + jQuery.fn.jquery + "\r\n");
|
313 |
-
|
314 |
-
$( '.jetpack-test-error .jetpack-test-heading' ).on( 'click', function() {
|
315 |
-
$( this ).parents( '.jetpack-test-error' ).find( '.jetpack-test-details' ).slideToggle();
|
316 |
-
return false;
|
317 |
-
} );
|
318 |
-
|
319 |
-
$( '.jetpack-show-contact-form a' ).on( 'click', function() {
|
320 |
-
$('#contact-message').slideToggle();
|
321 |
-
return false;
|
322 |
-
} );
|
323 |
-
|
324 |
-
$( '#toggle_debug_info a' ).on( 'click', function() {
|
325 |
-
$('#debug_info_div').slideToggle();
|
326 |
-
return false;
|
327 |
-
} );
|
328 |
-
|
329 |
-
$('form#contactme').on("submit", function(e){
|
330 |
-
var form = $(this);
|
331 |
-
var message = form.find('#did');
|
332 |
-
var name = form.find('#your_name');
|
333 |
-
var email = form.find('#your_email')
|
334 |
-
var validation_error = false;
|
335 |
-
if( !name.val() ) {
|
336 |
-
name.parents('.formbox').addClass('error');
|
337 |
-
validation_error = true;
|
338 |
}
|
339 |
-
|
340 |
-
|
341 |
-
|
|
|
342 |
}
|
343 |
-
|
344 |
-
|
|
|
|
|
|
|
|
|
345 |
}
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
|
3 |
+
class Jetpack_Debugger {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
+
private static function is_jetpack_support_open() {
|
6 |
+
try {
|
7 |
+
$response = wp_remote_request( "http://jetpack.me/is-support-open" );
|
8 |
+
$body = wp_remote_retrieve_body( $response );
|
9 |
+
$json = json_decode( $body );
|
10 |
+
return ( ( bool )$json->is_support_open );
|
11 |
+
}
|
12 |
+
catch ( Exception $e ) {
|
13 |
+
return true;
|
14 |
+
}
|
|
|
|
|
15 |
}
|
16 |
|
17 |
+
public static function jetpack_increase_timeout($time) {
|
18 |
+
$time = 20; //seconds
|
19 |
+
return $time;
|
20 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
+
public static function jetpack_debug_display_handler() {
|
23 |
+
if ( ! current_user_can( 'manage_options' ) )
|
24 |
+
wp_die( esc_html__('You do not have sufficient permissions to access this page.', 'jetpack' ) );
|
|
|
|
|
|
|
|
|
25 |
|
26 |
+
global $current_user;
|
27 |
+
get_currentuserinfo();
|
28 |
+
|
29 |
+
$user_id = get_current_user_id();
|
30 |
+
$user_tokens = Jetpack::get_option( 'user_tokens' );
|
31 |
+
if ( is_array( $user_tokens ) && array_key_exists( $user_id, $user_tokens ) ) {
|
32 |
+
$user_token = $user_tokens[$user_id];
|
33 |
+
} else {
|
34 |
+
$user_token = '[this user has no token]';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
}
|
36 |
+
unset( $user_tokens );
|
37 |
+
|
38 |
+
$debug_info = "\r\n";
|
39 |
+
foreach ( array(
|
40 |
+
'CLIENT_ID' => 'id',
|
41 |
+
'BLOG_TOKEN' => 'blog_token',
|
42 |
+
'MASTER_USER' => 'master_user',
|
43 |
+
'CERT' => 'fallback_no_verify_ssl_certs',
|
44 |
+
'TIME_DIFF' => 'time_diff',
|
45 |
+
'VERSION' => 'version',
|
46 |
+
'OLD_VERSION' => 'old_version',
|
47 |
+
'PUBLIC' => 'public',
|
48 |
+
) as $label => $option_name ) {
|
49 |
+
$debug_info .= "\r\n" . esc_html( $label . ": " . Jetpack::get_option( $option_name ) );
|
50 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
+
$debug_info .= "\r\n" . esc_html( "USER_ID: " . $user_id );
|
53 |
+
$debug_info .= "\r\n" . esc_html( "USER_TOKEN: " . $user_token );
|
54 |
+
$debug_info .= "\r\n" . esc_html( "PHP_VERSION: " . PHP_VERSION );
|
55 |
+
$debug_info .= "\r\n" . esc_html( "WORDPRESS_VERSION: " . $GLOBALS['wp_version'] );
|
56 |
+
$debug_info .= "\r\n" . esc_html( "JETPACK__VERSION: " . JETPACK__VERSION );
|
57 |
+
$debug_info .= "\r\n" . esc_html( "JETPACK__PLUGIN_DIR: " . JETPACK__PLUGIN_DIR );
|
58 |
+
$debug_info .= "\r\n" . esc_html( "SITE_URL: " . site_url() );
|
59 |
+
$debug_info .= "\r\n" . esc_html( "HOME_URL: " . home_url() );
|
60 |
+
|
61 |
+
$debug_info .= "\r\n\r\nTEST RESULTS:\r\n\r\n";
|
62 |
+
$debug_raw_info = '';
|
63 |
+
|
64 |
+
|
65 |
+
$tests = array();
|
66 |
+
|
67 |
+
$tests['HTTP']['result'] = wp_remote_get( preg_replace( '/^https:/', 'http:', JETPACK__API_BASE ) . 'test/1/' );
|
68 |
+
$tests['HTTP']['fail_message'] = esc_html__( 'Your site isn’t reaching the Jetpack servers.', 'jetpack' );
|
69 |
+
|
70 |
+
$tests['HTTPS']['result'] = wp_remote_get( preg_replace( '/^http:/', 'https:', JETPACK__API_BASE ) . 'test/1/' );
|
71 |
+
$tests['HTTPS']['fail_message'] = esc_html__( 'Your site isn’t securely reaching the Jetpack servers.', 'jetpack' );
|
72 |
+
|
73 |
+
$self_xml_rpc_url = home_url( 'xmlrpc.php' );
|
74 |
|
75 |
+
$args = array();
|
76 |
+
$testsite_url = Jetpack::fix_url_for_bad_hosts( JETPACK__API_BASE . 'testsite/1/?url=', $args );
|
77 |
+
|
78 |
+
add_filter( 'http_request_timeout', array( 'Jetpack_Debugger', 'jetpack_increase_timeout' ) );
|
79 |
+
|
80 |
+
$tests['SELF']['result'] = wp_remote_get( $testsite_url . $self_xml_rpc_url );
|
81 |
+
$tests['SELF']['fail_message'] = esc_html__( 'It looks like your site can not communicate properly with Jetpack.', 'jetpack' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
|
83 |
+
remove_filter( 'http_request_timeout', array( 'Jetpack_Debugger', 'jetpack_increase_timeout' ) );
|
84 |
+
|
85 |
+
?>
|
86 |
+
<div class="wrap">
|
87 |
+
<h2><?php esc_html_e( 'Jetpack Debugging Center', 'jetpack' ); ?></h2>
|
88 |
+
<h3><?php _e( "Testing your site's compatibily with Jetpack...", 'jetpack' ); ?></h3>
|
89 |
+
<div class="jetpack-debug-test-container">
|
90 |
+
<?php
|
91 |
+
ob_start();
|
92 |
+
foreach ( $tests as $test_name => $test_info ) :
|
93 |
+
if ( is_wp_error( $test_info['result'] ) ||
|
94 |
+
false == ( $response_code = wp_remote_retrieve_response_code( $test_info['result'] ) ) ||
|
95 |
+
'200' != $response_code ) {
|
96 |
+
$debug_info .= $test_name . ": FAIL\r\n";
|
97 |
+
?>
|
98 |
+
<div class="jetpack-test-error">
|
99 |
+
<p>
|
100 |
+
<a class="jetpack-test-heading" href="#"><?php echo $test_info['fail_message']; ?>
|
101 |
+
<span class="noticon noticon-collapse"></span>
|
102 |
+
</a>
|
103 |
+
</p>
|
104 |
+
<pre class="jetpack-test-details"><?php esc_html_e( $test_name , 'jetpack'); ?>:
|
105 |
+
<?php esc_html_e( is_wp_error( $test_info['result'] ) ? $test_info['result']->get_error_message() : print_r( $test_info['result'], 1 ), 'jetpack' ); ?></pre>
|
106 |
+
</div><?php
|
107 |
+
} else {
|
108 |
+
$debug_info .= $test_name . ": PASS\r\n";
|
109 |
+
}
|
110 |
+
$debug_raw_info .= "\r\n\r\n" . $test_name . "\r\n" . esc_html( print_r( $test_info['result'], 1 ) );
|
111 |
+
?>
|
112 |
+
<?php endforeach;
|
113 |
+
$html = ob_get_clean();
|
114 |
+
|
115 |
+
if ( '' == trim( $html ) ) {
|
116 |
+
echo '<div class="jetpack-tests-succed">' . esc_html__( 'Your Jetpack setup looks a-okay!', 'jetpack' ) . '</div>';
|
117 |
+
}
|
118 |
+
else {
|
119 |
+
echo '<h3>' . esc_html__( 'There seems to be a problem with your site’s ability to communicate with Jetpack!', 'jetpack' ) . '</h3>';
|
120 |
+
echo $html;
|
121 |
+
}
|
122 |
+
$debug_info .= "\r\n\r\nRAW TEST RESULTS:" . $debug_raw_info ."\r\n";
|
123 |
+
?>
|
124 |
+
</div>
|
125 |
+
<div class="entry-content">
|
126 |
+
<h3><?php esc_html_e( 'Trouble with Jetpack?', 'jetpack' ); ?></h3>
|
127 |
+
<h4><?php esc_html_e( 'It may be caused by one of these issues, which you can diagnose yourself:', 'jetpack' ); ?></h4>
|
128 |
+
<ol>
|
129 |
+
<li><b><em><?php esc_html_e( 'A known issue.', 'jetpack' ); ?></em></b> <?php echo sprintf( __( 'Some themes and plugins have <a href="%1$s" target="_blank">known conflicts</a> with Jetpack – check the <a href="%2$s" target="_blank">list</a>. (You can also browse the <a href="%3$s">Jetpack support pages</a> or <a href="%4$s">Jetpack support forum</a> to see if others have experienced and solved the problem.)', 'jetpack' ), 'http://jetpack.me/known-issues/', 'http://jetpack.me/known-issues/', 'http://jetpack.me/support/', 'http://wordpress.org/support/plugin/jetpack' ); ?></li>
|
130 |
+
<li><b><em><?php esc_html_e( 'An incompatible plugin.', 'jetpack' ); ?></em></b> <?php esc_html_e( "Find out by disabling all plugins except Jetpack. If the problem persists, it's not a plugin issue. If the problem is solved, turn your plugins on one by one until the problem pops up again – there's the culprit! Let us know, and we'll try to help.", 'jetpack' ); ?></li>
|
131 |
+
<li><b><em><?php esc_html_e( 'A theme conflict.', 'jetpack' ); ?></em></b> <?php esc_html_e( "If your problem isn't known or caused by a plugin, try activating Twenty Twelve (the default WordPress theme). If this solves the problem, something in your theme is probably broken – let the theme's author know.", 'jetpack' ); ?></li>
|
132 |
+
<li><b><em><?php esc_html_e( 'A problem with your XMLRPC file.', 'jetpack' ); ?></em></b> <?php echo sprintf( __( 'Load your <a href="%s">XMLRPC file</a>. It should say “XML-RPC server accepts POST requests only.” on a line by itself.', 'jetpack' ), site_url( 'xmlrpc.php' ) ); ?>
|
133 |
+
<ul>
|
134 |
+
<li>- <?php esc_html_e( "If it's not by itself, a theme or plugin is displaying extra characters. Try steps 2 and 3.", 'jetpack' ); ?></li>
|
135 |
+
<li>- <?php esc_html_e( "If you get a 404 message, contact your web host. Their security may block XMLRPC.", 'jetpack' ); ?></li>
|
136 |
+
</ul>
|
137 |
+
</li>
|
138 |
+
</ol>
|
139 |
+
<p class="jetpack-show-contact-form"><?php _e( 'If none of these help you find a solution, <a href="#">click here to contact Jetpack support</a>. Tell us as much as you can about the issue and what steps you\'ve tried to resolve it, and one of our Happiness Engineers will be in touch to help.', 'jetpack' ); ?>
|
140 |
+
</p>
|
141 |
+
</div>
|
142 |
+
<div id="contact-message" style="display:none">
|
143 |
+
<?php if ( self::is_jetpack_support_open() ): ?>
|
144 |
+
<form id="contactme" method="post" action="http://jetpack.me/contact-support/">
|
145 |
+
<input type="hidden" name="action" value="submit">
|
146 |
+
<input type="hidden" name="jetpack" value="needs-service">
|
147 |
+
|
148 |
+
<input type="hidden" name="contact_form" id="contact_form" value="1">
|
149 |
+
<input type="hidden" name="blog_url" id="blog_url" value="<?php echo esc_attr( site_url() ); ?>">
|
150 |
+
<input type="hidden" name="subject" id="subject" value="from: <?php echo esc_attr( site_url() ); ?> Jetpack contact form">
|
151 |
+
<div class="formbox">
|
152 |
+
<label for="message" class="h"><?php esc_html_e( 'Please describe the problem you are having.', 'jetpack' ); ?></label>
|
153 |
+
<textarea name="message" cols="40" rows="7" id="did"></textarea>
|
154 |
+
</div>
|
155 |
+
|
156 |
+
<div id="name_div" class="formbox">
|
157 |
+
<label class="h" for="your_name"><?php esc_html_e( 'Name', 'jetpack' ); ?></label>
|
158 |
+
<span class="errormsg"><?php esc_html_e( 'Let us know your name.', 'jetpack' ); ?></span>
|
159 |
+
<input name="your_name" type="text" id="your_name" value="<?php esc_html_e( $current_user->display_name , 'jetpack'); ?>" size="40">
|
160 |
+
</div>
|
161 |
+
|
162 |
+
<div id="email_div" class="formbox">
|
163 |
+
<label class="h" for="your_email"><?php esc_html_e( 'E-mail', 'jetpack' ); ?></label>
|
164 |
+
<span class="errormsg"><?php esc_html_e( 'Use a valid email address.', 'jetpack' ); ?></span>
|
165 |
+
<input name="your_email" type="text" id="your_email" value="<?php esc_html_e( $current_user->user_email , 'jetpack'); ?>" size="40">
|
166 |
+
</div>
|
167 |
+
|
168 |
+
<div id="toggle_debug_info" class="formbox">
|
169 |
+
<p><?php _e( 'The test results and some other useful debug information will be sent to the support team. Please feel free to <a href="#">review/modify</a> this information.', 'jetpack' ); ?></p>
|
170 |
+
</div>
|
171 |
+
|
172 |
+
<div id="debug_info_div" class="formbox" style="display:none">
|
173 |
+
<label class="h" for="debug_info"><?php esc_html_e( 'Debug Info', 'jetpack' ); ?></label>
|
174 |
+
<textarea name="debug_info" cols="40" rows="7" id="debug_info"><?php echo esc_attr( $debug_info ); ?></textarea>
|
175 |
+
</div>
|
176 |
+
|
177 |
+
<div style="clear: both;"></div>
|
178 |
+
|
179 |
+
<div id="blog_div" class="formbox">
|
180 |
+
<div id="submit_div" class="contact-support">
|
181 |
+
<input type="submit" name="submit" value="Contact Support">
|
182 |
+
</div>
|
183 |
</div>
|
184 |
+
<div style="clear: both;"></div>
|
185 |
+
</form>
|
186 |
+
<?php endif; ?>
|
187 |
+
</div>
|
188 |
</div>
|
189 |
+
<?php
|
190 |
+
}
|
191 |
+
|
192 |
+
public static function jetpack_debug_admin_head() {
|
193 |
+
?>
|
194 |
+
<style type="text/css">
|
195 |
+
|
196 |
+
.jetpack-debug-test-container {
|
197 |
+
margin-top: 20px;
|
198 |
+
margin-bottom: 30px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
}
|
200 |
+
|
201 |
+
.jetpack-tests-succed {
|
202 |
+
font-size: large;
|
203 |
+
color: #8BAB3E;
|
204 |
}
|
205 |
+
|
206 |
+
.jetpack-test-details {
|
207 |
+
margin: 4px 6px;
|
208 |
+
padding: 10px;
|
209 |
+
overflow: auto;
|
210 |
+
display: none;
|
211 |
}
|
212 |
+
|
213 |
+
.jetpack-test-error {
|
214 |
+
margin-bottom: 10px;
|
215 |
+
background: #FFEBE8;
|
216 |
+
border: solid 1px #C00;
|
217 |
+
border-radius: 3px;
|
218 |
+
}
|
219 |
+
|
220 |
+
.jetpack-test-error p {
|
221 |
+
margin: 0;
|
222 |
+
padding: 0;
|
223 |
+
}
|
224 |
+
|
225 |
+
.jetpack-test-error a.jetpack-test-heading {
|
226 |
+
padding: 4px 6px;
|
227 |
+
display: block;
|
228 |
+
text-decoration: none;
|
229 |
+
color: inherit;
|
230 |
+
}
|
231 |
+
|
232 |
+
.jetpack-test-error .noticon {
|
233 |
+
float: right;
|
234 |
+
}
|
235 |
+
|
236 |
+
form#contactme {
|
237 |
+
border: 1px solid #dfdfdf;
|
238 |
+
background: #eaf3fa;
|
239 |
+
padding: 20px;
|
240 |
+
margin: 10px;
|
241 |
+
background-color: #eaf3fa;
|
242 |
+
border-radius: 5px;
|
243 |
+
font-size: 15px;
|
244 |
+
font-family: "Open Sans", "Helvetica Neue", sans-serif;
|
245 |
+
}
|
246 |
+
|
247 |
+
form#contactme label.h {
|
248 |
+
color: #444;
|
249 |
+
display: block;
|
250 |
+
font-weight: bold;
|
251 |
+
margin: 0 0 7px 10px;
|
252 |
+
text-shadow: 1px 1px 0 #fff;
|
253 |
+
}
|
254 |
+
|
255 |
+
.formbox {
|
256 |
+
margin: 0 0 25px 0;
|
257 |
+
}
|
258 |
+
|
259 |
+
.formbox input[type="text"], .formbox input[type="email"], .formbox input[type="url"], .formbox textarea {
|
260 |
+
border: 1px solid #e5e5e5;
|
261 |
+
border-radius: 11px;
|
262 |
+
box-shadow: inset 0 1px 1px rgba(0,0,0,0.1);
|
263 |
+
color: #666;
|
264 |
+
font-size: 14px;
|
265 |
+
padding: 10px;
|
266 |
+
width: 97%;
|
267 |
+
}
|
268 |
+
.formbox .contact-support input[type="submit"] {
|
269 |
+
float: right;
|
270 |
+
margin: 0 !important;
|
271 |
+
border-radius: 20px !important;
|
272 |
+
cursor: pointer;
|
273 |
+
font-size: 13pt !important;
|
274 |
+
height: auto !important;
|
275 |
+
margin: 0 0 2em 10px !important;
|
276 |
+
padding: 8px 16px !important;
|
277 |
+
background-color: #ddd;
|
278 |
+
border: 1px solid rgba(0,0,0,0.05);
|
279 |
+
border-top-color: rgba(255,255,255,0.1);
|
280 |
+
border-bottom-color: rgba(0,0,0,0.15);
|
281 |
+
color: #333;
|
282 |
+
font-weight: 400;
|
283 |
+
display: inline-block;
|
284 |
+
text-align: center;
|
285 |
+
text-decoration: none;
|
286 |
+
}
|
287 |
+
|
288 |
+
.formbox span.errormsg {
|
289 |
+
margin: 0 0 10px 10px;
|
290 |
+
color: #d00;
|
291 |
+
display: none;
|
292 |
+
}
|
293 |
+
|
294 |
+
.formbox.error span.errormsg {
|
295 |
+
display: block;
|
296 |
+
}
|
297 |
+
|
298 |
+
#contact-message ul {
|
299 |
+
margin: 0 0 20px 10px;
|
300 |
+
}
|
301 |
+
|
302 |
+
#contact-message li {
|
303 |
+
margin: 0 0 10px 10px;
|
304 |
+
list-style: disc;
|
305 |
+
display: list-item;
|
306 |
+
}
|
307 |
+
|
308 |
+
</style>
|
309 |
+
<script type="text/javascript">
|
310 |
+
jQuery( document ).ready( function($) {
|
311 |
+
|
312 |
+
$('#debug_info').prepend('jQuery version: ' + jQuery.fn.jquery + "\r\n");
|
313 |
+
|
314 |
+
$( '.jetpack-test-error .jetpack-test-heading' ).on( 'click', function() {
|
315 |
+
$( this ).parents( '.jetpack-test-error' ).find( '.jetpack-test-details' ).slideToggle();
|
316 |
+
return false;
|
317 |
+
} );
|
318 |
+
|
319 |
+
$( '.jetpack-show-contact-form a' ).on( 'click', function() {
|
320 |
+
$('#contact-message').slideToggle();
|
321 |
+
return false;
|
322 |
+
} );
|
323 |
+
|
324 |
+
$( '#toggle_debug_info a' ).on( 'click', function() {
|
325 |
+
$('#debug_info_div').slideToggle();
|
326 |
+
return false;
|
327 |
+
} );
|
328 |
+
|
329 |
+
$('form#contactme').on("submit", function(e){
|
330 |
+
var form = $(this);
|
331 |
+
var message = form.find('#did');
|
332 |
+
var name = form.find('#your_name');
|
333 |
+
var email = form.find('#your_email')
|
334 |
+
var validation_error = false;
|
335 |
+
if( !name.val() ) {
|
336 |
+
name.parents('.formbox').addClass('error');
|
337 |
+
validation_error = true;
|
338 |
+
}
|
339 |
+
if( !email.val() ) {
|
340 |
+
email.parents('.formbox').addClass('error');
|
341 |
+
validation_error = true;
|
342 |
+
}
|
343 |
+
if ( validation_error ) {
|
344 |
+
return false;
|
345 |
+
}
|
346 |
+
message.val(message.val() + "\r\n\r\n----------------------------------------------\r\n\r\nDEBUG INFO:\r\n" + $('#debug_info').val() );
|
347 |
+
return true;
|
348 |
+
});
|
349 |
+
|
350 |
+
} );
|
351 |
+
</script>
|
352 |
+
<?php
|
353 |
+
}
|
354 |
+
}
|
class.jetpack-heartbeat.php
CHANGED
@@ -73,7 +73,7 @@ class Jetpack_Heartbeat {
|
|
73 |
|
74 |
$jetpack = Jetpack::init();
|
75 |
|
76 |
-
$jetpack->stat( 'active-modules', implode( ',', $
|
77 |
$jetpack->stat( 'active', JETPACK__VERSION );
|
78 |
$jetpack->stat( 'wp-version', get_bloginfo( 'version' ) );
|
79 |
$jetpack->stat( 'php-version', PHP_VERSION );
|
@@ -108,14 +108,14 @@ class Jetpack_Heartbeat {
|
|
108 |
public function add_cron_intervals( $schedules ) {
|
109 |
$schedules['jetpack_weekly'] = array(
|
110 |
'interval' => WEEK_IN_SECONDS,
|
111 |
-
'display' => __('Jetpack weekly')
|
112 |
);
|
113 |
return $schedules;
|
114 |
}
|
115 |
|
116 |
public function deactivate() {
|
117 |
$timestamp = wp_next_scheduled( $this->cron_name );
|
118 |
-
wp_unschedule_event($timestamp, $this->cron_name );
|
119 |
}
|
120 |
|
121 |
}
|
73 |
|
74 |
$jetpack = Jetpack::init();
|
75 |
|
76 |
+
$jetpack->stat( 'active-modules', implode( ',', $jetpack->get_active_modules() ) );
|
77 |
$jetpack->stat( 'active', JETPACK__VERSION );
|
78 |
$jetpack->stat( 'wp-version', get_bloginfo( 'version' ) );
|
79 |
$jetpack->stat( 'php-version', PHP_VERSION );
|
108 |
public function add_cron_intervals( $schedules ) {
|
109 |
$schedules['jetpack_weekly'] = array(
|
110 |
'interval' => WEEK_IN_SECONDS,
|
111 |
+
'display' => __( 'Jetpack weekly', 'jetpack' ),
|
112 |
);
|
113 |
return $schedules;
|
114 |
}
|
115 |
|
116 |
public function deactivate() {
|
117 |
$timestamp = wp_next_scheduled( $this->cron_name );
|
118 |
+
wp_unschedule_event( $timestamp, $this->cron_name );
|
119 |
}
|
120 |
|
121 |
}
|
class.jetpack-options.php
CHANGED
@@ -13,6 +13,7 @@ class Jetpack_Options {
|
|
13 |
'do_activate',
|
14 |
'publicize',
|
15 |
'widget_twitter',
|
|
|
16 |
);
|
17 |
}
|
18 |
|
13 |
'do_activate',
|
14 |
'publicize',
|
15 |
'widget_twitter',
|
16 |
+
'wpcc_options',
|
17 |
);
|
18 |
}
|
19 |
|
class.jetpack.php
CHANGED
@@ -37,6 +37,7 @@ class Jetpack {
|
|
37 |
'after-the-deadline' => array( 'after-the-deadline/after-the-deadline.php', 'After The Deadline' ),
|
38 |
'contact-form' => array( 'grunion-contact-form/grunion-contact-form.php', 'Grunion Contact Form' ),
|
39 |
'custom-css' => array( 'safecss/safecss.php', 'WordPress.com Custom CSS' ),
|
|
|
40 |
);
|
41 |
|
42 |
var $capability_translations = array(
|
@@ -85,7 +86,7 @@ class Jetpack {
|
|
85 |
/**
|
86 |
* Holds the singleton instance of this class
|
87 |
* @since 2.3.3
|
88 |
-
* @var Jetpack
|
89 |
*/
|
90 |
static $instance = false;
|
91 |
|
@@ -162,7 +163,7 @@ class Jetpack {
|
|
162 |
|
163 |
// Modules should do Jetpack_Sync::sync_options( __FILE__, $option, ... ); instead
|
164 |
// We access the "internal" method here only because the Jetpack object isn't instantiated yet
|
165 |
-
$this->sync->options(
|
166 |
'home',
|
167 |
'siteurl',
|
168 |
'blogname',
|
@@ -173,7 +174,7 @@ class Jetpack {
|
|
173 |
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && isset( $_GET['for'] ) && 'jetpack' == $_GET['for'] ) {
|
174 |
@ini_set( 'display_errors', false ); // Display errors can cause the XML to be not well formed.
|
175 |
|
176 |
-
require_once
|
177 |
$this->xmlrpc_server = new Jetpack_XMLRPC_Server();
|
178 |
|
179 |
$this->require_jetpack_authentication();
|
@@ -448,7 +449,7 @@ class Jetpack {
|
|
448 |
do_action( 'jetpack_modules_loaded' );
|
449 |
|
450 |
// Load module-specific code that is needed even when a module isn't active. Loaded here because code contained therein may need actions such as setup_theme.
|
451 |
-
require_once(
|
452 |
}
|
453 |
|
454 |
/**
|
@@ -460,7 +461,7 @@ class Jetpack {
|
|
460 |
$_jetpack_rest_api_compat_includes = apply_filters( 'jetpack_rest_api_compat', array() );
|
461 |
|
462 |
if ( function_exists( 'bbpress' ) )
|
463 |
-
$_jetpack_rest_api_compat_includes[] =
|
464 |
|
465 |
foreach ( $_jetpack_rest_api_compat_includes as $_jetpack_rest_api_compat_include )
|
466 |
require_once $_jetpack_rest_api_compat_include;
|
@@ -490,28 +491,35 @@ class Jetpack {
|
|
490 |
}
|
491 |
|
492 |
$conflicting_plugins = array(
|
493 |
-
'facebook/facebook.php',
|
494 |
-
'wordpress-seo/wp-seo.php',
|
495 |
-
'add-link-to-facebook/add-link-to-facebook.php',
|
496 |
-
'facebook-awd/AWD_facebook.php',
|
497 |
-
'header-footer/plugin.php',
|
498 |
-
'nextgen-facebook/nextgen-facebook.php',
|
499 |
-
'seo-facebook-comments/seofacebook.php',
|
500 |
-
'seo-ultimate/seo-ultimate.php',
|
501 |
-
'sexybookmarks/sexy-bookmarks.php',
|
502 |
-
'shareaholic/sexy-bookmarks.php',
|
503 |
-
'social-discussions/social-discussions.php',
|
504 |
-
'social-networks-auto-poster-facebook-twitter-g/NextScripts_SNAP.php',
|
505 |
-
'wordbooker/wordbooker.php',
|
506 |
-
'socialize/socialize.php',
|
507 |
-
'simple-facebook-connect/sfc.php',
|
508 |
-
'social-sharing-toolkit/social_sharing_toolkit.php',
|
509 |
-
'wp-facebook-open-graph-protocol/wp-facebook-ogp.php',
|
510 |
-
'opengraph/opengraph.php',
|
511 |
-
'sharepress/sharepress.php',
|
512 |
-
'wp-facebook-like-send-open-graph-meta/wp-facebook-like-send-open-graph-meta.php',
|
513 |
-
'network-publisher/networkpub.php',
|
514 |
-
'wp-ogp/wp-ogp.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
515 |
);
|
516 |
|
517 |
foreach ( $conflicting_plugins as $plugin ) {
|
@@ -522,7 +530,7 @@ class Jetpack {
|
|
522 |
}
|
523 |
|
524 |
if ( apply_filters( 'jetpack_enable_open_graph', false ) )
|
525 |
-
require_once
|
526 |
}
|
527 |
|
528 |
/* Jetpack Options API */
|
@@ -701,7 +709,7 @@ class Jetpack {
|
|
701 |
static $modules = null;
|
702 |
|
703 |
if ( !isset( $modules ) ) {
|
704 |
-
$files = Jetpack::glob_php(
|
705 |
|
706 |
$modules = array();
|
707 |
|
@@ -714,6 +722,8 @@ class Jetpack {
|
|
714 |
}
|
715 |
}
|
716 |
|
|
|
|
|
717 |
if ( !$min_version && !$max_version ) {
|
718 |
return array_keys( $modules );
|
719 |
}
|
@@ -741,33 +751,25 @@ class Jetpack {
|
|
741 |
$return = array();
|
742 |
|
743 |
foreach ( Jetpack::get_available_modules( $min_version, $max_version ) as $module ) {
|
744 |
-
|
745 |
-
switch ( $module ) {
|
746 |
-
|
747 |
-
// These modules are default off: they change things blog-side
|
748 |
-
case 'comments' :
|
749 |
-
case 'carousel' :
|
750 |
-
case 'minileven':
|
751 |
-
case 'infinite-scroll' :
|
752 |
-
case 'photon' :
|
753 |
-
case 'tiled-gallery' :
|
754 |
-
case 'likes' :
|
755 |
-
break;
|
756 |
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
761 |
break;
|
762 |
-
}
|
763 |
-
// else no break
|
764 |
-
// The rest are default on
|
765 |
-
default :
|
766 |
-
$return[] = $module;
|
767 |
}
|
|
|
768 |
}
|
769 |
|
770 |
-
return $return;
|
771 |
}
|
772 |
|
773 |
/**
|
@@ -781,7 +783,7 @@ class Jetpack {
|
|
781 |
* Generate a module's path from its slug.
|
782 |
*/
|
783 |
public static function get_module_path( $slug ) {
|
784 |
-
return
|
785 |
}
|
786 |
|
787 |
/**
|
@@ -799,6 +801,7 @@ class Jetpack {
|
|
799 |
'deactivate' => 'Deactivate',
|
800 |
'free' => 'Free',
|
801 |
'requires_connection' => 'Requires Connection',
|
|
|
802 |
);
|
803 |
|
804 |
$file = Jetpack::get_module_path( Jetpack::get_module_slug( $module ) );
|
@@ -816,6 +819,13 @@ class Jetpack {
|
|
816 |
$mod['deactivate'] = empty( $mod['deactivate'] );
|
817 |
$mod['free'] = empty( $mod['free'] );
|
818 |
$mod['requires_connection'] = ( ! empty( $mod['requires_connection'] ) && 'No' == $mod['requires_connection'] ) ? false : true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
819 |
return $mod;
|
820 |
}
|
821 |
|
@@ -988,7 +998,7 @@ class Jetpack {
|
|
988 |
|
989 |
$module_data = Jetpack::get_module( $module );
|
990 |
|
991 |
-
if ( ! Jetpack::is_active() ) {
|
992 |
if ( ! Jetpack::is_development_mode() )
|
993 |
return false;
|
994 |
|
@@ -1101,7 +1111,7 @@ p {
|
|
1101 |
<?php
|
1102 |
if ( $deactivate ) {
|
1103 |
$plugins = get_option( 'active_plugins' );
|
1104 |
-
$jetpack = plugin_basename(
|
1105 |
$update = false;
|
1106 |
foreach ( $plugins as $i => $plugin ) {
|
1107 |
if ( $plugin === $jetpack ) {
|
@@ -1273,7 +1283,7 @@ p {
|
|
1273 |
|
1274 |
add_action( 'load-plugins.php', array( $this, 'intercept_plugin_error_scrape_init' ) );
|
1275 |
add_action( 'admin_head', array( $this, 'admin_menu_css' ) );
|
1276 |
-
add_filter( 'plugin_action_links_' . plugin_basename(
|
1277 |
|
1278 |
if ( Jetpack::is_active() || Jetpack::is_development_mode() ) {
|
1279 |
// Artificially throw errors in certain whitelisted cases during plugin activation
|
@@ -1372,10 +1382,9 @@ p {
|
|
1372 |
}
|
1373 |
|
1374 |
$hook = add_menu_page( 'Jetpack', $title, 'read', 'jetpack', array( $this, 'admin_page' ), 'div' );
|
1375 |
-
|
1376 |
-
$debugger_hook = add_submenu_page( 'jetpack', 'Jetpack Debugging Center', '', 'manage_options', 'jetpack-debugger', array( $this, 'debugger_page' ) );
|
1377 |
-
add_action( "admin_head-$debugger_hook", 'jetpack_debug_admin_head' );
|
1378 |
|
|
|
|
|
1379 |
|
1380 |
add_action( "load-$hook", array( $this, 'admin_page_load' ) );
|
1381 |
|
@@ -1404,7 +1413,7 @@ p {
|
|
1404 |
add_action( "load-$hook", array( $this, 'admin_help' ) );
|
1405 |
add_action( "admin_head-$hook", array( $this, 'admin_head' ) );
|
1406 |
add_action( "admin_print_styles-$hook", array( $this, 'admin_styles' ) );
|
1407 |
-
add_action( "admin_print_scripts-$hook", array( $this, 'admin_scripts' ) );
|
1408 |
}
|
1409 |
/**/
|
1410 |
function add_remote_request_handlers() {
|
@@ -1585,7 +1594,7 @@ p {
|
|
1585 |
'<p><strong>' . __( 'For more information:', 'jetpack' ) . '</strong></p>' .
|
1586 |
'<p><a href="http://jetpack.me/faq/" target="_blank">' . __( 'Jetpack FAQ', 'jetpack' ) . '</a></p>' .
|
1587 |
'<p><a href="http://jetpack.me/support/" target="_blank">' . __( 'Jetpack Support', 'jetpack' ) . '</a></p>' .
|
1588 |
-
'<p><a href="' . Jetpack::admin_url( array( 'page' => 'jetpack-debugger' ) ) .'">' . __( 'Jetpack Debugging Center', 'jetpack' ) . '</a></p>'
|
1589 |
|
1590 |
);
|
1591 |
}
|
@@ -1593,12 +1602,12 @@ p {
|
|
1593 |
function admin_menu_css() { ?>
|
1594 |
<style type="text/css" id="jetpack-menu-css">
|
1595 |
#toplevel_page_jetpack .wp-menu-image {
|
1596 |
-
background: url( <?php echo plugins_url(
|
1597 |
}
|
1598 |
/* Retina Jetpack Menu Icon */
|
1599 |
@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
|
1600 |
#toplevel_page_jetpack .wp-menu-image {
|
1601 |
-
background: url( <?php echo plugins_url(
|
1602 |
background-size:30px 64px;
|
1603 |
}
|
1604 |
}
|
@@ -1635,12 +1644,12 @@ p {
|
|
1635 |
|
1636 |
function admin_styles() {
|
1637 |
global $wp_styles;
|
1638 |
-
wp_enqueue_style( 'jetpack', plugins_url(
|
1639 |
$wp_styles->add_data( 'jetpack', 'rtl', true );
|
1640 |
}
|
1641 |
|
1642 |
function admin_scripts() {
|
1643 |
-
wp_enqueue_script( 'jetpack-js', plugins_url(
|
1644 |
wp_localize_script( 'jetpack-js', 'jetpackL10n', array(
|
1645 |
'ays_disconnect' => "This will deactivate all Jetpack modules.\nAre you sure you want to disconnect?",
|
1646 |
'ays_unlink' => "This will prevent user-specific modules such as Publicize, Notifications and Post By Email from working.\nAre you sure you want to unlink?",
|
@@ -1666,7 +1675,7 @@ p {
|
|
1666 |
return;
|
1667 |
?>
|
1668 |
|
1669 |
-
<div id="message" class="updated jetpack-message jp-connect">
|
1670 |
<div id="jp-dismiss" class="jetpack-close-button-container">
|
1671 |
<a class="jetpack-close-button" href="?page=jetpack&jetpack-notice=dismiss" title="<?php _e( 'Dismiss this notice and deactivate Jetpack.', 'jetpack' ); ?>"><?php _e( 'Dismiss this notice and deactivate Jetpack.', 'jetpack' ); ?></a>
|
1672 |
</div>
|
@@ -2371,10 +2380,10 @@ p {
|
|
2371 |
}
|
2372 |
|
2373 |
function dismiss_jetpack_notice() {
|
2374 |
-
if ( isset( $_GET['jetpack-notice'] ) && 'dismiss' == $_GET['jetpack-notice'] && ! is_plugin_active_for_network( plugin_basename(
|
2375 |
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
2376 |
|
2377 |
-
deactivate_plugins(
|
2378 |
|
2379 |
wp_safe_redirect( admin_url() . 'plugins.php?deactivate=true&plugin_status=all&paged=1&s=' );
|
2380 |
exit;
|
@@ -2434,7 +2443,7 @@ p {
|
|
2434 |
?>
|
2435 |
<?php if ( ! $is_connected ) : ?>
|
2436 |
|
2437 |
-
<div id="message" class="updated jetpack-message jp-connect">
|
2438 |
<div id="jp-dismiss" class="jetpack-close-button-container">
|
2439 |
<a class="jetpack-close-button" href="?page=jetpack&jetpack-notice=dismiss" title="<?php _e( 'Dismiss this notice.', 'jetpack' ); ?>"><?php _e( 'Dismiss this notice.', 'jetpack' ); ?></a>
|
2440 |
</div>
|
@@ -2452,7 +2461,7 @@ p {
|
|
2452 |
|
2453 |
<?php elseif ( ! $is_user_connected ) : ?>
|
2454 |
|
2455 |
-
<div id="message" class="updated jetpack-message jp-connect">
|
2456 |
<div class="jetpack-wrap-container">
|
2457 |
<div class="jetpack-text-container">
|
2458 |
<h4>
|
@@ -2650,7 +2659,7 @@ p {
|
|
2650 |
if ( !current_user_can( 'manage_options' ) ) {
|
2651 |
die( '-1' );
|
2652 |
}
|
2653 |
-
jetpack_debug_display_handler();
|
2654 |
exit;
|
2655 |
}
|
2656 |
|
@@ -2679,7 +2688,7 @@ p {
|
|
2679 |
}
|
2680 |
|
2681 |
function admin_screen_list_modules() {
|
2682 |
-
require_once
|
2683 |
$jetpack_connected = true;
|
2684 |
if ( !Jetpack::is_active() )
|
2685 |
$jetpack_connected = false;
|
@@ -2912,9 +2921,9 @@ p {
|
|
2912 |
|
2913 |
/**
|
2914 |
* Checks to see if the URL is using SSL to connect with Jetpack
|
2915 |
-
*
|
2916 |
* @since 2.3.3
|
2917 |
-
* @return boolean
|
2918 |
*/
|
2919 |
public static function permit_ssl( $force_recheck = false ) {
|
2920 |
// Do some fancy tests to see if ssl is being supported
|
@@ -2934,7 +2943,7 @@ p {
|
|
2934 |
break;
|
2935 |
}
|
2936 |
|
2937 |
-
// If it's not 'NEVER', test to see
|
2938 |
if ( $ssl ) {
|
2939 |
$response = wp_remote_get( JETPACK__API_BASE . 'test/1/' );
|
2940 |
if ( is_wp_error( $response ) || ( 'OK' !== wp_remote_retrieve_body( $response ) ) ) {
|
@@ -3088,7 +3097,7 @@ p {
|
|
3088 |
*/
|
3089 |
public static function load_xml_rpc_client() {
|
3090 |
require_once ABSPATH . WPINC . '/class-IXR.php';
|
3091 |
-
require_once
|
3092 |
}
|
3093 |
|
3094 |
function verify_xml_rpc_signature() {
|
@@ -3135,7 +3144,7 @@ p {
|
|
3135 |
return false;
|
3136 |
}
|
3137 |
|
3138 |
-
require_once
|
3139 |
|
3140 |
$jetpack_signature = new Jetpack_Signature( $token->secret, (int) Jetpack::get_option( 'time_diff' ) );
|
3141 |
if ( isset( $_POST['_jetpack_is_multipart'] ) ) {
|
@@ -3503,7 +3512,7 @@ p {
|
|
3503 |
|
3504 |
// Verifies the request by checking the signature
|
3505 |
function verify_json_api_authorization_request() {
|
3506 |
-
require_once
|
3507 |
|
3508 |
$token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
|
3509 |
if ( !$token || empty( $token->secret ) ) {
|
@@ -3587,7 +3596,8 @@ p {
|
|
3587 |
* Get $content_width, but with a <s>twist</s> filter.
|
3588 |
*/
|
3589 |
public static function get_content_width() {
|
3590 |
-
|
|
|
3591 |
}
|
3592 |
|
3593 |
/**
|
@@ -3597,7 +3607,7 @@ p {
|
|
3597 |
* @param int $size Size of the avatar image
|
3598 |
* @param string $default URL to a default image to use if no avatar is available
|
3599 |
* @param bool $force_display Whether to force it to return an avatar even if show_avatars is disabled
|
3600 |
-
*
|
3601 |
* @return array First element is the URL, second is the class.
|
3602 |
*/
|
3603 |
public static function get_avatar_url( $id_or_email, $size = 96, $default = '', $force_display = false ) {
|
37 |
'after-the-deadline' => array( 'after-the-deadline/after-the-deadline.php', 'After The Deadline' ),
|
38 |
'contact-form' => array( 'grunion-contact-form/grunion-contact-form.php', 'Grunion Contact Form' ),
|
39 |
'custom-css' => array( 'safecss/safecss.php', 'WordPress.com Custom CSS' ),
|
40 |
+
'random-redirect' => array( 'random-redirect/random-redirect.php', 'Random Redirect' ),
|
41 |
);
|
42 |
|
43 |
var $capability_translations = array(
|
86 |
/**
|
87 |
* Holds the singleton instance of this class
|
88 |
* @since 2.3.3
|
89 |
+
* @var Jetpack
|
90 |
*/
|
91 |
static $instance = false;
|
92 |
|
163 |
|
164 |
// Modules should do Jetpack_Sync::sync_options( __FILE__, $option, ... ); instead
|
165 |
// We access the "internal" method here only because the Jetpack object isn't instantiated yet
|
166 |
+
$this->sync->options( JETPACK__PLUGIN_DIR . 'jetpack.php',
|
167 |
'home',
|
168 |
'siteurl',
|
169 |
'blogname',
|
174 |
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && isset( $_GET['for'] ) && 'jetpack' == $_GET['for'] ) {
|
175 |
@ini_set( 'display_errors', false ); // Display errors can cause the XML to be not well formed.
|
176 |
|
177 |
+
require_once JETPACK__PLUGIN_DIR . 'class.jetpack-xmlrpc-server.php';
|
178 |
$this->xmlrpc_server = new Jetpack_XMLRPC_Server();
|
179 |
|
180 |
$this->require_jetpack_authentication();
|
449 |
do_action( 'jetpack_modules_loaded' );
|
450 |
|
451 |
// Load module-specific code that is needed even when a module isn't active. Loaded here because code contained therein may need actions such as setup_theme.
|
452 |
+
require_once( JETPACK__PLUGIN_DIR . 'modules/module-extras.php' );
|
453 |
}
|
454 |
|
455 |
/**
|
461 |
$_jetpack_rest_api_compat_includes = apply_filters( 'jetpack_rest_api_compat', array() );
|
462 |
|
463 |
if ( function_exists( 'bbpress' ) )
|
464 |
+
$_jetpack_rest_api_compat_includes[] = JETPACK__PLUGIN_DIR . 'class.jetpack-bbpress-json-api-compat.php';
|
465 |
|
466 |
foreach ( $_jetpack_rest_api_compat_includes as $_jetpack_rest_api_compat_include )
|
467 |
require_once $_jetpack_rest_api_compat_include;
|
491 |
}
|
492 |
|
493 |
$conflicting_plugins = array(
|
494 |
+
'facebook/facebook.php', // Official Facebook plugin
|
495 |
+
'wordpress-seo/wp-seo.php', // WordPress SEO by Yoast
|
496 |
+
'add-link-to-facebook/add-link-to-facebook.php', // Add Link to Facebook
|
497 |
+
'facebook-awd/AWD_facebook.php', // Facebook AWD All in one
|
498 |
+
'header-footer/plugin.php', // Header and Footer
|
499 |
+
'nextgen-facebook/nextgen-facebook.php', // NextGEN Facebook OG
|
500 |
+
'seo-facebook-comments/seofacebook.php', // SEO Facebook Comments
|
501 |
+
'seo-ultimate/seo-ultimate.php', // SEO Ultimate
|
502 |
+
'sexybookmarks/sexy-bookmarks.php', // Shareaholic
|
503 |
+
'shareaholic/sexy-bookmarks.php', // Shareaholic
|
504 |
+
'social-discussions/social-discussions.php', // Social Discussions
|
505 |
+
'social-networks-auto-poster-facebook-twitter-g/NextScripts_SNAP.php', // NextScripts SNAP
|
506 |
+
'wordbooker/wordbooker.php', // Wordbooker
|
507 |
+
'socialize/socialize.php', // Socialize
|
508 |
+
'simple-facebook-connect/sfc.php', // Simple Facebook Connect
|
509 |
+
'social-sharing-toolkit/social_sharing_toolkit.php', // Social Sharing Toolkit
|
510 |
+
'wp-facebook-open-graph-protocol/wp-facebook-ogp.php', // WP Facebook Open Graph protocol
|
511 |
+
'opengraph/opengraph.php', // Open Graph
|
512 |
+
'sharepress/sharepress.php', // SharePress
|
513 |
+
'wp-facebook-like-send-open-graph-meta/wp-facebook-like-send-open-graph-meta.php', // WP Facebook Like Send & Open Graph Meta
|
514 |
+
'network-publisher/networkpub.php', // Network Publisher
|
515 |
+
'wp-ogp/wp-ogp.php', // WP-OGP
|
516 |
+
'twitter-cards/twitter-cards.php', // Twitter Cards
|
517 |
+
'twitter-cards-meta/twitter-cards-meta.php', // Twitter Cards Meta
|
518 |
+
'ig-twitter-cards/ig-twitter-cards.php', // IG:Twitter Cards
|
519 |
+
'kevinjohn-gallagher-pure-web-brilliants-social-graph-twitter-cards-extention/kevinjohn_gallagher___social_graph_twitter_output.php', // Pure Web Brilliant's Social Graph Twitter Cards Extention
|
520 |
+
'jm-twitter-cards/jm-twitter-cards.php', // JM Twitter Cards
|
521 |
+
'wp-twitter-cards/twitter_cards.php', // WP Twitter Cards
|
522 |
+
'eewee-twitter-card/index.php', // eewee twitter card
|
523 |
);
|
524 |
|
525 |
foreach ( $conflicting_plugins as $plugin ) {
|
530 |
}
|
531 |
|
532 |
if ( apply_filters( 'jetpack_enable_open_graph', false ) )
|
533 |
+
require_once JETPACK__PLUGIN_DIR . 'functions.opengraph.php';
|
534 |
}
|
535 |
|
536 |
/* Jetpack Options API */
|
709 |
static $modules = null;
|
710 |
|
711 |
if ( !isset( $modules ) ) {
|
712 |
+
$files = Jetpack::glob_php( JETPACK__PLUGIN_DIR . 'modules' );
|
713 |
|
714 |
$modules = array();
|
715 |
|
722 |
}
|
723 |
}
|
724 |
|
725 |
+
$modules = apply_filters( 'jetpack_get_available_modules', $modules, $min_version, $max_version );
|
726 |
+
|
727 |
if ( !$min_version && !$max_version ) {
|
728 |
return array_keys( $modules );
|
729 |
}
|
751 |
$return = array();
|
752 |
|
753 |
foreach ( Jetpack::get_available_modules( $min_version, $max_version ) as $module ) {
|
754 |
+
$module_data = Jetpack::get_module( $module );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
755 |
|
756 |
+
switch ( strtolower( $module_data['auto_activate'] ) ) {
|
757 |
+
case 'yes' :
|
758 |
+
$return[] = $module;
|
759 |
+
break;
|
760 |
+
case 'public' :
|
761 |
+
if ( Jetpack::get_option( 'public' ) ) {
|
762 |
+
$return[] = $module;
|
763 |
+
}
|
764 |
+
break;
|
765 |
+
case 'no' :
|
766 |
+
default :
|
767 |
break;
|
|
|
|
|
|
|
|
|
|
|
768 |
}
|
769 |
+
|
770 |
}
|
771 |
|
772 |
+
return apply_filters( 'jetpack_get_default_modules', $return, $min_version, $max_version );
|
773 |
}
|
774 |
|
775 |
/**
|
783 |
* Generate a module's path from its slug.
|
784 |
*/
|
785 |
public static function get_module_path( $slug ) {
|
786 |
+
return JETPACK__PLUGIN_DIR . "modules/$slug.php";
|
787 |
}
|
788 |
|
789 |
/**
|
801 |
'deactivate' => 'Deactivate',
|
802 |
'free' => 'Free',
|
803 |
'requires_connection' => 'Requires Connection',
|
804 |
+
'auto_activate' => 'Auto Activate',
|
805 |
);
|
806 |
|
807 |
$file = Jetpack::get_module_path( Jetpack::get_module_slug( $module ) );
|
819 |
$mod['deactivate'] = empty( $mod['deactivate'] );
|
820 |
$mod['free'] = empty( $mod['free'] );
|
821 |
$mod['requires_connection'] = ( ! empty( $mod['requires_connection'] ) && 'No' == $mod['requires_connection'] ) ? false : true;
|
822 |
+
|
823 |
+
if ( empty( $mod['auto_activate'] ) || ! in_array( strtolower( $mod['auto_activate'] ), array( 'yes', 'no', 'public' ) ) ) {
|
824 |
+
$mod['auto_activate'] = 'No';
|
825 |
+
} else {
|
826 |
+
$mod['auto_activate'] = (string) $mod['auto_activate'];
|
827 |
+
}
|
828 |
+
|
829 |
return $mod;
|
830 |
}
|
831 |
|
998 |
|
999 |
$module_data = Jetpack::get_module( $module );
|
1000 |
|
1001 |
+
if ( ! Jetpack::is_active() ) {
|
1002 |
if ( ! Jetpack::is_development_mode() )
|
1003 |
return false;
|
1004 |
|
1111 |
<?php
|
1112 |
if ( $deactivate ) {
|
1113 |
$plugins = get_option( 'active_plugins' );
|
1114 |
+
$jetpack = plugin_basename( JETPACK__PLUGIN_DIR . 'jetpack.php' );
|
1115 |
$update = false;
|
1116 |
foreach ( $plugins as $i => $plugin ) {
|
1117 |
if ( $plugin === $jetpack ) {
|
1283 |
|
1284 |
add_action( 'load-plugins.php', array( $this, 'intercept_plugin_error_scrape_init' ) );
|
1285 |
add_action( 'admin_head', array( $this, 'admin_menu_css' ) );
|
1286 |
+
add_filter( 'plugin_action_links_' . plugin_basename( JETPACK__PLUGIN_DIR . 'jetpack.php' ), array( $this, 'plugin_action_links' ) );
|
1287 |
|
1288 |
if ( Jetpack::is_active() || Jetpack::is_development_mode() ) {
|
1289 |
// Artificially throw errors in certain whitelisted cases during plugin activation
|
1382 |
}
|
1383 |
|
1384 |
$hook = add_menu_page( 'Jetpack', $title, 'read', 'jetpack', array( $this, 'admin_page' ), 'div' );
|
|
|
|
|
|
|
1385 |
|
1386 |
+
$debugger_hook = add_submenu_page( null, __( 'Jetpack Debugging Center', 'jetpack' ), '', 'manage_options', 'jetpack-debugger', array( $this, 'debugger_page' ) );
|
1387 |
+
add_action( "admin_head-$debugger_hook", array( 'Jetpack_Debugger', 'jetpack_debug_admin_head' ) );
|
1388 |
|
1389 |
add_action( "load-$hook", array( $this, 'admin_page_load' ) );
|
1390 |
|
1413 |
add_action( "load-$hook", array( $this, 'admin_help' ) );
|
1414 |
add_action( "admin_head-$hook", array( $this, 'admin_head' ) );
|
1415 |
add_action( "admin_print_styles-$hook", array( $this, 'admin_styles' ) );
|
1416 |
+
add_action( "admin_print_scripts-$hook", array( $this, 'admin_scripts' ) );
|
1417 |
}
|
1418 |
/**/
|
1419 |
function add_remote_request_handlers() {
|
1594 |
'<p><strong>' . __( 'For more information:', 'jetpack' ) . '</strong></p>' .
|
1595 |
'<p><a href="http://jetpack.me/faq/" target="_blank">' . __( 'Jetpack FAQ', 'jetpack' ) . '</a></p>' .
|
1596 |
'<p><a href="http://jetpack.me/support/" target="_blank">' . __( 'Jetpack Support', 'jetpack' ) . '</a></p>' .
|
1597 |
+
'<p><a href="' . Jetpack::admin_url( array( 'page' => 'jetpack-debugger' ) ) .'">' . __( 'Jetpack Debugging Center', 'jetpack' ) . '</a></p>'
|
1598 |
|
1599 |
);
|
1600 |
}
|
1602 |
function admin_menu_css() { ?>
|
1603 |
<style type="text/css" id="jetpack-menu-css">
|
1604 |
#toplevel_page_jetpack .wp-menu-image {
|
1605 |
+
background: url( <?php echo plugins_url( '_inc/images/menuicon-sprite.png', __FILE__ ) ?> ) 0 90% no-repeat;
|
1606 |
}
|
1607 |
/* Retina Jetpack Menu Icon */
|
1608 |
@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
|
1609 |
#toplevel_page_jetpack .wp-menu-image {
|
1610 |
+
background: url( <?php echo plugins_url( '_inc/images/menuicon-sprite-2x.png', __FILE__ ) ?> ) 0 90% no-repeat;
|
1611 |
background-size:30px 64px;
|
1612 |
}
|
1613 |
}
|
1644 |
|
1645 |
function admin_styles() {
|
1646 |
global $wp_styles;
|
1647 |
+
wp_enqueue_style( 'jetpack', plugins_url( '_inc/jetpack.css', __FILE__ ), false, JETPACK__VERSION . '-20121016' );
|
1648 |
$wp_styles->add_data( 'jetpack', 'rtl', true );
|
1649 |
}
|
1650 |
|
1651 |
function admin_scripts() {
|
1652 |
+
wp_enqueue_script( 'jetpack-js', plugins_url( '_inc/jetpack.js', __FILE__ ), array( 'jquery' ), JETPACK__VERSION . '-20121111' );
|
1653 |
wp_localize_script( 'jetpack-js', 'jetpackL10n', array(
|
1654 |
'ays_disconnect' => "This will deactivate all Jetpack modules.\nAre you sure you want to disconnect?",
|
1655 |
'ays_unlink' => "This will prevent user-specific modules such as Publicize, Notifications and Post By Email from working.\nAre you sure you want to unlink?",
|
1675 |
return;
|
1676 |
?>
|
1677 |
|
1678 |
+
<div id="message" class="updated jetpack-message jp-connect" style="display:block !important;">
|
1679 |
<div id="jp-dismiss" class="jetpack-close-button-container">
|
1680 |
<a class="jetpack-close-button" href="?page=jetpack&jetpack-notice=dismiss" title="<?php _e( 'Dismiss this notice and deactivate Jetpack.', 'jetpack' ); ?>"><?php _e( 'Dismiss this notice and deactivate Jetpack.', 'jetpack' ); ?></a>
|
1681 |
</div>
|
2380 |
}
|
2381 |
|
2382 |
function dismiss_jetpack_notice() {
|
2383 |
+
if ( isset( $_GET['jetpack-notice'] ) && 'dismiss' == $_GET['jetpack-notice'] && ! is_plugin_active_for_network( plugin_basename( JETPACK__PLUGIN_DIR . 'jetpack.php' ) ) ) {
|
2384 |
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
2385 |
|
2386 |
+
deactivate_plugins( JETPACK__PLUGIN_DIR . 'jetpack.php', false, false );
|
2387 |
|
2388 |
wp_safe_redirect( admin_url() . 'plugins.php?deactivate=true&plugin_status=all&paged=1&s=' );
|
2389 |
exit;
|
2443 |
?>
|
2444 |
<?php if ( ! $is_connected ) : ?>
|
2445 |
|
2446 |
+
<div id="message" class="updated jetpack-message jp-connect" style="display:block !important;">
|
2447 |
<div id="jp-dismiss" class="jetpack-close-button-container">
|
2448 |
<a class="jetpack-close-button" href="?page=jetpack&jetpack-notice=dismiss" title="<?php _e( 'Dismiss this notice.', 'jetpack' ); ?>"><?php _e( 'Dismiss this notice.', 'jetpack' ); ?></a>
|
2449 |
</div>
|
2461 |
|
2462 |
<?php elseif ( ! $is_user_connected ) : ?>
|
2463 |
|
2464 |
+
<div id="message" class="updated jetpack-message jp-connect" style="display:block !important;">
|
2465 |
<div class="jetpack-wrap-container">
|
2466 |
<div class="jetpack-text-container">
|
2467 |
<h4>
|
2659 |
if ( !current_user_can( 'manage_options' ) ) {
|
2660 |
die( '-1' );
|
2661 |
}
|
2662 |
+
Jetpack_Debugger::jetpack_debug_display_handler();
|
2663 |
exit;
|
2664 |
}
|
2665 |
|
2688 |
}
|
2689 |
|
2690 |
function admin_screen_list_modules() {
|
2691 |
+
require_once JETPACK__PLUGIN_DIR . 'modules/module-info.php';
|
2692 |
$jetpack_connected = true;
|
2693 |
if ( !Jetpack::is_active() )
|
2694 |
$jetpack_connected = false;
|
2921 |
|
2922 |
/**
|
2923 |
* Checks to see if the URL is using SSL to connect with Jetpack
|
2924 |
+
*
|
2925 |
* @since 2.3.3
|
2926 |
+
* @return boolean
|
2927 |
*/
|
2928 |
public static function permit_ssl( $force_recheck = false ) {
|
2929 |
// Do some fancy tests to see if ssl is being supported
|
2943 |
break;
|
2944 |
}
|
2945 |
|
2946 |
+
// If it's not 'NEVER', test to see
|
2947 |
if ( $ssl ) {
|
2948 |
$response = wp_remote_get( JETPACK__API_BASE . 'test/1/' );
|
2949 |
if ( is_wp_error( $response ) || ( 'OK' !== wp_remote_retrieve_body( $response ) ) ) {
|
3097 |
*/
|
3098 |
public static function load_xml_rpc_client() {
|
3099 |
require_once ABSPATH . WPINC . '/class-IXR.php';
|
3100 |
+
require_once JETPACK__PLUGIN_DIR . 'class.jetpack-ixr-client.php';
|
3101 |
}
|
3102 |
|
3103 |
function verify_xml_rpc_signature() {
|
3144 |
return false;
|
3145 |
}
|
3146 |
|
3147 |
+
require_once JETPACK__PLUGIN_DIR . 'class.jetpack-signature.php';
|
3148 |
|
3149 |
$jetpack_signature = new Jetpack_Signature( $token->secret, (int) Jetpack::get_option( 'time_diff' ) );
|
3150 |
if ( isset( $_POST['_jetpack_is_multipart'] ) ) {
|
3512 |
|
3513 |
// Verifies the request by checking the signature
|
3514 |
function verify_json_api_authorization_request() {
|
3515 |
+
require_once JETPACK__PLUGIN_DIR . 'class.jetpack-signature.php';
|
3516 |
|
3517 |
$token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
|
3518 |
if ( !$token || empty( $token->secret ) ) {
|
3596 |
* Get $content_width, but with a <s>twist</s> filter.
|
3597 |
*/
|
3598 |
public static function get_content_width() {
|
3599 |
+
$content_width = isset( $GLOBALS['content_width'] ) ? $GLOBALS['content_width'] : false;
|
3600 |
+
return apply_filters( 'jetpack_content_width', $content_width );
|
3601 |
}
|
3602 |
|
3603 |
/**
|
3607 |
* @param int $size Size of the avatar image
|
3608 |
* @param string $default URL to a default image to use if no avatar is available
|
3609 |
* @param bool $force_display Whether to force it to return an avatar even if show_avatars is disabled
|
3610 |
+
*
|
3611 |
* @return array First element is the URL, second is the class.
|
3612 |
*/
|
3613 |
public static function get_avatar_url( $id_or_email, $size = 96, $default = '', $force_display = false ) {
|
class.json-api-endpoints.php
CHANGED
@@ -880,6 +880,7 @@ EOPHP;
|
|
880 |
$name = $author->comment_author;
|
881 |
$URL = $author->comment_author_url;
|
882 |
$profile_URL = 'http://en.gravatar.com/' . md5( strtolower( trim( $email ) ) );
|
|
|
883 |
} else {
|
884 |
if ( isset( $author->post_author ) ) {
|
885 |
if ( 0 == $author->post_author )
|
@@ -902,6 +903,7 @@ EOPHP;
|
|
902 |
$email = $user->user_email;
|
903 |
$name = $user->display_name;
|
904 |
$URL = $user->user_url;
|
|
|
905 |
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
906 |
$profile_URL = "http://en.gravatar.com/{$user->user_login}";
|
907 |
} else {
|
@@ -917,6 +919,7 @@ EOPHP;
|
|
917 |
'ID' => (int) $ID,
|
918 |
'email' => $email, // (string|bool)
|
919 |
'name' => (string) $name,
|
|
|
920 |
'URL' => (string) esc_url_raw( $URL ),
|
921 |
'avatar_URL' => (string) esc_url_raw( $avatar_URL ),
|
922 |
'profile_URL' => (string) esc_url_raw( $profile_URL ),
|
@@ -2230,7 +2233,11 @@ class WPCOM_JSON_API_Update_Taxonomy_Endpoint extends WPCOM_JSON_API_Taxonomy_En
|
|
2230 |
)
|
2231 |
);
|
2232 |
|
|
|
|
|
|
|
2233 |
$taxonomy = get_term_by( 'id', $data['term_id'], $taxonomy_type );
|
|
|
2234 |
$return = $this->get_taxonomy( $taxonomy->slug, $taxonomy_type, $args['context'] );
|
2235 |
if ( !$return || is_wp_error( $return ) ) {
|
2236 |
return $return;
|
880 |
$name = $author->comment_author;
|
881 |
$URL = $author->comment_author_url;
|
882 |
$profile_URL = 'http://en.gravatar.com/' . md5( strtolower( trim( $email ) ) );
|
883 |
+
$nice = '';
|
884 |
} else {
|
885 |
if ( isset( $author->post_author ) ) {
|
886 |
if ( 0 == $author->post_author )
|
903 |
$email = $user->user_email;
|
904 |
$name = $user->display_name;
|
905 |
$URL = $user->user_url;
|
906 |
+
$nice = $user->user_nicename;
|
907 |
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
908 |
$profile_URL = "http://en.gravatar.com/{$user->user_login}";
|
909 |
} else {
|
919 |
'ID' => (int) $ID,
|
920 |
'email' => $email, // (string|bool)
|
921 |
'name' => (string) $name,
|
922 |
+
'nice_name' => (string) $nice,
|
923 |
'URL' => (string) esc_url_raw( $URL ),
|
924 |
'avatar_URL' => (string) esc_url_raw( $avatar_URL ),
|
925 |
'profile_URL' => (string) esc_url_raw( $profile_URL ),
|
2233 |
)
|
2234 |
);
|
2235 |
|
2236 |
+
if ( is_wp_error( $data ) )
|
2237 |
+
return $data;
|
2238 |
+
|
2239 |
$taxonomy = get_term_by( 'id', $data['term_id'], $taxonomy_type );
|
2240 |
+
|
2241 |
$return = $this->get_taxonomy( $taxonomy->slug, $taxonomy_type, $args['context'] );
|
2242 |
if ( !$return || is_wp_error( $return ) ) {
|
2243 |
return $return;
|
class.photon.php
CHANGED
@@ -444,7 +444,7 @@ class Jetpack_Photon {
|
|
444 |
) );
|
445 |
|
446 |
// Bail if scheme isn't http or port is set that isn't port 80
|
447 |
-
if ( 'http' != $url_info['scheme'] || ! in_array( $url_info['port'], array( 80, null ) ) )
|
448 |
return false;
|
449 |
|
450 |
// Bail if no host is found
|
444 |
) );
|
445 |
|
446 |
// Bail if scheme isn't http or port is set that isn't port 80
|
447 |
+
if ( ( 'http' != $url_info['scheme'] || ! in_array( $url_info['port'], array( 80, null ) ) ) && apply_filters( 'jetpack_photon_reject_https', true ) )
|
448 |
return false;
|
449 |
|
450 |
// Bail if no host is found
|
functions.twitter-cards.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* Twitter Cards
|
4 |
+
*
|
5 |
+
* Hooks onto the Open Graph protocol and extends it by adding only the tags
|
6 |
+
* we need for twitter cards.
|
7 |
+
*
|
8 |
+
* @see /wp-content/blog-plugins/open-graph.php
|
9 |
+
* @see https://dev.twitter.com/docs/cards
|
10 |
+
*/
|
11 |
+
function wpcom_twitter_cards_tags( $og_tags ) {
|
12 |
+
global $post, $wpdb;
|
13 |
+
|
14 |
+
$og_tags['twitter:site'] = '@wordpressdotcom';
|
15 |
+
|
16 |
+
if ( ! is_singular() || ! empty( $og_tags['twitter:card'] ) )
|
17 |
+
return $og_tags;
|
18 |
+
|
19 |
+
$img_count = 0;
|
20 |
+
foreach ( $og_tags as $key => $value ) {
|
21 |
+
if ( 'og:image' != $key || ! is_array( $value ) || empty( $value[0] ) )
|
22 |
+
continue;
|
23 |
+
|
24 |
+
$img_count = 0;
|
25 |
+
foreach ( (array) $value as $counter => $image ) {
|
26 |
+
$og_tags['twitter:image' . $counter] = $image;
|
27 |
+
$img_count++;
|
28 |
+
if ( $img_count >= 4 )
|
29 |
+
break; // Only 4 images allowed
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
// Figure out what kind of card this is, based on the number of images found
|
34 |
+
if ( 0 == $img_count ) {
|
35 |
+
// No images = summary
|
36 |
+
$card = 'summary';
|
37 |
+
} else if ( $img_count <= 3 ) {
|
38 |
+
// < 4 images = photo
|
39 |
+
$card = 'photo';
|
40 |
+
$og_tags['twitter:image'] = $og_tags['twitter:image0']; // Rename back to photo format (from gallery)
|
41 |
+
unset( $og_tags['twitter:image0'] );
|
42 |
+
for ( $i = 1; $i < 4; $i++ ) {
|
43 |
+
unset( $og_tags['twitter:image' . $i] ); // Remove >0 image references
|
44 |
+
}
|
45 |
+
} else if ( $img_count >= 4 ) {
|
46 |
+
// >= 4 images = gallery
|
47 |
+
$card = 'gallery';
|
48 |
+
}
|
49 |
+
$og_tags['twitter:card'] = $card;
|
50 |
+
|
51 |
+
// If we have information on the author/creator, then include that as well
|
52 |
+
if ( ! empty( $post ) && ! empty( $post->post_author ) ) {
|
53 |
+
$handle = apply_filters( 'jetpack_sharing_twitter_via', '', $post->ID );
|
54 |
+
if ( !empty( $handle ) )
|
55 |
+
$og_tags['twitter:creator'] = '@' . $handle;
|
56 |
+
}
|
57 |
+
|
58 |
+
return $og_tags;
|
59 |
+
}
|
60 |
+
|
61 |
+
add_filter( 'jetpack_open_graph_tags', 'wpcom_twitter_cards_tags' );
|
62 |
+
|
63 |
+
function wpcom_twitter_cards_output( $og_tag ) {
|
64 |
+
return ( false !== strpos( $og_tag, 'twitter:' ) ) ? preg_replace( '/property="([^"]+)"/', 'name="\1"', $og_tag ) : $og_tag;
|
65 |
+
}
|
66 |
+
|
67 |
+
add_filter( 'jetpack_open_graph_output', 'wpcom_twitter_cards_output' );
|
jetpack.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* Plugin URI: http://wordpress.org/extend/plugins/jetpack/
|
6 |
* Description: Bring the power of the WordPress.com cloud to your self-hosted WordPress. Jetpack enables you to connect your blog to a WordPress.com account to use the powerful features normally only available to WordPress.com users.
|
7 |
* Author: Automattic
|
8 |
-
* Version: 2.
|
9 |
* Author URI: http://jetpack.me
|
10 |
* License: GPL2+
|
11 |
* Text Domain: jetpack
|
@@ -17,7 +17,7 @@ define( 'JETPACK__API_VERSION', 1 );
|
|
17 |
define( 'JETPACK__MINIMUM_WP_VERSION', '3.5' );
|
18 |
defined( 'JETPACK_CLIENT__AUTH_LOCATION' ) or define( 'JETPACK_CLIENT__AUTH_LOCATION', 'header' );
|
19 |
defined( 'JETPACK_CLIENT__HTTPS' ) or define( 'JETPACK_CLIENT__HTTPS', 'AUTO' );
|
20 |
-
define( 'JETPACK__VERSION', '2.
|
21 |
define( 'JETPACK__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
22 |
defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) or define( 'JETPACK__GLOTPRESS_LOCALES_PATH', JETPACK__PLUGIN_DIR . 'locales.php' );
|
23 |
|
@@ -49,6 +49,7 @@ require_once( JETPACK__PLUGIN_DIR . 'class.photon.php' );
|
|
49 |
require_once( JETPACK__PLUGIN_DIR . 'functions.photon.php' );
|
50 |
require_once( JETPACK__PLUGIN_DIR . 'functions.compat.php' );
|
51 |
require_once( JETPACK__PLUGIN_DIR . 'functions.gallery.php' );
|
|
|
52 |
|
53 |
register_activation_hook( __FILE__, array( 'Jetpack', 'plugin_activation' ) );
|
54 |
register_deactivation_hook( __FILE__, array( 'Jetpack', 'plugin_deactivation' ) );
|
@@ -57,10 +58,26 @@ add_action( 'init', array( 'Jetpack', 'init' ) );
|
|
57 |
add_action( 'plugins_loaded', array( 'Jetpack', 'load_modules' ), 100 );
|
58 |
add_filter( 'jetpack_static_url', array( 'Jetpack', 'staticize_subdomain' ) );
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
/*
|
61 |
if ( is_admin() && ! Jetpack::check_identity_crisis() ) {
|
62 |
Jetpack_Sync::sync_options( __FILE__, 'db_version', 'jetpack_active_modules', 'active_plugins' );
|
63 |
}
|
64 |
*/
|
65 |
-
|
66 |
-
Jetpack_Sync::sync_options( __FILE__, 'widget_twitter' );
|
5 |
* Plugin URI: http://wordpress.org/extend/plugins/jetpack/
|
6 |
* Description: Bring the power of the WordPress.com cloud to your self-hosted WordPress. Jetpack enables you to connect your blog to a WordPress.com account to use the powerful features normally only available to WordPress.com users.
|
7 |
* Author: Automattic
|
8 |
+
* Version: 2.4.5
|
9 |
* Author URI: http://jetpack.me
|
10 |
* License: GPL2+
|
11 |
* Text Domain: jetpack
|
17 |
define( 'JETPACK__MINIMUM_WP_VERSION', '3.5' );
|
18 |
defined( 'JETPACK_CLIENT__AUTH_LOCATION' ) or define( 'JETPACK_CLIENT__AUTH_LOCATION', 'header' );
|
19 |
defined( 'JETPACK_CLIENT__HTTPS' ) or define( 'JETPACK_CLIENT__HTTPS', 'AUTO' );
|
20 |
+
define( 'JETPACK__VERSION', '2.4.5' );
|
21 |
define( 'JETPACK__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
22 |
defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) or define( 'JETPACK__GLOTPRESS_LOCALES_PATH', JETPACK__PLUGIN_DIR . 'locales.php' );
|
23 |
|
49 |
require_once( JETPACK__PLUGIN_DIR . 'functions.photon.php' );
|
50 |
require_once( JETPACK__PLUGIN_DIR . 'functions.compat.php' );
|
51 |
require_once( JETPACK__PLUGIN_DIR . 'functions.gallery.php' );
|
52 |
+
require_once( JETPACK__PLUGIN_DIR . 'functions.twitter-cards.php' );
|
53 |
|
54 |
register_activation_hook( __FILE__, array( 'Jetpack', 'plugin_activation' ) );
|
55 |
register_deactivation_hook( __FILE__, array( 'Jetpack', 'plugin_deactivation' ) );
|
58 |
add_action( 'plugins_loaded', array( 'Jetpack', 'load_modules' ), 100 );
|
59 |
add_filter( 'jetpack_static_url', array( 'Jetpack', 'staticize_subdomain' ) );
|
60 |
|
61 |
+
add_filter( 'jetpack_open_graph_tags', 'change_twitter_site_param' );
|
62 |
+
|
63 |
+
function change_twitter_site_param( $og_tags ) {
|
64 |
+
$og_tags['twitter:site'] = '@jetpack';
|
65 |
+
return $og_tags;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Add an easy way to photon-ize a URL that is safe to call even if Jetpack isn't active.
|
70 |
+
*
|
71 |
+
* See: http://jetpack.me/2013/07/11/photon-and-themes/
|
72 |
+
*/
|
73 |
+
if ( Jetpack::init()->is_module_active( 'photon' ) ) {
|
74 |
+
add_filter( 'jetpack_photon_url', 'jetpack_photon_url', 10, 3 );
|
75 |
+
} else {
|
76 |
+
remove_filter( 'jetpack_photon_url', 'jetpack_photon_url', 10, 3 );
|
77 |
+
}
|
78 |
+
|
79 |
/*
|
80 |
if ( is_admin() && ! Jetpack::check_identity_crisis() ) {
|
81 |
Jetpack_Sync::sync_options( __FILE__, 'db_version', 'jetpack_active_modules', 'active_plugins' );
|
82 |
}
|
83 |
*/
|
|
|
|
languages/jetpack-ar.mo
CHANGED
Binary file
|
languages/jetpack-az.mo
CHANGED
Binary file
|
languages/jetpack-bs_BA.mo
CHANGED
Binary file
|
languages/jetpack-ca.mo
CHANGED
Binary file
|
languages/jetpack-cs_CZ.mo
CHANGED
Binary file
|
languages/jetpack-da_DK.mo
CHANGED
Binary file
|
languages/jetpack-de_DE.mo
CHANGED
Binary file
|
languages/jetpack-el.mo
CHANGED
Binary file
|
languages/jetpack-es_ES.mo
CHANGED
Binary file
|
languages/jetpack-fa_IR.mo
CHANGED
Binary file
|
languages/jetpack-fi.mo
CHANGED
Binary file
|
languages/jetpack-fr_FR.mo
CHANGED
Binary file
|
languages/jetpack-gl_ES.mo
CHANGED
Binary file
|
languages/jetpack-he_IL.mo
CHANGED
Binary file
|
languages/jetpack-hr.mo
CHANGED
Binary file
|
languages/jetpack-hu_HU.mo
CHANGED
Binary file
|
languages/jetpack-id_ID.mo
CHANGED
Binary file
|
languages/jetpack-it_IT.mo
CHANGED
Binary file
|
languages/jetpack-ja.mo
CHANGED
Binary file
|
languages/jetpack-ko_KR.mo
CHANGED
Binary file
|
languages/jetpack-lt_LT.mo
CHANGED
Binary file
|
languages/jetpack-mk_MK.mo
CHANGED
Binary file
|
languages/jetpack-my_MM.mo
CHANGED
Binary file
|
languages/jetpack-nb_NO.mo
CHANGED
Binary file
|
languages/jetpack-nl_NL.mo
CHANGED
Binary file
|
languages/jetpack-nn_NO.mo
CHANGED
Binary file
|
languages/jetpack-pl_PL.mo
CHANGED
Binary file
|
languages/jetpack-pt_BR.mo
CHANGED
Binary file
|
languages/jetpack-pt_PT.mo
CHANGED
Binary file
|
languages/jetpack-ro_RO.mo
CHANGED
Binary file
|
languages/jetpack-ru_RU.mo
CHANGED
Binary file
|
languages/jetpack-sa_IN.mo
CHANGED
Binary file
|
languages/jetpack-sk_SK.mo
CHANGED
Binary file
|
languages/jetpack-sq.mo
CHANGED
Binary file
|
languages/jetpack-sr_RS.mo
CHANGED
Binary file
|
languages/jetpack-sv_SE.mo
CHANGED
Binary file
|
languages/jetpack-th.mo
CHANGED
Binary file
|
languages/jetpack-tr_TR.mo
CHANGED
Binary file
|
languages/jetpack-uk.mo
CHANGED
Binary file
|
languages/jetpack-ur.mo
CHANGED
Binary file
|
languages/jetpack-zh_CN.mo
CHANGED
Binary file
|
languages/jetpack-zh_TW.mo
CHANGED
Binary file
|
modules/after-the-deadline.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 6
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
add_action( 'jetpack_modules_loaded', 'AtD_load' );
|
5 |
* Sort Order: 6
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
add_action( 'jetpack_modules_loaded', 'AtD_load' );
|
modules/after-the-deadline/config-unignore.php
CHANGED
@@ -32,6 +32,9 @@ function AtD_process_unignore_update() {
|
|
32 |
if ( ! AtD_is_allowed() )
|
33 |
return;
|
34 |
|
|
|
|
|
|
|
35 |
$user = wp_get_current_user();
|
36 |
|
37 |
if ( ! $user || $user->ID == 0 )
|
32 |
if ( ! AtD_is_allowed() )
|
33 |
return;
|
34 |
|
35 |
+
if ( ! isset( $_POST['AtD_ignored_phrases'] ) )
|
36 |
+
return;
|
37 |
+
|
38 |
$user = wp_get_current_user();
|
39 |
|
40 |
if ( ! $user || $user->ID == 0 )
|
modules/carousel.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* Sort Order: 4
|
7 |
* First Introduced: 1.5
|
8 |
* Requires Connection: No
|
|
|
9 |
*/
|
10 |
|
11 |
include dirname( __FILE__ ) . '/carousel/jetpack-carousel.php';
|
6 |
* Sort Order: 4
|
7 |
* First Introduced: 1.5
|
8 |
* Requires Connection: No
|
9 |
+
* Auto Activate: No
|
10 |
*/
|
11 |
|
12 |
include dirname( __FILE__ ) . '/carousel/jetpack-carousel.php';
|
modules/comments.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* First Introduced: 1.4
|
7 |
* Sort Order: 2
|
8 |
* Requires Connection: Yes
|
|
|
9 |
*/
|
10 |
|
11 |
require dirname( __FILE__ ) . '/comments/comments.php';
|
6 |
* First Introduced: 1.4
|
7 |
* Sort Order: 2
|
8 |
* Requires Connection: Yes
|
9 |
+
* Auto Activate: No
|
10 |
*/
|
11 |
|
12 |
require dirname( __FILE__ ) . '/comments/comments.php';
|
modules/contact-form.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 9
|
6 |
* First Introduced: 1.3
|
7 |
* Requires Connection: No
|
|
|
8 |
*/
|
9 |
|
10 |
include dirname( __FILE__ ) . '/contact-form/grunion-contact-form.php';
|
5 |
* Sort Order: 9
|
6 |
* First Introduced: 1.3
|
7 |
* Requires Connection: No
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
include dirname( __FILE__ ) . '/contact-form/grunion-contact-form.php';
|
modules/contact-form/admin.php
CHANGED
@@ -402,7 +402,12 @@ jQuery(document).ready( function($) {
|
|
402 |
break;
|
403 |
|
404 |
case 'feedback_date':
|
405 |
-
|
|
|
|
|
|
|
|
|
|
|
406 |
break;
|
407 |
}
|
408 |
}
|
402 |
break;
|
403 |
|
404 |
case 'feedback_date':
|
405 |
+
|
406 |
+
$date_time_format = _x( '%1$s \a\t %2$s', '{$date_format} \a\t {$time_format}', 'jetpack' );
|
407 |
+
$date_time_format = sprintf( $date_time_format, get_option( 'date_format' ), get_option( 'time_format' ) );
|
408 |
+
$time = date_i18n( $date_time_format, get_the_time( 'U' ) );
|
409 |
+
|
410 |
+
echo $time;
|
411 |
break;
|
412 |
}
|
413 |
}
|
modules/contact-form/css/menu-alter.css
CHANGED
@@ -12,11 +12,11 @@
|
|
12 |
background: url(../images/grunion-menu.png) no-repeat 7px 7px !important;
|
13 |
}
|
14 |
|
15 |
-
body.
|
16 |
background: none !important;
|
17 |
}
|
18 |
|
19 |
-
body.
|
20 |
content: '\f175';
|
21 |
margin-left: -1px;
|
22 |
}
|
12 |
background: url(../images/grunion-menu.png) no-repeat 7px 7px !important;
|
13 |
}
|
14 |
|
15 |
+
body.mp6 #adminmenu .menu-icon-feedback div.wp-menu-image {
|
16 |
background: none !important;
|
17 |
}
|
18 |
|
19 |
+
body.mp6 #adminmenu .menu-icon-feedback div.wp-menu-image:before {
|
20 |
content: '\f175';
|
21 |
margin-left: -1px;
|
22 |
}
|
modules/contact-form/css/rtl/menu-alter-rtl.css
CHANGED
@@ -14,15 +14,15 @@
|
|
14 |
background: url(../../images/grunion-menu.png) no-repeat 7px 7px !important;
|
15 |
}
|
16 |
|
17 |
-
body.
|
18 |
display: none;
|
19 |
}
|
20 |
|
21 |
-
body.
|
22 |
background: none !important;
|
23 |
}
|
24 |
|
25 |
-
body.
|
26 |
content: '\f175';
|
27 |
margin-right: -1px;
|
28 |
}
|
14 |
background: url(../../images/grunion-menu.png) no-repeat 7px 7px !important;
|
15 |
}
|
16 |
|
17 |
+
body.mp6 #adminmenu .toplevel_page_feedback div.wp-menu-image img {
|
18 |
display: none;
|
19 |
}
|
20 |
|
21 |
+
body.mp6 #adminmenu .menu-icon-feedback div.wp-menu-image, body.mp6 #adminmenu .toplevel_page_feedback div.wp-menu-image {
|
22 |
background: none !important;
|
23 |
}
|
24 |
|
25 |
+
body.mp6 #adminmenu .menu-icon-feedback div.wp-menu-image:before, body.mp6 #adminmenu .toplevel_page_feedback div.wp-menu-image:before {
|
26 |
content: '\f175';
|
27 |
margin-right: -1px;
|
28 |
}
|
modules/contact-form/grunion-contact-form.php
CHANGED
@@ -359,7 +359,7 @@ class Grunion_Contact_Form_Plugin {
|
|
359 |
<?php wp_nonce_field( 'feedback_export','feedback_export_nonce' ); ?>
|
360 |
|
361 |
<input name="action" value="feedback_export" type="hidden">
|
362 |
-
<label for="post"><? _e( 'Select feedback to download', 'jetpack' ) ?></label>
|
363 |
<select name="post">
|
364 |
<option value="all"><?php esc_html_e( 'All posts', 'jetpack' ) ?></option>
|
365 |
<?php echo $this->get_feedbacks_as_options() ?>
|
359 |
<?php wp_nonce_field( 'feedback_export','feedback_export_nonce' ); ?>
|
360 |
|
361 |
<input name="action" value="feedback_export" type="hidden">
|
362 |
+
<label for="post"><?php _e( 'Select feedback to download', 'jetpack' ) ?></label>
|
363 |
<select name="post">
|
364 |
<option value="all"><?php esc_html_e( 'All posts', 'jetpack' ) ?></option>
|
365 |
<?php echo $this->get_feedbacks_as_options() ?>
|
modules/custom-css.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* Sort Order: 11
|
7 |
* First Introduced: 1.7
|
8 |
* Requires Connection: No
|
|
|
9 |
*/
|
10 |
|
11 |
function jetpack_load_custom_css() {
|
6 |
* Sort Order: 11
|
7 |
* First Introduced: 1.7
|
8 |
* Requires Connection: No
|
9 |
+
* Auto Activate: Yes
|
10 |
*/
|
11 |
|
12 |
function jetpack_load_custom_css() {
|
modules/custom-css/custom-css.php
CHANGED
@@ -901,14 +901,25 @@ class Jetpack_Custom_CSS {
|
|
901 |
|
902 |
/**
|
903 |
* Render metabox listing CSS revisions and the themes that correspond to the revisions.
|
904 |
-
* Called by
|
905 |
-
*
|
906 |
* @global $post
|
907 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
908 |
* @return string
|
909 |
*/
|
910 |
static function revisions_meta_box( $safecss_post ) {
|
911 |
-
|
|
|
|
|
|
|
|
|
912 |
$posts_per_page = isset( $_GET['show_all_rev'] ) ? $max_revisions : 6;
|
913 |
|
914 |
$revisions = new WP_Query( array(
|
901 |
|
902 |
/**
|
903 |
* Render metabox listing CSS revisions and the themes that correspond to the revisions.
|
904 |
+
* Called by safecss_admin
|
905 |
+
*
|
906 |
* @global $post
|
907 |
+
* @param array $safecss_post
|
908 |
+
* @uses wp_revisions_to_keep
|
909 |
+
* @uses WP_Query
|
910 |
+
* @uses wp_post_revision_title
|
911 |
+
* @uses esc_html
|
912 |
+
* @uses add_query_arg
|
913 |
+
* @uses menu_page_url
|
914 |
+
* @uses wp_reset_query
|
915 |
* @return string
|
916 |
*/
|
917 |
static function revisions_meta_box( $safecss_post ) {
|
918 |
+
if ( function_exists( 'wp_revisions_to_keep' ) )
|
919 |
+
$max_revisions = wp_revisions_to_keep( $safecss_post );
|
920 |
+
else
|
921 |
+
$max_revisions = defined( 'WP_POST_REVISIONS' ) && is_numeric( WP_POST_REVISIONS ) ? (int) WP_POST_REVISIONS : 25;
|
922 |
+
|
923 |
$posts_per_page = isset( $_GET['show_all_rev'] ) ? $max_revisions : 6;
|
924 |
|
925 |
$revisions = new WP_Query( array(
|
modules/custom-css/custom-css/css/css-editor.css
CHANGED
@@ -21,4 +21,7 @@
|
|
21 |
|
22 |
.misc-pub-section > div {
|
23 |
margin-top: 3px;
|
|
|
|
|
|
|
24 |
}
|
21 |
|
22 |
.misc-pub-section > div {
|
23 |
margin-top: 3px;
|
24 |
+
}
|
25 |
+
#safecss-ace .ace_gutter {
|
26 |
+
z-index: 1;
|
27 |
}
|
modules/custom-css/custom-css/preprocessors/lessc.inc.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
-
* lessphp v0.
|
5 |
* http://leafo.net/lessphp
|
6 |
*
|
7 |
* LESS css compiler, adapted from http://lesscss.org
|
@@ -38,7 +38,7 @@
|
|
38 |
* handling things like indentation.
|
39 |
*/
|
40 |
class lessc {
|
41 |
-
static public $VERSION = "v0.
|
42 |
static protected $TRUE = array("keyword", "true");
|
43 |
static protected $FALSE = array("keyword", "false");
|
44 |
|
@@ -55,6 +55,8 @@ class lessc {
|
|
55 |
|
56 |
protected $numberPrecision = null;
|
57 |
|
|
|
|
|
58 |
// set to the parser that generated the current line when compiling
|
59 |
// so we know how to create error messages
|
60 |
protected $sourceParser = null;
|
@@ -103,12 +105,17 @@ class lessc {
|
|
103 |
if (substr_compare($url, '.css', -4, 4) === 0) return false;
|
104 |
|
105 |
$realPath = $this->findImport($url);
|
|
|
106 |
if ($realPath === null) return false;
|
107 |
|
108 |
if ($this->importDisabled) {
|
109 |
return array(false, "/* import disabled */");
|
110 |
}
|
111 |
|
|
|
|
|
|
|
|
|
112 |
$this->addParsedFile($realPath);
|
113 |
$parser = $this->makeParser($realPath);
|
114 |
$root = $parser->parse(file_get_contents($realPath));
|
@@ -276,6 +283,8 @@ class lessc {
|
|
276 |
foreach ($this->sortProps($block->props) as $prop) {
|
277 |
$this->compileProp($prop, $block, $out);
|
278 |
}
|
|
|
|
|
279 |
}
|
280 |
|
281 |
protected function sortProps($props, $split = false) {
|
@@ -327,6 +336,9 @@ class lessc {
|
|
327 |
$parts[] = "($q[1])";
|
328 |
}
|
329 |
break;
|
|
|
|
|
|
|
330 |
}
|
331 |
}
|
332 |
|
@@ -434,7 +446,7 @@ class lessc {
|
|
434 |
foreach ($selectors as $s) {
|
435 |
if (is_array($s)) {
|
436 |
list(, $value) = $s;
|
437 |
-
$out[] = $this->compileValue($this->reduce($value));
|
438 |
} else {
|
439 |
$out[] = $s;
|
440 |
}
|
@@ -447,7 +459,7 @@ class lessc {
|
|
447 |
return $left == $right;
|
448 |
}
|
449 |
|
450 |
-
protected function patternMatch($block, $
|
451 |
// match the guards if it has them
|
452 |
// any one of the groups must have all its guards pass for a match
|
453 |
if (!empty($block->guards)) {
|
@@ -455,7 +467,7 @@ class lessc {
|
|
455 |
foreach ($block->guards as $guardGroup) {
|
456 |
foreach ($guardGroup as $guard) {
|
457 |
$this->pushEnv();
|
458 |
-
$this->zipSetArgs($block->args, $
|
459 |
|
460 |
$negate = false;
|
461 |
if ($guard[0] == "negate") {
|
@@ -484,24 +496,34 @@ class lessc {
|
|
484 |
}
|
485 |
}
|
486 |
|
487 |
-
$numCalling = count($callingArgs);
|
488 |
-
|
489 |
if (empty($block->args)) {
|
490 |
-
return $block->isVararg || $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
491 |
}
|
492 |
|
493 |
$i = -1; // no args
|
494 |
// try to match by arity or by argument literal
|
495 |
-
foreach ($
|
496 |
switch ($arg[0]) {
|
497 |
case "lit":
|
498 |
-
if (empty($
|
499 |
return false;
|
500 |
}
|
501 |
break;
|
502 |
case "arg":
|
503 |
// no arg and no default value
|
504 |
-
if (!isset($
|
505 |
return false;
|
506 |
}
|
507 |
break;
|
@@ -516,14 +538,19 @@ class lessc {
|
|
516 |
} else {
|
517 |
$numMatched = $i + 1;
|
518 |
// greater than becuase default values always match
|
519 |
-
return $numMatched >= $
|
520 |
}
|
521 |
}
|
522 |
|
523 |
-
protected function patternMatchAll($blocks, $
|
524 |
$matches = null;
|
525 |
foreach ($blocks as $block) {
|
526 |
-
|
|
|
|
|
|
|
|
|
|
|
527 |
$matches[] = $block;
|
528 |
}
|
529 |
}
|
@@ -532,7 +559,7 @@ class lessc {
|
|
532 |
}
|
533 |
|
534 |
// attempt to find blocks matched by path and args
|
535 |
-
protected function findBlocks($searchIn, $path, $
|
536 |
if ($searchIn == null) return null;
|
537 |
if (isset($seen[$searchIn->id])) return null;
|
538 |
$seen[$searchIn->id] = true;
|
@@ -542,7 +569,7 @@ class lessc {
|
|
542 |
if (isset($searchIn->children[$name])) {
|
543 |
$blocks = $searchIn->children[$name];
|
544 |
if (count($path) == 1) {
|
545 |
-
$matches = $this->patternMatchAll($blocks, $
|
546 |
if (!empty($matches)) {
|
547 |
// This will return all blocks that match in the closest
|
548 |
// scope that has any matching block, like lessjs
|
@@ -552,7 +579,7 @@ class lessc {
|
|
552 |
$matches = array();
|
553 |
foreach ($blocks as $subBlock) {
|
554 |
$subMatches = $this->findBlocks($subBlock,
|
555 |
-
array_slice($path, 1), $
|
556 |
|
557 |
if (!is_null($subMatches)) {
|
558 |
foreach ($subMatches as $sm) {
|
@@ -564,39 +591,51 @@ class lessc {
|
|
564 |
return count($matches) > 0 ? $matches : null;
|
565 |
}
|
566 |
}
|
567 |
-
|
568 |
if ($searchIn->parent === $searchIn) return null;
|
569 |
-
return $this->findBlocks($searchIn->parent, $path, $
|
570 |
}
|
571 |
|
572 |
// sets all argument names in $args to either the default value
|
573 |
// or the one passed in through $values
|
574 |
-
protected function zipSetArgs($args, $
|
575 |
-
$i = 0;
|
576 |
$assignedValues = array();
|
577 |
-
|
|
|
|
|
578 |
if ($a[0] == "arg") {
|
579 |
-
if (
|
580 |
-
|
|
|
|
|
|
|
|
|
|
|
581 |
} elseif (isset($a[2])) {
|
|
|
582 |
$value = $a[2];
|
583 |
-
} else
|
|
|
|
|
|
|
584 |
|
585 |
$value = $this->reduce($value);
|
586 |
$this->set($a[1], $value);
|
587 |
$assignedValues[] = $value;
|
|
|
|
|
|
|
588 |
}
|
589 |
-
$i++;
|
590 |
}
|
591 |
|
592 |
// check for a rest
|
593 |
$last = end($args);
|
594 |
if ($last[0] == "rest") {
|
595 |
-
$rest = array_slice($
|
596 |
$this->set($last[1], $this->reduce(array("list", " ", $rest)));
|
597 |
}
|
598 |
|
599 |
-
|
|
|
600 |
}
|
601 |
|
602 |
// compile a prop and update $lines or $blocks appropriately
|
@@ -621,8 +660,28 @@ class lessc {
|
|
621 |
case 'mixin':
|
622 |
list(, $path, $args, $suffix) = $prop;
|
623 |
|
624 |
-
$
|
625 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
626 |
|
627 |
if ($mixins === null) {
|
628 |
// fwrite(STDERR,"failed to find block: ".implode(" > ", $path)."\n");
|
@@ -630,6 +689,10 @@ class lessc {
|
|
630 |
}
|
631 |
|
632 |
foreach ($mixins as $mixin) {
|
|
|
|
|
|
|
|
|
633 |
$haveScope = false;
|
634 |
if (isset($mixin->parent->scope)) {
|
635 |
$haveScope = true;
|
@@ -641,7 +704,7 @@ class lessc {
|
|
641 |
if (isset($mixin->args)) {
|
642 |
$haveArgs = true;
|
643 |
$this->pushEnv();
|
644 |
-
$this->zipSetArgs($mixin->args, $
|
645 |
}
|
646 |
|
647 |
$oldParent = $mixin->parent;
|
@@ -698,7 +761,9 @@ class lessc {
|
|
698 |
list(,$importId) = $prop;
|
699 |
$import = $this->env->imports[$importId];
|
700 |
if ($import[0] === false) {
|
701 |
-
|
|
|
|
|
702 |
} else {
|
703 |
list(, $bottom, $parser, $importDir) = $import;
|
704 |
$this->compileImportedProps($bottom, $block, $out, $parser, $importDir);
|
@@ -786,6 +851,60 @@ class lessc {
|
|
786 |
}
|
787 |
}
|
788 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
789 |
protected function lib_isnumber($value) {
|
790 |
return $this->toBool($value[0] == "number");
|
791 |
}
|
@@ -814,6 +933,10 @@ class lessc {
|
|
814 |
return $this->toBool($value[0] == "number" && $value[2] == "em");
|
815 |
}
|
816 |
|
|
|
|
|
|
|
|
|
817 |
protected function lib_rgbahex($color) {
|
818 |
$color = $this->coerceColor($color);
|
819 |
if (is_null($color))
|
@@ -890,6 +1013,16 @@ class lessc {
|
|
890 |
return array("number", round($value), $arg[2]);
|
891 |
}
|
892 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
893 |
/**
|
894 |
* Helper function to get arguments for color manipulation functions.
|
895 |
* takes a list that contains a color like thing and a percentage
|
@@ -996,19 +1129,24 @@ class lessc {
|
|
996 |
}
|
997 |
|
998 |
// mixes two colors by weight
|
999 |
-
// mix(@color1, @color2, @weight);
|
1000 |
// http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method
|
1001 |
protected function lib_mix($args) {
|
1002 |
-
if ($args[0] != "list" || count($args[2]) <
|
1003 |
$this->throwError("mix expects (color1, color2, weight)");
|
1004 |
|
1005 |
-
list($first, $second
|
1006 |
$first = $this->assertColor($first);
|
1007 |
$second = $this->assertColor($second);
|
1008 |
|
1009 |
$first_a = $this->lib_alpha($first);
|
1010 |
$second_a = $this->lib_alpha($second);
|
1011 |
-
|
|
|
|
|
|
|
|
|
|
|
1012 |
|
1013 |
$w = $weight * 2 - 1;
|
1014 |
$a = $first_a - $second_a;
|
@@ -1029,6 +1167,25 @@ class lessc {
|
|
1029 |
return $this->fixColor($new);
|
1030 |
}
|
1031 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1032 |
protected function assertColor($value, $error = "expected color value") {
|
1033 |
$color = $this->coerceColor($value);
|
1034 |
if (is_null($color)) $this->throwError($error);
|
@@ -1040,6 +1197,25 @@ class lessc {
|
|
1040 |
$this->throwError($error);
|
1041 |
}
|
1042 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1043 |
protected function toHSL($color) {
|
1044 |
if ($color[0] == 'hsl') return $color;
|
1045 |
|
@@ -1091,7 +1267,7 @@ class lessc {
|
|
1091 |
* Expects H to be in range of 0 to 360, S and L in 0 to 100
|
1092 |
*/
|
1093 |
protected function toRGB($color) {
|
1094 |
-
if ($color == 'color') return $color;
|
1095 |
|
1096 |
$H = $color[1] / 360;
|
1097 |
$S = $color[2] / 100;
|
@@ -1179,6 +1355,18 @@ class lessc {
|
|
1179 |
|
1180 |
protected function reduce($value, $forExpression = false) {
|
1181 |
switch ($value[0]) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1182 |
case "variable":
|
1183 |
$key = $value[1];
|
1184 |
if (is_array($key)) {
|
@@ -1299,8 +1487,12 @@ class lessc {
|
|
1299 |
case 'keyword':
|
1300 |
$name = $value[1];
|
1301 |
if (isset(self::$cssColors[$name])) {
|
1302 |
-
|
1303 |
-
|
|
|
|
|
|
|
|
|
1304 |
}
|
1305 |
return null;
|
1306 |
}
|
@@ -1445,6 +1637,34 @@ class lessc {
|
|
1445 |
return $this->fixColor($out);
|
1446 |
}
|
1447 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1448 |
// operator on two numbers
|
1449 |
protected function op_number_number($op, $left, $right) {
|
1450 |
$unit = empty($left[2]) ? $right[2] : $left[2];
|
@@ -1605,7 +1825,6 @@ class lessc {
|
|
1605 |
$this->importDir = (array)$this->importDir;
|
1606 |
$this->importDir[] = $pi['dirname'].'/';
|
1607 |
|
1608 |
-
$this->allParsedFiles = array();
|
1609 |
$this->addParsedFile($fname);
|
1610 |
|
1611 |
$out = $this->compile(file_get_contents($fname), $fname);
|
@@ -1945,6 +2164,7 @@ class lessc {
|
|
1945 |
'teal' => '0,128,128',
|
1946 |
'thistle' => '216,191,216',
|
1947 |
'tomato' => '255,99,71',
|
|
|
1948 |
'turquoise' => '64,224,208',
|
1949 |
'violet' => '238,130,238',
|
1950 |
'wheat' => '245,222,179',
|
@@ -1988,7 +2208,7 @@ class lessc_parser {
|
|
1988 |
static protected $supressDivisionProps =
|
1989 |
array('/border-radius$/i', '/^font$/i');
|
1990 |
|
1991 |
-
protected $blockDirectives = array("font-face", "keyframes", "page", "-moz-document");
|
1992 |
protected $lineDirectives = array("charset");
|
1993 |
|
1994 |
/**
|
@@ -2227,7 +2447,7 @@ class lessc_parser {
|
|
2227 |
|
2228 |
// mixin
|
2229 |
if ($this->mixinTags($tags) &&
|
2230 |
-
($this->
|
2231 |
($this->keyword($suffix) || true) && $this->end())
|
2232 |
{
|
2233 |
$tags = $this->fixTags($tags);
|
@@ -2519,6 +2739,9 @@ class lessc_parser {
|
|
2519 |
$out = array("mediaExp", $feature);
|
2520 |
if ($value) $out[] = $value;
|
2521 |
return true;
|
|
|
|
|
|
|
2522 |
}
|
2523 |
|
2524 |
$this->seek($s);
|
@@ -2572,12 +2795,10 @@ class lessc_parser {
|
|
2572 |
continue;
|
2573 |
}
|
2574 |
|
2575 |
-
if (in_array($tok, $rejectStrs)) {
|
2576 |
-
$count = null;
|
2577 |
break;
|
2578 |
}
|
2579 |
|
2580 |
-
|
2581 |
$content[] = $tok;
|
2582 |
$this->count+= strlen($tok);
|
2583 |
}
|
@@ -2652,10 +2873,10 @@ class lessc_parser {
|
|
2652 |
|
2653 |
$s = $this->seek();
|
2654 |
if ($this->literal("@{") &&
|
2655 |
-
$this->
|
2656 |
$this->literal("}", false))
|
2657 |
{
|
2658 |
-
$out = array("
|
2659 |
$this->eatWhiteDefault = $oldWhite;
|
2660 |
if ($this->eatWhiteDefault) $this->whitespace();
|
2661 |
return true;
|
@@ -2694,38 +2915,18 @@ class lessc_parser {
|
|
2694 |
return false;
|
2695 |
}
|
2696 |
|
2697 |
-
// consume a list of property values delimited by ; and wrapped in ()
|
2698 |
-
protected function argumentValues(&$args, $delim = ',') {
|
2699 |
-
$s = $this->seek();
|
2700 |
-
if (!$this->literal('(')) return false;
|
2701 |
-
|
2702 |
-
$values = array();
|
2703 |
-
while (true) {
|
2704 |
-
if ($this->expressionList($value)) $values[] = $value;
|
2705 |
-
if (!$this->literal($delim)) break;
|
2706 |
-
else {
|
2707 |
-
if ($value == null) $values[] = null;
|
2708 |
-
$value = null;
|
2709 |
-
}
|
2710 |
-
}
|
2711 |
-
|
2712 |
-
if (!$this->literal(')')) {
|
2713 |
-
$this->seek($s);
|
2714 |
-
return false;
|
2715 |
-
}
|
2716 |
-
|
2717 |
-
$args = $values;
|
2718 |
-
return true;
|
2719 |
-
}
|
2720 |
-
|
2721 |
// consume an argument definition list surrounded by ()
|
2722 |
// each argument is a variable name with optional value
|
2723 |
// or at the end a ... or a variable named followed by ...
|
2724 |
-
|
|
|
|
|
2725 |
$s = $this->seek();
|
2726 |
if (!$this->literal('(')) return false;
|
2727 |
|
2728 |
$values = array();
|
|
|
|
|
2729 |
|
2730 |
$isVararg = false;
|
2731 |
while (true) {
|
@@ -2734,28 +2935,77 @@ class lessc_parser {
|
|
2734 |
break;
|
2735 |
}
|
2736 |
|
2737 |
-
if ($this
|
2738 |
-
$
|
2739 |
-
|
2740 |
-
|
2741 |
-
|
2742 |
-
|
2743 |
-
|
2744 |
-
|
2745 |
-
$
|
2746 |
-
$
|
|
|
|
|
|
|
2747 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2748 |
}
|
2749 |
-
$values[] = $arg;
|
2750 |
-
if ($isVararg) break;
|
2751 |
-
continue;
|
2752 |
}
|
2753 |
|
2754 |
-
if ($this->value($literal)) {
|
2755 |
-
$values[] = array("lit", $literal);
|
2756 |
-
}
|
2757 |
|
2758 |
-
if (!$this->literal($delim))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2759 |
}
|
2760 |
|
2761 |
if (!$this->literal(')')) {
|
@@ -2797,70 +3047,136 @@ class lessc_parser {
|
|
2797 |
}
|
2798 |
|
2799 |
// a bracketed value (contained within in a tag definition)
|
2800 |
-
protected function tagBracket(&$
|
2801 |
// speed shortcut
|
2802 |
if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") {
|
2803 |
return false;
|
2804 |
}
|
2805 |
|
2806 |
$s = $this->seek();
|
2807 |
-
if ($this->literal('[') && $this->to(']', $c, true) && $this->literal(']', false)) {
|
2808 |
-
$value = '['.$c.']';
|
2809 |
-
// whitespace?
|
2810 |
-
if ($this->whitespace()) $value .= " ";
|
2811 |
|
2812 |
-
|
2813 |
-
$value = str_replace($this->lessc->parentSelector, "$&$", $value);
|
2814 |
-
return true;
|
2815 |
-
}
|
2816 |
|
2817 |
-
$this->
|
2818 |
-
|
2819 |
-
|
|
|
|
|
|
|
|
|
|
|
2820 |
|
2821 |
-
|
2822 |
-
|
2823 |
-
|
2824 |
-
|
2825 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2826 |
}
|
2827 |
|
2828 |
$this->seek($s);
|
2829 |
return false;
|
2830 |
}
|
2831 |
|
2832 |
-
// a
|
2833 |
protected function tag(&$tag, $simple = false) {
|
2834 |
if ($simple)
|
2835 |
-
$chars = '
|
2836 |
else
|
2837 |
-
$chars = '
|
2838 |
|
2839 |
-
|
2840 |
-
return true;
|
2841 |
-
}
|
2842 |
|
2843 |
-
$
|
2844 |
-
|
|
|
|
|
|
|
|
|
2845 |
|
2846 |
while (true) {
|
2847 |
if ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) {
|
2848 |
-
$
|
2849 |
if ($simple) break;
|
2850 |
|
2851 |
-
while ($this->tagBracket($
|
2852 |
continue;
|
2853 |
-
}
|
2854 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2855 |
continue;
|
2856 |
}
|
|
|
2857 |
break;
|
2858 |
}
|
2859 |
|
|
|
|
|
|
|
|
|
|
|
2860 |
|
2861 |
-
|
2862 |
-
|
|
|
|
|
|
|
2863 |
|
|
|
2864 |
return true;
|
2865 |
}
|
2866 |
|
@@ -2948,7 +3264,7 @@ class lessc_parser {
|
|
2948 |
protected function end() {
|
2949 |
if ($this->literal(';')) {
|
2950 |
return true;
|
2951 |
-
} elseif ($this->count == strlen($this->buffer) || $this->buffer
|
2952 |
// if there is end of file or a closing block next then we don't need a ;
|
2953 |
return true;
|
2954 |
}
|
@@ -3212,7 +3528,7 @@ class lessc_parser {
|
|
3212 |
break;
|
3213 |
case '"':
|
3214 |
case "'":
|
3215 |
-
if (preg_match('/'.$min[0].'.*?'.$min[0].'/', $text, $m, 0, $count))
|
3216 |
$count += strlen($m[0]) - 1;
|
3217 |
break;
|
3218 |
case '//':
|
@@ -3356,4 +3672,3 @@ class lessc_formatter_lessjs extends lessc_formatter_classic {
|
|
3356 |
public $selectorSeparator = ",";
|
3357 |
}
|
3358 |
|
3359 |
-
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
+
* lessphp v0.4.0
|
5 |
* http://leafo.net/lessphp
|
6 |
*
|
7 |
* LESS css compiler, adapted from http://lesscss.org
|
38 |
* handling things like indentation.
|
39 |
*/
|
40 |
class lessc {
|
41 |
+
static public $VERSION = "v0.4.0";
|
42 |
static protected $TRUE = array("keyword", "true");
|
43 |
static protected $FALSE = array("keyword", "false");
|
44 |
|
55 |
|
56 |
protected $numberPrecision = null;
|
57 |
|
58 |
+
protected $allParsedFiles = array();
|
59 |
+
|
60 |
// set to the parser that generated the current line when compiling
|
61 |
// so we know how to create error messages
|
62 |
protected $sourceParser = null;
|
105 |
if (substr_compare($url, '.css', -4, 4) === 0) return false;
|
106 |
|
107 |
$realPath = $this->findImport($url);
|
108 |
+
|
109 |
if ($realPath === null) return false;
|
110 |
|
111 |
if ($this->importDisabled) {
|
112 |
return array(false, "/* import disabled */");
|
113 |
}
|
114 |
|
115 |
+
if (isset($this->allParsedFiles[realpath($realPath)])) {
|
116 |
+
return array(false, null);
|
117 |
+
}
|
118 |
+
|
119 |
$this->addParsedFile($realPath);
|
120 |
$parser = $this->makeParser($realPath);
|
121 |
$root = $parser->parse(file_get_contents($realPath));
|
283 |
foreach ($this->sortProps($block->props) as $prop) {
|
284 |
$this->compileProp($prop, $block, $out);
|
285 |
}
|
286 |
+
|
287 |
+
$out->lines = array_values(array_unique($out->lines));
|
288 |
}
|
289 |
|
290 |
protected function sortProps($props, $split = false) {
|
336 |
$parts[] = "($q[1])";
|
337 |
}
|
338 |
break;
|
339 |
+
case "variable":
|
340 |
+
$parts[] = $this->compileValue($this->reduce($q));
|
341 |
+
break;
|
342 |
}
|
343 |
}
|
344 |
|
446 |
foreach ($selectors as $s) {
|
447 |
if (is_array($s)) {
|
448 |
list(, $value) = $s;
|
449 |
+
$out[] = trim($this->compileValue($this->reduce($value)));
|
450 |
} else {
|
451 |
$out[] = $s;
|
452 |
}
|
459 |
return $left == $right;
|
460 |
}
|
461 |
|
462 |
+
protected function patternMatch($block, $orderedArgs, $keywordArgs) {
|
463 |
// match the guards if it has them
|
464 |
// any one of the groups must have all its guards pass for a match
|
465 |
if (!empty($block->guards)) {
|
467 |
foreach ($block->guards as $guardGroup) {
|
468 |
foreach ($guardGroup as $guard) {
|
469 |
$this->pushEnv();
|
470 |
+
$this->zipSetArgs($block->args, $orderedArgs, $keywordArgs);
|
471 |
|
472 |
$negate = false;
|
473 |
if ($guard[0] == "negate") {
|
496 |
}
|
497 |
}
|
498 |
|
|
|
|
|
499 |
if (empty($block->args)) {
|
500 |
+
return $block->isVararg || empty($orderedArgs) && empty($keywordArgs);
|
501 |
+
}
|
502 |
+
|
503 |
+
$remainingArgs = $block->args;
|
504 |
+
if ($keywordArgs) {
|
505 |
+
$remainingArgs = array();
|
506 |
+
foreach ($block->args as $arg) {
|
507 |
+
if ($arg[0] == "arg" && isset($keywordArgs[$arg[1]])) {
|
508 |
+
continue;
|
509 |
+
}
|
510 |
+
|
511 |
+
$remainingArgs[] = $arg;
|
512 |
+
}
|
513 |
}
|
514 |
|
515 |
$i = -1; // no args
|
516 |
// try to match by arity or by argument literal
|
517 |
+
foreach ($remainingArgs as $i => $arg) {
|
518 |
switch ($arg[0]) {
|
519 |
case "lit":
|
520 |
+
if (empty($orderedArgs[$i]) || !$this->eq($arg[1], $orderedArgs[$i])) {
|
521 |
return false;
|
522 |
}
|
523 |
break;
|
524 |
case "arg":
|
525 |
// no arg and no default value
|
526 |
+
if (!isset($orderedArgs[$i]) && !isset($arg[2])) {
|
527 |
return false;
|
528 |
}
|
529 |
break;
|
538 |
} else {
|
539 |
$numMatched = $i + 1;
|
540 |
// greater than becuase default values always match
|
541 |
+
return $numMatched >= count($orderedArgs);
|
542 |
}
|
543 |
}
|
544 |
|
545 |
+
protected function patternMatchAll($blocks, $orderedArgs, $keywordArgs, $skip=array()) {
|
546 |
$matches = null;
|
547 |
foreach ($blocks as $block) {
|
548 |
+
// skip seen blocks that don't have arguments
|
549 |
+
if (isset($skip[$block->id]) && !isset($block->args)) {
|
550 |
+
continue;
|
551 |
+
}
|
552 |
+
|
553 |
+
if ($this->patternMatch($block, $orderedArgs, $keywordArgs)) {
|
554 |
$matches[] = $block;
|
555 |
}
|
556 |
}
|
559 |
}
|
560 |
|
561 |
// attempt to find blocks matched by path and args
|
562 |
+
protected function findBlocks($searchIn, $path, $orderedArgs, $keywordArgs, $seen=array()) {
|
563 |
if ($searchIn == null) return null;
|
564 |
if (isset($seen[$searchIn->id])) return null;
|
565 |
$seen[$searchIn->id] = true;
|
569 |
if (isset($searchIn->children[$name])) {
|
570 |
$blocks = $searchIn->children[$name];
|
571 |
if (count($path) == 1) {
|
572 |
+
$matches = $this->patternMatchAll($blocks, $orderedArgs, $keywordArgs, $seen);
|
573 |
if (!empty($matches)) {
|
574 |
// This will return all blocks that match in the closest
|
575 |
// scope that has any matching block, like lessjs
|
579 |
$matches = array();
|
580 |
foreach ($blocks as $subBlock) {
|
581 |
$subMatches = $this->findBlocks($subBlock,
|
582 |
+
array_slice($path, 1), $orderedArgs, $keywordArgs, $seen);
|
583 |
|
584 |
if (!is_null($subMatches)) {
|
585 |
foreach ($subMatches as $sm) {
|
591 |
return count($matches) > 0 ? $matches : null;
|
592 |
}
|
593 |
}
|
|
|
594 |
if ($searchIn->parent === $searchIn) return null;
|
595 |
+
return $this->findBlocks($searchIn->parent, $path, $orderedArgs, $keywordArgs, $seen);
|
596 |
}
|
597 |
|
598 |
// sets all argument names in $args to either the default value
|
599 |
// or the one passed in through $values
|
600 |
+
protected function zipSetArgs($args, $orderedValues, $keywordValues) {
|
|
|
601 |
$assignedValues = array();
|
602 |
+
|
603 |
+
$i = 0;
|
604 |
+
foreach ($args as $a) {
|
605 |
if ($a[0] == "arg") {
|
606 |
+
if (isset($keywordValues[$a[1]])) {
|
607 |
+
// has keyword arg
|
608 |
+
$value = $keywordValues[$a[1]];
|
609 |
+
} elseif (isset($orderedValues[$i])) {
|
610 |
+
// has ordered arg
|
611 |
+
$value = $orderedValues[$i];
|
612 |
+
$i++;
|
613 |
} elseif (isset($a[2])) {
|
614 |
+
// has default value
|
615 |
$value = $a[2];
|
616 |
+
} else {
|
617 |
+
$this->throwError("Failed to assign arg " . $a[1]);
|
618 |
+
$value = null; // :(
|
619 |
+
}
|
620 |
|
621 |
$value = $this->reduce($value);
|
622 |
$this->set($a[1], $value);
|
623 |
$assignedValues[] = $value;
|
624 |
+
} else {
|
625 |
+
// a lit
|
626 |
+
$i++;
|
627 |
}
|
|
|
628 |
}
|
629 |
|
630 |
// check for a rest
|
631 |
$last = end($args);
|
632 |
if ($last[0] == "rest") {
|
633 |
+
$rest = array_slice($orderedValues, count($args) - 1);
|
634 |
$this->set($last[1], $this->reduce(array("list", " ", $rest)));
|
635 |
}
|
636 |
|
637 |
+
// wow is this the only true use of PHP's + operator for arrays?
|
638 |
+
$this->env->arguments = $assignedValues + $orderedValues;
|
639 |
}
|
640 |
|
641 |
// compile a prop and update $lines or $blocks appropriately
|
660 |
case 'mixin':
|
661 |
list(, $path, $args, $suffix) = $prop;
|
662 |
|
663 |
+
$orderedArgs = array();
|
664 |
+
$keywordArgs = array();
|
665 |
+
foreach ((array)$args as $arg) {
|
666 |
+
$argval = null;
|
667 |
+
switch ($arg[0]) {
|
668 |
+
case "arg":
|
669 |
+
if (!isset($arg[2])) {
|
670 |
+
$orderedArgs[] = $this->reduce(array("variable", $arg[1]));
|
671 |
+
} else {
|
672 |
+
$keywordArgs[$arg[1]] = $this->reduce($arg[2]);
|
673 |
+
}
|
674 |
+
break;
|
675 |
+
|
676 |
+
case "lit":
|
677 |
+
$orderedArgs[] = $this->reduce($arg[1]);
|
678 |
+
break;
|
679 |
+
default:
|
680 |
+
$this->throwError("Unknown arg type: " . $arg[0]);
|
681 |
+
}
|
682 |
+
}
|
683 |
+
|
684 |
+
$mixins = $this->findBlocks($block, $path, $orderedArgs, $keywordArgs);
|
685 |
|
686 |
if ($mixins === null) {
|
687 |
// fwrite(STDERR,"failed to find block: ".implode(" > ", $path)."\n");
|
689 |
}
|
690 |
|
691 |
foreach ($mixins as $mixin) {
|
692 |
+
if ($mixin === $block && !$orderedArgs) {
|
693 |
+
continue;
|
694 |
+
}
|
695 |
+
|
696 |
$haveScope = false;
|
697 |
if (isset($mixin->parent->scope)) {
|
698 |
$haveScope = true;
|
704 |
if (isset($mixin->args)) {
|
705 |
$haveArgs = true;
|
706 |
$this->pushEnv();
|
707 |
+
$this->zipSetArgs($mixin->args, $orderedArgs, $keywordArgs);
|
708 |
}
|
709 |
|
710 |
$oldParent = $mixin->parent;
|
761 |
list(,$importId) = $prop;
|
762 |
$import = $this->env->imports[$importId];
|
763 |
if ($import[0] === false) {
|
764 |
+
if (isset($import[1])) {
|
765 |
+
$out->lines[] = $import[1];
|
766 |
+
}
|
767 |
} else {
|
768 |
list(, $bottom, $parser, $importDir) = $import;
|
769 |
$this->compileImportedProps($bottom, $block, $out, $parser, $importDir);
|
851 |
}
|
852 |
}
|
853 |
|
854 |
+
protected function lib_pow($args) {
|
855 |
+
list($base, $exp) = $this->assertArgs($args, 2, "pow");
|
856 |
+
return pow($this->assertNumber($base), $this->assertNumber($exp));
|
857 |
+
}
|
858 |
+
|
859 |
+
protected function lib_pi() {
|
860 |
+
return pi();
|
861 |
+
}
|
862 |
+
|
863 |
+
protected function lib_mod($args) {
|
864 |
+
list($a, $b) = $this->assertArgs($args, 2, "mod");
|
865 |
+
return $this->assertNumber($a) % $this->assertNumber($b);
|
866 |
+
}
|
867 |
+
|
868 |
+
protected function lib_tan($num) {
|
869 |
+
return tan($this->assertNumber($num));
|
870 |
+
}
|
871 |
+
|
872 |
+
protected function lib_sin($num) {
|
873 |
+
return sin($this->assertNumber($num));
|
874 |
+
}
|
875 |
+
|
876 |
+
protected function lib_cos($num) {
|
877 |
+
return cos($this->assertNumber($num));
|
878 |
+
}
|
879 |
+
|
880 |
+
protected function lib_atan($num) {
|
881 |
+
$num = atan($this->assertNumber($num));
|
882 |
+
return array("number", $num, "rad");
|
883 |
+
}
|
884 |
+
|
885 |
+
protected function lib_asin($num) {
|
886 |
+
$num = asin($this->assertNumber($num));
|
887 |
+
return array("number", $num, "rad");
|
888 |
+
}
|
889 |
+
|
890 |
+
protected function lib_acos($num) {
|
891 |
+
$num = acos($this->assertNumber($num));
|
892 |
+
return array("number", $num, "rad");
|
893 |
+
}
|
894 |
+
|
895 |
+
protected function lib_sqrt($num) {
|
896 |
+
return sqrt($this->assertNumber($num));
|
897 |
+
}
|
898 |
+
|
899 |
+
protected function lib_extract($value) {
|
900 |
+
list($list, $idx) = $this->assertArgs($value, 2, "extract");
|
901 |
+
$idx = $this->assertNumber($idx);
|
902 |
+
// 1 indexed
|
903 |
+
if ($list[0] == "list" && isset($list[2][$idx - 1])) {
|
904 |
+
return $list[2][$idx - 1];
|
905 |
+
}
|
906 |
+
}
|
907 |
+
|
908 |
protected function lib_isnumber($value) {
|
909 |
return $this->toBool($value[0] == "number");
|
910 |
}
|
933 |
return $this->toBool($value[0] == "number" && $value[2] == "em");
|
934 |
}
|
935 |
|
936 |
+
protected function lib_isrem($value) {
|
937 |
+
return $this->toBool($value[0] == "number" && $value[2] == "rem");
|
938 |
+
}
|
939 |
+
|
940 |
protected function lib_rgbahex($color) {
|
941 |
$color = $this->coerceColor($color);
|
942 |
if (is_null($color))
|
1013 |
return array("number", round($value), $arg[2]);
|
1014 |
}
|
1015 |
|
1016 |
+
protected function lib_unit($arg) {
|
1017 |
+
if ($arg[0] == "list") {
|
1018 |
+
list($number, $newUnit) = $arg[2];
|
1019 |
+
return array("number", $this->assertNumber($number),
|
1020 |
+
$this->compileValue($this->lib_e($newUnit)));
|
1021 |
+
} else {
|
1022 |
+
return array("number", $this->assertNumber($arg), "");
|
1023 |
+
}
|
1024 |
+
}
|
1025 |
+
|
1026 |
/**
|
1027 |
* Helper function to get arguments for color manipulation functions.
|
1028 |
* takes a list that contains a color like thing and a percentage
|
1129 |
}
|
1130 |
|
1131 |
// mixes two colors by weight
|
1132 |
+
// mix(@color1, @color2, [@weight: 50%]);
|
1133 |
// http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method
|
1134 |
protected function lib_mix($args) {
|
1135 |
+
if ($args[0] != "list" || count($args[2]) < 2)
|
1136 |
$this->throwError("mix expects (color1, color2, weight)");
|
1137 |
|
1138 |
+
list($first, $second) = $args[2];
|
1139 |
$first = $this->assertColor($first);
|
1140 |
$second = $this->assertColor($second);
|
1141 |
|
1142 |
$first_a = $this->lib_alpha($first);
|
1143 |
$second_a = $this->lib_alpha($second);
|
1144 |
+
|
1145 |
+
if (isset($args[2][2])) {
|
1146 |
+
$weight = $args[2][2][1] / 100.0;
|
1147 |
+
} else {
|
1148 |
+
$weight = 0.5;
|
1149 |
+
}
|
1150 |
|
1151 |
$w = $weight * 2 - 1;
|
1152 |
$a = $first_a - $second_a;
|
1167 |
return $this->fixColor($new);
|
1168 |
}
|
1169 |
|
1170 |
+
protected function lib_contrast($args) {
|
1171 |
+
if ($args[0] != 'list' || count($args[2]) < 3) {
|
1172 |
+
return array(array('color', 0, 0, 0), 0);
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
list($inputColor, $darkColor, $lightColor) = $args[2];
|
1176 |
+
|
1177 |
+
$inputColor = $this->assertColor($inputColor);
|
1178 |
+
$darkColor = $this->assertColor($darkColor);
|
1179 |
+
$lightColor = $this->assertColor($lightColor);
|
1180 |
+
$hsl = $this->toHSL($inputColor);
|
1181 |
+
|
1182 |
+
if ($hsl[3] > 50) {
|
1183 |
+
return $darkColor;
|
1184 |
+
}
|
1185 |
+
|
1186 |
+
return $lightColor;
|
1187 |
+
}
|
1188 |
+
|
1189 |
protected function assertColor($value, $error = "expected color value") {
|
1190 |
$color = $this->coerceColor($value);
|
1191 |
if (is_null($color)) $this->throwError($error);
|
1197 |
$this->throwError($error);
|
1198 |
}
|
1199 |
|
1200 |
+
protected function assertArgs($value, $expectedArgs, $name="") {
|
1201 |
+
if ($expectedArgs == 1) {
|
1202 |
+
return $value;
|
1203 |
+
} else {
|
1204 |
+
if ($value[0] !== "list" || $value[1] != ",") $this->throwError("expecting list");
|
1205 |
+
$values = $value[2];
|
1206 |
+
$numValues = count($values);
|
1207 |
+
if ($expectedArgs != $numValues) {
|
1208 |
+
if ($name) {
|
1209 |
+
$name = $name . ": ";
|
1210 |
+
}
|
1211 |
+
|
1212 |
+
$this->throwError("${name}expecting $expectedArgs arguments, got $numValues");
|
1213 |
+
}
|
1214 |
+
|
1215 |
+
return $values;
|
1216 |
+
}
|
1217 |
+
}
|
1218 |
+
|
1219 |
protected function toHSL($color) {
|
1220 |
if ($color[0] == 'hsl') return $color;
|
1221 |
|
1267 |
* Expects H to be in range of 0 to 360, S and L in 0 to 100
|
1268 |
*/
|
1269 |
protected function toRGB($color) {
|
1270 |
+
if ($color[0] == 'color') return $color;
|
1271 |
|
1272 |
$H = $color[1] / 360;
|
1273 |
$S = $color[2] / 100;
|
1355 |
|
1356 |
protected function reduce($value, $forExpression = false) {
|
1357 |
switch ($value[0]) {
|
1358 |
+
case "interpolate":
|
1359 |
+
$reduced = $this->reduce($value[1]);
|
1360 |
+
$var = $this->compileValue($reduced);
|
1361 |
+
$res = $this->reduce(array("variable", $this->vPrefix . $var));
|
1362 |
+
|
1363 |
+
if ($res[0] == "raw_color") {
|
1364 |
+
$res = $this->coerceColor($res);
|
1365 |
+
}
|
1366 |
+
|
1367 |
+
if (empty($value[2])) $res = $this->lib_e($res);
|
1368 |
+
|
1369 |
+
return $res;
|
1370 |
case "variable":
|
1371 |
$key = $value[1];
|
1372 |
if (is_array($key)) {
|
1487 |
case 'keyword':
|
1488 |
$name = $value[1];
|
1489 |
if (isset(self::$cssColors[$name])) {
|
1490 |
+
$rgba = explode(',', self::$cssColors[$name]);
|
1491 |
+
|
1492 |
+
if(isset($rgba[3]))
|
1493 |
+
return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
|
1494 |
+
|
1495 |
+
return array('color', $rgba[0], $rgba[1], $rgba[2]);
|
1496 |
}
|
1497 |
return null;
|
1498 |
}
|
1637 |
return $this->fixColor($out);
|
1638 |
}
|
1639 |
|
1640 |
+
function lib_red($color){
|
1641 |
+
$color = $this->coerceColor($color);
|
1642 |
+
if (is_null($color)) {
|
1643 |
+
$this->throwError('color expected for red()');
|
1644 |
+
}
|
1645 |
+
|
1646 |
+
return $color[1];
|
1647 |
+
}
|
1648 |
+
|
1649 |
+
function lib_green($color){
|
1650 |
+
$color = $this->coerceColor($color);
|
1651 |
+
if (is_null($color)) {
|
1652 |
+
$this->throwError('color expected for green()');
|
1653 |
+
}
|
1654 |
+
|
1655 |
+
return $color[2];
|
1656 |
+
}
|
1657 |
+
|
1658 |
+
function lib_blue($color){
|
1659 |
+
$color = $this->coerceColor($color);
|
1660 |
+
if (is_null($color)) {
|
1661 |
+
$this->throwError('color expected for blue()');
|
1662 |
+
}
|
1663 |
+
|
1664 |
+
return $color[3];
|
1665 |
+
}
|
1666 |
+
|
1667 |
+
|
1668 |
// operator on two numbers
|
1669 |
protected function op_number_number($op, $left, $right) {
|
1670 |
$unit = empty($left[2]) ? $right[2] : $left[2];
|
1825 |
$this->importDir = (array)$this->importDir;
|
1826 |
$this->importDir[] = $pi['dirname'].'/';
|
1827 |
|
|
|
1828 |
$this->addParsedFile($fname);
|
1829 |
|
1830 |
$out = $this->compile(file_get_contents($fname), $fname);
|
2164 |
'teal' => '0,128,128',
|
2165 |
'thistle' => '216,191,216',
|
2166 |
'tomato' => '255,99,71',
|
2167 |
+
'transparent' => '0,0,0,0',
|
2168 |
'turquoise' => '64,224,208',
|
2169 |
'violet' => '238,130,238',
|
2170 |
'wheat' => '245,222,179',
|
2208 |
static protected $supressDivisionProps =
|
2209 |
array('/border-radius$/i', '/^font$/i');
|
2210 |
|
2211 |
+
protected $blockDirectives = array("font-face", "keyframes", "page", "-moz-document", "viewport", "-moz-viewport", "-o-viewport", "-ms-viewport");
|
2212 |
protected $lineDirectives = array("charset");
|
2213 |
|
2214 |
/**
|
2447 |
|
2448 |
// mixin
|
2449 |
if ($this->mixinTags($tags) &&
|
2450 |
+
($this->argumentDef($argv, $isVararg) || true) &&
|
2451 |
($this->keyword($suffix) || true) && $this->end())
|
2452 |
{
|
2453 |
$tags = $this->fixTags($tags);
|
2739 |
$out = array("mediaExp", $feature);
|
2740 |
if ($value) $out[] = $value;
|
2741 |
return true;
|
2742 |
+
} elseif ($this->variable($variable)) {
|
2743 |
+
$out = array('variable', $variable);
|
2744 |
+
return true;
|
2745 |
}
|
2746 |
|
2747 |
$this->seek($s);
|
2795 |
continue;
|
2796 |
}
|
2797 |
|
2798 |
+
if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) {
|
|
|
2799 |
break;
|
2800 |
}
|
2801 |
|
|
|
2802 |
$content[] = $tok;
|
2803 |
$this->count+= strlen($tok);
|
2804 |
}
|
2873 |
|
2874 |
$s = $this->seek();
|
2875 |
if ($this->literal("@{") &&
|
2876 |
+
$this->openString("}", $interp, null, array("'", '"', ";")) &&
|
2877 |
$this->literal("}", false))
|
2878 |
{
|
2879 |
+
$out = array("interpolate", $interp);
|
2880 |
$this->eatWhiteDefault = $oldWhite;
|
2881 |
if ($this->eatWhiteDefault) $this->whitespace();
|
2882 |
return true;
|
2915 |
return false;
|
2916 |
}
|
2917 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2918 |
// consume an argument definition list surrounded by ()
|
2919 |
// each argument is a variable name with optional value
|
2920 |
// or at the end a ... or a variable named followed by ...
|
2921 |
+
// arguments are separated by , unless a ; is in the list, then ; is the
|
2922 |
+
// delimiter.
|
2923 |
+
protected function argumentDef(&$args, &$isVararg) {
|
2924 |
$s = $this->seek();
|
2925 |
if (!$this->literal('(')) return false;
|
2926 |
|
2927 |
$values = array();
|
2928 |
+
$delim = ",";
|
2929 |
+
$method = "expressionList";
|
2930 |
|
2931 |
$isVararg = false;
|
2932 |
while (true) {
|
2935 |
break;
|
2936 |
}
|
2937 |
|
2938 |
+
if ($this->$method($value)) {
|
2939 |
+
if ($value[0] == "variable") {
|
2940 |
+
$arg = array("arg", $value[1]);
|
2941 |
+
$ss = $this->seek();
|
2942 |
+
|
2943 |
+
if ($this->assign() && $this->$method($rhs)) {
|
2944 |
+
$arg[] = $rhs;
|
2945 |
+
} else {
|
2946 |
+
$this->seek($ss);
|
2947 |
+
if ($this->literal("...")) {
|
2948 |
+
$arg[0] = "rest";
|
2949 |
+
$isVararg = true;
|
2950 |
+
}
|
2951 |
}
|
2952 |
+
|
2953 |
+
$values[] = $arg;
|
2954 |
+
if ($isVararg) break;
|
2955 |
+
continue;
|
2956 |
+
} else {
|
2957 |
+
$values[] = array("lit", $value);
|
2958 |
}
|
|
|
|
|
|
|
2959 |
}
|
2960 |
|
|
|
|
|
|
|
2961 |
|
2962 |
+
if (!$this->literal($delim)) {
|
2963 |
+
if ($delim == "," && $this->literal(";")) {
|
2964 |
+
// found new delim, convert existing args
|
2965 |
+
$delim = ";";
|
2966 |
+
$method = "propertyValue";
|
2967 |
+
|
2968 |
+
// transform arg list
|
2969 |
+
if (isset($values[1])) { // 2 items
|
2970 |
+
$newList = array();
|
2971 |
+
foreach ($values as $i => $arg) {
|
2972 |
+
switch($arg[0]) {
|
2973 |
+
case "arg":
|
2974 |
+
if ($i) {
|
2975 |
+
$this->throwError("Cannot mix ; and , as delimiter types");
|
2976 |
+
}
|
2977 |
+
$newList[] = $arg[2];
|
2978 |
+
break;
|
2979 |
+
case "lit":
|
2980 |
+
$newList[] = $arg[1];
|
2981 |
+
break;
|
2982 |
+
case "rest":
|
2983 |
+
$this->throwError("Unexpected rest before semicolon");
|
2984 |
+
}
|
2985 |
+
}
|
2986 |
+
|
2987 |
+
$newList = array("list", ", ", $newList);
|
2988 |
+
|
2989 |
+
switch ($values[0][0]) {
|
2990 |
+
case "arg":
|
2991 |
+
$newArg = array("arg", $values[0][1], $newList);
|
2992 |
+
break;
|
2993 |
+
case "lit":
|
2994 |
+
$newArg = array("lit", $newList);
|
2995 |
+
break;
|
2996 |
+
}
|
2997 |
+
|
2998 |
+
} elseif ($values) { // 1 item
|
2999 |
+
$newArg = $values[0];
|
3000 |
+
}
|
3001 |
+
|
3002 |
+
if ($newArg) {
|
3003 |
+
$values = array($newArg);
|
3004 |
+
}
|
3005 |
+
} else {
|
3006 |
+
break;
|
3007 |
+
}
|
3008 |
+
}
|
3009 |
}
|
3010 |
|
3011 |
if (!$this->literal(')')) {
|
3047 |
}
|
3048 |
|
3049 |
// a bracketed value (contained within in a tag definition)
|
3050 |
+
protected function tagBracket(&$parts, &$hasExpression) {
|
3051 |
// speed shortcut
|
3052 |
if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") {
|
3053 |
return false;
|
3054 |
}
|
3055 |
|
3056 |
$s = $this->seek();
|
|
|
|
|
|
|
|
|
3057 |
|
3058 |
+
$hasInterpolation = false;
|
|
|
|
|
|
|
3059 |
|
3060 |
+
if ($this->literal("[", false)) {
|
3061 |
+
$attrParts = array("[");
|
3062 |
+
// keyword, string, operator
|
3063 |
+
while (true) {
|
3064 |
+
if ($this->literal("]", false)) {
|
3065 |
+
$this->count--;
|
3066 |
+
break; // get out early
|
3067 |
+
}
|
3068 |
|
3069 |
+
if ($this->match('\s+', $m)) {
|
3070 |
+
$attrParts[] = " ";
|
3071 |
+
continue;
|
3072 |
+
}
|
3073 |
+
if ($this->string($str)) {
|
3074 |
+
// escape parent selector, (yuck)
|
3075 |
+
foreach ($str[2] as &$chunk) {
|
3076 |
+
$chunk = str_replace($this->lessc->parentSelector, "$&$", $chunk);
|
3077 |
+
}
|
3078 |
+
|
3079 |
+
$attrParts[] = $str;
|
3080 |
+
$hasInterpolation = true;
|
3081 |
+
continue;
|
3082 |
+
}
|
3083 |
+
|
3084 |
+
if ($this->keyword($word)) {
|
3085 |
+
$attrParts[] = $word;
|
3086 |
+
continue;
|
3087 |
+
}
|
3088 |
+
|
3089 |
+
if ($this->interpolation($inter, false)) {
|
3090 |
+
$attrParts[] = $inter;
|
3091 |
+
$hasInterpolation = true;
|
3092 |
+
continue;
|
3093 |
+
}
|
3094 |
+
|
3095 |
+
// operator, handles attr namespace too
|
3096 |
+
if ($this->match('[|-~\$\*\^=]+', $m)) {
|
3097 |
+
$attrParts[] = $m[0];
|
3098 |
+
continue;
|
3099 |
+
}
|
3100 |
+
|
3101 |
+
break;
|
3102 |
+
}
|
3103 |
+
|
3104 |
+
if ($this->literal("]", false)) {
|
3105 |
+
$attrParts[] = "]";
|
3106 |
+
foreach ($attrParts as $part) {
|
3107 |
+
$parts[] = $part;
|
3108 |
+
}
|
3109 |
+
$hasExpression = $hasExpression || $hasInterpolation;
|
3110 |
+
return true;
|
3111 |
+
}
|
3112 |
+
$this->seek($s);
|
3113 |
}
|
3114 |
|
3115 |
$this->seek($s);
|
3116 |
return false;
|
3117 |
}
|
3118 |
|
3119 |
+
// a space separated list of selectors
|
3120 |
protected function tag(&$tag, $simple = false) {
|
3121 |
if ($simple)
|
3122 |
+
$chars = '^@,:;{}\][>\(\) "\'';
|
3123 |
else
|
3124 |
+
$chars = '^@,;{}["\'';
|
3125 |
|
3126 |
+
$s = $this->seek();
|
|
|
|
|
3127 |
|
3128 |
+
$hasExpression = false;
|
3129 |
+
$parts = array();
|
3130 |
+
while ($this->tagBracket($parts, $hasExpression));
|
3131 |
+
|
3132 |
+
$oldWhite = $this->eatWhiteDefault;
|
3133 |
+
$this->eatWhiteDefault = false;
|
3134 |
|
3135 |
while (true) {
|
3136 |
if ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) {
|
3137 |
+
$parts[] = $m[1];
|
3138 |
if ($simple) break;
|
3139 |
|
3140 |
+
while ($this->tagBracket($parts, $hasExpression));
|
3141 |
continue;
|
3142 |
+
}
|
3143 |
+
|
3144 |
+
if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") {
|
3145 |
+
if ($this->interpolation($interp)) {
|
3146 |
+
$hasExpression = true;
|
3147 |
+
$interp[2] = true; // don't unescape
|
3148 |
+
$parts[] = $interp;
|
3149 |
+
continue;
|
3150 |
+
}
|
3151 |
+
|
3152 |
+
if ($this->literal("@")) {
|
3153 |
+
$parts[] = "@";
|
3154 |
+
continue;
|
3155 |
+
}
|
3156 |
+
}
|
3157 |
+
|
3158 |
+
if ($this->unit($unit)) { // for keyframes
|
3159 |
+
$parts[] = $unit[1];
|
3160 |
+
$parts[] = $unit[2];
|
3161 |
continue;
|
3162 |
}
|
3163 |
+
|
3164 |
break;
|
3165 |
}
|
3166 |
|
3167 |
+
$this->eatWhiteDefault = $oldWhite;
|
3168 |
+
if (!$parts) {
|
3169 |
+
$this->seek($s);
|
3170 |
+
return false;
|
3171 |
+
}
|
3172 |
|
3173 |
+
if ($hasExpression) {
|
3174 |
+
$tag = array("exp", array("string", "", $parts));
|
3175 |
+
} else {
|
3176 |
+
$tag = trim(implode($parts));
|
3177 |
+
}
|
3178 |
|
3179 |
+
$this->whitespace();
|
3180 |
return true;
|
3181 |
}
|
3182 |
|
3264 |
protected function end() {
|
3265 |
if ($this->literal(';')) {
|
3266 |
return true;
|
3267 |
+
} elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') {
|
3268 |
// if there is end of file or a closing block next then we don't need a ;
|
3269 |
return true;
|
3270 |
}
|
3528 |
break;
|
3529 |
case '"':
|
3530 |
case "'":
|
3531 |
+
if (preg_match('/'.$min[0].'.*?(?<!\\\\)'.$min[0].'/', $text, $m, 0, $count))
|
3532 |
$count += strlen($m[0]) - 1;
|
3533 |
break;
|
3534 |
case '//':
|
3672 |
public $selectorSeparator = ",";
|
3673 |
}
|
3674 |
|
|
modules/custom-css/custom-css/preprocessors/scss.inc.php
CHANGED
@@ -1,7 +1,49 @@
|
|
1 |
<?php
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
class scssc {
|
4 |
-
static public $VERSION = "v0.0.
|
5 |
|
6 |
static protected $operatorNames = array(
|
7 |
'+' => "add",
|
@@ -25,7 +67,7 @@ class scssc {
|
|
25 |
"function" => "^",
|
26 |
);
|
27 |
|
28 |
-
static protected $numberPrecision =
|
29 |
static protected $unitTable = array(
|
30 |
"in" => array(
|
31 |
"in" => 1,
|
@@ -39,6 +81,7 @@ class scssc {
|
|
39 |
|
40 |
static public $true = array("keyword", "true");
|
41 |
static public $false = array("keyword", "false");
|
|
|
42 |
|
43 |
static public $defaultValue = array("keyword", "");
|
44 |
static public $selfSelector = array("self");
|
@@ -69,17 +112,28 @@ class scssc {
|
|
69 |
$this->scope = null;
|
70 |
|
71 |
$this->compileRoot($tree);
|
72 |
-
$this->flattenSelectors($this->scope);
|
73 |
|
74 |
-
|
75 |
-
$this->formatter->block($this->scope);
|
76 |
-
$out = ob_get_clean();
|
77 |
|
78 |
setlocale(LC_NUMERIC, $locale);
|
79 |
return $out;
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
protected function pushExtends($target, $origin) {
|
|
|
|
|
|
|
|
|
83 |
$i = count($this->extends);
|
84 |
$this->extends[] = array($target, $origin);
|
85 |
|
@@ -93,7 +147,7 @@ class scssc {
|
|
93 |
}
|
94 |
|
95 |
protected function makeOutputBlock($type, $selectors = null) {
|
96 |
-
$out = new
|
97 |
$out->type = $type;
|
98 |
$out->lines = array();
|
99 |
$out->children = array();
|
@@ -104,7 +158,7 @@ class scssc {
|
|
104 |
return $out;
|
105 |
}
|
106 |
|
107 |
-
protected function matchExtendsSingle($single, &$
|
108 |
$counts = array();
|
109 |
foreach ($single as $part) {
|
110 |
if (!is_string($part)) return false; // hmm
|
@@ -117,20 +171,30 @@ class scssc {
|
|
117 |
}
|
118 |
}
|
119 |
|
|
|
|
|
|
|
120 |
foreach ($counts as $idx => $count) {
|
121 |
list($target, $origin) = $this->extends[$idx];
|
|
|
122 |
// check count
|
123 |
if ($count != count($target)) continue;
|
|
|
124 |
// check if target is subset of single
|
125 |
if (array_diff(array_intersect($single, $target), $target)) continue;
|
126 |
|
127 |
-
$
|
128 |
-
$out_rem = array_diff($single, $target);
|
129 |
|
130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
}
|
132 |
|
133 |
-
return
|
134 |
}
|
135 |
|
136 |
protected function combineSelectorSingle($base, $other) {
|
@@ -139,7 +203,7 @@ class scssc {
|
|
139 |
|
140 |
foreach (array($base, $other) as $single) {
|
141 |
foreach ($single as $part) {
|
142 |
-
if (preg_match('/^[
|
143 |
$tag = $part;
|
144 |
} else {
|
145 |
$out[] = $part;
|
@@ -158,15 +222,13 @@ class scssc {
|
|
158 |
foreach ($selector as $i => $part) {
|
159 |
if ($i < $from) continue;
|
160 |
|
161 |
-
if ($this->matchExtendsSingle($part, $origin
|
162 |
$before = array_slice($selector, 0, $i);
|
163 |
$after = array_slice($selector, $i + 1);
|
164 |
|
165 |
foreach ($origin as $new) {
|
166 |
-
$new[count($new) - 1] =
|
167 |
-
$this->combineSelectorSingle(end($new), $rem);
|
168 |
-
|
169 |
$k = 0;
|
|
|
170 |
// remove shared parts
|
171 |
if ($initial) {
|
172 |
foreach ($before as $k => $val) {
|
@@ -203,7 +265,7 @@ class scssc {
|
|
203 |
}
|
204 |
}
|
205 |
|
206 |
-
protected function flattenSelectors($block) {
|
207 |
if ($block->selectors) {
|
208 |
$selectors = array();
|
209 |
foreach ($block->selectors as $s) {
|
@@ -215,19 +277,34 @@ class scssc {
|
|
215 |
}
|
216 |
}
|
217 |
|
218 |
-
$selectors =
|
219 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
}
|
221 |
|
222 |
-
foreach ($block->children as $child) {
|
223 |
-
$this->flattenSelectors($child);
|
224 |
}
|
225 |
}
|
226 |
|
227 |
protected function compileRoot($rootBlock) {
|
228 |
$this->pushEnv($rootBlock);
|
229 |
$this->scope = $this->makeOutputBlock("root");
|
|
|
230 |
$this->compileChildren($rootBlock->children, $this->scope);
|
|
|
|
|
231 |
$this->popEnv();
|
232 |
}
|
233 |
|
@@ -241,6 +318,24 @@ class scssc {
|
|
241 |
|
242 |
$parentScope->children[] = $this->scope;
|
243 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
244 |
$this->compileChildren($media->children, $this->scope);
|
245 |
|
246 |
$this->scope = $this->scope->parent;
|
@@ -270,6 +365,24 @@ class scssc {
|
|
270 |
$this->popEnv();
|
271 |
}
|
272 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
protected function compileBlock($block) {
|
274 |
$env = $this->pushEnv($block);
|
275 |
|
@@ -289,7 +402,7 @@ class scssc {
|
|
289 |
foreach ($single as $part) {
|
290 |
if (empty($joined) ||
|
291 |
!is_string($part) ||
|
292 |
-
preg_match('/[
|
293 |
{
|
294 |
$joined[] = $part;
|
295 |
continue;
|
@@ -318,6 +431,9 @@ class scssc {
|
|
318 |
case "interpolate":
|
319 |
$p = $this->compileValue($p);
|
320 |
break;
|
|
|
|
|
|
|
321 |
}
|
322 |
}
|
323 |
|
@@ -350,6 +466,21 @@ class scssc {
|
|
350 |
return implode($piece);
|
351 |
}
|
352 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
protected function compileChildren($stms, $out) {
|
354 |
foreach ($stms as $stm) {
|
355 |
$ret = $this->compileChild($stm, $out);
|
@@ -365,13 +496,13 @@ class scssc {
|
|
365 |
foreach ($query as $q) {
|
366 |
switch ($q[0]) {
|
367 |
case "mediaType":
|
368 |
-
$parts[] = implode(" ", array_slice($q, 1));
|
369 |
break;
|
370 |
case "mediaExp":
|
371 |
if (isset($q[2])) {
|
372 |
-
$parts[] = "($q[1]
|
373 |
} else {
|
374 |
-
$parts[] = "($q[1])";
|
375 |
}
|
376 |
break;
|
377 |
}
|
@@ -398,7 +529,8 @@ class scssc {
|
|
398 |
return true;
|
399 |
}
|
400 |
return false;
|
401 |
-
}
|
|
|
402 |
// handle a list of strings
|
403 |
if (count($rawPath[2]) == 0) return false;
|
404 |
foreach ($rawPath[2] as $path) {
|
@@ -417,6 +549,9 @@ class scssc {
|
|
417 |
|
418 |
// return a value to halt execution
|
419 |
protected function compileChild($child, $out) {
|
|
|
|
|
|
|
420 |
switch ($child[0]) {
|
421 |
case "import":
|
422 |
list(,$rawPath) = $child;
|
@@ -446,15 +581,31 @@ class scssc {
|
|
446 |
list(,$name, $value) = $child;
|
447 |
if ($name[0] == "var") {
|
448 |
$isDefault = !empty($child[3]);
|
449 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
$this->set($name[1], $this->reduce($value));
|
451 |
}
|
452 |
break;
|
453 |
}
|
454 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
455 |
$out->lines[] = $this->formatter->property(
|
456 |
-
$this->compileValue($
|
457 |
-
$
|
458 |
break;
|
459 |
case "comment":
|
460 |
$out->lines[] = $child[1];
|
@@ -474,12 +625,12 @@ class scssc {
|
|
474 |
break;
|
475 |
case "if":
|
476 |
list(, $if) = $child;
|
477 |
-
if ($this->reduce($if->cond, true)
|
478 |
return $this->compileChildren($if->children, $out);
|
479 |
} else {
|
480 |
foreach ($if->cases as $case) {
|
481 |
if ($case->type == "else" ||
|
482 |
-
$case->type == "elseif" && ($this->reduce($case->cond)
|
483 |
{
|
484 |
return $this->compileChildren($case->children, $out);
|
485 |
}
|
@@ -490,7 +641,7 @@ class scssc {
|
|
490 |
return $this->reduce($child[1], true);
|
491 |
case "each":
|
492 |
list(,$each) = $child;
|
493 |
-
$list = $this->
|
494 |
foreach ($list[2] as $item) {
|
495 |
$this->pushEnv();
|
496 |
$this->set($each->var, $item);
|
@@ -501,7 +652,7 @@ class scssc {
|
|
501 |
break;
|
502 |
case "while":
|
503 |
list(,$while) = $child;
|
504 |
-
while ($this->reduce($while->cond, true)
|
505 |
$ret = $this->compileChildren($while->children, $out);
|
506 |
if ($ret) return $ret;
|
507 |
}
|
@@ -547,12 +698,17 @@ class scssc {
|
|
547 |
case "include": // including a mixin
|
548 |
list(,$name, $argValues, $content) = $child;
|
549 |
$mixin = $this->get(self::$namespaces["mixin"] . $name, false);
|
550 |
-
if (!$mixin)
|
|
|
|
|
551 |
|
552 |
$callingScope = $this->env;
|
553 |
|
554 |
// push scope, apply args
|
555 |
$this->pushEnv();
|
|
|
|
|
|
|
556 |
|
557 |
if (!is_null($content)) {
|
558 |
$content->scope = $callingScope;
|
@@ -573,12 +729,14 @@ class scssc {
|
|
573 |
case "mixin_content":
|
574 |
$content = $this->get(self::$namespaces["special"] . "content");
|
575 |
if (is_null($content)) {
|
576 |
-
|
577 |
}
|
578 |
|
579 |
-
$this->storeEnv = $content->scope;
|
580 |
-
|
581 |
foreach ($content->children as $child) {
|
|
|
|
|
|
|
|
|
582 |
$this->compileChild($child, $out);
|
583 |
}
|
584 |
|
@@ -591,20 +749,24 @@ class scssc {
|
|
591 |
fwrite(STDERR, "Line $line DEBUG: $value\n");
|
592 |
break;
|
593 |
default:
|
594 |
-
|
595 |
}
|
596 |
}
|
597 |
|
598 |
protected function expToString($exp) {
|
599 |
list(, $op, $left, $right, $inParens, $whiteLeft, $whiteRight) = $exp;
|
600 |
-
$content = array($left);
|
601 |
if ($whiteLeft) $content[] = " ";
|
602 |
$content[] = $op;
|
603 |
if ($whiteRight) $content[] = " ";
|
604 |
-
$content[] = $right;
|
605 |
return array("string", "", $content);
|
606 |
}
|
607 |
|
|
|
|
|
|
|
|
|
608 |
// should $value cause its operand to eval
|
609 |
protected function shouldEval($value) {
|
610 |
switch ($value[0]) {
|
@@ -662,7 +824,7 @@ class scssc {
|
|
662 |
$left[0] == "number" && $right[0] == "number")
|
663 |
{
|
664 |
if ($opName == "mod" && $right[2] != "") {
|
665 |
-
|
666 |
}
|
667 |
|
668 |
$unitChange = true;
|
@@ -796,6 +958,27 @@ class scssc {
|
|
796 |
}
|
797 |
}
|
798 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
799 |
// just does physical lengths for now
|
800 |
protected function normalizeNumber($number) {
|
801 |
list(, $value, $unit) = $number;
|
@@ -887,12 +1070,16 @@ class scssc {
|
|
887 |
break;
|
888 |
case '/':
|
889 |
if ($rval == 0) {
|
890 |
-
|
891 |
}
|
892 |
$out[] = $lval / $rval;
|
893 |
break;
|
|
|
|
|
|
|
|
|
894 |
default:
|
895 |
-
|
896 |
}
|
897 |
}
|
898 |
|
@@ -948,6 +1135,19 @@ class scssc {
|
|
948 |
return $thing ? self::$true : self::$false;
|
949 |
}
|
950 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
951 |
protected function compileValue($value) {
|
952 |
$value = $this->reduce($value);
|
953 |
|
@@ -990,10 +1190,14 @@ class scssc {
|
|
990 |
if ($value[0] != "list") return $this->compileValue($value);
|
991 |
|
992 |
list(, $delim, $items) = $value;
|
993 |
-
|
994 |
-
|
|
|
|
|
|
|
995 |
}
|
996 |
-
|
|
|
997 |
case "interpolated": # node created by extractInterpolation
|
998 |
list(, $interpolate, $left, $right) = $value;
|
999 |
list(,, $whiteLeft, $whiteRight) = $interpolate;
|
@@ -1011,14 +1215,20 @@ class scssc {
|
|
1011 |
|
1012 |
// strip quotes if it's a string
|
1013 |
$reduced = $this->reduce($exp);
|
1014 |
-
|
1015 |
-
|
1016 |
-
$
|
|
|
|
|
|
|
|
|
1017 |
}
|
1018 |
|
1019 |
return $this->compileValue($reduced);
|
|
|
|
|
1020 |
default:
|
1021 |
-
|
1022 |
}
|
1023 |
}
|
1024 |
|
@@ -1049,28 +1259,28 @@ class scssc {
|
|
1049 |
}
|
1050 |
|
1051 |
// find the final set of selectors
|
1052 |
-
protected function multiplySelectors($env
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
}
|
1061 |
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
$selectors = array();
|
1066 |
-
foreach ($env->selectors as $
|
1067 |
-
foreach ($
|
1068 |
-
$selectors[] = $this->joinSelectors($parent, $
|
1069 |
}
|
1070 |
}
|
|
|
1071 |
}
|
1072 |
|
1073 |
-
return $
|
1074 |
}
|
1075 |
|
1076 |
// looks for & to replace, or append parent before child
|
@@ -1142,31 +1352,69 @@ class scssc {
|
|
1142 |
}
|
1143 |
|
1144 |
protected function applyArguments($argDef, $argValues) {
|
1145 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
1146 |
|
1147 |
$keywordArgs = array();
|
|
|
1148 |
$remaining = array();
|
1149 |
-
|
1150 |
// assign the keyword args
|
1151 |
-
foreach ($argValues as $arg) {
|
1152 |
if (!empty($arg[0])) {
|
1153 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1154 |
} else {
|
1155 |
$remaining[] = $arg[1];
|
1156 |
}
|
1157 |
}
|
1158 |
|
1159 |
-
foreach ($
|
1160 |
-
list($name, $default) = $arg;
|
1161 |
-
|
1162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1163 |
$val = $remaining[$i];
|
1164 |
} elseif (isset($keywordArgs[$name])) {
|
1165 |
$val = $keywordArgs[$name];
|
1166 |
} elseif (!empty($default)) {
|
1167 |
$val = $default;
|
1168 |
} else {
|
1169 |
-
$
|
1170 |
}
|
1171 |
|
1172 |
$this->set($name, $this->reduce($val, true), true);
|
@@ -1174,7 +1422,7 @@ class scssc {
|
|
1174 |
}
|
1175 |
|
1176 |
protected function pushEnv($block=null) {
|
1177 |
-
$env = new
|
1178 |
$env->parent = $this->env;
|
1179 |
$env->store = array();
|
1180 |
$env->block = $block;
|
@@ -1194,6 +1442,7 @@ class scssc {
|
|
1194 |
|
1195 |
protected function set($name, $value, $shadow=false) {
|
1196 |
$name = $this->normalizeName($name);
|
|
|
1197 |
if ($shadow) {
|
1198 |
$this->setRaw($name, $value);
|
1199 |
} else {
|
@@ -1226,7 +1475,7 @@ class scssc {
|
|
1226 |
|
1227 |
if (isset($env->store[$name])) {
|
1228 |
return $env->store[$name];
|
1229 |
-
} elseif (
|
1230 |
return $this->get($name, $defaultValue, $env->parent);
|
1231 |
}
|
1232 |
|
@@ -1270,7 +1519,7 @@ class scssc {
|
|
1270 |
$tree = $this->importCache[$realPath];
|
1271 |
} else {
|
1272 |
$code = file_get_contents($path);
|
1273 |
-
$parser = new scss_parser($path);
|
1274 |
$tree = $parser->parse($code);
|
1275 |
$this->parsedFiles[] = $path;
|
1276 |
|
@@ -1336,7 +1585,7 @@ class scssc {
|
|
1336 |
$val = $this->reduce($val, true);
|
1337 |
}
|
1338 |
$returnValue = call_user_func($f, $sorted, $this);
|
1339 |
-
}
|
1340 |
// see if we can find a user function
|
1341 |
$fn = $this->userFunctions[$name];
|
1342 |
|
@@ -1420,7 +1669,7 @@ class scssc {
|
|
1420 |
$name = $value[1];
|
1421 |
if (isset(self::$cssColors[$name])) {
|
1422 |
list($r, $g, $b) = explode(',', self::$cssColors[$name]);
|
1423 |
-
return array('color', $r, $g, $b);
|
1424 |
}
|
1425 |
return null;
|
1426 |
}
|
@@ -1438,14 +1687,20 @@ class scssc {
|
|
1438 |
return null;
|
1439 |
}
|
1440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1441 |
protected function assertColor($value) {
|
1442 |
if ($color = $this->coerceColor($value)) return $color;
|
1443 |
-
|
1444 |
}
|
1445 |
|
1446 |
protected function assertNumber($value) {
|
1447 |
if ($value[0] != "number")
|
1448 |
-
|
1449 |
return $value[1];
|
1450 |
}
|
1451 |
|
@@ -1469,74 +1724,71 @@ class scssc {
|
|
1469 |
return $c;
|
1470 |
}
|
1471 |
|
1472 |
-
function toHSL($
|
1473 |
-
$r = $
|
1474 |
-
$g = $
|
1475 |
-
$b = $
|
1476 |
|
1477 |
$min = min($r, $g, $b);
|
1478 |
$max = max($r, $g, $b);
|
|
|
|
|
1479 |
|
1480 |
-
$L = ($min + $max) / 2;
|
1481 |
if ($min == $max) {
|
1482 |
-
$
|
1483 |
} else {
|
1484 |
-
if ($
|
1485 |
-
$
|
1486 |
else
|
1487 |
-
$
|
1488 |
-
|
1489 |
-
if ($r == $max) $H = ($g - $b)/($max - $min);
|
1490 |
-
elseif ($g == $max) $H = 2.0 + ($b - $r)/($max - $min);
|
1491 |
-
elseif ($b == $max) $H = 4.0 + ($r - $g)/($max - $min);
|
1492 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1493 |
}
|
1494 |
|
1495 |
-
return array('hsl',
|
1496 |
-
($H < 0 ? $H + 6 : $H)*60,
|
1497 |
-
$S*100,
|
1498 |
-
$L*100,
|
1499 |
-
);
|
1500 |
}
|
1501 |
|
1502 |
-
function
|
1503 |
-
if ($
|
1504 |
-
|
|
|
|
|
1505 |
|
1506 |
-
if (
|
1507 |
-
|
1508 |
-
if (3 * $comp < 2) return $temp1 + ($temp2 - $temp1)*((2/3) - $comp) * 6;
|
1509 |
|
1510 |
-
|
1511 |
-
|
1512 |
|
1513 |
-
|
1514 |
-
|
1515 |
-
$H = $H % 360;
|
1516 |
-
if ($H < 0) $H += 360;
|
1517 |
|
1518 |
-
|
1519 |
-
|
1520 |
|
1521 |
-
|
1522 |
-
|
1523 |
-
$
|
|
|
|
|
1524 |
|
1525 |
-
|
1526 |
-
|
1527 |
-
|
1528 |
-
$temp2 = $L < 0.5 ?
|
1529 |
-
$L*(1.0 + $S) :
|
1530 |
-
$L + $S - $L * $S;
|
1531 |
|
1532 |
-
|
|
|
1533 |
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
}
|
1538 |
|
1539 |
-
$out = array('color', $r
|
1540 |
return $out;
|
1541 |
}
|
1542 |
|
@@ -1549,6 +1801,20 @@ class scssc {
|
|
1549 |
return $t;
|
1550 |
}
|
1551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1552 |
protected static $lib_rgb = array("red", "green", "blue");
|
1553 |
protected function lib_rgb($args) {
|
1554 |
list($r,$g,$b) = $args;
|
@@ -1687,11 +1953,13 @@ class scssc {
|
|
1687 |
}
|
1688 |
|
1689 |
// this might be the IE function, so return value unchanged
|
1690 |
-
return
|
1691 |
}
|
1692 |
|
1693 |
protected static $lib_opacity = array("color");
|
1694 |
protected function lib_opacity($args) {
|
|
|
|
|
1695 |
return $this->lib_alpha($args);
|
1696 |
}
|
1697 |
|
@@ -1708,11 +1976,11 @@ class scssc {
|
|
1708 |
$weight = $this->coercePercent($weight);
|
1709 |
}
|
1710 |
|
1711 |
-
$
|
1712 |
-
$
|
1713 |
|
1714 |
$w = $weight * 2 - 1;
|
1715 |
-
$a = $
|
1716 |
|
1717 |
$w1 = (($w * $a == -1 ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2.0;
|
1718 |
$w2 = 1.0 - $w1;
|
@@ -1723,8 +1991,8 @@ class scssc {
|
|
1723 |
$w1 * $first[3] + $w2 * $second[3],
|
1724 |
);
|
1725 |
|
1726 |
-
if ($
|
1727 |
-
$new[] = $
|
1728 |
}
|
1729 |
|
1730 |
return $this->fixColor($new);
|
@@ -1766,7 +2034,6 @@ class scssc {
|
|
1766 |
return array("number", $hsl[3], "%");
|
1767 |
}
|
1768 |
|
1769 |
-
|
1770 |
protected function adjustHsl($color, $idx, $amount) {
|
1771 |
$hsl = $this->toHSL($color[1], $color[2], $color[3]);
|
1772 |
$hsl[$idx] += $amount;
|
@@ -1798,7 +2065,9 @@ class scssc {
|
|
1798 |
|
1799 |
protected static $lib_saturate = array("color", "amount");
|
1800 |
protected function lib_saturate($args) {
|
1801 |
-
$
|
|
|
|
|
1802 |
$amount = 100*$this->coercePercent($args[1]);
|
1803 |
return $this->adjustHsl($color, 2, $amount);
|
1804 |
}
|
@@ -1812,7 +2081,9 @@ class scssc {
|
|
1812 |
|
1813 |
protected static $lib_grayscale = array("color");
|
1814 |
protected function lib_grayscale($args) {
|
1815 |
-
|
|
|
|
|
1816 |
}
|
1817 |
|
1818 |
protected static $lib_complement = array("color");
|
@@ -1822,14 +2093,15 @@ class scssc {
|
|
1822 |
|
1823 |
protected static $lib_invert = array("color");
|
1824 |
protected function lib_invert($args) {
|
1825 |
-
$
|
|
|
|
|
1826 |
$color[1] = 255 - $color[1];
|
1827 |
$color[2] = 255 - $color[2];
|
1828 |
$color[3] = 255 - $color[3];
|
1829 |
return $color;
|
1830 |
}
|
1831 |
|
1832 |
-
|
1833 |
// increases opacity by amount
|
1834 |
protected static $lib_opacify = array("color", "amount");
|
1835 |
protected function lib_opacify($args) {
|
@@ -1942,14 +2214,14 @@ class scssc {
|
|
1942 |
$numbers = array();
|
1943 |
foreach ($args as $key => $item) {
|
1944 |
if ('number' != $item[0]) {
|
1945 |
-
|
1946 |
}
|
1947 |
$number = $this->normalizeNumber($item);
|
1948 |
|
1949 |
if (null === $unit) {
|
1950 |
$unit = $number[2];
|
1951 |
} elseif ($unit !== $number[2]) {
|
1952 |
-
|
1953 |
}
|
1954 |
|
1955 |
$originalUnit = $item[2];
|
@@ -2002,6 +2274,27 @@ class scssc {
|
|
2002 |
return array("list", $sep, array_merge($list1[2], array($value)));
|
2003 |
}
|
2004 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005 |
|
2006 |
protected static $lib_type_of = array("value");
|
2007 |
protected function lib_type_of($args) {
|
@@ -2037,10 +2330,29 @@ class scssc {
|
|
2037 |
return $value[0] == "number" && empty($value[2]);
|
2038 |
}
|
2039 |
|
2040 |
-
|
2041 |
protected static $lib_comparable = array("number-1", "number-2");
|
2042 |
protected function lib_comparable($args) {
|
2043 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2044 |
}
|
2045 |
|
2046 |
static protected $cssColors = array(
|
@@ -2194,6 +2506,11 @@ class scssc {
|
|
2194 |
);
|
2195 |
}
|
2196 |
|
|
|
|
|
|
|
|
|
|
|
2197 |
class scss_parser {
|
2198 |
static protected $precedence = array(
|
2199 |
"or" => 0,
|
@@ -2225,8 +2542,9 @@ class scss_parser {
|
|
2225 |
static protected $commentMultiLeft = "/*";
|
2226 |
static protected $commentMultiRight = "*/";
|
2227 |
|
2228 |
-
function __construct($sourceName = null) {
|
2229 |
$this->sourceName = $sourceName;
|
|
|
2230 |
|
2231 |
if (empty(self::$operatorStr)) {
|
2232 |
self::$operatorStr = $this->makeOperatorStr(self::$operators);
|
@@ -2268,6 +2586,45 @@ class scss_parser {
|
|
2268 |
return $this->env;
|
2269 |
}
|
2270 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2271 |
protected function parseChunk() {
|
2272 |
$s = $this->seek();
|
2273 |
|
@@ -2309,7 +2666,7 @@ class scss_parser {
|
|
2309 |
$include = $this->pushSpecialBlock("include");
|
2310 |
$include->child = $child;
|
2311 |
} else {
|
2312 |
-
$this->append($child);
|
2313 |
}
|
2314 |
|
2315 |
return true;
|
@@ -2321,7 +2678,7 @@ class scss_parser {
|
|
2321 |
$this->valueList($importPath) &&
|
2322 |
$this->end())
|
2323 |
{
|
2324 |
-
$this->append(array("import", $importPath));
|
2325 |
return true;
|
2326 |
} else {
|
2327 |
$this->seek($s);
|
@@ -2331,19 +2688,19 @@ class scss_parser {
|
|
2331 |
$this->selectors($selector) &&
|
2332 |
$this->end())
|
2333 |
{
|
2334 |
-
$this->append(array("extend", $selector));
|
2335 |
return true;
|
2336 |
} else {
|
2337 |
$this->seek($s);
|
2338 |
}
|
2339 |
|
2340 |
if ($this->literal("@function") &&
|
2341 |
-
$this->keyword($
|
2342 |
$this->argumentDef($args) &&
|
2343 |
$this->literal("{"))
|
2344 |
{
|
2345 |
$func = $this->pushSpecialBlock("function");
|
2346 |
-
$func->name = $
|
2347 |
$func->args = $args;
|
2348 |
return true;
|
2349 |
} else {
|
@@ -2351,7 +2708,7 @@ class scss_parser {
|
|
2351 |
}
|
2352 |
|
2353 |
if ($this->literal("@return") && $this->valueList($retVal) && $this->end()) {
|
2354 |
-
$this->append(array("return", $retVal));
|
2355 |
return true;
|
2356 |
} else {
|
2357 |
$this->seek($s);
|
@@ -2413,14 +2770,14 @@ class scss_parser {
|
|
2413 |
if (($this->literal("@debug") || $this->literal("@warn")) &&
|
2414 |
$this->valueList($value) &&
|
2415 |
$this->end()) {
|
2416 |
-
$this->append(array("debug", $value, $s));
|
2417 |
return true;
|
2418 |
} else {
|
2419 |
$this->seek($s);
|
2420 |
}
|
2421 |
|
2422 |
if ($this->literal("@content") && $this->end()) {
|
2423 |
-
$this->append(array("mixin_content"));
|
2424 |
return true;
|
2425 |
} else {
|
2426 |
$this->seek($s);
|
@@ -2450,7 +2807,7 @@ class scss_parser {
|
|
2450 |
if ($this->literal("@charset") &&
|
2451 |
$this->valueList($charset) && $this->end())
|
2452 |
{
|
2453 |
-
$this->append(array("charset", $charset));
|
2454 |
return true;
|
2455 |
} else {
|
2456 |
$this->seek($s);
|
@@ -2479,7 +2836,7 @@ class scss_parser {
|
|
2479 |
$this->end())
|
2480 |
{
|
2481 |
$name = array("string", "", array($name));
|
2482 |
-
$this->append(array("assign", $name, $value));
|
2483 |
return true;
|
2484 |
} else {
|
2485 |
$this->seek($s);
|
@@ -2490,17 +2847,9 @@ class scss_parser {
|
|
2490 |
$this->literal(":") &&
|
2491 |
$this->valueList($value) && $this->end())
|
2492 |
{
|
2493 |
-
$defaultVar = false;
|
2494 |
// check for !default
|
2495 |
-
|
2496 |
-
|
2497 |
-
if ($def[0] == "keyword" && $def[1] == "!default") {
|
2498 |
-
array_pop($value[2]);
|
2499 |
-
$value = $this->flattenList($value);
|
2500 |
-
$defaultVar = true;
|
2501 |
-
}
|
2502 |
-
}
|
2503 |
-
$this->append(array("assign", $name, $value, $defaultVar));
|
2504 |
return true;
|
2505 |
} else {
|
2506 |
$this->seek($s);
|
@@ -2527,7 +2876,7 @@ class scss_parser {
|
|
2527 |
if ($this->propertyName($name) && $this->literal(":")) {
|
2528 |
$foundSomething = false;
|
2529 |
if ($this->valueList($value)) {
|
2530 |
-
$this->append(array("assign", $name, $value));
|
2531 |
$foundSomething = true;
|
2532 |
}
|
2533 |
|
@@ -2555,10 +2904,10 @@ class scss_parser {
|
|
2555 |
$include = $block->child;
|
2556 |
unset($block->child);
|
2557 |
$include[3] = $block;
|
2558 |
-
$this->append($include);
|
2559 |
-
}
|
2560 |
$type = isset($block->type) ? $block->type : "block";
|
2561 |
-
$this->append(array($type, $block));
|
2562 |
}
|
2563 |
return true;
|
2564 |
}
|
@@ -2573,19 +2922,35 @@ class scss_parser {
|
|
2573 |
return false;
|
2574 |
}
|
2575 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2576 |
protected function literal($what, $eatWhitespace = null) {
|
2577 |
if (is_null($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
|
2578 |
|
2579 |
-
// this is here mainly prevent notice from { } string accessor
|
2580 |
-
if ($this->count >= strlen($this->buffer)) return false;
|
2581 |
-
|
2582 |
// shortcut on single letter
|
2583 |
-
if (
|
2584 |
-
if ($this->buffer
|
2585 |
-
|
2586 |
-
|
|
|
|
|
|
|
|
|
|
|
2587 |
}
|
2588 |
-
else return false;
|
2589 |
}
|
2590 |
|
2591 |
return $this->match($this->preg_quote($what), $m, $eatWhitespace);
|
@@ -2594,7 +2959,7 @@ class scss_parser {
|
|
2594 |
// tree builders
|
2595 |
|
2596 |
protected function pushBlock($selectors) {
|
2597 |
-
$b = new
|
2598 |
$b->parent = $this->env; // not sure if we need this yet
|
2599 |
|
2600 |
$b->selectors = $selectors;
|
@@ -2621,7 +2986,11 @@ class scss_parser {
|
|
2621 |
return $old;
|
2622 |
}
|
2623 |
|
2624 |
-
protected function append($statement) {
|
|
|
|
|
|
|
|
|
2625 |
$this->env->children[] = $statement;
|
2626 |
}
|
2627 |
|
@@ -2644,20 +3013,23 @@ class scss_parser {
|
|
2644 |
$expressions = null;
|
2645 |
$parts = array();
|
2646 |
|
2647 |
-
if (($this->literal("only") && ($only = true) || $this->literal("not") && ($not = true) || true) && $this->
|
2648 |
$prop = array("mediaType");
|
2649 |
-
if (isset($only)) $prop[] = "only";
|
2650 |
-
if (isset($not)) $prop[] = "not";
|
2651 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2652 |
$parts[] = $prop;
|
2653 |
-
} else {
|
2654 |
-
$this->seek($s);
|
2655 |
}
|
2656 |
|
2657 |
-
|
2658 |
-
if (!empty($mediaType) && !$this->literal("and")) {
|
2659 |
-
// ~
|
2660 |
-
} else {
|
2661 |
$this->genericList($expressions, "mediaExpression", "and", false);
|
2662 |
if (is_array($expressions)) $parts = array_merge($parts, $expressions[2]);
|
2663 |
}
|
@@ -2670,7 +3042,7 @@ class scss_parser {
|
|
2670 |
$s = $this->seek();
|
2671 |
$value = null;
|
2672 |
if ($this->literal("(") &&
|
2673 |
-
$this->
|
2674 |
($this->literal(":") && $this->expression($value) || true) &&
|
2675 |
$this->literal(")"))
|
2676 |
{
|
@@ -2701,7 +3073,13 @@ class scss_parser {
|
|
2701 |
}
|
2702 |
|
2703 |
if ($this->genericList($value, "expression")) {
|
2704 |
-
$out = array($keyword, $value);
|
|
|
|
|
|
|
|
|
|
|
|
|
2705 |
return true;
|
2706 |
}
|
2707 |
|
@@ -2710,11 +3088,11 @@ class scss_parser {
|
|
2710 |
|
2711 |
|
2712 |
protected function valueList(&$out) {
|
2713 |
-
return $this->genericList($out, "
|
2714 |
}
|
2715 |
|
2716 |
-
protected function
|
2717 |
-
return $this->genericList($out, "expression"
|
2718 |
}
|
2719 |
|
2720 |
protected function genericList(&$out, $parseItem, $delim="", $flatten=true) {
|
@@ -2838,7 +3216,11 @@ class scss_parser {
|
|
2838 |
if ($this->progid($out)) return true;
|
2839 |
|
2840 |
if ($this->keyword($keyword)) {
|
2841 |
-
$
|
|
|
|
|
|
|
|
|
2842 |
return true;
|
2843 |
}
|
2844 |
|
@@ -2890,7 +3272,12 @@ class scss_parser {
|
|
2890 |
if ($this->keyword($name, false) &&
|
2891 |
$this->literal("("))
|
2892 |
{
|
2893 |
-
if ($name
|
|
|
|
|
|
|
|
|
|
|
2894 |
$ss = $this->seek();
|
2895 |
if ($this->argValues($args) && $this->literal(")")) {
|
2896 |
$func = array("fncall", $name, $args);
|
@@ -2916,21 +3303,64 @@ class scss_parser {
|
|
2916 |
return false;
|
2917 |
}
|
2918 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2919 |
protected function argumentDef(&$out) {
|
2920 |
$s = $this->seek();
|
2921 |
$this->literal("(");
|
2922 |
|
2923 |
$args = array();
|
2924 |
while ($this->variable($var)) {
|
2925 |
-
$arg = array($var[1], null);
|
2926 |
|
2927 |
$ss = $this->seek();
|
2928 |
-
if ($this->literal(":") && $this->
|
2929 |
$arg[1] = $defaultVal;
|
2930 |
} else {
|
2931 |
$this->seek($ss);
|
2932 |
}
|
2933 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2934 |
$args[] = $arg;
|
2935 |
if (!$this->literal(",")) break;
|
2936 |
}
|
@@ -2990,15 +3420,10 @@ class scss_parser {
|
|
2990 |
}
|
2991 |
|
2992 |
$content = array();
|
2993 |
-
|
2994 |
-
// look for either ending delim , escape, or string interpolation
|
2995 |
-
$patt = '([^\n]*?)(#\{|\\\\|' .
|
2996 |
-
$this->preg_quote($delim).')';
|
2997 |
-
|
2998 |
$oldWhite = $this->eatWhiteDefault;
|
2999 |
$this->eatWhiteDefault = false;
|
3000 |
|
3001 |
-
while ($this->
|
3002 |
$content[] = $m[1];
|
3003 |
if ($m[2] == "#{") {
|
3004 |
$this->count -= strlen($m[2]);
|
@@ -3056,6 +3481,10 @@ class scss_parser {
|
|
3056 |
|
3057 |
if (count($parts) == 0) return false;
|
3058 |
|
|
|
|
|
|
|
|
|
3059 |
$out = $parts;
|
3060 |
return true;
|
3061 |
}
|
@@ -3075,7 +3504,7 @@ class scss_parser {
|
|
3075 |
|
3076 |
$content = array();
|
3077 |
while ($this->match($patt, $m, false)) {
|
3078 |
-
if (
|
3079 |
$content[] = $m[1];
|
3080 |
if ($nestingOpen) {
|
3081 |
$nestingLevel += substr_count($m[1], $nestingOpen);
|
@@ -3209,7 +3638,7 @@ class scss_parser {
|
|
3209 |
return true;
|
3210 |
}
|
3211 |
|
3212 |
-
//
|
3213 |
protected function selector(&$out) {
|
3214 |
$selector = array();
|
3215 |
|
@@ -3219,6 +3648,8 @@ class scss_parser {
|
|
3219 |
} elseif ($this->selectorSingle($part)) {
|
3220 |
$selector[] = $part;
|
3221 |
$this->whitespace();
|
|
|
|
|
3222 |
} else {
|
3223 |
break;
|
3224 |
}
|
@@ -3234,7 +3665,7 @@ class scss_parser {
|
|
3234 |
}
|
3235 |
|
3236 |
// the parts that make up
|
3237 |
-
// div[yes=no]#something.hello.world:nth-child(-2n+1)
|
3238 |
protected function selectorSingle(&$out) {
|
3239 |
$oldWhite = $this->eatWhiteDefault;
|
3240 |
$this->eatWhiteDefault = false;
|
@@ -3285,6 +3716,12 @@ class scss_parser {
|
|
3285 |
continue;
|
3286 |
}
|
3287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
3288 |
if ($this->literal("#", false)) {
|
3289 |
$parts[] = "#";
|
3290 |
continue;
|
@@ -3395,11 +3832,19 @@ class scss_parser {
|
|
3395 |
return false;
|
3396 |
}
|
3397 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3398 |
// consume an end of statement delimiter
|
3399 |
protected function end() {
|
3400 |
if ($this->literal(';')) {
|
3401 |
return true;
|
3402 |
-
} elseif ($this->count == strlen($this->buffer) || $this->buffer
|
3403 |
// if there is end of file or a closing block next then we don't need a ;
|
3404 |
return true;
|
3405 |
}
|
@@ -3421,7 +3866,7 @@ class scss_parser {
|
|
3421 |
return true;
|
3422 |
}
|
3423 |
|
3424 |
-
|
3425 |
$count = is_null($count) ? $this->count : $count;
|
3426 |
|
3427 |
$line = $this->getLineNo($count);
|
@@ -3433,9 +3878,9 @@ class scss_parser {
|
|
3433 |
}
|
3434 |
|
3435 |
if ($this->peek("(.*?)(\n|$)", $m, $count)) {
|
3436 |
-
throw new
|
3437 |
} else {
|
3438 |
-
throw new
|
3439 |
}
|
3440 |
}
|
3441 |
|
@@ -3443,6 +3888,48 @@ class scss_parser {
|
|
3443 |
return 1 + substr_count(substr($this->buffer, 0, $pos), "\n");
|
3444 |
}
|
3445 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3446 |
// try to match something on head of buffer
|
3447 |
protected function match($regex, &$out, $eatWhitespace = null) {
|
3448 |
if (is_null($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
|
@@ -3507,6 +3994,11 @@ class scss_parser {
|
|
3507 |
}
|
3508 |
}
|
3509 |
|
|
|
|
|
|
|
|
|
|
|
3510 |
class scss_formatter {
|
3511 |
public $indentChar = " ";
|
3512 |
|
@@ -3528,7 +4020,7 @@ class scss_formatter {
|
|
3528 |
return $name . $this->assignSeparator . $value . ";";
|
3529 |
}
|
3530 |
|
3531 |
-
|
3532 |
if (empty($block->lines) && empty($block->children)) return;
|
3533 |
|
3534 |
$inner = $pre = $this->indentStr();
|
@@ -3559,9 +4051,21 @@ class scss_formatter {
|
|
3559 |
echo $pre . $this->close . $this->break;
|
3560 |
}
|
3561 |
}
|
3562 |
-
}
|
3563 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3564 |
|
|
|
|
|
|
|
|
|
|
|
3565 |
class scss_formatter_nested extends scss_formatter {
|
3566 |
public $close = " }";
|
3567 |
|
@@ -3578,6 +4082,21 @@ class scss_formatter_nested extends scss_formatter {
|
|
3578 |
}
|
3579 |
$children[] = $child;
|
3580 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3581 |
$block->children = $children;
|
3582 |
|
3583 |
// make relative to parent
|
@@ -3587,7 +4106,7 @@ class scss_formatter_nested extends scss_formatter {
|
|
3587 |
}
|
3588 |
}
|
3589 |
|
3590 |
-
|
3591 |
if ($block->type == "root") {
|
3592 |
$this->adjustAllChildren($block);
|
3593 |
}
|
@@ -3633,6 +4152,11 @@ class scss_formatter_nested extends scss_formatter {
|
|
3633 |
}
|
3634 |
}
|
3635 |
|
|
|
|
|
|
|
|
|
|
|
3636 |
class scss_formatter_compressed extends scss_formatter {
|
3637 |
public $open = "{";
|
3638 |
public $tagSeparator = ",";
|
@@ -3644,37 +4168,86 @@ class scss_formatter_compressed extends scss_formatter {
|
|
3644 |
}
|
3645 |
}
|
3646 |
|
|
|
|
|
|
|
|
|
|
|
3647 |
class scss_server {
|
3648 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3649 |
protected function join($left, $right) {
|
3650 |
-
return rtrim($left,
|
3651 |
}
|
3652 |
|
|
|
|
|
|
|
|
|
|
|
3653 |
protected function inputName() {
|
3654 |
-
|
3655 |
-
|
3656 |
-
|
3657 |
-
|
3658 |
-
|
|
|
|
|
3659 |
}
|
3660 |
}
|
3661 |
|
|
|
|
|
|
|
|
|
|
|
3662 |
protected function findInput() {
|
3663 |
-
if ($input = $this->inputName()
|
|
|
|
|
|
|
3664 |
$name = $this->join($this->dir, $input);
|
3665 |
-
|
|
|
|
|
|
|
3666 |
}
|
|
|
3667 |
return false;
|
3668 |
}
|
3669 |
|
|
|
|
|
|
|
|
|
|
|
3670 |
protected function cacheName($fname) {
|
3671 |
-
return $this->join($this->cacheDir, md5($fname) .
|
3672 |
}
|
3673 |
|
|
|
|
|
|
|
|
|
|
|
3674 |
protected function importsCacheName($out) {
|
3675 |
-
return $out .
|
3676 |
}
|
3677 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3678 |
protected function needsCompile($in, $out) {
|
3679 |
if (!is_file($out)) return true;
|
3680 |
|
@@ -3692,13 +4265,21 @@ class scss_server {
|
|
3692 |
return false;
|
3693 |
}
|
3694 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3695 |
protected function compile($in, $out) {
|
3696 |
$start = microtime(true);
|
3697 |
$css = $this->scss->compile(file_get_contents($in), $in);
|
3698 |
$elapsed = round((microtime(true) - $start), 4);
|
3699 |
|
3700 |
$v = scssc::$VERSION;
|
3701 |
-
$t = date(
|
3702 |
$css = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css;
|
3703 |
|
3704 |
file_put_contents($out, $css);
|
@@ -3707,17 +4288,20 @@ class scss_server {
|
|
3707 |
return $css;
|
3708 |
}
|
3709 |
|
|
|
|
|
|
|
3710 |
public function serve() {
|
3711 |
if ($input = $this->findInput()) {
|
3712 |
$output = $this->cacheName($input);
|
3713 |
-
header(
|
3714 |
|
3715 |
if ($this->needsCompile($input, $output)) {
|
3716 |
try {
|
3717 |
echo $this->compile($input, $output);
|
3718 |
-
} catch (
|
3719 |
header('HTTP/1.1 500 Internal Server Error');
|
3720 |
-
echo
|
3721 |
}
|
3722 |
} else {
|
3723 |
header('X-SCSS-Cache: true');
|
@@ -3728,16 +4312,23 @@ class scss_server {
|
|
3728 |
}
|
3729 |
|
3730 |
header('HTTP/1.0 404 Not Found');
|
3731 |
-
header(
|
3732 |
$v = scssc::$VERSION;
|
3733 |
echo "/* INPUT NOT FOUND scss $v */\n";
|
3734 |
}
|
3735 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3736 |
public function __construct($dir, $cacheDir=null, $scss=null) {
|
3737 |
$this->dir = $dir;
|
3738 |
|
3739 |
if (is_null($cacheDir)) {
|
3740 |
-
$cacheDir = $this->join($dir,
|
3741 |
}
|
3742 |
|
3743 |
$this->cacheDir = $cacheDir;
|
@@ -3750,10 +4341,13 @@ class scss_server {
|
|
3750 |
$this->scss = $scss;
|
3751 |
}
|
3752 |
|
|
|
|
|
|
|
|
|
|
|
3753 |
static public function serveFrom($path) {
|
3754 |
$server = new self($path);
|
3755 |
$server->serve();
|
3756 |
}
|
3757 |
}
|
3758 |
-
|
3759 |
-
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* SCSS compiler written in PHP
|
4 |
+
*
|
5 |
+
* @copyright 2012-2013 Leaf Corcoran
|
6 |
+
*
|
7 |
+
* @license http://opensource.org/licenses/gpl-license GPL-3.0
|
8 |
+
* @license http://opensource.org/licenses/MIT MIT
|
9 |
+
*
|
10 |
+
* @link http://leafo.net/scssphp
|
11 |
+
*/
|
12 |
+
|
13 |
+
/**
|
14 |
+
* The scss compiler and parser.
|
15 |
+
*
|
16 |
+
* Converting SCSS to CSS is a three stage process. The incoming file is parsed
|
17 |
+
* by `scssc_parser` into a syntax tree, then it is compiled into another tree
|
18 |
+
* representing the CSS structure by `scssc`. The CSS tree is fed into a
|
19 |
+
* formatter, like `scssc_formatter` which then outputs CSS as a string.
|
20 |
+
*
|
21 |
+
* During the first compile, all values are *reduced*, which means that their
|
22 |
+
* types are brought to the lowest form before being dump as strings. This
|
23 |
+
* handles math equations, variable dereferences, and the like.
|
24 |
+
*
|
25 |
+
* The `parse` function of `scssc` is the entry point.
|
26 |
+
*
|
27 |
+
* In summary:
|
28 |
+
*
|
29 |
+
* The `scssc` class creates an instance of the parser, feeds it SCSS code,
|
30 |
+
* then transforms the resulting tree to a CSS tree. This class also holds the
|
31 |
+
* evaluation context, such as all available mixins and variables at any given
|
32 |
+
* time.
|
33 |
+
*
|
34 |
+
* The `scssc_parser` class is only concerned with parsing its input.
|
35 |
+
*
|
36 |
+
* The `scssc_formatter` takes a CSS tree, and dumps it to a formatted string,
|
37 |
+
* handling things like indentation.
|
38 |
+
*/
|
39 |
+
|
40 |
+
/**
|
41 |
+
* SCSS compiler
|
42 |
+
*
|
43 |
+
* @author Leaf Corcoran <leafot@gmail.com>
|
44 |
+
*/
|
45 |
class scssc {
|
46 |
+
static public $VERSION = "v0.0.7";
|
47 |
|
48 |
static protected $operatorNames = array(
|
49 |
'+' => "add",
|
67 |
"function" => "^",
|
68 |
);
|
69 |
|
70 |
+
static protected $numberPrecision = 5;
|
71 |
static protected $unitTable = array(
|
72 |
"in" => array(
|
73 |
"in" => 1,
|
81 |
|
82 |
static public $true = array("keyword", "true");
|
83 |
static public $false = array("keyword", "false");
|
84 |
+
static public $null = array("null");
|
85 |
|
86 |
static public $defaultValue = array("keyword", "");
|
87 |
static public $selfSelector = array("self");
|
112 |
$this->scope = null;
|
113 |
|
114 |
$this->compileRoot($tree);
|
|
|
115 |
|
116 |
+
$out = $this->formatter->format($this->scope);
|
|
|
|
|
117 |
|
118 |
setlocale(LC_NUMERIC, $locale);
|
119 |
return $out;
|
120 |
}
|
121 |
|
122 |
+
protected function isSelfExtend($target, $origin) {
|
123 |
+
foreach ($origin as $sel) {
|
124 |
+
if (in_array($target, $sel)) {
|
125 |
+
return true;
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
return false;
|
130 |
+
}
|
131 |
+
|
132 |
protected function pushExtends($target, $origin) {
|
133 |
+
if ($this->isSelfExtend($target, $origin)) {
|
134 |
+
return;
|
135 |
+
}
|
136 |
+
|
137 |
$i = count($this->extends);
|
138 |
$this->extends[] = array($target, $origin);
|
139 |
|
147 |
}
|
148 |
|
149 |
protected function makeOutputBlock($type, $selectors = null) {
|
150 |
+
$out = new stdClass;
|
151 |
$out->type = $type;
|
152 |
$out->lines = array();
|
153 |
$out->children = array();
|
158 |
return $out;
|
159 |
}
|
160 |
|
161 |
+
protected function matchExtendsSingle($single, &$outOrigin) {
|
162 |
$counts = array();
|
163 |
foreach ($single as $part) {
|
164 |
if (!is_string($part)) return false; // hmm
|
171 |
}
|
172 |
}
|
173 |
|
174 |
+
$outOrigin = array();
|
175 |
+
$found = false;
|
176 |
+
|
177 |
foreach ($counts as $idx => $count) {
|
178 |
list($target, $origin) = $this->extends[$idx];
|
179 |
+
|
180 |
// check count
|
181 |
if ($count != count($target)) continue;
|
182 |
+
|
183 |
// check if target is subset of single
|
184 |
if (array_diff(array_intersect($single, $target), $target)) continue;
|
185 |
|
186 |
+
$rem = array_diff($single, $target);
|
|
|
187 |
|
188 |
+
foreach ($origin as $j => $new) {
|
189 |
+
$origin[$j][count($origin[$j]) - 1] = $this->combineSelectorSingle(end($new), $rem);
|
190 |
+
}
|
191 |
+
|
192 |
+
$outOrigin = array_merge($outOrigin, $origin);
|
193 |
+
|
194 |
+
$found = true;
|
195 |
}
|
196 |
|
197 |
+
return $found;
|
198 |
}
|
199 |
|
200 |
protected function combineSelectorSingle($base, $other) {
|
203 |
|
204 |
foreach (array($base, $other) as $single) {
|
205 |
foreach ($single as $part) {
|
206 |
+
if (preg_match('/^[^\[.#:]/', $part)) {
|
207 |
$tag = $part;
|
208 |
} else {
|
209 |
$out[] = $part;
|
222 |
foreach ($selector as $i => $part) {
|
223 |
if ($i < $from) continue;
|
224 |
|
225 |
+
if ($this->matchExtendsSingle($part, $origin)) {
|
226 |
$before = array_slice($selector, 0, $i);
|
227 |
$after = array_slice($selector, $i + 1);
|
228 |
|
229 |
foreach ($origin as $new) {
|
|
|
|
|
|
|
230 |
$k = 0;
|
231 |
+
|
232 |
// remove shared parts
|
233 |
if ($initial) {
|
234 |
foreach ($before as $k => $val) {
|
265 |
}
|
266 |
}
|
267 |
|
268 |
+
protected function flattenSelectors($block, $parentKey = null) {
|
269 |
if ($block->selectors) {
|
270 |
$selectors = array();
|
271 |
foreach ($block->selectors as $s) {
|
277 |
}
|
278 |
}
|
279 |
|
280 |
+
$block->selectors = array();
|
281 |
+
$placeholderSelector = false;
|
282 |
+
foreach ($selectors as $selector) {
|
283 |
+
if ($this->hasSelectorPlaceholder($selector)) {
|
284 |
+
$placeholderSelector = true;
|
285 |
+
continue;
|
286 |
+
}
|
287 |
+
$block->selectors[] = $this->compileSelector($selector);
|
288 |
+
}
|
289 |
+
|
290 |
+
if ($placeholderSelector && 0 == count($block->selectors) && null !== $parentKey) {
|
291 |
+
unset($block->parent->children[$parentKey]);
|
292 |
+
return;
|
293 |
+
}
|
294 |
}
|
295 |
|
296 |
+
foreach ($block->children as $key => $child) {
|
297 |
+
$this->flattenSelectors($child, $key);
|
298 |
}
|
299 |
}
|
300 |
|
301 |
protected function compileRoot($rootBlock) {
|
302 |
$this->pushEnv($rootBlock);
|
303 |
$this->scope = $this->makeOutputBlock("root");
|
304 |
+
|
305 |
$this->compileChildren($rootBlock->children, $this->scope);
|
306 |
+
$this->flattenSelectors($this->scope);
|
307 |
+
|
308 |
$this->popEnv();
|
309 |
}
|
310 |
|
318 |
|
319 |
$parentScope->children[] = $this->scope;
|
320 |
|
321 |
+
// top level properties in a media cause it to be wrapped
|
322 |
+
$needsWrap = false;
|
323 |
+
foreach ($media->children as $child) {
|
324 |
+
$type = $child[0];
|
325 |
+
if ($type !== 'block' && $type !== 'media' && $type !== 'directive') {
|
326 |
+
$needsWrap = true;
|
327 |
+
break;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
if ($needsWrap) {
|
332 |
+
$wrapped = (object)array(
|
333 |
+
"selectors" => array(),
|
334 |
+
"children" => $media->children
|
335 |
+
);
|
336 |
+
$media->children = array(array("block", $wrapped));
|
337 |
+
}
|
338 |
+
|
339 |
$this->compileChildren($media->children, $this->scope);
|
340 |
|
341 |
$this->scope = $this->scope->parent;
|
365 |
$this->popEnv();
|
366 |
}
|
367 |
|
368 |
+
/**
|
369 |
+
* Recursively compiles a block.
|
370 |
+
*
|
371 |
+
* A block is analogous to a CSS block in most cases. A single SCSS document
|
372 |
+
* is encapsulated in a block when parsed, but it does not have parent tags
|
373 |
+
* so all of its children appear on the root level when compiled.
|
374 |
+
*
|
375 |
+
* Blocks are made up of selectors and children.
|
376 |
+
*
|
377 |
+
* The children of a block are just all the blocks that are defined within.
|
378 |
+
*
|
379 |
+
* Compiling the block involves pushing a fresh environment on the stack,
|
380 |
+
* and iterating through the props, compiling each one.
|
381 |
+
*
|
382 |
+
* @see scss::compileChild()
|
383 |
+
*
|
384 |
+
* @param \StdClass $block
|
385 |
+
*/
|
386 |
protected function compileBlock($block) {
|
387 |
$env = $this->pushEnv($block);
|
388 |
|
402 |
foreach ($single as $part) {
|
403 |
if (empty($joined) ||
|
404 |
!is_string($part) ||
|
405 |
+
preg_match('/[\[.:#%]/', $part))
|
406 |
{
|
407 |
$joined[] = $part;
|
408 |
continue;
|
431 |
case "interpolate":
|
432 |
$p = $this->compileValue($p);
|
433 |
break;
|
434 |
+
case "string":
|
435 |
+
$p = $this->compileValue($p);
|
436 |
+
break;
|
437 |
}
|
438 |
}
|
439 |
|
466 |
return implode($piece);
|
467 |
}
|
468 |
|
469 |
+
protected function hasSelectorPlaceholder($selector)
|
470 |
+
{
|
471 |
+
if (!is_array($selector)) return false;
|
472 |
+
|
473 |
+
foreach ($selector as $parts) {
|
474 |
+
foreach ($parts as $part) {
|
475 |
+
if ('%' == $part[0]) {
|
476 |
+
return true;
|
477 |
+
}
|
478 |
+
}
|
479 |
+
}
|
480 |
+
|
481 |
+
return false;
|
482 |
+
}
|
483 |
+
|
484 |
protected function compileChildren($stms, $out) {
|
485 |
foreach ($stms as $stm) {
|
486 |
$ret = $this->compileChild($stm, $out);
|
496 |
foreach ($query as $q) {
|
497 |
switch ($q[0]) {
|
498 |
case "mediaType":
|
499 |
+
$parts[] = implode(" ", array_map(array($this, "compileValue"), array_slice($q, 1)));
|
500 |
break;
|
501 |
case "mediaExp":
|
502 |
if (isset($q[2])) {
|
503 |
+
$parts[] = "(". $this->compileValue($q[1]) . $this->formatter->assignSeparator . $this->compileValue($q[2]) . ")";
|
504 |
} else {
|
505 |
+
$parts[] = "(" . $this->compileValue($q[1]) . ")";
|
506 |
}
|
507 |
break;
|
508 |
}
|
529 |
return true;
|
530 |
}
|
531 |
return false;
|
532 |
+
}
|
533 |
+
if ($rawPath[0] == "list") {
|
534 |
// handle a list of strings
|
535 |
if (count($rawPath[2]) == 0) return false;
|
536 |
foreach ($rawPath[2] as $path) {
|
549 |
|
550 |
// return a value to halt execution
|
551 |
protected function compileChild($child, $out) {
|
552 |
+
$this->sourcePos = isset($child[-1]) ? $child[-1] : -1;
|
553 |
+
$this->sourceParser = isset($child[-2]) ? $child[-2] : $this->parser;
|
554 |
+
|
555 |
switch ($child[0]) {
|
556 |
case "import":
|
557 |
list(,$rawPath) = $child;
|
581 |
list(,$name, $value) = $child;
|
582 |
if ($name[0] == "var") {
|
583 |
$isDefault = !empty($child[3]);
|
584 |
+
|
585 |
+
if ($isDefault) {
|
586 |
+
$existingValue = $this->get($name[1], true);
|
587 |
+
$shouldSet = $existingValue === true || $existingValue == self::$null;
|
588 |
+
}
|
589 |
+
|
590 |
+
if (!$isDefault || $shouldSet) {
|
591 |
$this->set($name[1], $this->reduce($value));
|
592 |
}
|
593 |
break;
|
594 |
}
|
595 |
|
596 |
+
// if the value reduces to null from something else then
|
597 |
+
// the property should be discarded
|
598 |
+
if ($value[0] != "null") {
|
599 |
+
$value = $this->reduce($value);
|
600 |
+
if ($value[0] == "null") {
|
601 |
+
break;
|
602 |
+
}
|
603 |
+
}
|
604 |
+
|
605 |
+
$compiledValue = $this->compileValue($value);
|
606 |
$out->lines[] = $this->formatter->property(
|
607 |
+
$this->compileValue($name),
|
608 |
+
$compiledValue);
|
609 |
break;
|
610 |
case "comment":
|
611 |
$out->lines[] = $child[1];
|
625 |
break;
|
626 |
case "if":
|
627 |
list(, $if) = $child;
|
628 |
+
if ($this->isTruthy($this->reduce($if->cond, true))) {
|
629 |
return $this->compileChildren($if->children, $out);
|
630 |
} else {
|
631 |
foreach ($if->cases as $case) {
|
632 |
if ($case->type == "else" ||
|
633 |
+
$case->type == "elseif" && $this->isTruthy($this->reduce($case->cond)))
|
634 |
{
|
635 |
return $this->compileChildren($case->children, $out);
|
636 |
}
|
641 |
return $this->reduce($child[1], true);
|
642 |
case "each":
|
643 |
list(,$each) = $child;
|
644 |
+
$list = $this->coerceList($this->reduce($each->list));
|
645 |
foreach ($list[2] as $item) {
|
646 |
$this->pushEnv();
|
647 |
$this->set($each->var, $item);
|
652 |
break;
|
653 |
case "while":
|
654 |
list(,$while) = $child;
|
655 |
+
while ($this->isTruthy($this->reduce($while->cond, true))) {
|
656 |
$ret = $this->compileChildren($while->children, $out);
|
657 |
if ($ret) return $ret;
|
658 |
}
|
698 |
case "include": // including a mixin
|
699 |
list(,$name, $argValues, $content) = $child;
|
700 |
$mixin = $this->get(self::$namespaces["mixin"] . $name, false);
|
701 |
+
if (!$mixin) {
|
702 |
+
$this->throwError("Undefined mixin $name");
|
703 |
+
}
|
704 |
|
705 |
$callingScope = $this->env;
|
706 |
|
707 |
// push scope, apply args
|
708 |
$this->pushEnv();
|
709 |
+
if ($this->env->depth > 0) {
|
710 |
+
$this->env->depth--;
|
711 |
+
}
|
712 |
|
713 |
if (!is_null($content)) {
|
714 |
$content->scope = $callingScope;
|
729 |
case "mixin_content":
|
730 |
$content = $this->get(self::$namespaces["special"] . "content");
|
731 |
if (is_null($content)) {
|
732 |
+
$this->throwError("Expected @content inside of mixin");
|
733 |
}
|
734 |
|
|
|
|
|
735 |
foreach ($content->children as $child) {
|
736 |
+
$this->storeEnv = ($child[0] == 'include' || $child[0] == 'block')
|
737 |
+
? null
|
738 |
+
: $content->scope;
|
739 |
+
|
740 |
$this->compileChild($child, $out);
|
741 |
}
|
742 |
|
749 |
fwrite(STDERR, "Line $line DEBUG: $value\n");
|
750 |
break;
|
751 |
default:
|
752 |
+
$this->throwError("unknown child type: $child[0]");
|
753 |
}
|
754 |
}
|
755 |
|
756 |
protected function expToString($exp) {
|
757 |
list(, $op, $left, $right, $inParens, $whiteLeft, $whiteRight) = $exp;
|
758 |
+
$content = array($this->reduce($left));
|
759 |
if ($whiteLeft) $content[] = " ";
|
760 |
$content[] = $op;
|
761 |
if ($whiteRight) $content[] = " ";
|
762 |
+
$content[] = $this->reduce($right);
|
763 |
return array("string", "", $content);
|
764 |
}
|
765 |
|
766 |
+
protected function isTruthy($value) {
|
767 |
+
return $value != self::$false && $value != self::$null;
|
768 |
+
}
|
769 |
+
|
770 |
// should $value cause its operand to eval
|
771 |
protected function shouldEval($value) {
|
772 |
switch ($value[0]) {
|
824 |
$left[0] == "number" && $right[0] == "number")
|
825 |
{
|
826 |
if ($opName == "mod" && $right[2] != "") {
|
827 |
+
$this->throwError("Cannot modulo by a number with units: $right[1]$right[2].");
|
828 |
}
|
829 |
|
830 |
$unitChange = true;
|
958 |
}
|
959 |
}
|
960 |
|
961 |
+
public function normalizeValue($value) {
|
962 |
+
$value = $this->coerceForExpression($this->reduce($value));
|
963 |
+
list($type) = $value;
|
964 |
+
|
965 |
+
switch ($type) {
|
966 |
+
case "list":
|
967 |
+
$value = $this->extractInterpolation($value);
|
968 |
+
if ($value[0] != "list") {
|
969 |
+
return array("keyword", $this->compileValue($value));
|
970 |
+
}
|
971 |
+
foreach ($value[2] as $key => $item) {
|
972 |
+
$value[2][$key] = $this->normalizeValue($item);
|
973 |
+
}
|
974 |
+
return $value;
|
975 |
+
case "number":
|
976 |
+
return $this->normalizeNumber($value);
|
977 |
+
default:
|
978 |
+
return $value;
|
979 |
+
}
|
980 |
+
}
|
981 |
+
|
982 |
// just does physical lengths for now
|
983 |
protected function normalizeNumber($number) {
|
984 |
list(, $value, $unit) = $number;
|
1070 |
break;
|
1071 |
case '/':
|
1072 |
if ($rval == 0) {
|
1073 |
+
$this->throwError("color: Can't divide by zero");
|
1074 |
}
|
1075 |
$out[] = $lval / $rval;
|
1076 |
break;
|
1077 |
+
case "==":
|
1078 |
+
return $this->op_eq($left, $right);
|
1079 |
+
case "!=":
|
1080 |
+
return $this->op_neq($left, $right);
|
1081 |
default:
|
1082 |
+
$this->throwError("color: unknown op $op");
|
1083 |
}
|
1084 |
}
|
1085 |
|
1135 |
return $thing ? self::$true : self::$false;
|
1136 |
}
|
1137 |
|
1138 |
+
/**
|
1139 |
+
* Compiles a primitive value into a CSS property value.
|
1140 |
+
*
|
1141 |
+
* Values in scssphp are typed by being wrapped in arrays, their format is
|
1142 |
+
* typically:
|
1143 |
+
*
|
1144 |
+
* array(type, contents [, additional_contents]*)
|
1145 |
+
*
|
1146 |
+
* The input is expected to be reduced. This function will not work on
|
1147 |
+
* things like expressions and variables.
|
1148 |
+
*
|
1149 |
+
* @param array $value
|
1150 |
+
*/
|
1151 |
protected function compileValue($value) {
|
1152 |
$value = $this->reduce($value);
|
1153 |
|
1190 |
if ($value[0] != "list") return $this->compileValue($value);
|
1191 |
|
1192 |
list(, $delim, $items) = $value;
|
1193 |
+
|
1194 |
+
$filtered = array();
|
1195 |
+
foreach ($items as $item) {
|
1196 |
+
if ($item[0] == "null") continue;
|
1197 |
+
$filtered[] = $this->compileValue($item);
|
1198 |
}
|
1199 |
+
|
1200 |
+
return implode("$delim ", $filtered);
|
1201 |
case "interpolated": # node created by extractInterpolation
|
1202 |
list(, $interpolate, $left, $right) = $value;
|
1203 |
list(,, $whiteLeft, $whiteRight) = $interpolate;
|
1215 |
|
1216 |
// strip quotes if it's a string
|
1217 |
$reduced = $this->reduce($exp);
|
1218 |
+
switch ($reduced[0]) {
|
1219 |
+
case "string":
|
1220 |
+
$reduced = array("keyword",
|
1221 |
+
$this->compileStringContent($reduced));
|
1222 |
+
break;
|
1223 |
+
case "null":
|
1224 |
+
$reduced = array("keyword", "");
|
1225 |
}
|
1226 |
|
1227 |
return $this->compileValue($reduced);
|
1228 |
+
case "null":
|
1229 |
+
return "null";
|
1230 |
default:
|
1231 |
+
$this->throwError("unknown value type: $type");
|
1232 |
}
|
1233 |
}
|
1234 |
|
1259 |
}
|
1260 |
|
1261 |
// find the final set of selectors
|
1262 |
+
protected function multiplySelectors($env) {
|
1263 |
+
$envs = array();
|
1264 |
+
while (null !== $env) {
|
1265 |
+
if (!empty($env->selectors)) {
|
1266 |
+
$envs[] = $env;
|
1267 |
+
}
|
1268 |
+
$env = $env->parent;
|
1269 |
+
};
|
|
|
1270 |
|
1271 |
+
$selectors = array();
|
1272 |
+
$parentSelectors = array(array());
|
1273 |
+
while ($env = array_pop($envs)) {
|
1274 |
$selectors = array();
|
1275 |
+
foreach ($env->selectors as $selector) {
|
1276 |
+
foreach ($parentSelectors as $parent) {
|
1277 |
+
$selectors[] = $this->joinSelectors($parent, $selector);
|
1278 |
}
|
1279 |
}
|
1280 |
+
$parentSelectors = $selectors;
|
1281 |
}
|
1282 |
|
1283 |
+
return $selectors;
|
1284 |
}
|
1285 |
|
1286 |
// looks for & to replace, or append parent before child
|
1352 |
}
|
1353 |
|
1354 |
protected function applyArguments($argDef, $argValues) {
|
1355 |
+
$hasVariable = false;
|
1356 |
+
$args = array();
|
1357 |
+
foreach ($argDef as $i => $arg) {
|
1358 |
+
list($name, $default, $isVariable) = $argDef[$i];
|
1359 |
+
$args[$name] = array($i, $name, $default, $isVariable);
|
1360 |
+
$hasVariable |= $isVariable;
|
1361 |
+
}
|
1362 |
|
1363 |
$keywordArgs = array();
|
1364 |
+
$deferredKeywordArgs = array();
|
1365 |
$remaining = array();
|
|
|
1366 |
// assign the keyword args
|
1367 |
+
foreach ((array) $argValues as $arg) {
|
1368 |
if (!empty($arg[0])) {
|
1369 |
+
if (!isset($args[$arg[0][1]])) {
|
1370 |
+
if ($hasVariable) {
|
1371 |
+
$deferredKeywordArgs[$arg[0][1]] = $arg[1];
|
1372 |
+
} else {
|
1373 |
+
$this->throwError("Mixin or function doesn't have an argument named $%s.", $arg[0][1]);
|
1374 |
+
}
|
1375 |
+
} elseif ($args[$arg[0][1]][0] < count($remaining)) {
|
1376 |
+
$this->throwError("The argument $%s was passed both by position and by name.", $arg[0][1]);
|
1377 |
+
} else {
|
1378 |
+
$keywordArgs[$arg[0][1]] = $arg[1];
|
1379 |
+
}
|
1380 |
+
} elseif (count($keywordArgs)) {
|
1381 |
+
$this->throwError('Positional arguments must come before keyword arguments.');
|
1382 |
+
} elseif ($arg[2] == true) {
|
1383 |
+
$val = $this->reduce($arg[1], true);
|
1384 |
+
if ($val[0] == "list") {
|
1385 |
+
foreach ($val[2] as $name => $item) {
|
1386 |
+
if (!is_numeric($name)) {
|
1387 |
+
$keywordArgs[$name] = $item;
|
1388 |
+
} else {
|
1389 |
+
$remaining[] = $item;
|
1390 |
+
}
|
1391 |
+
}
|
1392 |
+
} else {
|
1393 |
+
$remaining[] = $val;
|
1394 |
+
}
|
1395 |
} else {
|
1396 |
$remaining[] = $arg[1];
|
1397 |
}
|
1398 |
}
|
1399 |
|
1400 |
+
foreach ($args as $arg) {
|
1401 |
+
list($i, $name, $default, $isVariable) = $arg;
|
1402 |
+
if ($isVariable) {
|
1403 |
+
$val = array("list", ",", array());
|
1404 |
+
for ($count = count($remaining); $i < $count; $i++) {
|
1405 |
+
$val[2][] = $remaining[$i];
|
1406 |
+
}
|
1407 |
+
foreach ($deferredKeywordArgs as $itemName => $item) {
|
1408 |
+
$val[2][$itemName] = $item;
|
1409 |
+
}
|
1410 |
+
} elseif (isset($remaining[$i])) {
|
1411 |
$val = $remaining[$i];
|
1412 |
} elseif (isset($keywordArgs[$name])) {
|
1413 |
$val = $keywordArgs[$name];
|
1414 |
} elseif (!empty($default)) {
|
1415 |
$val = $default;
|
1416 |
} else {
|
1417 |
+
$this->throwError("Missing argument $$name");
|
1418 |
}
|
1419 |
|
1420 |
$this->set($name, $this->reduce($val, true), true);
|
1422 |
}
|
1423 |
|
1424 |
protected function pushEnv($block=null) {
|
1425 |
+
$env = new stdClass;
|
1426 |
$env->parent = $this->env;
|
1427 |
$env->store = array();
|
1428 |
$env->block = $block;
|
1442 |
|
1443 |
protected function set($name, $value, $shadow=false) {
|
1444 |
$name = $this->normalizeName($name);
|
1445 |
+
|
1446 |
if ($shadow) {
|
1447 |
$this->setRaw($name, $value);
|
1448 |
} else {
|
1475 |
|
1476 |
if (isset($env->store[$name])) {
|
1477 |
return $env->store[$name];
|
1478 |
+
} elseif (isset($env->parent)) {
|
1479 |
return $this->get($name, $defaultValue, $env->parent);
|
1480 |
}
|
1481 |
|
1519 |
$tree = $this->importCache[$realPath];
|
1520 |
} else {
|
1521 |
$code = file_get_contents($path);
|
1522 |
+
$parser = new scss_parser($path, false);
|
1523 |
$tree = $parser->parse($code);
|
1524 |
$this->parsedFiles[] = $path;
|
1525 |
|
1585 |
$val = $this->reduce($val, true);
|
1586 |
}
|
1587 |
$returnValue = call_user_func($f, $sorted, $this);
|
1588 |
+
} elseif (isset($this->userFunctions[$name])) {
|
1589 |
// see if we can find a user function
|
1590 |
$fn = $this->userFunctions[$name];
|
1591 |
|
1669 |
$name = $value[1];
|
1670 |
if (isset(self::$cssColors[$name])) {
|
1671 |
list($r, $g, $b) = explode(',', self::$cssColors[$name]);
|
1672 |
+
return array('color', (int) $r, (int) $g, (int) $b);
|
1673 |
}
|
1674 |
return null;
|
1675 |
}
|
1687 |
return null;
|
1688 |
}
|
1689 |
|
1690 |
+
protected function assertList($value) {
|
1691 |
+
if ($value[0] != "list")
|
1692 |
+
$this->throwError("expecting list");
|
1693 |
+
return $value;
|
1694 |
+
}
|
1695 |
+
|
1696 |
protected function assertColor($value) {
|
1697 |
if ($color = $this->coerceColor($value)) return $color;
|
1698 |
+
$this->throwError("expecting color");
|
1699 |
}
|
1700 |
|
1701 |
protected function assertNumber($value) {
|
1702 |
if ($value[0] != "number")
|
1703 |
+
$this->throwError("expecting number");
|
1704 |
return $value[1];
|
1705 |
}
|
1706 |
|
1724 |
return $c;
|
1725 |
}
|
1726 |
|
1727 |
+
function toHSL($red, $green, $blue) {
|
1728 |
+
$r = $red / 255;
|
1729 |
+
$g = $green / 255;
|
1730 |
+
$b = $blue / 255;
|
1731 |
|
1732 |
$min = min($r, $g, $b);
|
1733 |
$max = max($r, $g, $b);
|
1734 |
+
$d = $max - $min;
|
1735 |
+
$l = ($min + $max) / 2;
|
1736 |
|
|
|
1737 |
if ($min == $max) {
|
1738 |
+
$s = $h = 0;
|
1739 |
} else {
|
1740 |
+
if ($l < 0.5)
|
1741 |
+
$s = $d / (2 * $l);
|
1742 |
else
|
1743 |
+
$s = $d / (2 - 2 * $l);
|
|
|
|
|
|
|
|
|
1744 |
|
1745 |
+
if ($r == $max)
|
1746 |
+
$h = 60 * ($g - $b) / $d;
|
1747 |
+
elseif ($g == $max)
|
1748 |
+
$h = 60 * ($b - $r) / $d + 120;
|
1749 |
+
elseif ($b == $max)
|
1750 |
+
$h = 60 * ($r - $g) / $d + 240;
|
1751 |
}
|
1752 |
|
1753 |
+
return array('hsl', fmod($h, 360), $s * 100, $l * 100);
|
|
|
|
|
|
|
|
|
1754 |
}
|
1755 |
|
1756 |
+
function hueToRGB($m1, $m2, $h) {
|
1757 |
+
if ($h < 0)
|
1758 |
+
$h += 1;
|
1759 |
+
elseif ($h > 1)
|
1760 |
+
$h -= 1;
|
1761 |
|
1762 |
+
if ($h * 6 < 1)
|
1763 |
+
return $m1 + ($m2 - $m1) * $h * 6;
|
|
|
1764 |
|
1765 |
+
if ($h * 2 < 1)
|
1766 |
+
return $m2;
|
1767 |
|
1768 |
+
if ($h * 3 < 2)
|
1769 |
+
return $m1 + ($m2 - $m1) * (2/3 - $h) * 6;
|
|
|
|
|
1770 |
|
1771 |
+
return $m1;
|
1772 |
+
}
|
1773 |
|
1774 |
+
// H from 0 to 360, S and L from 0 to 100
|
1775 |
+
function toRGB($hue, $saturation, $lightness) {
|
1776 |
+
if ($hue < 0) {
|
1777 |
+
$hue += 360;
|
1778 |
+
}
|
1779 |
|
1780 |
+
$h = $hue / 360;
|
1781 |
+
$s = min(100, max(0, $saturation)) / 100;
|
1782 |
+
$l = min(100, max(0, $lightness)) / 100;
|
|
|
|
|
|
|
1783 |
|
1784 |
+
$m2 = $l <= 0.5 ? $l * ($s + 1) : $l + $s - $l * $s;
|
1785 |
+
$m1 = $l * 2 - $m2;
|
1786 |
|
1787 |
+
$r = $this->hueToRGB($m1, $m2, $h + 1/3) * 255;
|
1788 |
+
$g = $this->hueToRGB($m1, $m2, $h) * 255;
|
1789 |
+
$b = $this->hueToRGB($m1, $m2, $h - 1/3) * 255;
|
|
|
1790 |
|
1791 |
+
$out = array('color', $r, $g, $b);
|
1792 |
return $out;
|
1793 |
}
|
1794 |
|
1801 |
return $t;
|
1802 |
}
|
1803 |
|
1804 |
+
protected static $lib_index = array("list", "value");
|
1805 |
+
protected function lib_index($args) {
|
1806 |
+
list($list, $value) = $args;
|
1807 |
+
$list = $this->assertList($list);
|
1808 |
+
|
1809 |
+
$values = array();
|
1810 |
+
foreach ($list[2] as $item) {
|
1811 |
+
$values[] = $this->normalizeValue($item);
|
1812 |
+
}
|
1813 |
+
$key = array_search($this->normalizeValue($value), $values);
|
1814 |
+
|
1815 |
+
return false === $key ? false : $key + 1;
|
1816 |
+
}
|
1817 |
+
|
1818 |
protected static $lib_rgb = array("red", "green", "blue");
|
1819 |
protected function lib_rgb($args) {
|
1820 |
list($r,$g,$b) = $args;
|
1953 |
}
|
1954 |
|
1955 |
// this might be the IE function, so return value unchanged
|
1956 |
+
return null;
|
1957 |
}
|
1958 |
|
1959 |
protected static $lib_opacity = array("color");
|
1960 |
protected function lib_opacity($args) {
|
1961 |
+
$value = $args[0];
|
1962 |
+
if ($value[0] === 'number') return null;
|
1963 |
return $this->lib_alpha($args);
|
1964 |
}
|
1965 |
|
1976 |
$weight = $this->coercePercent($weight);
|
1977 |
}
|
1978 |
|
1979 |
+
$firstAlpha = isset($first[4]) ? $first[4] : 1;
|
1980 |
+
$secondAlpha = isset($second[4]) ? $second[4] : 1;
|
1981 |
|
1982 |
$w = $weight * 2 - 1;
|
1983 |
+
$a = $firstAlpha - $secondAlpha;
|
1984 |
|
1985 |
$w1 = (($w * $a == -1 ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2.0;
|
1986 |
$w2 = 1.0 - $w1;
|
1991 |
$w1 * $first[3] + $w2 * $second[3],
|
1992 |
);
|
1993 |
|
1994 |
+
if ($firstAlpha != 1.0 || $secondAlpha != 1.0) {
|
1995 |
+
$new[] = $firstAlpha * $weight + $secondAlpha * ($weight - 1);
|
1996 |
}
|
1997 |
|
1998 |
return $this->fixColor($new);
|
2034 |
return array("number", $hsl[3], "%");
|
2035 |
}
|
2036 |
|
|
|
2037 |
protected function adjustHsl($color, $idx, $amount) {
|
2038 |
$hsl = $this->toHSL($color[1], $color[2], $color[3]);
|
2039 |
$hsl[$idx] += $amount;
|
2065 |
|
2066 |
protected static $lib_saturate = array("color", "amount");
|
2067 |
protected function lib_saturate($args) {
|
2068 |
+
$value = $args[0];
|
2069 |
+
if ($value[0] === 'number') return null;
|
2070 |
+
$color = $this->assertColor($value);
|
2071 |
$amount = 100*$this->coercePercent($args[1]);
|
2072 |
return $this->adjustHsl($color, 2, $amount);
|
2073 |
}
|
2081 |
|
2082 |
protected static $lib_grayscale = array("color");
|
2083 |
protected function lib_grayscale($args) {
|
2084 |
+
$value = $args[0];
|
2085 |
+
if ($value[0] === 'number') return null;
|
2086 |
+
return $this->adjustHsl($this->assertColor($value), 2, -100);
|
2087 |
}
|
2088 |
|
2089 |
protected static $lib_complement = array("color");
|
2093 |
|
2094 |
protected static $lib_invert = array("color");
|
2095 |
protected function lib_invert($args) {
|
2096 |
+
$value = $args[0];
|
2097 |
+
if ($value[0] === 'number') return null;
|
2098 |
+
$color = $this->assertColor($value);
|
2099 |
$color[1] = 255 - $color[1];
|
2100 |
$color[2] = 255 - $color[2];
|
2101 |
$color[3] = 255 - $color[3];
|
2102 |
return $color;
|
2103 |
}
|
2104 |
|
|
|
2105 |
// increases opacity by amount
|
2106 |
protected static $lib_opacify = array("color", "amount");
|
2107 |
protected function lib_opacify($args) {
|
2214 |
$numbers = array();
|
2215 |
foreach ($args as $key => $item) {
|
2216 |
if ('number' != $item[0]) {
|
2217 |
+
$this->throwError("%s is not a number", $item[0]);
|
2218 |
}
|
2219 |
$number = $this->normalizeNumber($item);
|
2220 |
|
2221 |
if (null === $unit) {
|
2222 |
$unit = $number[2];
|
2223 |
} elseif ($unit !== $number[2]) {
|
2224 |
+
$this->throwError('Incompatible units: "%s" and "%s".', $originalUnit, $item[2]);
|
2225 |
}
|
2226 |
|
2227 |
$originalUnit = $item[2];
|
2274 |
return array("list", $sep, array_merge($list1[2], array($value)));
|
2275 |
}
|
2276 |
|
2277 |
+
protected function lib_zip($args) {
|
2278 |
+
foreach ($args as $arg) {
|
2279 |
+
$this->assertList($arg);
|
2280 |
+
}
|
2281 |
+
|
2282 |
+
$lists = array();
|
2283 |
+
$firstList = array_shift($args);
|
2284 |
+
foreach ($firstList[2] as $key => $item) {
|
2285 |
+
$list = array("list", "", array($item));
|
2286 |
+
foreach ($args as $arg) {
|
2287 |
+
if (isset($arg[2][$key])) {
|
2288 |
+
$list[2][] = $arg[2][$key];
|
2289 |
+
} else {
|
2290 |
+
break 2;
|
2291 |
+
}
|
2292 |
+
}
|
2293 |
+
$lists[] = $list;
|
2294 |
+
}
|
2295 |
+
|
2296 |
+
return array("list", ",", $lists);
|
2297 |
+
}
|
2298 |
|
2299 |
protected static $lib_type_of = array("value");
|
2300 |
protected function lib_type_of($args) {
|
2330 |
return $value[0] == "number" && empty($value[2]);
|
2331 |
}
|
2332 |
|
|
|
2333 |
protected static $lib_comparable = array("number-1", "number-2");
|
2334 |
protected function lib_comparable($args) {
|
2335 |
+
list($number1, $number2) = $args;
|
2336 |
+
if (!isset($number1[0]) || $number1[0] != "number" || !isset($number2[0]) || $number2[0] != "number") {
|
2337 |
+
$this->throwError('Invalid argument(s) for "comparable"');
|
2338 |
+
}
|
2339 |
+
|
2340 |
+
$number1 = $this->normalizeNumber($number1);
|
2341 |
+
$number2 = $this->normalizeNumber($number2);
|
2342 |
+
|
2343 |
+
return $number1[2] == $number2[2] || $number1[2] == "" || $number2[2] == "";
|
2344 |
+
}
|
2345 |
+
|
2346 |
+
protected function throwError($msg = null) {
|
2347 |
+
if (func_num_args() > 1) {
|
2348 |
+
$msg = call_user_func_array("sprintf", func_get_args());
|
2349 |
+
}
|
2350 |
+
|
2351 |
+
if ($this->sourcePos >= 0 && isset($this->sourceParser)) {
|
2352 |
+
$this->sourceParser->throwParseError($msg, $this->sourcePos);
|
2353 |
+
}
|
2354 |
+
|
2355 |
+
throw new Exception($msg);
|
2356 |
}
|
2357 |
|
2358 |
static protected $cssColors = array(
|
2506 |
);
|
2507 |
}
|
2508 |
|
2509 |
+
/**
|
2510 |
+
* SCSS parser
|
2511 |
+
*
|
2512 |
+
* @author Leaf Corcoran <leafot@gmail.com>
|
2513 |
+
*/
|
2514 |
class scss_parser {
|
2515 |
static protected $precedence = array(
|
2516 |
"or" => 0,
|
2542 |
static protected $commentMultiLeft = "/*";
|
2543 |
static protected $commentMultiRight = "*/";
|
2544 |
|
2545 |
+
function __construct($sourceName = null, $rootParser = true) {
|
2546 |
$this->sourceName = $sourceName;
|
2547 |
+
$this->rootParser = $rootParser;
|
2548 |
|
2549 |
if (empty(self::$operatorStr)) {
|
2550 |
self::$operatorStr = $this->makeOperatorStr(self::$operators);
|
2586 |
return $this->env;
|
2587 |
}
|
2588 |
|
2589 |
+
/**
|
2590 |
+
* Parse a single chunk off the head of the buffer and append it to the
|
2591 |
+
* current parse environment.
|
2592 |
+
*
|
2593 |
+
* Returns false when the buffer is empty, or when there is an error.
|
2594 |
+
*
|
2595 |
+
* This function is called repeatedly until the entire document is
|
2596 |
+
* parsed.
|
2597 |
+
*
|
2598 |
+
* This parser is most similar to a recursive descent parser. Single
|
2599 |
+
* functions represent discrete grammatical rules for the language, and
|
2600 |
+
* they are able to capture the text that represents those rules.
|
2601 |
+
*
|
2602 |
+
* Consider the function scssc::keyword(). (All parse functions are
|
2603 |
+
* structured the same.)
|
2604 |
+
*
|
2605 |
+
* The function takes a single reference argument. When calling the
|
2606 |
+
* function it will attempt to match a keyword on the head of the buffer.
|
2607 |
+
* If it is successful, it will place the keyword in the referenced
|
2608 |
+
* argument, advance the position in the buffer, and return true. If it
|
2609 |
+
* fails then it won't advance the buffer and it will return false.
|
2610 |
+
*
|
2611 |
+
* All of these parse functions are powered by scssc::match(), which behaves
|
2612 |
+
* the same way, but takes a literal regular expression. Sometimes it is
|
2613 |
+
* more convenient to use match instead of creating a new function.
|
2614 |
+
*
|
2615 |
+
* Because of the format of the functions, to parse an entire string of
|
2616 |
+
* grammatical rules, you can chain them together using &&.
|
2617 |
+
*
|
2618 |
+
* But, if some of the rules in the chain succeed before one fails, then
|
2619 |
+
* the buffer position will be left at an invalid state. In order to
|
2620 |
+
* avoid this, scssc::seek() is used to remember and set buffer positions.
|
2621 |
+
*
|
2622 |
+
* Before parsing a chain, use $s = $this->seek() to remember the current
|
2623 |
+
* position into $s. Then if a chain fails, use $this->seek($s) to
|
2624 |
+
* go back where we started.
|
2625 |
+
*
|
2626 |
+
* @return boolean
|
2627 |
+
*/
|
2628 |
protected function parseChunk() {
|
2629 |
$s = $this->seek();
|
2630 |
|
2666 |
$include = $this->pushSpecialBlock("include");
|
2667 |
$include->child = $child;
|
2668 |
} else {
|
2669 |
+
$this->append($child, $s);
|
2670 |
}
|
2671 |
|
2672 |
return true;
|
2678 |
$this->valueList($importPath) &&
|
2679 |
$this->end())
|
2680 |
{
|
2681 |
+
$this->append(array("import", $importPath), $s);
|
2682 |
return true;
|
2683 |
} else {
|
2684 |
$this->seek($s);
|
2688 |
$this->selectors($selector) &&
|
2689 |
$this->end())
|
2690 |
{
|
2691 |
+
$this->append(array("extend", $selector), $s);
|
2692 |
return true;
|
2693 |
} else {
|
2694 |
$this->seek($s);
|
2695 |
}
|
2696 |
|
2697 |
if ($this->literal("@function") &&
|
2698 |
+
$this->keyword($fnName) &&
|
2699 |
$this->argumentDef($args) &&
|
2700 |
$this->literal("{"))
|
2701 |
{
|
2702 |
$func = $this->pushSpecialBlock("function");
|
2703 |
+
$func->name = $fnName;
|
2704 |
$func->args = $args;
|
2705 |
return true;
|
2706 |
} else {
|
2708 |
}
|
2709 |
|
2710 |
if ($this->literal("@return") && $this->valueList($retVal) && $this->end()) {
|
2711 |
+
$this->append(array("return", $retVal), $s);
|
2712 |
return true;
|
2713 |
} else {
|
2714 |
$this->seek($s);
|
2770 |
if (($this->literal("@debug") || $this->literal("@warn")) &&
|
2771 |
$this->valueList($value) &&
|
2772 |
$this->end()) {
|
2773 |
+
$this->append(array("debug", $value, $s), $s);
|
2774 |
return true;
|
2775 |
} else {
|
2776 |
$this->seek($s);
|
2777 |
}
|
2778 |
|
2779 |
if ($this->literal("@content") && $this->end()) {
|
2780 |
+
$this->append(array("mixin_content"), $s);
|
2781 |
return true;
|
2782 |
} else {
|
2783 |
$this->seek($s);
|
2807 |
if ($this->literal("@charset") &&
|
2808 |
$this->valueList($charset) && $this->end())
|
2809 |
{
|
2810 |
+
$this->append(array("charset", $charset), $s);
|
2811 |
return true;
|
2812 |
} else {
|
2813 |
$this->seek($s);
|
2836 |
$this->end())
|
2837 |
{
|
2838 |
$name = array("string", "", array($name));
|
2839 |
+
$this->append(array("assign", $name, $value), $s);
|
2840 |
return true;
|
2841 |
} else {
|
2842 |
$this->seek($s);
|
2847 |
$this->literal(":") &&
|
2848 |
$this->valueList($value) && $this->end())
|
2849 |
{
|
|
|
2850 |
// check for !default
|
2851 |
+
$defaultVar = $value[0] == "list" && $this->stripDefault($value);
|
2852 |
+
$this->append(array("assign", $name, $value, $defaultVar), $s);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2853 |
return true;
|
2854 |
} else {
|
2855 |
$this->seek($s);
|
2876 |
if ($this->propertyName($name) && $this->literal(":")) {
|
2877 |
$foundSomething = false;
|
2878 |
if ($this->valueList($value)) {
|
2879 |
+
$this->append(array("assign", $name, $value), $s);
|
2880 |
$foundSomething = true;
|
2881 |
}
|
2882 |
|
2904 |
$include = $block->child;
|
2905 |
unset($block->child);
|
2906 |
$include[3] = $block;
|
2907 |
+
$this->append($include, $s);
|
2908 |
+
} elseif (empty($block->dontAppend)) {
|
2909 |
$type = isset($block->type) ? $block->type : "block";
|
2910 |
+
$this->append(array($type, $block), $s);
|
2911 |
}
|
2912 |
return true;
|
2913 |
}
|
2922 |
return false;
|
2923 |
}
|
2924 |
|
2925 |
+
protected function stripDefault(&$value) {
|
2926 |
+
$def = end($value[2]);
|
2927 |
+
if ($def[0] == "keyword" && $def[1] == "!default") {
|
2928 |
+
array_pop($value[2]);
|
2929 |
+
$value = $this->flattenList($value);
|
2930 |
+
return true;
|
2931 |
+
}
|
2932 |
+
|
2933 |
+
if ($def[0] == "list") {
|
2934 |
+
return $this->stripDefault($value[2][count($value[2]) - 1]);
|
2935 |
+
}
|
2936 |
+
|
2937 |
+
return false;
|
2938 |
+
}
|
2939 |
+
|
2940 |
protected function literal($what, $eatWhitespace = null) {
|
2941 |
if (is_null($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
|
2942 |
|
|
|
|
|
|
|
2943 |
// shortcut on single letter
|
2944 |
+
if (!isset($what[1]) && isset($this->buffer[$this->count])) {
|
2945 |
+
if ($this->buffer[$this->count] == $what) {
|
2946 |
+
if (!$eatWhitespace) {
|
2947 |
+
$this->count++;
|
2948 |
+
return true;
|
2949 |
+
}
|
2950 |
+
// goes below...
|
2951 |
+
} else {
|
2952 |
+
return false;
|
2953 |
}
|
|
|
2954 |
}
|
2955 |
|
2956 |
return $this->match($this->preg_quote($what), $m, $eatWhitespace);
|
2959 |
// tree builders
|
2960 |
|
2961 |
protected function pushBlock($selectors) {
|
2962 |
+
$b = new stdClass;
|
2963 |
$b->parent = $this->env; // not sure if we need this yet
|
2964 |
|
2965 |
$b->selectors = $selectors;
|
2986 |
return $old;
|
2987 |
}
|
2988 |
|
2989 |
+
protected function append($statement, $pos=null) {
|
2990 |
+
if ($pos !== null) {
|
2991 |
+
$statement[-1] = $pos;
|
2992 |
+
if (!$this->rootParser) $statement[-2] = $this;
|
2993 |
+
}
|
2994 |
$this->env->children[] = $statement;
|
2995 |
}
|
2996 |
|
3013 |
$expressions = null;
|
3014 |
$parts = array();
|
3015 |
|
3016 |
+
if (($this->literal("only") && ($only = true) || $this->literal("not") && ($not = true) || true) && $this->mixedKeyword($mediaType)) {
|
3017 |
$prop = array("mediaType");
|
3018 |
+
if (isset($only)) $prop[] = array("keyword", "only");
|
3019 |
+
if (isset($not)) $prop[] = array("keyword", "not");
|
3020 |
+
$media = array("list", "", array());
|
3021 |
+
foreach ((array)$mediaType as $type) {
|
3022 |
+
if (is_array($type)) {
|
3023 |
+
$media[2][] = $type;
|
3024 |
+
} else {
|
3025 |
+
$media[2][] = array("keyword", $type);
|
3026 |
+
}
|
3027 |
+
}
|
3028 |
+
$prop[] = $media;
|
3029 |
$parts[] = $prop;
|
|
|
|
|
3030 |
}
|
3031 |
|
3032 |
+
if (empty($parts) || $this->literal("and")) {
|
|
|
|
|
|
|
3033 |
$this->genericList($expressions, "mediaExpression", "and", false);
|
3034 |
if (is_array($expressions)) $parts = array_merge($parts, $expressions[2]);
|
3035 |
}
|
3042 |
$s = $this->seek();
|
3043 |
$value = null;
|
3044 |
if ($this->literal("(") &&
|
3045 |
+
$this->expression($feature) &&
|
3046 |
($this->literal(":") && $this->expression($value) || true) &&
|
3047 |
$this->literal(")"))
|
3048 |
{
|
3073 |
}
|
3074 |
|
3075 |
if ($this->genericList($value, "expression")) {
|
3076 |
+
$out = array($keyword, $value, false);
|
3077 |
+
$s = $this->seek();
|
3078 |
+
if ($this->literal("...")) {
|
3079 |
+
$out[2] = true;
|
3080 |
+
} else {
|
3081 |
+
$this->seek($s);
|
3082 |
+
}
|
3083 |
return true;
|
3084 |
}
|
3085 |
|
3088 |
|
3089 |
|
3090 |
protected function valueList(&$out) {
|
3091 |
+
return $this->genericList($out, "spaceList", ",");
|
3092 |
}
|
3093 |
|
3094 |
+
protected function spaceList(&$out) {
|
3095 |
+
return $this->genericList($out, "expression");
|
3096 |
}
|
3097 |
|
3098 |
protected function genericList(&$out, $parseItem, $delim="", $flatten=true) {
|
3216 |
if ($this->progid($out)) return true;
|
3217 |
|
3218 |
if ($this->keyword($keyword)) {
|
3219 |
+
if ($keyword == "null") {
|
3220 |
+
$out = array("null");
|
3221 |
+
} else {
|
3222 |
+
$out = array("keyword", $keyword);
|
3223 |
+
}
|
3224 |
return true;
|
3225 |
}
|
3226 |
|
3272 |
if ($this->keyword($name, false) &&
|
3273 |
$this->literal("("))
|
3274 |
{
|
3275 |
+
if ($name == "alpha" && $this->argumentList($args)) {
|
3276 |
+
$func = array("function", $name, array("string", "", $args));
|
3277 |
+
return true;
|
3278 |
+
}
|
3279 |
+
|
3280 |
+
if ($name != "expression" && !preg_match("/^(-[a-z]+-)?calc$/", $name)) {
|
3281 |
$ss = $this->seek();
|
3282 |
if ($this->argValues($args) && $this->literal(")")) {
|
3283 |
$func = array("fncall", $name, $args);
|
3303 |
return false;
|
3304 |
}
|
3305 |
|
3306 |
+
protected function argumentList(&$out) {
|
3307 |
+
$s = $this->seek();
|
3308 |
+
$this->literal("(");
|
3309 |
+
|
3310 |
+
$args = array();
|
3311 |
+
while ($this->keyword($var)) {
|
3312 |
+
$ss = $this->seek();
|
3313 |
+
|
3314 |
+
if ($this->literal("=") && $this->expression($exp)) {
|
3315 |
+
$args[] = array("string", "", array($var."="));
|
3316 |
+
$arg = $exp;
|
3317 |
+
} else {
|
3318 |
+
break;
|
3319 |
+
}
|
3320 |
+
|
3321 |
+
$args[] = $arg;
|
3322 |
+
|
3323 |
+
if (!$this->literal(",")) break;
|
3324 |
+
|
3325 |
+
$args[] = array("string", "", array(", "));
|
3326 |
+
}
|
3327 |
+
|
3328 |
+
if (!$this->literal(")")) {
|
3329 |
+
$this->seek($s);
|
3330 |
+
return false;
|
3331 |
+
}
|
3332 |
+
|
3333 |
+
$out = $args;
|
3334 |
+
return true;
|
3335 |
+
}
|
3336 |
+
|
3337 |
protected function argumentDef(&$out) {
|
3338 |
$s = $this->seek();
|
3339 |
$this->literal("(");
|
3340 |
|
3341 |
$args = array();
|
3342 |
while ($this->variable($var)) {
|
3343 |
+
$arg = array($var[1], null, false);
|
3344 |
|
3345 |
$ss = $this->seek();
|
3346 |
+
if ($this->literal(":") && $this->genericList($defaultVal, "expression")) {
|
3347 |
$arg[1] = $defaultVal;
|
3348 |
} else {
|
3349 |
$this->seek($ss);
|
3350 |
}
|
3351 |
|
3352 |
+
$ss = $this->seek();
|
3353 |
+
if ($this->literal("...")) {
|
3354 |
+
$sss = $this->seek();
|
3355 |
+
if (!$this->literal(")")) {
|
3356 |
+
$this->throwParseError("... has to be after the final argument");
|
3357 |
+
}
|
3358 |
+
$arg[2] = true;
|
3359 |
+
$this->seek($sss);
|
3360 |
+
} else {
|
3361 |
+
$this->seek($ss);
|
3362 |
+
}
|
3363 |
+
|
3364 |
$args[] = $arg;
|
3365 |
if (!$this->literal(",")) break;
|
3366 |
}
|
3420 |
}
|
3421 |
|
3422 |
$content = array();
|
|
|
|
|
|
|
|
|
|
|
3423 |
$oldWhite = $this->eatWhiteDefault;
|
3424 |
$this->eatWhiteDefault = false;
|
3425 |
|
3426 |
+
while ($this->matchString($m, $delim)) {
|
3427 |
$content[] = $m[1];
|
3428 |
if ($m[2] == "#{") {
|
3429 |
$this->count -= strlen($m[2]);
|
3481 |
|
3482 |
if (count($parts) == 0) return false;
|
3483 |
|
3484 |
+
if ($this->eatWhiteDefault) {
|
3485 |
+
$this->whitespace();
|
3486 |
+
}
|
3487 |
+
|
3488 |
$out = $parts;
|
3489 |
return true;
|
3490 |
}
|
3504 |
|
3505 |
$content = array();
|
3506 |
while ($this->match($patt, $m, false)) {
|
3507 |
+
if (isset($m[1]) && $m[1] !== '') {
|
3508 |
$content[] = $m[1];
|
3509 |
if ($nestingOpen) {
|
3510 |
$nestingLevel += substr_count($m[1], $nestingOpen);
|
3638 |
return true;
|
3639 |
}
|
3640 |
|
3641 |
+
// whitespace separated list of selectorSingle
|
3642 |
protected function selector(&$out) {
|
3643 |
$selector = array();
|
3644 |
|
3648 |
} elseif ($this->selectorSingle($part)) {
|
3649 |
$selector[] = $part;
|
3650 |
$this->whitespace();
|
3651 |
+
} elseif ($this->match('\/[^\/]+\/', $m)) {
|
3652 |
+
$selector[] = array($m[0]);
|
3653 |
} else {
|
3654 |
break;
|
3655 |
}
|
3665 |
}
|
3666 |
|
3667 |
// the parts that make up
|
3668 |
+
// div[yes=no]#something.hello.world:nth-child(-2n+1)%placeholder
|
3669 |
protected function selectorSingle(&$out) {
|
3670 |
$oldWhite = $this->eatWhiteDefault;
|
3671 |
$this->eatWhiteDefault = false;
|
3716 |
continue;
|
3717 |
}
|
3718 |
|
3719 |
+
if ($this->literal('%', false) && $this->placeholder($placeholder)) {
|
3720 |
+
$parts[] = '%';
|
3721 |
+
$parts[] = $placeholder;
|
3722 |
+
continue;
|
3723 |
+
}
|
3724 |
+
|
3725 |
if ($this->literal("#", false)) {
|
3726 |
$parts[] = "#";
|
3727 |
continue;
|
3832 |
return false;
|
3833 |
}
|
3834 |
|
3835 |
+
protected function placeholder(&$placeholder) {
|
3836 |
+
if ($this->match('([\w\-_]+)', $m)) {
|
3837 |
+
$placeholder = $m[1];
|
3838 |
+
return true;
|
3839 |
+
}
|
3840 |
+
return false;
|
3841 |
+
}
|
3842 |
+
|
3843 |
// consume an end of statement delimiter
|
3844 |
protected function end() {
|
3845 |
if ($this->literal(';')) {
|
3846 |
return true;
|
3847 |
+
} elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') {
|
3848 |
// if there is end of file or a closing block next then we don't need a ;
|
3849 |
return true;
|
3850 |
}
|
3866 |
return true;
|
3867 |
}
|
3868 |
|
3869 |
+
public function throwParseError($msg = "parse error", $count = null) {
|
3870 |
$count = is_null($count) ? $this->count : $count;
|
3871 |
|
3872 |
$line = $this->getLineNo($count);
|
3878 |
}
|
3879 |
|
3880 |
if ($this->peek("(.*?)(\n|$)", $m, $count)) {
|
3881 |
+
throw new Exception("$msg: failed at `$m[1]` $loc");
|
3882 |
} else {
|
3883 |
+
throw new Exception("$msg: $loc");
|
3884 |
}
|
3885 |
}
|
3886 |
|
3888 |
return 1 + substr_count(substr($this->buffer, 0, $pos), "\n");
|
3889 |
}
|
3890 |
|
3891 |
+
/**
|
3892 |
+
* Match string looking for either ending delim, escape, or string interpolation
|
3893 |
+
*
|
3894 |
+
* {@internal This is a workaround for preg_match's 250K string match limit. }}
|
3895 |
+
*
|
3896 |
+
* @param array $m Matches (passed by reference)
|
3897 |
+
* @param string $delim Delimeter
|
3898 |
+
*
|
3899 |
+
* @return boolean True if match; false otherwise
|
3900 |
+
*/
|
3901 |
+
protected function matchString(&$m, $delim) {
|
3902 |
+
$token = null;
|
3903 |
+
|
3904 |
+
$end = strpos($this->buffer, "\n", $this->count);
|
3905 |
+
if ($end === false) {
|
3906 |
+
$end = strlen($this->buffer);
|
3907 |
+
}
|
3908 |
+
|
3909 |
+
// look for either ending delim, escape, or string interpolation
|
3910 |
+
foreach (array('#{', '\\', $delim) as $lookahead) {
|
3911 |
+
$pos = strpos($this->buffer, $lookahead, $this->count);
|
3912 |
+
if ($pos !== false && $pos < $end) {
|
3913 |
+
$end = $pos;
|
3914 |
+
$token = $lookahead;
|
3915 |
+
}
|
3916 |
+
}
|
3917 |
+
|
3918 |
+
if (!isset($token)) {
|
3919 |
+
return false;
|
3920 |
+
}
|
3921 |
+
|
3922 |
+
$match = substr($this->buffer, $this->count, $end - $this->count);
|
3923 |
+
$m = array(
|
3924 |
+
$match . $token,
|
3925 |
+
$match,
|
3926 |
+
$token
|
3927 |
+
);
|
3928 |
+
$this->count = $end + strlen($token);
|
3929 |
+
|
3930 |
+
return true;
|
3931 |
+
}
|
3932 |
+
|
3933 |
// try to match something on head of buffer
|
3934 |
protected function match($regex, &$out, $eatWhitespace = null) {
|
3935 |
if (is_null($eatWhitespace)) $eatWhitespace = $this->eatWhiteDefault;
|
3994 |
}
|
3995 |
}
|
3996 |
|
3997 |
+
/**
|
3998 |
+
* SCSS base formatter
|
3999 |
+
*
|
4000 |
+
* @author Leaf Corcoran <leafot@gmail.com>
|
4001 |
+
*/
|
4002 |
class scss_formatter {
|
4003 |
public $indentChar = " ";
|
4004 |
|
4020 |
return $name . $this->assignSeparator . $value . ";";
|
4021 |
}
|
4022 |
|
4023 |
+
protected function block($block) {
|
4024 |
if (empty($block->lines) && empty($block->children)) return;
|
4025 |
|
4026 |
$inner = $pre = $this->indentStr();
|
4051 |
echo $pre . $this->close . $this->break;
|
4052 |
}
|
4053 |
}
|
|
|
4054 |
|
4055 |
+
public function format($block) {
|
4056 |
+
ob_start();
|
4057 |
+
$this->block($block);
|
4058 |
+
$out = ob_get_clean();
|
4059 |
+
|
4060 |
+
return $out;
|
4061 |
+
}
|
4062 |
+
}
|
4063 |
|
4064 |
+
/**
|
4065 |
+
* SCSS nested formatter
|
4066 |
+
*
|
4067 |
+
* @author Leaf Corcoran <leafot@gmail.com>
|
4068 |
+
*/
|
4069 |
class scss_formatter_nested extends scss_formatter {
|
4070 |
public $close = " }";
|
4071 |
|
4082 |
}
|
4083 |
$children[] = $child;
|
4084 |
}
|
4085 |
+
|
4086 |
+
$count = count($children);
|
4087 |
+
for ($i = 0; $i < $count; $i++) {
|
4088 |
+
$depth = $children[$i]->depth;
|
4089 |
+
$j = $i + 1;
|
4090 |
+
if (isset($children[$j]) && $depth < $children[$j]->depth) {
|
4091 |
+
$childDepth = $children[$j]->depth;
|
4092 |
+
for (; $j < $count; $j++) {
|
4093 |
+
if ($depth < $children[$j]->depth && $childDepth >= $children[$j]->depth) {
|
4094 |
+
$children[$j]->depth = $depth + 1;
|
4095 |
+
}
|
4096 |
+
}
|
4097 |
+
}
|
4098 |
+
}
|
4099 |
+
|
4100 |
$block->children = $children;
|
4101 |
|
4102 |
// make relative to parent
|
4106 |
}
|
4107 |
}
|
4108 |
|
4109 |
+
protected function block($block) {
|
4110 |
if ($block->type == "root") {
|
4111 |
$this->adjustAllChildren($block);
|
4112 |
}
|
4152 |
}
|
4153 |
}
|
4154 |
|
4155 |
+
/**
|
4156 |
+
* SCSS compressed formatter
|
4157 |
+
*
|
4158 |
+
* @author Leaf Corcoran <leafot@gmail.com>
|
4159 |
+
*/
|
4160 |
class scss_formatter_compressed extends scss_formatter {
|
4161 |
public $open = "{";
|
4162 |
public $tagSeparator = ",";
|
4168 |
}
|
4169 |
}
|
4170 |
|
4171 |
+
/**
|
4172 |
+
* SCSS server
|
4173 |
+
*
|
4174 |
+
* @author Leaf Corcoran <leafot@gmail.com>
|
4175 |
+
*/
|
4176 |
class scss_server {
|
4177 |
+
/**
|
4178 |
+
* Join path components
|
4179 |
+
*
|
4180 |
+
* @param string $left Path component, left of the directory separator
|
4181 |
+
* @param string $right Path component, right of the directory separator
|
4182 |
+
*
|
4183 |
+
* @return string
|
4184 |
+
*/
|
4185 |
protected function join($left, $right) {
|
4186 |
+
return rtrim($left, '/\\') . DIRECTORY_SEPARATOR . ltrim($right, '/\\');
|
4187 |
}
|
4188 |
|
4189 |
+
/**
|
4190 |
+
* Get name of requested .scss file
|
4191 |
+
*
|
4192 |
+
* @return string|null
|
4193 |
+
*/
|
4194 |
protected function inputName() {
|
4195 |
+
switch (true) {
|
4196 |
+
case isset($_GET['p']):
|
4197 |
+
return $_GET['p'];
|
4198 |
+
case isset($_SERVER['PATH_INFO']):
|
4199 |
+
return $_SERVER['PATH_INFO'];
|
4200 |
+
case isset($_SERVER['DOCUMENT_URI']):
|
4201 |
+
return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME']));
|
4202 |
}
|
4203 |
}
|
4204 |
|
4205 |
+
/**
|
4206 |
+
* Get path to requested .scss file
|
4207 |
+
*
|
4208 |
+
* @return string
|
4209 |
+
*/
|
4210 |
protected function findInput() {
|
4211 |
+
if ($input = $this->inputName()
|
4212 |
+
&& strpos($input, '..') === false
|
4213 |
+
&& substr($input, -5) === '.scss'
|
4214 |
+
) {
|
4215 |
$name = $this->join($this->dir, $input);
|
4216 |
+
|
4217 |
+
if (is_file($name) && is_readable($name)) {
|
4218 |
+
return $name;
|
4219 |
+
}
|
4220 |
}
|
4221 |
+
|
4222 |
return false;
|
4223 |
}
|
4224 |
|
4225 |
+
/**
|
4226 |
+
* Get path to cached .css file
|
4227 |
+
*
|
4228 |
+
* @return string
|
4229 |
+
*/
|
4230 |
protected function cacheName($fname) {
|
4231 |
+
return $this->join($this->cacheDir, md5($fname) . '.css');
|
4232 |
}
|
4233 |
|
4234 |
+
/**
|
4235 |
+
* Get path to cached imports
|
4236 |
+
*
|
4237 |
+
* @return string
|
4238 |
+
*/
|
4239 |
protected function importsCacheName($out) {
|
4240 |
+
return $out . '.imports';
|
4241 |
}
|
4242 |
|
4243 |
+
/**
|
4244 |
+
* Determine whether .scss file needs to be re-compiled.
|
4245 |
+
*
|
4246 |
+
* @param string $in Input path
|
4247 |
+
* @param string $out Output path
|
4248 |
+
*
|
4249 |
+
* @return boolean True if compile required.
|
4250 |
+
*/
|
4251 |
protected function needsCompile($in, $out) {
|
4252 |
if (!is_file($out)) return true;
|
4253 |
|
4265 |
return false;
|
4266 |
}
|
4267 |
|
4268 |
+
/**
|
4269 |
+
* Compile .scss file
|
4270 |
+
*
|
4271 |
+
* @param string $in Input path (.scss)
|
4272 |
+
* @param string $out Output path (.css)
|
4273 |
+
*
|
4274 |
+
* @return string
|
4275 |
+
*/
|
4276 |
protected function compile($in, $out) {
|
4277 |
$start = microtime(true);
|
4278 |
$css = $this->scss->compile(file_get_contents($in), $in);
|
4279 |
$elapsed = round((microtime(true) - $start), 4);
|
4280 |
|
4281 |
$v = scssc::$VERSION;
|
4282 |
+
$t = date('r');
|
4283 |
$css = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css;
|
4284 |
|
4285 |
file_put_contents($out, $css);
|
4288 |
return $css;
|
4289 |
}
|
4290 |
|
4291 |
+
/**
|
4292 |
+
* Compile requested scss and serve css. Outputs HTTP response.
|
4293 |
+
*/
|
4294 |
public function serve() {
|
4295 |
if ($input = $this->findInput()) {
|
4296 |
$output = $this->cacheName($input);
|
4297 |
+
header('Content-type: text/css');
|
4298 |
|
4299 |
if ($this->needsCompile($input, $output)) {
|
4300 |
try {
|
4301 |
echo $this->compile($input, $output);
|
4302 |
+
} catch (Exception $e) {
|
4303 |
header('HTTP/1.1 500 Internal Server Error');
|
4304 |
+
echo 'Parse error: ' . $e->getMessage() . "\n";
|
4305 |
}
|
4306 |
} else {
|
4307 |
header('X-SCSS-Cache: true');
|
4312 |
}
|
4313 |
|
4314 |
header('HTTP/1.0 404 Not Found');
|
4315 |
+
header('Content-type: text');
|
4316 |
$v = scssc::$VERSION;
|
4317 |
echo "/* INPUT NOT FOUND scss $v */\n";
|
4318 |
}
|
4319 |
|
4320 |
+
/**
|
4321 |
+
* Constructor
|
4322 |
+
*
|
4323 |
+
* @param string $dir Root directory to .scss files
|
4324 |
+
* @param string $cacheDir Cache directory
|
4325 |
+
* @param \scssc|null $scss SCSS compiler instance
|
4326 |
+
*/
|
4327 |
public function __construct($dir, $cacheDir=null, $scss=null) {
|
4328 |
$this->dir = $dir;
|
4329 |
|
4330 |
if (is_null($cacheDir)) {
|
4331 |
+
$cacheDir = $this->join($dir, 'scss_cache');
|
4332 |
}
|
4333 |
|
4334 |
$this->cacheDir = $cacheDir;
|
4341 |
$this->scss = $scss;
|
4342 |
}
|
4343 |
|
4344 |
+
/**
|
4345 |
+
* Helper method to serve compiled scss
|
4346 |
+
*
|
4347 |
+
* @param string $path Root path
|
4348 |
+
*/
|
4349 |
static public function serveFrom($path) {
|
4350 |
$server = new self($path);
|
4351 |
$server->serve();
|
4352 |
}
|
4353 |
}
|
|
|
|
modules/custom-post-types/comics.php
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
class Jetpack_Comic {
|
4 |
const POST_TYPE = 'jetpack-comic';
|
5 |
|
6 |
-
function init() {
|
7 |
static $instance = false;
|
8 |
|
9 |
if ( ! $instance )
|
@@ -78,13 +78,13 @@ class Jetpack_Comic {
|
|
78 |
<?php if ( ! $post_type || 'post' == $post_type ) { ?>
|
79 |
$( '<option>' )
|
80 |
.val( 'post2comic' )
|
81 |
-
.text( <?php echo json_encode( __( 'Convert to Comic' ) ); ?> )
|
82 |
.appendTo( "select[name='action'], select[name='action2']" );
|
83 |
<?php } ?>
|
84 |
<?php if ( ! $post_type || self::POST_TYPE == $post_type ) { ?>
|
85 |
$( '<option>' )
|
86 |
.val( 'comic2post' )
|
87 |
-
.text( <?php echo json_encode( __( 'Convert to Post' ) ); ?> )
|
88 |
.appendTo( "select[name='action'], select[name='action2']" );
|
89 |
<?php } ?>
|
90 |
|
@@ -108,7 +108,7 @@ class Jetpack_Comic {
|
|
108 |
|
109 |
if ( 'post2comic' == $action || 'comic2post' == $action ) {
|
110 |
if ( ! current_user_can( 'publish_posts' ) )
|
111 |
-
wp_die( __( 'You are not allowed to make this change.' ) );
|
112 |
|
113 |
$post_ids = array_map( 'intval', $_REQUEST['post'] );
|
114 |
|
@@ -142,7 +142,7 @@ class Jetpack_Comic {
|
|
142 |
$pagenum = $wp_list_table->get_pagenum();
|
143 |
$sendback = add_query_arg( array( 'paged' => $pagenum, 'post_type_changed' => $modified_count ), $sendback );
|
144 |
|
145 |
-
|
146 |
exit();
|
147 |
}
|
148 |
}
|
@@ -155,7 +155,7 @@ class Jetpack_Comic {
|
|
155 |
|
156 |
if ( 'edit.php' == $pagenow && ! empty( $_GET['post_type_changed'] ) ) {
|
157 |
?><div id="message" class="updated below-h2 jetpack-comic-post-type-conversion" style="display: none;"><p><?php
|
158 |
-
printf( _n( 'Post converted.', '%s posts converted', $_GET['post_type_changed'] ), number_format_i18n( $_GET['post_type_changed'] ) );
|
159 |
?></p></div><?php
|
160 |
}
|
161 |
}
|
@@ -171,7 +171,7 @@ class Jetpack_Comic {
|
|
171 |
'dragging' => __( 'Drop images to upload', 'jetpack' ),
|
172 |
'uploading' => __( 'Uploading...', 'jetpack' ),
|
173 |
'processing' => __( 'Processing...', 'jetpack' ),
|
174 |
-
'unsupported' => __( "Sorry, your browser isn't supported. Upgrade at browsehappy.com." ),
|
175 |
'invalidUpload' => __( 'Only images can be uploaded here.', 'jetpack' ),
|
176 |
'error' => __( "Your upload didn't complete; try again later or cross your fingers and try again right now.", 'jetpack' ),
|
177 |
)
|
@@ -279,7 +279,7 @@ class Jetpack_Comic {
|
|
279 |
8 => sprintf( __( 'Comic submitted. <a target="_blank" href="%s">Preview comic</a>', 'jetpack'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ),
|
280 |
9 => sprintf( __( 'Comic scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview comic</a>', 'jetpack' ),
|
281 |
// translators: Publish box date format, see http://php.net/date
|
282 |
-
date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post->ID) ) ),
|
283 |
10 => sprintf( __( 'Comic draft updated. <a target="_blank" href="%s">Preview comic</a>', 'jetpack' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ),
|
284 |
);
|
285 |
|
@@ -302,7 +302,7 @@ class Jetpack_Comic {
|
|
302 |
}
|
303 |
|
304 |
private function _site_supports_comics() {
|
305 |
-
return ( site_vertical
|
306 |
}
|
307 |
|
308 |
/**
|
@@ -341,7 +341,7 @@ class Jetpack_Comic {
|
|
341 |
header( 'Content-Type: application/json' );
|
342 |
|
343 |
if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'jetpack_comic_upload_nonce' ) )
|
344 |
-
die( json_encode( array( 'error' => __( 'Invalid or expired nonce.' ) ) ) );
|
345 |
|
346 |
$_POST['action'] = 'wp_handle_upload';
|
347 |
|
@@ -457,7 +457,7 @@ Your webcomic's new site is ready to go. Get started by <a href=\"BLOG_URLwp-adm
|
|
457 |
Looking for more help with setting up your site? Check out the WordPress.com <a href=\"http://learn.wordpress.com/\">beginner's tutorial</a> and the <a href=\"http://en.support.wordpress.com/comics/\">guide to comics on WordPress.com</a>. Dive right in by <a href=\"BLOG_URLwp-admin/customize.php#title\">publishing your first strip!</a>
|
458 |
|
459 |
Lots of laughs,
|
460 |
-
The WordPress.com Team" );
|
461 |
}
|
462 |
|
463 |
return $welcome_email;
|
1 |
<?php
|
2 |
+
|
3 |
class Jetpack_Comic {
|
4 |
const POST_TYPE = 'jetpack-comic';
|
5 |
|
6 |
+
static function init() {
|
7 |
static $instance = false;
|
8 |
|
9 |
if ( ! $instance )
|
78 |
<?php if ( ! $post_type || 'post' == $post_type ) { ?>
|
79 |
$( '<option>' )
|
80 |
.val( 'post2comic' )
|
81 |
+
.text( <?php echo json_encode( __( 'Convert to Comic', 'jetpack' ) ); ?> )
|
82 |
.appendTo( "select[name='action'], select[name='action2']" );
|
83 |
<?php } ?>
|
84 |
<?php if ( ! $post_type || self::POST_TYPE == $post_type ) { ?>
|
85 |
$( '<option>' )
|
86 |
.val( 'comic2post' )
|
87 |
+
.text( <?php echo json_encode( __( 'Convert to Post', 'jetpack' ) ); ?> )
|
88 |
.appendTo( "select[name='action'], select[name='action2']" );
|
89 |
<?php } ?>
|
90 |
|
108 |
|
109 |
if ( 'post2comic' == $action || 'comic2post' == $action ) {
|
110 |
if ( ! current_user_can( 'publish_posts' ) )
|
111 |
+
wp_die( __( 'You are not allowed to make this change.', 'jetpack' ) );
|
112 |
|
113 |
$post_ids = array_map( 'intval', $_REQUEST['post'] );
|
114 |
|
142 |
$pagenum = $wp_list_table->get_pagenum();
|
143 |
$sendback = add_query_arg( array( 'paged' => $pagenum, 'post_type_changed' => $modified_count ), $sendback );
|
144 |
|
145 |
+
wp_safe_redirect( $sendback );
|
146 |
exit();
|
147 |
}
|
148 |
}
|
155 |
|
156 |
if ( 'edit.php' == $pagenow && ! empty( $_GET['post_type_changed'] ) ) {
|
157 |
?><div id="message" class="updated below-h2 jetpack-comic-post-type-conversion" style="display: none;"><p><?php
|
158 |
+
printf( _n( 'Post converted.', '%s posts converted', $_GET['post_type_changed'], 'jetpack' ), number_format_i18n( $_GET['post_type_changed'] ) );
|
159 |
?></p></div><?php
|
160 |
}
|
161 |
}
|
171 |
'dragging' => __( 'Drop images to upload', 'jetpack' ),
|
172 |
'uploading' => __( 'Uploading...', 'jetpack' ),
|
173 |
'processing' => __( 'Processing...', 'jetpack' ),
|
174 |
+
'unsupported' => __( "Sorry, your browser isn't supported. Upgrade at browsehappy.com.", 'jetpack' ),
|
175 |
'invalidUpload' => __( 'Only images can be uploaded here.', 'jetpack' ),
|
176 |
'error' => __( "Your upload didn't complete; try again later or cross your fingers and try again right now.", 'jetpack' ),
|
177 |
)
|
279 |
8 => sprintf( __( 'Comic submitted. <a target="_blank" href="%s">Preview comic</a>', 'jetpack'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ),
|
280 |
9 => sprintf( __( 'Comic scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview comic</a>', 'jetpack' ),
|
281 |
// translators: Publish box date format, see http://php.net/date
|
282 |
+
date_i18n( __( 'M j, Y @ G:i', 'jetpack' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post->ID) ) ),
|
283 |
10 => sprintf( __( 'Comic draft updated. <a target="_blank" href="%s">Preview comic</a>', 'jetpack' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ),
|
284 |
);
|
285 |
|
302 |
}
|
303 |
|
304 |
private function _site_supports_comics() {
|
305 |
+
return ( ( function_exists( 'site_vertical' ) && 'comics' == site_vertical() ) || current_theme_supports( self::POST_TYPE ) );
|
306 |
}
|
307 |
|
308 |
/**
|
341 |
header( 'Content-Type: application/json' );
|
342 |
|
343 |
if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'jetpack_comic_upload_nonce' ) )
|
344 |
+
die( json_encode( array( 'error' => __( 'Invalid or expired nonce.', 'jetpack' ) ) ) );
|
345 |
|
346 |
$_POST['action'] = 'wp_handle_upload';
|
347 |
|
457 |
Looking for more help with setting up your site? Check out the WordPress.com <a href=\"http://learn.wordpress.com/\">beginner's tutorial</a> and the <a href=\"http://en.support.wordpress.com/comics/\">guide to comics on WordPress.com</a>. Dive right in by <a href=\"BLOG_URLwp-admin/customize.php#title\">publishing your first strip!</a>
|
458 |
|
459 |
Lots of laughs,
|
460 |
+
The WordPress.com Team", 'jetpack' );
|
461 |
}
|
462 |
|
463 |
return $welcome_email;
|
modules/custom-post-types/testimonial.php
CHANGED
@@ -14,7 +14,7 @@ class Jetpack_Testimonial {
|
|
14 |
|
15 |
var $version = '0.1';
|
16 |
|
17 |
-
function init() {
|
18 |
static $instance = false;
|
19 |
|
20 |
if ( ! $instance )
|
@@ -128,7 +128,7 @@ class Jetpack_Testimonial {
|
|
128 |
8 => sprintf( __( 'Testimonial submitted. <a target="_blank" href="%s">Preview testimonial</a>', 'jetpack'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ),
|
129 |
9 => sprintf( __( 'Testimonial scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview testimonial</a>', 'jetpack' ),
|
130 |
// translators: Publish box date format, see http://php.net/date
|
131 |
-
date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post->ID) ) ),
|
132 |
10 => sprintf( __( 'Testimonial draft updated. <a target="_blank" href="%s">Preview testimonial</a>', 'jetpack' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ),
|
133 |
);
|
134 |
|
@@ -283,4 +283,4 @@ function jetpack_testimonial_custom_control_classes() {
|
|
283 |
}
|
284 |
}
|
285 |
|
286 |
-
add_action( 'init', array( 'Jetpack_Testimonial', 'init' ) );
|
14 |
|
15 |
var $version = '0.1';
|
16 |
|
17 |
+
static function init() {
|
18 |
static $instance = false;
|
19 |
|
20 |
if ( ! $instance )
|
128 |
8 => sprintf( __( 'Testimonial submitted. <a target="_blank" href="%s">Preview testimonial</a>', 'jetpack'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ),
|
129 |
9 => sprintf( __( 'Testimonial scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview testimonial</a>', 'jetpack' ),
|
130 |
// translators: Publish box date format, see http://php.net/date
|
131 |
+
date_i18n( __( 'M j, Y @ G:i', 'jetpack' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post->ID) ) ),
|
132 |
10 => sprintf( __( 'Testimonial draft updated. <a target="_blank" href="%s">Preview testimonial</a>', 'jetpack' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ),
|
133 |
);
|
134 |
|
283 |
}
|
284 |
}
|
285 |
|
286 |
+
add_action( 'init', array( 'Jetpack_Testimonial', 'init' ) );
|
modules/debug.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Deprecated. No longer needed.
|
4 |
+
*
|
5 |
+
* @package Jetpack
|
6 |
+
*/
|
modules/enhanced-distribution.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 100
|
6 |
* First Introduced: 1.2
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
Jetpack_Sync::sync_posts( __FILE__ );
|
5 |
* Sort Order: 100
|
6 |
* First Introduced: 1.2
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Public
|
9 |
*/
|
10 |
|
11 |
Jetpack_Sync::sync_posts( __FILE__ );
|
modules/gravatar-hovercards.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 8
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: No
|
|
|
8 |
*/
|
9 |
|
10 |
define( 'GROFILES__CACHE_BUSTER', gmdate( 'YM' ) . 'aa' ); // Break CDN cache, increment when gravatar.com/js/gprofiles.js changes
|
5 |
* Sort Order: 8
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: No
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
define( 'GROFILES__CACHE_BUSTER', gmdate( 'YM' ) . 'aa' ); // Break CDN cache, increment when gravatar.com/js/gprofiles.js changes
|
modules/holiday-snow.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* Not a module that is activated/deactivated
|
7 |
* First Introduced: 2.0.3 ??
|
8 |
* Requires Connection: No
|
|
|
9 |
*/
|
10 |
|
11 |
class Jetpack_Holiday_Snow_Settings {
|
6 |
* Not a module that is activated/deactivated
|
7 |
* First Introduced: 2.0.3 ??
|
8 |
* Requires Connection: No
|
9 |
+
* Auto Activate: Yes
|
10 |
*/
|
11 |
|
12 |
class Jetpack_Holiday_Snow_Settings {
|
modules/infinite-scroll.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 14
|
6 |
* First Introduced: 2.0
|
7 |
* Requires Connection: No
|
|
|
8 |
*/
|
9 |
|
10 |
/**
|
5 |
* Sort Order: 14
|
6 |
* First Introduced: 2.0
|
7 |
* Requires Connection: No
|
8 |
+
* Auto Activate: No
|
9 |
*/
|
10 |
|
11 |
/**
|
modules/json-api.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 100
|
6 |
* First Introduced: 1.9
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
function jetpack_json_api_toggle() {
|
5 |
* Sort Order: 100
|
6 |
* First Introduced: 1.9
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Public
|
9 |
*/
|
10 |
|
11 |
function jetpack_json_api_toggle() {
|
modules/latex.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 12
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
/**
|
5 |
* Sort Order: 12
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
/**
|
modules/likes.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* First Introduced: 2.2
|
6 |
* Sort Order: 4
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
class Jetpack_Likes {
|
10 |
var $version = '20130620a';
|
@@ -520,11 +521,11 @@ class Jetpack_Likes {
|
|
520 |
.fixed .column-likes .post-com-count { background-image: none; }
|
521 |
.fixed .column-likes .comment-count { background-color: #888; }
|
522 |
.fixed .column-likes .comment-count:hover { background-color: #D54E21; }
|
523 |
-
.
|
524 |
-
.
|
525 |
-
.
|
526 |
-
.
|
527 |
-
.
|
528 |
</style> <?php
|
529 |
}
|
530 |
|
@@ -533,10 +534,14 @@ class Jetpack_Likes {
|
|
533 |
*/
|
534 |
function enqueue_admin_scripts() {
|
535 |
if ( empty( $_GET['post_type'] ) || 'post' == $_GET['post_type'] || 'page' == $_GET['post_type'] ) {
|
536 |
-
if ( $this->in_jetpack )
|
537 |
wp_enqueue_script( 'likes-post-count', plugins_url( 'modules/likes/post-count.js', dirname( __FILE__ ) ), array( 'jquery' ), JETPACK__VERSION );
|
538 |
-
|
|
|
|
|
539 |
wp_enqueue_script( 'likes-post-count', plugins_url( 'likes/post-count.js', dirname( __FILE__ ) ), array( 'jquery' ), JETPACK__VERSION );
|
|
|
|
|
540 |
}
|
541 |
}
|
542 |
|
@@ -586,10 +591,6 @@ class Jetpack_Likes {
|
|
586 |
if ( ! $this->is_likes_visible() )
|
587 |
return $content;
|
588 |
|
589 |
-
$protocol = 'http';
|
590 |
-
if ( is_ssl() )
|
591 |
-
$protocol = 'https';
|
592 |
-
|
593 |
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
594 |
$blog_id = get_current_blog_id();
|
595 |
$bloginfo = get_blog_details( (int) $blog_id );
|
@@ -610,7 +611,7 @@ class Jetpack_Likes {
|
|
610 |
*/
|
611 |
$uniqid = uniqid();
|
612 |
|
613 |
-
$src = sprintf( '
|
614 |
$name = sprintf( 'like-post-frame-%1$d-%2$d-%3$s', $blog_id, $post->ID, $uniqid );
|
615 |
$wrapper = sprintf( 'like-post-wrapper-%1$d-%2$d-%3$s', $blog_id, $post->ID, $uniqid );
|
616 |
|
5 |
* First Introduced: 2.2
|
6 |
* Sort Order: 4
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: No
|
9 |
*/
|
10 |
class Jetpack_Likes {
|
11 |
var $version = '20130620a';
|
521 |
.fixed .column-likes .post-com-count { background-image: none; }
|
522 |
.fixed .column-likes .comment-count { background-color: #888; }
|
523 |
.fixed .column-likes .comment-count:hover { background-color: #D54E21; }
|
524 |
+
.mp6 .fixed .column-likes .post-com-count::after { border: none !important; }
|
525 |
+
.mp6 .fixed .column-likes .comment-count { background-color: #bbb; }
|
526 |
+
.mp6 .fixed .column-likes .comment-count:hover { background-color: #2ea2cc; }
|
527 |
+
.mp6 .fixed .column-likes .vers img { display: none; }
|
528 |
+
.mp6 .fixed .column-likes .vers:before {font:20px/1 dashicons;content: '\f155';-webkit-font-smoothing:antialiased;}
|
529 |
</style> <?php
|
530 |
}
|
531 |
|
534 |
*/
|
535 |
function enqueue_admin_scripts() {
|
536 |
if ( empty( $_GET['post_type'] ) || 'post' == $_GET['post_type'] || 'page' == $_GET['post_type'] ) {
|
537 |
+
if ( $this->in_jetpack ) {
|
538 |
wp_enqueue_script( 'likes-post-count', plugins_url( 'modules/likes/post-count.js', dirname( __FILE__ ) ), array( 'jquery' ), JETPACK__VERSION );
|
539 |
+
wp_enqueue_script( 'likes-post-count-jetpack', plugins_url( 'modules/likes/post-count-jetpack.js', dirname( __FILE__ ) ), array( 'likes-post-count' ), JETPACK__VERSION );
|
540 |
+
} else {
|
541 |
+
wp_enqueue_script( 'jquery.wpcom-proxy-request', "/wp-content/js/jquery/jquery.wpcom-proxy-request.js", array('jquery'), NULL, true );
|
542 |
wp_enqueue_script( 'likes-post-count', plugins_url( 'likes/post-count.js', dirname( __FILE__ ) ), array( 'jquery' ), JETPACK__VERSION );
|
543 |
+
wp_enqueue_script( 'likes-post-count-wpcom', plugins_url( 'likes/post-count-wpcom.js', dirname( __FILE__ ) ), array( 'likes-post-count', 'jquery.wpcom-proxy-request' ), JETPACK__VERSION );
|
544 |
+
}
|
545 |
}
|
546 |
}
|
547 |
|
591 |
if ( ! $this->is_likes_visible() )
|
592 |
return $content;
|
593 |
|
|
|
|
|
|
|
|
|
594 |
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
595 |
$blog_id = get_current_blog_id();
|
596 |
$bloginfo = get_blog_details( (int) $blog_id );
|
611 |
*/
|
612 |
$uniqid = uniqid();
|
613 |
|
614 |
+
$src = sprintf( '//widgets.wp.com/likes/#blog_id=%1$d&post_id=%2$d&origin=%3$s&obj_id=%1$d-%2$d-%4$s', $blog_id, $post->ID, $domain, $uniqid );
|
615 |
$name = sprintf( 'like-post-frame-%1$d-%2$d-%3$s', $blog_id, $post->ID, $uniqid );
|
616 |
$wrapper = sprintf( 'like-post-wrapper-%1$d-%2$d-%3$s', $blog_id, $post->ID, $uniqid );
|
617 |
|
modules/likes/post-count-jetpack.js
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var wpPostLikeCount = wpPostLikeCount || {};
|
2 |
+
|
3 |
+
(function($) {
|
4 |
+
|
5 |
+
wpPostLikeCount = jQuery.extend( wpPostLikeCount, {
|
6 |
+
request: function( options ) {
|
7 |
+
return $.ajax( {
|
8 |
+
type: 'GET',
|
9 |
+
url: wpPostLikeCount.jsonAPIbase + options.path,
|
10 |
+
dataType : "jsonp",
|
11 |
+
data: options.data,
|
12 |
+
success: function( response ) { options.success( response ); },
|
13 |
+
error: function( response ) { options.error( response ); }
|
14 |
+
} );
|
15 |
+
}
|
16 |
+
} );
|
17 |
+
|
18 |
+
})(jQuery);
|
modules/likes/post-count.js
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
var wpPostLikeCount;
|
2 |
|
3 |
(function($) {
|
4 |
|
5 |
-
wpPostLikeCount = {
|
6 |
|
7 |
jsonAPIbase: 'https://public-api.wordpress.com/rest/v1',
|
8 |
APIqueue: [],
|
@@ -47,23 +47,11 @@ var wpPostLikeCount;
|
|
47 |
}
|
48 |
|
49 |
wpPostLikeCount.request( batchRequest );
|
50 |
-
},
|
51 |
-
|
52 |
-
request: function( options ) {
|
53 |
-
return $.ajax( {
|
54 |
-
type: 'GET',
|
55 |
-
url: wpPostLikeCount.jsonAPIbase + options.path,
|
56 |
-
dataType : "jsonp",
|
57 |
-
data: options.data,
|
58 |
-
success: function( response ) { options.success( response ) },
|
59 |
-
error: function( response ) { options.error( response ) }
|
60 |
-
} )
|
61 |
}
|
62 |
-
|
63 |
-
};
|
64 |
|
65 |
})(jQuery);
|
66 |
|
67 |
jQuery(document).ready(function($) {
|
68 |
wpPostLikeCount.wpPostLikeCount();
|
69 |
-
});
|
1 |
+
var wpPostLikeCount = wpPostLikeCount || {};
|
2 |
|
3 |
(function($) {
|
4 |
|
5 |
+
wpPostLikeCount = jQuery.extend( wpPostLikeCount, {
|
6 |
|
7 |
jsonAPIbase: 'https://public-api.wordpress.com/rest/v1',
|
8 |
APIqueue: [],
|
47 |
}
|
48 |
|
49 |
wpPostLikeCount.request( batchRequest );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
+
} );
|
|
|
52 |
|
53 |
})(jQuery);
|
54 |
|
55 |
jQuery(document).ready(function($) {
|
56 |
wpPostLikeCount.wpPostLikeCount();
|
57 |
+
});
|
modules/likes/style.css
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
#wpadminbar li#wp-admin-bar-admin-bar-likes-widget {
|
2 |
width: 61px;
|
|
|
3 |
}
|
4 |
-
|
5 |
#wpadminbar iframe.admin-bar-likes-widget {
|
6 |
width: 61px;
|
7 |
height: 28px;
|
1 |
#wpadminbar li#wp-admin-bar-admin-bar-likes-widget {
|
2 |
width: 61px;
|
3 |
+
overflow: hidden;
|
4 |
}
|
|
|
5 |
#wpadminbar iframe.admin-bar-likes-widget {
|
6 |
width: 61px;
|
7 |
height: 28px;
|
modules/minileven.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* Sort Order: 11
|
7 |
* First Introduced: 1.8
|
8 |
* Requires Connection: No
|
|
|
9 |
*/
|
10 |
|
11 |
function jetpack_load_minileven() {
|
6 |
* Sort Order: 11
|
7 |
* First Introduced: 1.8
|
8 |
* Requires Connection: No
|
9 |
+
* Auto Activate: No
|
10 |
*/
|
11 |
|
12 |
function jetpack_load_minileven() {
|
modules/minileven/theme/pub/minileven/functions.php
CHANGED
@@ -40,6 +40,11 @@ function minileven_setup() {
|
|
40 |
*/
|
41 |
require( get_template_directory() . '/inc/tweaks.php' );
|
42 |
|
|
|
|
|
|
|
|
|
|
|
43 |
/* Make Minileven available for translation.
|
44 |
* Translations can be added to the /languages/ directory.
|
45 |
* If you're building a theme based on Minileven, use a find and replace
|
@@ -176,11 +181,6 @@ function minileven_get_background() {
|
|
176 |
return false;
|
177 |
}
|
178 |
|
179 |
-
/**
|
180 |
-
* Implement the Custom Header functions
|
181 |
-
*/
|
182 |
-
require( get_template_directory() . '/inc/custom-header.php' );
|
183 |
-
|
184 |
/**
|
185 |
* If the user has set a static front page, show all posts on the front page, instead of a static page.
|
186 |
*/
|
40 |
*/
|
41 |
require( get_template_directory() . '/inc/tweaks.php' );
|
42 |
|
43 |
+
/**
|
44 |
+
* Implement the Custom Header functions
|
45 |
+
*/
|
46 |
+
require( get_template_directory() . '/inc/custom-header.php' );
|
47 |
+
|
48 |
/* Make Minileven available for translation.
|
49 |
* Translations can be added to the /languages/ directory.
|
50 |
* If you're building a theme based on Minileven, use a find and replace
|
181 |
return false;
|
182 |
}
|
183 |
|
|
|
|
|
|
|
|
|
|
|
184 |
/**
|
185 |
* If the user has set a static front page, show all posts on the front page, instead of a static page.
|
186 |
*/
|
modules/minileven/theme/pub/minileven/style.css
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
/*
|
2 |
Theme Name: Minileven
|
3 |
-
Theme URI: http://
|
4 |
Author: Automattic
|
5 |
-
Author URI: http://
|
6 |
Description: The Minileven theme is a clean, lightweight mobile experience for your blog based on Twenty Eleven.
|
7 |
Version: 2.0-wpcom
|
8 |
License: GNU General Public License
|
@@ -1483,8 +1483,11 @@ p.comment-form-comment {
|
|
1483 |
display: block;
|
1484 |
}
|
1485 |
#wpl-mustlogin {
|
1486 |
-
width: 240px !important;
|
1487 |
-
margin-left: -60px !important;
|
|
|
|
|
|
|
1488 |
}
|
1489 |
|
1490 |
/* WP.com comment form */
|
1 |
/*
|
2 |
Theme Name: Minileven
|
3 |
+
Theme URI: http://theme.wordpress.com
|
4 |
Author: Automattic
|
5 |
+
Author URI: http://theme.wordpress.com
|
6 |
Description: The Minileven theme is a clean, lightweight mobile experience for your blog based on Twenty Eleven.
|
7 |
Version: 2.0-wpcom
|
8 |
License: GNU General Public License
|
1483 |
display: block;
|
1484 |
}
|
1485 |
#wpl-mustlogin {
|
1486 |
+
width: 240px !important;
|
1487 |
+
margin-left: -60px !important;
|
1488 |
+
}
|
1489 |
+
img.latex {
|
1490 |
+
display: inline;
|
1491 |
}
|
1492 |
|
1493 |
/* WP.com comment form */
|
modules/mobile-push.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 100
|
6 |
* First Introduced: 1.9
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
Jetpack_Sync::sync_comments( __FILE__, array(
|
5 |
* Sort Order: 100
|
6 |
* First Introduced: 1.9
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
Jetpack_Sync::sync_comments( __FILE__, array(
|
modules/module-extras.php
CHANGED
@@ -4,57 +4,16 @@
|
|
4 |
* For example, if a module shouldn't be activatable unless certain conditions are met, the code belongs in this file.
|
5 |
*/
|
6 |
|
7 |
-
/**
|
8 |
-
* INFINITE SCROLL
|
9 |
-
*/
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Load theme's infinite scroll annotation file, if present in the IS plugin.
|
13 |
-
* The `setup_theme` action is used because the annotation files should be using `after_setup_theme` to register support for IS.
|
14 |
-
*
|
15 |
-
* As released in Jetpack 2.0, a child theme's parent wasn't checked for in the plugin's bundled support, hence the convoluted way the parent is checked for now.
|
16 |
-
*
|
17 |
-
* @uses is_admin, wp_get_theme, get_theme, get_current_theme, apply_filters
|
18 |
-
* @action setup_theme
|
19 |
-
* @return null
|
20 |
-
*/
|
21 |
-
function jetpack_load_infinite_scroll_annotation() {
|
22 |
-
if ( is_admin() && isset( $_GET['page'] ) && 'jetpack' == $_GET['page'] ) {
|
23 |
-
$theme = function_exists( 'wp_get_theme' ) ? wp_get_theme() : get_theme( get_current_theme() );
|
24 |
-
|
25 |
-
if ( ! is_a( $theme, 'WP_Theme' ) && ! is_array( $theme ) )
|
26 |
-
return;
|
27 |
-
|
28 |
-
$customization_file = apply_filters( 'infinite_scroll_customization_file', dirname( __FILE__ ) . "/infinite-scroll/themes/{$theme['Stylesheet']}.php", $theme['Stylesheet'] );
|
29 |
-
|
30 |
-
if ( is_readable( $customization_file ) ) {
|
31 |
-
require_once( $customization_file );
|
32 |
-
}
|
33 |
-
elseif ( ! empty( $theme['Template'] ) ) {
|
34 |
-
$customization_file = dirname( __FILE__ ) . "/infinite-scroll/themes/{$theme['Template']}.php";
|
35 |
-
|
36 |
-
if ( is_readable( $customization_file ) )
|
37 |
-
require_once( $customization_file );
|
38 |
-
}
|
39 |
-
}
|
40 |
-
}
|
41 |
-
add_action( 'setup_theme', 'jetpack_load_infinite_scroll_annotation' );
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Prevent IS from being activated if theme doesn't support it
|
45 |
-
*
|
46 |
-
* @param bool $can_activate
|
47 |
-
* @filter jetpack_can_activate_infinite-scroll
|
48 |
-
* @return bool
|
49 |
-
*/
|
50 |
-
function jetpack_can_activate_infinite_scroll( $can_activate ) {
|
51 |
-
return (bool) current_theme_supports( 'infinite-scroll' );
|
52 |
-
}
|
53 |
-
add_filter( 'jetpack_can_activate_infinite-scroll', 'jetpack_can_activate_infinite_scroll' );
|
54 |
-
|
55 |
// Happy Holidays!
|
56 |
require_once( dirname( __FILE__ ) . '/holiday-snow.php' );
|
57 |
|
58 |
-
|
|
|
59 |
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* For example, if a module shouldn't be activatable unless certain conditions are met, the code belongs in this file.
|
5 |
*/
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
// Happy Holidays!
|
8 |
require_once( dirname( __FILE__ ) . '/holiday-snow.php' );
|
9 |
|
10 |
+
// Include extra tools that aren't modules, in a filterable way
|
11 |
+
$jetpack_tools_to_include = apply_filters( 'jetpack-tools-to-include', array( 'theme-tools.php' ) );
|
12 |
|
13 |
+
if ( ! empty( $jetpack_tools_to_include ) ) {
|
14 |
+
foreach ( $jetpack_tools_to_include as $tool ) {
|
15 |
+
if ( file_exists( JETPACK__PLUGIN_DIR . '/modules/' . $tool ) ) {
|
16 |
+
require_once( JETPACK__PLUGIN_DIR . '/modules/' . $tool );
|
17 |
+
}
|
18 |
+
}
|
19 |
+
}
|
modules/module-info.php
CHANGED
@@ -777,30 +777,9 @@ function jetpack_likes_more_link() {
|
|
777 |
add_action( 'jetpack_learn_more_button_likes', 'jetpack_likes_more_link' );
|
778 |
// Likes: STOP
|
779 |
|
780 |
-
// Debug: START
|
781 |
-
function jetpack_debug_more_info() { ?>
|
782 |
-
|
783 |
-
<h4><?php esc_html_e( 'Debug' , 'jetpack' ); ?></h4>
|
784 |
-
|
785 |
-
<p><?php esc_html_e( "A debugging platform for the Jetpack plugin. Find out why Jetpack isn't working for you and submit a help request direct from your Dashboard.", 'jetpack' ); ?></p>
|
786 |
-
<?php if ( Jetpack::is_module_active( 'debug' ) ) : ?>
|
787 |
-
<p><a href="<?php echo admin_url( 'admin.php?page=jetpack-debugger' ); ?>"><?php esc_html_e( "Click here to start debugging.", 'jetpack' ); ?></a></p>
|
788 |
-
|
789 |
-
<?php endif; ?>
|
790 |
-
<?php
|
791 |
-
}
|
792 |
-
|
793 |
-
function jetpack_debug_more_link() {
|
794 |
-
echo '<a class="button-secondary more-info-link" href="http://jetpack.me/support/debug/">' . __( 'Learn More', 'jetpack' ) . '</a>';
|
795 |
-
}
|
796 |
-
|
797 |
-
add_action( 'jetpack_module_more_info_debug', 'jetpack_debug_more_info' );
|
798 |
-
add_action( 'jetpack_module_more_info_connected_debug', 'jetpack_debug_more_info' );
|
799 |
-
add_action( 'jetpack_learn_more_button_debug', 'jetpack_debug_more_link' );
|
800 |
-
// Debug: STOP
|
801 |
-
|
802 |
// Omnisearch: START
|
803 |
-
function jetpack_omnisearch_more_info() {
|
|
|
804 |
|
805 |
<h4><?php esc_html_e( 'Omnisearch' , 'jetpack' ); ?></h4>
|
806 |
|
@@ -812,7 +791,7 @@ function jetpack_omnisearch_more_info() { ?>
|
|
812 |
<?php echo Jetpack_Omnisearch::get_omnisearch_form(); ?>
|
813 |
<?php endif; ?>
|
814 |
|
815 |
-
<?php
|
816 |
}
|
817 |
|
818 |
function jetpack_omnisearch_more_link() {
|
@@ -822,3 +801,41 @@ function jetpack_omnisearch_more_link() {
|
|
822 |
add_action( 'jetpack_module_more_info_omnisearch', 'jetpack_omnisearch_more_info' );
|
823 |
add_action( 'jetpack_learn_more_button_omnisearch', 'jetpack_omnisearch_more_link' );
|
824 |
// Omnisearch: STOP
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
777 |
add_action( 'jetpack_learn_more_button_likes', 'jetpack_likes_more_link' );
|
778 |
// Likes: STOP
|
779 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
780 |
// Omnisearch: START
|
781 |
+
function jetpack_omnisearch_more_info() {
|
782 |
+
?>
|
783 |
|
784 |
<h4><?php esc_html_e( 'Omnisearch' , 'jetpack' ); ?></h4>
|
785 |
|
791 |
<?php echo Jetpack_Omnisearch::get_omnisearch_form(); ?>
|
792 |
<?php endif; ?>
|
793 |
|
794 |
+
<?php
|
795 |
}
|
796 |
|
797 |
function jetpack_omnisearch_more_link() {
|
801 |
add_action( 'jetpack_module_more_info_omnisearch', 'jetpack_omnisearch_more_info' );
|
802 |
add_action( 'jetpack_learn_more_button_omnisearch', 'jetpack_omnisearch_more_link' );
|
803 |
// Omnisearch: STOP
|
804 |
+
|
805 |
+
// Widget Visibility: START
|
806 |
+
function jetpack_widget_visibility_more_info() { ?>
|
807 |
+
<h4><?php esc_html_e( 'Widget Visibility', 'jetpack' ); ?></h4>
|
808 |
+
|
809 |
+
<p><?php esc_html_e( 'Control which pages your widgets appear on with Widget Visibility.', 'jetpack' ); ?></p>
|
810 |
+
<p><?php esc_html_e( 'To control visibility, expand the widget and click the Visibility button next to the Save button, and then, choose a set of visibility options.', 'jetpack' ); ?></p>
|
811 |
+
<p><?php esc_html_e( 'For example, if you wanted the Archives widget to only appear on category archives and error pages, choose "Show" from the first dropdown and then add two rules: "Page is 404 Error Page" and "Category is All Category Pages."', 'jetpack' ); ?></p>
|
812 |
+
<p><?php esc_html_e( 'You can also hide widgets based on the current page. For example, if you don\'t want the Archives widget to appear on search results pages, choose "Hide" and "Page is Search results."', 'jetpack' ); ?></p>
|
813 |
+
<?php
|
814 |
+
}
|
815 |
+
|
816 |
+
function jetpack_widget_visibility_more_link() {
|
817 |
+
echo '<a class="button-secondary more-info-link" href="http://jetpack.me/support/widget-visibility/">' . __( 'Learn More', 'jetpack' ) . '</a>';
|
818 |
+
}
|
819 |
+
|
820 |
+
add_action( 'jetpack_module_more_info_widget-visibility', 'jetpack_widget_visibility_more_info' );
|
821 |
+
add_action( 'jetpack_learn_more_button_widget-visibility', 'jetpack_widget_visibility_more_link' );
|
822 |
+
// Widget Visibility: STOP
|
823 |
+
|
824 |
+
|
825 |
+
// WordPress.com Connect: START
|
826 |
+
function jetpack_wpcc_more_info() { ?>
|
827 |
+
<h4><?php esc_html_e( 'WordPress.com Connect' , 'jetpack' ); ?></h4>
|
828 |
+
|
829 |
+
<p><?php esc_html_e( 'With WordPress.com Connect, your users will be able to log into your WordPress admin with the same credentials they use to log into WordPress.com. It\'s safe and secure.' , 'jetpack' ); ?></p>
|
830 |
+
<p><?php esc_html_e( 'Once enabled, a "Connect with WordPress.com" option will be added to your existing log-in form.' , 'jetpack' ); ?></p>
|
831 |
+
|
832 |
+
<?php
|
833 |
+
}
|
834 |
+
|
835 |
+
function jetpack_wpcc_more_link() {
|
836 |
+
echo '<a class="button-secondary more-info-link" href="http://jetpack.me/support/wpcc/">' . __( 'Learn More', 'jetpack' ) . '</a>';
|
837 |
+
}
|
838 |
+
|
839 |
+
add_action( 'jetpack_module_more_info_wpcc', 'jetpack_wpcc_more_info' );
|
840 |
+
add_action( 'jetpack_learn_more_button_wpcc', 'jetpack_wpcc_more_link' );
|
841 |
+
// WordPress.com Connect: STOP
|
modules/notes.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 1
|
6 |
* First Introduced: 1.9
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
if ( !defined( 'JETPACK_NOTES__CACHE_BUSTER' ) ) define( 'JETPACK_NOTES__CACHE_BUSTER', JETPACK__VERSION . '-' . gmdate( 'oW' ) );
|
5 |
* Sort Order: 1
|
6 |
* First Introduced: 1.9
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
if ( !defined( 'JETPACK_NOTES__CACHE_BUSTER' ) ) define( 'JETPACK_NOTES__CACHE_BUSTER', JETPACK__VERSION . '-' . gmdate( 'oW' ) );
|
modules/omnisearch.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* Sort Order: 8
|
7 |
* First Introduced: 2.3
|
8 |
* Requires Connection: No
|
|
|
9 |
*/
|
10 |
|
11 |
// Only do Jetpack Omnisearch if there isn't already a Core WP_Omnisearch Class.
|
6 |
* Sort Order: 8
|
7 |
* First Introduced: 2.3
|
8 |
* Requires Connection: No
|
9 |
+
* Auto Activate: Yes
|
10 |
*/
|
11 |
|
12 |
// Only do Jetpack Omnisearch if there isn't already a Core WP_Omnisearch Class.
|
modules/omnisearch/omnisearch-core.php
CHANGED
@@ -27,6 +27,11 @@ class Jetpack_Omnisearch {
|
|
27 |
require_once( dirname(__FILE__) . '/omnisearch-comments.php' );
|
28 |
new Jetpack_Omnisearch_Comments;
|
29 |
|
|
|
|
|
|
|
|
|
|
|
30 |
if ( current_user_can( 'install_plugins' ) ) {
|
31 |
require_once( dirname(__FILE__) . '/omnisearch-plugins.php' );
|
32 |
new Jetpack_Omnisearch_Plugins;
|
27 |
require_once( dirname(__FILE__) . '/omnisearch-comments.php' );
|
28 |
new Jetpack_Omnisearch_Comments;
|
29 |
|
30 |
+
if ( current_user_can( 'upload_files' ) ) {
|
31 |
+
require_once( dirname(__FILE__) . '/omnisearch-media.php' );
|
32 |
+
new Jetpack_Omnisearch_Media;
|
33 |
+
}
|
34 |
+
|
35 |
if ( current_user_can( 'install_plugins' ) ) {
|
36 |
require_once( dirname(__FILE__) . '/omnisearch-plugins.php' );
|
37 |
new Jetpack_Omnisearch_Plugins;
|
modules/omnisearch/omnisearch-media.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( ! class_exists( 'WP_Media_List_Table' ) )
|
4 |
+
require_once( ABSPATH . 'wp-admin/includes/class-wp-media-list-table.php' );
|
5 |
+
|
6 |
+
class Jetpack_Omnisearch_Media extends WP_Media_List_Table {
|
7 |
+
static $instance;
|
8 |
+
|
9 |
+
function __construct() {
|
10 |
+
self::$instance = $this;
|
11 |
+
add_filter( 'omnisearch_results', array( $this, 'search'), 10, 2 );
|
12 |
+
}
|
13 |
+
|
14 |
+
function search( $results, $search_term ) {
|
15 |
+
$search_url = esc_url( add_query_arg( 's', $search_term, admin_url( 'upload.php' ) ) );
|
16 |
+
$search_link = sprintf( ' <a href="%s" class="add-new-h2">%s</a>', $search_url, esc_html__('Search Media', 'jetpack') );
|
17 |
+
$html = '<h2>' . esc_html__('Media', 'jetpack') . $search_link . '</h2>';
|
18 |
+
parent::__construct();
|
19 |
+
|
20 |
+
ob_start();
|
21 |
+
$this->prepare_items();
|
22 |
+
$columns = $this->get_columns();
|
23 |
+
unset( $columns['cb'] );
|
24 |
+
$this->_column_headers = array( $columns, array(), array() );
|
25 |
+
$this->display();
|
26 |
+
$html .= ob_get_clean();
|
27 |
+
|
28 |
+
$label = __( 'Media', 'jetpack' );
|
29 |
+
$results[ $label ] = $html;
|
30 |
+
return $results;
|
31 |
+
}
|
32 |
+
|
33 |
+
function get_sortable_columns() {
|
34 |
+
return array();
|
35 |
+
}
|
36 |
+
|
37 |
+
function get_bulk_actions() {
|
38 |
+
return array();
|
39 |
+
}
|
40 |
+
|
41 |
+
function pagination( $which ) {}
|
42 |
+
|
43 |
+
function extra_tablenav( $which ) {}
|
44 |
+
}
|
45 |
+
|
46 |
+
|
modules/omnisearch/omnisearch.css
CHANGED
@@ -19,7 +19,7 @@ input.omnisearch {
|
|
19 |
width: 100%;
|
20 |
}
|
21 |
|
22 |
-
.
|
23 |
line-height: 1.35;
|
24 |
}
|
25 |
|
@@ -40,7 +40,7 @@ button.omnisearch-submit {
|
|
40 |
bottom: 0;
|
41 |
}
|
42 |
|
43 |
-
.
|
44 |
padding: 0.3em 0.5em 0.1em;
|
45 |
}
|
46 |
|
@@ -113,10 +113,22 @@ button.omnisearch-submit span {
|
|
113 |
width: 15%;
|
114 |
}
|
115 |
|
116 |
-
.comments .column-author {
|
117 |
width: 20%;
|
118 |
}
|
119 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
.tablenav {
|
121 |
height: 0;
|
122 |
}
|
@@ -124,3 +136,4 @@ button.omnisearch-submit span {
|
|
124 |
.omnisearch-results .tablenav.top {
|
125 |
margin: 5px 0;
|
126 |
}
|
|
19 |
width: 100%;
|
20 |
}
|
21 |
|
22 |
+
.mp6 input.omnisearch {
|
23 |
line-height: 1.35;
|
24 |
}
|
25 |
|
40 |
bottom: 0;
|
41 |
}
|
42 |
|
43 |
+
.mp6 button.omnisearch-submit {
|
44 |
padding: 0.3em 0.5em 0.1em;
|
45 |
}
|
46 |
|
113 |
width: 15%;
|
114 |
}
|
115 |
|
116 |
+
.wp-list-table.comments .column-author {
|
117 |
width: 20%;
|
118 |
}
|
119 |
|
120 |
+
.wp-list-table.media th {
|
121 |
+
white-space: nowrap;
|
122 |
+
}
|
123 |
+
|
124 |
+
.wp-list-table.media .column-parent {
|
125 |
+
width: 15%;
|
126 |
+
}
|
127 |
+
|
128 |
+
.wp-list-table.media .column-comments span.vers {
|
129 |
+
display: block;
|
130 |
+
}
|
131 |
+
|
132 |
.tablenav {
|
133 |
height: 0;
|
134 |
}
|
136 |
.omnisearch-results .tablenav.top {
|
137 |
margin: 5px 0;
|
138 |
}
|
139 |
+
|
modules/omnisearch/rtl/omnisearch-rtl.css
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
/* This file was automatically generated on
|
2 |
|
3 |
|
4 |
h2.page-title small {
|
@@ -21,7 +21,7 @@ input.omnisearch {
|
|
21 |
width: 100%;
|
22 |
}
|
23 |
|
24 |
-
.
|
25 |
line-height: 1.35;
|
26 |
}
|
27 |
|
@@ -42,7 +42,7 @@ button.omnisearch-submit {
|
|
42 |
bottom: 0;
|
43 |
}
|
44 |
|
45 |
-
.
|
46 |
padding: 0.3em 0.5em 0.1em;
|
47 |
}
|
48 |
|
@@ -115,10 +115,22 @@ button.omnisearch-submit span {
|
|
115 |
width: 15%;
|
116 |
}
|
117 |
|
118 |
-
.comments .column-author {
|
119 |
width: 20%;
|
120 |
}
|
121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
.tablenav {
|
123 |
height: 0;
|
124 |
}
|
@@ -126,3 +138,4 @@ button.omnisearch-submit span {
|
|
126 |
.omnisearch-results .tablenav.top {
|
127 |
margin: 5px 0;
|
128 |
}
|
|
1 |
+
/* This file was automatically generated on Aug 15 2013 16:01:51 */
|
2 |
|
3 |
|
4 |
h2.page-title small {
|
21 |
width: 100%;
|
22 |
}
|
23 |
|
24 |
+
.mp6 input.omnisearch {
|
25 |
line-height: 1.35;
|
26 |
}
|
27 |
|
42 |
bottom: 0;
|
43 |
}
|
44 |
|
45 |
+
.mp6 button.omnisearch-submit {
|
46 |
padding: 0.3em 0.5em 0.1em;
|
47 |
}
|
48 |
|
115 |
width: 15%;
|
116 |
}
|
117 |
|
118 |
+
.wp-list-table.comments .column-author {
|
119 |
width: 20%;
|
120 |
}
|
121 |
|
122 |
+
.wp-list-table.media th {
|
123 |
+
white-space: nowrap;
|
124 |
+
}
|
125 |
+
|
126 |
+
.wp-list-table.media .column-parent {
|
127 |
+
width: 15%;
|
128 |
+
}
|
129 |
+
|
130 |
+
.wp-list-table.media .column-comments span.vers {
|
131 |
+
display: block;
|
132 |
+
}
|
133 |
+
|
134 |
.tablenav {
|
135 |
height: 0;
|
136 |
}
|
138 |
.omnisearch-results .tablenav.top {
|
139 |
margin: 5px 0;
|
140 |
}
|
141 |
+
|
modules/photon.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 15
|
6 |
* First Introduced: 2.0
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
Jetpack_Photon::instance();
|
5 |
* Sort Order: 15
|
6 |
* First Introduced: 2.0
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: No
|
9 |
*/
|
10 |
|
11 |
Jetpack_Photon::instance();
|
modules/post-by-email.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* First Introduced: 2.0
|
7 |
* Sort Order: 4
|
8 |
* Requires Connection: Yes
|
|
|
9 |
*/
|
10 |
|
11 |
add_action( 'jetpack_modules_loaded', array( 'Jetpack_Post_By_Email', 'init' ) );
|
6 |
* First Introduced: 2.0
|
7 |
* Sort Order: 4
|
8 |
* Requires Connection: Yes
|
9 |
+
* Auto Activate: Yes
|
10 |
*/
|
11 |
|
12 |
add_action( 'jetpack_modules_loaded', array( 'Jetpack_Post_By_Email', 'init' ) );
|
modules/publicize.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 1
|
6 |
* First Introduced: 2.0
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
class Jetpack_Publicize {
|
5 |
* Sort Order: 1
|
6 |
* First Introduced: 2.0
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
class Jetpack_Publicize {
|
modules/publicize/assets/publicize.js
CHANGED
@@ -70,7 +70,7 @@ jQuery( function( $ ) {
|
|
70 |
|
71 |
$.post( ajaxurl, 'action=publicize_'+ service + '_options_save&connection=' + connection + '&selected_id=' + id + '&token=' + token + '&type=' + type + '&_wpnonce=' + nonce + '&global=' + global_conn + '&global_nonce=' + global_nonce, function( response ) {
|
72 |
tb_remove();
|
73 |
-
|
74 |
} );
|
75 |
|
76 |
} );
|
70 |
|
71 |
$.post( ajaxurl, 'action=publicize_'+ service + '_options_save&connection=' + connection + '&selected_id=' + id + '&token=' + token + '&type=' + type + '&_wpnonce=' + nonce + '&global=' + global_conn + '&global_nonce=' + global_nonce, function( response ) {
|
72 |
tb_remove();
|
73 |
+
top.location = 'options-general.php?page=sharing';
|
74 |
} );
|
75 |
|
76 |
} );
|
modules/publicize/assets/rtl/publicize-rtl.css
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
/* This file was automatically generated on
|
2 |
|
3 |
div#publicize-services-block {
|
4 |
display: inline-block;
|
@@ -23,6 +23,7 @@ span#facebook { background: url( ../facebook-logo.png ) 50% 19px no-repeat; back
|
|
23 |
span#twitter { background: url( ../twitter-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
|
24 |
span#linkedin { background: url( ../linkedin-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
|
25 |
span#tumblr { background: url( ../tumblr-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
|
|
|
26 |
|
27 |
a.publicize-profile-link, a.publicize-profile-link:visited {
|
28 |
text-decoration: none;
|
1 |
+
/* This file was automatically generated on Aug 12 2013 17:03:27 */
|
2 |
|
3 |
div#publicize-services-block {
|
4 |
display: inline-block;
|
23 |
span#twitter { background: url( ../twitter-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
|
24 |
span#linkedin { background: url( ../linkedin-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
|
25 |
span#tumblr { background: url( ../tumblr-logo.png ) 50% 19px no-repeat; background-size: 125px 47px; }
|
26 |
+
span#path { background: url( ../path-logo.png ) 50% 19px no-repeat; background-size: 85px 32px; }
|
27 |
|
28 |
a.publicize-profile-link, a.publicize-profile-link:visited {
|
29 |
text-decoration: none;
|
modules/publicize/ui.php
CHANGED
@@ -99,7 +99,7 @@ class Publicize_UI {
|
|
99 |
$doc_link = "http://en.support.wordpress.com/publicize/";
|
100 |
?>
|
101 |
|
102 |
-
<p>→ <a href="<?php echo esc_url( $doc_link ); ?>"><?php esc_html_e( 'More information on using Publicize.', 'jetpack' ); ?></a></p>
|
103 |
|
104 |
<div id="publicize-services-block">
|
105 |
<?php
|
@@ -108,7 +108,7 @@ class Publicize_UI {
|
|
108 |
?>
|
109 |
<div class="publicize-service-entry">
|
110 |
<div id="<?php echo esc_attr( $name ); ?>" class="publicize-service-left">
|
111 |
-
<a href="<?php echo esc_url( $connect_url ); ?>"><span class="pub-logos" id="<?php echo esc_attr( $name ); ?>"> </span></a>
|
112 |
</div>
|
113 |
|
114 |
<div class="publicize-service-right">
|
@@ -141,7 +141,7 @@ class Publicize_UI {
|
|
141 |
<li>
|
142 |
<?php
|
143 |
if ( !empty( $profile_link ) ) : ?>
|
144 |
-
<a class="publicize-profile-link" href="<?php echo esc_url( $profile_link ); ?>">
|
145 |
<?php echo esc_html( $connection_display ); ?>
|
146 |
</a><?php
|
147 |
else :
|
@@ -153,11 +153,11 @@ class Publicize_UI {
|
|
153 |
<small>(<?php esc_html_e( 'Shared', 'jetpack' ); ?>)</small>
|
154 |
|
155 |
<?php if ( current_user_can( $this->publicize->GLOBAL_CAP ) ) : ?>
|
156 |
-
<a class="pub-disconnect-button" title="<?php esc_html_e( 'Disconnect', 'jetpack' ); ?>" href="<?php echo esc_url( $disconnect_url ); ?>">×</a>
|
157 |
<?php endif; ?>
|
158 |
|
159 |
<?php else : ?>
|
160 |
-
<a class="pub-disconnect-button" title="<?php esc_html_e( 'Disconnect', 'jetpack' ); ?>" href="<?php echo esc_url( $disconnect_url ); ?>">×</a>
|
161 |
<?php endif; ?>
|
162 |
</li>
|
163 |
|
@@ -166,7 +166,7 @@ class Publicize_UI {
|
|
166 |
?>
|
167 |
</ul>
|
168 |
<?php endif; ?>
|
169 |
-
<a id="<?php echo esc_attr( $name ); ?>" class="publicize-add-connection" href="<?php echo esc_url( $connect_url); ?>"><?php echo esc_html( sprintf( __( 'Add new %s connection.', 'jetpack' ), $this->publicize->get_service_label( $name ) ) ); ?></a>
|
170 |
</div>
|
171 |
</div>
|
172 |
<?php endforeach; ?>
|
@@ -464,6 +464,10 @@ jQuery( function($) {
|
|
464 |
$checked = $skip != 1 || $done;
|
465 |
$checked = apply_filters( 'publicize_checkbox_default', $checked, $post->ID, $name, $connection );
|
466 |
|
|
|
|
|
|
|
|
|
467 |
// This post has been handled, so disable everything
|
468 |
if ( $all_done )
|
469 |
$disabled = ' disabled="disabled"';
|
99 |
$doc_link = "http://en.support.wordpress.com/publicize/";
|
100 |
?>
|
101 |
|
102 |
+
<p>→ <a href="<?php echo esc_url( $doc_link ); ?>" target="_blank"><?php esc_html_e( 'More information on using Publicize.', 'jetpack' ); ?></a></p>
|
103 |
|
104 |
<div id="publicize-services-block">
|
105 |
<?php
|
108 |
?>
|
109 |
<div class="publicize-service-entry">
|
110 |
<div id="<?php echo esc_attr( $name ); ?>" class="publicize-service-left">
|
111 |
+
<a href="<?php echo esc_url( $connect_url ); ?>" target="_top"><span class="pub-logos" id="<?php echo esc_attr( $name ); ?>"> </span></a>
|
112 |
</div>
|
113 |
|
114 |
<div class="publicize-service-right">
|
141 |
<li>
|
142 |
<?php
|
143 |
if ( !empty( $profile_link ) ) : ?>
|
144 |
+
<a class="publicize-profile-link" href="<?php echo esc_url( $profile_link ); ?>" target="_top">
|
145 |
<?php echo esc_html( $connection_display ); ?>
|
146 |
</a><?php
|
147 |
else :
|
153 |
<small>(<?php esc_html_e( 'Shared', 'jetpack' ); ?>)</small>
|
154 |
|
155 |
<?php if ( current_user_can( $this->publicize->GLOBAL_CAP ) ) : ?>
|
156 |
+
<a class="pub-disconnect-button" title="<?php esc_html_e( 'Disconnect', 'jetpack' ); ?>" href="<?php echo esc_url( $disconnect_url ); ?>" target="_top">×</a>
|
157 |
<?php endif; ?>
|
158 |
|
159 |
<?php else : ?>
|
160 |
+
<a class="pub-disconnect-button" title="<?php esc_html_e( 'Disconnect', 'jetpack' ); ?>" href="<?php echo esc_url( $disconnect_url ); ?>" target="_top">×</a>
|
161 |
<?php endif; ?>
|
162 |
</li>
|
163 |
|
166 |
?>
|
167 |
</ul>
|
168 |
<?php endif; ?>
|
169 |
+
<a id="<?php echo esc_attr( $name ); ?>" class="publicize-add-connection" href="<?php echo esc_url( $connect_url); ?>" target="_top"><?php echo esc_html( sprintf( __( 'Add new %s connection.', 'jetpack' ), $this->publicize->get_service_label( $name ) ) ); ?></a>
|
170 |
</div>
|
171 |
</div>
|
172 |
<?php endforeach; ?>
|
464 |
$checked = $skip != 1 || $done;
|
465 |
$checked = apply_filters( 'publicize_checkbox_default', $checked, $post->ID, $name, $connection );
|
466 |
|
467 |
+
// Force the checkbox to be checked if the post was DONE, regardless of what the filter does
|
468 |
+
if ( $done )
|
469 |
+
$checked = true;
|
470 |
+
|
471 |
// This post has been handled, so disable everything
|
472 |
if ( $all_done )
|
473 |
$disabled = ' disabled="disabled"';
|
modules/random-redirect.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Random Redirect
|
4 |
+
Plugin URI: http://wordpress.org/extend/plugins/random-redirect/
|
5 |
+
Description: Allows you to create a link to yourblog.example.com/?random which will redirect someone to a random post on your blog, in a StumbleUpon-like fashion.
|
6 |
+
Version: 1.2-wpcom
|
7 |
+
Author: Matt Mullenweg
|
8 |
+
Author URI: http://photomatt.net/
|
9 |
+
*/
|
10 |
+
|
11 |
+
function matt_random_redirect() {
|
12 |
+
// Acceptables URL formats: /[...]/?random=[post type], /?random, /&random, /&random=1
|
13 |
+
if ( ! isset( $_GET['random'] ) && ! in_array( strtolower( $_SERVER['REQUEST_URI'] ), array( '/&random', '/&random=1' ) ) )
|
14 |
+
return;
|
15 |
+
|
16 |
+
// Ignore requests that include more than just the random parameter.
|
17 |
+
if ( ! empty( $_POST ) || ( isset( $_GET['random'] ) && count( $_GET ) > 1 ) )
|
18 |
+
return;
|
19 |
+
|
20 |
+
// Persistent AppEngine abuse. ORDER BY RAND is expensive.
|
21 |
+
if ( strstr( $_SERVER['HTTP_USER_AGENT'], 'AppEngine-Google' ) )
|
22 |
+
wp_die( 'Please <a href="http://en.support.wordpress.com/contact/">contact support</a>' );
|
23 |
+
|
24 |
+
// Use the post type of the current page as the context for the random lookup.
|
25 |
+
$post_type = get_post_type();
|
26 |
+
|
27 |
+
// /?random should always show a random post, even if the home page is a static page.
|
28 |
+
if ( '/' == $_SERVER['DOCUMENT_URI'] )
|
29 |
+
$post_type = 'post';
|
30 |
+
else
|
31 |
+
$post_type = get_post_type();
|
32 |
+
|
33 |
+
if ( ! $post_type )
|
34 |
+
$post_type = 'post';
|
35 |
+
|
36 |
+
global $wpdb;
|
37 |
+
$random_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = %s AND post_password = '' AND post_status = 'publish' ORDER BY RAND() LIMIT 1", $post_type ) );
|
38 |
+
$permalink = get_permalink( $random_id );
|
39 |
+
wp_safe_redirect( $permalink );
|
40 |
+
exit;
|
41 |
+
}
|
42 |
+
|
43 |
+
add_action( 'template_redirect', 'matt_random_redirect' );
|
modules/sharedaddy.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* First Introduced: 1.1
|
7 |
* Major Changes In: 1.2
|
8 |
* Requires Connection: No
|
|
|
9 |
*/
|
10 |
|
11 |
if ( !function_exists( 'sharing_init' ) )
|
6 |
* First Introduced: 1.1
|
7 |
* Major Changes In: 1.2
|
8 |
* Requires Connection: No
|
9 |
+
* Auto Activate: Yes
|
10 |
*/
|
11 |
|
12 |
if ( !function_exists( 'sharing_init' ) )
|
modules/sharedaddy/images/facebook.png
CHANGED
Binary file
|
modules/sharedaddy/images/facebook@2x.png
CHANGED
Binary file
|
modules/sharedaddy/images/icon-facebook-2x.png
CHANGED
Binary file
|
modules/sharedaddy/images/icon-facebook.png
CHANGED
Binary file
|
modules/sharedaddy/sharing-service.php
CHANGED
@@ -620,7 +620,7 @@ function get_base_recaptcha_lang_code() {
|
|
620 |
'tr' => 'tr'
|
621 |
);
|
622 |
|
623 |
-
$blog_lang_code = function_exists( 'get_blog_lang_code' ) ? get_blog_lang_code() : get_bloginfo( 'language' );
|
624 |
if( isset( $base_recaptcha_lang_code_mapping[ $blog_lang_code ] ) )
|
625 |
return $base_recaptcha_lang_code_mapping[ $blog_lang_code ];
|
626 |
|
620 |
'tr' => 'tr'
|
621 |
);
|
622 |
|
623 |
+
$blog_lang_code = function_exists( 'get_blog_lang_code' ) ? get_blog_lang_code() : get_bloginfo( 'language' );
|
624 |
if( isset( $base_recaptcha_lang_code_mapping[ $blog_lang_code ] ) )
|
625 |
return $base_recaptcha_lang_code_mapping[ $blog_lang_code ];
|
626 |
|
modules/sharedaddy/sharing.php
CHANGED
@@ -166,6 +166,7 @@ class Sharing_Admin {
|
|
166 |
|
167 |
<?php if ( current_user_can( 'manage_options' ) ) : ?>
|
168 |
|
|
|
169 |
<h3><?php _e( 'Sharing Buttons', 'jetpack' ) ?></h3>
|
170 |
<p><?php _e( 'Add sharing buttons to your blog and allow your visitors to share posts with their friends.', 'jetpack' ) ?></p>
|
171 |
|
@@ -402,7 +403,7 @@ class Sharing_Admin {
|
|
402 |
<input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'sharing-new_service' );?>" />
|
403 |
</form>
|
404 |
</div>
|
405 |
-
|
406 |
|
407 |
<?php endif; ?>
|
408 |
|
166 |
|
167 |
<?php if ( current_user_can( 'manage_options' ) ) : ?>
|
168 |
|
169 |
+
<div class="share_manage_options">
|
170 |
<h3><?php _e( 'Sharing Buttons', 'jetpack' ) ?></h3>
|
171 |
<p><?php _e( 'Add sharing buttons to your blog and allow your visitors to share posts with their friends.', 'jetpack' ) ?></p>
|
172 |
|
403 |
<input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'sharing-new_service' );?>" />
|
404 |
</form>
|
405 |
</div>
|
406 |
+
</div>
|
407 |
|
408 |
<?php endif; ?>
|
409 |
|
modules/shortcodes.php
CHANGED
@@ -7,6 +7,7 @@
|
|
7 |
* First Introduced: 1.1
|
8 |
* Major Changes In: 1.2
|
9 |
* Requires Connection: No
|
|
|
10 |
*/
|
11 |
|
12 |
/**
|
7 |
* First Introduced: 1.1
|
8 |
* Major Changes In: 1.2
|
9 |
* Requires Connection: No
|
10 |
+
* Auto Activate: Yes
|
11 |
*/
|
12 |
|
13 |
/**
|
modules/shortcodes/css/rtl/slideshow-shortcode-rtl.css
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
/* This file was automatically generated on
|
2 |
|
3 |
.slideshow-window {
|
4 |
background-color: #222;
|
@@ -8,6 +8,7 @@
|
|
8 |
-webkit-border-radius: 11px;
|
9 |
-khtml-border-radius: 11px;
|
10 |
margin-bottom: 20px;
|
|
|
11 |
}
|
12 |
|
13 |
.slideshow-window, .slideshow-window * {
|
1 |
+
/* This file was automatically generated on Aug 22 2013 17:45:44 */
|
2 |
|
3 |
.slideshow-window {
|
4 |
background-color: #222;
|
8 |
-webkit-border-radius: 11px;
|
9 |
-khtml-border-radius: 11px;
|
10 |
margin-bottom: 20px;
|
11 |
+
height: 410px;
|
12 |
}
|
13 |
|
14 |
.slideshow-window, .slideshow-window * {
|
modules/shortcodes/css/slideshow-shortcode.css
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
-webkit-border-radius: 11px;
|
7 |
-khtml-border-radius: 11px;
|
8 |
margin-bottom: 20px;
|
|
|
9 |
}
|
10 |
|
11 |
.slideshow-window, .slideshow-window * {
|
6 |
-webkit-border-radius: 11px;
|
7 |
-khtml-border-radius: 11px;
|
8 |
margin-bottom: 20px;
|
9 |
+
height: 410px;
|
10 |
}
|
11 |
|
12 |
.slideshow-window, .slideshow-window * {
|
modules/shortcodes/css/style.css
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* 1. Fullscreen styles
|
3 |
+
*/
|
4 |
+
html.presentation-wrapper-fullscreen-parent,
|
5 |
+
body.presentation-wrapper-fullscreen-parent {
|
6 |
+
overflow: hidden !important;
|
7 |
+
}
|
8 |
+
|
9 |
+
.presentation-wrapper-fullscreen-parent #wpadminbar {
|
10 |
+
display: none;
|
11 |
+
}
|
12 |
+
|
13 |
+
.presentation-wrapper-fullscreen,
|
14 |
+
.presentation-wrapper-fullscreen-parent {
|
15 |
+
min-width: 100% !important;
|
16 |
+
min-height: 100% !important;
|
17 |
+
position: absolute !important;
|
18 |
+
top: 0 !important;
|
19 |
+
right: 0 !important;
|
20 |
+
bottom: 0 !important;
|
21 |
+
left: 0 !important;
|
22 |
+
margin: 0 !important;
|
23 |
+
padding: 0 !important;
|
24 |
+
z-index: 10000 !important;
|
25 |
+
}
|
26 |
+
|
27 |
+
.presentation-wrapper-fullscreen {
|
28 |
+
background-color: #808080;
|
29 |
+
border: none !important;
|
30 |
+
}
|
31 |
+
|
32 |
+
.presentation-wrapper-fullscreen .nav-arrow-left,
|
33 |
+
.presentation-wrapper-fullscreen .nav-arrow-right {
|
34 |
+
z-index: 20001;
|
35 |
+
}
|
36 |
+
|
37 |
+
.presentation-wrapper-fullscreen .nav-fullscreen-button {
|
38 |
+
z-index: 20002;
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* 2. General presentation styles
|
44 |
+
*/
|
45 |
+
.presentation-wrapper {
|
46 |
+
margin: 20px auto;
|
47 |
+
border: 1px solid #e5e5e5;
|
48 |
+
}
|
49 |
+
|
50 |
+
.presentation {
|
51 |
+
position: relative;
|
52 |
+
margin: 0;
|
53 |
+
overflow: hidden;
|
54 |
+
outline: none;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* jmpress requires that step sizes are explicitly defined
|
59 |
+
* as it inserts sizeless divs before the steps. These
|
60 |
+
* dimensions are set by the js code on initialization
|
61 |
+
*/
|
62 |
+
.presentation,
|
63 |
+
.presentation .step {
|
64 |
+
background-repeat: no-repeat;
|
65 |
+
background-position: center;
|
66 |
+
background-size: 100% 100%;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Opacity transition durations are set by the js code
|
71 |
+
* so they match the presentation animation durations
|
72 |
+
*/
|
73 |
+
.presentation .step.fade:not(.active) {
|
74 |
+
opacity: 0;
|
75 |
+
}
|
76 |
+
|
77 |
+
.presentation .slide-content {
|
78 |
+
padding: 30px;
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
/**
|
83 |
+
* 3. Styles for the navigation arrows
|
84 |
+
*/
|
85 |
+
.presentation .nav-arrow-left,
|
86 |
+
.presentation .nav-arrow-right,
|
87 |
+
.presentation .nav-fullscreen-button {
|
88 |
+
position: absolute;
|
89 |
+
width: 34px;
|
90 |
+
background-repeat: no-repeat;
|
91 |
+
z-index: 2;
|
92 |
+
opacity: 0;
|
93 |
+
|
94 |
+
-webkit-transition : opacity .25s;
|
95 |
+
-moz-transition : opacity .25s;
|
96 |
+
-ms-transition : opacity .25s;
|
97 |
+
-o-transition : opacity .25s;
|
98 |
+
transition : opacity .25s;
|
99 |
+
}
|
100 |
+
|
101 |
+
.presentation .nav-arrow-left,
|
102 |
+
.presentation .nav-arrow-right {
|
103 |
+
height: 100%;
|
104 |
+
background-image: url(../images/slide-nav.png);
|
105 |
+
background-size: 450% 61px;
|
106 |
+
}
|
107 |
+
|
108 |
+
.presentation .nav-arrow-left {
|
109 |
+
left: 0;
|
110 |
+
background-position: 4px 50%;
|
111 |
+
}
|
112 |
+
|
113 |
+
.presentation .nav-arrow-right {
|
114 |
+
right: 0;
|
115 |
+
background-position: -120px 50%;
|
116 |
+
}
|
117 |
+
|
118 |
+
.presentation .nav-fullscreen-button {
|
119 |
+
width: 32px;
|
120 |
+
height: 32px;
|
121 |
+
margin: 4px;
|
122 |
+
bottom: 0;
|
123 |
+
right: 0;
|
124 |
+
z-index: 3;
|
125 |
+
background-image: url(../images/expand.png);
|
126 |
+
background-size: 100% 100%;
|
127 |
+
}
|
128 |
+
|
129 |
+
.presentation:hover .nav-arrow-left,
|
130 |
+
.presentation:hover .nav-arrow-right {
|
131 |
+
opacity: 1;
|
132 |
+
}
|
133 |
+
|
134 |
+
.presentation:hover .nav-fullscreen-button {
|
135 |
+
opacity: 0.8;
|
136 |
+
}
|
137 |
+
|
138 |
+
.presentation-wrapper-fullscreen .nav-fullscreen-button {
|
139 |
+
background-image: url(../images/collapse.png);
|
140 |
+
}
|
modules/shortcodes/images/collapse.png
ADDED
Binary file
|
modules/shortcodes/images/expand.png
ADDED
Binary file
|
modules/shortcodes/images/slide-nav.png
ADDED
Binary file
|
modules/shortcodes/js/jmpress.js
ADDED
@@ -0,0 +1,2721 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* jmpress.js v0.4.5
|
3 |
+
* http://jmpressjs.github.com/jmpress.js
|
4 |
+
*
|
5 |
+
* A jQuery plugin to build a website on the infinite canvas.
|
6 |
+
*
|
7 |
+
* Copyright 2013 Kyle Robinson Young @shama & Tobias Koppers @sokra
|
8 |
+
* Licensed MIT
|
9 |
+
* http://www.opensource.org/licenses/mit-license.php
|
10 |
+
*
|
11 |
+
* Based on the foundation laid by Bartek Szopka @bartaz
|
12 |
+
*//*!
|
13 |
+
* jmpress.js v0.4.5
|
14 |
+
* http://jmpressjs.github.com/jmpress.js
|
15 |
+
*
|
16 |
+
* A jQuery plugin to build a website on the infinite canvas.
|
17 |
+
*
|
18 |
+
* Copyright 2013 Kyle Robinson Young @shama & Tobias Koppers @sokra
|
19 |
+
* Licensed MIT
|
20 |
+
* http://www.opensource.org/licenses/mit-license.php
|
21 |
+
*
|
22 |
+
* Based on the foundation laid by Bartek Szopka @bartaz
|
23 |
+
*//*
|
24 |
+
* core.js
|
25 |
+
* The core of jmpress.js
|
26 |
+
*/
|
27 |
+
(function( $, document, window, undefined ) {
|
28 |
+
|
29 |
+
'use strict';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Set supported prefixes
|
33 |
+
*
|
34 |
+
* @access protected
|
35 |
+
* @return Function to get prefixed property
|
36 |
+
*/
|
37 |
+
var pfx = (function () {
|
38 |
+
var style = document.createElement('dummy').style,
|
39 |
+
prefixes = 'Webkit Moz O ms Khtml'.split(' '),
|
40 |
+
memory = {};
|
41 |
+
return function ( prop ) {
|
42 |
+
if ( typeof memory[ prop ] === "undefined" ) {
|
43 |
+
var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
|
44 |
+
props = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');
|
45 |
+
memory[ prop ] = null;
|
46 |
+
for ( var i in props ) {
|
47 |
+
if ( style[ props[i] ] !== undefined ) {
|
48 |
+
memory[ prop ] = props[i];
|
49 |
+
break;
|
50 |
+
}
|
51 |
+
}
|
52 |
+
}
|
53 |
+
return memory[ prop ];
|
54 |
+
};
|
55 |
+
}());
|
56 |
+
|
57 |
+
/**
|
58 |
+
* map ex. "WebkitTransform" to "-webkit-transform"
|
59 |
+
*/
|
60 |
+
function mapProperty( name ) {
|
61 |
+
if(!name) {
|
62 |
+
return;
|
63 |
+
}
|
64 |
+
var index = 1 + name.substr(1).search(/[A-Z]/);
|
65 |
+
var prefix = name.substr(0, index).toLowerCase();
|
66 |
+
var postfix = name.substr(index).toLowerCase();
|
67 |
+
return "-" + prefix + "-" + postfix;
|
68 |
+
}
|
69 |
+
function addComma( attribute ) {
|
70 |
+
if(!attribute) {
|
71 |
+
return "";
|
72 |
+
}
|
73 |
+
return attribute + ",";
|
74 |
+
}
|
75 |
+
/**
|
76 |
+
* Return an jquery object only if it's not empty
|
77 |
+
*/
|
78 |
+
function ifNotEmpty(el) {
|
79 |
+
if(el.length > 0) {
|
80 |
+
return el;
|
81 |
+
}
|
82 |
+
return null;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Default Settings
|
87 |
+
*/
|
88 |
+
var defaults = {
|
89 |
+
/* CLASSES */
|
90 |
+
stepSelector: '.step'
|
91 |
+
,containerClass: ''
|
92 |
+
,canvasClass: ''
|
93 |
+
,areaClass: ''
|
94 |
+
,notSupportedClass: 'not-supported'
|
95 |
+
|
96 |
+
/* CONFIG */
|
97 |
+
,fullscreen: true
|
98 |
+
|
99 |
+
/* ANIMATION */
|
100 |
+
,animation: {
|
101 |
+
transformOrigin: 'top left'
|
102 |
+
,transitionProperty: addComma(mapProperty(pfx('transform'))) + addComma(mapProperty(pfx('perspective'))) + 'opacity'
|
103 |
+
,transitionDuration: '1s'
|
104 |
+
,transitionDelay: '500ms'
|
105 |
+
,transitionTimingFunction: 'ease-in-out'
|
106 |
+
,transformStyle: "preserve-3d"
|
107 |
+
}
|
108 |
+
,transitionDuration: 1500
|
109 |
+
};
|
110 |
+
var callbacks = {
|
111 |
+
'beforeChange': 1
|
112 |
+
,'beforeInitStep': 1
|
113 |
+
,'initStep': 1
|
114 |
+
,'beforeInit': 1
|
115 |
+
,'afterInit': 1
|
116 |
+
,'beforeDeinit': 1
|
117 |
+
,'afterDeinit': 1
|
118 |
+
,'applyStep': 1
|
119 |
+
,'unapplyStep': 1
|
120 |
+
,'setInactive': 1
|
121 |
+
,'beforeActive': 1
|
122 |
+
,'setActive': 1
|
123 |
+
,'selectInitialStep': 1
|
124 |
+
,'selectPrev': 1
|
125 |
+
,'selectNext': 1
|
126 |
+
,'selectHome': 1
|
127 |
+
,'selectEnd': 1
|
128 |
+
,'idle': 1
|
129 |
+
,'applyTarget': 1
|
130 |
+
};
|
131 |
+
for(var callbackName in callbacks) {
|
132 |
+
defaults[callbackName] = [];
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Initialize jmpress
|
138 |
+
*/
|
139 |
+
function init( args ) {
|
140 |
+
args = $.extend(true, {}, args || {});
|
141 |
+
|
142 |
+
// accept functions and arrays of functions as callbacks
|
143 |
+
var callbackArgs = {};
|
144 |
+
var callbackName = null;
|
145 |
+
for (callbackName in callbacks) {
|
146 |
+
callbackArgs[callbackName] = $.isFunction( args[callbackName] ) ?
|
147 |
+
[ args[callbackName] ] :
|
148 |
+
args[callbackName];
|
149 |
+
args[callbackName] = [];
|
150 |
+
}
|
151 |
+
|
152 |
+
// MERGE SETTINGS
|
153 |
+
var settings = $.extend(true, {}, defaults, args);
|
154 |
+
|
155 |
+
for (callbackName in callbacks) {
|
156 |
+
if (callbackArgs[callbackName]) {
|
157 |
+
Array.prototype.push.apply(settings[callbackName], callbackArgs[callbackName]);
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
/*** MEMBER VARS ***/
|
162 |
+
|
163 |
+
var jmpress = $( this )
|
164 |
+
,container = null
|
165 |
+
,area = null
|
166 |
+
,oldStyle = {
|
167 |
+
container: ""
|
168 |
+
,area: ""
|
169 |
+
}
|
170 |
+
,canvas = null
|
171 |
+
,current = null
|
172 |
+
,active = false
|
173 |
+
,activeSubstep = null
|
174 |
+
,activeDelegated = false;
|
175 |
+
|
176 |
+
|
177 |
+
/*** MEMBER FUNCTIONS ***/
|
178 |
+
// functions have to be called with this
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Init a single step
|
182 |
+
*
|
183 |
+
* @param element the element of the step
|
184 |
+
* @param idx number of step
|
185 |
+
*/
|
186 |
+
function doStepInit( element, idx ) {
|
187 |
+
var data = dataset( element );
|
188 |
+
var step = {
|
189 |
+
oldStyle: $(element).attr("style") || ""
|
190 |
+
};
|
191 |
+
|
192 |
+
var callbackData = {
|
193 |
+
data: data
|
194 |
+
,stepData: step
|
195 |
+
};
|
196 |
+
callCallback.call(this, 'beforeInitStep', $(element), callbackData);
|
197 |
+
step.delegate = data.delegate;
|
198 |
+
callCallback.call(this, 'initStep', $(element), callbackData);
|
199 |
+
|
200 |
+
$(element).data('stepData', step);
|
201 |
+
|
202 |
+
if ( !$(element).attr('id') ) {
|
203 |
+
$(element).attr('id', 'step-' + (idx + 1));
|
204 |
+
}
|
205 |
+
|
206 |
+
callCallback.call(this, 'applyStep', $(element), callbackData);
|
207 |
+
}
|
208 |
+
/**
|
209 |
+
* Deinit a single step
|
210 |
+
*
|
211 |
+
* @param element the element of the step
|
212 |
+
*/
|
213 |
+
function doStepDeinit( element ) {
|
214 |
+
var stepData = $(element).data('stepData');
|
215 |
+
|
216 |
+
$(element).attr("style", stepData.oldStyle);
|
217 |
+
|
218 |
+
callCallback.call(this, 'unapplyStep', $(element), {
|
219 |
+
stepData: stepData
|
220 |
+
});
|
221 |
+
}
|
222 |
+
/**
|
223 |
+
* Reapplies stepData to the element
|
224 |
+
*
|
225 |
+
* @param element
|
226 |
+
*/
|
227 |
+
function doStepReapply( element ) {
|
228 |
+
callCallback.call(this, 'unapplyStep', $(element), {
|
229 |
+
stepData: element.data("stepData")
|
230 |
+
});
|
231 |
+
|
232 |
+
callCallback.call(this, 'applyStep', $(element), {
|
233 |
+
stepData: element.data("stepData")
|
234 |
+
});
|
235 |
+
}
|
236 |
+
/**
|
237 |
+
* Completly deinit jmpress
|
238 |
+
*
|
239 |
+
*/
|
240 |
+
function deinit() {
|
241 |
+
if ( active ) {
|
242 |
+
callCallback.call(this, 'setInactive', active, {
|
243 |
+
stepData: $(active).data('stepData')
|
244 |
+
,reason: "deinit"
|
245 |
+
} );
|
246 |
+
}
|
247 |
+
if (current.jmpressClass) {
|
248 |
+
$(jmpress).removeClass(current.jmpressClass);
|
249 |
+
}
|
250 |
+
|
251 |
+
callCallback.call(this, 'beforeDeinit', $(this), {});
|
252 |
+
|
253 |
+
$(settings.stepSelector, jmpress).each(function( idx ) {
|
254 |
+
doStepDeinit.call(jmpress, this );
|
255 |
+
});
|
256 |
+
|
257 |
+
container.attr("style", oldStyle.container);
|
258 |
+
if(settings.fullscreen) {
|
259 |
+
$("html").attr("style", "");
|
260 |
+
}
|
261 |
+
area.attr("style", oldStyle.area);
|
262 |
+
$(canvas).children().each(function() {
|
263 |
+
jmpress.append( $( this ) );
|
264 |
+
});
|
265 |
+
if( settings.fullscreen ) {
|
266 |
+
canvas.remove();
|
267 |
+
} else {
|
268 |
+
canvas.remove();
|
269 |
+
area.remove();
|
270 |
+
}
|
271 |
+
|
272 |
+
callCallback.call(this, 'afterDeinit', $(this), {});
|
273 |
+
|
274 |
+
$(jmpress).data("jmpressmethods", false);
|
275 |
+
}
|
276 |
+
/**
|
277 |
+
* Call a callback
|
278 |
+
*
|
279 |
+
* @param callbackName String callback which should be called
|
280 |
+
* @param element some arguments to the callback
|
281 |
+
* @param eventData
|
282 |
+
*/
|
283 |
+
function callCallback( callbackName, element, eventData ) {
|
284 |
+
eventData.settings = settings;
|
285 |
+
eventData.current = current;
|
286 |
+
eventData.container = container;
|
287 |
+
eventData.parents = element ? getStepParents(element) : null;
|
288 |
+
eventData.current = current;
|
289 |
+
eventData.jmpress = this;
|
290 |
+
var result = {};
|
291 |
+
$.each( settings[callbackName], function(idx, callback) {
|
292 |
+
result.value = callback.call( jmpress, element, eventData ) || result.value;
|
293 |
+
});
|
294 |
+
return result.value;
|
295 |
+
}
|
296 |
+
/**
|
297 |
+
*
|
298 |
+
*/
|
299 |
+
function getStepParents( el ) {
|
300 |
+
return $(el).parentsUntil(jmpress).not(jmpress).filter(settings.stepSelector);
|
301 |
+
}
|
302 |
+
/**
|
303 |
+
* Reselect the active step
|
304 |
+
*
|
305 |
+
* @param String type reason of reselecting step
|
306 |
+
*/
|
307 |
+
function reselect( type ) {
|
308 |
+
return select( { step: active, substep: activeSubstep }, type);
|
309 |
+
}
|
310 |
+
/**
|
311 |
+
* Select a given step
|
312 |
+
*
|
313 |
+
* @param el element to select
|
314 |
+
* @param type reason of changing step
|
315 |
+
* @return Object element selected
|
316 |
+
*/
|
317 |
+
function select( el, type ) {
|
318 |
+
var substep;
|
319 |
+
if ( $.isPlainObject( el ) ) {
|
320 |
+
substep = el.substep;
|
321 |
+
el = el.step;
|
322 |
+
}
|
323 |
+
if ( typeof el === 'string') {
|
324 |
+
el = jmpress.find( el ).first();
|
325 |
+
}
|
326 |
+
if ( !el || !$(el).data('stepData') ) {
|
327 |
+
return false;
|
328 |
+
}
|
329 |
+
|
330 |
+
scrollFix.call(this);
|
331 |
+
|
332 |
+
var step = $(el).data('stepData');
|
333 |
+
|
334 |
+
var cancelSelect = false;
|
335 |
+
callCallback.call(this, "beforeChange", el, {
|
336 |
+
stepData: step
|
337 |
+
,reason: type
|
338 |
+
,cancel: function() {
|
339 |
+
cancelSelect = true;
|
340 |
+
}
|
341 |
+
});
|
342 |
+
if (cancelSelect) {
|
343 |
+
return undefined;
|
344 |
+
}
|
345 |
+
|
346 |
+
var target = {};
|
347 |
+
|
348 |
+
var delegated = el;
|
349 |
+
if($(el).data("stepData").delegate) {
|
350 |
+
delegated = ifNotEmpty($(el).parentsUntil(jmpress).filter(settings.stepSelector).filter(step.delegate)) ||
|
351 |
+
ifNotEmpty($(el).near(step.delegate)) ||
|
352 |
+
ifNotEmpty($(el).near(step.delegate, true)) ||
|
353 |
+
ifNotEmpty($(step.delegate, jmpress));
|
354 |
+
if(delegated) {
|
355 |
+
step = delegated.data("stepData");
|
356 |
+
} else {
|
357 |
+
// Do not delegate if expression not found
|
358 |
+
delegated = el;
|
359 |
+
}
|
360 |
+
}
|
361 |
+
if ( activeDelegated ) {
|
362 |
+
callCallback.call(this, 'setInactive', activeDelegated, {
|
363 |
+
stepData: $(activeDelegated).data('stepData')
|
364 |
+
,delegatedFrom: active
|
365 |
+
,reason: type
|
366 |
+
,target: target
|
367 |
+
,nextStep: delegated
|
368 |
+
,nextSubstep: substep
|
369 |
+
,nextStepData: step
|
370 |
+
} );
|
371 |
+
}
|
372 |
+
var callbackData = {
|
373 |
+
stepData: step
|
374 |
+
,delegatedFrom: el
|
375 |
+
,reason: type
|
376 |
+
,target: target
|
377 |
+
,substep: substep
|
378 |
+
,prevStep: activeDelegated
|
379 |
+
,prevSubstep: activeSubstep
|
380 |
+
,prevStepData: activeDelegated && $(activeDelegated).data('stepData')
|
381 |
+
};
|
382 |
+
callCallback.call(this, 'beforeActive', delegated, callbackData);
|
383 |
+
callCallback.call(this, 'setActive', delegated, callbackData);
|
384 |
+
|
385 |
+
// Set on step class on root element
|
386 |
+
if (current.jmpressClass) {
|
387 |
+
$(jmpress).removeClass(current.jmpressClass);
|
388 |
+
}
|
389 |
+
$(jmpress).addClass(current.jmpressClass = 'step-' + $(delegated).attr('id') );
|
390 |
+
if (current.jmpressDelegatedClass) {
|
391 |
+
$(jmpress).removeClass(current.jmpressDelegatedClass);
|
392 |
+
}
|
393 |
+
$(jmpress).addClass(current.jmpressDelegatedClass = 'delegating-step-' + $(el).attr('id') );
|
394 |
+
|
395 |
+
callCallback.call(this, "applyTarget", delegated, $.extend({
|
396 |
+
canvas: canvas
|
397 |
+
,area: area
|
398 |
+
,beforeActive: activeDelegated
|
399 |
+
}, callbackData));
|
400 |
+
|
401 |
+
active = el;
|
402 |
+
activeSubstep = callbackData.substep;
|
403 |
+
activeDelegated = delegated;
|
404 |
+
|
405 |
+
if(current.idleTimeout) {
|
406 |
+
clearTimeout(current.idleTimeout);
|
407 |
+
}
|
408 |
+
current.idleTimeout = setTimeout(function() {
|
409 |
+
callCallback.call(this, 'idle', delegated, callbackData);
|
410 |
+
}, Math.max(1, settings.transitionDuration - 100));
|
411 |
+
|
412 |
+
return delegated;
|
413 |
+
}
|
414 |
+
/**
|
415 |
+
* This should fix ANY kind of buggy scrolling
|
416 |
+
*/
|
417 |
+
function scrollFix() {
|
418 |
+
(function fix() {
|
419 |
+
if ($(container)[0].tagName === "BODY") {
|
420 |
+
try {
|
421 |
+
window.scrollTo(0, 0);
|
422 |
+
} catch(e) {}
|
423 |
+
}
|
424 |
+
$(container).scrollTop(0);
|
425 |
+
$(container).scrollLeft(0);
|
426 |
+
function check() {
|
427 |
+
if ($(container).scrollTop() !== 0 ||
|
428 |
+
$(container).scrollLeft() !== 0) {
|
429 |
+
fix();
|
430 |
+
}
|
431 |
+
}
|
432 |
+
setTimeout(check, 1);
|
433 |
+
setTimeout(check, 10);
|
434 |
+
setTimeout(check, 100);
|
435 |
+
setTimeout(check, 200);
|
436 |
+
setTimeout(check, 400);
|
437 |
+
}());
|
438 |
+
}
|
439 |
+
/**
|
440 |
+
* Alias for select
|
441 |
+
*/
|
442 |
+
function goTo( el ) {
|
443 |
+
return select.call(this, el, "jump" );
|
444 |
+
}
|
445 |
+
/**
|
446 |
+
* Goto Next Slide
|
447 |
+
*
|
448 |
+
* @return Object newly active slide
|
449 |
+
*/
|
450 |
+
function next() {
|
451 |
+
return select.call(this, callCallback.call(this, 'selectNext', active, {
|
452 |
+
stepData: $(active).data('stepData')
|
453 |
+
,substep: activeSubstep
|
454 |
+
}), "next" );
|
455 |
+
}
|
456 |
+
/**
|
457 |
+
* Goto Previous Slide
|
458 |
+
*
|
459 |
+
* @return Object newly active slide
|
460 |
+
*/
|
461 |
+
function prev() {
|
462 |
+
return select.call(this, callCallback.call(this, 'selectPrev', active, {
|
463 |
+
stepData: $(active).data('stepData')
|
464 |
+
,substep: activeSubstep
|
465 |
+
}), "prev" );
|
466 |
+
}
|
467 |
+
/**
|
468 |
+
* Goto First Slide
|
469 |
+
*
|
470 |
+
* @return Object newly active slide
|
471 |
+
*/
|
472 |
+
function home() {
|
473 |
+
return select.call(this, callCallback.call(this, 'selectHome', active, {
|
474 |
+
stepData: $(active).data('stepData')
|
475 |
+
}), "home" );
|
476 |
+
}
|
477 |
+
/**
|
478 |
+
* Goto Last Slide
|
479 |
+
*
|
480 |
+
* @return Object newly active slide
|
481 |
+
*/
|
482 |
+
function end() {
|
483 |
+
return select.call(this, callCallback.call(this, 'selectEnd', active, {
|
484 |
+
stepData: $(active).data('stepData')
|
485 |
+
}), "end" );
|
486 |
+
}
|
487 |
+
/**
|
488 |
+
* Manipulate the canvas
|
489 |
+
*
|
490 |
+
* @param props
|
491 |
+
* @return Object
|
492 |
+
*/
|
493 |
+
function canvasMod( props ) {
|
494 |
+
css(canvas, props || {});
|
495 |
+
return $(canvas);
|
496 |
+
}
|
497 |
+
/**
|
498 |
+
* Return current step
|
499 |
+
*
|
500 |
+
* @return Object
|
501 |
+
*/
|
502 |
+
function getActive() {
|
503 |
+
return activeDelegated && $(activeDelegated);
|
504 |
+
}
|
505 |
+
/**
|
506 |
+
* fire a callback
|
507 |
+
*
|
508 |
+
* @param callbackName
|
509 |
+
* @param element
|
510 |
+
* @param eventData
|
511 |
+
* @return void
|
512 |
+
*/
|
513 |
+
function fire( callbackName, element, eventData ) {
|
514 |
+
if( !callbacks[callbackName] ) {
|
515 |
+
$.error( "callback " + callbackName + " is not registered." );
|
516 |
+
} else {
|
517 |
+
return callCallback.call(this, callbackName, element, eventData);
|
518 |
+
}
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* PUBLIC METHODS LIST
|
523 |
+
*/
|
524 |
+
jmpress.data("jmpressmethods", {
|
525 |
+
select: select
|
526 |
+
,reselect: reselect
|
527 |
+
,scrollFix: scrollFix
|
528 |
+
,goTo: goTo
|
529 |
+
,next: next
|
530 |
+
,prev: prev
|
531 |
+
,home: home
|
532 |
+
,end: end
|
533 |
+
,canvas: canvasMod
|
534 |
+
,container: function() { return container; }
|
535 |
+
,settings: function() { return settings; }
|
536 |
+
,active: getActive
|
537 |
+
,current: function() { return current; }
|
538 |
+
,fire: fire
|
539 |
+
,init: function(step) {
|
540 |
+
doStepInit.call(this, $(step), current.nextIdNumber++);
|
541 |
+
}
|
542 |
+
,deinit: function(step) {
|
543 |
+
if(step) {
|
544 |
+
doStepDeinit.call(this, $(step));
|
545 |
+
} else {
|
546 |
+
deinit.call(this);
|
547 |
+
}
|
548 |
+
}
|
549 |
+
,reapply: doStepReapply
|
550 |
+
});
|
551 |
+
|
552 |
+
/**
|
553 |
+
* Check for support
|
554 |
+
* This will be removed in near future, when support is coming
|
555 |
+
*
|
556 |
+
* @access protected
|
557 |
+
* @return void
|
558 |
+
*/
|
559 |
+
function checkSupport() {
|
560 |
+
var ua = navigator.userAgent.toLowerCase();
|
561 |
+
return (ua.search(/(iphone)|(ipod)|(android)/) === -1) || (ua.search(/(chrome)/) !== -1);
|
562 |
+
}
|
563 |
+
|
564 |
+
// BEGIN INIT
|
565 |
+
|
566 |
+
// CHECK FOR SUPPORT
|
567 |
+
if (checkSupport() === false) {
|
568 |
+
if (settings.notSupportedClass) {
|
569 |
+
jmpress.addClass(settings.notSupportedClass);
|
570 |
+
}
|
571 |
+
return;
|
572 |
+
} else {
|
573 |
+
if (settings.notSupportedClass) {
|
574 |
+
jmpress.removeClass(settings.notSupportedClass);
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
// grabbing all steps
|
579 |
+
var steps = $(settings.stepSelector, jmpress);
|
580 |
+
|
581 |
+
// GERNERAL INIT OF FRAME
|
582 |
+
container = jmpress;
|
583 |
+
area = $('<div />');
|
584 |
+
canvas = $('<div />');
|
585 |
+
$(jmpress).children().filter(steps).each(function() {
|
586 |
+
canvas.append( $( this ) );
|
587 |
+
});
|
588 |
+
if(settings.fullscreen) {
|
589 |
+
container = $('body');
|
590 |
+
$("html").css({
|
591 |
+
overflow: 'hidden'
|
592 |
+
});
|
593 |
+
area = jmpress;
|
594 |
+
}
|
595 |
+
oldStyle.area = area.attr("style") || "";
|
596 |
+
oldStyle.container = container.attr("style") || "";
|
597 |
+
if(settings.fullscreen) {
|
598 |
+
container.css({
|
599 |
+
height: '100%'
|
600 |
+
});
|
601 |
+
jmpress.append( canvas );
|
602 |
+
} else {
|
603 |
+
container.css({
|
604 |
+
position: "relative"
|
605 |
+
});
|
606 |
+
area.append( canvas );
|
607 |
+
jmpress.append( area );
|
608 |
+
}
|
609 |
+
|
610 |
+
$(container).addClass(settings.containerClass);
|
611 |
+
$(area).addClass(settings.areaClass);
|
612 |
+
$(canvas).addClass(settings.canvasClass);
|
613 |
+
|
614 |
+
document.documentElement.style.height = "100%";
|
615 |
+
container.css({
|
616 |
+
overflow: 'hidden'
|
617 |
+
});
|
618 |
+
|
619 |
+
var props = {
|
620 |
+
position: "absolute"
|
621 |
+
,transitionDuration: '0s'
|
622 |
+
};
|
623 |
+
props = $.extend({}, settings.animation, props);
|
624 |
+
css(area, props);
|
625 |
+
css(area, {
|
626 |
+
top: '50%'
|
627 |
+
,left: '50%'
|
628 |
+
,perspective: '1000px'
|
629 |
+
});
|
630 |
+
css(canvas, props);
|
631 |
+
|
632 |
+
current = {};
|
633 |
+
|
634 |
+
callCallback.call(this, 'beforeInit', null, {});
|
635 |
+
|
636 |
+
// INITIALIZE EACH STEP
|
637 |
+
steps.each(function( idx ) {
|
638 |
+
doStepInit.call(jmpress, this, idx );
|
639 |
+
});
|
640 |
+
current.nextIdNumber = steps.length;
|
641 |
+
|
642 |
+
callCallback.call(this, 'afterInit', null, {});
|
643 |
+
|
644 |
+
// START
|
645 |
+
select.call(this, callCallback.call(this, 'selectInitialStep', "init", {}) );
|
646 |
+
|
647 |
+
if (settings.initClass) {
|
648 |
+
$(steps).removeClass(settings.initClass);
|
649 |
+
}
|
650 |
+
}
|
651 |
+
/**
|
652 |
+
* Return default settings
|
653 |
+
*
|
654 |
+
* @return Object
|
655 |
+
*/
|
656 |
+
function getDefaults() {
|
657 |
+
return defaults;
|
658 |
+
}
|
659 |
+
/**
|
660 |
+
* Register a callback or a jmpress function
|
661 |
+
*
|
662 |
+
* @access public
|
663 |
+
* @param name String the name of the callback or function
|
664 |
+
* @param func Function? the function to be added
|
665 |
+
*/
|
666 |
+
function register(name, func) {
|
667 |
+
if( $.isFunction(func) ) {
|
668 |
+
if( methods[name] ) {
|
669 |
+
$.error( "function " + name + " is already registered." );
|
670 |
+
} else {
|
671 |
+
methods[name] = func;
|
672 |
+
}
|
673 |
+
} else {
|
674 |
+
if( callbacks[name] ) {
|
675 |
+
$.error( "callback " + name + " is already registered." );
|
676 |
+
} else {
|
677 |
+
callbacks[name] = 1;
|
678 |
+
defaults[name] = [];
|
679 |
+
}
|
680 |
+
}
|
681 |
+
}
|
682 |
+
/**
|
683 |
+
* Set CSS on element w/ prefixes
|
684 |
+
*
|
685 |
+
* @return Object element which properties were set
|
686 |
+
*
|
687 |
+
* TODO: Consider bypassing pfx and blindly set as jQuery
|
688 |
+
* already checks for support
|
689 |
+
*/
|
690 |
+
function css( el, props ) {
|
691 |
+
var key, pkey, cssObj = {};
|
692 |
+
for ( key in props ) {
|
693 |
+
if ( props.hasOwnProperty(key) ) {
|
694 |
+
pkey = pfx(key);
|
695 |
+
if ( pkey !== null ) {
|
696 |
+
cssObj[pkey] = props[key];
|
697 |
+
}
|
698 |
+
}
|
699 |
+
}
|
700 |
+
$(el).css(cssObj);
|
701 |
+
return el;
|
702 |
+
}
|
703 |
+
/**
|
704 |
+
* Return dataset for element
|
705 |
+
*
|
706 |
+
* @param el element
|
707 |
+
* @return Object
|
708 |
+
*/
|
709 |
+
function dataset( el ) {
|
710 |
+
if ( $(el)[0].dataset ) {
|
711 |
+
return $.extend({}, $(el)[0].dataset);
|
712 |
+
}
|
713 |
+
function toCamelcase( str ) {
|
714 |
+
str = str.split( '-' );
|
715 |
+
for( var i = 1; i < str.length; i++ ) {
|
716 |
+
str[i] = str[i].substr(0, 1).toUpperCase() + str[i].substr(1);
|
717 |
+
}
|
718 |
+
return str.join( '' );
|
719 |
+
}
|
720 |
+
var returnDataset = {};
|
721 |
+
var attrs = $(el)[0].attributes;
|
722 |
+
$.each(attrs, function ( idx, attr ) {
|
723 |
+
if ( attr.nodeName.substr(0, 5) === "data-" ) {
|
724 |
+
returnDataset[ toCamelcase(attr.nodeName.substr(5)) ] = attr.nodeValue;
|
725 |
+
}
|
726 |
+
});
|
727 |
+
return returnDataset;
|
728 |
+
}
|
729 |
+
/**
|
730 |
+
* Returns true, if jmpress is initialized
|
731 |
+
*
|
732 |
+
* @return bool
|
733 |
+
*/
|
734 |
+
function initialized() {
|
735 |
+
return !!$(this).data("jmpressmethods");
|
736 |
+
}
|
737 |
+
|
738 |
+
|
739 |
+
/**
|
740 |
+
* PUBLIC STATIC METHODS LIST
|
741 |
+
*/
|
742 |
+
var methods = {
|
743 |
+
init: init
|
744 |
+
,initialized: initialized
|
745 |
+
,deinit: function() {}
|
746 |
+
,css: css
|
747 |
+
,pfx: pfx
|
748 |
+
,defaults: getDefaults
|
749 |
+
,register: register
|
750 |
+
,dataset: dataset
|
751 |
+
};
|
752 |
+
|
753 |
+
/**
|
754 |
+
* $.jmpress()
|
755 |
+
*/
|
756 |
+
$.fn.jmpress = function( method ) {
|
757 |
+
function f() {
|
758 |
+
var jmpressmethods = $(this).data("jmpressmethods");
|
759 |
+
if ( jmpressmethods && jmpressmethods[method] ) {
|
760 |
+
return jmpressmethods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
|
761 |
+
} else if ( methods[method] ) {
|
762 |
+
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
|
763 |
+
} else if ( callbacks[method] && jmpressmethods ) {
|
764 |
+
var settings = jmpressmethods.settings();
|
765 |
+
var func = Array.prototype.slice.call( arguments, 1 )[0];
|
766 |
+
if ($.isFunction( func )) {
|
767 |
+
settings[method] = settings[method] || [];
|
768 |
+
settings[method].push(func);
|
769 |
+
}
|
770 |
+
} else if ( typeof method === 'object' || ! method ) {
|
771 |
+
return init.apply( this, arguments );
|
772 |
+
} else {
|
773 |
+
$.error( 'Method ' + method + ' does not exist on jQuery.jmpress' );
|
774 |
+
}
|
775 |
+
// to allow chaining
|
776 |
+
return this;
|
777 |
+
}
|
778 |
+
var args = arguments;
|
779 |
+
var result;
|
780 |
+
$(this).each(function(idx, element) {
|
781 |
+
result = f.apply(element, args);
|
782 |
+
});
|
783 |
+
return result;
|
784 |
+
};
|
785 |
+
$.extend({
|
786 |
+
jmpress: function( method ) {
|
787 |
+
if ( methods[method] ) {
|
788 |
+
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
|
789 |
+
} else if ( callbacks[method] ) {
|
790 |
+
// plugin interface
|
791 |
+
var func = Array.prototype.slice.call( arguments, 1 )[0];
|
792 |
+
if ($.isFunction( func )) {
|
793 |
+
defaults[method].push(func);
|
794 |
+
} else {
|
795 |
+
$.error( 'Second parameter should be a function: $.jmpress( callbackName, callbackFunction )' );
|
796 |
+
}
|
797 |
+
} else {
|
798 |
+
$.error( 'Method ' + method + ' does not exist on jQuery.jmpress' );
|
799 |
+
}
|
800 |
+
}
|
801 |
+
});
|
802 |
+
|
803 |
+
}(jQuery, document, window));
|
804 |
+
|
805 |
+
/*
|
806 |
+
* near.js
|
807 |
+
* Find steps near each other
|
808 |
+
*/
|
809 |
+
(function( $, document, window, undefined ) {
|
810 |
+
|
811 |
+
'use strict';
|
812 |
+
|
813 |
+
// add near( selector, backwards = false) to jquery
|
814 |
+
|
815 |
+
|
816 |
+
function checkAndGo( elements, func, selector, backwards ) {
|
817 |
+
var next;
|
818 |
+
elements.each(function(idx, element) {
|
819 |
+
if(backwards) {
|
820 |
+
next = func(element, selector, backwards);
|
821 |
+
if (next) {
|
822 |
+
return false;
|
823 |
+
}
|
824 |
+
}
|
825 |
+
if( $(element).is(selector) ) {
|
826 |
+
next = element;
|
827 |
+
return false;
|
828 |
+
}
|
829 |
+
if(!backwards) {
|
830 |
+
next = func(element, selector, backwards);
|
831 |
+
if (next) {
|
832 |
+
return false;
|
833 |
+
}
|
834 |
+
}
|
835 |
+
});
|
836 |
+
return next;
|
837 |
+
}
|
838 |
+
function findNextInChildren(item, selector, backwards) {
|
839 |
+
var children = $(item).children();
|
840 |
+
if(backwards) {
|
841 |
+
children = $(children.get().reverse());
|
842 |
+
}
|
843 |
+
return checkAndGo( children, findNextInChildren, selector, backwards );
|
844 |
+
}
|
845 |
+
function findNextInSiblings(item, selector, backwards) {
|
846 |
+
return checkAndGo(
|
847 |
+
$(item)[backwards ? "prevAll" : "nextAll"](),
|
848 |
+
findNextInChildren, selector, backwards );
|
849 |
+
}
|
850 |
+
function findNextInParents(item, selector, backwards) {
|
851 |
+
var next;
|
852 |
+
var parents = $(item).parents();
|
853 |
+
parents = $(parents.get());
|
854 |
+
$.each(parents.get(), function(idx, element) {
|
855 |
+
if( backwards && $(element).is(selector) ) {
|
856 |
+
next = element;
|
857 |
+
return false;
|
858 |
+
}
|
859 |
+
next = findNextInSiblings(element, selector, backwards);
|
860 |
+
if(next) {
|
861 |
+
return false;
|
862 |
+
}
|
863 |
+
});
|
864 |
+
return next;
|
865 |
+
}
|
866 |
+
|
867 |
+
$.fn.near = function( selector, backwards ) {
|
868 |
+
var array = [];
|
869 |
+
$(this).each(function(idx, element) {
|
870 |
+
var near = (backwards ?
|
871 |
+
false :
|
872 |
+
findNextInChildren( element, selector, backwards )) ||
|
873 |
+
findNextInSiblings( element, selector, backwards ) ||
|
874 |
+
findNextInParents( element, selector, backwards );
|
875 |
+
if( near ) {
|
876 |
+
array.push(near);
|
877 |
+
}
|
878 |
+
});
|
879 |
+
return $(array);
|
880 |
+
};
|
881 |
+
}(jQuery, document, window));
|
882 |
+
/*
|
883 |
+
* transform.js
|
884 |
+
* The engine that powers the transforms or falls back to other methods
|
885 |
+
*/
|
886 |
+
(function( $, document, window, undefined ) {
|
887 |
+
|
888 |
+
'use strict';
|
889 |
+
|
890 |
+
/* FUNCTIONS */
|
891 |
+
function toCssNumber(number) {
|
892 |
+
return (Math.round(10000*number)/10000)+"";
|
893 |
+
}
|
894 |
+
|
895 |
+
/**
|
896 |
+
* 3D and 2D engines
|
897 |
+
*/
|
898 |
+
var engines = {
|
899 |
+
3: {
|
900 |
+
transform: function( el, data ) {
|
901 |
+
var transform = 'translate(-50%,-50%)';
|
902 |
+
$.each(data, function(idx, item) {
|
903 |
+
var coord = ["X", "Y", "Z"];
|
904 |
+
var i;
|
905 |
+
if(item[0] === "translate") { // ["translate", x, y, z]
|
906 |
+
transform += " translate3d(" + toCssNumber(item[1] || 0) + "px," + toCssNumber(item[2] || 0) + "px," + toCssNumber(item[3] || 0) + "px)";
|
907 |
+
} else if(item[0] === "rotate") {
|
908 |
+
var order = item[4] ? [1, 2, 3] : [3, 2, 1];
|
909 |
+
for(i = 0; i < 3; i++) {
|
910 |
+
transform += " rotate" + coord[order[i]-1] + "(" + toCssNumber(item[order[i]] || 0) + "deg)";
|
911 |
+
}
|
912 |
+
} else if(item[0] === "scale") {
|
913 |
+
for(i = 0; i < 3; i++) {
|
914 |
+
transform += " scale" + coord[i] + "(" + toCssNumber(item[i+1] || 1) + ")";
|
915 |
+
}
|
916 |
+
}
|
917 |
+
});
|
918 |
+
$.jmpress("css", el, $.extend({}, { transform: transform }));
|
919 |
+
}
|
920 |
+
}
|
921 |
+
,2: {
|
922 |
+
transform: function( el, data ) {
|
923 |
+
var transform = 'translate(-50%,-50%)';
|
924 |
+
$.each(data, function(idx, item) {
|
925 |
+
var coord = ["X", "Y"];
|
926 |
+
if(item[0] === "translate") { // ["translate", x, y, z]
|
927 |
+
transform += " translate(" + toCssNumber(item[1] || 0) + "px," + toCssNumber(item[2] || 0) + "px)";
|
928 |
+
} else if(item[0] === "rotate") {
|
929 |
+
transform += " rotate(" + toCssNumber(item[3] || 0) + "deg)";
|
930 |
+
} else if(item[0] === "scale") {
|
931 |
+
for(var i = 0; i < 2; i++) {
|
932 |
+
transform += " scale" + coord[i] + "(" + toCssNumber(item[i+1] || 1) + ")";
|
933 |
+
}
|
934 |
+
}
|
935 |
+
});
|
936 |
+
$.jmpress("css", el, $.extend({}, { transform: transform }));
|
937 |
+
}
|
938 |
+
}
|
939 |
+
,1: {
|
940 |
+
// CHECK IF SUPPORT IS REALLY NEEDED?
|
941 |
+
// this not even work without scaling...
|
942 |
+
// it may better to display the normal view
|
943 |
+
transform: function( el, data ) {
|
944 |
+
var anitarget = { top: 0, left: 0 };
|
945 |
+
$.each(data, function(idx, item) {
|
946 |
+
var coord = ["X", "Y"];
|
947 |
+
if(item[0] === "translate") { // ["translate", x, y, z]
|
948 |
+
anitarget.left = Math.round(item[1] || 0) + "px";
|
949 |
+
anitarget.top = Math.round(item[2] || 0) + "px";
|
950 |
+
}
|
951 |
+
});
|
952 |
+
el.animate(anitarget, 1000); // TODO: Use animation duration
|
953 |
+
}
|
954 |
+
}
|
955 |
+
};
|
956 |
+
|
957 |
+
/**
|
958 |
+
* Engine to power cross-browser translate, scale and rotate.
|
959 |
+
*/
|
960 |
+
var engine = (function() {
|
961 |
+
if ($.jmpress("pfx", "perspective")) {
|
962 |
+
return engines[3];
|
963 |
+
} else if ($.jmpress("pfx", "transform")) {
|
964 |
+
return engines[2];
|
965 |
+
} else {
|
966 |
+
// CHECK IF SUPPORT IS REALLY NEEDED?
|
967 |
+
return engines[1];
|
968 |
+
}
|
969 |
+
}());
|
970 |
+
|
971 |
+
$.jmpress("defaults").reasonableAnimation = {};
|
972 |
+
$.jmpress("initStep", function( step, eventData ) {
|
973 |
+
var data = eventData.data;
|
974 |
+
var stepData = eventData.stepData;
|
975 |
+
var pf = parseFloat;
|
976 |
+
$.extend(stepData, {
|
977 |
+
x: pf(data.x) || 0
|
978 |
+
,y: pf(data.y) || 0
|
979 |
+
,z: pf(data.z) || 0
|
980 |
+
,r: pf(data.r) || 0
|
981 |
+
,phi: pf(data.phi) || 0
|
982 |
+
,rotate: pf(data.rotate) || 0
|
983 |
+
,rotateX: pf(data.rotateX) || 0
|
984 |
+
,rotateY: pf(data.rotateY) || 0
|
985 |
+
,rotateZ: pf(data.rotateZ) || 0
|
986 |
+
,revertRotate: false
|
987 |
+
,scale: pf(data.scale) || 1
|
988 |
+
,scaleX: pf(data.scaleX) || false
|
989 |
+
,scaleY: pf(data.scaleY) || false
|
990 |
+
,scaleZ: pf(data.scaleZ) || 1
|
991 |
+
});
|
992 |
+
});
|
993 |
+
$.jmpress("afterInit", function( nil, eventData ) {
|
994 |
+
var stepSelector = eventData.settings.stepSelector,
|
995 |
+
current = eventData.current;
|
996 |
+
current.perspectiveScale = 1;
|
997 |
+
current.maxNestedDepth = 0;
|
998 |
+
var nestedSteps = $(eventData.jmpress).find(stepSelector).children(stepSelector);
|
999 |
+
while(nestedSteps.length) {
|
1000 |
+
current.maxNestedDepth++;
|
1001 |
+
nestedSteps = nestedSteps.children(stepSelector);
|
1002 |
+
}
|
1003 |
+
});
|
1004 |
+
$.jmpress("applyStep", function( step, eventData ) {
|
1005 |
+
$.jmpress("css", $(step), {
|
1006 |
+
position: "absolute"
|
1007 |
+
,transformStyle: "preserve-3d"
|
1008 |
+
});
|
1009 |
+
if ( eventData.parents.length > 0 ) {
|
1010 |
+
$.jmpress("css", $(step), {
|
1011 |
+
top: "50%"
|
1012 |
+
,left: "50%"
|
1013 |
+
});
|
1014 |
+
}
|
1015 |
+
var sd = eventData.stepData;
|
1016 |
+
var transform = [
|
1017 |
+
["translate",
|
1018 |
+
sd.x || (sd.r * Math.sin(sd.phi*Math.PI/180)),
|
1019 |
+
sd.y || (-sd.r * Math.cos(sd.phi*Math.PI/180)),
|
1020 |
+
sd.z],
|
1021 |
+
["rotate",
|
1022 |
+
sd.rotateX,
|
1023 |
+
sd.rotateY,
|
1024 |
+
sd.rotateZ || sd.rotate,
|
1025 |
+
true],
|
1026 |
+
["scale",
|
1027 |
+
sd.scaleX || sd.scale,
|
1028 |
+
sd.scaleY || sd.scale,
|
1029 |
+
sd.scaleZ || sd.scale]
|
1030 |
+
];
|
1031 |
+
engine.transform( step, transform );
|
1032 |
+
});
|
1033 |
+
$.jmpress("setActive", function( element, eventData ) {
|
1034 |
+
var target = eventData.target;
|
1035 |
+
var step = eventData.stepData;
|
1036 |
+
var tf = target.transform = [];
|
1037 |
+
target.perspectiveScale = 1;
|
1038 |
+
|
1039 |
+
for(var i = eventData.current.maxNestedDepth; i > (eventData.parents.length || 0); i--) {
|
1040 |
+
tf.push(["scale"], ["rotate"], ["translate"]);
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
tf.push(["scale",
|
1044 |
+
1 / (step.scaleX || step.scale),
|
1045 |
+
1 / (step.scaleY || step.scale),
|
1046 |
+
1 / (step.scaleZ)]);
|
1047 |
+
tf.push(["rotate",
|
1048 |
+
-step.rotateX,
|
1049 |
+
-step.rotateY,
|
1050 |
+
-(step.rotateZ || step.rotate)]);
|
1051 |
+
tf.push(["translate",
|
1052 |
+
-(step.x || (step.r * Math.sin(step.phi*Math.PI/180))),
|
1053 |
+
-(step.y || (-step.r * Math.cos(step.phi*Math.PI/180))),
|
1054 |
+
-step.z]);
|
1055 |
+
target.perspectiveScale *= (step.scaleX || step.scale);
|
1056 |
+
|
1057 |
+
$.each(eventData.parents, function(idx, element) {
|
1058 |
+
var step = $(element).data("stepData");
|
1059 |
+
tf.push(["scale",
|
1060 |
+
1 / (step.scaleX || step.scale),
|
1061 |
+
1 / (step.scaleY || step.scale),
|
1062 |
+
1 / (step.scaleZ)]);
|
1063 |
+
tf.push(["rotate",
|
1064 |
+
-step.rotateX,
|
1065 |
+
-step.rotateY,
|
1066 |
+
-(step.rotateZ || step.rotate)]);
|
1067 |
+
tf.push(["translate",
|
1068 |
+
-(step.x || (step.r * Math.sin(step.phi*Math.PI/180))),
|
1069 |
+
-(step.y || (-step.r * Math.cos(step.phi*Math.PI/180))),
|
1070 |
+
-step.z]);
|
1071 |
+
target.perspectiveScale *= (step.scaleX || step.scale);
|
1072 |
+
});
|
1073 |
+
|
1074 |
+
$.each(tf, function(idx, item) {
|
1075 |
+
if(item[0] !== "rotate") {
|
1076 |
+
return;
|
1077 |
+
}
|
1078 |
+
function lowRotate(name) {
|
1079 |
+
if(eventData.current["rotate"+name+"-"+idx] === undefined) {
|
1080 |
+
eventData.current["rotate"+name+"-"+idx] = item[name] || 0;
|
1081 |
+
}
|
1082 |
+
var cur = eventData.current["rotate"+name+"-"+idx], tar = item[name] || 0,
|
1083 |
+
curmod = cur % 360, tarmod = tar % 360;
|
1084 |
+
if(curmod < 0) {
|
1085 |
+
curmod += 360;
|
1086 |
+
}
|
1087 |
+
if(tarmod < 0) {
|
1088 |
+
tarmod += 360;
|
1089 |
+
}
|
1090 |
+
var diff = tarmod - curmod;
|
1091 |
+
if(diff < -180) {
|
1092 |
+
diff += 360;
|
1093 |
+
} else if(diff > 180) {
|
1094 |
+
diff -= 360;
|
1095 |
+
}
|
1096 |
+
eventData.current["rotate"+name+"-"+idx] = item[name] = cur + diff;
|
1097 |
+
}
|
1098 |
+
lowRotate(1);
|
1099 |
+
lowRotate(2);
|
1100 |
+
lowRotate(3);
|
1101 |
+
});
|
1102 |
+
});
|
1103 |
+
$.jmpress("applyTarget", function( active, eventData ) {
|
1104 |
+
|
1105 |
+
var target = eventData.target,
|
1106 |
+
props, step = eventData.stepData,
|
1107 |
+
settings = eventData.settings,
|
1108 |
+
zoomin = target.perspectiveScale * 1.3 < eventData.current.perspectiveScale,
|
1109 |
+
zoomout = target.perspectiveScale > eventData.current.perspectiveScale * 1.3;
|
1110 |
+
|
1111 |
+
// extract first scale from transform
|
1112 |
+
var lastScale = -1;
|
1113 |
+
$.each(target.transform, function(idx, item) {
|
1114 |
+
if(item.length <= 1) {
|
1115 |
+
return;
|
1116 |
+
}
|
1117 |
+
if(item[0] === "rotate" &&
|
1118 |
+
item[1] % 360 === 0 &&
|
1119 |
+
item[2] % 360 === 0 &&
|
1120 |
+
item[3] % 360 === 0) {
|
1121 |
+
return;
|
1122 |
+
}
|
1123 |
+
if(item[0] === "scale") {
|
1124 |
+
lastScale = idx;
|
1125 |
+
} else {
|
1126 |
+
return false;
|
1127 |
+
}
|
1128 |
+
});
|
1129 |
+
|
1130 |
+
if(lastScale !== eventData.current.oldLastScale) {
|
1131 |
+
zoomin = zoomout = false;
|
1132 |
+
eventData.current.oldLastScale = lastScale;
|
1133 |
+
}
|
1134 |
+
|
1135 |
+
var extracted = [];
|
1136 |
+
if(lastScale !== -1) {
|
1137 |
+
while(lastScale >= 0) {
|
1138 |
+
if(target.transform[lastScale][0] === "scale") {
|
1139 |
+
extracted.push(target.transform[lastScale]);
|
1140 |
+
target.transform[lastScale] = ["scale"];
|
1141 |
+
}
|
1142 |
+
lastScale--;
|
1143 |
+
}
|
1144 |
+
}
|
1145 |
+
|
1146 |
+
var animation = settings.animation;
|
1147 |
+
if(settings.reasonableAnimation[eventData.reason]) {
|
1148 |
+
animation = $.extend({},
|
1149 |
+
animation,
|
1150 |
+
settings.reasonableAnimation[eventData.reason]);
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
props = {
|
1154 |
+
// to keep the perspective look similar for different scales
|
1155 |
+
// we need to 'scale' the perspective, too
|
1156 |
+
perspective: Math.round(target.perspectiveScale * 1000) + "px"
|
1157 |
+
};
|
1158 |
+
props = $.extend({}, animation, props);
|
1159 |
+
if (!zoomin) {
|
1160 |
+
props.transitionDelay = '0s';
|
1161 |
+
}
|
1162 |
+
if (!eventData.beforeActive) {
|
1163 |
+
props.transitionDuration = '0s';
|
1164 |
+
props.transitionDelay = '0s';
|
1165 |
+
}
|
1166 |
+
$.jmpress("css", eventData.area, props);
|
1167 |
+
engine.transform(eventData.area, extracted);
|
1168 |
+
|
1169 |
+
props = $.extend({}, animation);
|
1170 |
+
if (!zoomout) {
|
1171 |
+
props.transitionDelay = '0s';
|
1172 |
+
}
|
1173 |
+
if (!eventData.beforeActive) {
|
1174 |
+
props.transitionDuration = '0s';
|
1175 |
+
props.transitionDelay = '0s';
|
1176 |
+
}
|
1177 |
+
|
1178 |
+
eventData.current.perspectiveScale = target.perspectiveScale;
|
1179 |
+
|
1180 |
+
$.jmpress("css", eventData.canvas, props);
|
1181 |
+
engine.transform(eventData.canvas, target.transform);
|
1182 |
+
});
|
1183 |
+
|
1184 |
+
}(jQuery, document, window));
|
1185 |
+
/*
|
1186 |
+
* active.js
|
1187 |
+
* Set the active classes on steps
|
1188 |
+
*/
|
1189 |
+
(function( $, document, window, undefined ) {
|
1190 |
+
|
1191 |
+
'use strict';
|
1192 |
+
var $jmpress = $.jmpress;
|
1193 |
+
|
1194 |
+
/* DEFINES */
|
1195 |
+
var activeClass = 'activeClass',
|
1196 |
+
nestedActiveClass = 'nestedActiveClass';
|
1197 |
+
|
1198 |
+
/* DEFAULTS */
|
1199 |
+
var defaults = $jmpress( 'defaults' );
|
1200 |
+
defaults[nestedActiveClass] = "nested-active";
|
1201 |
+
defaults[activeClass] = "active";
|
1202 |
+
|
1203 |
+
/* HOOKS */
|
1204 |
+
$jmpress( 'setInactive', function( step, eventData ) {
|
1205 |
+
var settings = eventData.settings,
|
1206 |
+
activeClassSetting = settings[activeClass],
|
1207 |
+
nestedActiveClassSettings = settings[nestedActiveClass];
|
1208 |
+
if(activeClassSetting) {
|
1209 |
+
$(step).removeClass( activeClassSetting );
|
1210 |
+
}
|
1211 |
+
if(nestedActiveClassSettings) {
|
1212 |
+
$.each(eventData.parents, function(idx, element) {
|
1213 |
+
$(element).removeClass(nestedActiveClassSettings);
|
1214 |
+
});
|
1215 |
+
}
|
1216 |
+
});
|
1217 |
+
$jmpress( 'setActive', function( step, eventData ) {
|
1218 |
+
var settings = eventData.settings,
|
1219 |
+
activeClassSetting = settings[activeClass],
|
1220 |
+
nestedActiveClassSettings = settings[nestedActiveClass];
|
1221 |
+
if(activeClassSetting) {
|
1222 |
+
$(step).addClass( activeClassSetting );
|
1223 |
+
}
|
1224 |
+
if(nestedActiveClassSettings) {
|
1225 |
+
$.each(eventData.parents, function(idx, element) {
|
1226 |
+
$(element).addClass(nestedActiveClassSettings);
|
1227 |
+
});
|
1228 |
+
}
|
1229 |
+
});
|
1230 |
+
|
1231 |
+
}(jQuery, document, window));
|
1232 |
+
/*
|
1233 |
+
* circular.js
|
1234 |
+
* Repeat from start after end
|
1235 |
+
*/
|
1236 |
+
(function( $, document, window, undefined ) {
|
1237 |
+
|
1238 |
+
'use strict';
|
1239 |
+
var $jmpress = $.jmpress;
|
1240 |
+
|
1241 |
+
/* FUNCTIONS */
|
1242 |
+
function firstSlide( step, eventData ) {
|
1243 |
+
return $(this).find(eventData.settings.stepSelector).first();
|
1244 |
+
}
|
1245 |
+
function prevOrNext( jmpress, step, eventData, prev) {
|
1246 |
+
if (!step) {
|
1247 |
+
return false;
|
1248 |
+
}
|
1249 |
+
var stepSelector = eventData.settings.stepSelector;
|
1250 |
+
step = $(step);
|
1251 |
+
do {
|
1252 |
+
var item = step.near( stepSelector, prev );
|
1253 |
+
if (item.length === 0 || item.closest(jmpress).length === 0) {
|
1254 |
+
item = $(jmpress).find(stepSelector)[prev?"last":"first"]();
|
1255 |
+
}
|
1256 |
+
if (!item.length) {
|
1257 |
+
return false;
|
1258 |
+
}
|
1259 |
+
step = item;
|
1260 |
+
} while( step.data("stepData").exclude );
|
1261 |
+
return step;
|
1262 |
+
}
|
1263 |
+
|
1264 |
+
/* HOOKS */
|
1265 |
+
$jmpress( 'initStep', function( step, eventData ) {
|
1266 |
+
eventData.stepData.exclude = eventData.data.exclude && ["false", "no"].indexOf(eventData.data.exclude) === -1;
|
1267 |
+
});
|
1268 |
+
$jmpress( 'selectInitialStep', firstSlide);
|
1269 |
+
$jmpress( 'selectHome', firstSlide);
|
1270 |
+
$jmpress( 'selectEnd', function( step, eventData ) {
|
1271 |
+
return $(this).find(eventData.settings.stepSelector).last();
|
1272 |
+
});
|
1273 |
+
$jmpress( 'selectPrev', function( step, eventData ) {
|
1274 |
+
return prevOrNext(this, step, eventData, true);
|
1275 |
+
});
|
1276 |
+
$jmpress( 'selectNext', function( step, eventData ) {
|
1277 |
+
return prevOrNext(this, step, eventData);
|
1278 |
+
});
|
1279 |
+
}(jQuery, document, window));
|
1280 |
+
/*
|
1281 |
+
* start.js
|
1282 |
+
* Set the first step to start on
|
1283 |
+
*/
|
1284 |
+
(function( $, document, window, undefined ) {
|
1285 |
+
|
1286 |
+
'use strict';
|
1287 |
+
|
1288 |
+
/* HOOKS */
|
1289 |
+
$.jmpress( 'selectInitialStep', function( nil, eventData ) {
|
1290 |
+
return eventData.settings.start;
|
1291 |
+
});
|
1292 |
+
|
1293 |
+
}(jQuery, document, window));
|
1294 |
+
/*
|
1295 |
+
* ways.js
|
1296 |
+
* Control the flow of the steps
|
1297 |
+
*/
|
1298 |
+
(function( $, document, window, undefined ) {
|
1299 |
+
|
1300 |
+
'use strict';
|
1301 |
+
var $jmpress = $.jmpress;
|
1302 |
+
|
1303 |
+
/* FUNCTIONS */
|
1304 |
+
function routeFunc( jmpress, route, type ) {
|
1305 |
+
for(var i = 0; i < route.length - 1; i++) {
|
1306 |
+
var from = route[i];
|
1307 |
+
var to = route[i+1];
|
1308 |
+
if($(jmpress).jmpress("initialized")) {
|
1309 |
+
$(from, jmpress).data("stepData")[type] = to;
|
1310 |
+
} else {
|
1311 |
+
$(from, jmpress).attr('data-' + type, to);
|
1312 |
+
}
|
1313 |
+
}
|
1314 |
+
}
|
1315 |
+
function selectPrevOrNext( step, eventData, attr, prev ) {
|
1316 |
+
var stepData = eventData.stepData;
|
1317 |
+
if(stepData[attr]) {
|
1318 |
+
var near = $(step).near(stepData[attr], prev);
|
1319 |
+
if(near && near.length) {
|
1320 |
+
return near;
|
1321 |
+
}
|
1322 |
+
near = $(stepData[attr], this)[prev?"last":"first"]();
|
1323 |
+
if(near && near.length) {
|
1324 |
+
return near;
|
1325 |
+
}
|
1326 |
+
}
|
1327 |
+
}
|
1328 |
+
|
1329 |
+
/* EXPORTED FUNCTIONS */
|
1330 |
+
$jmpress( 'register', 'route', function( route, unidirectional, reversedRoute ) {
|
1331 |
+
if( typeof route === "string" ) {
|
1332 |
+
route = [route, route];
|
1333 |
+
}
|
1334 |
+
routeFunc(this, route, reversedRoute ? "prev" : "next");
|
1335 |
+
if (!unidirectional) {
|
1336 |
+
routeFunc(this, route.reverse(), reversedRoute ? "next" : "prev");
|
1337 |
+
}
|
1338 |
+
});
|
1339 |
+
|
1340 |
+
/* HOOKS */
|
1341 |
+
$jmpress( 'initStep', function( step, eventData ) {
|
1342 |
+
for(var attr in {next:1,prev:1}) {
|
1343 |
+
eventData.stepData[attr] = eventData.data[attr];
|
1344 |
+
}
|
1345 |
+
});
|
1346 |
+
$jmpress( 'selectNext', function( step, eventData ) {
|
1347 |
+
return selectPrevOrNext.call(this, step, eventData, "next");
|
1348 |
+
});
|
1349 |
+
$jmpress( 'selectPrev', function( step, eventData ) {
|
1350 |
+
return selectPrevOrNext.call(this, step, eventData, "prev", true);
|
1351 |
+
});
|
1352 |
+
|
1353 |
+
}(jQuery, document, window));
|
1354 |
+
/*
|
1355 |
+
* ajax.js
|
1356 |
+
* Load steps via ajax
|
1357 |
+
*/
|
1358 |
+
(function( $, document, window, undefined ) {
|
1359 |
+
|
1360 |
+
'use strict';
|
1361 |
+
var $jmpress = $.jmpress;
|
1362 |
+
|
1363 |
+
/* DEFINES */
|
1364 |
+
var afterStepLoaded = 'ajax:afterStepLoaded',
|
1365 |
+
loadStep = 'ajax:loadStep';
|
1366 |
+
|
1367 |
+
/* REGISTER EVENTS */
|
1368 |
+
$jmpress('register', loadStep);
|
1369 |
+
$jmpress('register', afterStepLoaded);
|
1370 |
+
|
1371 |
+
/* DEFAULTS */
|
1372 |
+
$jmpress('defaults').ajaxLoadedClass = "loaded";
|
1373 |
+
|
1374 |
+
/* HOOKS */
|
1375 |
+
$jmpress('initStep', function( step, eventData ) {
|
1376 |
+
eventData.stepData.src = $(step).attr('href') || eventData.data.src || false;
|
1377 |
+
eventData.stepData.srcLoaded = false;
|
1378 |
+
});
|
1379 |
+
$jmpress(loadStep, function( step, eventData ) {
|
1380 |
+
var stepData = eventData.stepData,
|
1381 |
+
href = stepData && stepData.src,
|
1382 |
+
settings = eventData.settings;
|
1383 |
+
if ( href ) {
|
1384 |
+
$(step).addClass( settings.ajaxLoadedClass );
|
1385 |
+
stepData.srcLoaded = true;
|
1386 |
+
$(step).load(href, function(response, status, xhr) {
|
1387 |
+
$(eventData.jmpress).jmpress('fire', afterStepLoaded, step, $.extend({}, eventData, {
|
1388 |
+
response: response
|
1389 |
+
,status: status
|
1390 |
+
,xhr: xhr
|
1391 |
+
}));
|
1392 |
+
});
|
1393 |
+
}
|
1394 |
+
});
|
1395 |
+
$jmpress('idle', function( step, eventData ) {
|
1396 |
+
if (!step) {
|
1397 |
+
return;
|
1398 |
+
}
|
1399 |
+
var settings = eventData.settings,
|
1400 |
+
jmpress = $(this),
|
1401 |
+
stepData = eventData.stepData;
|
1402 |
+
var siblings = $(step)
|
1403 |
+
.add( $(step).near( settings.stepSelector ) )
|
1404 |
+
.add( $(step).near( settings.stepSelector, true) )
|
1405 |
+
.add( jmpress.jmpress('fire', 'selectPrev', step, {
|
1406 |
+
stepData: $(step).data('stepData')
|
1407 |
+
}))
|
1408 |
+
.add( jmpress.jmpress('fire', 'selectNext', step, {
|
1409 |
+
stepData: $(step).data('stepData')
|
1410 |
+
}));
|
1411 |
+
siblings.each(function() {
|
1412 |
+
var step = this,
|
1413 |
+
stepData = $(step).data("stepData");
|
1414 |
+
if(!stepData.src || stepData.srcLoaded) {
|
1415 |
+
return;
|
1416 |
+
}
|
1417 |
+
jmpress.jmpress('fire', loadStep, step, {
|
1418 |
+
stepData: $(step).data('stepData')
|
1419 |
+
});
|
1420 |
+
});
|
1421 |
+
});
|
1422 |
+
$jmpress("setActive", function(step, eventData) {
|
1423 |
+
var stepData = $(step).data("stepData");
|
1424 |
+
if(!stepData.src || stepData.srcLoaded) {
|
1425 |
+
return;
|
1426 |
+
}
|
1427 |
+
$(this).jmpress('fire', loadStep, step, {
|
1428 |
+
stepData: $(step).data('stepData')
|
1429 |
+
});
|
1430 |
+
});
|
1431 |
+
|
1432 |
+
}(jQuery, document, window));
|
1433 |
+
/*
|
1434 |
+
* hash.js
|
1435 |
+
* Detect and set the URL hash
|
1436 |
+
*/
|
1437 |
+
(function( $, document, window, undefined ) {
|
1438 |
+
|
1439 |
+
'use strict';
|
1440 |
+
var $jmpress = $.jmpress,
|
1441 |
+
hashLink = "a[href^=#]";
|
1442 |
+
|
1443 |
+
/* FUNCTIONS */
|
1444 |
+
function randomString() {
|
1445 |
+
return "" + Math.round(Math.random() * 100000, 0);
|
1446 |
+
}
|
1447 |
+
/**
|
1448 |
+
* getElementFromUrl
|
1449 |
+
*
|
1450 |
+
* @return String or undefined
|
1451 |
+
*/
|
1452 |
+
function getElementFromUrl(settings) {
|
1453 |
+
// get id from url # by removing `#` or `#/` from the beginning,
|
1454 |
+
// so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work
|
1455 |
+
// TODO SECURITY check user input to be valid!
|
1456 |
+
try {
|
1457 |
+
var el = $( '#' + window.location.hash.replace(/^#\/?/,"") );
|
1458 |
+
return el.length > 0 && el.is(settings.stepSelector) ? el : undefined;
|
1459 |
+
} catch(e) {}
|
1460 |
+
}
|
1461 |
+
function setHash(stepid) {
|
1462 |
+
var shouldBeHash = "#/" + stepid;
|
1463 |
+
if(window.history && window.history.pushState) {
|
1464 |
+
// shouldBeHash = "#" + stepid;
|
1465 |
+
// consider this for future versions
|
1466 |
+
// it has currently issues, when startup with a link with hash (webkit)
|
1467 |
+
if(window.location.hash !== shouldBeHash) {
|
1468 |
+
window.history.pushState({}, '', shouldBeHash);
|
1469 |
+
}
|
1470 |
+
} else {
|
1471 |
+
if(window.location.hash !== shouldBeHash) {
|
1472 |
+
window.location.hash = shouldBeHash;
|
1473 |
+
}
|
1474 |
+
}
|
1475 |
+
}
|
1476 |
+
|
1477 |
+
/* DEFAULTS */
|
1478 |
+
$jmpress('defaults').hash = {
|
1479 |
+
use: true
|
1480 |
+
,update: true
|
1481 |
+
,bindChange: true
|
1482 |
+
// NOTICE: {use: true, update: false, bindChange: true}
|
1483 |
+
// will cause a error after clicking on a link to the current step
|
1484 |
+
};
|
1485 |
+
|
1486 |
+
/* HOOKS */
|
1487 |
+
$jmpress('selectInitialStep', function( step, eventData ) {
|
1488 |
+
var settings = eventData.settings,
|
1489 |
+
hashSettings = settings.hash,
|
1490 |
+
current = eventData.current,
|
1491 |
+
jmpress = $(this);
|
1492 |
+
eventData.current.hashNamespace = ".jmpress-"+randomString();
|
1493 |
+
// HASH CHANGE EVENT
|
1494 |
+
if ( hashSettings.use ) {
|
1495 |
+
if ( hashSettings.bindChange ) {
|
1496 |
+
$(window).bind('hashchange'+current.hashNamespace, function(event) {
|
1497 |
+
var urlItem = getElementFromUrl(settings);
|
1498 |
+
if ( jmpress.jmpress('initialized') ) {
|
1499 |
+
jmpress.jmpress("scrollFix");
|
1500 |
+
}
|
1501 |
+
if(urlItem && urlItem.length) {
|
1502 |
+
if(urlItem.attr("id") !== jmpress.jmpress("active").attr("id")) {
|
1503 |
+
jmpress.jmpress('select', urlItem);
|
1504 |
+
}
|
1505 |
+
setHash(urlItem.attr("id"));
|
1506 |
+
}
|
1507 |
+
event.preventDefault();
|
1508 |
+
});
|
1509 |
+
$(hashLink).on("click"+current.hashNamespace, function(event) {
|
1510 |
+
var href = $(this).attr("href");
|
1511 |
+
try {
|
1512 |
+
if($(href).is(settings.stepSelector)) {
|
1513 |
+
jmpress.jmpress("select", href);
|
1514 |
+
event.preventDefault();
|
1515 |
+
event.stopPropagation();
|
1516 |
+
}
|
1517 |
+
} catch(e) {}
|
1518 |
+
});
|
1519 |
+
}
|
1520 |
+
return getElementFromUrl(settings);
|
1521 |
+
}
|
1522 |
+
});
|
1523 |
+
$jmpress('afterDeinit', function( nil, eventData ) {
|
1524 |
+
$(hashLink).off(eventData.current.hashNamespace);
|
1525 |
+
$(window).unbind(eventData.current.hashNamespace);
|
1526 |
+
});
|
1527 |
+
$jmpress('setActive', function( step, eventData ) {
|
1528 |
+
var settings = eventData.settings,
|
1529 |
+
current = eventData.current;
|
1530 |
+
// `#/step-id` is used instead of `#step-id` to prevent default browser
|
1531 |
+
// scrolling to element in hash
|
1532 |
+
if ( settings.hash.use && settings.hash.update ) {
|
1533 |
+
clearTimeout(current.hashtimeout);
|
1534 |
+
current.hashtimeout = setTimeout(function() {
|
1535 |
+
setHash($(eventData.delegatedFrom).attr('id'));
|
1536 |
+
}, settings.transitionDuration + 200);
|
1537 |
+
}
|
1538 |
+
});
|
1539 |
+
|
1540 |
+
}(jQuery, document, window));
|
1541 |
+
/*
|
1542 |
+
* keyboard.js
|
1543 |
+
* Keyboard event mapping and default keyboard actions
|
1544 |
+
*/
|
1545 |
+
(function( $, document, window, undefined ) {
|
1546 |
+
|
1547 |
+
'use strict';
|
1548 |
+
var $jmpress = $.jmpress,
|
1549 |
+
jmpressNext = "next",
|
1550 |
+
jmpressPrev = "prev";
|
1551 |
+
|
1552 |
+
/* FUNCTIONS */
|
1553 |
+
function randomString() {
|
1554 |
+
return "" + Math.round(Math.random() * 100000, 0);
|
1555 |
+
}
|
1556 |
+
function stopEvent(event) {
|
1557 |
+
event.preventDefault();
|
1558 |
+
event.stopPropagation();
|
1559 |
+
}
|
1560 |
+
|
1561 |
+
/* DEFAULTS */
|
1562 |
+
$jmpress('defaults').keyboard = {
|
1563 |
+
use: true
|
1564 |
+
,keys: {
|
1565 |
+
33: jmpressPrev // pg up
|
1566 |
+
,37: jmpressPrev // left
|
1567 |
+
,38: jmpressPrev // up
|
1568 |
+
|
1569 |
+
,9: jmpressNext+":"+jmpressPrev // tab
|
1570 |
+
,32: jmpressNext // space
|
1571 |
+
,34: jmpressNext // pg down
|
1572 |
+
,39: jmpressNext // right
|
1573 |
+
,40: jmpressNext // down
|
1574 |
+
|
1575 |
+
,36: "home" // home
|
1576 |
+
|
1577 |
+
,35: "end" // end
|
1578 |
+
}
|
1579 |
+
,ignore: {
|
1580 |
+
"INPUT": [
|
1581 |
+
32 // space
|
1582 |
+
,37 // left
|
1583 |
+
,38 // up
|
1584 |
+
,39 // right
|
1585 |
+
,40 // down
|
1586 |
+
]
|
1587 |
+
,"TEXTAREA": [
|
1588 |
+
32 // space
|
1589 |
+
,37 // left
|
1590 |
+
,38 // up
|
1591 |
+
,39 // right
|
1592 |
+
,40 // down
|
1593 |
+
]
|
1594 |
+
,"SELECT": [
|
1595 |
+
38 // up
|
1596 |
+
,40 // down
|
1597 |
+
]
|
1598 |
+
}
|
1599 |
+
,tabSelector: "a[href]:visible, :input:visible"
|
1600 |
+
};
|
1601 |
+
|
1602 |
+
/* HOOKS */
|
1603 |
+
$jmpress('afterInit', function( nil, eventData ) {
|
1604 |
+
var settings = eventData.settings,
|
1605 |
+
keyboardSettings = settings.keyboard,
|
1606 |
+
ignoreKeyboardSettings = keyboardSettings.ignore,
|
1607 |
+
current = eventData.current,
|
1608 |
+
jmpress = $(this);
|
1609 |
+
|
1610 |
+
// tabindex make it focusable so that it can recieve key events
|
1611 |
+
if(!settings.fullscreen) {
|
1612 |
+
jmpress.attr("tabindex", 0);
|
1613 |
+
}
|
1614 |
+
|
1615 |
+
current.keyboardNamespace = ".jmpress-"+randomString();
|
1616 |
+
|
1617 |
+
// KEYPRESS EVENT: this fixes a Opera bug
|
1618 |
+
$(settings.fullscreen ? document : jmpress)
|
1619 |
+
.bind("keypress"+current.keyboardNamespace, function( event ) {
|
1620 |
+
|
1621 |
+
for( var nodeName in ignoreKeyboardSettings ) {
|
1622 |
+
if ( event.target.nodeName === nodeName && ignoreKeyboardSettings[nodeName].indexOf(event.which) !== -1 ) {
|
1623 |
+
return;
|
1624 |
+
}
|
1625 |
+
}
|
1626 |
+
if(event.which >= 37 && event.which <= 40 || event.which === 32) {
|
1627 |
+
stopEvent(event);
|
1628 |
+
}
|
1629 |
+
});
|
1630 |
+
// KEYDOWN EVENT
|
1631 |
+
$(settings.fullscreen ? document : jmpress)
|
1632 |
+
.bind("keydown"+current.keyboardNamespace, function( event ) {
|
1633 |
+
var eventTarget = $(event.target);
|
1634 |
+
|
1635 |
+
if ( !settings.fullscreen && !eventTarget.closest(jmpress).length || !keyboardSettings.use ) {
|
1636 |
+
return;
|
1637 |
+
}
|
1638 |
+
|
1639 |
+
for( var nodeName in ignoreKeyboardSettings ) {
|
1640 |
+
if ( eventTarget[0].nodeName === nodeName && ignoreKeyboardSettings[nodeName].indexOf(event.which) !== -1 ) {
|
1641 |
+
return;
|
1642 |
+
}
|
1643 |
+
}
|
1644 |
+
|
1645 |
+
var reverseSelect = false;
|
1646 |
+
var nextFocus;
|
1647 |
+
if (event.which === 9) {
|
1648 |
+
// tab
|
1649 |
+
if ( !eventTarget.closest( jmpress.jmpress('active') ).length ) {
|
1650 |
+
if ( !event.shiftKey ) {
|
1651 |
+
nextFocus = jmpress.jmpress('active').find("a[href], :input").filter(":visible").first();
|
1652 |
+
} else {
|
1653 |
+
reverseSelect = true;
|
1654 |
+
}
|
1655 |
+
} else {
|
1656 |
+
nextFocus = eventTarget.near( keyboardSettings.tabSelector, event.shiftKey );
|
1657 |
+
if( !$(nextFocus)
|
1658 |
+
.closest( settings.stepSelector )
|
1659 |
+
.is(jmpress.jmpress('active') ) ) {
|
1660 |
+
nextFocus = undefined;
|
1661 |
+
}
|
1662 |
+
}
|
1663 |
+
if( nextFocus && nextFocus.length > 0 ) {
|
1664 |
+
nextFocus.focus();
|
1665 |
+
jmpress.jmpress("scrollFix");
|
1666 |
+
stopEvent(event);
|
1667 |
+
return;
|
1668 |
+
} else {
|
1669 |
+
if(event.shiftKey) {
|
1670 |
+
reverseSelect = true;
|
1671 |
+
}
|
1672 |
+
}
|
1673 |
+
}
|
1674 |
+
|
1675 |
+
var action = keyboardSettings.keys[ event.which ];
|
1676 |
+
if ( typeof action === "string" ) {
|
1677 |
+
if (action.indexOf(":") !== -1) {
|
1678 |
+
action = action.split(":");
|
1679 |
+
action = event.shiftKey ? action[1] : action[0];
|
1680 |
+
}
|
1681 |
+
jmpress.jmpress( action );
|
1682 |
+
stopEvent(event);
|
1683 |
+
} else if ( $.isFunction(action) ) {
|
1684 |
+
action.call(jmpress, event);
|
1685 |
+
} else if ( action ) {
|
1686 |
+
jmpress.jmpress.apply( jmpress, action );
|
1687 |
+
stopEvent(event);
|
1688 |
+
}
|
1689 |
+
|
1690 |
+
if (reverseSelect) {
|
1691 |
+
// tab
|
1692 |
+
nextFocus = jmpress.jmpress('active').find("a[href], :input").filter(":visible").last();
|
1693 |
+
nextFocus.focus();
|
1694 |
+
jmpress.jmpress("scrollFix");
|
1695 |
+
}
|
1696 |
+
});
|
1697 |
+
});
|
1698 |
+
$jmpress('afterDeinit', function( nil, eventData ) {
|
1699 |
+
$(document).unbind(eventData.current.keyboardNamespace);
|
1700 |
+
});
|
1701 |
+
|
1702 |
+
|
1703 |
+
}(jQuery, document, window));
|
1704 |
+
/*
|
1705 |
+
* viewport.js
|
1706 |
+
* Scale to fit a given viewport
|
1707 |
+
*/
|
1708 |
+
(function( $, document, window, undefined ) {
|
1709 |
+
|
1710 |
+
'use strict';
|
1711 |
+
|
1712 |
+
function randomString() {
|
1713 |
+
return "" + Math.round(Math.random() * 100000, 0);
|
1714 |
+
}
|
1715 |
+
|
1716 |
+
var browser = (function() {
|
1717 |
+
var ua = navigator.userAgent.toLowerCase();
|
1718 |
+
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
|
1719 |
+
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
|
1720 |
+
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
|
1721 |
+
/(msie) ([\w.]+)/.exec(ua) ||
|
1722 |
+
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
|
1723 |
+
[];
|
1724 |
+
return match[1] || "";
|
1725 |
+
}());
|
1726 |
+
|
1727 |
+
var defaults = $.jmpress("defaults");
|
1728 |
+
defaults.viewPort = {
|
1729 |
+
width: false
|
1730 |
+
,height: false
|
1731 |
+
,maxScale: 0
|
1732 |
+
,minScale: 0
|
1733 |
+
,zoomable: 0
|
1734 |
+
,zoomBindMove: true
|
1735 |
+
,zoomBindWheel: true
|
1736 |
+
};
|
1737 |
+
var keys = defaults.keyboard.keys;
|
1738 |
+
keys[browser === 'mozilla' ? 107 : 187] = "zoomIn"; // +
|
1739 |
+
keys[browser === 'mozilla' ? 109 : 189] = "zoomOut"; // -
|
1740 |
+
defaults.reasonableAnimation.resize = {
|
1741 |
+
transitionDuration: '0s'
|
1742 |
+
,transitionDelay: '0ms'
|
1743 |
+
};
|
1744 |
+
defaults.reasonableAnimation.zoom = {
|
1745 |
+
transitionDuration: '0s'
|
1746 |
+
,transitionDelay: '0ms'
|
1747 |
+
};
|
1748 |
+
$.jmpress("initStep", function( step, eventData ) {
|
1749 |
+
for(var variable in {"viewPortHeight":1, "viewPortWidth":1, "viewPortMinScale":1, "viewPortMaxScale":1, "viewPortZoomable":1}) {
|
1750 |
+
eventData.stepData[variable] = eventData.data[variable] && parseFloat(eventData.data[variable]);
|
1751 |
+
}
|
1752 |
+
});
|
1753 |
+
$.jmpress("afterInit", function( nil, eventData ) {
|
1754 |
+
var jmpress = this;
|
1755 |
+
eventData.current.viewPortNamespace = ".jmpress-"+randomString();
|
1756 |
+
$(window).bind("resize"+eventData.current.viewPortNamespace, function (event) {
|
1757 |
+
$(jmpress).jmpress("reselect", "resize");
|
1758 |
+
});
|
1759 |
+
eventData.current.userZoom = 0;
|
1760 |
+
eventData.current.userTranslateX = 0;
|
1761 |
+
eventData.current.userTranslateY = 0;
|
1762 |
+
if(eventData.settings.viewPort.zoomBindWheel) {
|
1763 |
+
$(eventData.settings.fullscreen ? document : this)
|
1764 |
+
.bind("mousewheel"+eventData.current.viewPortNamespace+" DOMMouseScroll"+eventData.current.viewPortNamespace, function( event, delta ) {
|
1765 |
+
delta = delta || event.originalEvent.wheelDelta || -event.originalEvent.detail /* mozilla */;
|
1766 |
+
var direction = (delta / Math.abs(delta));
|
1767 |
+
if(direction < 0) {
|
1768 |
+
$(eventData.jmpress).jmpress("zoomOut", event.originalEvent.x, event.originalEvent.y);
|
1769 |
+
} else if(direction > 0) {
|
1770 |
+
$(eventData.jmpress).jmpress("zoomIn", event.originalEvent.x, event.originalEvent.y);
|
1771 |
+
}
|
1772 |
+
return false;
|
1773 |
+
});
|
1774 |
+
}
|
1775 |
+
if(eventData.settings.viewPort.zoomBindMove) {
|
1776 |
+
$(eventData.settings.fullscreen ? document : this).bind("mousedown"+eventData.current.viewPortNamespace, function (event) {
|
1777 |
+
if(eventData.current.userZoom) {
|
1778 |
+
eventData.current.userTranslating = { x: event.clientX, y: event.clientY };
|
1779 |
+
event.preventDefault();
|
1780 |
+
event.stopImmediatePropagation();
|
1781 |
+
}
|
1782 |
+
}).bind("mousemove"+eventData.current.viewPortNamespace, function (event) {
|
1783 |
+
var userTranslating = eventData.current.userTranslating;
|
1784 |
+
if(userTranslating) {
|
1785 |
+
$(jmpress).jmpress("zoomTranslate", event.clientX - userTranslating.x, event.clientY - userTranslating.y);
|
1786 |
+
userTranslating.x = event.clientX;
|
1787 |
+
userTranslating.y = event.clientY;
|
1788 |
+
event.preventDefault();
|
1789 |
+
event.stopImmediatePropagation();
|
1790 |
+
}
|
1791 |
+
}).bind("mouseup"+eventData.current.viewPortNamespace, function (event) {
|
1792 |
+
if(eventData.current.userTranslating) {
|
1793 |
+
eventData.current.userTranslating = undefined;
|
1794 |
+
event.preventDefault();
|
1795 |
+
event.stopImmediatePropagation();
|
1796 |
+
}
|
1797 |
+
});
|
1798 |
+
}
|
1799 |
+
});
|
1800 |
+
function maxAbs(value, range) {
|
1801 |
+
return Math.max(Math.min(value, range), -range);
|
1802 |
+
}
|
1803 |
+
function zoom(x, y, direction) {
|
1804 |
+
var current = $(this).jmpress("current"),
|
1805 |
+
settings = $(this).jmpress("settings"),
|
1806 |
+
stepData = $(this).jmpress("active").data("stepData"),
|
1807 |
+
container = $(this).jmpress("container");
|
1808 |
+
if(current.userZoom === 0 && direction < 0) {
|
1809 |
+
return;
|
1810 |
+
}
|
1811 |
+
var zoomableSteps = stepData.viewPortZoomable || settings.viewPort.zoomable;
|
1812 |
+
if(current.userZoom === zoomableSteps && direction > 0) {
|
1813 |
+
return;
|
1814 |
+
}
|
1815 |
+
current.userZoom += direction;
|
1816 |
+
|
1817 |
+
var halfWidth = $(container).innerWidth()/2,
|
1818 |
+
halfHeight = $(container).innerHeight()/2;
|
1819 |
+
|
1820 |
+
x = x ? x - halfWidth : x;
|
1821 |
+
y = y ? y - halfHeight : y;
|
1822 |
+
|
1823 |
+
// TODO this is not perfect... too much math... :(
|
1824 |
+
current.userTranslateX =
|
1825 |
+
maxAbs(current.userTranslateX - direction * x / current.zoomOriginWindowScale / zoomableSteps,
|
1826 |
+
halfWidth * current.userZoom * current.userZoom / zoomableSteps);
|
1827 |
+
current.userTranslateY =
|
1828 |
+
maxAbs(current.userTranslateY - direction * y / current.zoomOriginWindowScale / zoomableSteps,
|
1829 |
+
halfHeight * current.userZoom * current.userZoom / zoomableSteps);
|
1830 |
+
|
1831 |
+
$(this).jmpress("reselect", "zoom");
|
1832 |
+
}
|
1833 |
+
$.jmpress("register", "zoomIn", function(x, y) {
|
1834 |
+
zoom.call(this, x||0, y||0, 1);
|
1835 |
+
});
|
1836 |
+
$.jmpress("register", "zoomOut", function(x, y) {
|
1837 |
+
zoom.call(this, x||0, y||0, -1);
|
1838 |
+
});
|
1839 |
+
$.jmpress("register", "zoomTranslate", function(x, y) {
|
1840 |
+
var current = $(this).jmpress("current"),
|
1841 |
+
settings = $(this).jmpress("settings"),
|
1842 |
+
stepData = $(this).jmpress("active").data("stepData"),
|
1843 |
+
container = $(this).jmpress("container");
|
1844 |
+
var zoomableSteps = stepData.viewPortZoomable || settings.viewPort.zoomable;
|
1845 |
+
var halfWidth = $(container).innerWidth(),
|
1846 |
+
halfHeight = $(container).innerHeight();
|
1847 |
+
current.userTranslateX =
|
1848 |
+
maxAbs(current.userTranslateX + x / current.zoomOriginWindowScale,
|
1849 |
+
halfWidth * current.userZoom * current.userZoom / zoomableSteps);
|
1850 |
+
current.userTranslateY =
|
1851 |
+
maxAbs(current.userTranslateY + y / current.zoomOriginWindowScale,
|
1852 |
+
halfHeight * current.userZoom * current.userZoom / zoomableSteps);
|
1853 |
+
$(this).jmpress("reselect", "zoom");
|
1854 |
+
});
|
1855 |
+
$.jmpress('afterDeinit', function( nil, eventData ) {
|
1856 |
+
$(eventData.settings.fullscreen ? document : this).unbind(eventData.current.viewPortNamespace);
|
1857 |
+
$(window).unbind(eventData.current.viewPortNamespace);
|
1858 |
+
});
|
1859 |
+
$.jmpress("setActive", function( step, eventData ) {
|
1860 |
+
var viewPort = eventData.settings.viewPort;
|
1861 |
+
var viewPortHeight = eventData.stepData.viewPortHeight || viewPort.height;
|
1862 |
+
var viewPortWidth = eventData.stepData.viewPortWidth || viewPort.width;
|
1863 |
+
var viewPortMaxScale = eventData.stepData.viewPortMaxScale || viewPort.maxScale;
|
1864 |
+
var viewPortMinScale = eventData.stepData.viewPortMinScale || viewPort.minScale;
|
1865 |
+
// Correct the scale based on the window's size
|
1866 |
+
var windowScaleY = viewPortHeight && $(eventData.container).innerHeight()/viewPortHeight;
|
1867 |
+
var windowScaleX = viewPortWidth && $(eventData.container).innerWidth()/viewPortWidth;
|
1868 |
+
var windowScale = (windowScaleX || windowScaleY) && Math.min( windowScaleX || windowScaleY, windowScaleY || windowScaleX );
|
1869 |
+
|
1870 |
+
if(windowScale) {
|
1871 |
+
windowScale = windowScale || 1;
|
1872 |
+
if(viewPortMaxScale) {
|
1873 |
+
windowScale = Math.min(windowScale, viewPortMaxScale);
|
1874 |
+
}
|
1875 |
+
if(viewPortMinScale) {
|
1876 |
+
windowScale = Math.max(windowScale, viewPortMinScale);
|
1877 |
+
}
|
1878 |
+
|
1879 |
+
var zoomableSteps = eventData.stepData.viewPortZoomable || eventData.settings.viewPort.zoomable;
|
1880 |
+
if(zoomableSteps) {
|
1881 |
+
var diff = (1/windowScale) - (1/viewPortMaxScale);
|
1882 |
+
diff /= zoomableSteps;
|
1883 |
+
windowScale = 1/((1/windowScale) - diff * eventData.current.userZoom);
|
1884 |
+
}
|
1885 |
+
|
1886 |
+
eventData.target.transform.reverse();
|
1887 |
+
if(eventData.current.userTranslateX && eventData.current.userTranslateY) {
|
1888 |
+
eventData.target.transform.push(["translate", eventData.current.userTranslateX, eventData.current.userTranslateY, 0]);
|
1889 |
+
} else {
|
1890 |
+
eventData.target.transform.push(["translate"]);
|
1891 |
+
}
|
1892 |
+
eventData.target.transform.push(["scale",
|
1893 |
+
windowScale,
|
1894 |
+
windowScale,
|
1895 |
+
1]);
|
1896 |
+
eventData.target.transform.reverse();
|
1897 |
+
eventData.target.perspectiveScale /= windowScale;
|
1898 |
+
}
|
1899 |
+
eventData.current.zoomOriginWindowScale = windowScale;
|
1900 |
+
});
|
1901 |
+
$.jmpress("setInactive", function( step, eventData ) {
|
1902 |
+
if(!eventData.nextStep || !step || $(eventData.nextStep).attr("id") !== $(step).attr("id")) {
|
1903 |
+
eventData.current.userZoom = 0;
|
1904 |
+
eventData.current.userTranslateX = 0;
|
1905 |
+
eventData.current.userTranslateY = 0;
|
1906 |
+
}
|
1907 |
+
});
|
1908 |
+
|
1909 |
+
}(jQuery, document, window));
|
1910 |
+
|
1911 |
+
/*
|
1912 |
+
* mouse.js
|
1913 |
+
* Clicking to select a step
|
1914 |
+
*/
|
1915 |
+
(function( $, document, window, undefined ) {
|
1916 |
+
|
1917 |
+
'use strict';
|
1918 |
+
var $jmpress = $.jmpress;
|
1919 |
+
|
1920 |
+
/* FUNCTIONS */
|
1921 |
+
function randomString() {
|
1922 |
+
return "" + Math.round(Math.random() * 100000, 0);
|
1923 |
+
}
|
1924 |
+
|
1925 |
+
/* DEFAULTS */
|
1926 |
+
$jmpress("defaults").mouse = {
|
1927 |
+
clickSelects: true
|
1928 |
+
};
|
1929 |
+
|
1930 |
+
/* HOOKS */
|
1931 |
+
$jmpress("afterInit", function( nil, eventData ) {
|
1932 |
+
var settings = eventData.settings,
|
1933 |
+
stepSelector = settings.stepSelector,
|
1934 |
+
current = eventData.current,
|
1935 |
+
jmpress = $(this);
|
1936 |
+
current.clickableStepsNamespace = ".jmpress-"+randomString();
|
1937 |
+
jmpress.bind("click"+current.clickableStepsNamespace, function(event) {
|
1938 |
+
if (!settings.mouse.clickSelects || current.userZoom) {
|
1939 |
+
return;
|
1940 |
+
}
|
1941 |
+
|
1942 |
+
// get clicked step
|
1943 |
+
var clickedStep = $(event.target).closest(stepSelector);
|
1944 |
+
|
1945 |
+
// clicks on the active step do default
|
1946 |
+
if ( clickedStep.is( jmpress.jmpress("active") ) ) {
|
1947 |
+
return;
|
1948 |
+
}
|
1949 |
+
|
1950 |
+
if (clickedStep.length) {
|
1951 |
+
// select the clicked step
|
1952 |
+
jmpress.jmpress("select", clickedStep[0], "click");
|
1953 |
+
event.preventDefault();
|
1954 |
+
event.stopPropagation();
|
1955 |
+
}
|
1956 |
+
});
|
1957 |
+
});
|
1958 |
+
$jmpress('afterDeinit', function( nil, eventData ) {
|
1959 |
+
$(this).unbind(eventData.current.clickableStepsNamespace);
|
1960 |
+
});
|
1961 |
+
|
1962 |
+
}(jQuery, document, window));
|
1963 |
+
/*
|
1964 |
+
* mobile.js
|
1965 |
+
* Adds support for swipe on touch supported browsers
|
1966 |
+
*/
|
1967 |
+
(function( $, document, window, undefined ) {
|
1968 |
+
|
1969 |
+
'use strict';
|
1970 |
+
var $jmpress = $.jmpress;
|
1971 |
+
|
1972 |
+
/* FUNCTIONS */
|
1973 |
+
function randomString() {
|
1974 |
+
return "" + Math.round(Math.random() * 100000, 0);
|
1975 |
+
}
|
1976 |
+
|
1977 |
+
/* HOOKS */
|
1978 |
+
$jmpress( 'afterInit', function( step, eventData ) {
|
1979 |
+
var settings = eventData.settings,
|
1980 |
+
current = eventData.current,
|
1981 |
+
jmpress = eventData.jmpress;
|
1982 |
+
current.mobileNamespace = ".jmpress-"+randomString();
|
1983 |
+
var data, start = [0,0];
|
1984 |
+
$(settings.fullscreen ? document : jmpress)
|
1985 |
+
.bind("touchstart"+current.mobileNamespace, function( event ) {
|
1986 |
+
|
1987 |
+
data = event.originalEvent.touches[0];
|
1988 |
+
start = [ data.pageX, data.pageY ];
|
1989 |
+
|
1990 |
+
}).bind("touchmove"+current.mobileNamespace, function( event ) {
|
1991 |
+
data = event.originalEvent.touches[0];
|
1992 |
+
event.preventDefault();
|
1993 |
+
return false;
|
1994 |
+
}).bind("touchend"+current.mobileNamespace, function( event ) {
|
1995 |
+
var end = [ data.pageX, data.pageY ],
|
1996 |
+
diff = [ end[0]-start[0], end[1]-start[1] ];
|
1997 |
+
|
1998 |
+
if(Math.max(Math.abs(diff[0]), Math.abs(diff[1])) > 50) {
|
1999 |
+
diff = Math.abs(diff[0]) > Math.abs(diff[1]) ? diff[0] : diff[1];
|
2000 |
+
$(jmpress).jmpress(diff > 0 ? "prev" : "next");
|
2001 |
+
event.preventDefault();
|
2002 |
+
return false;
|
2003 |
+
}
|
2004 |
+
});
|
2005 |
+
});
|
2006 |
+
$jmpress('afterDeinit', function( nil, eventData ) {
|
2007 |
+
var settings = eventData.settings,
|
2008 |
+
current = eventData.current,
|
2009 |
+
jmpress = eventData.jmpress;
|
2010 |
+
$(settings.fullscreen ? document : jmpress).unbind(current.mobileNamespace);
|
2011 |
+
});
|
2012 |
+
|
2013 |
+
}(jQuery, document, window));
|
2014 |
+
/*
|
2015 |
+
* templates.js
|
2016 |
+
* The amazing template engine
|
2017 |
+
*/
|
2018 |
+
(function( $, document, window, undefined ) {
|
2019 |
+
|
2020 |
+
'use strict';
|
2021 |
+
var $jmpress = $.jmpress,
|
2022 |
+
templateFromParentIdent = "_template_",
|
2023 |
+
templateFromApplyIdent = "_applied_template_";
|
2024 |
+
|
2025 |
+
/* STATIC VARS */
|
2026 |
+
var templates = {};
|
2027 |
+
|
2028 |
+
/* FUNCTIONS */
|
2029 |
+
function addUndefined( target, values, prefix ) {
|
2030 |
+
for( var name in values ) {
|
2031 |
+
var targetName = name;
|
2032 |
+
if ( prefix ) {
|
2033 |
+
targetName = prefix + targetName.substr(0, 1).toUpperCase() + targetName.substr(1);
|
2034 |
+
}
|
2035 |
+
if ( $.isPlainObject(values[name]) ) {
|
2036 |
+
addUndefined( target, values[name], targetName );
|
2037 |
+
} else if( target[targetName] === undefined ) {
|
2038 |
+
target[targetName] = values[name];
|
2039 |
+
}
|
2040 |
+
}
|
2041 |
+
}
|
2042 |
+
function applyChildrenTemplates( children, templateChildren ) {
|
2043 |
+
if ($.isArray(templateChildren)) {
|
2044 |
+
if (templateChildren.length < children.length) {
|
2045 |
+
$.error("more nested steps than children in template");
|
2046 |
+
} else {
|
2047 |
+
children.each(function(idx, child) {
|
2048 |
+
child = $(child);
|
2049 |
+
var tmpl = child.data(templateFromParentIdent) || {};
|
2050 |
+
addUndefined(tmpl, templateChildren[idx]);
|
2051 |
+
child.data(templateFromParentIdent, tmpl);
|
2052 |
+
});
|
2053 |
+
}
|
2054 |
+
} else if($.isFunction(templateChildren)) {
|
2055 |
+
children.each(function(idx, child) {
|
2056 |
+
child = $(child);
|
2057 |
+
var tmpl = child.data(templateFromParentIdent) || {};
|
2058 |
+
addUndefined(tmpl, templateChildren(idx, child, children));
|
2059 |
+
child.data(templateFromParentIdent, tmpl);
|
2060 |
+
});
|
2061 |
+
} // TODO: else if(object)
|
2062 |
+
}
|
2063 |
+
function applyTemplate( data, element, template, eventData ) {
|
2064 |
+
if (template.children) {
|
2065 |
+
var children = element.children( eventData.settings.stepSelector );
|
2066 |
+
applyChildrenTemplates( children, template.children );
|
2067 |
+
}
|
2068 |
+
applyTemplateData( data, template );
|
2069 |
+
}
|
2070 |
+
function applyTemplateData( data, template ) {
|
2071 |
+
addUndefined(data, template);
|
2072 |
+
}
|
2073 |
+
|
2074 |
+
/* HOOKS */
|
2075 |
+
$jmpress("beforeInitStep", function( step, eventData ) {
|
2076 |
+
step = $(step);
|
2077 |
+
var data = eventData.data,
|
2078 |
+
templateFromAttr = data.template,
|
2079 |
+
templateFromApply = step.data(templateFromApplyIdent),
|
2080 |
+
templateFromParent = step.data(templateFromParentIdent);
|
2081 |
+
if(templateFromAttr) {
|
2082 |
+
$.each(templateFromAttr.split(" "), function(idx, tmpl) {
|
2083 |
+
var template = templates[tmpl];
|
2084 |
+
applyTemplate( data, step, template, eventData );
|
2085 |
+
});
|
2086 |
+
}
|
2087 |
+
if (templateFromApply) {
|
2088 |
+
applyTemplate( data, step, templateFromApply, eventData );
|
2089 |
+
}
|
2090 |
+
if (templateFromParent) {
|
2091 |
+
applyTemplate( data, step, templateFromParent, eventData );
|
2092 |
+
step.data(templateFromParentIdent, null);
|
2093 |
+
if(templateFromParent.template) {
|
2094 |
+
$.each(templateFromParent.template.split(" "), function(idx, tmpl) {
|
2095 |
+
var template = templates[tmpl];
|
2096 |
+
applyTemplate( data, step, template, eventData );
|
2097 |
+
});
|
2098 |
+
}
|
2099 |
+
}
|
2100 |
+
});
|
2101 |
+
$jmpress("beforeInit", function( nil, eventData ) {
|
2102 |
+
var data = $jmpress("dataset", this),
|
2103 |
+
dataTemplate = data.template,
|
2104 |
+
stepSelector = eventData.settings.stepSelector;
|
2105 |
+
if (dataTemplate) {
|
2106 |
+
var template = templates[dataTemplate];
|
2107 |
+
applyChildrenTemplates( $(this).find(stepSelector).filter(function() {
|
2108 |
+
return !$(this).parent().is(stepSelector);
|
2109 |
+
}), template.children );
|
2110 |
+
}
|
2111 |
+
});
|
2112 |
+
|
2113 |
+
/* EXPORTED FUNCTIONS */
|
2114 |
+
$jmpress("register", "template", function( name, tmpl ) {
|
2115 |
+
if (templates[name]) {
|
2116 |
+
templates[name] = $.extend(true, {}, templates[name], tmpl);
|
2117 |
+
} else {
|
2118 |
+
templates[name] = $.extend(true, {}, tmpl);
|
2119 |
+
}
|
2120 |
+
});
|
2121 |
+
$jmpress("register", "apply", function( selector, tmpl ) {
|
2122 |
+
if( !tmpl ) {
|
2123 |
+
// TODO ERROR because settings not found
|
2124 |
+
var stepSelector = $(this).jmpress("settings").stepSelector;
|
2125 |
+
applyChildrenTemplates( $(this).find(stepSelector).filter(function() {
|
2126 |
+
return !$(this).parent().is(stepSelector);
|
2127 |
+
}), selector );
|
2128 |
+
} else if($.isArray(tmpl)) {
|
2129 |
+
applyChildrenTemplates( $(selector), tmpl );
|
2130 |
+
} else {
|
2131 |
+
var template;
|
2132 |
+
if(typeof tmpl === "string") {
|
2133 |
+
template = templates[tmpl];
|
2134 |
+
} else {
|
2135 |
+
template = $.extend(true, {}, tmpl);
|
2136 |
+
}
|
2137 |
+
$(selector).each(function(idx, element) {
|
2138 |
+
element = $(element);
|
2139 |
+
var tmpl = element.data(templateFromApplyIdent) || {};
|
2140 |
+
addUndefined(tmpl, template);
|
2141 |
+
element.data(templateFromApplyIdent, tmpl);
|
2142 |
+
});
|
2143 |
+
}
|
2144 |
+
});
|
2145 |
+
|
2146 |
+
}(jQuery, document, window));
|
2147 |
+
/*
|
2148 |
+
* jqevents.js
|
2149 |
+
* Fires jQuery events
|
2150 |
+
*/
|
2151 |
+
(function( $, document, window, undefined ) {
|
2152 |
+
|
2153 |
+
'use strict';
|
2154 |
+
|
2155 |
+
/* HOOKS */
|
2156 |
+
// the events should not bubble up the tree
|
2157 |
+
// elsewise nested jmpress would cause buggy behavior
|
2158 |
+
$.jmpress("setActive", function( step, eventData ) {
|
2159 |
+
if(eventData.prevStep !== step) {
|
2160 |
+
$(step).triggerHandler("enterStep");
|
2161 |
+
}
|
2162 |
+
});
|
2163 |
+
$.jmpress("setInactive", function( step, eventData ) {
|
2164 |
+
if(eventData.nextStep !== step) {
|
2165 |
+
$(step).triggerHandler("leaveStep");
|
2166 |
+
}
|
2167 |
+
});
|
2168 |
+
|
2169 |
+
}(jQuery, document, window));
|
2170 |
+
/*
|
2171 |
+
* animation.js
|
2172 |
+
* Apply custom animations to steps
|
2173 |
+
*/
|
2174 |
+
(function( $, document, window, undefined ) {
|
2175 |
+
|
2176 |
+
'use strict';
|
2177 |
+
|
2178 |
+
function parseSubstepInfo(str) {
|
2179 |
+
var arr = str.split(" ");
|
2180 |
+
var className = arr[0];
|
2181 |
+
var config = { willClass: "will-"+className, doClass: "do-"+className, hasClass: "has-"+className };
|
2182 |
+
var state = "";
|
2183 |
+
for(var i = 1; i < arr.length; i++) {
|
2184 |
+
var s = arr[i];
|
2185 |
+
switch(state) {
|
2186 |
+
case "":
|
2187 |
+
if(s === "after") {
|
2188 |
+
state = "after";
|
2189 |
+
} else {
|
2190 |
+
$.warn("unknown keyword in '"+str+"'. '"+s+"' unknown.");
|
2191 |
+
}
|
2192 |
+
break;
|
2193 |
+
case "after":
|
2194 |
+
if(s.match(/^[1-9][0-9]*m?s?/)) {
|
2195 |
+
var value = parseFloat(s);
|
2196 |
+
if(s.indexOf("ms") !== -1) {
|
2197 |
+
value *= 1;
|
2198 |
+
} else if(s.indexOf("s") !== -1) {
|
2199 |
+
value *= 1000;
|
2200 |
+
} else if(s.indexOf("m") !== -1) {
|
2201 |
+
value *= 60000;
|
2202 |
+
}
|
2203 |
+
config.delay = value;
|
2204 |
+
} else {
|
2205 |
+
config.after = Array.prototype.slice.call(arr, i).join(" ");
|
2206 |
+
i = arr.length;
|
2207 |
+
}
|
2208 |
+
}
|
2209 |
+
}
|
2210 |
+
return config;
|
2211 |
+
}
|
2212 |
+
function find(array, selector, start, end) {
|
2213 |
+
end = end || (array.length - 1);
|
2214 |
+
start = start || 0;
|
2215 |
+
for(var i = start; i < end + 1; i++) {
|
2216 |
+
if($(array[i].element).is(selector)) {
|
2217 |
+
return i;
|
2218 |
+
}
|
2219 |
+
}
|
2220 |
+
}
|
2221 |
+
function addOn(list, substep, delay) {
|
2222 |
+
$.each(substep._on, function(idx, child) {
|
2223 |
+
list.push({substep: child.substep, delay: child.delay + delay});
|
2224 |
+
addOn(list, child.substep, child.delay + delay);
|
2225 |
+
});
|
2226 |
+
}
|
2227 |
+
$.jmpress("defaults").customAnimationDataAttribute = "jmpress";
|
2228 |
+
$.jmpress("afterInit", function( nil, eventData ) {
|
2229 |
+
eventData.current.animationTimeouts = [];
|
2230 |
+
eventData.current.animationCleanupWaiting = [];
|
2231 |
+
});
|
2232 |
+
$.jmpress("applyStep", function( step, eventData ) {
|
2233 |
+
// read custom animation from elements
|
2234 |
+
var substepsData = {};
|
2235 |
+
var listOfSubsteps = [];
|
2236 |
+
$(step).find("[data-"+eventData.settings.customAnimationDataAttribute+"]")
|
2237 |
+
.each(function(idx, element) {
|
2238 |
+
if($(element).closest(eventData.settings.stepSelector).is(step)) {
|
2239 |
+
listOfSubsteps.push({element: element});
|
2240 |
+
}
|
2241 |
+
});
|
2242 |
+
if(listOfSubsteps.length === 0) {
|
2243 |
+
return;
|
2244 |
+
}
|
2245 |
+
$.each(listOfSubsteps, function(idx, substep) {
|
2246 |
+
substep.info = parseSubstepInfo(
|
2247 |
+
$(substep.element).data(eventData.settings.customAnimationDataAttribute));
|
2248 |
+
$(substep.element).addClass(substep.info.willClass);
|
2249 |
+
substep._on = [];
|
2250 |
+
substep._after = null;
|
2251 |
+
});
|
2252 |
+
var current = {_after: undefined, _on: [], info: {}}; // virtual zero step
|
2253 |
+
$.each(listOfSubsteps, function(idx, substep) {
|
2254 |
+
var other = substep.info.after;
|
2255 |
+
if(other) {
|
2256 |
+
if(other === "step") {
|
2257 |
+
other = current;
|
2258 |
+
} else if(other === "prev") {
|
2259 |
+
other = listOfSubsteps[idx-1];
|
2260 |
+
} else {
|
2261 |
+
var index = find(listOfSubsteps, other, 0, idx - 1);
|
2262 |
+
if(index === undefined) {
|
2263 |
+
index = find(listOfSubsteps, other);
|
2264 |
+
}
|
2265 |
+
other = (index === undefined || index === idx) ? listOfSubsteps[idx-1] : listOfSubsteps[index];
|
2266 |
+
}
|
2267 |
+
} else {
|
2268 |
+
other = listOfSubsteps[idx-1];
|
2269 |
+
}
|
2270 |
+
if(other) {
|
2271 |
+
if(!substep.info.delay) {
|
2272 |
+
if(!other._after) {
|
2273 |
+
other._after = substep;
|
2274 |
+
return;
|
2275 |
+
}
|
2276 |
+
other = other._after;
|
2277 |
+
}
|
2278 |
+
other._on.push({substep: substep, delay: substep.info.delay || 0});
|
2279 |
+
}
|
2280 |
+
});
|
2281 |
+
if(current._after === undefined && current._on.length === 0) {
|
2282 |
+
var startStep = find(listOfSubsteps, eventData.stepData.startSubstep) || 0;
|
2283 |
+
current._after = listOfSubsteps[startStep];
|
2284 |
+
}
|
2285 |
+
var substepsInOrder = [];
|
2286 |
+
function findNextFunc(idx, item) {
|
2287 |
+
if(item.substep._after) {
|
2288 |
+
current = item.substep._after;
|
2289 |
+
return false;
|
2290 |
+
}
|
2291 |
+
}
|
2292 |
+
do {
|
2293 |
+
var substepList = [{substep: current, delay: 0}];
|
2294 |
+
addOn(substepList, current, 0);
|
2295 |
+
substepsInOrder.push(substepList);
|
2296 |
+
current = null;
|
2297 |
+
$.each(substepList, findNextFunc);
|
2298 |
+
} while(current);
|
2299 |
+
substepsData.list = substepsInOrder;
|
2300 |
+
$(step).data("substepsData", substepsData);
|
2301 |
+
});
|
2302 |
+
$.jmpress("unapplyStep", function( step, eventData ) {
|
2303 |
+
var substepsData = $(step).data("substepsData");
|
2304 |
+
if(substepsData) {
|
2305 |
+
$.each(substepsData.list, function(idx, activeSubsteps) {
|
2306 |
+
$.each(activeSubsteps, function(idx, substep) {
|
2307 |
+
if(substep.substep.info.willClass) {
|
2308 |
+
$(substep.substep.element).removeClass(substep.substep.info.willClass);
|
2309 |
+
}
|
2310 |
+
if(substep.substep.info.hasClass) {
|
2311 |
+
$(substep.substep.element).removeClass(substep.substep.info.hasClass);
|
2312 |
+
}
|
2313 |
+
if(substep.substep.info.doClass) {
|
2314 |
+
$(substep.substep.element).removeClass(substep.substep.info.doClass);
|
2315 |
+
}
|
2316 |
+
});
|
2317 |
+
});
|
2318 |
+
}
|
2319 |
+
});
|
2320 |
+
$.jmpress("setActive", function(step, eventData) {
|
2321 |
+
var substepsData = $(step).data("substepsData");
|
2322 |
+
if(!substepsData) {
|
2323 |
+
return;
|
2324 |
+
}
|
2325 |
+
if(eventData.substep === undefined) {
|
2326 |
+
eventData.substep =
|
2327 |
+
(eventData.reason === "prev" ?
|
2328 |
+
substepsData.list.length-1 :
|
2329 |
+
0
|
2330 |
+
);
|
2331 |
+
}
|
2332 |
+
var substep = eventData.substep;
|
2333 |
+
$.each(eventData.current.animationTimeouts, function(idx, timeout) {
|
2334 |
+
clearTimeout(timeout);
|
2335 |
+
});
|
2336 |
+
eventData.current.animationTimeouts = [];
|
2337 |
+
$.each(substepsData.list, function(idx, activeSubsteps) {
|
2338 |
+
var applyHas = idx < substep;
|
2339 |
+
var applyDo = idx <= substep;
|
2340 |
+
$.each(activeSubsteps, function(idx, substep) {
|
2341 |
+
if(substep.substep.info.hasClass) {
|
2342 |
+
$(substep.substep.element)[(applyHas?"add":"remove")+"Class"](substep.substep.info.hasClass);
|
2343 |
+
}
|
2344 |
+
function applyIt() {
|
2345 |
+
$(substep.substep.element).addClass(substep.substep.info.doClass);
|
2346 |
+
}
|
2347 |
+
if(applyDo && !applyHas && substep.delay && eventData.reason !== "prev") {
|
2348 |
+
if(substep.substep.info.doClass) {
|
2349 |
+
$(substep.substep.element).removeClass(substep.substep.info.doClass);
|
2350 |
+
eventData.current.animationTimeouts.push(setTimeout(applyIt, substep.delay));
|
2351 |
+
}
|
2352 |
+
} else {
|
2353 |
+
if(substep.substep.info.doClass) {
|
2354 |
+
$(substep.substep.element)[(applyDo?"add":"remove")+"Class"](substep.substep.info.doClass);
|
2355 |
+
}
|
2356 |
+
}
|
2357 |
+
});
|
2358 |
+
});
|
2359 |
+
});
|
2360 |
+
$.jmpress("setInactive", function(step, eventData) {
|
2361 |
+
if(eventData.nextStep === step) {
|
2362 |
+
return;
|
2363 |
+
}
|
2364 |
+
function cleanupAnimation( substepsData ) {
|
2365 |
+
$.each(substepsData.list, function(idx, activeSubsteps) {
|
2366 |
+
$.each(activeSubsteps, function(idx, substep) {
|
2367 |
+
if(substep.substep.info.hasClass) {
|
2368 |
+
$(substep.substep.element).removeClass(substep.substep.info.hasClass);
|
2369 |
+
}
|
2370 |
+
if(substep.substep.info.doClass) {
|
2371 |
+
$(substep.substep.element).removeClass(substep.substep.info.doClass);
|
2372 |
+
}
|
2373 |
+
});
|
2374 |
+
});
|
2375 |
+
}
|
2376 |
+
$.each(eventData.current.animationCleanupWaiting, function(idx, item) {
|
2377 |
+
cleanupAnimation(item);
|
2378 |
+
});
|
2379 |
+
eventData.current.animationCleanupWaiting = [];
|
2380 |
+
var substepsData = $(step).data("substepsData");
|
2381 |
+
if(substepsData) {
|
2382 |
+
eventData.current.animationCleanupWaiting.push( substepsData );
|
2383 |
+
}
|
2384 |
+
});
|
2385 |
+
$.jmpress("selectNext", function( step, eventData ) {
|
2386 |
+
if(eventData.substep === undefined) {
|
2387 |
+
return;
|
2388 |
+
}
|
2389 |
+
var substepsData = $(step).data("substepsData");
|
2390 |
+
if(!substepsData) {
|
2391 |
+
return;
|
2392 |
+
}
|
2393 |
+
if(eventData.substep < substepsData.list.length-1) {
|
2394 |
+
return {step: step, substep: eventData.substep+1};
|
2395 |
+
}
|
2396 |
+
});
|
2397 |
+
$.jmpress("selectPrev", function( step, eventData ) {
|
2398 |
+
if(eventData.substep === undefined) {
|
2399 |
+
return;
|
2400 |
+
}
|
2401 |
+
var substepsData = $(step).data("substepsData");
|
2402 |
+
if(!substepsData) {
|
2403 |
+
return;
|
2404 |
+
}
|
2405 |
+
if(eventData.substep > 0) {
|
2406 |
+
return {step: step, substep: eventData.substep-1};
|
2407 |
+
}
|
2408 |
+
});
|
2409 |
+
|
2410 |
+
}(jQuery, document, window));
|
2411 |
+
/*!
|
2412 |
+
* plugin for jmpress.js v0.4.5
|
2413 |
+
*
|
2414 |
+
* Copyright 2013 Kyle Robinson Young @shama & Tobias Koppers @sokra
|
2415 |
+
* Licensed MIT
|
2416 |
+
* http://www.opensource.org/licenses/mit-license.php
|
2417 |
+
*//*
|
2418 |
+
* jmpress.toggle plugin
|
2419 |
+
* For binding a key to toggle de/initialization of jmpress.js.
|
2420 |
+
*/
|
2421 |
+
(function( $, document, window, undefined ) {
|
2422 |
+
'use strict';
|
2423 |
+
$.jmpress("register", "toggle", function( key, config, initial ) {
|
2424 |
+
var jmpress = this;
|
2425 |
+
$(document).bind("keydown", function( event ) {
|
2426 |
+
if ( event.keyCode === key ) {
|
2427 |
+
if ($(jmpress).jmpress("initialized")) {
|
2428 |
+
$(jmpress).jmpress("deinit");
|
2429 |
+
} else {
|
2430 |
+
$(jmpress).jmpress(config);
|
2431 |
+
}
|
2432 |
+
}
|
2433 |
+
});
|
2434 |
+
if ( initial ) {
|
2435 |
+
$(jmpress).jmpress(config);
|
2436 |
+
}
|
2437 |
+
});
|
2438 |
+
}(jQuery, document, window));
|
2439 |
+
|
2440 |
+
/*
|
2441 |
+
* jmpress.secondary plugin
|
2442 |
+
* Apply a secondary animation when step is selected.
|
2443 |
+
*/
|
2444 |
+
(function( $, document, window, undefined ) {
|
2445 |
+
'use strict';
|
2446 |
+
$.jmpress("initStep", function( step, eventData ) {
|
2447 |
+
for(var name in eventData.data) {
|
2448 |
+
if(name.indexOf("secondary") === 0) {
|
2449 |
+
eventData.stepData[name] = eventData.data[name];
|
2450 |
+
}
|
2451 |
+
}
|
2452 |
+
});
|
2453 |
+
function exchangeIf(childStepData, condition, step) {
|
2454 |
+
if(childStepData.secondary &&
|
2455 |
+
childStepData.secondary.split(" ").indexOf(condition) !== -1) {
|
2456 |
+
for(var name in childStepData) {
|
2457 |
+
if(name.length > 9 && name.indexOf("secondary") === 0) {
|
2458 |
+
var tmp = childStepData[name];
|
2459 |
+
var normal = name.substr(9);
|
2460 |
+
normal = normal.substr(0, 1).toLowerCase() + normal.substr(1);
|
2461 |
+
childStepData[name] = childStepData[normal];
|
2462 |
+
childStepData[normal] = tmp;
|
2463 |
+
}
|
2464 |
+
}
|
2465 |
+
$(this).jmpress("reapply", $(step));
|
2466 |
+
}
|
2467 |
+
}
|
2468 |
+
$.jmpress("beforeActive", function( step, eventData ) {
|
2469 |
+
exchangeIf.call(eventData.jmpress, $(step).data("stepData"), "self", step);
|
2470 |
+
var parent = $(step).parent();
|
2471 |
+
$(parent)
|
2472 |
+
.children(eventData.settings.stepSelector)
|
2473 |
+
.each(function(idx, child) {
|
2474 |
+
var childStepData = $(child).data("stepData");
|
2475 |
+
exchangeIf.call(eventData.jmpress, childStepData, "siblings", child);
|
2476 |
+
});
|
2477 |
+
function grandchildrenFunc(idx, child) {
|
2478 |
+
var childStepData = $(child).data("stepData");
|
2479 |
+
exchangeIf.call(eventData.jmpress, childStepData, "grandchildren", child);
|
2480 |
+
}
|
2481 |
+
for(var i = 1; i < eventData.parents.length; i++) {
|
2482 |
+
$(eventData.parents[i])
|
2483 |
+
.children(eventData.settings.stepSelector)
|
2484 |
+
.each();
|
2485 |
+
}
|
2486 |
+
});
|
2487 |
+
$.jmpress("setInactive", function( step, eventData ) {
|
2488 |
+
exchangeIf.call(eventData.jmpress, $(step).data("stepData"), "self", step);
|
2489 |
+
var parent = $(step).parent();
|
2490 |
+
$(parent)
|
2491 |
+
.children(eventData.settings.stepSelector)
|
2492 |
+
.each(function(idx, child) {
|
2493 |
+
var childStepData = $(child).data("stepData");
|
2494 |
+
exchangeIf.call(eventData.jmpress, childStepData, "siblings", child);
|
2495 |
+
});
|
2496 |
+
function grandchildrenFunc(idx, child) {
|
2497 |
+
var childStepData = $(child).data("stepData");
|
2498 |
+
exchangeIf.call(eventData.jmpress, childStepData, "grandchildren", child);
|
2499 |
+
}
|
2500 |
+
for(var i = 1; i < eventData.parents.length; i++) {
|
2501 |
+
$(eventData.parents[i])
|
2502 |
+
.children(eventData.settings.stepSelector)
|
2503 |
+
.each(grandchildrenFunc);
|
2504 |
+
}
|
2505 |
+
});
|
2506 |
+
}(jQuery, document, window));
|
2507 |
+
|
2508 |
+
/*
|
2509 |
+
* jmpress.duration plugin
|
2510 |
+
* For auto advancing steps after a given duration and optionally displaying a
|
2511 |
+
* progress bar.
|
2512 |
+
*/
|
2513 |
+
(function( $, document, window, undefined ) {
|
2514 |
+
'use strict';
|
2515 |
+
|
2516 |
+
$.jmpress("defaults").duration = {
|
2517 |
+
defaultValue: -1
|
2518 |
+
,defaultAction: "next"
|
2519 |
+
,barSelector: undefined
|
2520 |
+
,barProperty: "width"
|
2521 |
+
,barPropertyStart: "0"
|
2522 |
+
,barPropertyEnd: "100%"
|
2523 |
+
};
|
2524 |
+
$.jmpress("initStep", function( step, eventData ) {
|
2525 |
+
eventData.stepData.duration = eventData.data.duration && parseInt(eventData.data.duration, 10);
|
2526 |
+
eventData.stepData.durationAction = eventData.data.durationAction;
|
2527 |
+
});
|
2528 |
+
$.jmpress("setInactive", function( step, eventData ) {
|
2529 |
+
var settings = eventData.settings,
|
2530 |
+
durationSettings = settings.duration,
|
2531 |
+
current = eventData.current;
|
2532 |
+
var dur = eventData.stepData.duration || durationSettings.defaultValue;
|
2533 |
+
if( current.durationTimeout ) {
|
2534 |
+
if( durationSettings.barSelector ) {
|
2535 |
+
var css = {
|
2536 |
+
transitionProperty: durationSettings.barProperty
|
2537 |
+
,transitionDuration: '0'
|
2538 |
+
,transitionDelay: '0'
|
2539 |
+
,transitionTimingFunction: 'linear'
|
2540 |
+
};
|
2541 |
+
css[durationSettings.barProperty] = durationSettings.barPropertyStart;
|
2542 |
+
var bars = $(durationSettings.barSelector);
|
2543 |
+
$.jmpress("css", bars, css);
|
2544 |
+
bars.each(function(idx, element) {
|
2545 |
+
var next = $(element).next();
|
2546 |
+
var parent = $(element).parent();
|
2547 |
+
$(element).detach();
|
2548 |
+
if(next.length) {
|
2549 |
+
next.insertBefore(element);
|
2550 |
+
} else {
|
2551 |
+
parent.append(element);
|
2552 |
+
}
|
2553 |
+
});
|
2554 |
+
}
|
2555 |
+
clearTimeout(current.durationTimeout);
|
2556 |
+
delete current.durationTimeout;
|
2557 |
+
}
|
2558 |
+
});
|
2559 |
+
$.jmpress("setActive", function( step, eventData ) {
|
2560 |
+
var settings = eventData.settings,
|
2561 |
+
durationSettings = settings.duration,
|
2562 |
+
current = eventData.current;
|
2563 |
+
var dur = eventData.stepData.duration || durationSettings.defaultValue;
|
2564 |
+
if( dur && dur > 0 ) {
|
2565 |
+
if( durationSettings.barSelector ) {
|
2566 |
+
var css = {
|
2567 |
+
transitionProperty: durationSettings.barProperty
|
2568 |
+
,transitionDuration: (dur-settings.transitionDuration*2/3-100)+"ms"
|
2569 |
+
,transitionDelay: (settings.transitionDuration*2/3)+'ms'
|
2570 |
+
,transitionTimingFunction: 'linear'
|
2571 |
+
};
|
2572 |
+
css[durationSettings.barProperty] = durationSettings.barPropertyEnd;
|
2573 |
+
$.jmpress("css", $(durationSettings.barSelector), css);
|
2574 |
+
}
|
2575 |
+
var jmpress = this;
|
2576 |
+
if(current.durationTimeout) {
|
2577 |
+
clearTimeout(current.durationTimeout);
|
2578 |
+
current.durationTimeout = undefined;
|
2579 |
+
}
|
2580 |
+
current.durationTimeout = setTimeout(function() {
|
2581 |
+
var action = eventData.stepData.durationAction || durationSettings.defaultAction;
|
2582 |
+
$(jmpress).jmpress(action);
|
2583 |
+
}, dur);
|
2584 |
+
}
|
2585 |
+
});
|
2586 |
+
}(jQuery, document, window));
|
2587 |
+
|
2588 |
+
/*
|
2589 |
+
* jmpress.presentation-mode plugin
|
2590 |
+
* Display a window for the presenter with notes and a control and view of the
|
2591 |
+
* presentation
|
2592 |
+
*/
|
2593 |
+
(function( $, document, window, undefined ) {
|
2594 |
+
|
2595 |
+
'use strict';
|
2596 |
+
var $jmpress = $.jmpress;
|
2597 |
+
|
2598 |
+
var PREFIX = "jmpress-presentation-";
|
2599 |
+
|
2600 |
+
/* FUNCTIONS */
|
2601 |
+
function randomString() {
|
2602 |
+
return "" + Math.round(Math.random() * 100000, 0);
|
2603 |
+
}
|
2604 |
+
|
2605 |
+
/* DEFAULTS */
|
2606 |
+
$jmpress("defaults").presentationMode = {
|
2607 |
+
use: true,
|
2608 |
+
url: "presentation-screen.html",
|
2609 |
+
notesUrl: false,
|
2610 |
+
transferredValues: ["userZoom", "userTranslateX", "userTranslateY"]
|
2611 |
+
};
|
2612 |
+
$jmpress("defaults").keyboard.keys[80] = "presentationPopup"; // p key
|
2613 |
+
|
2614 |
+
/* HOOKS */
|
2615 |
+
$jmpress("afterInit", function( nil, eventData) {
|
2616 |
+
var current = eventData.current;
|
2617 |
+
|
2618 |
+
current.selectMessageListeners = [];
|
2619 |
+
|
2620 |
+
if(eventData.settings.presentationMode.use) {
|
2621 |
+
|
2622 |
+
window.addEventListener("message", function(event) {
|
2623 |
+
// We do not test orgin, because we want to accept messages
|
2624 |
+
// from all orgins
|
2625 |
+
try {
|
2626 |
+
if(typeof event.data !== "string" || event.data.indexOf(PREFIX) !== 0) {
|
2627 |
+
return;
|
2628 |
+
}
|
2629 |
+
var json = JSON.parse(event.data.slice(PREFIX.length));
|
2630 |
+
switch(json.type) {
|
2631 |
+
case "select":
|
2632 |
+
$.each(eventData.settings.presentationMode.transferredValues, function(idx, name) {
|
2633 |
+
eventData.current[name] = json[name];
|
2634 |
+
});
|
2635 |
+
if(/[a-z0-9\-]+/i.test(json.targetId) && typeof json.substep in {number:1,undefined:1}) {
|
2636 |
+
$(eventData.jmpress).jmpress("select", {step: "#"+json.targetId, substep: json.substep}, json.reason);
|
2637 |
+
} else {
|
2638 |
+
$.error("For security reasons the targetId must match /[a-z0-9\\-]+/i and substep must be a number.");
|
2639 |
+
}
|
2640 |
+
break;
|
2641 |
+
case "listen":
|
2642 |
+
current.selectMessageListeners.push(event.source);
|
2643 |
+
break;
|
2644 |
+
case "ok":
|
2645 |
+
clearTimeout(current.presentationPopupTimeout);
|
2646 |
+
break;
|
2647 |
+
case "read":
|
2648 |
+
try {
|
2649 |
+
event.source.postMessage(PREFIX + JSON.stringify({type: "url", url: window.location.href, notesUrl: eventData.settings.presentationMode.notesUrl}), "*");
|
2650 |
+
} catch(e) {
|
2651 |
+
$.error("Cannot post message to source: " + e);
|
2652 |
+
}
|
2653 |
+
break;
|
2654 |
+
default:
|
2655 |
+
throw "Unknown message type: " + json.type;
|
2656 |
+
}
|
2657 |
+
} catch(e) {
|
2658 |
+
$.error("Received message is malformed: " + e);
|
2659 |
+
}
|
2660 |
+
});
|
2661 |
+
try {
|
2662 |
+
if(window.parent && window.parent !== window) {
|
2663 |
+
window.parent.postMessage(PREFIX + JSON.stringify({
|
2664 |
+
"type": "afterInit"
|
2665 |
+
}), "*");
|
2666 |
+
}
|
2667 |
+
} catch(e) {
|
2668 |
+
$.error("Cannot post message to parent: " + e);
|
2669 |
+
}
|
2670 |
+
}
|
2671 |
+
});
|
2672 |
+
$jmpress("afterDeinit", function( nil, eventData) {
|
2673 |
+
if(eventData.settings.presentationMode.use) {
|
2674 |
+
try {
|
2675 |
+
if(window.parent && window.parent !== window) {
|
2676 |
+
window.parent.postMessage(PREFIX + JSON.stringify({
|
2677 |
+
"type": "afterDeinit"
|
2678 |
+
}), "*");
|
2679 |
+
}
|
2680 |
+
} catch(e) {
|
2681 |
+
$.error("Cannot post message to parent: " + e);
|
2682 |
+
}
|
2683 |
+
}
|
2684 |
+
});
|
2685 |
+
$jmpress("setActive", function( step, eventData) {
|
2686 |
+
var stepId = $(eventData.delegatedFrom).attr("id"),
|
2687 |
+
substep = eventData.substep,
|
2688 |
+
reason = eventData.reason;
|
2689 |
+
$.each(eventData.current.selectMessageListeners, function(idx, listener) {
|
2690 |
+
try {
|
2691 |
+
var msg = {
|
2692 |
+
"type": "select",
|
2693 |
+
"targetId": stepId,
|
2694 |
+
"substep": substep,
|
2695 |
+
"reason": reason
|
2696 |
+
};
|
2697 |
+
$.each(eventData.settings.presentationMode.transferredValues, function(idx, name) {
|
2698 |
+
msg[name] = eventData.current[name];
|
2699 |
+
});
|
2700 |
+
listener.postMessage(PREFIX + JSON.stringify(msg), "*");
|
2701 |
+
} catch(e) {
|
2702 |
+
$.error("Cannot post message to listener: " + e);
|
2703 |
+
}
|
2704 |
+
});
|
2705 |
+
});
|
2706 |
+
$jmpress("register", "presentationPopup", function() {
|
2707 |
+
function trySend() {
|
2708 |
+
jmpress.jmpress("current").presentationPopupTimeout = setTimeout(trySend, 100);
|
2709 |
+
try {
|
2710 |
+
popup.postMessage(PREFIX + JSON.stringify({type: "url", url: window.location.href, notesUrl: jmpress.jmpress("settings").presentationMode.notesUrl}), "*");
|
2711 |
+
} catch(e) {
|
2712 |
+
}
|
2713 |
+
}
|
2714 |
+
var jmpress = $(this),
|
2715 |
+
popup;
|
2716 |
+
if(jmpress.jmpress("settings").presentationMode.use) {
|
2717 |
+
popup = window.open($(this).jmpress("settings").presentationMode.url);
|
2718 |
+
jmpress.jmpress("current").presentationPopupTimeout = setTimeout(trySend, 100);
|
2719 |
+
}
|
2720 |
+
});
|
2721 |
+
}(jQuery, document, window));
|
modules/shortcodes/js/jmpress.min.js
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* jmpress.js v0.4.5
|
3 |
+
* http://jmpressjs.github.com/jmpress.js
|
4 |
+
*
|
5 |
+
* A jQuery plugin to build a website on the infinite canvas.
|
6 |
+
*
|
7 |
+
* Copyright 2013 Kyle Robinson Young @shama & Tobias Koppers @sokra
|
8 |
+
* Licensed MIT
|
9 |
+
* http://www.opensource.org/licenses/mit-license.php
|
10 |
+
*
|
11 |
+
* Based on the foundation laid by Bartek Szopka @bartaz
|
12 |
+
*/(function(e,t,s,a){"use strict";function r(e){if(e){var t=1+e.substr(1).search(/[A-Z]/),s=e.substr(0,t).toLowerCase(),a=e.substr(t).toLowerCase();return"-"+s+"-"+a}}function n(e){return e?e+",":""}function i(e){return e.length>0?e:null}function o(r){function n(t,s){var a=p(t),r={oldStyle:e(t).attr("style")||""},n={data:a,stepData:r};f.call(this,"beforeInitStep",e(t),n),r.delegate=a.delegate,f.call(this,"initStep",e(t),n),e(t).data("stepData",r),e(t).attr("id")||e(t).attr("id","step-"+(s+1)),f.call(this,"applyStep",e(t),n)}function o(t){var s=e(t).data("stepData");e(t).attr("style",s.oldStyle),f.call(this,"unapplyStep",e(t),{stepData:s})}function c(t){f.call(this,"unapplyStep",e(t),{stepData:t.data("stepData")}),f.call(this,"applyStep",e(t),{stepData:t.data("stepData")})}function l(){O&&f.call(this,"setInactive",O,{stepData:e(O).data("stepData"),reason:"deinit"}),Y.jmpressClass&&e(I).removeClass(Y.jmpressClass),f.call(this,"beforeDeinit",e(this),{}),e(A.stepSelector,I).each(function(){o.call(I,this)}),k.attr("style",Z.container),A.fullscreen&&e("html").attr("style",""),z.attr("style",Z.area),e(X).children().each(function(){I.append(e(this))}),A.fullscreen?X.remove():(X.remove(),z.remove()),f.call(this,"afterDeinit",e(this),{}),e(I).data("jmpressmethods",!1)}function f(t,s,a){a.settings=A,a.current=Y,a.container=k,a.parents=s?d(s):null,a.current=Y,a.jmpress=this;var r={};return e.each(A[t],function(e,t){r.value=t.call(I,s,a)||r.value}),r.value}function d(t){return e(t).parentsUntil(I).not(I).filter(A.stepSelector)}function v(e){return g({step:O,substep:F},e)}function g(t,s){var r;if(e.isPlainObject(t)&&(r=t.substep,t=t.step),"string"==typeof t&&(t=I.find(t).first()),!t||!e(t).data("stepData"))return!1;b.call(this);var n=e(t).data("stepData"),o=!1;if(f.call(this,"beforeChange",t,{stepData:n,reason:s,cancel:function(){o=!0}}),o)return a;var c={},l=t;e(t).data("stepData").delegate&&(l=i(e(t).parentsUntil(I).filter(A.stepSelector).filter(n.delegate))||i(e(t).near(n.delegate))||i(e(t).near(n.delegate,!0))||i(e(n.delegate,I)),l?n=l.data("stepData"):l=t),Q&&f.call(this,"setInactive",Q,{stepData:e(Q).data("stepData"),delegatedFrom:O,reason:s,target:c,nextStep:l,nextSubstep:r,nextStepData:n});var u={stepData:n,delegatedFrom:t,reason:s,target:c,substep:r,prevStep:Q,prevSubstep:F,prevStepData:Q&&e(Q).data("stepData")};return f.call(this,"beforeActive",l,u),f.call(this,"setActive",l,u),Y.jmpressClass&&e(I).removeClass(Y.jmpressClass),e(I).addClass(Y.jmpressClass="step-"+e(l).attr("id")),Y.jmpressDelegatedClass&&e(I).removeClass(Y.jmpressDelegatedClass),e(I).addClass(Y.jmpressDelegatedClass="delegating-step-"+e(t).attr("id")),f.call(this,"applyTarget",l,e.extend({canvas:X,area:z,beforeActive:Q},u)),O=t,F=u.substep,Q=l,Y.idleTimeout&&clearTimeout(Y.idleTimeout),Y.idleTimeout=setTimeout(function(){f.call(this,"idle",l,u)},Math.max(1,A.transitionDuration-100)),l}function b(){(function t(){function a(){(0!==e(k).scrollTop()||0!==e(k).scrollLeft())&&t()}if("BODY"===e(k)[0].tagName)try{s.scrollTo(0,0)}catch(r){}e(k).scrollTop(0),e(k).scrollLeft(0),setTimeout(a,1),setTimeout(a,10),setTimeout(a,100),setTimeout(a,200),setTimeout(a,400)})()}function y(e){return g.call(this,e,"jump")}function j(){return g.call(this,f.call(this,"selectNext",O,{stepData:e(O).data("stepData"),substep:F}),"next")}function D(){return g.call(this,f.call(this,"selectPrev",O,{stepData:e(O).data("stepData"),substep:F}),"prev")}function S(){return g.call(this,f.call(this,"selectHome",O,{stepData:e(O).data("stepData")}),"home")}function x(){return g.call(this,f.call(this,"selectEnd",O,{stepData:e(O).data("stepData")}),"end")}function w(t){return u(X,t||{}),e(X)}function C(){return Q&&e(Q)}function T(t,s,r){return h[t]?f.call(this,t,s,r):(e.error("callback "+t+" is not registered."),a)}function M(){var e=navigator.userAgent.toLowerCase();return-1===e.search(/(iphone)|(ipod)|(android)/)||-1!==e.search(/(chrome)/)}r=e.extend(!0,{},r||{});var P={},N=null;for(N in h)P[N]=e.isFunction(r[N])?[r[N]]:r[N],r[N]=[];var A=e.extend(!0,{},m,r);for(N in h)P[N]&&Array.prototype.push.apply(A[N],P[N]);var I=e(this),k=null,z=null,Z={container:"",area:""},X=null,Y=null,O=!1,F=null,Q=!1;if(I.data("jmpressmethods",{select:g,reselect:v,scrollFix:b,goTo:y,next:j,prev:D,home:S,end:x,canvas:w,container:function(){return k},settings:function(){return A},active:C,current:function(){return Y},fire:T,init:function(t){n.call(this,e(t),Y.nextIdNumber++)},deinit:function(t){t?o.call(this,e(t)):l.call(this)},reapply:c}),M()===!1)return A.notSupportedClass&&I.addClass(A.notSupportedClass),a;A.notSupportedClass&&I.removeClass(A.notSupportedClass);var E=e(A.stepSelector,I);k=I,z=e("<div />"),X=e("<div />"),e(I).children().filter(E).each(function(){X.append(e(this))}),A.fullscreen&&(k=e("body"),e("html").css({overflow:"hidden"}),z=I),Z.area=z.attr("style")||"",Z.container=k.attr("style")||"",A.fullscreen?(k.css({height:"100%"}),I.append(X)):(k.css({position:"relative"}),z.append(X),I.append(z)),e(k).addClass(A.containerClass),e(z).addClass(A.areaClass),e(X).addClass(A.canvasClass),t.documentElement.style.height="100%",k.css({overflow:"hidden"});var L={position:"absolute",transitionDuration:"0s"};L=e.extend({},A.animation,L),u(z,L),u(z,{top:"50%",left:"50%",perspective:"1000px"}),u(X,L),Y={},f.call(this,"beforeInit",null,{}),E.each(function(e){n.call(I,this,e)}),Y.nextIdNumber=E.length,f.call(this,"afterInit",null,{}),g.call(this,f.call(this,"selectInitialStep","init",{})),A.initClass&&e(E).removeClass(A.initClass)}function c(){return m}function l(t,s){e.isFunction(s)?g[t]?e.error("function "+t+" is already registered."):g[t]=s:h[t]?e.error("callback "+t+" is already registered."):(h[t]=1,m[t]=[])}function u(t,s){var a,r,n={};for(a in s)s.hasOwnProperty(a)&&(r=d(a),null!==r&&(n[r]=s[a]));return e(t).css(n),t}function p(t){function s(e){e=e.split("-");for(var t=1;e.length>t;t++)e[t]=e[t].substr(0,1).toUpperCase()+e[t].substr(1);return e.join("")}if(e(t)[0].dataset)return e.extend({},e(t)[0].dataset);var a={},r=e(t)[0].attributes;return e.each(r,function(e,t){"data-"===t.nodeName.substr(0,5)&&(a[s(t.nodeName.substr(5))]=t.nodeValue)}),a}function f(){return!!e(this).data("jmpressmethods")}var d=function(){var e=t.createElement("dummy").style,s="Webkit Moz O ms Khtml".split(" "),r={};return function(t){if(r[t]===a){var n=t.charAt(0).toUpperCase()+t.substr(1),i=(t+" "+s.join(n+" ")+n).split(" ");r[t]=null;for(var o in i)if(e[i[o]]!==a){r[t]=i[o];break}}return r[t]}}(),m={stepSelector:".step",containerClass:"",canvasClass:"",areaClass:"",notSupportedClass:"not-supported",fullscreen:!0,animation:{transformOrigin:"top left",transitionProperty:n(r(d("transform")))+n(r(d("perspective")))+"opacity",transitionDuration:"1s",transitionDelay:"500ms",transitionTimingFunction:"ease-in-out",transformStyle:"preserve-3d"},transitionDuration:1500},h={beforeChange:1,beforeInitStep:1,initStep:1,beforeInit:1,afterInit:1,beforeDeinit:1,afterDeinit:1,applyStep:1,unapplyStep:1,setInactive:1,beforeActive:1,setActive:1,selectInitialStep:1,selectPrev:1,selectNext:1,selectHome:1,selectEnd:1,idle:1,applyTarget:1};for(var v in h)m[v]=[];var g={init:o,initialized:f,deinit:function(){},css:u,pfx:d,defaults:c,register:l,dataset:p};e.fn.jmpress=function(t){function s(){var s=e(this).data("jmpressmethods");if(s&&s[t])return s[t].apply(this,Array.prototype.slice.call(arguments,1));if(g[t])return g[t].apply(this,Array.prototype.slice.call(arguments,1));if(h[t]&&s){var a=s.settings(),r=Array.prototype.slice.call(arguments,1)[0];e.isFunction(r)&&(a[t]=a[t]||[],a[t].push(r))}else{if("object"==typeof t||!t)return o.apply(this,arguments);e.error("Method "+t+" does not exist on jQuery.jmpress")}return this}var a,r=arguments;return e(this).each(function(e,t){a=s.apply(t,r)}),a},e.extend({jmpress:function(t){if(g[t])return g[t].apply(this,Array.prototype.slice.call(arguments,1));if(h[t]){var s=Array.prototype.slice.call(arguments,1)[0];e.isFunction(s)?m[t].push(s):e.error("Second parameter should be a function: $.jmpress( callbackName, callbackFunction )")}else e.error("Method "+t+" does not exist on jQuery.jmpress")}})})(jQuery,document,window),function(e){"use strict";function t(t,s,a,r){var n;return t.each(function(t,i){return r&&(n=s(i,a,r))?!1:e(i).is(a)?(n=i,!1):!r&&(n=s(i,a,r))?!1:undefined}),n}function s(a,r,n){var i=e(a).children();return n&&(i=e(i.get().reverse())),t(i,s,r,n)}function a(a,r,n){return t(e(a)[n?"prevAll":"nextAll"](),s,r,n)}function r(t,s,r){var n,i=e(t).parents();return i=e(i.get()),e.each(i.get(),function(t,i){return r&&e(i).is(s)?(n=i,!1):(n=a(i,s,r),n?!1:undefined)}),n}e.fn.near=function(t,n){var i=[];return e(this).each(function(e,o){var c=(n?!1:s(o,t,n))||a(o,t,n)||r(o,t,n);c&&i.push(c)}),e(i)}}(jQuery,document,window),function(e,t,s,a){"use strict";function r(e){return Math.round(1e4*e)/1e4+""}var n={3:{transform:function(t,s){var a="translate(-50%,-50%)";e.each(s,function(e,t){var s,n=["X","Y","Z"];if("translate"===t[0])a+=" translate3d("+r(t[1]||0)+"px,"+r(t[2]||0)+"px,"+r(t[3]||0)+"px)";else if("rotate"===t[0]){var i=t[4]?[1,2,3]:[3,2,1];for(s=0;3>s;s++)a+=" rotate"+n[i[s]-1]+"("+r(t[i[s]]||0)+"deg)"}else if("scale"===t[0])for(s=0;3>s;s++)a+=" scale"+n[s]+"("+r(t[s+1]||1)+")"}),e.jmpress("css",t,e.extend({},{transform:a}))}},2:{transform:function(t,s){var a="translate(-50%,-50%)";e.each(s,function(e,t){var s=["X","Y"];if("translate"===t[0])a+=" translate("+r(t[1]||0)+"px,"+r(t[2]||0)+"px)";else if("rotate"===t[0])a+=" rotate("+r(t[3]||0)+"deg)";else if("scale"===t[0])for(var n=0;2>n;n++)a+=" scale"+s[n]+"("+r(t[n+1]||1)+")"}),e.jmpress("css",t,e.extend({},{transform:a}))}},1:{transform:function(t,s){var a={top:0,left:0};e.each(s,function(e,t){"translate"===t[0]&&(a.left=Math.round(t[1]||0)+"px",a.top=Math.round(t[2]||0)+"px")}),t.animate(a,1e3)}}},i=function(){return e.jmpress("pfx","perspective")?n[3]:e.jmpress("pfx","transform")?n[2]:n[1]}();e.jmpress("defaults").reasonableAnimation={},e.jmpress("initStep",function(t,s){var a=s.data,r=s.stepData,n=parseFloat;e.extend(r,{x:n(a.x)||0,y:n(a.y)||0,z:n(a.z)||0,r:n(a.r)||0,phi:n(a.phi)||0,rotate:n(a.rotate)||0,rotateX:n(a.rotateX)||0,rotateY:n(a.rotateY)||0,rotateZ:n(a.rotateZ)||0,revertRotate:!1,scale:n(a.scale)||1,scaleX:n(a.scaleX)||!1,scaleY:n(a.scaleY)||!1,scaleZ:n(a.scaleZ)||1})}),e.jmpress("afterInit",function(t,s){var a=s.settings.stepSelector,r=s.current;r.perspectiveScale=1,r.maxNestedDepth=0;for(var n=e(s.jmpress).find(a).children(a);n.length;)r.maxNestedDepth++,n=n.children(a)}),e.jmpress("applyStep",function(t,s){e.jmpress("css",e(t),{position:"absolute",transformStyle:"preserve-3d"}),s.parents.length>0&&e.jmpress("css",e(t),{top:"50%",left:"50%"});var a=s.stepData,r=[["translate",a.x||a.r*Math.sin(a.phi*Math.PI/180),a.y||-a.r*Math.cos(a.phi*Math.PI/180),a.z],["rotate",a.rotateX,a.rotateY,a.rotateZ||a.rotate,!0],["scale",a.scaleX||a.scale,a.scaleY||a.scale,a.scaleZ||a.scale]];i.transform(t,r)}),e.jmpress("setActive",function(t,s){var r=s.target,n=s.stepData,i=r.transform=[];r.perspectiveScale=1;for(var o=s.current.maxNestedDepth;o>(s.parents.length||0);o--)i.push(["scale"],["rotate"],["translate"]);i.push(["scale",1/(n.scaleX||n.scale),1/(n.scaleY||n.scale),1/n.scaleZ]),i.push(["rotate",-n.rotateX,-n.rotateY,-(n.rotateZ||n.rotate)]),i.push(["translate",-(n.x||n.r*Math.sin(n.phi*Math.PI/180)),-(n.y||-n.r*Math.cos(n.phi*Math.PI/180)),-n.z]),r.perspectiveScale*=n.scaleX||n.scale,e.each(s.parents,function(t,s){var a=e(s).data("stepData");i.push(["scale",1/(a.scaleX||a.scale),1/(a.scaleY||a.scale),1/a.scaleZ]),i.push(["rotate",-a.rotateX,-a.rotateY,-(a.rotateZ||a.rotate)]),i.push(["translate",-(a.x||a.r*Math.sin(a.phi*Math.PI/180)),-(a.y||-a.r*Math.cos(a.phi*Math.PI/180)),-a.z]),r.perspectiveScale*=a.scaleX||a.scale}),e.each(i,function(e,t){function r(r){s.current["rotate"+r+"-"+e]===a&&(s.current["rotate"+r+"-"+e]=t[r]||0);var n=s.current["rotate"+r+"-"+e],i=t[r]||0,o=n%360,c=i%360;0>o&&(o+=360),0>c&&(c+=360);var l=c-o;-180>l?l+=360:l>180&&(l-=360),s.current["rotate"+r+"-"+e]=t[r]=n+l}"rotate"===t[0]&&(r(1),r(2),r(3))})}),e.jmpress("applyTarget",function(t,s){var r,n=s.target,o=(s.stepData,s.settings),c=1.3*n.perspectiveScale<s.current.perspectiveScale,l=n.perspectiveScale>1.3*s.current.perspectiveScale,u=-1;e.each(n.transform,function(e,t){return 1>=t.length||"rotate"===t[0]&&0===t[1]%360&&0===t[2]%360&&0===t[3]%360?a:"scale"!==t[0]?!1:(u=e,a)}),u!==s.current.oldLastScale&&(c=l=!1,s.current.oldLastScale=u);var p=[];if(-1!==u)for(;u>=0;)"scale"===n.transform[u][0]&&(p.push(n.transform[u]),n.transform[u]=["scale"]),u--;var f=o.animation;o.reasonableAnimation[s.reason]&&(f=e.extend({},f,o.reasonableAnimation[s.reason])),r={perspective:Math.round(1e3*n.perspectiveScale)+"px"},r=e.extend({},f,r),c||(r.transitionDelay="0s"),s.beforeActive||(r.transitionDuration="0s",r.transitionDelay="0s"),e.jmpress("css",s.area,r),i.transform(s.area,p),r=e.extend({},f),l||(r.transitionDelay="0s"),s.beforeActive||(r.transitionDuration="0s",r.transitionDelay="0s"),s.current.perspectiveScale=n.perspectiveScale,e.jmpress("css",s.canvas,r),i.transform(s.canvas,n.transform)})}(jQuery,document,window),function(e){"use strict";var t=e.jmpress,s="activeClass",a="nestedActiveClass",r=t("defaults");r[a]="nested-active",r[s]="active",t("setInactive",function(t,r){var n=r.settings,i=n[s],o=n[a];i&&e(t).removeClass(i),o&&e.each(r.parents,function(t,s){e(s).removeClass(o)})}),t("setActive",function(t,r){var n=r.settings,i=n[s],o=n[a];i&&e(t).addClass(i),o&&e.each(r.parents,function(t,s){e(s).addClass(o)})})}(jQuery,document,window),function(e){"use strict";function t(t,s){return e(this).find(s.settings.stepSelector).first()}function s(t,s,a,r){if(!s)return!1;var n=a.settings.stepSelector;s=e(s);do{var i=s.near(n,r);if((0===i.length||0===i.closest(t).length)&&(i=e(t).find(n)[r?"last":"first"]()),!i.length)return!1;s=i}while(s.data("stepData").exclude);return s}var a=e.jmpress;a("initStep",function(e,t){t.stepData.exclude=t.data.exclude&&-1===["false","no"].indexOf(t.data.exclude)}),a("selectInitialStep",t),a("selectHome",t),a("selectEnd",function(t,s){return e(this).find(s.settings.stepSelector).last()}),a("selectPrev",function(e,t){return s(this,e,t,!0)}),a("selectNext",function(e,t){return s(this,e,t)})}(jQuery,document,window),function(e){"use strict";e.jmpress("selectInitialStep",function(e,t){return t.settings.start})}(jQuery,document,window),function(e){"use strict";function t(t,s,a){for(var r=0;s.length-1>r;r++){var n=s[r],i=s[r+1];e(t).jmpress("initialized")?e(n,t).data("stepData")[a]=i:e(n,t).attr("data-"+a,i)}}function s(t,s,a,r){var n=s.stepData;if(n[a]){var i=e(t).near(n[a],r);if(i&&i.length)return i;if(i=e(n[a],this)[r?"last":"first"](),i&&i.length)return i}}var a=e.jmpress;a("register","route",function(e,s,a){"string"==typeof e&&(e=[e,e]),t(this,e,a?"prev":"next"),s||t(this,e.reverse(),a?"next":"prev")}),a("initStep",function(e,t){for(var s in{next:1,prev:1})t.stepData[s]=t.data[s]}),a("selectNext",function(e,t){return s.call(this,e,t,"next")}),a("selectPrev",function(e,t){return s.call(this,e,t,"prev",!0)})}(jQuery,document,window),function(e){"use strict";var t=e.jmpress,s="ajax:afterStepLoaded",a="ajax:loadStep";t("register",a),t("register",s),t("defaults").ajaxLoadedClass="loaded",t("initStep",function(t,s){s.stepData.src=e(t).attr("href")||s.data.src||!1,s.stepData.srcLoaded=!1}),t(a,function(t,a){var r=a.stepData,n=r&&r.src,i=a.settings;n&&(e(t).addClass(i.ajaxLoadedClass),r.srcLoaded=!0,e(t).load(n,function(r,n,i){e(a.jmpress).jmpress("fire",s,t,e.extend({},a,{response:r,status:n,xhr:i}))}))}),t("idle",function(t,s){if(t){var r=s.settings,n=e(this);s.stepData;var i=e(t).add(e(t).near(r.stepSelector)).add(e(t).near(r.stepSelector,!0)).add(n.jmpress("fire","selectPrev",t,{stepData:e(t).data("stepData")})).add(n.jmpress("fire","selectNext",t,{stepData:e(t).data("stepData")}));i.each(function(){var t=this,s=e(t).data("stepData");s.src&&!s.srcLoaded&&n.jmpress("fire",a,t,{stepData:e(t).data("stepData")})})}}),t("setActive",function(t){var s=e(t).data("stepData");s.src&&!s.srcLoaded&&e(this).jmpress("fire",a,t,{stepData:e(t).data("stepData")})})}(jQuery,document,window),function(e,t,s,a){"use strict";function r(){return""+Math.round(1e5*Math.random(),0)}function n(t){try{var r=e("#"+s.location.hash.replace(/^#\/?/,""));return r.length>0&&r.is(t.stepSelector)?r:a}catch(n){}}function i(e){var t="#/"+e;s.history&&s.history.pushState?s.location.hash!==t&&s.history.pushState({},"",t):s.location.hash!==t&&(s.location.hash=t)}var o=e.jmpress,c="a[href^=#]";o("defaults").hash={use:!0,update:!0,bindChange:!0},o("selectInitialStep",function(t,o){var l=o.settings,u=l.hash,p=o.current,f=e(this);return o.current.hashNamespace=".jmpress-"+r(),u.use?(u.bindChange&&(e(s).bind("hashchange"+p.hashNamespace,function(e){var t=n(l);f.jmpress("initialized")&&f.jmpress("scrollFix"),t&&t.length&&(t.attr("id")!==f.jmpress("active").attr("id")&&f.jmpress("select",t),i(t.attr("id"))),e.preventDefault()}),e(c).on("click"+p.hashNamespace,function(t){var s=e(this).attr("href");try{e(s).is(l.stepSelector)&&(f.jmpress("select",s),t.preventDefault(),t.stopPropagation())}catch(a){}})),n(l)):a}),o("afterDeinit",function(t,a){e(c).off(a.current.hashNamespace),e(s).unbind(a.current.hashNamespace)}),o("setActive",function(t,s){var a=s.settings,r=s.current;a.hash.use&&a.hash.update&&(clearTimeout(r.hashtimeout),r.hashtimeout=setTimeout(function(){i(e(s.delegatedFrom).attr("id"))},a.transitionDuration+200))})}(jQuery,document,window),function(e,t,s,a){"use strict";function r(){return""+Math.round(1e5*Math.random(),0)}function n(e){e.preventDefault(),e.stopPropagation()}var i=e.jmpress,o="next",c="prev";i("defaults").keyboard={use:!0,keys:{33:c,37:c,38:c,9:o+":"+c,32:o,34:o,39:o,40:o,36:"home",35:"end"},ignore:{INPUT:[32,37,38,39,40],TEXTAREA:[32,37,38,39,40],SELECT:[38,40]},tabSelector:"a[href]:visible, :input:visible"},i("afterInit",function(s,i){var o=i.settings,c=o.keyboard,l=c.ignore,u=i.current,p=e(this);o.fullscreen||p.attr("tabindex",0),u.keyboardNamespace=".jmpress-"+r(),e(o.fullscreen?t:p).bind("keypress"+u.keyboardNamespace,function(e){for(var t in l)if(e.target.nodeName===t&&-1!==l[t].indexOf(e.which))return;(e.which>=37&&40>=e.which||32===e.which)&&n(e)}),e(o.fullscreen?t:p).bind("keydown"+u.keyboardNamespace,function(t){var s=e(t.target);if((o.fullscreen||s.closest(p).length)&&c.use){for(var r in l)if(s[0].nodeName===r&&-1!==l[r].indexOf(t.which))return;var i,u=!1;if(9===t.which){if(s.closest(p.jmpress("active")).length?(i=s.near(c.tabSelector,t.shiftKey),e(i).closest(o.stepSelector).is(p.jmpress("active"))||(i=a)):t.shiftKey?u=!0:i=p.jmpress("active").find("a[href], :input").filter(":visible").first(),i&&i.length>0)return i.focus(),p.jmpress("scrollFix"),n(t),a;t.shiftKey&&(u=!0)}var f=c.keys[t.which];"string"==typeof f?(-1!==f.indexOf(":")&&(f=f.split(":"),f=t.shiftKey?f[1]:f[0]),p.jmpress(f),n(t)):e.isFunction(f)?f.call(p,t):f&&(p.jmpress.apply(p,f),n(t)),u&&(i=p.jmpress("active").find("a[href], :input").filter(":visible").last(),i.focus(),p.jmpress("scrollFix"))}})}),i("afterDeinit",function(s,a){e(t).unbind(a.current.keyboardNamespace)})}(jQuery,document,window),function(e,t,s,a){"use strict";function r(){return""+Math.round(1e5*Math.random(),0)}function n(e,t){return Math.max(Math.min(e,t),-t)}function i(t,s,a){var r=e(this).jmpress("current"),i=e(this).jmpress("settings"),o=e(this).jmpress("active").data("stepData"),c=e(this).jmpress("container");if(!(0===r.userZoom&&0>a)){var l=o.viewPortZoomable||i.viewPort.zoomable;if(!(r.userZoom===l&&a>0)){r.userZoom+=a;var u=e(c).innerWidth()/2,p=e(c).innerHeight()/2;t=t?t-u:t,s=s?s-p:s,r.userTranslateX=n(r.userTranslateX-a*t/r.zoomOriginWindowScale/l,u*r.userZoom*r.userZoom/l),r.userTranslateY=n(r.userTranslateY-a*s/r.zoomOriginWindowScale/l,p*r.userZoom*r.userZoom/l),e(this).jmpress("reselect","zoom")}}}var o=function(){var e=navigator.userAgent.toLowerCase(),t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||0>e.indexOf("compatible")&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return t[1]||""}(),c=e.jmpress("defaults");c.viewPort={width:!1,height:!1,maxScale:0,minScale:0,zoomable:0,zoomBindMove:!0,zoomBindWheel:!0};var l=c.keyboard.keys;l["mozilla"===o?107:187]="zoomIn",l["mozilla"===o?109:189]="zoomOut",c.reasonableAnimation.resize={transitionDuration:"0s",transitionDelay:"0ms"},c.reasonableAnimation.zoom={transitionDuration:"0s",transitionDelay:"0ms"},e.jmpress("initStep",function(e,t){for(var s in{viewPortHeight:1,viewPortWidth:1,viewPortMinScale:1,viewPortMaxScale:1,viewPortZoomable:1})t.stepData[s]=t.data[s]&&parseFloat(t.data[s])}),e.jmpress("afterInit",function(n,i){var o=this;i.current.viewPortNamespace=".jmpress-"+r(),e(s).bind("resize"+i.current.viewPortNamespace,function(){e(o).jmpress("reselect","resize")}),i.current.userZoom=0,i.current.userTranslateX=0,i.current.userTranslateY=0,i.settings.viewPort.zoomBindWheel&&e(i.settings.fullscreen?t:this).bind("mousewheel"+i.current.viewPortNamespace+" DOMMouseScroll"+i.current.viewPortNamespace,function(t,s){s=s||t.originalEvent.wheelDelta||-t.originalEvent.detail;var a=s/Math.abs(s);return 0>a?e(i.jmpress).jmpress("zoomOut",t.originalEvent.x,t.originalEvent.y):a>0&&e(i.jmpress).jmpress("zoomIn",t.originalEvent.x,t.originalEvent.y),!1}),i.settings.viewPort.zoomBindMove&&e(i.settings.fullscreen?t:this).bind("mousedown"+i.current.viewPortNamespace,function(e){i.current.userZoom&&(i.current.userTranslating={x:e.clientX,y:e.clientY},e.preventDefault(),e.stopImmediatePropagation())}).bind("mousemove"+i.current.viewPortNamespace,function(t){var s=i.current.userTranslating;s&&(e(o).jmpress("zoomTranslate",t.clientX-s.x,t.clientY-s.y),s.x=t.clientX,s.y=t.clientY,t.preventDefault(),t.stopImmediatePropagation())}).bind("mouseup"+i.current.viewPortNamespace,function(e){i.current.userTranslating&&(i.current.userTranslating=a,e.preventDefault(),e.stopImmediatePropagation())})}),e.jmpress("register","zoomIn",function(e,t){i.call(this,e||0,t||0,1)}),e.jmpress("register","zoomOut",function(e,t){i.call(this,e||0,t||0,-1)}),e.jmpress("register","zoomTranslate",function(t,s){var a=e(this).jmpress("current"),r=e(this).jmpress("settings"),i=e(this).jmpress("active").data("stepData"),o=e(this).jmpress("container"),c=i.viewPortZoomable||r.viewPort.zoomable,l=e(o).innerWidth(),u=e(o).innerHeight();a.userTranslateX=n(a.userTranslateX+t/a.zoomOriginWindowScale,l*a.userZoom*a.userZoom/c),a.userTranslateY=n(a.userTranslateY+s/a.zoomOriginWindowScale,u*a.userZoom*a.userZoom/c),e(this).jmpress("reselect","zoom")}),e.jmpress("afterDeinit",function(a,r){e(r.settings.fullscreen?t:this).unbind(r.current.viewPortNamespace),e(s).unbind(r.current.viewPortNamespace)}),e.jmpress("setActive",function(t,s){var a=s.settings.viewPort,r=s.stepData.viewPortHeight||a.height,n=s.stepData.viewPortWidth||a.width,i=s.stepData.viewPortMaxScale||a.maxScale,o=s.stepData.viewPortMinScale||a.minScale,c=r&&e(s.container).innerHeight()/r,l=n&&e(s.container).innerWidth()/n,u=(l||c)&&Math.min(l||c,c||l);if(u){u=u||1,i&&(u=Math.min(u,i)),o&&(u=Math.max(u,o));var p=s.stepData.viewPortZoomable||s.settings.viewPort.zoomable;if(p){var f=1/u-1/i;f/=p,u=1/(1/u-f*s.current.userZoom)}s.target.transform.reverse(),s.current.userTranslateX&&s.current.userTranslateY?s.target.transform.push(["translate",s.current.userTranslateX,s.current.userTranslateY,0]):s.target.transform.push(["translate"]),s.target.transform.push(["scale",u,u,1]),s.target.transform.reverse(),s.target.perspectiveScale/=u}s.current.zoomOriginWindowScale=u}),e.jmpress("setInactive",function(t,s){s.nextStep&&t&&e(s.nextStep).attr("id")===e(t).attr("id")||(s.current.userZoom=0,s.current.userTranslateX=0,s.current.userTranslateY=0)})}(jQuery,document,window),function(e){"use strict";function t(){return""+Math.round(1e5*Math.random(),0)}var s=e.jmpress;s("defaults").mouse={clickSelects:!0},s("afterInit",function(s,a){var r=a.settings,n=r.stepSelector,i=a.current,o=e(this);i.clickableStepsNamespace=".jmpress-"+t(),o.bind("click"+i.clickableStepsNamespace,function(t){if(r.mouse.clickSelects&&!i.userZoom){var s=e(t.target).closest(n);s.is(o.jmpress("active"))||s.length&&(o.jmpress("select",s[0],"click"),t.preventDefault(),t.stopPropagation())}})}),s("afterDeinit",function(t,s){e(this).unbind(s.current.clickableStepsNamespace)})}(jQuery,document,window),function(e,t){"use strict";function s(){return""+Math.round(1e5*Math.random(),0)}var a=e.jmpress;a("afterInit",function(a,r){var n=r.settings,i=r.current,o=r.jmpress;i.mobileNamespace=".jmpress-"+s();var c,l=[0,0];e(n.fullscreen?t:o).bind("touchstart"+i.mobileNamespace,function(e){c=e.originalEvent.touches[0],l=[c.pageX,c.pageY]}).bind("touchmove"+i.mobileNamespace,function(e){return c=e.originalEvent.touches[0],e.preventDefault(),!1}).bind("touchend"+i.mobileNamespace,function(t){var s=[c.pageX,c.pageY],a=[s[0]-l[0],s[1]-l[1]];return Math.max(Math.abs(a[0]),Math.abs(a[1]))>50?(a=Math.abs(a[0])>Math.abs(a[1])?a[0]:a[1],e(o).jmpress(a>0?"prev":"next"),t.preventDefault(),!1):undefined})}),a("afterDeinit",function(s,a){var r=a.settings,n=a.current,i=a.jmpress;e(r.fullscreen?t:i).unbind(n.mobileNamespace)})}(jQuery,document,window),function(e,t,s,a){"use strict";function r(t,s,n){for(var i in s){var o=i;n&&(o=n+o.substr(0,1).toUpperCase()+o.substr(1)),e.isPlainObject(s[i])?r(t,s[i],o):t[o]===a&&(t[o]=s[i])}}function n(t,s){e.isArray(s)?s.length<t.length?e.error("more nested steps than children in template"):t.each(function(t,a){a=e(a);var n=a.data(l)||{};r(n,s[t]),a.data(l,n)}):e.isFunction(s)&&t.each(function(a,n){n=e(n);var i=n.data(l)||{};r(i,s(a,n,t)),n.data(l,i)})}function i(e,t,s,a){if(s.children){var r=t.children(a.settings.stepSelector);n(r,s.children)}o(e,s)}function o(e,t){r(e,t)}var c=e.jmpress,l="_template_",u="_applied_template_",p={};c("beforeInitStep",function(t,s){t=e(t);var a=s.data,r=a.template,n=t.data(u),o=t.data(l);r&&e.each(r.split(" "),function(e,r){var n=p[r];i(a,t,n,s)}),n&&i(a,t,n,s),o&&(i(a,t,o,s),t.data(l,null),o.template&&e.each(o.template.split(" "),function(e,r){var n=p[r];i(a,t,n,s)}))}),c("beforeInit",function(t,s){var a=c("dataset",this),r=a.template,i=s.settings.stepSelector;if(r){var o=p[r];n(e(this).find(i).filter(function(){return!e(this).parent().is(i)}),o.children)}}),c("register","template",function(t,s){p[t]=p[t]?e.extend(!0,{},p[t],s):e.extend(!0,{},s)}),c("register","apply",function(t,s){if(s)if(e.isArray(s))n(e(t),s);else{var a;a="string"==typeof s?p[s]:e.extend(!0,{},s),e(t).each(function(t,s){s=e(s);var n=s.data(u)||{};r(n,a),s.data(u,n)})}else{var i=e(this).jmpress("settings").stepSelector;n(e(this).find(i).filter(function(){return!e(this).parent().is(i)}),t)}})}(jQuery,document,window),function(e){"use strict";e.jmpress("setActive",function(t,s){s.prevStep!==t&&e(t).triggerHandler("enterStep")}),e.jmpress("setInactive",function(t,s){s.nextStep!==t&&e(t).triggerHandler("leaveStep")})}(jQuery,document,window),function(e,t,s,a){"use strict";function r(t){for(var s=t.split(" "),a=s[0],r={willClass:"will-"+a,doClass:"do-"+a,hasClass:"has-"+a},n="",i=1;s.length>i;i++){var o=s[i];switch(n){case"":"after"===o?n="after":e.warn("unknown keyword in '"+t+"'. '"+o+"' unknown.");break;case"after":if(o.match(/^[1-9][0-9]*m?s?/)){var c=parseFloat(o);-1!==o.indexOf("ms")?c*=1:-1!==o.indexOf("s")?c*=1e3:-1!==o.indexOf("m")&&(c*=6e4),r.delay=c}else r.after=Array.prototype.slice.call(s,i).join(" "),i=s.length}}return r}function n(t,s,a,r){r=r||t.length-1,a=a||0;for(var n=a;r+1>n;n++)if(e(t[n].element).is(s))return n}function i(t,s,a){e.each(s._on,function(e,s){t.push({substep:s.substep,delay:s.delay+a}),i(t,s.substep,s.delay+a)})}e.jmpress("defaults").customAnimationDataAttribute="jmpress",e.jmpress("afterInit",function(e,t){t.current.animationTimeouts=[],t.current.animationCleanupWaiting=[]}),e.jmpress("applyStep",function(t,s){function o(e,t){return t.substep._after?(u=t.substep._after,!1):a}var c={},l=[];if(e(t).find("[data-"+s.settings.customAnimationDataAttribute+"]").each(function(a,r){e(r).closest(s.settings.stepSelector).is(t)&&l.push({element:r})}),0!==l.length){e.each(l,function(t,a){a.info=r(e(a.element).data(s.settings.customAnimationDataAttribute)),e(a.element).addClass(a.info.willClass),a._on=[],a._after=null});var u={_after:a,_on:[],info:{}};if(e.each(l,function(e,t){var s=t.info.after;if(s)if("step"===s)s=u;else if("prev"===s)s=l[e-1];else{var r=n(l,s,0,e-1);r===a&&(r=n(l,s)),s=r===a||r===e?l[e-1]:l[r]}else s=l[e-1];if(s){if(!t.info.delay){if(!s._after)return s._after=t,a;s=s._after}s._on.push({substep:t,delay:t.info.delay||0})}}),u._after===a&&0===u._on.length){var p=n(l,s.stepData.startSubstep)||0;u._after=l[p]}var f=[];do{var d=[{substep:u,delay:0}];i(d,u,0),f.push(d),u=null,e.each(d,o)}while(u);c.list=f,e(t).data("substepsData",c)}}),e.jmpress("unapplyStep",function(t){var s=e(t).data("substepsData");s&&e.each(s.list,function(t,s){e.each(s,function(t,s){s.substep.info.willClass&&e(s.substep.element).removeClass(s.substep.info.willClass),s.substep.info.hasClass&&e(s.substep.element).removeClass(s.substep.info.hasClass),s.substep.info.doClass&&e(s.substep.element).removeClass(s.substep.info.doClass)})})}),e.jmpress("setActive",function(t,s){var r=e(t).data("substepsData");if(r){s.substep===a&&(s.substep="prev"===s.reason?r.list.length-1:0);var n=s.substep;e.each(s.current.animationTimeouts,function(e,t){clearTimeout(t)}),s.current.animationTimeouts=[],e.each(r.list,function(t,a){var r=n>t,i=n>=t;e.each(a,function(t,a){function n(){e(a.substep.element).addClass(a.substep.info.doClass)}a.substep.info.hasClass&&e(a.substep.element)[(r?"add":"remove")+"Class"](a.substep.info.hasClass),i&&!r&&a.delay&&"prev"!==s.reason?a.substep.info.doClass&&(e(a.substep.element).removeClass(a.substep.info.doClass),s.current.animationTimeouts.push(setTimeout(n,a.delay))):a.substep.info.doClass&&e(a.substep.element)[(i?"add":"remove")+"Class"](a.substep.info.doClass)})})}}),e.jmpress("setInactive",function(t,s){function a(t){e.each(t.list,function(t,s){e.each(s,function(t,s){s.substep.info.hasClass&&e(s.substep.element).removeClass(s.substep.info.hasClass),s.substep.info.doClass&&e(s.substep.element).removeClass(s.substep.info.doClass)})})}if(s.nextStep!==t){e.each(s.current.animationCleanupWaiting,function(e,t){a(t)}),s.current.animationCleanupWaiting=[];var r=e(t).data("substepsData");r&&s.current.animationCleanupWaiting.push(r)}}),e.jmpress("selectNext",function(t,s){if(s.substep!==a){var r=e(t).data("substepsData");if(r)return s.substep<r.list.length-1?{step:t,substep:s.substep+1}:a}}),e.jmpress("selectPrev",function(t,s){if(s.substep!==a){var r=e(t).data("substepsData");if(r)return s.substep>0?{step:t,substep:s.substep-1}:a}})}(jQuery,document,window),function(e,t){"use strict";e.jmpress("register","toggle",function(s,a,r){var n=this;e(t).bind("keydown",function(t){t.keyCode===s&&(e(n).jmpress("initialized")?e(n).jmpress("deinit"):e(n).jmpress(a))}),r&&e(n).jmpress(a)})}(jQuery,document,window),function(e){"use strict";function t(t,s,a){if(t.secondary&&-1!==t.secondary.split(" ").indexOf(s)){for(var r in t)if(r.length>9&&0===r.indexOf("secondary")){var n=t[r],i=r.substr(9);i=i.substr(0,1).toLowerCase()+i.substr(1),t[r]=t[i],t[i]=n}e(this).jmpress("reapply",e(a))}}e.jmpress("initStep",function(e,t){for(var s in t.data)0===s.indexOf("secondary")&&(t.stepData[s]=t.data[s])}),e.jmpress("beforeActive",function(s,a){t.call(a.jmpress,e(s).data("stepData"),"self",s);var r=e(s).parent();e(r).children(a.settings.stepSelector).each(function(s,r){var n=e(r).data("stepData");t.call(a.jmpress,n,"siblings",r)});for(var n=1;a.parents.length>n;n++)e(a.parents[n]).children(a.settings.stepSelector).each()}),e.jmpress("setInactive",function(s,a){function r(s,r){var n=e(r).data("stepData");t.call(a.jmpress,n,"grandchildren",r)}t.call(a.jmpress,e(s).data("stepData"),"self",s);
|
13 |
+
var n=e(s).parent();e(n).children(a.settings.stepSelector).each(function(s,r){var n=e(r).data("stepData");t.call(a.jmpress,n,"siblings",r)});for(var i=1;a.parents.length>i;i++)e(a.parents[i]).children(a.settings.stepSelector).each(r)})}(jQuery,document,window),function(e,t,s,a){"use strict";e.jmpress("defaults").duration={defaultValue:-1,defaultAction:"next",barSelector:a,barProperty:"width",barPropertyStart:"0",barPropertyEnd:"100%"},e.jmpress("initStep",function(e,t){t.stepData.duration=t.data.duration&&parseInt(t.data.duration,10),t.stepData.durationAction=t.data.durationAction}),e.jmpress("setInactive",function(t,s){var a=s.settings,r=a.duration,n=s.current;if(s.stepData.duration||r.defaultValue,n.durationTimeout){if(r.barSelector){var i={transitionProperty:r.barProperty,transitionDuration:"0",transitionDelay:"0",transitionTimingFunction:"linear"};i[r.barProperty]=r.barPropertyStart;var o=e(r.barSelector);e.jmpress("css",o,i),o.each(function(t,s){var a=e(s).next(),r=e(s).parent();e(s).detach(),a.length?a.insertBefore(s):r.append(s)})}clearTimeout(n.durationTimeout),delete n.durationTimeout}}),e.jmpress("setActive",function(t,s){var r=s.settings,n=r.duration,i=s.current,o=s.stepData.duration||n.defaultValue;if(o&&o>0){if(n.barSelector){var c={transitionProperty:n.barProperty,transitionDuration:o-2*r.transitionDuration/3-100+"ms",transitionDelay:2*r.transitionDuration/3+"ms",transitionTimingFunction:"linear"};c[n.barProperty]=n.barPropertyEnd,e.jmpress("css",e(n.barSelector),c)}var l=this;i.durationTimeout&&(clearTimeout(i.durationTimeout),i.durationTimeout=a),i.durationTimeout=setTimeout(function(){var t=s.stepData.durationAction||n.defaultAction;e(l).jmpress(t)},o)}})}(jQuery,document,window),function(e,t,s){"use strict";var a=e.jmpress,r="jmpress-presentation-";a("defaults").presentationMode={use:!0,url:"presentation-screen.html",notesUrl:!1,transferredValues:["userZoom","userTranslateX","userTranslateY"]},a("defaults").keyboard.keys[80]="presentationPopup",a("afterInit",function(t,a){var n=a.current;if(n.selectMessageListeners=[],a.settings.presentationMode.use){s.addEventListener("message",function(t){try{if("string"!=typeof t.data||0!==t.data.indexOf(r))return;var i=JSON.parse(t.data.slice(r.length));switch(i.type){case"select":e.each(a.settings.presentationMode.transferredValues,function(e,t){a.current[t]=i[t]}),/[a-z0-9\-]+/i.test(i.targetId)&&typeof i.substep in{number:1,undefined:1}?e(a.jmpress).jmpress("select",{step:"#"+i.targetId,substep:i.substep},i.reason):e.error("For security reasons the targetId must match /[a-z0-9\\-]+/i and substep must be a number.");break;case"listen":n.selectMessageListeners.push(t.source);break;case"ok":clearTimeout(n.presentationPopupTimeout);break;case"read":try{t.source.postMessage(r+JSON.stringify({type:"url",url:s.location.href,notesUrl:a.settings.presentationMode.notesUrl}),"*")}catch(o){e.error("Cannot post message to source: "+o)}break;default:throw"Unknown message type: "+i.type}}catch(o){e.error("Received message is malformed: "+o)}});try{s.parent&&s.parent!==s&&s.parent.postMessage(r+JSON.stringify({type:"afterInit"}),"*")}catch(i){e.error("Cannot post message to parent: "+i)}}}),a("afterDeinit",function(t,a){if(a.settings.presentationMode.use)try{s.parent&&s.parent!==s&&s.parent.postMessage(r+JSON.stringify({type:"afterDeinit"}),"*")}catch(n){e.error("Cannot post message to parent: "+n)}}),a("setActive",function(t,s){var a=e(s.delegatedFrom).attr("id"),n=s.substep,i=s.reason;e.each(s.current.selectMessageListeners,function(t,o){try{var c={type:"select",targetId:a,substep:n,reason:i};e.each(s.settings.presentationMode.transferredValues,function(e,t){c[t]=s.current[t]}),o.postMessage(r+JSON.stringify(c),"*")}catch(l){e.error("Cannot post message to listener: "+l)}})}),a("register","presentationPopup",function(){function t(){n.jmpress("current").presentationPopupTimeout=setTimeout(t,100);try{a.postMessage(r+JSON.stringify({type:"url",url:s.location.href,notesUrl:n.jmpress("settings").presentationMode.notesUrl}),"*")}catch(e){}}var a,n=e(this);n.jmpress("settings").presentationMode.use&&(a=s.open(e(this).jmpress("settings").presentationMode.url),n.jmpress("current").presentationPopupTimeout=setTimeout(t,100))})}(jQuery,document,window);
|
modules/shortcodes/js/main.js
ADDED
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function($){
|
2 |
+
var jmpressOpts = {
|
3 |
+
fullscreen : false,
|
4 |
+
hash : { use : false },
|
5 |
+
mouse : { clickSelects : false },
|
6 |
+
keyboard : { use : true },
|
7 |
+
animation : { transitionDuration : '1s' },
|
8 |
+
presentationMode : false,
|
9 |
+
stepSelector : '.step'
|
10 |
+
};
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Presentation constructor
|
14 |
+
*/
|
15 |
+
function Presentation (wrapper) {
|
16 |
+
var _self, size, duration, new_css, ie_regex, matches;
|
17 |
+
|
18 |
+
_self = this;
|
19 |
+
|
20 |
+
_self.wrapper = $(wrapper); // The wrapper for toggling fullscreen
|
21 |
+
_self.slideshow = $('.presentation', wrapper); // Holds the slides for jmpress
|
22 |
+
_self.navLeft = $('.nav-arrow-left', wrapper);
|
23 |
+
_self.navRight = $('.nav-arrow-right', wrapper);
|
24 |
+
_self.expandButton = $('.nav-fullscreen-button', wrapper);
|
25 |
+
_self.fullscreen = false;
|
26 |
+
|
27 |
+
// The wrapper is scaled to the contents' size so that its border wraps tightly
|
28 |
+
_self.wrapper.css({
|
29 |
+
width: _self.slideshow.width(),
|
30 |
+
height: _self.slideshow.height()
|
31 |
+
});
|
32 |
+
|
33 |
+
duration = _self.slideshow.attr('duration') || '1s';
|
34 |
+
jmpressOpts.animation.transitionDuration = duration;
|
35 |
+
|
36 |
+
// Set the opacity transition duration
|
37 |
+
// as it is delegated by css and not jmpress
|
38 |
+
duration = 'opacity ' + duration;
|
39 |
+
new_css = {
|
40 |
+
'width' : _self.slideshow.width(),
|
41 |
+
'height' : _self.slideshow.height(),
|
42 |
+
'-webkit-transition': duration,
|
43 |
+
'-moz-transition' : duration,
|
44 |
+
'-ms-transition' : duration,
|
45 |
+
'-o-transition' : duration,
|
46 |
+
'transition' : duration
|
47 |
+
};
|
48 |
+
|
49 |
+
$('.step', _self.slideshow).each(function(i, step) {
|
50 |
+
$(step).css(new_css);
|
51 |
+
});
|
52 |
+
|
53 |
+
// Register resizing to window when fullscreen
|
54 |
+
$(window).resize(function() {
|
55 |
+
if ( _self.fullscreen )
|
56 |
+
_self.resizePresentation();
|
57 |
+
});
|
58 |
+
|
59 |
+
// Register the nav bars to move the slides
|
60 |
+
_self.navLeft.on('click', function(){
|
61 |
+
_self.slideshow.jmpress('prev');
|
62 |
+
});
|
63 |
+
|
64 |
+
_self.navRight.on('click', function(){
|
65 |
+
_self.slideshow.jmpress('next');
|
66 |
+
});
|
67 |
+
|
68 |
+
// Register toggling fullscreen except for IE 9 or lower
|
69 |
+
ie_regex = /MSIE\s(\d+)\.\d+/;
|
70 |
+
matches = ie_regex.exec(navigator.userAgent);
|
71 |
+
|
72 |
+
if ( matches && parseInt(matches[1]) < 10 ) {
|
73 |
+
_self.expandButton.remove();
|
74 |
+
_self.expandButton = null;
|
75 |
+
} else {
|
76 |
+
_self.expandButton.on('click', function() {
|
77 |
+
_self.setFullscreen( !_self.fullscreen );
|
78 |
+
});
|
79 |
+
}
|
80 |
+
|
81 |
+
// Register ESC key to exit fullscreen
|
82 |
+
$(window).on('keydown', function( event ) {
|
83 |
+
if ( event.which == 27 )
|
84 |
+
_self.setFullscreen( false );
|
85 |
+
});
|
86 |
+
|
87 |
+
// Start the presentation
|
88 |
+
_self.slideshow.jmpress(jmpressOpts);
|
89 |
+
|
90 |
+
// Make content visible and remove error message on jmpress success
|
91 |
+
if ( _self.slideshow.jmpress('initialized') ) {
|
92 |
+
_self.slideshow.css('display', '');
|
93 |
+
$('.not-supported-msg', _self.wrapper).remove();
|
94 |
+
}
|
95 |
+
|
96 |
+
// A bug in Firefox causes issues with the nav arrows appearing
|
97 |
+
// on hover in presentation mode. Explicitly disabling fullscreen
|
98 |
+
// on init seems to fix the issue
|
99 |
+
_self.setFullscreen( false );
|
100 |
+
}
|
101 |
+
|
102 |
+
$.extend( Presentation.prototype, {
|
103 |
+
resizePresentation: function () {
|
104 |
+
var scale, duration, settings, new_css, widthScale, heightScale;
|
105 |
+
|
106 |
+
// Set the animation duration to 0 during resizing
|
107 |
+
// so that there isn't an animation delay when scaling
|
108 |
+
// up the slide contents
|
109 |
+
settings = this.slideshow.jmpress('settings');
|
110 |
+
duration = settings.animation.transitionDuration;
|
111 |
+
|
112 |
+
settings.animation.transitionDuration = '0s';
|
113 |
+
this.slideshow.jmpress('reselect');
|
114 |
+
|
115 |
+
scale = 1;
|
116 |
+
new_css = {
|
117 |
+
top : 0,
|
118 |
+
left : 0,
|
119 |
+
zoom : 1
|
120 |
+
};
|
121 |
+
|
122 |
+
// Expand the presentation to fill the lesser of the max width or height
|
123 |
+
// This avoids content moving past the window for certain window sizes
|
124 |
+
if ( this.fullscreen ) {
|
125 |
+
widthScale = $(window).width() / this.slideshow.width();
|
126 |
+
heightScale = $(window).height() / this.slideshow.height();
|
127 |
+
|
128 |
+
scale = Math.min(widthScale, heightScale);
|
129 |
+
|
130 |
+
new_css.top = ( $(window).height() - (scale * this.slideshow.height()) ) / 2;
|
131 |
+
new_css.left = ( $(window).width() - (scale * this.slideshow.width() ) ) / 2;
|
132 |
+
}
|
133 |
+
|
134 |
+
// Firefox does not support the zoom property; IE does, but it does not work
|
135 |
+
// well like in webkit, so we manually transform and position the slideshow
|
136 |
+
if ( this.slideshow.css('-moz-transform') || this.slideshow.css('-ms-transform') ) {
|
137 |
+
// Firefox keeps the center of the element in place and expands outward
|
138 |
+
// so we must shift everything to compensate
|
139 |
+
new_css.top += (scale - 1) * this.slideshow.height() / 2;
|
140 |
+
new_css.left += (scale - 1) * this.slideshow.width() / 2;
|
141 |
+
|
142 |
+
scale = 'scale(' + scale + ')';
|
143 |
+
|
144 |
+
$.extend(new_css, {
|
145 |
+
'-moz-transform' : scale,
|
146 |
+
'-ms-transform' : scale,
|
147 |
+
'transform' : scale,
|
148 |
+
});
|
149 |
+
} else {
|
150 |
+
// webkit scales everything with zoom so we need to offset the right amount
|
151 |
+
// so that the content is vertically centered after scaling effects
|
152 |
+
new_css.top /= scale;
|
153 |
+
new_css.left /= scale;
|
154 |
+
new_css.zoom = scale;
|
155 |
+
}
|
156 |
+
|
157 |
+
this.slideshow.css(new_css);
|
158 |
+
|
159 |
+
settings.animation.transitionDuration = duration;
|
160 |
+
this.slideshow.jmpress('reselect');
|
161 |
+
},
|
162 |
+
|
163 |
+
setFullscreen: function ( on ) {
|
164 |
+
this.fullscreen = on;
|
165 |
+
|
166 |
+
// Save the scroll positions before going into fullscreen mode
|
167 |
+
if ( on ) {
|
168 |
+
this.scrollVert = $(window).scrollTop();
|
169 |
+
this.scrollHoriz = $(window).scrollLeft();
|
170 |
+
}
|
171 |
+
|
172 |
+
$('html').toggleClass('presentation-global-fullscreen', on);
|
173 |
+
$('body').toggleClass('presentation-global-fullscreen', on);
|
174 |
+
|
175 |
+
this.wrapper.toggleClass('presentation-wrapper-fullscreen', on);
|
176 |
+
|
177 |
+
this.wrapper.parents().each(function(i, e){
|
178 |
+
$(e).toggleClass('presentation-wrapper-fullscreen-parent', on);
|
179 |
+
});
|
180 |
+
|
181 |
+
this.resizePresentation();
|
182 |
+
|
183 |
+
// Reset the scroll positions after exiting fullscreen mode
|
184 |
+
if ( !on ) {
|
185 |
+
$(window).scrollTop(this.scrollVert);
|
186 |
+
$(window).scrollLeft(this.scrollHoriz);
|
187 |
+
}
|
188 |
+
}
|
189 |
+
});
|
190 |
+
|
191 |
+
$( document ).ready( function(){
|
192 |
+
$('.presentation-wrapper').map(function() {
|
193 |
+
new Presentation(this);
|
194 |
+
});
|
195 |
+
});
|
196 |
+
|
197 |
+
})(jQuery);
|
modules/shortcodes/presentations.php
ADDED
@@ -0,0 +1,382 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Presentations
|
4 |
+
Plugin URI: http://automattic.com/wordpress-plugins/
|
5 |
+
Description: Presentations plugin based on the work done by <a href="http://darylkoop.com/">Daryl Koopersmith</a>. Powered by jmpress.js
|
6 |
+
Version: 0.2
|
7 |
+
Author: Automattic
|
8 |
+
Author URI: http://automattic.com/wordpress-plugins/
|
9 |
+
|
10 |
+
This program is free software; you can redistribute it and/or modify
|
11 |
+
it under the terms of the GNU General Public License as published by
|
12 |
+
the Free Software Foundation; either version 2 of the License, or
|
13 |
+
(at your option) any later version.
|
14 |
+
|
15 |
+
This program is distributed in the hope that it will be useful,
|
16 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18 |
+
GNU General Public License for more details.
|
19 |
+
|
20 |
+
You should have received a copy of the GNU General Public License
|
21 |
+
along with this program; if not, write to the Free Software
|
22 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
23 |
+
*/
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Known issues:
|
28 |
+
*
|
29 |
+
* - IE 7/8 are not supported by jmpress and presentations will not work
|
30 |
+
* - IE 9 will not animate transitions at all, though it's possible to at least
|
31 |
+
* switch between slides.
|
32 |
+
* - Infinite Scroll themes will not load presentations properly unless the post
|
33 |
+
* happens to be on the first loaded page. The permalink page will function
|
34 |
+
* properly, however.
|
35 |
+
* - Exiting fullscreen mode will not properly reset the scroll locations in Safari
|
36 |
+
*/
|
37 |
+
|
38 |
+
|
39 |
+
/*
|
40 |
+
HOW TO: How the plugin settings are organized and which features are supported.
|
41 |
+
|
42 |
+
The entire presentation should be wrapped with a [presentation] shortcode, and every
|
43 |
+
individual slide should be wrapped with a [slide] shortcode. Any settings supported
|
44 |
+
by [slide] can be set into [presentation], which will apply that setting for the entire
|
45 |
+
presentation unless overridden by individual slides.
|
46 |
+
|
47 |
+
- [presentation] only settings:
|
48 |
+
- duration: transition durations, default is one second.
|
49 |
+
- height: content height, default is 400px
|
50 |
+
- width: content width, default is 550px
|
51 |
+
|
52 |
+
- [slide] settings:
|
53 |
+
- transition: specifies where the next slide will be placed relative
|
54 |
+
to the last one before it. Supported values are "up", "down"
|
55 |
+
"left", "right", or "none". Default value is "down".
|
56 |
+
|
57 |
+
- scale: scales the content relative to other slides, default value is one
|
58 |
+
|
59 |
+
- rotate: rotates the content by the specified degrees, default is zero
|
60 |
+
|
61 |
+
- fade: slides will fade in and out during transition. Values of "on" or
|
62 |
+
"true" will enable fading, while values of "no" or "false" will
|
63 |
+
disable it. Default value is "on"
|
64 |
+
|
65 |
+
- bgcolor: specifies a background color for the slides. Any CSS valid value
|
66 |
+
is permitted. Default color is transparent.
|
67 |
+
|
68 |
+
- bgimg: specifies an image url which will fill the background. Image is
|
69 |
+
set to fill the background 100% width and height
|
70 |
+
*/
|
71 |
+
|
72 |
+
if ( ! class_exists( 'Presentations' ) ) :
|
73 |
+
|
74 |
+
class Presentations {
|
75 |
+
|
76 |
+
private $presentation_settings;
|
77 |
+
private $presentation_initialized;
|
78 |
+
private $scripts_and_style_included;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Constructor
|
82 |
+
*/
|
83 |
+
function __construct() {
|
84 |
+
// Bail without 3.0.
|
85 |
+
if ( ! function_exists( '__return_false' ) )
|
86 |
+
return;
|
87 |
+
|
88 |
+
$this->presentation_initialized = false;
|
89 |
+
$this->scripts_and_style_included = false;
|
90 |
+
|
91 |
+
// Registers shortcodes
|
92 |
+
add_action( 'wp_head', array( &$this, 'add_scripts' ), 1 );
|
93 |
+
|
94 |
+
add_shortcode( 'presentation', array( &$this, 'presentation_shortcode' ) );
|
95 |
+
add_shortcode( 'slide', array( &$this, 'slide_shortcode' ) );
|
96 |
+
}
|
97 |
+
|
98 |
+
function add_scripts() {
|
99 |
+
$this->scripts_and_style_included = false;
|
100 |
+
|
101 |
+
if ( empty( $GLOBALS['posts'] ) || !is_array( $GLOBALS['posts'] ) ) {
|
102 |
+
return;
|
103 |
+
}
|
104 |
+
|
105 |
+
foreach ( $GLOBALS['posts'] as $p ) {
|
106 |
+
if ( false !== strpos( $p->post_content, '[presentation' ) ) {
|
107 |
+
$this->scripts_and_style_included = true;
|
108 |
+
break;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
if ( ! $this->scripts_and_style_included )
|
113 |
+
return;
|
114 |
+
|
115 |
+
$plugin = plugin_dir_url( __FILE__ );
|
116 |
+
// Add CSS
|
117 |
+
wp_enqueue_style('presentations', $plugin . 'css/style.css');
|
118 |
+
// Add JavaScript
|
119 |
+
wp_enqueue_script('jquery');
|
120 |
+
wp_enqueue_script('jmpress',
|
121 |
+
$plugin . 'js/jmpress.min.js',
|
122 |
+
array('jquery'),
|
123 |
+
'0.4.5',
|
124 |
+
true);
|
125 |
+
wp_enqueue_script('presentations',
|
126 |
+
$plugin . 'js/main.js',
|
127 |
+
array('jquery', 'jmpress'),
|
128 |
+
false,
|
129 |
+
true);
|
130 |
+
}
|
131 |
+
|
132 |
+
function presentation_shortcode( $atts, $content='' ) {
|
133 |
+
// Mark that we've found a valid [presentation] shortcode
|
134 |
+
$this->presentation_initialized = true;
|
135 |
+
|
136 |
+
$atts = shortcode_atts( array(
|
137 |
+
'duration' => '',
|
138 |
+
'height' => '',
|
139 |
+
'width' => '',
|
140 |
+
'bgcolor' => '',
|
141 |
+
'bgimg' => '',
|
142 |
+
|
143 |
+
// Settings
|
144 |
+
'transition' => '',
|
145 |
+
'scale' => '',
|
146 |
+
'rotate' => '',
|
147 |
+
'fade' => '',
|
148 |
+
), $atts );
|
149 |
+
|
150 |
+
$this->presentation_settings = array(
|
151 |
+
'transition' => 'down',
|
152 |
+
'scale' => 1,
|
153 |
+
'rotate' => 0,
|
154 |
+
'fade' => 'on',
|
155 |
+
'last' => array(
|
156 |
+
'x' => 0,
|
157 |
+
'y' => 0,
|
158 |
+
'scale' => 1,
|
159 |
+
'rotate' => 0,
|
160 |
+
),
|
161 |
+
);
|
162 |
+
|
163 |
+
// Set the presentation-wide settings
|
164 |
+
if ( '' != trim( $atts['transition'] ) )
|
165 |
+
$this->presentation_settings['transition'] = $atts['transition'];
|
166 |
+
|
167 |
+
if ( '' != trim( $atts['scale'] ) )
|
168 |
+
$this->presentation_settings['scale'] = floatval( $atts['scale'] );
|
169 |
+
|
170 |
+
if ( '' != trim( $atts['rotate'] ) )
|
171 |
+
$this->presentation_settings['rotate'] = floatval( $atts['rotate'] );
|
172 |
+
|
173 |
+
if ( '' != trim( $atts['fade'] ) )
|
174 |
+
$this->presentation_settings['fade'] = $atts['fade'];
|
175 |
+
|
176 |
+
// Set any settings the slides don't care about
|
177 |
+
if ( '' != trim( $atts['duration'] ) )
|
178 |
+
$duration = floatval( $atts['duration'] ) . 's';
|
179 |
+
else
|
180 |
+
$duration = '1s';
|
181 |
+
|
182 |
+
// Set the presentation size as specified or with some nicely sized dimensions
|
183 |
+
if ( '' != trim( $atts['width'] ) )
|
184 |
+
$this->presentation_settings['width'] = intval( $atts['width'] );
|
185 |
+
else
|
186 |
+
$this->presentation_settings['width'] = 480;
|
187 |
+
|
188 |
+
if ( '' != trim( $atts['height'] ) )
|
189 |
+
$this->presentation_settings['height'] = intval( $atts['height'] );
|
190 |
+
else
|
191 |
+
$this->presentation_settings['height'] = 370;
|
192 |
+
|
193 |
+
// Hide the content by default in case the scripts fail
|
194 |
+
$style = 'display: none; width: ' . $this->presentation_settings['width'] . 'px; height: ' . $this->presentation_settings['height'] . 'px;';
|
195 |
+
|
196 |
+
// Check for background color XOR background image
|
197 |
+
// Use a white background if nothing specified
|
198 |
+
if ( preg_match( '/https?\:\/\/[^\'"\s]*/', $atts['bgimg'], $matches ) ) {
|
199 |
+
$style .= ' background-image: url("' . esc_url( $matches[0] ) . '");';
|
200 |
+
} else if ( '' != trim( $atts['bgcolor'] ) ) {
|
201 |
+
$style .= ' background-color: ' . esc_attr( $atts['bgcolor'] ) . ';';
|
202 |
+
} else {
|
203 |
+
$style .= ' background-color: #fff;';
|
204 |
+
}
|
205 |
+
|
206 |
+
// Not supported message style is inlined incase the style sheet doesn't get included
|
207 |
+
$out = "<section class='presentation-wrapper'>";
|
208 |
+
$out.= "<p class='not-supported-msg' style='display: inherit; padding: 25%; text-align: center;'>";
|
209 |
+
$out.= __( 'This slideshow could not be started. Try refreshing the page or viewing it in another browser.', 'jetpack' ) . '</p>';
|
210 |
+
|
211 |
+
// Bail out unless the scripts were added
|
212 |
+
if ( $this->scripts_and_style_included ) {
|
213 |
+
$out.= "<div class='presentation' duration='$duration' style='$style'>";
|
214 |
+
$out.= "<div class='nav-arrow-left'></div>";
|
215 |
+
$out.= "<div class='nav-arrow-right'></div>";
|
216 |
+
$out.= "<div class='nav-fullscreen-button'></div>";
|
217 |
+
$out.= do_shortcode( $content );
|
218 |
+
$out.= "</section>";
|
219 |
+
}
|
220 |
+
|
221 |
+
$out.= "</section>";
|
222 |
+
|
223 |
+
$this->presentation_initialized = false;
|
224 |
+
return $out;
|
225 |
+
}
|
226 |
+
|
227 |
+
function slide_shortcode( $atts, $content = '' ) {
|
228 |
+
// Bail out unless wrapped by a [presentation] shortcode
|
229 |
+
if ( ! $this->presentation_initialized )
|
230 |
+
return $content;
|
231 |
+
|
232 |
+
$atts = shortcode_atts( array(
|
233 |
+
'transition' => '',
|
234 |
+
'scale' => '',
|
235 |
+
'rotate' => '',
|
236 |
+
'fade' => '',
|
237 |
+
'bgcolor' => '',
|
238 |
+
'bgimg' => '',
|
239 |
+
), $atts );
|
240 |
+
|
241 |
+
// Determine positioning based on transition
|
242 |
+
if ( '' == trim( $atts['transition'] ) )
|
243 |
+
$atts['transition'] = $this->presentation_settings['transition'];
|
244 |
+
|
245 |
+
// Setting the content scale
|
246 |
+
if ( '' == trim( $atts['scale'] ) )
|
247 |
+
$atts['scale'] = $this->presentation_settings['scale'];
|
248 |
+
|
249 |
+
if( '' == trim( $atts['scale'] ) )
|
250 |
+
$scale = 1;
|
251 |
+
else
|
252 |
+
$scale = floatval( $atts['scale'] );
|
253 |
+
|
254 |
+
if ( $scale < 0 )
|
255 |
+
$scale *= -1;
|
256 |
+
|
257 |
+
// Setting the content rotation
|
258 |
+
if ( '' == trim( $atts['rotate'] ) )
|
259 |
+
$atts['rotate'] = $this->presentation_settings['rotate'];
|
260 |
+
|
261 |
+
if( '' == trim( $atts['rotate'] ) )
|
262 |
+
$rotate = 0;
|
263 |
+
else
|
264 |
+
$rotate = floatval( $atts['rotate'] );
|
265 |
+
|
266 |
+
// Setting if the content should fade
|
267 |
+
if ( '' == trim( $atts['fade'] ) )
|
268 |
+
$atts['fade'] = $this->presentation_settings['fade'];
|
269 |
+
|
270 |
+
if ( 'on' == $atts['fade'] || 'true' == $atts['fade'] )
|
271 |
+
$fade = 'fade';
|
272 |
+
else
|
273 |
+
$fade = '';
|
274 |
+
|
275 |
+
$coords = $this->get_coords( array(
|
276 |
+
'transition' => $atts['transition'],
|
277 |
+
'scale' => $scale,
|
278 |
+
'rotate' => $rotate,
|
279 |
+
));
|
280 |
+
|
281 |
+
$x = $coords['x'];
|
282 |
+
$y = $coords['y'];
|
283 |
+
|
284 |
+
// Check for background color XOR background image
|
285 |
+
// Use a white background if nothing specified
|
286 |
+
if ( preg_match( '/https?\:\/\/[^\'"\s]*/', $atts['bgimg'], $matches ) ) {
|
287 |
+
$style = 'background-image: url("' . esc_url( $matches[0] ) . '");';
|
288 |
+
} else if ( '' != trim( $atts['bgcolor'] ) ) {
|
289 |
+
$style = 'background-color: ' . esc_attr( $atts['bgcolor'] ) . ';';
|
290 |
+
} else {
|
291 |
+
$style = '';
|
292 |
+
}
|
293 |
+
|
294 |
+
// Put everything together and let jmpress do the magic!
|
295 |
+
$out = "<div class='step $fade' data-x='$x' data-y='$y' data-scale='$scale' data-rotate='$rotate' style='$style'>";
|
296 |
+
$out.= "<div class='slide-content'>";
|
297 |
+
$out.= do_shortcode( $content );
|
298 |
+
$out.= "</div></div>";
|
299 |
+
return $out;
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Determines the position of the next slide based on the position and scaling of the previous slide.
|
304 |
+
*
|
305 |
+
* @param array $args: an array with the following key-value pairs
|
306 |
+
* string $transition: the transition name, "up", "down", "left", or "right"
|
307 |
+
* float $scale: the scale of the next slide (used to determine the position of the slide after that)
|
308 |
+
*
|
309 |
+
* @return array with the 'x' and 'y' coordinates of the slide
|
310 |
+
*/
|
311 |
+
function get_coords( $args ) {
|
312 |
+
if ( 0 == $args['scale'] )
|
313 |
+
$args['scale'] = 1;
|
314 |
+
|
315 |
+
$width = $this->presentation_settings['width'];
|
316 |
+
$height = $this->presentation_settings['height'];
|
317 |
+
$last = $this->presentation_settings['last'];
|
318 |
+
$scale = $last['scale'];
|
319 |
+
|
320 |
+
$next = array(
|
321 |
+
'x' => $last['x'],
|
322 |
+
'y' => $last['y'],
|
323 |
+
'scale' => $args['scale'],
|
324 |
+
'rotate' => $args['rotate'],
|
325 |
+
);
|
326 |
+
|
327 |
+
// All angles are measured from the vertical axis, so everything is backwards!
|
328 |
+
$diagAngle = atan2( $width, $height );
|
329 |
+
$diagonal = sqrt( pow( $width, 2 ) + pow( $height, 2 ) );
|
330 |
+
|
331 |
+
// We offset the angles by the angle formed by the diagonal so that
|
332 |
+
// we can multiply the sines directly against the diagonal length
|
333 |
+
$theta = deg2rad( $last['rotate'] ) - $diagAngle;
|
334 |
+
$phi = deg2rad( $next['rotate'] ) - $diagAngle;
|
335 |
+
|
336 |
+
// We start by displacing by the slide dimensions
|
337 |
+
$totalHorizDisp = $width * $scale;
|
338 |
+
$totalVertDisp = $height * $scale;
|
339 |
+
|
340 |
+
// If the previous slide was rotated, we add the incremental offset from the rotation
|
341 |
+
// Namely the difference between the regular dimension (no rotation) and the component
|
342 |
+
// of the diagonal for that angle
|
343 |
+
$totalHorizDisp += ( ( ( abs( sin( $theta ) ) * $diagonal) - $width ) / 2) * $scale;
|
344 |
+
$totalVertDisp += ( ( ( abs( cos( $theta ) ) * $diagonal) - $height) / 2) * $scale;
|
345 |
+
|
346 |
+
// Similarly, we check if the current slide has been rotated and add whatever additional
|
347 |
+
// offset has been added. This is so that two rotated corners don't clash with each other.
|
348 |
+
// Note: we are checking the raw angle relative to the vertical axis, NOT the diagonal angle.
|
349 |
+
if ( $next['rotate'] % 180 != 0 ){
|
350 |
+
$totalHorizDisp += ( abs( ( sin( $phi ) * $diagonal ) - $width ) / 2) * $next['scale'];
|
351 |
+
$totalVertDisp += ( abs( ( cos( $phi ) * $diagonal ) - $height ) / 2) * $next['scale'];
|
352 |
+
}
|
353 |
+
|
354 |
+
switch ( trim( $args['transition'] ) ) {
|
355 |
+
case 'none':
|
356 |
+
break;
|
357 |
+
|
358 |
+
case 'left':
|
359 |
+
$next['x'] -= $totalHorizDisp;
|
360 |
+
break;
|
361 |
+
|
362 |
+
case 'right':
|
363 |
+
$next['x'] += $totalHorizDisp;
|
364 |
+
break;
|
365 |
+
|
366 |
+
case 'up':
|
367 |
+
$next['y'] -= $totalVertDisp;
|
368 |
+
break;
|
369 |
+
|
370 |
+
case 'down':
|
371 |
+
default:
|
372 |
+
$next['y'] += $totalVertDisp;
|
373 |
+
break;
|
374 |
+
}
|
375 |
+
|
376 |
+
$this->presentation_settings['last'] = $next;
|
377 |
+
return $next;
|
378 |
+
}
|
379 |
+
}
|
380 |
+
|
381 |
+
$GLOBALS['presentations'] = new Presentations();
|
382 |
+
endif;
|
modules/shortcodes/twitter-timeline.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
add_shortcode( 'twitter-timeline', 'twitter_timeline_shortcode' );
|
3 |
+
|
4 |
+
function twitter_timeline_shortcode( $attr ) {
|
5 |
+
|
6 |
+
$default_atts = array(
|
7 |
+
'username' => '',
|
8 |
+
'id' => '',
|
9 |
+
'height' => 282,
|
10 |
+
'width' => 450,
|
11 |
+
|
12 |
+
);
|
13 |
+
|
14 |
+
$attr = shortcode_atts( $default_atts, $attr );
|
15 |
+
|
16 |
+
if ( $attr['username'] != preg_replace( '/[^A-Za-z0-9_]+/', '', $attr['username'] ) )
|
17 |
+
return '<!--' . __( 'Invalid username', 'jetpack' ) . '-->';
|
18 |
+
|
19 |
+
if ( ! is_numeric( $attr['id'] ) )
|
20 |
+
return '<!--' . __( 'Invalid id', 'jetpack' ) . '-->';
|
21 |
+
|
22 |
+
$tweets_by = sprintf( __( 'Tweets by @%s', 'jetpack' ), $attr['username'] );
|
23 |
+
$output = '<a class="twitter-timeline" width="' . (int)$attr['width'] . '" height="' . (int)$attr['width'] . '" href="' . esc_url( 'https://twitter.com/'. $attr['username'] ) . '" data-widget-id="' . (int)$attr['id'] . '">' . esc_html( $tweets_by ) . '</a>';
|
24 |
+
add_action( 'wp_footer', 'twitter_timeline_js' );
|
25 |
+
|
26 |
+
return $output;
|
27 |
+
}
|
28 |
+
|
29 |
+
function twitter_timeline_js() {
|
30 |
+
echo '<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>';
|
31 |
+
}
|
modules/shortcodes/vine.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Vine shortcode
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Vine embed code:
|
8 |
+
* <iframe class="vine-embed" src="https://vine.co/v/bjHh0zHdgZT" width="600" height="600" frameborder="0"></iframe>
|
9 |
+
* <script async src="//platform.vine.co/static/scripts/embed.js" charset="utf-8"></script>
|
10 |
+
*
|
11 |
+
* URL example:
|
12 |
+
* https://vine.co/v/bjHh0zHdgZT/
|
13 |
+
*
|
14 |
+
* Embed shortcode examples:
|
15 |
+
* [embed]https://vine.co/v/bjHh0zHdgZT[/embed]
|
16 |
+
* [embed width="300"]https://vine.co/v/bjHh0zHdgZT[/embed]
|
17 |
+
* [embed type="postcard" width="300"]https://vine.co/v/bjHh0zHdgZT[/embed]
|
18 |
+
**/
|
19 |
+
|
20 |
+
function vine_embed_video( $matches, $attr, $url, $rawattr ) {
|
21 |
+
static $vine_flag_embedded_script;
|
22 |
+
|
23 |
+
$max_height = 300;
|
24 |
+
$type = 'simple';
|
25 |
+
|
26 |
+
// Only allow 'postcard' or 'simple' types
|
27 |
+
if ( isset( $rawattr['type'] ) && $rawattr['type'] === 'postcard' )
|
28 |
+
$type = 'postcard';
|
29 |
+
|
30 |
+
$vine_size = Jetpack::get_content_width();
|
31 |
+
|
32 |
+
// If the user enters a value for width or height, we ignore the Jetpack::get_content_width()
|
33 |
+
if ( isset( $rawattr['width'] ) || isset( $rawattr['height'] ) ) {
|
34 |
+
// 300 is the minimum size that Vine provides for embeds. Lower than that, the postcard embeds looks weird.
|
35 |
+
$vine_size = max( $max_height, min( $attr['width'], $attr['height'] ) );
|
36 |
+
}
|
37 |
+
|
38 |
+
if ( empty( $vine_size ) ) {
|
39 |
+
$vine_size = $max_height;
|
40 |
+
}
|
41 |
+
|
42 |
+
$url = 'https://vine.co/v/' . $matches[1] . '/embed/' . $type;
|
43 |
+
$vine_html = sprintf( '<iframe class="vine-embed" src="%s" width="%s" height="%s" frameborder="0"></iframe>', esc_url( $url ), (int) $vine_size, (int) $vine_size );
|
44 |
+
|
45 |
+
if ( $vine_flag_embedded_script !== true ) {
|
46 |
+
$vine_html .= '<script async src="//platform.vine.co/static/scripts/embed.js" charset="utf-8"></script>';
|
47 |
+
$vine_flag_embedded_script = true;
|
48 |
+
}
|
49 |
+
|
50 |
+
return $vine_html;
|
51 |
+
}
|
52 |
+
wp_embed_register_handler( 'jetpack_vine', '#https?://vine.co/v/([a-z0-9]+).*#i', 'vine_embed_video' );
|
53 |
+
|
54 |
+
function vine_shortcode( $atts ) {
|
55 |
+
global $wp_embed;
|
56 |
+
|
57 |
+
if ( empty( $atts['url'] ) )
|
58 |
+
return '';
|
59 |
+
|
60 |
+
if ( ! preg_match( '#https?://vine.co/v/([a-z0-9]+).*#i', $atts['url'] ) )
|
61 |
+
return '';
|
62 |
+
|
63 |
+
return $wp_embed->shortcode( $atts, $atts['url'] );
|
64 |
+
}
|
65 |
+
add_shortcode( 'vine', 'vine_shortcode' );
|
modules/shortlinks.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 10
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
add_filter( 'get_shortlink', 'wpme_get_shortlink_handler', 1, 4 );
|
5 |
* Sort Order: 10
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
add_filter( 'get_shortlink', 'wpme_get_shortlink_handler', 1, 4 );
|
modules/stats.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 1
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
if ( defined( 'STATS_VERSION' ) ) {
|
5 |
* Sort Order: 1
|
6 |
* First Introduced: 1.1
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
if ( defined( 'STATS_VERSION' ) ) {
|
modules/subscriptions.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 3
|
6 |
* First Introduced: 1.2
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
|
@@ -82,7 +83,9 @@ class Jetpack_Subscriptions {
|
|
82 |
return false;
|
83 |
}
|
84 |
|
85 |
-
|
|
|
|
|
86 |
}
|
87 |
|
88 |
/**
|
@@ -280,7 +283,7 @@ class Jetpack_Subscriptions {
|
|
280 |
* unknown : strange error. Jetpack servers at WordPress.com returned something malformed.
|
281 |
* unknown_status : strange error. Jetpack servers at WordPress.com returned something I didn't understand.
|
282 |
*/
|
283 |
-
function subscribe( $email, $post_ids = 0, $async = true ) {
|
284 |
if ( !is_email( $email ) ) {
|
285 |
return new Jetpack_Error( 'invalid_email' );
|
286 |
}
|
@@ -299,9 +302,9 @@ class Jetpack_Subscriptions {
|
|
299 |
}
|
300 |
|
301 |
if ( $async ) {
|
302 |
-
Jetpack::xmlrpc_async_call( 'jetpack.subscribeToSite', $email, $post_id );
|
303 |
} else {
|
304 |
-
$xml->addCall( 'jetpack.subscribeToSite', $email, $post_id );
|
305 |
}
|
306 |
}
|
307 |
|
@@ -383,7 +386,17 @@ class Jetpack_Subscriptions {
|
|
383 |
$redirect_fragment = 'subscribe-blog';
|
384 |
}
|
385 |
|
386 |
-
$subscribe = Jetpack_Subscriptions::subscribe(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
|
388 |
if ( is_wp_error( $subscribe ) ) {
|
389 |
$error = $subscribe->get_error_code();
|
@@ -484,7 +497,17 @@ class Jetpack_Subscriptions {
|
|
484 |
if ( isset( $_REQUEST['subscribe_blog'] ) )
|
485 |
$post_ids[] = 0;
|
486 |
|
487 |
-
Jetpack_Subscriptions::subscribe(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
488 |
}
|
489 |
|
490 |
/**
|
@@ -527,10 +550,7 @@ class Jetpack_Subscriptions_Widget extends WP_Widget {
|
|
527 |
function widget( $args, $instance ) {
|
528 |
global $current_user;
|
529 |
|
530 |
-
$source
|
531 |
-
|
532 |
-
extract( $args );
|
533 |
-
|
534 |
$instance = wp_parse_args( (array) $instance, $this->defaults() );
|
535 |
$title = isset( $instance['title'] ) ? stripslashes( $instance['title'] ) : '';
|
536 |
$subscribe_text = isset( $instance['subscribe_text'] ) ? stripslashes( $instance['subscribe_text'] ) : '';
|
@@ -593,9 +613,9 @@ class Jetpack_Subscriptions_Widget extends WP_Widget {
|
|
593 |
<input type="hidden" name="source" value="<?php echo esc_url( $referer ); ?>" />
|
594 |
<input type="hidden" name="sub-type" value="<?php echo esc_attr( $source ); ?>" />
|
595 |
<input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $widget_id ); ?>" />
|
596 |
-
<?php
|
597 |
if ( is_user_logged_in() ) {
|
598 |
-
wp_nonce_field( 'blogsub_subscribe_'. get_current_blog_id(), '_wpnonce', false );
|
599 |
}
|
600 |
?>
|
601 |
<input type="submit" value="<?php echo esc_attr( $subscribe_button ); ?>" name="jetpack_subscriptions_widget" />
|
5 |
* Sort Order: 3
|
6 |
* First Introduced: 1.2
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
add_action( 'jetpack_modules_loaded', 'jetpack_subscriptions_load' );
|
83 |
return false;
|
84 |
}
|
85 |
|
86 |
+
if ( 'publish' === $post->post_status && strlen( (string) $post->post_password ) < 1 ) {
|
87 |
+
return apply_filters( 'jetpack_is_post_mailable', true );
|
88 |
+
}
|
89 |
}
|
90 |
|
91 |
/**
|
283 |
* unknown : strange error. Jetpack servers at WordPress.com returned something malformed.
|
284 |
* unknown_status : strange error. Jetpack servers at WordPress.com returned something I didn't understand.
|
285 |
*/
|
286 |
+
function subscribe( $email, $post_ids = 0, $async = true, $extra_data = array() ) {
|
287 |
if ( !is_email( $email ) ) {
|
288 |
return new Jetpack_Error( 'invalid_email' );
|
289 |
}
|
302 |
}
|
303 |
|
304 |
if ( $async ) {
|
305 |
+
Jetpack::xmlrpc_async_call( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data ) );
|
306 |
} else {
|
307 |
+
$xml->addCall( 'jetpack.subscribeToSite', $email, $post_id, serialize( $extra_data) );
|
308 |
}
|
309 |
}
|
310 |
|
386 |
$redirect_fragment = 'subscribe-blog';
|
387 |
}
|
388 |
|
389 |
+
$subscribe = Jetpack_Subscriptions::subscribe(
|
390 |
+
$_REQUEST['email'],
|
391 |
+
0,
|
392 |
+
false,
|
393 |
+
array(
|
394 |
+
'source' => 'widget',
|
395 |
+
'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
|
396 |
+
'comment_status' => '',
|
397 |
+
'server_data' => $_SERVER,
|
398 |
+
)
|
399 |
+
);
|
400 |
|
401 |
if ( is_wp_error( $subscribe ) ) {
|
402 |
$error = $subscribe->get_error_code();
|
497 |
if ( isset( $_REQUEST['subscribe_blog'] ) )
|
498 |
$post_ids[] = 0;
|
499 |
|
500 |
+
Jetpack_Subscriptions::subscribe(
|
501 |
+
$comment->comment_author_email,
|
502 |
+
$post_ids,
|
503 |
+
true,
|
504 |
+
array(
|
505 |
+
'source' => 'comment-form',
|
506 |
+
'widget-in-use' => is_active_widget( false, false, 'blog_subscription', true ) ? 'yes' : 'no',
|
507 |
+
'comment_status' => $approved,
|
508 |
+
'server_data' => $_SERVER,
|
509 |
+
)
|
510 |
+
);
|
511 |
}
|
512 |
|
513 |
/**
|
550 |
function widget( $args, $instance ) {
|
551 |
global $current_user;
|
552 |
|
553 |
+
$source = 'widget';
|
|
|
|
|
|
|
554 |
$instance = wp_parse_args( (array) $instance, $this->defaults() );
|
555 |
$title = isset( $instance['title'] ) ? stripslashes( $instance['title'] ) : '';
|
556 |
$subscribe_text = isset( $instance['subscribe_text'] ) ? stripslashes( $instance['subscribe_text'] ) : '';
|
613 |
<input type="hidden" name="source" value="<?php echo esc_url( $referer ); ?>" />
|
614 |
<input type="hidden" name="sub-type" value="<?php echo esc_attr( $source ); ?>" />
|
615 |
<input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $widget_id ); ?>" />
|
616 |
+
<?php
|
617 |
if ( is_user_logged_in() ) {
|
618 |
+
wp_nonce_field( 'blogsub_subscribe_'. get_current_blog_id(), '_wpnonce', false );
|
619 |
}
|
620 |
?>
|
621 |
<input type="submit" value="<?php echo esc_attr( $subscribe_button ); ?>" name="jetpack_subscriptions_widget" />
|
modules/theme-tools.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* Load code specific to themes or theme tools
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* INFINITE SCROLL
|
8 |
+
*/
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Load theme's infinite scroll annotation file, if present in the IS plugin.
|
12 |
+
* The `setup_theme` action is used because the annotation files should be using `after_setup_theme` to register support for IS.
|
13 |
+
*
|
14 |
+
* As released in Jetpack 2.0, a child theme's parent wasn't checked for in the plugin's bundled support, hence the convoluted way the parent is checked for now.
|
15 |
+
*
|
16 |
+
* @uses is_admin, wp_get_theme, get_theme, get_current_theme, apply_filters
|
17 |
+
* @action setup_theme
|
18 |
+
* @return null
|
19 |
+
*/
|
20 |
+
function jetpack_load_infinite_scroll_annotation() {
|
21 |
+
if ( is_admin() && isset( $_GET['page'] ) && 'jetpack' == $_GET['page'] ) {
|
22 |
+
$theme = function_exists( 'wp_get_theme' ) ? wp_get_theme() : get_theme( get_current_theme() );
|
23 |
+
|
24 |
+
if ( ! is_a( $theme, 'WP_Theme' ) && ! is_array( $theme ) )
|
25 |
+
return;
|
26 |
+
|
27 |
+
$customization_file = apply_filters( 'infinite_scroll_customization_file', dirname( __FILE__ ) . "/infinite-scroll/themes/{$theme['Stylesheet']}.php", $theme['Stylesheet'] );
|
28 |
+
|
29 |
+
if ( is_readable( $customization_file ) ) {
|
30 |
+
require_once( $customization_file );
|
31 |
+
}
|
32 |
+
elseif ( ! empty( $theme['Template'] ) ) {
|
33 |
+
$customization_file = dirname( __FILE__ ) . "/infinite-scroll/themes/{$theme['Template']}.php";
|
34 |
+
|
35 |
+
if ( is_readable( $customization_file ) )
|
36 |
+
require_once( $customization_file );
|
37 |
+
}
|
38 |
+
}
|
39 |
+
}
|
40 |
+
add_action( 'setup_theme', 'jetpack_load_infinite_scroll_annotation' );
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Prevent IS from being activated if theme doesn't support it
|
44 |
+
*
|
45 |
+
* @param bool $can_activate
|
46 |
+
* @filter jetpack_can_activate_infinite-scroll
|
47 |
+
* @return bool
|
48 |
+
*/
|
49 |
+
function jetpack_can_activate_infinite_scroll( $can_activate ) {
|
50 |
+
return (bool) current_theme_supports( 'infinite-scroll' );
|
51 |
+
}
|
52 |
+
add_filter( 'jetpack_can_activate_infinite-scroll', 'jetpack_can_activate_infinite_scroll' );
|
53 |
+
|
54 |
+
require_once( dirname( __FILE__ ) . '/featured-content/featured-content.php' );
|
55 |
+
|
56 |
+
require_once( dirname( __FILE__ ) . '/social-links.php' );
|
57 |
+
|
58 |
+
// Custom Post Types - we don't want a module card for these (yet)
|
59 |
+
require_once( dirname( __FILE__ ) . '/custom-post-types/comics.php' );
|
60 |
+
require_once( dirname( __FILE__ ) . '/custom-post-types/testimonial.php' );
|
61 |
+
|
62 |
+
require_once( dirname( __FILE__ ) . '/random-redirect.php' );
|
modules/tiled-gallery.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Module Description: Create elegant magazine-style mosaic layouts for your photos without using an external graphic editor.
|
6 |
* First Introduced: 2.1
|
7 |
* Requires Connection: Yes
|
|
|
8 |
*/
|
9 |
|
10 |
function jetpack_load_tiled_gallery() {
|
5 |
* Module Description: Create elegant magazine-style mosaic layouts for your photos without using an external graphic editor.
|
6 |
* First Introduced: 2.1
|
7 |
* Requires Connection: Yes
|
8 |
+
* Auto Activate: No
|
9 |
*/
|
10 |
|
11 |
function jetpack_load_tiled_gallery() {
|
modules/tiled-gallery/tiled-gallery.php
CHANGED
@@ -59,6 +59,11 @@ class Jetpack_Tiled_Gallery {
|
|
59 |
foreach ( $_attachments as $key => $val ) {
|
60 |
$attachments[$val->ID] = $_attachments[$key];
|
61 |
}
|
|
|
|
|
|
|
|
|
|
|
62 |
} elseif ( !empty( $exclude ) ) {
|
63 |
$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
|
64 |
$attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
|
59 |
foreach ( $_attachments as $key => $val ) {
|
60 |
$attachments[$val->ID] = $_attachments[$key];
|
61 |
}
|
62 |
+
} elseif ( 0 == $id ) {
|
63 |
+
// Should NEVER Happen but infinite_scroll_load_other_plugins_scripts means it does
|
64 |
+
// Querying with post_parent == 0 can generate stupidly memcache sets on sites with 10000's of unattached attachments as get_children puts every post in the cache.
|
65 |
+
// TODO Fix this properly
|
66 |
+
$attachments = array();
|
67 |
} elseif ( !empty( $exclude ) ) {
|
68 |
$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
|
69 |
$attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
|
modules/vaultpress.php
CHANGED
@@ -7,6 +7,7 @@
|
|
7 |
* Deactivate: false
|
8 |
* Free: false
|
9 |
* Requires Connection: Yes
|
|
|
10 |
*/
|
11 |
|
12 |
add_action( 'jetpack_modules_loaded', 'vaultpress_jetpack_stub' );
|
7 |
* Deactivate: false
|
8 |
* Free: false
|
9 |
* Requires Connection: Yes
|
10 |
+
* Auto Activate: Yes
|
11 |
*/
|
12 |
|
13 |
add_action( 'jetpack_modules_loaded', 'vaultpress_jetpack_stub' );
|
modules/widget-visibility.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Module Name: Widget Visibility
|
5 |
+
* Module Description: Control what pages your widgets appear on.
|
6 |
+
* First Introduced: 2.4
|
7 |
+
* Requires Connection: No
|
8 |
+
* Auto Activate: Yes
|
9 |
+
*/
|
10 |
+
|
11 |
+
include dirname( __FILE__ ) . "/widget-visibility/widget-conditions.php";
|
modules/widget-visibility/widget-conditions.php
ADDED
@@ -0,0 +1,379 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Hide or show widgets conditionally.
|
6 |
+
*/
|
7 |
+
|
8 |
+
class Jetpack_Widget_Conditions {
|
9 |
+
public static function init() {
|
10 |
+
if ( is_admin() ) {
|
11 |
+
add_action( 'sidebar_admin_setup', array( __CLASS__, 'widget_admin_setup' ) );
|
12 |
+
add_filter( 'widget_update_callback', array( __CLASS__, 'widget_update' ), 10, 3 );
|
13 |
+
add_action( 'in_widget_form', array( __CLASS__, 'widget_conditions_admin' ), 10, 3 );
|
14 |
+
add_action( 'wp_ajax_widget_conditions_options', array( __CLASS__, 'widget_conditions_options' ) );
|
15 |
+
}
|
16 |
+
else {
|
17 |
+
add_action( 'widget_display_callback', array( __CLASS__, 'filter_widget' ) );
|
18 |
+
add_action( 'sidebars_widgets', array( __CLASS__, 'sidebars_widgets' ) );
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
22 |
+
public static function widget_admin_setup() {
|
23 |
+
wp_enqueue_style( 'widget-conditions', plugins_url( 'widget-conditions/widget-conditions.css', __FILE__ ) );
|
24 |
+
wp_enqueue_script( 'widget-conditions', plugins_url( 'widget-conditions/widget-conditions.js', __FILE__ ), array( 'jquery', 'jquery-ui-core' ), 20130129, true );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Provided a second level of granularity for widget conditions.
|
29 |
+
*/
|
30 |
+
public static function widget_conditions_options_echo( $major = '', $minor = '' ) {
|
31 |
+
switch ( $major ) {
|
32 |
+
case 'category':
|
33 |
+
?>
|
34 |
+
<option value=""><?php _e( 'All category pages', 'jetpack' ); ?></option>
|
35 |
+
<?php
|
36 |
+
|
37 |
+
$categories = get_categories( array( 'number' => 1000, 'orderby' => 'count', 'order' => 'DESC' ) );
|
38 |
+
usort( $categories, array( __CLASS__, 'strcasecmp_name' ) );
|
39 |
+
|
40 |
+
foreach ( $categories as $category ) {
|
41 |
+
?>
|
42 |
+
<option value="<?php echo esc_attr( $category->term_id ); ?>" <?php selected( $category->term_id, $minor ); ?>><?php echo esc_html( $category->name ); ?></option>
|
43 |
+
<?php
|
44 |
+
}
|
45 |
+
break;
|
46 |
+
case 'author':
|
47 |
+
?>
|
48 |
+
<option value=""><?php _e( 'All author pages', 'jetpack' ); ?></option>
|
49 |
+
<?php
|
50 |
+
|
51 |
+
foreach ( get_users( array( 'orderby' => 'name', 'exclude_admin' => true ) ) as $author ) {
|
52 |
+
?>
|
53 |
+
<option value="<?php echo esc_attr( $author->ID ); ?>" <?php selected( $author->ID, $minor ); ?>><?php echo esc_html( $author->display_name ); ?></option>
|
54 |
+
<?php
|
55 |
+
}
|
56 |
+
break;
|
57 |
+
case 'tag':
|
58 |
+
?>
|
59 |
+
<option value=""><?php _e( 'All tag pages', 'jetpack' ); ?></option>
|
60 |
+
<?php
|
61 |
+
|
62 |
+
$tags = get_tags( array( 'number' => 1000, 'orderby' => 'count', 'order' => 'DESC' ) );
|
63 |
+
usort( $tags, array( __CLASS__, 'strcasecmp_name' ) );
|
64 |
+
|
65 |
+
foreach ( $tags as $tag ) {
|
66 |
+
?>
|
67 |
+
<option value="<?php echo esc_attr($tag->term_id ); ?>" <?php selected( $tag->term_id, $minor ); ?>><?php echo esc_html( $tag->name ); ?></option>
|
68 |
+
<?php
|
69 |
+
}
|
70 |
+
break;
|
71 |
+
case 'date':
|
72 |
+
?>
|
73 |
+
<option value="" <?php selected( '', $minor ); ?>><?php _e( 'All date archives', 'jetpack' ); ?></option>
|
74 |
+
<option value="day"<?php selected( 'day', $minor ); ?>><?php _e( 'Daily archives', 'jetpack' ); ?></option>
|
75 |
+
<option value="month"<?php selected( 'month', $minor ); ?>><?php _e( 'Monthly archives', 'jetpack' ); ?></option>
|
76 |
+
<option value="year"<?php selected( 'year', $minor ); ?>><?php _e( 'Yearly archives', 'jetpack' ); ?></option>
|
77 |
+
<?php
|
78 |
+
break;
|
79 |
+
case 'page':
|
80 |
+
// Previously hardcoded post type options.
|
81 |
+
if ( ! $minor )
|
82 |
+
$minor = 'post_type-page';
|
83 |
+
else if ( 'post' == $minor )
|
84 |
+
$minor = 'post_type-post';
|
85 |
+
|
86 |
+
?>
|
87 |
+
<option value="front" <?php selected( 'front', $minor ); ?>><?php _e( 'Front page', 'jetpack' ); ?></option>
|
88 |
+
<option value="posts" <?php selected( 'posts', $minor ); ?>><?php _e( 'Posts page', 'jetpack' ); ?></option>
|
89 |
+
<option value="404" <?php selected( '404', $minor ); ?>><?php _e( '404 error page', 'jetpack' ); ?></option>
|
90 |
+
<option value="search" <?php selected( 'search', $minor ); ?>><?php _e( 'Search results', 'jetpack' ); ?></option>
|
91 |
+
<optgroup label="<?php esc_attr_e( 'Post type:', 'jetpack' ); ?>">
|
92 |
+
<?php
|
93 |
+
|
94 |
+
$post_types = get_post_types( array( 'public' => true ), 'objects' );
|
95 |
+
|
96 |
+
foreach ( $post_types as $post_type ) {
|
97 |
+
?>
|
98 |
+
<option value="<?php echo esc_attr( 'post_type-' . $post_type->name ); ?>" <?php selected( 'post_type-' . $post_type->name, $minor ); ?>><?php echo esc_html( $post_type->labels->singular_name ); ?></option>
|
99 |
+
<?php
|
100 |
+
}
|
101 |
+
|
102 |
+
?>
|
103 |
+
</optgroup>
|
104 |
+
<optgroup label="<?php esc_attr_e( 'Static page:', 'jetpack' ); ?>">
|
105 |
+
<?php
|
106 |
+
|
107 |
+
echo str_replace( ' value="' . esc_attr( $minor ) . '"', ' value="' . esc_attr( $minor ) . '" selected="selected"', preg_replace( '/<\/?select[^>]*?>/i', '', wp_dropdown_pages( array( 'echo' => false ) ) ) );
|
108 |
+
|
109 |
+
?>
|
110 |
+
</optgroup>
|
111 |
+
<?php
|
112 |
+
break;
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* This is the AJAX endpoint for the second level of conditions.
|
118 |
+
*/
|
119 |
+
public static function widget_conditions_options() {
|
120 |
+
self::widget_conditions_options_echo( $_REQUEST['major'], isset( $_REQUEST['minor'] ) ? $_REQUEST['minor'] : '' );
|
121 |
+
die;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Add the widget conditions to each widget in the admin.
|
126 |
+
*
|
127 |
+
* @param $widget unused.
|
128 |
+
* @param $return unused.
|
129 |
+
* @param array $instance The widget settings.
|
130 |
+
*/
|
131 |
+
public static function widget_conditions_admin( $widget, $return, $instance ) {
|
132 |
+
$conditions = array();
|
133 |
+
|
134 |
+
if ( isset( $instance['conditions'] ) )
|
135 |
+
$conditions = $instance['conditions'];
|
136 |
+
|
137 |
+
if ( ! isset( $conditions['action'] ) )
|
138 |
+
$conditions['action'] = 'show';
|
139 |
+
|
140 |
+
if ( empty( $conditions['rules'] ) )
|
141 |
+
$conditions['rules'][] = array( 'major' => '', 'minor' => '' );
|
142 |
+
|
143 |
+
?>
|
144 |
+
<div class="widget-conditional <?php if ( empty( $_POST['widget-conditions-visible'] ) || $_POST['widget-conditions-visible'] == '0' ) { ?>widget-conditional-hide<?php } ?>">
|
145 |
+
<input type="hidden" name="widget-conditions-visible" value="<?php if ( isset( $_POST['widget-conditions-visible'] ) ) { echo esc_attr( $_POST['widget-conditions-visible'] ); } else { ?>0<?php } ?>" />
|
146 |
+
<?php if ( ! isset( $_POST['widget-conditions-visible'] ) ) { ?><a href="#" class="button display-options"><?php _e( 'Visibility', 'jetpack' ); ?></a><?php } ?>
|
147 |
+
<div class="widget-conditional-inner">
|
148 |
+
<div class="condition-top">
|
149 |
+
<?php printf( _x( '%s if:', 'placeholder: dropdown menu to select widget visibility; hide if or show if', 'jetpack' ), '<select name="conditions[action]"><option value="show" ' . selected( $conditions['action'], 'show', false ) . '>' . esc_html_x( 'Show', 'Used in the "%s if:" translation for the widget visibility dropdown', 'jetpack' ) . '</option><option value="hide" ' . selected( $conditions['action'], 'hide', false ) . '>' . esc_html_x( 'Hide', 'Used in the "%s if:" translation for the widget visibility dropdown', 'jetpack' ) . '</option></select>' ); ?>
|
150 |
+
</div><!-- .condition-top -->
|
151 |
+
|
152 |
+
<div class="conditions">
|
153 |
+
<?php
|
154 |
+
|
155 |
+
foreach ( $conditions['rules'] as $rule ) {
|
156 |
+
?>
|
157 |
+
<div class="condition">
|
158 |
+
<div class="alignleft">
|
159 |
+
<select class="conditions-rule-major" name="conditions[rules_major][]">
|
160 |
+
<option value="" <?php selected( "", $rule['major'] ); ?>><?php echo esc_html_x( '-- Select --', 'Used as the default option in a dropdown list', 'jetpack' ); ?></option>
|
161 |
+
<option value="category" <?php selected( "category", $rule['major'] ); ?>><?php esc_html_e( 'Category', 'jetpack' ); ?></option>
|
162 |
+
<option value="author" <?php selected( "author", $rule['major'] ); ?>><?php echo esc_html_x( 'Author', 'Noun, as in: "The author of this post is..."', 'jetpack' ); ?></option>
|
163 |
+
<option value="tag" <?php selected( "tag", $rule['major'] ); ?>><?php echo esc_html_x( 'Tag', 'Noun, as in: "This post has one tag."', 'jetpack' ); ?></option>
|
164 |
+
<option value="date" <?php selected( "date", $rule['major'] ); ?>><?php echo esc_html_x( 'Date', 'Noun, as in: "This page is a date archive."', 'jetpack' ); ?></option>
|
165 |
+
<option value="page" <?php selected( "page", $rule['major'] ); ?>><?php echo esc_html_x( 'Page', 'Example: The user is looking at a page, not a post.', 'jetpack' ); ?></option>
|
166 |
+
</select>
|
167 |
+
<?php _ex( 'is', 'Widget Visibility: {Rule Major [Page]} is {Rule Minor [Search results]}', 'jetpack' ); ?>
|
168 |
+
<select class="conditions-rule-minor" name="conditions[rules_minor][]" <?php if ( ! $rule['major'] ) { ?> disabled="disabled"<?php } ?> data-loading-text="<?php esc_attr_e( 'Loading...', 'jetpack' ); ?>">
|
169 |
+
<?php self::widget_conditions_options_echo( $rule['major'], $rule['minor'] ); ?>
|
170 |
+
</select>
|
171 |
+
<span class="condition-conjunction"><?php echo esc_html_x( 'or', 'Shown between widget visibility conditions.', 'jetpack' ); ?></span>
|
172 |
+
</div>
|
173 |
+
<div class="condition-control alignright">
|
174 |
+
<a href="#" class="delete-condition"><?php esc_html_e( 'Delete', 'jetpack' ); ?></a> | <a href="#" class="add-condition"><?php esc_html_e( 'Add', 'jetpack' ); ?></a>
|
175 |
+
</div>
|
176 |
+
<br class="clear" />
|
177 |
+
</div><!-- .condition -->
|
178 |
+
<?php
|
179 |
+
}
|
180 |
+
|
181 |
+
?>
|
182 |
+
</div><!-- .conditions -->
|
183 |
+
</div><!-- .widget-conditional-inner -->
|
184 |
+
</div><!-- .widget-conditional -->
|
185 |
+
<?php
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* On an AJAX update of the widget settings, process the display conditions.
|
190 |
+
*
|
191 |
+
* @param array $new_instance New settings for this instance as input by the user.
|
192 |
+
* @param array $old_instance Old settings for this instance.
|
193 |
+
* @return array Modified settings.
|
194 |
+
*/
|
195 |
+
public static function widget_update( $instance, $new_instance, $old_instance ) {
|
196 |
+
$conditions = array();
|
197 |
+
$conditions['action'] = $_POST['conditions']['action'];
|
198 |
+
$conditions['rules'] = array();
|
199 |
+
|
200 |
+
foreach ( $_POST['conditions']['rules_major'] as $index => $major_rule ) {
|
201 |
+
if ( ! $major_rule )
|
202 |
+
continue;
|
203 |
+
|
204 |
+
$conditions['rules'][] = array(
|
205 |
+
'major' => $major_rule,
|
206 |
+
'minor' => isset( $_POST['conditions']['rules_minor'][$index] ) ? $_POST['conditions']['rules_minor'][$index] : ''
|
207 |
+
);
|
208 |
+
}
|
209 |
+
|
210 |
+
if ( ! empty( $conditions['rules'] ) )
|
211 |
+
$instance['conditions'] = $conditions;
|
212 |
+
else
|
213 |
+
unset( $instance['conditions'] );
|
214 |
+
|
215 |
+
if (
|
216 |
+
( isset( $instance['conditions'] ) && ! isset( $old_instance['conditions'] ) )
|
217 |
+
||
|
218 |
+
(
|
219 |
+
isset( $instance['conditions'], $old_instance['conditions'] )
|
220 |
+
&&
|
221 |
+
serialize( $instance['conditions'] ) != serialize( $old_instance['conditions'] )
|
222 |
+
)
|
223 |
+
) {
|
224 |
+
do_action( 'widget_conditions_save' );
|
225 |
+
}
|
226 |
+
else if ( ! isset( $instance['conditions'] ) && isset( $old_instance['conditions'] ) ) {
|
227 |
+
do_action( 'widget_conditions_delete' );
|
228 |
+
}
|
229 |
+
|
230 |
+
return $instance;
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Filter the list of widgets for a sidebar so that active sidebars work as expected.
|
235 |
+
*
|
236 |
+
* @param array $widget_areas An array of widget areas and their widgets.
|
237 |
+
* @return array The modified $widget_area array.
|
238 |
+
*/
|
239 |
+
public static function sidebars_widgets( $widget_areas ) {
|
240 |
+
$settings = array();
|
241 |
+
|
242 |
+
foreach ( $widget_areas as $widget_area => $widgets ) {
|
243 |
+
if ( empty( $widgets ) )
|
244 |
+
continue;
|
245 |
+
|
246 |
+
if ( 'wp_inactive_widgets' == $widget_area )
|
247 |
+
continue;
|
248 |
+
|
249 |
+
foreach ( $widgets as $position => $widget_id ) {
|
250 |
+
// Find the conditions for this widget.
|
251 |
+
list( $basename, $suffix ) = explode( "-", $widget_id, 2 );
|
252 |
+
|
253 |
+
if ( ! isset( $settings[$basename] ) )
|
254 |
+
$settings[$basename] = get_option( 'widget_' . $basename );
|
255 |
+
|
256 |
+
if ( isset( $settings[$basename][$suffix] ) ) {
|
257 |
+
if ( false === self::filter_widget( $settings[$basename][$suffix] ) )
|
258 |
+
unset( $widget_areas[$widget_area][$position] );
|
259 |
+
}
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
return $widget_areas;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Determine whether the widget should be displayed based on conditions set by the user.
|
268 |
+
*
|
269 |
+
* @param array $instance The widget settings.
|
270 |
+
* @return array Settings to display or bool false to hide.
|
271 |
+
*/
|
272 |
+
public static function filter_widget( $instance ) {
|
273 |
+
global $post, $wp_query;
|
274 |
+
|
275 |
+
if ( empty( $instance['conditions'] ) || empty( $instance['conditions']['rules'] ) )
|
276 |
+
return $instance;
|
277 |
+
|
278 |
+
$condition_result = false;
|
279 |
+
|
280 |
+
foreach ( $instance['conditions']['rules'] as $rule ) {
|
281 |
+
switch ( $rule['major'] ) {
|
282 |
+
case 'date':
|
283 |
+
switch ( $rule['minor'] ) {
|
284 |
+
case '':
|
285 |
+
$condition_result = is_date();
|
286 |
+
break;
|
287 |
+
case 'month':
|
288 |
+
$condition_result = is_month();
|
289 |
+
break;
|
290 |
+
case 'day':
|
291 |
+
$condition_result = is_day();
|
292 |
+
break;
|
293 |
+
case 'year':
|
294 |
+
$condition_result = is_year();
|
295 |
+
break;
|
296 |
+
}
|
297 |
+
break;
|
298 |
+
case 'page':
|
299 |
+
// Previously hardcoded post type options.
|
300 |
+
if ( 'post' == $rule['minor'] )
|
301 |
+
$rule['minor'] = 'post_type-post';
|
302 |
+
else if ( ! $rule['minor'] )
|
303 |
+
$rule['minor'] = 'post_type-page';
|
304 |
+
|
305 |
+
switch ( $rule['minor'] ) {
|
306 |
+
case '404':
|
307 |
+
$condition_result = is_404();
|
308 |
+
break;
|
309 |
+
case 'search':
|
310 |
+
$condition_result = is_search();
|
311 |
+
break;
|
312 |
+
case 'archive':
|
313 |
+
$condition_result = is_archive();
|
314 |
+
break;
|
315 |
+
case 'posts':
|
316 |
+
$condition_result = $wp_query->is_posts_page;
|
317 |
+
break;
|
318 |
+
case 'home':
|
319 |
+
$condition_result = is_home();
|
320 |
+
break;
|
321 |
+
case 'front':
|
322 |
+
$condition_result = is_front_page();
|
323 |
+
break;
|
324 |
+
default:
|
325 |
+
if ( substr( $rule['minor'], 0, 10 ) == 'post_type-' )
|
326 |
+
$condition_result = is_singular( substr( $rule['minor'], 10 ) );
|
327 |
+
else {
|
328 |
+
// $rule['minor'] is a page ID
|
329 |
+
$condition_result = is_page( $rule['minor'] );
|
330 |
+
}
|
331 |
+
break;
|
332 |
+
}
|
333 |
+
break;
|
334 |
+
case 'tag':
|
335 |
+
if ( ! $rule['minor'] && is_tag() )
|
336 |
+
$condition_result = true;
|
337 |
+
else if ( is_singular() && $rule['minor'] && has_tag( $rule['minor'] ) )
|
338 |
+
$condition_result = true;
|
339 |
+
else {
|
340 |
+
$tag = get_tag( $rule['minor'] );
|
341 |
+
|
342 |
+
if ( $tag && is_tag( $tag->slug ) )
|
343 |
+
$condition_result = true;
|
344 |
+
}
|
345 |
+
break;
|
346 |
+
case 'category':
|
347 |
+
if ( ! $rule['minor'] && is_category() )
|
348 |
+
$condition_result = true;
|
349 |
+
else if ( is_category( $rule['minor'] ) )
|
350 |
+
$condition_result = true;
|
351 |
+
else if ( is_singular() && $rule['minor'] && has_category( $rule['minor'] ) )
|
352 |
+
$condition_result = true;
|
353 |
+
break;
|
354 |
+
case 'author':
|
355 |
+
if ( ! $rule['minor'] && is_author() )
|
356 |
+
$condition_result = true;
|
357 |
+
else if ( $rule['minor'] && is_author( $rule['minor'] ) )
|
358 |
+
$condition_result = true;
|
359 |
+
else if ( is_singular() && $rule['minor'] && $rule['minor'] == $post->post_author )
|
360 |
+
$condition_result = true;
|
361 |
+
break;
|
362 |
+
}
|
363 |
+
|
364 |
+
if ( $condition_result )
|
365 |
+
break;
|
366 |
+
}
|
367 |
+
|
368 |
+
if ( ( 'show' == $instance['conditions']['action'] && ! $condition_result ) || ( 'hide' == $instance['conditions']['action'] && $condition_result ) )
|
369 |
+
return false;
|
370 |
+
|
371 |
+
return $instance;
|
372 |
+
}
|
373 |
+
|
374 |
+
public static function strcasecmp_name( $a, $b ) {
|
375 |
+
return strcasecmp( $a->name, $b->name );
|
376 |
+
}
|
377 |
+
}
|
378 |
+
|
379 |
+
add_action( 'init', array( 'Jetpack_Widget_Conditions', 'init' ) );
|
modules/widget-visibility/widget-conditions/rtl/widget-conditions-rtl.css
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file was automatically generated on Mar 14 2013 17:20:54 */
|
2 |
+
|
3 |
+
.widget-liquid-right .widget.expanded {
|
4 |
+
overflow: visible;
|
5 |
+
}
|
6 |
+
.widget-conditional-hide {
|
7 |
+
display: none;
|
8 |
+
}
|
9 |
+
.widget-conditional .widget-conditional-inner {
|
10 |
+
background: #F9F9F9;
|
11 |
+
border: 1px solid #DFDFDF;
|
12 |
+
padding: 12px 12px 0;
|
13 |
+
}
|
14 |
+
.widget-conditional .condition,
|
15 |
+
.widget-conditional .condition-top {
|
16 |
+
margin-bottom: 12px;
|
17 |
+
}
|
18 |
+
.widget-conditional .condition select {
|
19 |
+
width: 120px;
|
20 |
+
}
|
21 |
+
.widget-conditional .condition-top select {
|
22 |
+
width: auto;
|
23 |
+
}
|
24 |
+
.widget-conditional .condition .alignright {
|
25 |
+
padding-top: 4px;
|
26 |
+
}
|
27 |
+
.widget-conditional .condition-control a {
|
28 |
+
text-decoration: none;
|
29 |
+
}
|
30 |
+
.widget-conditional .condition:last-child .condition-conjunction {
|
31 |
+
display: none;
|
32 |
+
}
|
33 |
+
.widget-control-actions .alignright {
|
34 |
+
text-align: left;
|
35 |
+
}
|
36 |
+
.wp-core-ui .button.display-options {
|
37 |
+
margin-left: 5px;
|
38 |
+
}
|
39 |
+
.wp-core-ui .button.display-options:hover {
|
40 |
+
text-decoration: none;
|
41 |
+
}
|
modules/widget-visibility/widget-conditions/widget-conditions.css
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.widget-liquid-right .widget.expanded {
|
2 |
+
overflow: visible;
|
3 |
+
}
|
4 |
+
.widget-conditional-hide {
|
5 |
+
display: none;
|
6 |
+
}
|
7 |
+
.widget-conditional .widget-conditional-inner {
|
8 |
+
background: #F9F9F9;
|
9 |
+
border: 1px solid #DFDFDF;
|
10 |
+
padding: 12px 12px 0;
|
11 |
+
}
|
12 |
+
.widget-conditional .condition,
|
13 |
+
.widget-conditional .condition-top {
|
14 |
+
margin-bottom: 12px;
|
15 |
+
}
|
16 |
+
.widget-conditional .condition select {
|
17 |
+
width: 120px;
|
18 |
+
}
|
19 |
+
.widget-conditional .condition-top select {
|
20 |
+
width: auto;
|
21 |
+
}
|
22 |
+
.widget-conditional .condition .alignright {
|
23 |
+
padding-top: 4px;
|
24 |
+
}
|
25 |
+
.widget-conditional .condition-control a {
|
26 |
+
text-decoration: none;
|
27 |
+
}
|
28 |
+
.widget-conditional .condition:last-child .condition-conjunction {
|
29 |
+
display: none;
|
30 |
+
}
|
31 |
+
.widget-control-actions .alignright {
|
32 |
+
text-align: right;
|
33 |
+
}
|
34 |
+
.wp-core-ui .button.display-options {
|
35 |
+
margin-right: 5px;
|
36 |
+
}
|
37 |
+
.wp-core-ui .button.display-options:hover {
|
38 |
+
text-decoration: none;
|
39 |
+
}
|
modules/widget-visibility/widget-conditions/widget-conditions.js
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery( function( $ ) {
|
2 |
+
function setWidgetMargin( $widget ) {
|
3 |
+
if ( $widget.hasClass( 'expanded' ) ) {
|
4 |
+
// The expanded widget must be at least 400px wide in order to
|
5 |
+
// contain the visibility settings. IE wasn't handling the
|
6 |
+
// margin-left value properly.
|
7 |
+
|
8 |
+
if ( $widget.attr( 'style' ) )
|
9 |
+
$widget.data( 'original-style', $widget.attr( 'style' ) );
|
10 |
+
|
11 |
+
var currentWidth = $widget.width();
|
12 |
+
|
13 |
+
if ( currentWidth < 400 ) {
|
14 |
+
var extra = 400 - currentWidth;
|
15 |
+
$widget.css( 'position', 'relative' ).css( 'left', '-' + extra + 'px' ).css( 'width', '400px' );
|
16 |
+
}
|
17 |
+
}
|
18 |
+
else if ( $widget.data( 'original-style' ) ) {
|
19 |
+
// Restore any original inline styles when visibility is toggled off.
|
20 |
+
$widget.attr( 'style', $widget.data( 'original-style' ) ).data( 'original-style', null );
|
21 |
+
}
|
22 |
+
else {
|
23 |
+
$widget.removeAttr( 'style' );
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
$( "a.display-options" ).each( function() {
|
28 |
+
var $displayOptionsButton = $( this ),
|
29 |
+
$widget = $displayOptionsButton.closest( "div.widget" );
|
30 |
+
$displayOptionsButton.insertBefore( $widget.find( "input.widget-control-save" ) );
|
31 |
+
|
32 |
+
// Widgets with no configurable options don't show the Save button's container.
|
33 |
+
$displayOptionsButton
|
34 |
+
.parent()
|
35 |
+
.removeClass( 'widget-control-noform' )
|
36 |
+
.find( '.spinner' )
|
37 |
+
.remove()
|
38 |
+
.css( 'float', 'left' )
|
39 |
+
.prependTo( $displayOptionsButton.parent() );
|
40 |
+
|
41 |
+
} );
|
42 |
+
|
43 |
+
$( "div#widgets-right" ).on( "click", "a.add-condition", function( e ) {
|
44 |
+
e.preventDefault();
|
45 |
+
var $condition = $( this ).closest( "div.condition" ),
|
46 |
+
$conditionClone = $condition.clone().insertAfter( $condition );
|
47 |
+
$conditionClone.find( "select.conditions-rule-major" ).val( "" );
|
48 |
+
$conditionClone.find( "select.conditions-rule-minor" ).html( "" ).attr( "disabled" );
|
49 |
+
} ).on( "click", "a.display-options", function ( e ) {
|
50 |
+
e.preventDefault();
|
51 |
+
|
52 |
+
var $displayOptionsButton = $( this ),
|
53 |
+
$widget = $displayOptionsButton.closest( "div.widget" );
|
54 |
+
|
55 |
+
$widget.find( "div.widget-conditional" ).toggleClass( "widget-conditional-hide" );
|
56 |
+
$( this ).toggleClass( "active" );
|
57 |
+
$widget.toggleClass( "expanded" );
|
58 |
+
setWidgetMargin( $widget );
|
59 |
+
|
60 |
+
if ( $( this ).hasClass( 'active' ) )
|
61 |
+
$widget.find( 'input[name=widget-conditions-visible]' ).val( '1' );
|
62 |
+
else
|
63 |
+
$widget.find( 'input[name=widget-conditions-visible]' ).val( '0' );
|
64 |
+
|
65 |
+
} );
|
66 |
+
|
67 |
+
$( "div#widgets-right" ).on( "click", "a.delete-condition", function( e ) {
|
68 |
+
e.preventDefault();
|
69 |
+
|
70 |
+
var $condition = $( this ).closest( "div.condition" );
|
71 |
+
|
72 |
+
if ( $condition.is( ":first-child" ) && $condition.is( ":last-child" ) ) {
|
73 |
+
$( this ).closest( "div.widget" ).find( "a.display-options" ).click();
|
74 |
+
$condition.find( "select.conditions-rule-major" ).val( "" ).change();
|
75 |
+
} else {
|
76 |
+
$condition.detach();
|
77 |
+
}
|
78 |
+
} ).on( "click", "div.widget-top", function() {
|
79 |
+
var $widget = $( this ).closest( "div.widget" ),
|
80 |
+
$displayOptionsButton = $widget.find( "a.display-options" );
|
81 |
+
|
82 |
+
if ( $displayOptionsButton.hasClass( "active" ) ) {
|
83 |
+
$displayOptionsButton.attr( "opened", "true" );
|
84 |
+
}
|
85 |
+
|
86 |
+
if ( $displayOptionsButton.attr( "opened" ) ) {
|
87 |
+
$displayOptionsButton.removeAttr( "opened" );
|
88 |
+
$widget.toggleClass( "expanded" );
|
89 |
+
setWidgetMargin( $widget );
|
90 |
+
}
|
91 |
+
} );
|
92 |
+
|
93 |
+
$( document ).on( "change", "select.conditions-rule-major", function() {
|
94 |
+
var $conditionsRuleMajor = $ ( this );
|
95 |
+
var $conditionsRuleMinor = $conditionsRuleMajor.siblings( "select.conditions-rule-minor:first" );
|
96 |
+
|
97 |
+
if ( $conditionsRuleMajor.val() ) {
|
98 |
+
$conditionsRuleMinor.html( '' ).append( $( '<option/>' ).text( $conditionsRuleMinor.data( 'loading-text' ) ) );
|
99 |
+
|
100 |
+
var data = {
|
101 |
+
action: 'widget_conditions_options',
|
102 |
+
major: $conditionsRuleMajor.val()
|
103 |
+
};
|
104 |
+
|
105 |
+
jQuery.post( ajaxurl, data, function( html ) {
|
106 |
+
$conditionsRuleMinor.html( html ).removeAttr( "disabled" );
|
107 |
+
} );
|
108 |
+
} else {
|
109 |
+
$conditionsRuleMajor.siblings( "select.conditions-rule-minor" ).attr( "disabled", "disabled" ).html( "" );
|
110 |
+
}
|
111 |
+
} );
|
112 |
+
} );
|
modules/widgets.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
* Sort Order: 13
|
6 |
* First Introduced: 1.2
|
7 |
* Requires Connection: No
|
|
|
8 |
*/
|
9 |
|
10 |
function jetpack_load_widgets() {
|
5 |
* Sort Order: 13
|
6 |
* First Introduced: 1.2
|
7 |
* Requires Connection: No
|
8 |
+
* Auto Activate: Yes
|
9 |
*/
|
10 |
|
11 |
function jetpack_load_widgets() {
|
modules/widgets/top-posts.php
CHANGED
@@ -222,7 +222,7 @@ class Jetpack_Top_Posts_Widget extends WP_Widget {
|
|
222 |
|
223 |
function get_by_views( $count ) {
|
224 |
global $wpdb;
|
225 |
-
$post_view_posts = stats_get_csv( 'postviews', array( 'days' => 2, 'limit' =>
|
226 |
if ( !$post_view_posts ) {
|
227 |
return array();
|
228 |
}
|
222 |
|
223 |
function get_by_views( $count ) {
|
224 |
global $wpdb;
|
225 |
+
$post_view_posts = stats_get_csv( 'postviews', array( 'days' => 2, 'limit' => 11 ) );
|
226 |
if ( !$post_view_posts ) {
|
227 |
return array();
|
228 |
}
|
modules/widgets/twitter-timeline.php
CHANGED
@@ -49,7 +49,7 @@ class Jetpack_Twitter_Timeline_Widget extends WP_Widget {
|
|
49 |
if ( $instance['title'] )
|
50 |
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
|
51 |
|
52 |
-
$data_attribs = array( 'widget-id', 'theme', 'link-color', 'border-color', 'chrome' );
|
53 |
$attribs = array( 'width', 'height', 'lang' );
|
54 |
|
55 |
// Start tag output
|
@@ -57,6 +57,9 @@ class Jetpack_Twitter_Timeline_Widget extends WP_Widget {
|
|
57 |
|
58 |
foreach ( $data_attribs as $att ) {
|
59 |
if ( !empty( $instance[$att] ) ) {
|
|
|
|
|
|
|
60 |
if ( is_array( $instance[$att] ) )
|
61 |
echo ' data-' . esc_attr( $att ) . '="' . esc_attr( join( ' ', $instance['chrome'] ) ) . '"';
|
62 |
else
|
@@ -94,8 +97,9 @@ class Jetpack_Twitter_Timeline_Widget extends WP_Widget {
|
|
94 |
$instance['title'] = sanitize_text_field( $new_instance['title'] );
|
95 |
$instance['width'] = (int) $new_instance['width'];
|
96 |
$instance['height'] = (int) $new_instance['height'];
|
97 |
-
$instance['width'] = ( 0 !== (int) $
|
98 |
-
$instance['height'] = ( 0 !== (int) $
|
|
|
99 |
|
100 |
// If they entered something that might be a full URL, try to parse it out
|
101 |
if ( is_string( $new_instance['widget-id'] ) ) {
|
@@ -167,6 +171,11 @@ class Jetpack_Twitter_Timeline_Widget extends WP_Widget {
|
|
167 |
<input class="widefat" id="<?php echo $this->get_field_id( 'height' ); ?>" name="<?php echo $this->get_field_name( 'height' ); ?>" type="text" value="<?php echo esc_attr( $instance['height'] ); ?>" />
|
168 |
</p>
|
169 |
|
|
|
|
|
|
|
|
|
|
|
170 |
<p><small>
|
171 |
<?php
|
172 |
echo wp_kses_post(
|
49 |
if ( $instance['title'] )
|
50 |
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
|
51 |
|
52 |
+
$data_attribs = array( 'widget-id', 'theme', 'link-color', 'border-color', 'chrome', 'tweet-limit' );
|
53 |
$attribs = array( 'width', 'height', 'lang' );
|
54 |
|
55 |
// Start tag output
|
57 |
|
58 |
foreach ( $data_attribs as $att ) {
|
59 |
if ( !empty( $instance[$att] ) ) {
|
60 |
+
if ( 'tweet-limit' == $att && 0 === $instance[$att] )
|
61 |
+
continue;
|
62 |
+
|
63 |
if ( is_array( $instance[$att] ) )
|
64 |
echo ' data-' . esc_attr( $att ) . '="' . esc_attr( join( ' ', $instance['chrome'] ) ) . '"';
|
65 |
else
|
97 |
$instance['title'] = sanitize_text_field( $new_instance['title'] );
|
98 |
$instance['width'] = (int) $new_instance['width'];
|
99 |
$instance['height'] = (int) $new_instance['height'];
|
100 |
+
$instance['width'] = ( 0 !== (int) $new_instance['width'] ) ? (int) $new_instance['width'] : 225;
|
101 |
+
$instance['height'] = ( 0 !== (int) $new_instance['height'] ) ? (int) $new_instance['height'] : 400;
|
102 |
+
$instance['tweet-limit'] = (int) $new_instance['tweet-limit'];
|
103 |
|
104 |
// If they entered something that might be a full URL, try to parse it out
|
105 |
if ( is_string( $new_instance['widget-id'] ) ) {
|
171 |
<input class="widefat" id="<?php echo $this->get_field_id( 'height' ); ?>" name="<?php echo $this->get_field_name( 'height' ); ?>" type="text" value="<?php echo esc_attr( $instance['height'] ); ?>" />
|
172 |
</p>
|
173 |
|
174 |
+
<p>
|
175 |
+
<label for="<?php echo $this->get_field_id( 'tweet-limit' ); ?>"><?php esc_html_e( '# of Tweets Shown:', 'jetpack' ); ?></label>
|
176 |
+
<input class="widefat" id="<?php echo $this->get_field_id( 'tweet-limit' ); ?>" name="<?php echo $this->get_field_name( 'tweet-limit' ); ?>" type="text" value="<?php echo esc_attr( $instance['tweet-limit'] ); ?>" />
|
177 |
+
</p>
|
178 |
+
|
179 |
<p><small>
|
180 |
<?php
|
181 |
echo wp_kses_post(
|
modules/wpcc.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Module Name: WordPress.com Connect
|
5 |
+
* Module Description: Let users login with their WordPress.com Credentials, through <a href="http://jetpack.me/support/wpcc/">WordPress.com Connect</a>
|
6 |
+
* Sort Order: 50
|
7 |
+
* First Introduced: 2.4
|
8 |
+
* Requires Connection: No
|
9 |
+
* Auto Activate: No
|
10 |
+
*/
|
11 |
+
|
12 |
+
if ( ! class_exists( 'WPCC_Sign_On' ) )
|
13 |
+
require_once( dirname( __FILE__ ) . '/wpcc/wpcc-sign-on.php' );
|
14 |
+
|
15 |
+
add_action( 'jetpack_modules_loaded', 'jetpack_wpcc_loaded' );
|
16 |
+
function jetpack_wpcc_loaded() {
|
17 |
+
Jetpack::enable_module_configurable( __FILE__ );
|
18 |
+
Jetpack::module_configuration_load( __FILE__, 'jetpack_wpcc_configuration_load' );
|
19 |
+
}
|
20 |
+
|
21 |
+
function jetpack_wpcc_configuration_load() {
|
22 |
+
wp_safe_redirect( admin_url( 'options-general.php#wpcc-sign-on-section' ) );
|
23 |
+
exit;
|
24 |
+
}
|
modules/wpcc/wpcc-sign-on.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
#loginform {
|
3 |
+
overflow: hidden;
|
4 |
+
padding-bottom: 26px;
|
5 |
+
}
|
6 |
+
|
7 |
+
#wpcc-sign-on {
|
8 |
+
display: block;
|
9 |
+
float: right;
|
10 |
+
margin:1em 0 0;
|
11 |
+
}
|
modules/wpcc/wpcc-sign-on.js
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
jQuery(document).ready(function($){
|
3 |
+
$( '#loginform' ).append( $( '#wpcc-sign-on' ) );
|
4 |
+
});
|
modules/wpcc/wpcc-sign-on.php
ADDED
@@ -0,0 +1,437 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: WPCC Sign On
|
4 |
+
* Plugin URI: https://github.com/Automattic/wpcc-sign-on
|
5 |
+
* Description: A single-sign-on via WordPress.com for your WordPress.org site!
|
6 |
+
* Author: Automatticians
|
7 |
+
* Version: 1.0
|
8 |
+
* Author URI: http://automattic.com/
|
9 |
+
*/
|
10 |
+
|
11 |
+
class WPCC_Sign_On {
|
12 |
+
static $instance = null;
|
13 |
+
|
14 |
+
var $request_token_url, // Fixed URL.
|
15 |
+
$authenticate_url, // Fixed URL.
|
16 |
+
$user_data_url, // Fixed URL.
|
17 |
+
$new_app_url_base, // Fixed URL.
|
18 |
+
$options_prefix, // Where the options are in the DB.
|
19 |
+
$options, // Options Array.
|
20 |
+
$client_id, // Option.
|
21 |
+
$client_secret, // Option.
|
22 |
+
$new_user_override, // Option.
|
23 |
+
$match_by_email, // Option.
|
24 |
+
$wpcc_state,
|
25 |
+
$secret,
|
26 |
+
$user_data;
|
27 |
+
|
28 |
+
function __construct() {
|
29 |
+
if ( self::$instance ) {
|
30 |
+
return self::$instance;
|
31 |
+
}
|
32 |
+
|
33 |
+
self::$instance = $this;
|
34 |
+
|
35 |
+
$this->request_token_url = 'https://public-api.wordpress.com/oauth2/token';
|
36 |
+
$this->authenticate_url = 'https://public-api.wordpress.com/oauth2/authenticate';
|
37 |
+
$this->user_data_url = 'https://public-api.wordpress.com/rest/v1/me/';
|
38 |
+
$this->new_app_url_base = 'https://developer.wordpress.com/apps/new/';
|
39 |
+
$this->options_prefix = $this->in_jetpack() ? 'jetpack_' : '';
|
40 |
+
$this->options = $this->fetch_options();
|
41 |
+
$this->client_id = $this->options['client_id'];
|
42 |
+
$this->client_secret = $this->options['client_secret'];
|
43 |
+
$this->new_user_override = $this->options['new_user_override'];
|
44 |
+
$this->match_by_email = $this->options['match_by_email'];
|
45 |
+
|
46 |
+
add_action( 'admin_init', array( $this, 'admin_init' ) );
|
47 |
+
|
48 |
+
if ( empty( $this->client_id ) ) {
|
49 |
+
return;
|
50 |
+
}
|
51 |
+
|
52 |
+
add_action( 'login_init', array( $this, 'login_init' ) );
|
53 |
+
add_action( 'login_enqueue_scripts', array( $this, 'login_enqueue_scripts' ) );
|
54 |
+
add_action( 'login_form', array( $this, 'login_form' ) );
|
55 |
+
}
|
56 |
+
|
57 |
+
function in_jetpack() {
|
58 |
+
return '/modules/wpcc' == substr( dirname( __FILE__ ), ( 0 - strlen( '/modules/wpcc' ) ) );
|
59 |
+
}
|
60 |
+
|
61 |
+
function fetch_options() {
|
62 |
+
$options = $this->in_jetpack() ? Jetpack_Options::get_option( 'wpcc_options' ) : get_option( 'wpcc_options' );
|
63 |
+
$args = wp_parse_args( $options, $this->default_options() );
|
64 |
+
|
65 |
+
$args['new_user_override'] = defined( 'WPCC_NEW_USER_OVERRIDE' ) ? WPCC_NEW_USER_OVERRIDE : false;
|
66 |
+
$args['match_by_email'] = defined( 'WPCC_MATCH_BY_EMAIL' ) ? WPCC_MATCH_BY_EMAIL : true;
|
67 |
+
|
68 |
+
return $args;
|
69 |
+
}
|
70 |
+
|
71 |
+
function default_options() {
|
72 |
+
return array(
|
73 |
+
'client_id' => '',
|
74 |
+
'client_secret' => '',
|
75 |
+
'new_user_override' => false,
|
76 |
+
'match_by_email' => true,
|
77 |
+
);
|
78 |
+
}
|
79 |
+
|
80 |
+
function admin_init() {
|
81 |
+
// Create the section
|
82 |
+
add_settings_section(
|
83 |
+
'wpcc',
|
84 |
+
esc_html__( 'WordPress.com Connect', 'jetpack' ),
|
85 |
+
array( $this, 'wpcc_settings_section' ),
|
86 |
+
'general'
|
87 |
+
);
|
88 |
+
|
89 |
+
add_settings_field(
|
90 |
+
'wpcc_sign_on_client_id',
|
91 |
+
sprintf( '<label for="wpcc_sign_on_client_id">%1$s</label>', __( 'WPCC Client ID', 'jetpack' ) ),
|
92 |
+
array( $this, 'wpcc_sign_on_client_id_cb' ),
|
93 |
+
'general',
|
94 |
+
'wpcc'
|
95 |
+
);
|
96 |
+
add_settings_field(
|
97 |
+
'wpcc_sign_on_client_secret',
|
98 |
+
sprintf( '<label for="wpcc_sign_on_client_secret">%1$s</label>', __( 'WPCC Client Secret', 'jetpack' ) ),
|
99 |
+
array( $this, 'wpcc_sign_on_client_secret_cb' ),
|
100 |
+
'general',
|
101 |
+
'wpcc'
|
102 |
+
);
|
103 |
+
|
104 |
+
register_setting( 'general', "{$this->options_prefix}wpcc_options", array( $this, 'sanitize_options' ) );
|
105 |
+
|
106 |
+
if ( ! empty( $this->client_id ) && ! empty( $this->client_secret ) ) {
|
107 |
+
add_action( 'show_user_profile', array( $this, 'edit_profile_fields' ) ); // For their own profile
|
108 |
+
add_action( 'edit_user_profile', array( $this, 'edit_profile_fields' ) ); // For folks editing others profiles
|
109 |
+
} else {
|
110 |
+
add_action( 'admin_notices', array( $this, 'no_credentials_admin_notice' ) );
|
111 |
+
}
|
112 |
+
|
113 |
+
if ( $user_ID = get_current_user_id() ) {
|
114 |
+
$this->wpcc_state = "localuser{$user_ID}";
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
function no_credentials_admin_notice() {
|
119 |
+
$disable_url = wp_nonce_url( Jetpack::admin_url( 'action=deactivate&module=wpcc' ), 'jetpack_deactivate-wpcc' );
|
120 |
+
?>
|
121 |
+
<div id="wpcc-needs-config" class="updated">
|
122 |
+
<p class="alignright"><a href="<?php echo esc_url( $disable_url ); ?>"><?php _e( 'Close', 'jetpack' ); ?></a></p>
|
123 |
+
<p><?php printf( __( '<strong>Almost done.</strong> Before WordPress.com Connect can finish activating, you\'ll need to <a href="%s">register your website as an application on WordPress.com</a>', 'jetpack' ), esc_url( admin_url( 'options-general.php#wpcc-sign-on-section' ) ) ); ?></p>
|
124 |
+
</div>
|
125 |
+
<?php
|
126 |
+
}
|
127 |
+
|
128 |
+
function sanitize_options( $options ) {
|
129 |
+
if ( ! empty( $options['client_id'] ) ) {
|
130 |
+
$options['client_id'] = intval( $options['client_id'] );
|
131 |
+
}
|
132 |
+
|
133 |
+
if ( ! empty( $options['client_secret'] ) ) {
|
134 |
+
$options['client_secret'] = sanitize_text_field( $options['client_secret'] );
|
135 |
+
}
|
136 |
+
|
137 |
+
return $options;
|
138 |
+
}
|
139 |
+
|
140 |
+
function wpcc_settings_section() {
|
141 |
+
?>
|
142 |
+
|
143 |
+
<p id="wpcc-sign-on-section">
|
144 |
+
<?php
|
145 |
+
if ( empty( $this->client_id ) || empty( $this->client_secret ) ) {
|
146 |
+
printf( __( 'Visit WordPress.com to <a href="%s">register a new WPCC client id and secret key</a>.', 'jetpack' ), $this->get_new_app_url() );
|
147 |
+
} else {
|
148 |
+
printf( __( 'Visit WordPress.com to <a href="%s">manage your WPCC client settings</a>.', 'jetpack' ), $this->get_edit_app_url() );
|
149 |
+
}
|
150 |
+
?>
|
151 |
+
</p>
|
152 |
+
<script>
|
153 |
+
jQuery('#wpcc-sign-on-section a').attr( 'target', '_blank' );
|
154 |
+
</script>
|
155 |
+
|
156 |
+
<?php
|
157 |
+
}
|
158 |
+
|
159 |
+
function wpcc_sign_on_client_id_cb() {
|
160 |
+
echo '<input class="regular-text code" autocomplete="off" type="text" id="wpcc_sign_on_client_id" name="' . $this->options_prefix . 'wpcc_options[client_id]" value="' . esc_attr( $this->client_id ) . '" />';
|
161 |
+
}
|
162 |
+
|
163 |
+
function wpcc_sign_on_client_secret_cb() {
|
164 |
+
echo '<input class="regular-text code" autocomplete="off" type="text" id="wpcc_sign_on_client_secret" name="' . $this->options_prefix . 'wpcc_options[client_secret]" value="' . esc_attr( $this->client_secret ) . '" />';
|
165 |
+
}
|
166 |
+
|
167 |
+
function edit_profile_fields( $user ) {
|
168 |
+
if ( isset( $_GET['wpcc'] ) && 'purge' == $_GET['wpcc'] ) {
|
169 |
+
delete_user_meta( $user->ID, 'wpcom_user_id' );
|
170 |
+
delete_user_meta( $user->ID, 'wpcom_user_data' );
|
171 |
+
}
|
172 |
+
?>
|
173 |
+
|
174 |
+
<h3><?php _e( 'WordPress.com Connect', 'jetpack' ); ?></h3>
|
175 |
+
<p><?php _e( 'Connecting with WordPress.com Connect enables you to log on via your WordPress.com account.', 'jetpack' ); ?></p>
|
176 |
+
|
177 |
+
<?php if ( ( $user_data = get_user_meta( $user->ID, 'wpcom_user_data', true ) ) && ! empty( $user_data->ID ) ) : /* If the user is currently connected... */ ?>
|
178 |
+
|
179 |
+
<table class="form-table wpcc-form-table">
|
180 |
+
<tbody>
|
181 |
+
<tr>
|
182 |
+
<td>
|
183 |
+
<div class="profile-card">
|
184 |
+
<img src="<?php echo esc_url( $user_data->avatar_URL ); ?>" height="48" width="48" />
|
185 |
+
<p class="connected"><strong><?php _e( 'Connected', 'jetpack' ); ?></strong></p>
|
186 |
+
<p><?php echo esc_html( $user_data->username ); ?></p>
|
187 |
+
</div>
|
188 |
+
<p><a class="button button-secondary" href="<?php echo esc_url( add_query_arg( 'wpcc', 'purge' ) ); ?>"><?php _e( 'Unlink This Account', 'jetpack' ); ?></a></p>
|
189 |
+
</td>
|
190 |
+
</tr>
|
191 |
+
</tbody>
|
192 |
+
</table>
|
193 |
+
|
194 |
+
<style>
|
195 |
+
.wpcc-form-table td {
|
196 |
+
padding-left: 0;
|
197 |
+
}
|
198 |
+
|
199 |
+
.wpcc-form-table .profile-card {
|
200 |
+
padding: 10px;
|
201 |
+
background: #fff;
|
202 |
+
overflow: hidden;
|
203 |
+
max-width: 400px;
|
204 |
+
box-shadow: 0 2px 5px rgba( 0, 0, 0, 0.4 );
|
205 |
+
margin-bottom: 1em;
|
206 |
+
}
|
207 |
+
|
208 |
+
.wpcc-form-table .profile-card img {
|
209 |
+
float: left;
|
210 |
+
margin-right: 1em;
|
211 |
+
}
|
212 |
+
|
213 |
+
.wpcc-form-table .profile-card .connected {
|
214 |
+
float: right;
|
215 |
+
margin-right: 0.5em;
|
216 |
+
color: #0a0;
|
217 |
+
}
|
218 |
+
|
219 |
+
.wpcc-form-table .profile-card p {
|
220 |
+
margin-top: 0.7em;
|
221 |
+
font-size: 1.2em;
|
222 |
+
}
|
223 |
+
</style>
|
224 |
+
|
225 |
+
<?php elseif ( get_current_user_id() == $user->ID ) : ?>
|
226 |
+
|
227 |
+
<?php echo $this->button( array( 'redirect_uri' => add_query_arg( 'for', 'profile', wp_login_url() ) ) ); ?>
|
228 |
+
|
229 |
+
<?php else : ?>
|
230 |
+
|
231 |
+
<p><?php _e( 'This profile is not currently linked to a WordPress.com Profile.', 'jetpack' ); ?></p>
|
232 |
+
|
233 |
+
<?php endif;
|
234 |
+
}
|
235 |
+
|
236 |
+
function verify_connection( $get_args = array() ) {
|
237 |
+
if ( empty( $_GET['state'] ) ) {
|
238 |
+
wp_die( __( 'Warning! State variable missing after authentication.', 'jetpack' ) );
|
239 |
+
}
|
240 |
+
|
241 |
+
if ( $_GET['state'] != $this->wpcc_state ) {
|
242 |
+
wp_die( __( 'Warning! State mismatch. Authentication attempt may have been compromised.', 'jetpack' ) );
|
243 |
+
}
|
244 |
+
|
245 |
+
$redirect_uri = wp_login_url();
|
246 |
+
|
247 |
+
if ( $get_args ) {
|
248 |
+
$redirect_uri = add_query_arg( $get_args, $redirect_uri );
|
249 |
+
}
|
250 |
+
|
251 |
+
$args = array(
|
252 |
+
'client_id' => $this->client_id,
|
253 |
+
'redirect_uri' => $redirect_uri,
|
254 |
+
'client_secret' => $this->client_secret,
|
255 |
+
'code' => sanitize_text_field( $_GET['code'] ), // The code from the previous request
|
256 |
+
'grant_type' => 'authorization_code',
|
257 |
+
);
|
258 |
+
|
259 |
+
$response = wp_remote_post( $this->request_token_url, array( 'body' => $args ) );
|
260 |
+
|
261 |
+
if ( is_wp_error( $response ) ) {
|
262 |
+
wp_die( __( 'Warning! Could not confirm request token url!', 'jetpack' ) );
|
263 |
+
}
|
264 |
+
|
265 |
+
$this->secret = json_decode( wp_remote_retrieve_body( $response ) );
|
266 |
+
|
267 |
+
$args = array(
|
268 |
+
'headers' => array(
|
269 |
+
'Authorization' => sprintf( 'Bearer %s', $this->secret->access_token ),
|
270 |
+
),
|
271 |
+
);
|
272 |
+
|
273 |
+
$response = wp_remote_get( $this->user_data_url, $args );
|
274 |
+
|
275 |
+
if ( is_wp_error( $response ) ) {
|
276 |
+
wp_die( __( 'Warning! Could not fetch user data!', 'jetpack' ) );
|
277 |
+
}
|
278 |
+
|
279 |
+
$this->user_data = json_decode( wp_remote_retrieve_body( $response ) );
|
280 |
+
|
281 |
+
return $this->user_data;
|
282 |
+
}
|
283 |
+
|
284 |
+
function login_init() {
|
285 |
+
// Set the wpcc_state
|
286 |
+
$this->wpcc_state = md5( mt_rand() );
|
287 |
+
if ( isset( $_COOKIE['wpcc_state'] ) ) {
|
288 |
+
$this->wpcc_state = $_COOKIE['wpcc_state'];
|
289 |
+
} else {
|
290 |
+
setcookie( 'wpcc_state', $this->wpcc_state );
|
291 |
+
}
|
292 |
+
|
293 |
+
if ( isset( $_GET['for'] ) && ( 'profile' == $_GET['for'] ) ) {
|
294 |
+
$user_ID = get_current_user_id();
|
295 |
+
|
296 |
+
$this->wpcc_state = "localuser{$user_ID}";
|
297 |
+
$user_data = $this->verify_connection( array( 'for' => 'profile' ) );
|
298 |
+
|
299 |
+
update_user_meta( get_current_user_id(), 'wpcom_user_id', $user_data->ID );
|
300 |
+
update_user_meta( get_current_user_id(), 'wpcom_user_data', $user_data );
|
301 |
+
|
302 |
+
wp_safe_redirect( admin_url( 'profile.php' ) );
|
303 |
+
exit;
|
304 |
+
}
|
305 |
+
|
306 |
+
// If they just got forwarded back ...
|
307 |
+
if ( isset( $_GET['code'] ) ) {
|
308 |
+
|
309 |
+
$user_data = $this->verify_connection();
|
310 |
+
|
311 |
+
$this->auth_user( $user_data );
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
function login_enqueue_scripts() {
|
316 |
+
wp_enqueue_style( 'wpcc-sign-on', plugins_url( 'wpcc-sign-on.css', __FILE__ ), 0, filemtime( dirname( __FILE__ ) . '/wpcc-sign-on.css' ) );
|
317 |
+
wp_enqueue_script( 'wpcc-sign-on', plugins_url( 'wpcc-sign-on.js', __FILE__ ), array( 'jquery' ), filemtime( dirname( __FILE__ ) . '/wpcc-sign-on.js' ) );
|
318 |
+
}
|
319 |
+
|
320 |
+
function login_form() {
|
321 |
+
if( ! did_action( 'login_init' ) )
|
322 |
+
return;
|
323 |
+
|
324 |
+
echo $this->button();
|
325 |
+
}
|
326 |
+
|
327 |
+
function button( $args = array() ) {
|
328 |
+
$defaults = array(
|
329 |
+
'response_type' => 'code',
|
330 |
+
'client_id' => $this->client_id,
|
331 |
+
'state' => $this->wpcc_state,
|
332 |
+
'redirect_uri' => wp_login_url(),
|
333 |
+
);
|
334 |
+
|
335 |
+
$args = wp_parse_args( $args, $defaults );
|
336 |
+
|
337 |
+
if ( ! empty( $_REQUEST['redirect_to'] ) ) {
|
338 |
+
$args['redirect_uri'] = add_query_arg( 'redirect_to', $_REQUEST['redirect_to'], $args['redirect_uri'] );
|
339 |
+
}
|
340 |
+
|
341 |
+
$url = add_query_arg( $args, $this->authenticate_url );
|
342 |
+
|
343 |
+
return sprintf( '<a id="wpcc-sign-on" href="%1$s"><img src="//s0.wp.com/i/wpcc-button.png" width="231" /></a>', esc_url( $url ) );
|
344 |
+
}
|
345 |
+
|
346 |
+
function auth_user( $user_data ) {
|
347 |
+
|
348 |
+
if ( ! $user_data->verified ) {
|
349 |
+
return false;
|
350 |
+
}
|
351 |
+
|
352 |
+
$user = $this->get_user_by_wpcom_id( $user_data->ID );
|
353 |
+
|
354 |
+
// If we don't have one by wpcom_user_id, try by the email?
|
355 |
+
if ( empty( $user ) && $this->match_by_email ) {
|
356 |
+
$user = get_user_by( 'email', $user_data->email );
|
357 |
+
if ( $user ) {
|
358 |
+
update_user_meta( $user->ID, 'wpcom_user_id', $user_data->ID );
|
359 |
+
}
|
360 |
+
}
|
361 |
+
|
362 |
+
// If we've still got nothing, create the user.
|
363 |
+
if ( empty( $user ) && ( get_option( 'users_can_register' ) || $this->new_user_override ) ) {
|
364 |
+
$username = $user_data->username;
|
365 |
+
|
366 |
+
if ( username_exists( $username ) ) {
|
367 |
+
$username .= '_' . $user_data->ID;
|
368 |
+
}
|
369 |
+
|
370 |
+
if ( username_exists( $username ) )
|
371 |
+
$username .= '_' . mt_rand();
|
372 |
+
|
373 |
+
$password = wp_generate_password( 20 );
|
374 |
+
$user_id = wp_create_user( $username, $password, $user_data->email );
|
375 |
+
$user = get_userdata( $user_id );
|
376 |
+
|
377 |
+
$user->display_name = $user_data->display_name;
|
378 |
+
wp_update_user( $user );
|
379 |
+
|
380 |
+
update_user_meta( $user->ID, 'wpcom_user_id', $user_data->ID );
|
381 |
+
}
|
382 |
+
|
383 |
+
if ( $user ) {
|
384 |
+
// Cache the user's details, so we can present it back to them on their user screen.
|
385 |
+
update_user_meta( $user->ID, 'wpcom_user_data', $user_data );
|
386 |
+
wp_set_auth_cookie( $user->ID );
|
387 |
+
|
388 |
+
$_request_redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
|
389 |
+
$redirect_to = user_can( $user, 'edit_posts' ) ? admin_url() : admin_url( 'profile.php' );
|
390 |
+
wp_safe_redirect( apply_filters( 'login_redirect', $redirect_to, $_request_redirect_to, $user ) );
|
391 |
+
exit;
|
392 |
+
}
|
393 |
+
|
394 |
+
add_action( 'login_message', array( $this, 'cant_find_user' ) );
|
395 |
+
}
|
396 |
+
|
397 |
+
function get_user_by_wpcom_id( $wpcom_user_id ) {
|
398 |
+
$user_query = new WP_User_Query( array(
|
399 |
+
'meta_key' => 'wpcom_user_id',
|
400 |
+
'meta_value' => intval( $wpcom_user_id ),
|
401 |
+
) );
|
402 |
+
|
403 |
+
$users = $user_query->get_results();
|
404 |
+
|
405 |
+
return ( is_array( $users ) && ! empty( $users ) ) ? array_shift( $users ) : $users;
|
406 |
+
}
|
407 |
+
|
408 |
+
function cant_find_user( $message ) {
|
409 |
+
$err_format = __( 'We couldn\'t find an account with the email <strong><code>%1$s</code></strong> to log you in with. If you already have an account on <strong>%2$s</strong>, please make sure that <strong><code>%1$s</code></strong> is configured as the email address, or that you have connected to WordPress.com on your profile page.', 'jetpack' );
|
410 |
+
if ( ! $this->match_by_email ) {
|
411 |
+
$err_format = __( 'We couldn\'t find any account on <strong>%2$s</strong> that is linked to your WordPress.com account to log you in with. If you already have an account on <strong>%2$s</strong>, please make sure that you have connected to WordPress.com on your profile page.', 'jetpack' );
|
412 |
+
}
|
413 |
+
$err = sprintf( $err_format, $this->user_data->email, get_bloginfo( 'name' ) );
|
414 |
+
$message .= sprintf( '<p class="message" id="login_error">%s</p>', $err );
|
415 |
+
return $message;
|
416 |
+
}
|
417 |
+
|
418 |
+
function get_new_app_url() {
|
419 |
+
$args = array(
|
420 |
+
'for' => 'jetpack',
|
421 |
+
'title' => urlencode( get_bloginfo( 'name' ) ),
|
422 |
+
'description' => urlencode( get_bloginfo( 'description' ) ),
|
423 |
+
'url' => urlencode( site_url() ),
|
424 |
+
'redirect_uri' => urlencode( wp_login_url() ),
|
425 |
+
);
|
426 |
+
return add_query_arg( $args, $this->new_app_url_base );
|
427 |
+
}
|
428 |
+
|
429 |
+
function get_edit_app_url( $client_id = null ) {
|
430 |
+
if ( empty( $client_id ) ) {
|
431 |
+
$client_id = $this->client_id;
|
432 |
+
}
|
433 |
+
return sprintf( 'https://developer.wordpress.com/apps/%d/', $client_id );
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
new WPCC_Sign_On;
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: automattic, alternatekev, andy, apeatling, azaozz, barry, beaulebe
|
|
3 |
Tags: WordPress.com, statistics, stats, views, tweets, twitter, widget, gravatar, hovercards, profile, equations, latex, math, maths, youtube, shortcode, archives, audio, blip, bliptv, dailymotion, digg, flickr, googlevideo, google, googlemaps, kyte, kytetv, livevideo, redlasso, rockyou, rss, scribd, slide, slideshare, soundcloud, vimeo, shortlinks, wp.me, subscriptions, notifications, notes, json, api, rest, mosaic, gallery, slideshow
|
4 |
Requires at least: 3.5
|
5 |
Tested up to: 3.6
|
6 |
-
Stable tag: 2.
|
7 |
|
8 |
Supercharge your WordPress site with powerful features previously only available to WordPress.com users.
|
9 |
|
@@ -62,11 +62,14 @@ Once you've installed Jetpack, your stats will be available via the "Site Stats"
|
|
62 |
|
63 |
= How do I contribute to Jetpack? =
|
64 |
|
65 |
-
Easy! There are
|
66 |
|
|
|
67 |
* Give us a hand answering questions in our [support forum](http://wordpress.org/support/plugin/jetpack)
|
68 |
* Report bugs, with reproduction steps, or post patches on our [Trac](http://plugins.trac.wordpress.org/newticket?component=jetpack)
|
69 |
|
|
|
|
|
70 |
== Screenshots ==
|
71 |
|
72 |
1. Stats chart.
|
@@ -79,17 +82,62 @@ Easy! There are a couple of ways (more coming soon):
|
|
79 |
8. Mobile Theme
|
80 |
|
81 |
== Changelog ==
|
82 |
-
|
|
|
83 |
Release Date: May 26, 2016
|
84 |
|
85 |
* Important security update. Please upgrade immediately.
|
86 |
|
87 |
-
= 2.
|
88 |
* Bug Fix: Avoid function which isn't always defined.
|
89 |
|
90 |
-
= 2.3
|
91 |
* Important security update. CVE-2014-0173
|
92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
= 2.3.5 =
|
94 |
* Enhancement: Added Path support to Publicize.
|
95 |
|
@@ -236,7 +284,7 @@ Release Date: May 26, 2016
|
|
236 |
* Bug Fix: Shortcodes - Slideshow: RTL styling update
|
237 |
* Bug Fix: Tiled Galleries - Fix IE8 display bug where it doesn't honor inline CSS for width on images
|
238 |
* Bug Fix: Tiled Galleries - Remove depreacted hover call, use mouseenter mouseleave instead
|
239 |
-
* Enhancement: Twitter Timeline Widget: New JavaScript based widget. Old one will discontinue May 7th.
|
240 |
|
241 |
= 2.2.2 =
|
242 |
* Enhancement: Mobile Theme: Add controls for custom CSS.
|
3 |
Tags: WordPress.com, statistics, stats, views, tweets, twitter, widget, gravatar, hovercards, profile, equations, latex, math, maths, youtube, shortcode, archives, audio, blip, bliptv, dailymotion, digg, flickr, googlevideo, google, googlemaps, kyte, kytetv, livevideo, redlasso, rockyou, rss, scribd, slide, slideshare, soundcloud, vimeo, shortlinks, wp.me, subscriptions, notifications, notes, json, api, rest, mosaic, gallery, slideshow
|
4 |
Requires at least: 3.5
|
5 |
Tested up to: 3.6
|
6 |
+
Stable tag: 2.4.5
|
7 |
|
8 |
Supercharge your WordPress site with powerful features previously only available to WordPress.com users.
|
9 |
|
62 |
|
63 |
= How do I contribute to Jetpack? =
|
64 |
|
65 |
+
Easy! There are opportunities for developers at all levels to contribute:
|
66 |
|
67 |
+
* Join our Beta Test group
|
68 |
* Give us a hand answering questions in our [support forum](http://wordpress.org/support/plugin/jetpack)
|
69 |
* Report bugs, with reproduction steps, or post patches on our [Trac](http://plugins.trac.wordpress.org/newticket?component=jetpack)
|
70 |
|
71 |
+
Learn more (and get detailed instructions) in our [contribute guide](http://jetpack.me/contribute/).
|
72 |
+
|
73 |
== Screenshots ==
|
74 |
|
75 |
1. Stats chart.
|
82 |
8. Mobile Theme
|
83 |
|
84 |
== Changelog ==
|
85 |
+
|
86 |
+
= 2.4.5 =
|
87 |
Release Date: May 26, 2016
|
88 |
|
89 |
* Important security update. Please upgrade immediately.
|
90 |
|
91 |
+
= 2.4.4 =
|
92 |
* Bug Fix: Avoid function which isn't always defined.
|
93 |
|
94 |
+
= 2.4.3 =
|
95 |
* Important security update. CVE-2014-0173
|
96 |
|
97 |
+
= 2.4.2 =
|
98 |
+
* Enhancement: Converted to module headers to detect Auto-Activating modules.
|
99 |
+
* Enhancement: WPCC: Added 'Close' link to deactivate WPCC in the admin nag.
|
100 |
+
* Enhancement: JSON API: Add User Nicename to the user data.
|
101 |
+
* Bug Fix: Contact Form: Stopped using a short tag.
|
102 |
+
* Bug Fix: Changed CSS selector to catch MP6 stylings.
|
103 |
+
* Bug Fix: Dropped __FILE__ references in class.jetpack.php in favor of JETPACK__PLUGIN_DIR constant, now code that deactivates the plugin from the connect nag works again.
|
104 |
+
* Bug Fix: Random Redirect: Add random-redirect to the plugins overriden list, in case someone is using Matt's Random Redirect plugin.
|
105 |
+
* Bug Fix: Tiled Gallery: Revert r757178 relating to tiled gallery defaults.
|
106 |
+
* Bug Fix: Return false, not zero, if $GLOBALS['content_width'] isn't defined.
|
107 |
+
* Bug Fix: WPCC: Don't call wp_login_url() in the constructor -- if someone is running a custom login page, that can break things if their plugin runs get_permalink as a filter before init.
|
108 |
+
* Bug Fix: Tiled Gallery: Add fallback if post_parent == 0 due to infinite_scroll_load_other_plugins_scripts.
|
109 |
+
* Bug Fix: Custom CSS: Set the ACE gutter z-index to 1.
|
110 |
+
* Bug Fix: Custom Post Types: Switch from wp_redirect() to wp_safe_redirect().
|
111 |
+
* Bug Fix: Likes: Set overflow:hidden; on the likes adminbar item.
|
112 |
+
* Bug Fix: Mobile Theme: Migrate where/when the custom header stuff is included.
|
113 |
+
* Bug Fix: Slideshow Shortcode: Add a height of 410px.
|
114 |
+
|
115 |
+
= 2.4.1 =
|
116 |
+
* Enhancement: Don't auto-activate WPCC.
|
117 |
+
|
118 |
+
= 2.4 =
|
119 |
+
* Enhancement: WordPress.com Connect (WPCC): New Module.
|
120 |
+
* Enhancement: Widget Visibility: New Module.
|
121 |
+
* Enhancement: Shortcode: Addition of new Twitter Timeline shortcode.
|
122 |
+
* Enhancement: Shortcode: Addition of new Presentation shortcode.
|
123 |
+
* Enhancement: Shortcode: Addition of new Vine shortcode.
|
124 |
+
* Enhancement: Custom Post Types: CPTs are available.
|
125 |
+
* Enhancement: Subscriptions: Add 'jetpack_is_post_mailable' filter.
|
126 |
+
* Enhancement: OpenGraph: Add Twitter Cards meta tags as well.
|
127 |
+
* Enhancement: Custom CSS: Update lessc and scssc preprocessors to 0.4.0 and 0.0.7 respectively.
|
128 |
+
* Enhancement: Omnisearch: Add Media results.
|
129 |
+
* Enhancement: Likes: Use a protocol-agnostic iframe, instead of forced HTTPS.
|
130 |
+
* Enhancement: Top Posts: Increase post limit.
|
131 |
+
* Enhancement: Publicize: Updated JS and UI.
|
132 |
+
* Enhancement: Photon: New filter to let site admins/owners enable photon for HTTPS urls.
|
133 |
+
* Enhancement: New jetpack_get_available_modules filter.
|
134 |
+
* Enhancement: Subscriptions: Antispam measures.
|
135 |
+
* Bug Fix: Add inline style to keep plugins/themes from inadvertently hiding the Connect box.
|
136 |
+
* Bug Fix: Custom CSS: Respect the new wp_revisions_to_keep filter.
|
137 |
+
* Bug Fix: Photon: Only hook jetpack_photon_url into the filter if the user has Photon active.
|
138 |
+
* Bug Fix: Heartbeat: Used wrong object, occasinally fatal-erroring out for the cron.
|
139 |
+
* Bug Fix: Add an empty debug.php file to the /modules/ folder, to solve some update issues where it never got deleted.
|
140 |
+
|
141 |
= 2.3.5 =
|
142 |
* Enhancement: Added Path support to Publicize.
|
143 |
|
284 |
* Bug Fix: Shortcodes - Slideshow: RTL styling update
|
285 |
* Bug Fix: Tiled Galleries - Fix IE8 display bug where it doesn't honor inline CSS for width on images
|
286 |
* Bug Fix: Tiled Galleries - Remove depreacted hover call, use mouseenter mouseleave instead
|
287 |
+
* Enhancement: Twitter Timeline Widget: New JavaScript based widget. Old one will discontinue May 7th.
|
288 |
|
289 |
= 2.2.2 =
|
290 |
* Enhancement: Mobile Theme: Add controls for custom CSS.
|