about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2021-07-19 17:13:22 +0100
committerGuillaume Gomez <guillaume.gomez@huawei.com>2021-07-21 19:54:27 +0200
commit155b055478eead93f70aa51994e2c56da948cc40 (patch)
treeefd310fb5860c34fa34ef0d1a6dc5107e84b59a0
parent05f2326c0570fdd64f53532a089bbbc361d190e6 (diff)
downloadrust-155b055478eead93f70aa51994e2c56da948cc40.tar.gz
rust-155b055478eead93f70aa51994e2c56da948cc40.zip
rustdoc: Restore --default-theme, etc, by restoring varname escaping
In #86157

    cd0f93193c84ddc6698f9b65909da71c084dcb74
    Use Tera templates for rustdoc.

dropped the following transformation from the keys of the default
settings element's `data-` attribute names:

    .map(|(k, v)| format!(r#" data-{}="{}""#, k.replace('-', "_"), Escape(v)))

The `Escape` part is indeed no longer needed, because Tera does that
for us.  But the massaging of `-` to `_` is needed, for the (bizarre)
reasons explained in the new comments.

I have tested that the default theme function works again for me.  I
have also verified that passing

    --default-theme="zork&"

escapes the value in the HTML.

Closes #87263.

CC: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
-rw-r--r--src/librustdoc/config.rs24
-rw-r--r--src/librustdoc/html/static/js/storage.js2
2 files changed, 25 insertions, 1 deletions
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index e5525424640..cae68447815 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -459,7 +459,29 @@ impl Options {
                 })
                 .collect(),
         ];
-        let default_settings = default_settings.into_iter().flatten().collect();
+        let default_settings = default_settings.into_iter().flatten()
+            .map(
+                // The keys here become part of `data-` attribute names in the generated HTML.  The
+                // browser does a strange mapping when converting them into attributes on the
+                // `dataset` property on the DOM HTML Node:
+                //   https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
+                //
+                // The original key values we have are the same as the DOM storage API keys and the
+                // command line options, so contain `-`.  Our Javascript needs to be able to look
+                // these values up both in `dataset` and in the storage API, so it needs to be able
+                // to convert the names back and forth.  Despite doing this kebab-case to
+                // StudlyCaps transformation automatically, the JS DOM API does not provide a
+                // mechanism for doing the just transformation on a string.  So we want to avoid
+                // the StudlyCaps representation in the `dataset` property.
+                //
+                // We solve this by replacing all the `-`s with `_`s.  We do that here, when we
+                // generate the `data-` attributes, and in the JS, when we look them up.  (See
+                // `getSettingValue` in `storage.js.`) Converting `-` to `_` is simple in JS.
+                //
+                // The values will be HTML-escaped by the default Tera escaping.
+                |(k, v)| (k.replace('-', "_"), v)
+            )
+            .collect();
 
         let test_args = matches.opt_strs("test-args");
         let test_args: Vec<String> =
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 2eaa81a97d8..78ed17e6899 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -22,6 +22,8 @@ function getSettingValue(settingName) {
         return current;
     }
     if (settingsDataset !== null) {
+        // See the comment for `default_settings.into_iter()` etc. in
+        // `Options::from_matches` in `librustdoc/config.rs`.
         var def = settingsDataset[settingName.replace(/-/g,'_')];
         if (def !== undefined) {
             return def;