FEATURE: Add support for Hotwire Turbo Drive (#498)

FEATURE: Add support for Hotwire Turbo Drive (#498)

We have a new config option enable_hotwire_turbo_drive_support to enable support for Hotwire Turbo Drive. If your application uses Hotwire Turbo Drive, set that config option to true. See the README for more details.

diff --git a/README.md b/README.md
index 8972361..1924133 100644
--- a/README.md
+++ b/README.md
@@ -413,6 +413,7 @@ snapshots_transport_auth_key|`nil`|`POST` requests made by the snapshots transpo
 snapshots_redact_sql_queries|`true`|When this is true, SQL queries will be redacted from sampling snapshots, but the backtrace and duration of each SQL query will be saved with the snapshot to keep debugging performance issues possible.
 snapshots_transport_gzip_requests|`false`|Make the snapshots transporter gzip the requests it makes to `snapshots_transport_destination_url`.
 content_security_policy_nonce|Rails: Current nonce<br>Rack: nil|Set the content security policy nonce to use when inserting MiniProfiler's script block.
+enable_hotwire_turbo_drive_support| `false` | Enable support for Hotwire TurboDrive page transitions.
 
 ### Using MiniProfiler with `Rack::Deflate` middleware
 
diff --git a/lib/html/includes.js b/lib/html/includes.js
index f704b43..805c2bb 100644
--- a/lib/html/includes.js
+++ b/lib/html/includes.js
@@ -495,6 +495,19 @@ var _MiniProfiler = (function() {
     }, 3000);
   };
 
+  var onTurboBeforeVisit = function onTurboBeforeVisit(e) {
+    if(!e.defaultPrevented) {
+      window.MiniProfilerContainer = document.querySelector('body > .profiler-results')
+      window.MiniProfiler.pageTransition()
+    }
+  }
+
+  var onTurboLoad = function onTurboLoad(e) {
+    if(window.MiniProfilerContainer) {
+      document.body.appendChild(window.MiniProfilerContainer)
+    }
+  }
+
   var onClickEvents = function onClickEvents(e) {
     // this happens on every keystroke, and :visible is crazy expensive in IE <9
     // and in this case, the display:none check is sufficient.
@@ -652,6 +665,11 @@ var _MiniProfiler = (function() {
         turbolinksSkipResultsFetch
       );
     }
+
+    if (options.hotwireTurboDriveSupport) {
+      document.addEventListener("turbo:before-visit", onTurboBeforeVisit)
+      document.addEventListener("turbo:load", onTurboLoad)
+    }
   };
 
   var unbindDocumentEvents = function unbindDocumentEvents() {
@@ -664,6 +682,8 @@ var _MiniProfiler = (function() {
       "turbolinks:request-start",
       turbolinksSkipResultsFetch
     );
+    document.removeEventListener("turbo:before-visit", onTurboBeforeVisit);
+    document.removeEventListener("turbo:load", onTurboLoad);
   };
 
   var initFullView = function initFullView() {
@@ -1033,6 +1053,8 @@ var _MiniProfiler = (function() {
           .getAttribute("data-hidden-custom-fields")
           .toLowerCase()
           .split(",");
+        var hotwireTurboDriveSupport = script
+          .getAttribute('data-turbo-permanent') === "true";
         return {
           ids: ids,
           path: path,
@@ -1051,7 +1073,8 @@ var _MiniProfiler = (function() {
           collapseResults: collapseResults,
           htmlContainer: htmlContainer,
           cssUrl: cssUrl,
-          hiddenCustomFields: hiddenCustomFields
+          hiddenCustomFields: hiddenCustomFields,
+          hotwireTurboDriveSupport: hotwireTurboDriveSupport
         };
       })();
 
diff --git a/lib/html/profile_handler.js b/lib/html/profile_handler.js
index 1fa51d4..fa183ec 100644
--- a/lib/html/profile_handler.js
+++ b/lib/html/profile_handler.js
@@ -1 +1 @@
-<script async nonce="{cspNonce}" type="text/javascript" id="mini-profiler" src="{url}" data-css-url="{cssUrl}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-horizontal-position="{horizontalPosition}" data-vertical-position="{verticalPosition}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-total-sql-count="{showTotalSqlCount}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}" data-collapse-results="{collapseResults}" data-html-container="{htmlContainer}" data-hidden-custom-fields="{hiddenCustomFields}"></script>
+<script async nonce="{cspNonce}" type="text/javascript" id="mini-profiler" src="{url}" data-css-url="{cssUrl}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-horizontal-position="{horizontalPosition}" data-vertical-position="{verticalPosition}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-total-sql-count="{showTotalSqlCount}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}" data-collapse-results="{collapseResults}" data-html-container="{htmlContainer}" data-hidden-custom-fields="{hiddenCustomFields}" data-turbo-permanent="{hotwireTurboDriveSupport}"></script>
diff --git a/lib/mini_profiler/asset_version.rb b/lib/mini_profiler/asset_version.rb
index 1c4c346..9d64ccd 100644
--- a/lib/mini_profiler/asset_version.rb
+++ b/lib/mini_profiler/asset_version.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 module Rack
   class MiniProfiler
-    ASSET_VERSION = '40756d3425f8c8e3f901fb5e850a065a'
+    ASSET_VERSION = 'ec6d5541ecbc11a48798626c16a61342'
   end
 end
diff --git a/lib/mini_profiler/config.rb b/lib/mini_profiler/config.rb
index 417b22b..ce773ef 100644
--- a/lib/mini_profiler/config.rb
+++ b/lib/mini_profiler/config.rb
@@ -57,6 +57,7 @@ module Rack
           @snapshots_transport_auth_key = nil
           @snapshots_redact_sql_queries = true
           @snapshots_transport_gzip_requests = false
+          @enable_hotwire_turbo_drive_support = false
 
           self
         }
@@ -69,7 +70,7 @@ module Rack
         :skip_schema_queries, :storage, :storage_failure, :storage_instance,
         :storage_options, :user_provider, :enable_advanced_debugging_tools,
         :skip_sql_param_names, :suppress_encoding, :max_sql_param_length,
-        :content_security_policy_nonce
+        :content_security_policy_nonce, :enable_hotwire_turbo_drive_support
 
       # ui accessors
       attr_accessor :collapse_results, :max_traces_to_show, :position,
diff --git a/lib/mini_profiler/profiler.rb b/lib/mini_profiler/profiler.rb
index efd5248..3485981 100644
--- a/lib/mini_profiler/profiler.rb
+++ b/lib/mini_profiler/profiler.rb
@@ -751,6 +751,7 @@ Append the following to your query string:
        htmlContainer: @config.html_container,
        hiddenCustomFields: @config.snapshot_hidden_custom_fields.join(','),
        cspNonce: content_security_policy_nonce,
+       hotwireTurboDriveSupport: @config.enable_hotwire_turbo_drive_support,
       }
 
       if current && current.page_struct
diff --git a/spec/integration/mini_profiler_spec.rb b/spec/integration/mini_profiler_spec.rb
index b3b7ed4..98645e5 100644
--- a/spec/integration/mini_profiler_spec.rb
+++ b/spec/integration/mini_profiler_spec.rb
@@ -257,6 +257,17 @@ describe Rack::MiniProfiler do
       expect(last_response.status).to equal(200)
     end
 
+    describe 'with hotwire turbo drive support enabled' do
+      before do
+        Rack::MiniProfiler.config.enable_hotwire_turbo_drive_support = true
+      end
+
+      it 'should define data-turbo-permanent as true' do
+        get '/html'
+        expect(last_response.body).to include('data-turbo-permanent="true"')
+      end
+    end
+
     describe 'with caching re-enabled' do
       before :each do
         Rack::MiniProfiler.config.disable_caching = false

GitHub sha: 1f8b391909ffe0b07608026319b236bd83609722

This commit appears in #498 which was merged by OsamaSayegh.