[Rt-commit] rt branch, 4.6/pjax, updated. rt-4.4.1-12-gd6eadbe
Shawn Moore
shawn at bestpractical.com
Thu Sep 29 19:06:24 EDT 2016
The branch, 4.6/pjax has been updated
via d6eadbe03788785d0f66a06ea1d6d12258cefa9e (commit)
via ae222b835b87d52fe237444725a9a29e5410af84 (commit)
via d3a848ed8d92c973c404cff10853ee9cec3b925a (commit)
via 0176dc26f29f8234288d75f3428c0159bdc904c1 (commit)
via a77201aced57d6317e530e212cc65ab1174f3ae2 (commit)
via 7d5e931f2e1e6937109ce2a65f4ef029155b345c (commit)
from e17b79b711e502af9f62153b50b02fdb8dbe8a2d (commit)
Summary of changes:
devel/docs/UPGRADING-4.6 | 71 ++++++++++++++
lib/RT/Interface/Web.pm | 2 +
share/html/Admin/Tools/Queries.html | 6 --
share/html/Admin/Tools/Theme.html | 2 -
share/html/Elements/Header | 11 ++-
share/html/Elements/HeaderJavascript | 16 ++--
share/html/Elements/Login | 2 +-
share/html/Helpers/TicketTimer | 2 +-
share/static/js/assets.js | 2 +-
share/static/js/autocomplete.js | 5 +-
share/static/js/event-registration.js | 10 +-
share/static/js/forms.js | 4 +-
share/static/js/keyboard-shortcuts.js | 168 +++++++++++++++++-----------------
share/static/js/late.js | 4 +-
share/static/js/util.js | 5 +-
15 files changed, 195 insertions(+), 115 deletions(-)
create mode 100644 devel/docs/UPGRADING-4.6
- Log -----------------------------------------------------------------
commit 7d5e931f2e1e6937109ce2a65f4ef029155b345c
Author: Shawn M Moore <shawn at bestpractical.com>
Date: Thu Sep 29 22:40:14 2016 +0000
Finish removing unused RichText parameter
c1c91d2a1d65153a555a52698660f9db85670149 made CKEditor unconditionally loaded,
but did not completely purge the RichText parameter which had been used
to request the conditional loading.
diff --git a/share/html/Elements/Header b/share/html/Elements/Header
index 0ead426..8e2eed9 100644
--- a/share/html/Elements/Header
+++ b/share/html/Elements/Header
@@ -97,7 +97,7 @@
% # Leave %ARGS for backward compatibility
% $m->callback( %ARGS, CallbackName => 'Head', ARGSRef => \%ARGS );
-<& HeaderJavascript, focus => $Focus, onload => $onload, RichText => $RichText &>
+<& HeaderJavascript, focus => $Focus, onload => $onload &>
<& /Elements/Framekiller &>
@@ -168,6 +168,5 @@ $RSSAutoDiscovery => undef
$onload => undef
$LinkRel => undef
$SkipDoctype => 0
-$RichText => 1
$BodyClass => undef
</%ARGS>
diff --git a/share/html/Elements/Login b/share/html/Elements/Login
index 6650962..70484bd 100644
--- a/share/html/Elements/Login
+++ b/share/html/Elements/Login
@@ -46,7 +46,7 @@
%#
%# END BPS TAGGED BLOCK }}}
% $m->callback( %ARGS, CallbackName => 'Header' );
-<& /Elements/Header, Title => loc('Login'), Focus => '#user', RichText => 0 &>
+<& /Elements/Header, Title => loc('Login'), Focus => '#user' &>
<div id="body" class="login-body">
diff --git a/share/html/Helpers/TicketTimer b/share/html/Helpers/TicketTimer
index 2a8b0d6..fef6f86 100644
--- a/share/html/Helpers/TicketTimer
+++ b/share/html/Helpers/TicketTimer
@@ -60,7 +60,7 @@ $Now->SetToNow;
my $SubmitURL = RT->Config->Get('WebPath') . '/Helpers/AddTimeWorked';
</%INIT>
-<& /Elements/Header, Title => loc('Timer for #[_1]: [_2]', $Ticket->Id, $Ticket->Subject), RichText => 0, ShowBar => 0, ShowTitle => 0 &>
+<& /Elements/Header, Title => loc('Timer for #[_1]: [_2]', $Ticket->Id, $Ticket->Subject), ShowBar => 0, ShowTitle => 0 &>
<script type="text/javascript">
jQuery( function() {
commit a77201aced57d6317e530e212cc65ab1174f3ae2
Author: Shawn M Moore <shawn at bestpractical.com>
Date: Thu Sep 29 21:34:41 2016 +0000
Avoid loading standalone JS files on individual pages
pjax page loads cannot include a <script src="...">; such declarations
are ignored.
This makes .tablesorter have universal effect, which is now usable by
extensions and other customizations.
This also makes farbtastic more readily available for use by extensions
and other customizations.
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index d92ef44..4c23e46 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -115,6 +115,7 @@ sub JSFiles {
jquery.modal.min.js
jquery.modal-defaults.js
jquery.cookie.js
+ jquery.tablesorter.min.js
jquery.pjax.js
titlebox-state.js
i18n.js
@@ -136,6 +137,7 @@ sub JSFiles {
assets.js
/static/RichText/ckeditor.js
dropzone.min.js
+ farbtastic.js
}, RT->Config->Get('JSFiles');
}
diff --git a/share/html/Admin/Tools/Queries.html b/share/html/Admin/Tools/Queries.html
index b6e263b..1d9ed02 100644
--- a/share/html/Admin/Tools/Queries.html
+++ b/share/html/Admin/Tools/Queries.html
@@ -57,8 +57,6 @@ unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'Super
</%init>
<& /Admin/Elements/Header, Title => $title &>
<& /Elements/Tabs &>
-<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/static/js/jquery.tablesorter.min.js"></script>
-
<&|/Widgets/TitleBox, title => loc('SQL Queries') &>
% my $history = $RT::Handle->QueryHistory;
% if (!RT->Config->Get('StatementLog')) {
@@ -66,10 +64,6 @@ unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'Super
% } elsif (!$history) {
<p><&|/l&>This server process has recorded no SQL queries.</&></p>
% } else {
- <script type="text/javascript">
- jQuery(function () { jQuery(".tablesorter").tablesorter(); });
- </script>
-
<ol>
% my $r = 0;
% for my $request (@$history) {
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index 2cc079f..70acfcf 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -51,8 +51,6 @@
<& /Elements/Tabs &>
<& /Elements/ListActions, actions => \@results &>
-<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/static/js/farbtastic.js"></script>
-
<div id="simple-customize">
<div id="upload-logo">
<h2>Logo</h2>
diff --git a/share/static/js/util.js b/share/static/js/util.js
index 20b32f9..e8a0848 100644
--- a/share/static/js/util.js
+++ b/share/static/js/util.js
@@ -550,6 +550,7 @@ jQuery(function() {
jQuery('.combobox input.combo-text').each(function () {
ComboBox_Init(this.id)();
});
+ jQuery(".tablesorter").tablesorter();
});
// focus jquery object in window, only moving the screen when necessary
commit 0176dc26f29f8234288d75f3428c0159bdc904c1
Author: Shawn M Moore <shawn at bestpractical.com>
Date: Thu Sep 29 21:27:51 2016 +0000
Switch primary jQuery(function ...) registrations to handle pjax too
This is necessary because jQuery(function () { ... }) fires only once,
when the first page load is complete. When a pjax page load happens, the
jQuery(function () { ... }) handler is not invoked again because it's
still the same page load as far as the browser is concerned. So to run
JS for each pjax page load we must run them on pjax:success events as well.
According to https://api.jquery.com/ready/, jQuery(function () { ... }) is
equivalent to jQuery(document).ready(function () { ... }) (which is equivalent
to jQuery(document).on('ready', function () { ... })), so the timing of the
initial "page loaded" callbacks will remain unchanged.
This is required only for standalone .js files; HTML files that include a
<script type="text/javascript">
jQuery(function () { ... })
</script>
will have such code executed even during pjax loads.
These changes unbreak the following JS-based features:
- datepicker
- ckeditor
- user accordion (for "more about requestors")
- chosen select box
- combobox
- attachment warning
- autocomplete
- disable queue checkboxes when apply globally is selected
- linkify users in history
- cascade-select custom fields
- messagebox background color for dynamic change of reply/comment
- assets accordion on ticket display
- lightbox for asset create
- lightbox for linked ticket create on assets
- keep multiple input fields for the same custom field in sync
- avoiding form double submission in Safari
diff --git a/share/static/js/assets.js b/share/static/js/assets.js
index 853ba86..7f7961a 100644
--- a/share/static/js/assets.js
+++ b/share/static/js/assets.js
@@ -1,4 +1,4 @@
-jQuery(function() {
+jQuery(document).on('ready pjax:success', function() {
var showModal = function(html) {
jQuery("<div class='modal'></div>")
.append(html).appendTo("body")
diff --git a/share/static/js/autocomplete.js b/share/static/js/autocomplete.js
index cd8ab2b..337692e 100644
--- a/share/static/js/autocomplete.js
+++ b/share/static/js/autocomplete.js
@@ -113,4 +113,7 @@ window.RT.Autocomplete.bind = function(from) {
};
});
};
-jQuery(function(){ RT.Autocomplete.bind(document) });
+
+jQuery(document).on('ready pjax:success', function () {
+ RT.Autocomplete.bind(document);
+});
diff --git a/share/static/js/event-registration.js b/share/static/js/event-registration.js
index eaacbdb..5256a98 100644
--- a/share/static/js/event-registration.js
+++ b/share/static/js/event-registration.js
@@ -1,5 +1,5 @@
// Disable chosing individual objects when a scrip is applied globally
-jQuery(function() {
+jQuery(document).on('ready pjax:success', function() {
var global_checkboxes = [
"form[name=AddRemoveScrip] input[type=checkbox][name^=AddScrip-][value=0]",
"form input[type=checkbox][name^=AddCustomField-][value=0]"
@@ -39,10 +39,10 @@ function ReplaceUserReferences() {
}
);
}
-jQuery(ReplaceUserReferences);
+jQuery(document).on('ready pjax:success', ReplaceUserReferences);
// Cascaded selects
-jQuery(function() {
+jQuery(document).on('ready pjax:success', function() {
jQuery("select.cascade-by-optgroup").each(function(){
var name = this.name;
if (!name) return;
@@ -115,7 +115,7 @@ jQuery(function() {
});
});
-jQuery( function() {
+jQuery(document).on('ready pjax:success', function () {
jQuery("input[type=file]").change( function() {
var input = jQuery(this);
var warning = input.next(".invalid");
@@ -135,7 +135,7 @@ jQuery( function() {
});
});
-jQuery(function() {
+jQuery(document).on('ready pjax:success', function() {
jQuery("#UpdateType").change(function(ev) {
jQuery(".messagebox-container")
.removeClass("action-response action-private")
diff --git a/share/static/js/forms.js b/share/static/js/forms.js
index 3c6f9b9..1bf28cb 100644
--- a/share/static/js/forms.js
+++ b/share/static/js/forms.js
@@ -1,4 +1,4 @@
-jQuery(function() {
+jQuery(document).on('ready', function() {
// reset form submit info when user goes backward or forward for Safari
// other browsers don't need this trick and they can work directly.
if ( window.addEventListener ) {
@@ -6,7 +6,9 @@ jQuery(function() {
jQuery('form').data('submitted', false);
});
}
+});
+jQuery(document).on('ready pjax:success', function () {
jQuery('form').submit(function(e) {
var form = jQuery(this);
if (form.data('submitted') === true) {
diff --git a/share/static/js/late.js b/share/static/js/late.js
index 92a8279..97ff9be 100644
--- a/share/static/js/late.js
+++ b/share/static/js/late.js
@@ -1,7 +1,6 @@
// Lower the speed limit for hover intent event
jQuery.event.special.hover.speed = 80; // pixels per second
-jQuery(function() { sync_grouped_custom_fields() } );
function sync_grouped_custom_fields() {
var all_inputs = jQuery("input,textarea,select");
var parse_cf = /^Object-([\w:]+)-(\d*)-CustomField(?::\w+)?-(\d+)-(.*)$/;
@@ -37,3 +36,6 @@ function sync_grouped_custom_fields() {
elem.change( trigger_func );
});
}
+jQuery(document).on('ready pjax:success', function() {
+ sync_grouped_custom_fields();
+});
diff --git a/share/static/js/util.js b/share/static/js/util.js
index e8a0848..07ebfdf 100644
--- a/share/static/js/util.js
+++ b/share/static/js/util.js
@@ -218,7 +218,7 @@ function doOnLoad( js ) {
jQuery(js);
}
-jQuery(function() {
+jQuery(document).on('ready pjax:success', function() {
var opts = {
dateFormat: 'yy-mm-dd',
constrainInput: false,
@@ -521,7 +521,7 @@ function escapeCssSelector(str) {
}
-jQuery(function() {
+jQuery(document).on('ready pjax:success', function() {
jQuery(".user-accordion").each(function(){
jQuery(this).accordion({
active: (jQuery(this).find("h3").length == 1 ? 0 : false),
commit d3a848ed8d92c973c404cff10853ee9cec3b925a
Author: Shawn M Moore <shawn at bestpractical.com>
Date: Thu Sep 29 22:03:53 2016 +0000
Switch keybindings to handle pjax page loads
This situation is special because we must call Mousetrap.reset() to reset
all keybindings. To avoid any ordering problem with event callbacks (say we
put .reset() in one of the two callbacks, but the other one is invoked
first), the two separate jQuery(function () { ... }) are combined into one.
diff --git a/share/static/js/keyboard-shortcuts.js b/share/static/js/keyboard-shortcuts.js
index a7b4cf5..cc421ec 100644
--- a/share/static/js/keyboard-shortcuts.js
+++ b/share/static/js/keyboard-shortcuts.js
@@ -1,4 +1,6 @@
-jQuery(function() {
+jQuery(document).on('ready pjax:success', function() {
+ Mousetrap.reset();
+
var goBack = function() {
window.history.back();
};
@@ -63,91 +65,89 @@ jQuery(function() {
Mousetrap.bind('g h', goHome);
Mousetrap.bind('/', simpleSearch);
Mousetrap.bind('?', openHelp);
-});
-jQuery(function() {
// Only load these shortcuts if there is a ticket list on the page
var hasTicketList = jQuery('table.ticket-list').length;
- if (!hasTicketList) return;
-
- var currentRow;
-
- var nextTicket = function() {
- var nextRow;
- var searchResultsTable = jQuery('.ticket-list.collection-as-table');
- if (!currentRow || !(nextRow = currentRow.next('tbody.list-item')).length) {
- nextRow = searchResultsTable.find('tbody.list-item').first();
- }
- setNewRow(nextRow);
- };
-
- var setNewRow = function(newRow) {
- if (currentRow) currentRow.removeClass('selected-row');
- currentRow = newRow;
- currentRow.addClass('selected-row');
- scrollToJQueryObject(currentRow);
- };
-
- var prevTicket = function() {
- var prevRow, searchResultsTable = jQuery('.ticket-list.collection-as-table');
- if (!currentRow || !(prevRow = currentRow.prev('tbody.list-item')).length) {
- prevRow = searchResultsTable.find('tbody.list-item').last();
- }
- setNewRow(prevRow);
- };
-
- var generateTicketLink = function(ticketId) {
- if (!ticketId) return '';
- return RT.Config.WebHomePath + '/Ticket/Display.html?id=' + ticketId;
- };
-
- var generateUpdateLink = function(ticketId, action) {
- if (!ticketId) return '';
- return RT.Config.WebHomePath + '/Ticket/Update.html?Action=' + action + '&id=' + ticketId;
- };
-
- var navigateToCurrentTicket = function() {
- if (!currentRow) return;
-
- var ticketId = currentRow.closest('tbody').data('recordId');
- var ticketLink = generateTicketLink(ticketId);
- if (!ticketLink) return;
-
- window.location.href = ticketLink;
- };
-
- var toggleTicketCheckbox = function() {
- if (!currentRow) return;
- var ticketCheckBox = currentRow.find('input[type=checkbox]');
- if (!ticketCheckBox.length) return;
- ticketCheckBox.prop("checked", !ticketCheckBox.prop("checked"));
- };
-
- var replyToTicket = function() {
- if (!currentRow) return;
-
- var ticketId = currentRow.closest('tbody').data('recordId');
- var replyLink = generateUpdateLink(ticketId, 'Respond');
- if (!replyLink) return;
-
- window.location.href = replyLink;
- };
-
- var commentOnTicket = function() {
- if (!currentRow) return;
-
- var ticketId = currentRow.closest('tbody').data('recordId');
- var commentLink = generateUpdateLink(ticketId, 'Comment');
- if (!commentLink) return;
-
- window.location.href = commentLink;
- };
-
- Mousetrap.bind('j', nextTicket);
- Mousetrap.bind('k', prevTicket);
- Mousetrap.bind(['enter','o'], navigateToCurrentTicket);
- Mousetrap.bind('r', replyToTicket);
- Mousetrap.bind('c', commentOnTicket);
- Mousetrap.bind('x', toggleTicketCheckbox);
+ if (hasTicketList) {
+ var currentRow;
+
+ var nextTicket = function() {
+ var nextRow;
+ var searchResultsTable = jQuery('.ticket-list.collection-as-table');
+ if (!currentRow || !(nextRow = currentRow.next('tbody.list-item')).length) {
+ nextRow = searchResultsTable.find('tbody.list-item').first();
+ }
+ setNewRow(nextRow);
+ };
+
+ var setNewRow = function(newRow) {
+ if (currentRow) currentRow.removeClass('selected-row');
+ currentRow = newRow;
+ currentRow.addClass('selected-row');
+ scrollToJQueryObject(currentRow);
+ };
+
+ var prevTicket = function() {
+ var prevRow, searchResultsTable = jQuery('.ticket-list.collection-as-table');
+ if (!currentRow || !(prevRow = currentRow.prev('tbody.list-item')).length) {
+ prevRow = searchResultsTable.find('tbody.list-item').last();
+ }
+ setNewRow(prevRow);
+ };
+
+ var generateTicketLink = function(ticketId) {
+ if (!ticketId) return '';
+ return RT.Config.WebHomePath + '/Ticket/Display.html?id=' + ticketId;
+ };
+
+ var generateUpdateLink = function(ticketId, action) {
+ if (!ticketId) return '';
+ return RT.Config.WebHomePath + '/Ticket/Update.html?Action=' + action + '&id=' + ticketId;
+ };
+
+ var navigateToCurrentTicket = function() {
+ if (!currentRow) return;
+
+ var ticketId = currentRow.closest('tbody').data('recordId');
+ var ticketLink = generateTicketLink(ticketId);
+ if (!ticketLink) return;
+
+ window.location.href = ticketLink;
+ };
+
+ var toggleTicketCheckbox = function() {
+ if (!currentRow) return;
+ var ticketCheckBox = currentRow.find('input[type=checkbox]');
+ if (!ticketCheckBox.length) return;
+ ticketCheckBox.prop("checked", !ticketCheckBox.prop("checked"));
+ };
+
+ var replyToTicket = function() {
+ if (!currentRow) return;
+
+ var ticketId = currentRow.closest('tbody').data('recordId');
+ var replyLink = generateUpdateLink(ticketId, 'Respond');
+ if (!replyLink) return;
+
+ window.location.href = replyLink;
+ };
+
+ var commentOnTicket = function() {
+ if (!currentRow) return;
+
+ var ticketId = currentRow.closest('tbody').data('recordId');
+ var commentLink = generateUpdateLink(ticketId, 'Comment');
+ if (!commentLink) return;
+
+ window.location.href = commentLink;
+ };
+
+ Mousetrap.bind('j', nextTicket);
+ Mousetrap.bind('k', prevTicket);
+ Mousetrap.bind(['enter','o'], navigateToCurrentTicket);
+ Mousetrap.bind('r', replyToTicket);
+ Mousetrap.bind('c', commentOnTicket);
+ Mousetrap.bind('x', toggleTicketCheckbox);
+ }
});
commit ae222b835b87d52fe237444725a9a29e5410af84
Author: Shawn M Moore <shawn at bestpractical.com>
Date: Thu Sep 29 22:43:24 2016 +0000
Handle onload and focus Header parameters under pjax
These parameters are used to do such things as focus the username textbox on
the login page, hide the Details panel on ticket create page load, and
automatically restore titlebox collapsedness. Under pjax, we don't send a
<head> tag. Thus HeaderJavascript, which ordinarily handles such
features, is not executed, breaking such features.
To continue providing those features (without any change to the calling
code, thankfully) we move their <script> tag implementations to the top
of the <body> tag under pjax.
diff --git a/share/html/Elements/Header b/share/html/Elements/Header
index 8e2eed9..3dfbeb0 100644
--- a/share/html/Elements/Header
+++ b/share/html/Elements/Header
@@ -45,7 +45,7 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-% unless (IsPjaxRequest()) {
+% unless ($IsPjaxRequest) {
%# index.html gets two doctypes unless we can skip it here
% unless ($SkipDoctype) {
<!DOCTYPE html>
@@ -106,6 +106,11 @@
<body class="<% join( ' ',@{$ARGS{'BodyClass'}}) %>" <% $id && qq[id="comp-$id"] |n %>>
+%# run onload and focus code for pjax requests too
+% if ($IsPjaxRequest) {
+<& HeaderJavascript, focus => $Focus, onload => $onload, include_jsfiles => 0 &>
+% }
+
% if ($ShowBar) {
<& /Elements/Logo, %ARGS &>
@@ -169,4 +174,5 @@ $onload => undef
$LinkRel => undef
$SkipDoctype => 0
$BodyClass => undef
+$IsPjaxRequest => IsPjaxRequest()
</%ARGS>
diff --git a/share/html/Elements/HeaderJavascript b/share/html/Elements/HeaderJavascript
index 81b44b0..bc1a9b2 100644
--- a/share/html/Elements/HeaderJavascript
+++ b/share/html/Elements/HeaderJavascript
@@ -48,6 +48,7 @@
<%args>
$focus => undef
$onload => undef
+$include_jsfiles => 1
</%args>
% for my $jsfile ( @js_files ) {
@@ -69,12 +70,13 @@ jQuery(document).pjax('a', 'body', { timeout: 30000 });
<%INIT>
my @js_files;
-if ( RT->Config->Get('DevelMode') ) {
- @js_files = map { $_ =~ m{^/} ? $_ : "/static/js/$_" } RT::Interface::Web->JSFiles();
+if ($include_jsfiles) {
+ if ( RT->Config->Get('DevelMode') ) {
+ @js_files = map { $_ =~ m{^/} ? $_ : "/static/js/$_" } RT::Interface::Web->JSFiles();
+ }
+ else {
+ my $key = RT::Interface::Web::SquishedJS()->Key;
+ @js_files = "/NoAuth/js/squished-$key.js";
+ }
}
-else {
- my $key = RT::Interface::Web::SquishedJS()->Key;
- @js_files = "/NoAuth/js/squished-$key.js";
-}
-
</%INIT>
commit d6eadbe03788785d0f66a06ea1d6d12258cefa9e
Author: Shawn M Moore <shawn at bestpractical.com>
Date: Thu Sep 29 23:04:09 2016 +0000
UPGRADING-4.6 dev notes for PJAX support
diff --git a/devel/docs/UPGRADING-4.6 b/devel/docs/UPGRADING-4.6
new file mode 100644
index 0000000..32ef006
--- /dev/null
+++ b/devel/docs/UPGRADING-4.6
@@ -0,0 +1,71 @@
+=head1 UPGRADING FROM RT 4.4.0 and greater
+
+This documentation notes internals changes between the 4.4 and 4.6
+series that are primarily of interest to developers writing extensions
+or local customizations. It is not an exhaustive list.
+
+=over
+
+=item *
+
+RT 4.6 adds "PJAX" support (https://github.com/defunkt/jquery-pjax) which,
+in a nutshell, augments hyperlinks to instead issue an AJAX request for only
+the C<< <body> >> tag and replace the current page with that content. This
+improves performance as JavaScript and CSS do not necessarily need to be
+downloaded, parsed, compiled, and executed on each subsequent page load.
+
+PJAX support requires some development work to take advantage of. The
+primary change is due to PJAX page loads not following the normal browser
+page request lifecycle. This means that you must make the following two
+changes to how your JavaScript is run:
+
+=over 4
+
+=item *
+
+If some subset of HTML pages include a
+C<< <script src="/path/to/foo.js"> >>
+tag to load some page-specific JavaScript, such JS will not be loaded as
+part of a PJAX page load.
+
+For extensions, you should migrate to using
+C<< RT->AddJavaScript('foo.js'); >> to unconditionally load the JavaScript
+file on all pages.
+
+For local customizations, you may instead migrate to using the C<@JSFiles>
+option in F<RT_SiteConfig.pm>.
+
+Depending on the nature of that JavaScript file, you may need to make
+additional changes to it to handle being loaded in additional places.
+
+=item *
+
+If any of your custom standalone JavaScript files includes a "document
+ready" event registration, like any of the following ...
+
+ jQuery(function () { ... })
+ jQuery(document).ready( function () { ... } )
+ jQuery(document).on('ready', function () { ... } )
+ jQuery('img').ready( function () { ... } )
+
+... then they most likely must also listen for the C<pjax:success> event to
+register to run on PJAX page loads as well. The typical invocation looks
+like:
+
+ jQuery(document).on('ready pjax:success', function () { ... } )
+
+Note that this does I<not> apply to script tags in HTML templates like so:
+
+ <script type="text/javascript">
+ jQuery(function () {
+ ...
+ });
+ </script>
+
+Such invocations I<are> executed during PJAX page loads. This is in contrast
+to C<< <script src="..."> >> tags as mentioned earlier (which are not
+executed during PJAX page loads).
+
+=back
+
+=back
-----------------------------------------------------------------------
More information about the rt-commit
mailing list