Created
September 15, 2017 13:00
-
-
Save stuporglue/39777add448008096cb6a43a6ffc8c47 to your computer and use it in GitHub Desktop.
Load required scripts and styles into a page if they're not already loaded.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* We'll need access to these two objects. | |
*/ | |
global $wp_scripts, $wp_styles; | |
/** | |
* Loop over all queued styles. If a style is still in the queue it hasn't been printed yet. | |
* | |
* Get its info so we can later check if it needs to be loaded. | |
* | |
* The queue only has the handles of the css files. | |
*/ | |
$maybe_missing_css = array(); | |
foreach( $wp_styles->queue as $handle ){ | |
if ( strpos( $handle, 'leafletphp' ) === 0 ) { | |
$maybe_missing_css[] = $handle; | |
} | |
} | |
/** | |
* The queued CSS files might depend on other CSS files. Load depenencies, then get info | |
* about each script from the to_do list. | |
*/ | |
$missing_css = array(); | |
if ( !empty( $maybe_missing_css ) ) { | |
$wp_styles->all_deps( $maybe_missing_css, true ); | |
foreach ( $wp_styles->to_do as $handle ) { | |
$src = $wp_styles->registered[$handle]->src; | |
// Some styles may be empty if they only have dependencies and no source. Skip these. We'll process their dependencies. | |
if ( empty( $src ) ) { | |
continue; | |
} | |
// Append the absolute URL to the stylesheet if it's a relative path. | |
if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_styles->content_url && 0 === strpos( $src, $wp_styles->content_url ) ) ) { | |
$src = $wp_styles->base_url . $src; | |
} | |
$missing_css[] = add_query_arg( 'ver', $wp_styles->registered[$handle]->ver, $src); | |
} | |
} | |
/** | |
* Now we do the exact same thing for JavaScript | |
*/ | |
$maybe_missing_js = array(); | |
foreach( $wp_scripts->queue as $handle ){ | |
if ( strpos( $handle, 'leafletphp' ) === 0 ) { | |
$maybe_missing_js[] = $handle; | |
} | |
} | |
$missing_js = array(); | |
if ( !empty( $maybe_missing_js ) ) { | |
$wp_scripts->all_deps( $maybe_missing_js, true ); | |
foreach( $wp_scripts->to_do as $handle ) { | |
$src = $wp_scripts->registered[$handle]->src; | |
if ( empty( $src ) ) { | |
continue; | |
} | |
if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_scripts->content_url && 0 === strpos( $src, $wp_scripts->content_url ) ) ) { | |
$src = $wp_scripts->base_url . $src; | |
} | |
$missing_js[] = add_query_arg( 'ver', $wp_scripts->registered[$handle]->ver, $src ); | |
} | |
} | |
/** | |
* At this point any CSS files which haven't been printed during this request | |
* should be in $missing_css and any JS which hasn't been printed should be in | |
* $missing_js. Note that since this may be an ajax request we don't know what | |
* was loaded on the actual page, or by other ajax calls. | |
* | |
* Now we print our HTML, including our <script> tag. | |
* | |
* In reality this might be bundled in a function and return the HTML as a string | |
* which would be included in the ajax response. | |
*/ | |
// Generate a unique ID for our div, so we can reference it in JavaScript later. | |
$div_id = 'my_div_' . time(); | |
// Set up the div wrapper. | |
?> | |
<div id="<?php echo $div_id;?>"> | |
<script> | |
// The ajax call may occur many times on a page, but we only need to load the JS/CSS once. | |
// Use a global to keep track of our promises. | |
window.js_promises = window.js_promises || []; | |
// Only run after the document is ready. This code may be being printed inline, in which case | |
// scripts may be being printed in the footer, in which case we don't want to also print ours. | |
jQuery(document).ready(function(){ | |
var maybe_missing_css = <?php echo json_encode( $missing_css ); ?>; | |
jQuery(maybe_missing_css).each(function(i,css){ | |
// Search for any missing CSS files. | |
if ( jQuery('link[href="'+css+'"]').length === 0 ) { | |
// CSS <link> elements can be added to the DOM at any time and they'll be loaded. | |
jQuery('head').append('<link rel="stylesheet" href="'+css+'">'); | |
} | |
}); | |
var maybe_missing_js = <?php echo json_encode( $missing_js ); ?>; | |
jQuery(maybe_missing_js).each(function(i,js){ | |
if ( jQuery('script[src="'+js+'"]').length === 0 ) { | |
// Adding a <script> to the DOM doesn't actually load it. We just do this | |
// so that if we have multiple blocks of ajax loaded content we don't end | |
// up loading a script for each one. | |
jQuery('head').append('<link rel="stylesheet" href="'+js+'">'); | |
// We could use .getScript() instead of .ajax(), but .getScript | |
// doesn't cache requested files, and we want caching. | |
var promise = jQuery.ajax({ | |
dataType: 'script', | |
cache: true, | |
url: js | |
}); | |
// Gather up the promises. | |
window.js_promises.push( promise ); | |
} | |
}); | |
// jQuery.when takes a comma delimited list of promises/deferred objects. | |
// Since we have an array of them, use .apply. | |
jQuery.when.apply( jQuery, window.js_promises ).then(function(){ | |
// This function will run when all of the promises have successfully | |
// completed, or in other words, when all our required JavaScript is available. | |
var div_id='<?php echo $div_id;?>'; | |
// With the scripts all loaded we're ready to do something awesome with this div! | |
jQuery('#'+div_id).doSomethingAwesome(); | |
}); | |
}); | |
</script> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment