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

Add persistence to online sandbox editor #323

Closed
wants to merge 17 commits into from

Conversation

camchenry
Copy link
Contributor

@camchenry camchenry commented Aug 20, 2022

What this PR accomplishes

Resolves #179.
Resolves #186.

This PR adds automatic persistence to the online code editor on the Peggy website, so that in-progress grammars will be persisted on the same computer across page loads. In addition, there is now a Copy link button to save the grammar to a URL so that it can be stored and sent to other people easily (convenient for sharing grammars on Discord, email, GitHub, etc.)

A live demo is available here: https://camchenry.github.io/peggy/online.html

Here is a shared grammar in a URL: https://camchenry.github.io/peggy/online.html#code/PTAEBUAsEsGdTqAhqA5gJyQWy09pZI8BTAE1ADN0B7LZUAVQCUAZAQgCgOBJAOwBdiqYvgBE0AUJGiOoUAF5QAbQAMAWgCcAXQDUoAN6h0xfgFd0vUAAc8sYn34AKQQA8nASgA0oAIwr3ANygAL4cQA

Why I took this approach

In general, I did not want to refactor the site (yet) in this PR, so I have opted for the smallest refactor that would achieve the goal of persistence.

ES modules (ESM)

To make reusing this code easier if/when we modernize the code more, I opted to use the standard import/export and ES module syntax. This requires the usage of <script type="module"> which is not supported by some browsers, however all modern browsers support this. In addition, it will make converting the code to TypeScript easier and should work well with a build tool like Webpack/Rollup in the future. To make it work with the Jest tests, I added Babel so that the import/export syntax would be transpiled.

Code persistence

Code is automatically saved to local storage whenever a change is made. There is also an option to generate a shareable link, which will take precedence over local storage, so that grammars can be shared no matter what. When sharing a link, the code is compressed so that larger grammars can still be shared via the URL. If there is nothing in storage or the URL, then the example grammar will be used instead, so that the editor is never initially empty.

},
"transformIgnorePatterns": [
"/test/cli/fixtures/bad",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jest was trying to parse this file using Babel which was failing, so we ignore it here

@@ -0,0 +1,3 @@
"use strict";

module.exports = { presets: ["@babel/preset-env"] };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handles transpiling the ESM syntax for the Jest tests

localStorage.setItem(codeStorageKey, code);
}

// The example grammar to use when there is no saved code in the URL or local storage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have UI for resetting back to this?

@@ -0,0 +1,80 @@
import {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add some tests to the puppeteer tests in the web-test directory as well.

@@ -8,14 +8,18 @@
"/vendor/codemirror/codemirror.css",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be vendored? https://unpkg.com/browse/[email protected]/libs/lz-string.min.js looks like it might work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could load it directly from the CDN, but then it wouldn't work in the tests anymore, because we reference the library directly there. I don't believe there is any way in Jest/Node to load from URLs directly, unfortunately. Another advantage of vendoring is that I changed the library to use standard import/export syntax rather than CommonJS.

(In the long run, we should just npm install this and bundle it, but I didn't want to do that in this PR.)

@@ -63,6 +64,7 @@
"@types/node": "^18.6.2",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"babel-jest": "^28.1.3",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can get away with not adding babel, I'd appreciate it. We're using tsc to do transforms everywhere else.

@camchenry camchenry closed this Jul 24, 2024
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

Successfully merging this pull request may close these issues.

Save grammar and test input in online version to localStorage Allow playground to save links
2 participants