diff --git a/crouton.php b/crouton.php index 50ef149..1eba0f8 100644 --- a/crouton.php +++ b/crouton.php @@ -5,7 +5,7 @@ Description: A tabbed based display for showing meeting information. Author: bmlt-enabled Author URI: https://bmlt.app -Version: 3.20.4 +Version: 3.20.5 */ /* Disallow direct access to the plugin file */ if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { @@ -24,9 +24,7 @@ class Crouton * @var mixed[] */ public $options = array(); - public $croutonBlockInitialized = false; public static $HOUR_IN_SECONDS = 3600; - public $has_handlebars = false; public $themes = [ "asheboro", "florida-nights", @@ -51,12 +49,10 @@ class Crouton 'timeout' => 60 ); // crouton includes a map, we need to include the JS files and create the croutonMap object. - private $hasMap = false; public $shortCodeOptions = array( "root_server" => '', "service_body" => '', "service_body_parent" => '', - "jsInFooter" => true, "venue_types" => '', "formats" => '', "has_tabs" => '1', @@ -130,7 +126,6 @@ class Crouton "filter_visible", "has_common_needs" ]; - private $waitMsg = '
'; private MeetingMap\Controller $meetingMapController; public function __construct() { @@ -146,19 +141,19 @@ public function __construct() add_action("wp_enqueue_scripts", array(&$this, "enqueueFrontendFiles")); add_shortcode('init_crouton', array( &$this, - "initCrouton" + "blank" )); add_shortcode('bmlt_tabs', array( &$this, - "tabbedUi" + "replaceShortcodeWithStandardTags" )); add_shortcode('crouton_map', array( &$this, - "croutonMap" + "replaceShortcodeWithStandardTags" )); add_shortcode('bmlt_map', array( &$this, - "meetingMap" + "replaceShortcodeWithStandardTags" )); add_shortcode('bmlt_count', array( &$this, @@ -182,26 +177,55 @@ public function __construct() )); } } - - private function hasShortcode() + /** + * + * @return string + */ + private function croutonInitializationScript() { $post_to_check = get_post(get_the_ID()); $post_content = $post_to_check->post_content ?? ''; - $tags = ['bmlt_tabs', 'bmlt_map', 'crouton_map', 'bmlt_count', 'meeting_count', 'group_count', 'service_body_names', 'bmlt_handlebar']; + $tags = ['bmlt_tabs', 'bmlt_map', 'crouton_map', 'bmlt_handlebar']; preg_match_all('/' . get_shortcode_regex($tags) . '/', $post_content, $matches, PREG_SET_ORDER); if (empty($matches)) { - return false; + return ''; } foreach ($matches as $shortcode) { - if ($shortcode[2] === 'bmlt_handlebar' || - $shortcode[2] === 'bmlt_tabs' || - $shortcode[2] === 'crouton_map' || - $shortcode[2] === 'bmlt_map') { - $this->hasMap = true; + if (isset($_GET['meeting-id'])) { + $shortcode[2] = 'bmlt_handlebar'; + $shortcode[3] = ''; + } + switch ($shortcode[2]) { + case 'bmlt_tabs': + $script = $this->renderTable(wp_parse_args($shortcode[3])); + break; + case 'init_crouton': + $script = $this->initCrouton(wp_parse_args($shortcode[3])); + break; + case 'crouton_map': + $script = $this->renderMap(wp_parse_args($shortcode[3])); + break; + case 'bmlt_map': + $atts = wp_parse_args($shortcode[3]); + if (is_array($atts)) { + $atts['has_venues'] = '0'; + } else { + $atts = ["has_venues" => "0"]; + } + $script = $this->renderMap($atts, false); + break; + case 'bmlt_handlebar': + $script = $this->handlebarFooterScript(); + break; + default: + $script = ''; + break; + } + if ($script != '') { + return $script; } } - return true; } @@ -245,7 +269,8 @@ public function enqueueBackendFiles($hook) */ public function enqueueFrontendFiles() { - if ($this->hasShortcode()) { + $script = $this->croutonInitializationScript(); + if ($script !== '') { wp_enqueue_style("croutoncss", plugin_dir_url(__FILE__) . "croutonjs/dist/crouton-core.min.css", false, filemtime(plugin_dir_path(__FILE__) . "croutonjs/dist/crouton-core.min.css"), false); if (isset($_GET['croutonjsdebug'])) { wp_enqueue_script("croutonnocorejs", plugin_dir_url(__FILE__) . "croutonjs/dist/crouton-nocore.js", array('jquery'), filemtime(plugin_dir_path(__FILE__) . "croutonjs/dist/crouton-nocore.js"), true); @@ -254,6 +279,7 @@ public function enqueueFrontendFiles() wp_enqueue_script("croutonjs", plugin_dir_url(__FILE__) . "croutonjs/dist/crouton-core.min.js", array('jquery'), filemtime(plugin_dir_path(__FILE__) . "croutonjs/dist/crouton-core.min.js"), true); } $this->meetingMapController->enqueueFrontendFiles(); + wp_add_inline_script("croutonjs", $script); } } @@ -294,10 +320,9 @@ private function testRootServer($root_server) return ''; } - - private function sharedRender() + private function outputTag() { - $output = ""; + $output = '
'; if (isset($_GET['this_title'])) { $output .= '
' . $_GET['this_title'] . '
'; } @@ -305,32 +330,23 @@ private function sharedRender() if (isset($_GET['sub_title'])) { $output .= '
' . $_GET['sub_title'] . '
'; } - - return $output; + return $output.'
'; } - private function inlineScript($s) - { - wp_add_inline_script('croutonjs', $s); - } - private function outputScript($s) - { - if (isset($this->options['jsInFooter'])) { - wp_add_inline_script('croutonjs', $s); - $s = ""; - } - return $this->waitMsg.sprintf('%s
%s
', $this->sharedRender(), $s); - } - public function tabbedUi($atts, $content = null) + /** + * When we are processing the main shortcodes themselves, we can just insert standard tags, because the difference is + * in how we initialize the JS Crouton object. And we do that when deciding whether to enqueue scripts or not. + * + * @return string + */ + public function replaceShortcodeWithStandardTags() { - $this->hasMap = true; if (isset($_GET['meeting-id'])) { return do_shortcode($this->getDefaultMeetingDetailsPageContents()); } - return $this->outputScript($this->renderTable($atts)); + return $this->outputTag(); } public function bmltHandlebar($atts, $template = null) { - $this->hasMap = true; if (!isset($_GET['meeting-id'])) { return "Meeting-ID not set in query-string"; } @@ -341,50 +357,17 @@ public function bmltHandlebar($atts, $template = null) return ''; } } - if (!$this->has_handlebars) { - $this->handlebarFooter(); - } - $this->has_handlebars = true; return sprintf('%sFetching...', htmlspecialchars($template)); } - public function croutonMap($atts, $content = null) - { - $this->hasMap = true; - if (isset($_GET['meeting-id'])) { - return do_shortcode($this->getDefaultMeetingDetailsPageContents()); - } - return $this->outputScript($this->renderMap($atts)); - } - public function meetingMap($atts, $content = null) - { - $this->hasMap = true; - if (isset($_GET['meeting-id'])) { - return do_shortcode($this->getDefaultMeetingDetailsPageContents()); - } - if (is_array($atts)) { - $atts['has_venues'] = '0'; - } else { - $atts = ["has_venues" => "0"]; - } - return $this->outputScript($this->renderMap($atts, false)); - } private function getMapInitialization($mapConfig) { $className = $this->meetingMapController->className(); - if ($this->hasMap) { - return "window.croutonMap = new $className($mapConfig);"; - } - return ""; + return "window.croutonMap = new $className($mapConfig);"; } private function getInitializeCroutonBlock($renderCmd, $config, $mapConfig) { - if (!$this->croutonBlockInitialized) { - $this->croutonBlockInitialized = true; - $croutonMap = $this->getMapInitialization($mapConfig); - return ""; - } else { - return isset($config) ? "" : ""; - } + $croutonMap = $this->getMapInitialization($mapConfig); + return "var crouton;jQuery(document).ready(function() { $croutonMap crouton = new Crouton($config); $renderCmd });"; } private function renderTable($atts) @@ -407,6 +390,11 @@ public function initCrouton($atts) return $this->getInitializeCroutonBlock("crouton.renderMeetingCount();", ...$this->getCroutonJsConfig($atts)); } + public function blank() + { + return ''; + } + public function meetingCount($atts) { if (isset($_GET['meeting-id'])) { @@ -442,7 +430,7 @@ public function serviceBodyNames($atts) } return "Fetching..."; } - public function handlebarFooter() + public function handlebarFooterScript() { if (!isset($_GET['meeting-id'])) { return; @@ -454,7 +442,7 @@ public function handlebarFooter() $croutonMap = $this->getMapInitialization($mapConfig); $ret = "var crouton;" ."jQuery(document).ready(function() { $croutonMap crouton = new Crouton($config); crouton.doHandlebars();})"; - $this->inlineScript($ret); + return $ret; } /** * @desc Adds the options sub-panel @@ -519,7 +507,6 @@ public function adminOptionsPage() } $this->options['root_server'] = $_POST['root_server']; $this->options['service_body_1'] = $_POST['service_body_1']; - $this->options['jsInFooter'] = isset($_POST['jsInFooter']); $this->options['time_format'] = $_POST['time_format']; $this->options['language'] = $_POST['language']; $this->options['strict_datafields'] = isset($_POST['strict_datafields']); @@ -578,9 +565,6 @@ public function adminOptionsPage() } else { $this->options['extra_meetings_enabled'] = 1; } - if (!isset($this->options['jsInFooter'])) { - $this->options['jsInFooter'] = true; - } ?>
@@ -710,14 +694,7 @@ public function adminOptionsPage() " /> -
-
-

