Skip to content

Commit

Permalink
Adds lint rules for data-astro-reload and data-astro-rerun on scr…
Browse files Browse the repository at this point in the history
…ipt tags (#965)

* Adds transition:reload directive

* add warnings and test

* Update internal/printer/printer.go

Co-authored-by: Happydev <[email protected]>

* adds review suggestions and additional warning

* Update internal/printer/printer.go

* Update internal/printer/printer.go

* adds review suggestions

* warn on unsupported data-astro-rerun attribute on scripts

* reactivate reload checks and tests

* update changeset

* with suggestios from review

* fixes tests after merge

---------

Co-authored-by: Happydev <[email protected]>
  • Loading branch information
martrapp and MoustaphaDev authored Mar 8, 2024
1 parent 4eaa5a9 commit d587ca6
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/orange-knives-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/compiler': patch
---

Adds warnings indicating that the `data-astro-rerun` attribute can not be used on an external module `<script>` and that `data-astro-reload` is only supported on `<a>`, `<area>` and `<form>` elements.
1 change: 1 addition & 0 deletions internal/loc/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
WARNING_CANNOT_DEFINE_VARS DiagnosticCode = 2007
WARNING_INVALID_SPREAD DiagnosticCode = 2008
WARNING_UNEXPECTED_CHARACTER DiagnosticCode = 2009
WARNING_CANNOT_RERUN DiagnosticCode = 2010
INFO DiagnosticCode = 3000
HINT DiagnosticCode = 4000
)
52 changes: 52 additions & 0 deletions internal/transform/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
const TRANSITION_ANIMATE = "transition:animate"
const TRANSITION_NAME = "transition:name"
const TRANSITION_PERSIST = "transition:persist"
const DATA_ASTRO_RELOAD = "data-astro-reload"
const TRANSITION_PERSIST_PROPS = "transition:persist-props"

type TransformOptions struct {
Expand All @@ -42,6 +43,8 @@ func Transform(doc *astro.Node, opts TransformOptions, h *handler.Handler) *astr
i := 0
walk(doc, func(n *astro.Node) {
i++
WarnAboutRerunOnExternalESMs(n, h)
WarnAboutMisplacedReload(n, h)
HintAboutImplicitInlineDirective(n, h)
ExtractScript(doc, n, &opts, h)
AddComponentProps(doc, n, &opts)
Expand Down Expand Up @@ -354,6 +357,55 @@ func collapseWhitespace(doc *astro.Node) {
})
}

func WarnAboutMisplacedReload(n *astro.Node, h *handler.Handler) {
if HasAttr(n, DATA_ASTRO_RELOAD) {
attr := &n.Attr[AttrIndex(n, DATA_ASTRO_RELOAD)]

/*
* When set on <a>, <form> or <area>,
* the data-astro-reload attribute replaces view transitions between pages with a full page loads.
* The data-astro-reload attribute is not supported for other elements. It does not accept a value.
*/

if n.Type != astro.ElementNode || n.Data != "a" && n.Data != "area" && n.Data != "form" {
h.AppendWarning(&loc.ErrorWithRange{
Code: loc.WARNING,
Text: "The data-astro-reload attribute is only supported on <a>, <form> and <area> elements.",
Range: loc.Range{Loc: attr.KeyLoc, Len: len(attr.Key)},
})
}
if attr.Val != "" {
h.AppendWarning(&loc.ErrorWithRange{
Code: loc.WARNING_UNSUPPORTED_EXPRESSION,
Text: "The data-astro-reload attribute does not accept a value",
Range: loc.Range{Loc: attr.ValLoc, Len: len(attr.Val)},
})
return
}
}
}

func WarnAboutRerunOnExternalESMs(n *astro.Node, h *handler.Handler) {
if n.Data == "script" && HasAttr(n, "src") && HasAttr(n, "type") && HasAttr(n, "data-astro-rerun") {

/*
* The browser caches external ECMAScript Modules. Even if such a script is included several times on a page,
* it will only run once. This means that the data-astro-rerun attribute will not have any effect.
*/
src := &n.Attr[AttrIndex(n, "src")]
typ := &n.Attr[AttrIndex(n, "type")]
rerun := &n.Attr[AttrIndex(n, "data-astro-rerun")]
if typ.Val == "module" && src.Val != "" {
h.AppendWarning(&loc.ErrorWithRange{
Code: loc.WARNING_CANNOT_RERUN,
Text: "The data-astro-rerun attribute is not supported on an external module <script>",
Hint: "Two out of three is OK: type=\"module\", src=\"...\", or data-astro-rerun",
Range: loc.Range{Loc: rerun.KeyLoc, Len: len(rerun.Key)},
})
}
}
}

func ExtractScript(doc *astro.Node, n *astro.Node, opts *TransformOptions, h *handler.Handler) {
if n.Type == astro.ElementNode && n.DataAtom == a.Script {
if HasSetDirective(n) || HasInlineDirective(n) {
Expand Down
23 changes: 23 additions & 0 deletions packages/compiler/test/transition/data-astro.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { test } from 'uvu';
import * as assert from 'uvu/assert';
import { transform } from '@astrojs/compiler';

const FIXTURE = `
<div data-astro-reload>
<a href="/" data-astro-reload>/</a>
<form data-astro-reload="x">.</form>
<area data-astro-reload/>
<svg xmlns="http://www.w3.org/2000/svg"><a data-astro-reload>.</a></svg>
<script is:inline data-astro-rerun src="some.js" type="module" />
<script is:inline data-astro-rerun>"Bar"</script>
</div>`;

test('Issues warnings for data-astro-* attributes', async () => {
const result = await transform(FIXTURE);
assert.equal(result.diagnostics.length, 3);
assert.equal(result.diagnostics[0].code, 2000);
assert.equal(result.diagnostics[1].code, 2005);
assert.equal(result.diagnostics[2].code, 2010);
});

test.run();

0 comments on commit d587ca6

Please sign in to comment.