Permalink
Browse files

feature(js): Adds temporary require() shim for deferring inline scripts

This allows plugin devs to convert inline scripts to use require() until
they can properly convert them to AMD/external files. This also patches
many Elgg core inline scripts to use require().
  • Loading branch information...
mrclay committed May 3, 2015
1 parent 9587ae0 commit 65fddb002e0231b141acd4e25cd8546da245db0b
View
@@ -15,10 +15,38 @@ From 1.11 to 2.0
All scripts moved to bottom of page
-----------------------------------
-All inline scripts must be converted to :doc:`AMD </guides/javascript>` or to external scripts loaded with
-``elgg_load_js``. For performance reasons, Elgg no longer loads its core scripts in the ``head`` element,
-and ``elgg_register_js`` no longer honors ``$location == 'head'``, instead outputting all scripts at the
-end of the ``body`` element.
+You should test your plugin **with the JavaScript error console visible**. For performance reasons, Elgg no longer
+supports ``script`` elements in the ``head`` element or in HTML views. ``elgg_register_js`` will now load *all*
+scripts at the end of the ``body`` element.
+
+You must convert inline scripts to :doc:`AMD </guides/javascript>` or to external scripts loaded with
+``elgg_load_js``.
+
+Early in the page, Elgg provides a shim of the RequireJS ``require()`` function that simply queues code until
+the AMD ``elgg`` and ``jQuery`` modules are defined. This provides a straightforward way to convert many inline
+scripts to use ``require()``.
+
+Inline code which will fail because the stack is not yet loaded:
+
+.. code:: html
+
+ <script>
+ $(function () {
+ // code using $ and elgg
+ });
+ </script>
+
+This should work in Elgg 2.0:
+
+.. code:: html
+
+ <script>
+ require(['elgg', 'jquery'], function (elgg, $) {
+ $(function () {
+ // code using $ and elgg
+ });
+ });
+ </script>
Removed Functions
-----------------
@@ -7,12 +7,14 @@
?>
<script>
-// This global variable must be set before the editor script loading.
-CKEDITOR_BASEPATH = elgg.config.wwwroot + 'mod/ckeditor/vendors/ckeditor/';
+require(['elgg'], function (elgg) {
+ // This global variable must be set before the editor script loading.
+ CKEDITOR_BASEPATH = elgg.config.wwwroot + 'mod/ckeditor/vendors/ckeditor/';
-require(['elgg/ckeditor', 'jquery', 'jquery.ckeditor'], function(elggCKEditor, $) {
- $('.elgg-input-longtext:not([data-cke-init])')
- .attr('data-cke-init', true)
- .ckeditor(elggCKEditor.init, elggCKEditor.config);
+ require(['elgg/ckeditor', 'jquery', 'jquery.ckeditor'], function(elggCKEditor, $) {
+ $('.elgg-input-longtext:not([data-cke-init])')
+ .attr('data-cke-init', true)
+ .ckeditor(elggCKEditor.init, elggCKEditor.config);
+ });
});
</script>
@@ -52,17 +52,19 @@ function css_permissions_override() {
?>
</div>
-<script type="text/javascript">
+<script>
+require(['elgg', 'jquery'], function (elgg, $) {
// widgets do not have guids so we override the edit toggle and delete button
$(function() {
$('.elgg-widget-edit-button').unbind('click');
- $('.elgg-widget-edit-button').click(function() {
+ $('.elgg-widget-edit-button').on('click', function() {
$(this).closest('.elgg-module-widget').find('.elgg-widget-edit').slideToggle('medium');
return false;
});
- $('.elgg-widget-delete-button').click(function() {
+ $('.elgg-widget-delete-button').on('click', function() {
$(this).closest('.elgg-module-widget').remove();
return false;
});
});
+});
</script>
@@ -7,19 +7,17 @@
$user = $vars['user'];
//@todo JS 1.8: no ?>
-<script type="text/javascript">
-
+<script>
function setCollection(members, method, id) {
for ( var i in members ) {
var checked = $('#' + method + 'collections' + id).children("INPUT[type='checkbox']").attr('checked');
- if ($("#"+method+members[i]).children("INPUT[type='checkbox']").attr('checked') != checked) {
+ if ($("#"+method+members[i]).children("INPUT[type='checkbox']").attr('checked') != checked) {
$("#"+method+members[i]).children("INPUT[type='checkbox']").attr('checked', checked);
functioncall = 'adjust' + method + '_alt("'+method+members[i]+'");';
eval(functioncall);
}
- }
+ }
}
-
</script>
<div class="elgg-module elgg-module-info">
<div class="elgg-head">
@@ -137,28 +137,29 @@
if ($formtarget) {
?>
<?php //@todo JS 1.8: no ?>
- <script language="text/javascript">
- $(function() { // onload...do
- $('#collectionMembersForm<?php echo $friendspicker; ?>').submit(function() {
- var inputs = [];
- $(':input', this).each(function() {
- if (this.type != 'checkbox' || (this.type == 'checkbox' && this.checked != false)) {
- inputs.push(this.name + '=' + escape(this.value));
- }
- });
- jQuery.ajax({
- type: "POST",
- data: inputs.join('&'),
- url: this.action,
- success: function(){
- $('a.collectionmembers<?php echo $friendspicker; ?>').click();
- }
+ <script>
+ require(['jquery'], function($) {
+ $(function () {
+ $('#collectionMembersForm<?php echo $friendspicker; ?>').submit(function() {
+ var inputs = [];
+ $(':input', this).each(function() {
+ if (this.type != 'checkbox' || (this.type == 'checkbox' && this.checked != false)) {
+ inputs.push(this.name + '=' + escape(this.value));
+ }
+ });
+ $.ajax({
+ type: "POST",
+ data: inputs.join('&'),
+ url: this.action,
+ success: function(){
+ $('a.collectionmembers<?php echo $friendspicker; ?>').click();
+ }
+ });
+ return false;
});
- return false;
- })
- })
-
+ });
+ });
</script>
<?php
@@ -307,26 +308,26 @@
if (!isset($vars['replacement'])) {
?>
<?php //@todo JS 1.8: no ?>
-<script type="text/javascript">
+<script>
+require(['elgg', 'jquery'], function(elgg, $) {
+ $(function () {
// initialise picker
$("div#friends-picker<?php echo $friendspicker; ?>").friendsPicker(<?php echo $friendspicker; ?>);
-</script>
-<script type="text/javascript">
- $(function () {
- // manually add class to corresponding tab for panels that have content
-<?php
- if (sizeof($activeletters) > 0) {
- $chararray .= "*";
- foreach($activeletters as $letter) {
- $tab = elgg_strpos($chararray, $letter) + 1;
-?>
- $("div#friends-picker-navigation<?php echo $friendspicker; ?> li.tab<?php echo $tab; ?> a").addClass("tabHasContent");
-<?php
- }
- }
-?>
+ // manually add class to corresponding tab for panels that have content
+ <?php
+ if (sizeof($activeletters) > 0) {
+ $chararray .= "*";
+ foreach($activeletters as $letter) {
+ $tab = elgg_strpos($chararray, $letter) + 1;
+ ?>
+ $("div#friends-picker-navigation<?php echo $friendspicker; ?> li.tab<?php echo $tab; ?> a").addClass("tabHasContent");
+ <?php
+ }
+ }
+ ?>
});
+});
</script>
<?php
@@ -4,30 +4,27 @@
?>
<?php //@todo JS 1.8: no ?>
-<script type="text/javascript">
+<script>
+require(['jquery'], function($) {
+ $(function () {
+ <?php
+ foreach($NOTIFICATION_HANDLERS as $method => $foo) {
+ ?>
+ $('input[type=checkbox]:checked').parent("a.<?php echo $method; ?>toggleOff").each(function(){
+ $(this).removeClass('<?php echo $method; ?>toggleOff').addClass('<?php echo $method; ?>toggleOn');
+ });
-$(document).ready(function () {
-<?php
-foreach($NOTIFICATION_HANDLERS as $method => $foo) {
-?>
- $('input[type=checkbox]:checked').parent("a.<?php echo $method; ?>toggleOff").each(function(){
- $(this).removeClass('<?php echo $method; ?>toggleOff').addClass('<?php echo $method; ?>toggleOn');
+ <?php
+ }
+ ?>
});
-
-<?php
-}
-?>
-
});
-
- clickflag = 0;
-
<?php
foreach($NOTIFICATION_HANDLERS as $method => $foo) {
?>
function adjust<?php echo $method; ?>(linkId) {
var obj = $(this).prev("a");
-
+
if (obj.className == "<?php echo $method; ?>toggleOff") {
obj.className = "<?php echo $method; ?>toggleOn";
} else {
@@ -11,13 +11,13 @@
?>
<?php //@todo JS 1.8: no ?>
-<script type="text/javascript">
+<script>
AudioPlayer.setup("<?php echo $swf_url; ?>", {width: 290});
</script>
<div class="zaudio">
<p id="zaudioplayer"></p>
- <script type="text/javascript">
+ <script>
AudioPlayer.embed("zaudioplayer", {soundFile: "<?php echo $mp3_url; ?>"});
</script>
</div>
@@ -51,11 +51,14 @@
));
?>
<?php //@todo JS 1.8: no ?>
- <script type="text/javascript">
- $(function () {
-
- $('#friends-picker_placeholder<?php echo $vars['friendspicker']; ?>').load(elgg.config.wwwroot + 'pages/friends/collections/pickercallback.php?username=<?php echo elgg_get_logged_in_user_entity()->username; ?>&type=list&collection=<?php echo $vars['collection']->id; ?>');
-
+ <script>
+ require(['elgg', 'jquery'], function(elgg, $) {
+ $(function () {
+ var url = elgg.config.wwwroot + 'pages/friends/collections/pickercallback.php' +
+ '?username=<?php echo elgg_get_logged_in_user_entity()->username; ?>' +
+ '&type=list&collection=<?php echo $vars['collection']->id; ?>';
+ $('#friends-picker_placeholder<?php echo $vars['friendspicker']; ?>').load(url);
+ });
});
</script>
<?php
@@ -30,10 +30,11 @@
?>
<?php //@todo JS 1.8: no ?>
<script>
-$(function(){
- $('#friends_collections_accordian h2').click(function () {
- $(this.parentNode).children("[class=friends-picker-main-wrapper]").slideToggle("fast");
- //return false;
+require(['jquery'], function($) {
+ $(function () {
+ $('#friends_collections_accordian h2').on('click', function () {
+ $(this.parentNode).children("[class=friends-picker-main-wrapper]").slideToggle("fast");
+ });
});
});
</script>
@@ -30,33 +30,32 @@
</ul>
<?php //@todo JS 1.8: no ?>
-<script type="text/javascript">
-$(function () {
-
- $('a.collectionmembers<?php echo $friendspicker; ?>').click(function () {
- // load collection members pane
- $('#friends-picker_placeholder<?php echo $friendspicker; ?>').load('<?php echo elgg_get_site_url(); ?>pages/friends/collections/pickercallback.php?username=<?php echo elgg_get_logged_in_user_entity()->username; ?>&type=list&collection=<?php echo $collectionid; ?>&friendspicker=<?php echo $friendspicker; ?>');
-
- // remove selected state from previous tab
- $(this).parent().parent().find("li.elgg-state-selected").removeClass("elgg-state-selected");
- // add selected class to current tab
- $(this).parent().addClass("elgg-state-selected");
-
- return false;
+<script>
+require(['jquery'], function($) {
+ $(function () {
+ $('a.collectionmembers<?php echo $friendspicker; ?>').click(function () {
+ // load collection members pane
+ $('#friends-picker_placeholder<?php echo $friendspicker; ?>').load('<?php echo elgg_get_site_url(); ?>pages/friends/collections/pickercallback.php?username=<?php echo elgg_get_logged_in_user_entity()->username; ?>&type=list&collection=<?php echo $collectionid; ?>&friendspicker=<?php echo $friendspicker; ?>');
+
+ // remove selected state from previous tab
+ $(this).parent().parent().find("li.elgg-state-selected").removeClass("elgg-state-selected");
+ // add selected class to current tab
+ $(this).parent().addClass("elgg-state-selected");
+
+ return false;
+ });
+
+ $('a.editmembers<?php echo $friendspicker; ?>').click(function () {
+ // load friends picker pane
+ $('#friends-picker_placeholder<?php echo $friendspicker; ?>').load('<?php echo elgg_get_site_url(); ?>pages/friends/collections/pickercallback.php?username=<?php echo elgg_get_logged_in_user_entity()->username; ?>&type=picker&collection=<?php echo $collectionid; ?>&friendspicker=<?php echo $friendspicker; ?>');
+
+ // remove selected state from previous tab
+ $(this).parent().parent().find("li.elgg-state-selected").removeClass("elgg-state-selected");
+ // add selected class to current tab
+ $(this).parent().addClass("elgg-state-selected");
+
+ return false;
+ });
});
-
- $('a.editmembers<?php echo $friendspicker; ?>').click(function () {
- // load friends picker pane
- $('#friends-picker_placeholder<?php echo $friendspicker; ?>').load('<?php echo elgg_get_site_url(); ?>pages/friends/collections/pickercallback.php?username=<?php echo elgg_get_logged_in_user_entity()->username; ?>&type=picker&collection=<?php echo $collectionid; ?>&friendspicker=<?php echo $friendspicker; ?>');
-
- // remove selected state from previous tab
- $(this).parent().parent().find("li.elgg-state-selected").removeClass("elgg-state-selected");
- // add selected class to current tab
- $(this).parent().addClass("elgg-state-selected");
-
- return false;
- });
-
-
});
</script>
@@ -12,6 +12,10 @@
?>
<?php //@todo JS 1.8: no ?>
-<script language="text/javascript">
- $("#friends_membership_count<?php echo $vars['friendspicker']; ?>").html("<?php echo $vars['count']; ?>");
+<script>
+require(['jquery'], function($) {
+ $(function () {
+ $("#friends_membership_count<?php echo $vars['friendspicker']; ?>").html("<?php echo $vars['count']; ?>");
+ });
+});
</script>
@@ -42,8 +42,10 @@
?>
-<script type="text/javascript">
-elgg.provide('elgg.autocomplete');
-elgg.autocomplete.url = "<?php echo elgg_get_site_url() . 'livesearch?' . $ac_url_params; ?>";
-</script>
+<script>
+require(['elgg'], function (elgg) {

This comment has been minimized.

Show comment
Hide comment
@migburillo

migburillo Jun 26, 2015

Hello,
I think this crashes the autocomplete since the ui.autocomplete.js file, which is loaded in line 40 elgg_load_js('elgg.autocomplete'); is using the var elgg.autocomplete.url before being defined.
Maybe you should load this file with require also (in line 46)

Thanks!

@migburillo

migburillo Jun 26, 2015

Hello,
I think this crashes the autocomplete since the ui.autocomplete.js file, which is loaded in line 40 elgg_load_js('elgg.autocomplete'); is using the var elgg.autocomplete.url before being defined.
Maybe you should load this file with require also (in line 46)

Thanks!

This comment has been minimized.

Show comment
Hide comment
@mrclay

mrclay Jun 26, 2015

Member

Have you done git pull recently? I don't think this is a problem in the latest commits. If it is, please file an issue.

@mrclay

mrclay Jun 26, 2015

Member

Have you done git pull recently? I don't think this is a problem in the latest commits. If it is, please file an issue.

+ elgg.provide('elgg.autocomplete');
+ elgg.autocomplete.url = "<?php echo elgg_get_site_url() . 'livesearch?' . $ac_url_params; ?>";
+});
+</script>
<input type="text" <?php echo elgg_format_attributes($vars); ?> />
Oops, something went wrong.

0 comments on commit 65fddb0

Please sign in to comment.