Advanced Options

-

Should the generated Javascript be placed in the footer or in the body.

-
- options['jsInFooter'] == 1 ? 'checked' : '') ?> />Place Javascript in Footer -
-
+
diff --git a/croutonjs/src/js/crouton-core.js b/croutonjs/src/js/crouton-core.js index 27b3afe..997717b 100644 --- a/croutonjs/src/js/crouton-core.js +++ b/croutonjs/src/js/crouton-core.js @@ -539,7 +539,7 @@ function Crouton(config) { if (showingNow!==null) filteredMeetings = self.meetingData.filter((m) => showingNow.includes(m.id_bigint)); var ids = getUniqueValuesOfKey(filteredMeetings, 'service_body_bigint'); var me = this; - self.getServiceBodies(ids).then(function (service_bodies) { + self.getServiceBodies(ids, false).then(function (service_bodies) { var n = service_bodies.length; var names = service_bodies.map((m)=>m['name']); names.sort(); @@ -559,9 +559,7 @@ function Crouton(config) { }); }); } - self.getServiceBodies = function(service_bodies_id) { - const requires_parents = true; - + self.getServiceBodies = function(service_bodies_id, requires_parents=true) { var url = this.config['root_server'] + '/client_interface/jsonp/?switcher=GetServiceBodies' + (requires_parents ? '&parents=1' : '') + getServiceBodiesQueryString(service_bodies_id); return fetchJsonp(url) diff --git a/croutonjs/src/templates/header.hbs b/croutonjs/src/templates/header.hbs index 073b79d..ed0a469 100644 --- a/croutonjs/src/templates/header.hbs +++ b/croutonjs/src/templates/header.hbs @@ -1,17 +1,17 @@ {{startup this}} {{#if this.config.header}} {{#if this.config.include_weekday_button}} - + {{/if}} {{#each this.config.button_filters}} - + {{/each}} {{#each this.config.button_format_filters}} - + {{/each}} {{#if this.config.map_page}} - - + + {{/if}} {{#each this.dropdownData}} diff --git a/readme.txt b/readme.txt index 68c5b78..1436c27 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: na, meeting list, meeting finder, maps, recovery, addiction, webservant, b Requires at least: 4.0 Required PHP: 8.0 Tested up to: 6.6.2 -Stable tag: 3.20.4 +Stable tag: 3.20.5 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html crouton implements a Tabbed UI for BMLT. @@ -36,6 +36,12 @@ https://demo.bmlt.app/crouton == Changelog == += 3.20.5 = +* Fix list_service_bodies including the parent service body. +* Correctly call add_inline_script, and always use it. +* Bug fix for checkbox placing JS in footer +* Accessibility improvements + = 3.20.4 = * Bug fix for fixing container height when using OSM