Skip to content
Draft
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
12 changes: 11 additions & 1 deletion apps/repl/app/components/verify-danger.gts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const ALLOWED = Object.freeze([]);
const MARKUP_FORMATS = new Set([
'js',
'gjs',
'gjs|codegen',
'gts',
'vue',
'jsx',
Expand All @@ -27,7 +28,16 @@ const MARKUP_FORMATS = new Set([
'hbs',
'hbs|ember',
]);
const SCRIPT_FORMATS = new Set(['js', 'gjs', 'gts', 'vue', 'jsx', 'jsx|react', 'svelte']);
const SCRIPT_FORMATS = new Set([
'js',
'gjs',
'gjs|codegen',
'gts',
'vue',
'jsx',
'jsx|react',
'svelte',
]);

function couldHaveMarkup(format: Format) {
return MARKUP_FORMATS.has(format);
Expand Down
7 changes: 7 additions & 0 deletions apps/repl/app/languages.gts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ const languages = {
</span>
</template>,
},
'gjs|codegen': {
name: 'Glimmer JS (codegen, experimental)',
ext: 'gjs',
icon: <template>
<span>{{{FileGlimmer}}}</span>
</template>,
},
// an alias
get hbs() {
return languages['hbs|ember'];
Expand Down
7 changes: 6 additions & 1 deletion apps/repl/app/snippets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ export const ALL = [
path: '/samples/nested-ember-routing-demo.gjs',
},
{ format: 'gts', label: 'Ember GTS', path: '/samples/gts-demo.gts' },
{
format: 'gjs|codegen',
label: 'Ember GJS (codegen, experimental)',
path: '/samples/gjs-codegen-demo.gjs',
},
{ format: 'svelte', label: 'Svelte', path: '/samples/svelte-demo.svelte' },
{ format: 'js', label: 'Vanilla JS', path: '/samples/js-demo.js' },
// Yaml
Expand Down Expand Up @@ -195,7 +200,7 @@ export async function getFromLabel(label: string): Promise<string> {
}

export function defaultSnippetForFormat(format: string) {
if (format === 'gjs') {
if (format === 'gjs' || format === 'gjs|codegen') {
return DEFAULT_GJS;
}

Expand Down
1 change: 1 addition & 0 deletions apps/repl/app/templates/edit/format-menu.gts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export class FormatMenu extends Component<{ Element: HTMLButtonElement }> {
<Button @format="js" />
<Button @format="gjs" />
<Button @format="gts" />
<Button @format="gjs|codegen" />
<Button @format="hbs" />
<Button @format="svelte" />
<Button @format="vue" />
Expand Down
4 changes: 4 additions & 0 deletions apps/repl/app/templates/edit/layout/controls/formatting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ const FORMATTERS: Record<FormatQP, { parser: string; plugins: PluginName[] } | u
parser: 'ember-template-tag',
plugins: ['babel', 'estree', 'glimmer', 'ember-template-tag'],
},
'gjs|codegen': {
parser: 'ember-template-tag',
plugins: ['babel', 'estree', 'glimmer', 'ember-template-tag'],
},
hbs: { parser: 'glimmer', plugins: ['glimmer'] },
'hbs|ember': { parser: 'glimmer', plugins: ['glimmer'] },
md: { parser: 'markdown', plugins: ['markdown'] },
Expand Down
93 changes: 93 additions & 0 deletions apps/repl/public/samples/gjs-codegen-demo.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// EXPERIMENTAL: this format compiles <template>s directly to DOM operations
// (no wire format, no VM). Strict mode only.
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { trackedArray } from '@ember/reactive/collections';
import { on } from '@ember/modifier';
import { fn } from '@ember/helper';
// A component compiled for the VM (from an addon): rendered by the VM,
// with the attributes and block from this compiled template.
import { ExternalLink } from 'ember-primitives';

const shout = (text) => `${text.toUpperCase()}!`;

const Card = <template>
<section class="card" ...attributes>
<h2>{{yield to="title"}}</h2>
{{#if (has-block "body")}}
{{yield to="body"}}
{{else}}
<p>(no body)</p>
{{/if}}
</section>
</template>;

class Counter extends Component {
@tracked count = 0;

increment = (by) => (this.count += by);

<template>
<button type="button" {{on "click" (fn this.increment @step)}}>
+{{@step}}
</button>
<output>{{this.count}}</output>
{{#if (eq this.count 0)}}
<span>Click it!</span>
{{else if (gt this.count 10)}}
<span>{{shout "that's a lot"}}</span>
{{/if}}
</template>
}

class Todos extends Component {
todos = trackedArray([
{ id: 1, title: 'Compile templates to JS' },
{ id: 2, title: 'Delete the VM?' },
{ id: 3, title: 'Measure it' },
]);

reverse = () => this.todos.reverse();
remove = (todo) => this.todos.splice(this.todos.indexOf(todo), 1);

<template>
<button type="button" {{on "click" this.reverse}}>Reverse</button>
<ul>
{{#each this.todos key="id" as |todo i|}}
<li>
{{i}}: {{todo.title}}
<button type="button" {{on "click" (fn this.remove todo)}}>×</button>
</li>
{{else}}
<li>All done</li>
{{/each}}
</ul>
</template>
}

<template>
<Card class="counter">
<:title>Counter</:title>
<:body><Counter @step={{2}} /></:body>
</Card>

<Card>
<:title>Todos</:title>
<:body><Todos /></:body>
</Card>

<Card><:title>Empty</:title></Card>

<Card>
<:title>From an addon</:title>
<:body>
<ExternalLink href="https://github.com/emberjs/ember.js/pull/21649" class="pr-link">
The ember.js PR
</ExternalLink>
</:body>
</Card>

<style>
.card { border: 1px solid #ccc; border-radius: 0.5rem; padding: 0.5rem 1rem; margin: 1rem 0; }
</style>
</template>
9 changes: 9 additions & 0 deletions packages/ember-repl/src/services/known-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ const frameworkModules = {
'@glimmer/tracking': () => import('@glimmer/tracking'),
'@glimmer/tracking/primitives/cache': () =>
import('@glimmer/tracking/primitives/cache'),
/**
* EXPERIMENTAL: the runtime for the `gjs|codegen` format, where templates
* are compiled directly to DOM operations (no wire format, no VM).
* Vendored from a branch of ember.js, see the file's header.
*/
// @ts-ignore
'@glimmer/dom': () => import('../vendor/glimmer-dom/index.js'),
// @ts-ignore
'@glimmer/dom/vm': () => import('../vendor/glimmer-dom/vm.js'),
};

const coreLibraries = {
Expand Down
Loading
Loading