Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions specs/01-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,13 @@ development) from one origin; there is no separate host app.
source `icons/og.webp`): absolute, as crawlers need, and versioned in its name because
`/web/` is served as immutable — a new image gets a new name. The legal pages carry the
same tags with their own `og:url` and canonical link.
- **No Grammarly**: the apps check spelling themselves (`wonky_spellcheck`), and Grammarly's
overlays on Flutter's hidden text fields interfere with editing. Each app's `web/index.html`
opts out: `data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false"` on
`<html>` and `<body>`, and an inline script puts the same attributes on every `input`,
`textarea` and `contenteditable` that Flutter adds (MutationObserver) and on the focused field
(capturing `focusin`, which runs before the extension's own handler). A new app's
`index.html` copies the attributes and the script.
- **Development**: the apps are declared in `serverpod: flutter_apps:` in the server pubspec
(aliases `drive`, `write`, `sheets`, `slides`; `path: ../wonky_<app>`,
`target: lib/driver.dart`, fixed `web-port`s so the origins are stable for
Expand Down
30 changes: 28 additions & 2 deletions wonky_drive/web/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false">
<head>
<!--
If you are serving your web app in a path other than the root, change the
Expand Down Expand Up @@ -53,7 +53,33 @@
<title>Wonky Drive</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<body data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false">
<script>
// Keep Grammarly and similar extensions out (specs/01 §2.4): the apps
// have their own spelling, and the extension's overlays fight Flutter's
// hidden text fields. <html> and <body> opt the page out; Flutter creates
// the fields on demand, so each one is tagged when added and on focus.
(function () {
var fields = 'input, textarea, [contenteditable]';
function tag(el) {
el.setAttribute('data-gramm', 'false');
el.setAttribute('data-gramm_editor', 'false');
el.setAttribute('data-enable-grammarly', 'false');
}
new MutationObserver(function (records) {
records.forEach(function (r) {
r.addedNodes.forEach(function (n) {
if (n.nodeType !== 1) return;
if (n.matches(fields)) tag(n);
n.querySelectorAll(fields).forEach(tag);
});
});
}).observe(document.body, { childList: true, subtree: true });
window.addEventListener('focusin', function (e) {
if (e.target.matches && e.target.matches(fields)) tag(e.target);
}, true);
})();
</script>
<!--
You can customize the "flutter_bootstrap.js" script.
This is useful to provide a custom configuration to the Flutter loader
Expand Down
30 changes: 28 additions & 2 deletions wonky_sheets/web/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false">
<head>
<!--
If you are serving your web app in a path other than the root, change the
Expand Down Expand Up @@ -52,7 +52,33 @@
<title>Wonky Sheets</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<body data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false">
<script>
// Keep Grammarly and similar extensions out (specs/01 §2.4): the apps
// have their own spelling, and the extension's overlays fight Flutter's
// hidden text fields. <html> and <body> opt the page out; Flutter creates
// the fields on demand, so each one is tagged when added and on focus.
(function () {
var fields = 'input, textarea, [contenteditable]';
function tag(el) {
el.setAttribute('data-gramm', 'false');
el.setAttribute('data-gramm_editor', 'false');
el.setAttribute('data-enable-grammarly', 'false');
}
new MutationObserver(function (records) {
records.forEach(function (r) {
r.addedNodes.forEach(function (n) {
if (n.nodeType !== 1) return;
if (n.matches(fields)) tag(n);
n.querySelectorAll(fields).forEach(tag);
});
});
}).observe(document.body, { childList: true, subtree: true });
window.addEventListener('focusin', function (e) {
if (e.target.matches && e.target.matches(fields)) tag(e.target);
}, true);
})();
</script>
<!--
You can customize the "flutter_bootstrap.js" script.
This is useful to provide a custom configuration to the Flutter loader
Expand Down
30 changes: 28 additions & 2 deletions wonky_slides/web/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false">
<head>
<!--
If you are serving your web app in a path other than the root, change the
Expand Down Expand Up @@ -52,7 +52,33 @@
<title>Wonky Slides</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<body data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false">
<script>
// Keep Grammarly and similar extensions out (specs/01 §2.4): the apps
// have their own spelling, and the extension's overlays fight Flutter's
// hidden text fields. <html> and <body> opt the page out; Flutter creates
// the fields on demand, so each one is tagged when added and on focus.
(function () {
var fields = 'input, textarea, [contenteditable]';
function tag(el) {
el.setAttribute('data-gramm', 'false');
el.setAttribute('data-gramm_editor', 'false');
el.setAttribute('data-enable-grammarly', 'false');
}
new MutationObserver(function (records) {
records.forEach(function (r) {
r.addedNodes.forEach(function (n) {
if (n.nodeType !== 1) return;
if (n.matches(fields)) tag(n);
n.querySelectorAll(fields).forEach(tag);
});
});
}).observe(document.body, { childList: true, subtree: true });
window.addEventListener('focusin', function (e) {
if (e.target.matches && e.target.matches(fields)) tag(e.target);
}, true);
})();
</script>
<!--
You can customize the "flutter_bootstrap.js" script.
This is useful to provide a custom configuration to the Flutter loader
Expand Down
30 changes: 28 additions & 2 deletions wonky_write/web/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false">
<head>
<!--
If you are serving your web app in a path other than the root, change the
Expand Down Expand Up @@ -68,7 +68,33 @@
@media (prefers-reduced-motion: reduce) { #wonky-splash .tile { animation: none; } }
</style>
</head>
<body>
<body data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false">
<script>
// Keep Grammarly and similar extensions out (specs/01 §2.4): the apps
// have their own spelling, and the extension's overlays fight Flutter's
// hidden text fields. <html> and <body> opt the page out; Flutter creates
// the fields on demand, so each one is tagged when added and on focus.
(function () {
var fields = 'input, textarea, [contenteditable]';
function tag(el) {
el.setAttribute('data-gramm', 'false');
el.setAttribute('data-gramm_editor', 'false');
el.setAttribute('data-enable-grammarly', 'false');
}
new MutationObserver(function (records) {
records.forEach(function (r) {
r.addedNodes.forEach(function (n) {
if (n.nodeType !== 1) return;
if (n.matches(fields)) tag(n);
n.querySelectorAll(fields).forEach(tag);
});
});
}).observe(document.body, { childList: true, subtree: true });
window.addEventListener('focusin', function (e) {
if (e.target.matches && e.target.matches(fields)) tag(e.target);
}, true);
})();
</script>
<div id="wonky-splash" aria-label="Loading Wonky Write">
<img class="tile" src="icons/Icon-192.png" alt="" aria-hidden="true">
<div>Wonky Write</div>
Expand Down
Loading