Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline scripts and styles #3

Closed
imbolc opened this issue Oct 30, 2024 · 8 comments
Closed

Inline scripts and styles #3

imbolc opened this issue Oct 30, 2024 · 8 comments

Comments

@imbolc
Copy link
Contributor

imbolc commented Oct 30, 2024

Could we find a way to write inline scripts and styles without wrapping them in quotes?

Context

People from the Hypermedia movement make libraries like these, enabling LOB without any builders (like Webpack):

Using them involves many inline scripts and styles. It would be great to enable IDE highlighting / autocompletion for them and, ideally, compile time lints.

The issue's history from Reddit

Q: Do inline scripts and styles need to be wrapped into quotes and PreEscaped? That's the major issue I'm having with Maud. It's really nice to think of components, having html alongside the rest of the code, but being unable to setup scripts / styles lints in the editor makes me often retreat to Askama.

Why string literals have to be wrapped in quotes btw? As I remember Maud needs it because it uses macro_rules, but you seem to use proc macros. Isn't there a way to avoid quoting?

A: Currently, you do need to use PreEscaped with quotes if you want to put content inside a <style> or <script> tag, however as you mentioned, I do care for DX and having good code locality promotes that, so I'll see exactly how I will go about this.

As for why this is required, the syn parser used in proc macros has limitations when it comes to 'any unquoted tokens', as its designed specifically to parse Rust tokens, it doesn't have the ability to collect detailed information about white space, newlines, line breaks, etc., as those things are not really relevant for Rust code. This means you have to join spans (a span is a sort of cursor pointing to a specific location in the source code), from the start of the text to the end of the text, although this feature is only available in nightly.

<!--    v span1        v span2 -->`
<div>   Hello,    World!  </div>

Joining the span1 and span2 would give us the text node

Hello,    World
@imbolc
Copy link
Contributor Author

imbolc commented Oct 30, 2024

I'm not sure the issue is related to all text nodes, as having quoted text could be considered a feature since it ensures explicit space control. Without it the resulting HTML would be polluted with spaces / tabs / newlines.

@imbolc
Copy link
Contributor Author

imbolc commented Oct 30, 2024

Also, can't we compile-check the content of tags? With something like Lightning CSS and OXC?

@jonahlund
Copy link
Owner

Could we find a way to write inline scripts and styles without wrapping them in quotes?

This is already kind of possible to do using the stringify! macro:

use vy::PreEscaped;

fn main() {
    let page = vy::render! {
        <script>{PreEscaped(stringify!(
            console.log("Hello, world!");
        ))}</script>
    };

    println!("{}", page);
}

We could even extract this into a helper macro

macro_rules! js {
    ($($t:tt)*) => {
        vy::PreEscaped(stringify!($($t)*))
    };
}

fn main() {
    let page = vy::render! {
        <script>{js!(
            console.log("Hello, world!");
        )}</script>
    };

    println!("{}", page);
}

You could extend this idea to a simple proc macro that proxies the input tokens through a js validator and minifier.

I'm not sure the issue is related to all text nodes, as having quoted text could be considered a feature since it ensures explicit space control. Without it the resulting HTML would be polluted with spaces / tabs / newlines.

This is a good reasoning I've made as well, explicit quoting makes it crystal clear what text content you are actually producing, as opposed to writing "typical" HTML where the exact content of your text may be ambiguous at times. Basically its a case where its either: have the compiler make assumptions about what text content you may want, or have all text nodes be quoted (no assumptions or ambiguity).

@imbolc
Copy link
Contributor Author

imbolc commented Oct 31, 2024

I haven't thought about stringify, thank you!

jonahlund added a commit that referenced this issue Oct 31, 2024
Inline script and style tags macros, closes #3
@imbolc
Copy link
Contributor Author

imbolc commented Nov 5, 2024

It's not that simple unfortunately, the style! macro breaks on em:

 margin-top: 2em;     ■ Syntax Error: Missing digits after the exponent symbol

@jonahlund
Copy link
Owner

It's not that simple unfortunately, the style! macro breaks on em:

 margin-top: 2em;     ■ Syntax Error: Missing digits after the exponent symbol

Okay so I haven't looked into this very thoroughly, but this does seem to be a bug with the stringify! macro or the related token parsing components. As per the docs of std::stringify!:

Stringifies its arguments.

This macro will yield an expression of type &'static str which is the stringification of all the tokens passed to the macro. No restrictions are placed on the syntax of the macro invocation itself.

With emphasis on "No restrictions are placed on the syntax of the macro invocation itself.", the fact that practically any other "non valid" input works, tells me that this is a bug.

@jonahlund
Copy link
Owner

More specifically, this appears to occur when using any digit followed by an e, like 4e or 6eeeeee or 1em or 1ewoiujk

@jonahlund
Copy link
Owner

In fact, this is a known issue rust-lang/rust#111615

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants