merge master

pull/9046/head
Ben McCann 3 years ago
commit fd8ebd8940

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: css sourcemap generation with unicode filenames

@ -46,7 +46,7 @@ For all the patches and performance updates from this month, check out the [Svel
**Learning Resources**
_Featuring Svelte Contributors and Ambassadors_
- [Exploring Svelte 4 w/ Kevin AK: Performance, Compatibility, & Web Component Support | Modern Web Pod](https://www.youtube.com/watch?v=YOL0HGGVib4) by This Dot Media
- [Svelte Sirens Stream Design Systems: Lessons Learned](https://www.youtube.com/live/YHZaiIGSqsE?feature=share) featuring Eric Liu creator of Carbon Components Svelte and Svelde the docgen library
- [Svelte Sirens Stream Design Systems: Lessons Learned](https://www.youtube.com/live/YHZaiIGSqsE?feature=share) featuring Eric Liu, creator of Carbon Components Svelte and the `sveld` docgen library
- This Week in Svelte:
- [2023 June 30](https://www.youtube.com/watch?v=sDz4_BLoYQ4) - Svelte 4.0.1, SK 1.21, lists, screen readers, loading
- [2023 July 7](https://www.youtube.com/watch?v=0tq1ph4DDFA) - Svelte 4.0.5, Kit 1.22.1, Svelte 5, local storage and markdown

@ -56,8 +56,9 @@ All other attributes are included unless their value is [nullish](https://develo
An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed:
<!-- prettier-ignore -->
```svelte
<button disabled={number !== 42}>...</button>
<button disabled="{number !== 42}">...</button>
```
When the attribute name and value match (`name={name}`), they can be replaced with `{name}`.

@ -140,6 +140,26 @@ declare namespace svelteHTML {
Then make sure that `d.ts` file is referenced in your `tsconfig.json`. If it reads something like `"include": ["src/**/*"]` and your `d.ts` file is inside `src`, it should work. You may need to reload for the changes to take effect.
Since Svelte version 4.2 / `svelte-check` version 3.5 / VS Code extension version 107.10.0 you can also declare the typings by augmenting the `svelte/elements` module like this:
```ts
/// file: additional-svelte-typings.d.ts
import { HTMLButtonAttributes } from 'svelte/elements'
declare module 'svelte/elements' {
export interface SvelteHTMLElements {
'custom-button': HTMLButtonAttributes;
}
// allows for more granular control over what element to add the typings to
export interface HTMLButtonAttributes {
'veryexperimentalattribute'?: string;
}
}
export {}; // ensure this is not an ambient module, else types will be overridden instead of augmented
```
## Experimental advanced typings
A few features are missing from taking full advantage of TypeScript in more advanced use cases like typing that a component implements a certain interface, explicitly typing slots, or using generics. These things are possible using experimental advanced type capabilities. See [this RFC](https://github.com/dummdidumm/rfcs/blob/ts-typedefs-within-svelte-components/text/ts-typing-props-slots-events.md) for more information on how to make use of them.

@ -69,11 +69,12 @@ const watcher = watch([
async generateBundle(_, bundle) {
const result = bundle['entry-server.js'];
const mod = (0, eval)(result.code);
const { html } = mod.render();
const { html, head } = mod.render();
writeFileSync(
'dist/index.html',
readFileSync('src/template.html', 'utf-8')
.replace('<!--app-head-->', head)
.replace('<!--app-html-->', html)
.replace('<!--app-title-->', svelte.VERSION)
);

@ -1,5 +1,11 @@
# svelte
## 4.2.0
### Minor Changes
- feat: move `svelteHTML` from language-tools into core to load the correct `svelte/element` types ([#9070](https://github.com/sveltejs/svelte/pull/9070))
## 4.1.2
### Patch Changes

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "4.1.2",
"version": "4.2.0",
"description": "Cybernetically enhanced web apps",
"type": "module",
"module": "src/runtime/index.js",
@ -19,6 +19,7 @@
"motion.d.ts",
"action.d.ts",
"elements.d.ts",
"svelte-html.d.ts",
"README.md"
],
"exports": {
@ -129,7 +130,7 @@
"dts-buddy": "^0.1.7",
"esbuild": "^0.18.11",
"happy-dom": "^9.20.3",
"jsdom": "^22.0.0",
"jsdom": "22.0.0",
"kleur": "^4.1.5",
"rollup": "^3.26.2",
"source-map": "^0.7.4",

@ -16,7 +16,7 @@ const GLOBAL_TS_PATH = './src/compiler/utils/globals.js';
const SPECIALS = ['global', 'globalThis', 'InternalError', 'process', 'undefined'];
const get_url = (name) =>
`https://raw.githubusercontent.com/microsoft/TypeScript/main/lib/lib.${name}.d.ts`;
`https://raw.githubusercontent.com/microsoft/TypeScript/main/src/lib/${name}.d.ts`;
const extract_name = (split) => split.match(/^[a-zA-Z0-9_$]+/)[0];
const extract_functions_and_references = (name, data) => {

@ -1,6 +1,6 @@
/** ----------------------------------------------------------------------
This file is automatically generated by `scripts/globals-extractor.js`.
Generated At: 2023-05-24T13:16:20.777Z
Generated At: 2023-08-11T04:11:50.562Z
---------------------------------------------------------------------- */
export default new Set([

@ -292,7 +292,18 @@ export function apply_preprocessor_sourcemap(filename, svelte_map, preprocessor_
toUrl: {
enumerable: false,
value: function toUrl() {
return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
let b64 = '';
if (typeof window !== 'undefined' && window.btoa) {
// btoa doesn't support multi-byte characters
b64 = window.btoa(unescape(encodeURIComponent(this.toString())));
} else if (typeof Buffer !== 'undefined') {
b64 = Buffer.from(this.toString(), 'utf8').toString('base64');
} else {
throw new Error(
'Unsupported environment: `window.btoa` or `Buffer` should be present to use toUrl.'
);
}
return 'data:application/json;charset=utf-8;base64,' + b64;
}
}
});

@ -6,5 +6,5 @@
* https://svelte.dev/docs/svelte-compiler#svelte-version
* @type {string}
*/
export const VERSION = '4.1.2';
export const VERSION = '4.2.0';
export const PUBLIC_VERSION = '4';

@ -0,0 +1,252 @@
/// <reference lib="dom" />
// This file is deliberately not exposed through the exports map.
// It's meant to be loaded directly by the Svelte language server
/* eslint-disable @typescript-eslint/no-empty-interface */
import * as svelteElements from './elements.js';
/**
* @internal do not use
*/
type HTMLProps<Property extends string, Override> = Omit<
import('./elements.js').SvelteHTMLElements[Property],
keyof Override
> &
Override;
declare global {
/**
* This namespace does not exist in the runtime, it is only used for typings
*/
namespace svelteHTML {
// Every namespace eligible for use needs to implement the following two functions
/**
* @internal do not use
*/
function mapElementTag<K extends keyof ElementTagNameMap>(tag: K): ElementTagNameMap[K];
function mapElementTag<K extends keyof SVGElementTagNameMap>(tag: K): SVGElementTagNameMap[K];
function mapElementTag(tag: any): any; // needs to be any because used in context of <svelte:element>
/**
* @internal do not use
*/
function createElement<Elements extends IntrinsicElements, Key extends keyof Elements>(
// "undefined | null" because of <svelte:element>
element: Key | undefined | null,
attrs: string extends Key ? svelteElements.HTMLAttributes<any> : Elements[Key]
): Key extends keyof ElementTagNameMap
? ElementTagNameMap[Key]
: Key extends keyof SVGElementTagNameMap
? SVGElementTagNameMap[Key]
: any;
function createElement<Elements extends IntrinsicElements, Key extends keyof Elements, T>(
// "undefined | null" because of <svelte:element>
element: Key | undefined | null,
attrsEnhancers: T,
attrs: (string extends Key ? svelteElements.HTMLAttributes<any> : Elements[Key]) & T
): Key extends keyof ElementTagNameMap
? ElementTagNameMap[Key]
: Key extends keyof SVGElementTagNameMap
? SVGElementTagNameMap[Key]
: any;
// For backwards-compatibility and ease-of-use, in case someone enhanced the typings from import('svelte/elements').HTMLAttributes/SVGAttributes
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface HTMLAttributes<T extends EventTarget = any> {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface SVGAttributes<T extends EventTarget = any> {}
/**
* Avoid using this interface directly. Instead use the `SvelteHTMLElements` interface exported by `svelte/elements`
* This should only be used if you need to extend the interface with custom elements
*/
interface IntrinsicElements extends svelteElements.SvelteHTMLElements {
a: HTMLProps<'a', HTMLAttributes>;
abbr: HTMLProps<'abbr', HTMLAttributes>;
address: HTMLProps<'address', HTMLAttributes>;
area: HTMLProps<'area', HTMLAttributes>;
article: HTMLProps<'article', HTMLAttributes>;
aside: HTMLProps<'aside', HTMLAttributes>;
audio: HTMLProps<'audio', HTMLAttributes>;
b: HTMLProps<'b', HTMLAttributes>;
base: HTMLProps<'base', HTMLAttributes>;
bdi: HTMLProps<'bdi', HTMLAttributes>;
bdo: HTMLProps<'bdo', HTMLAttributes>;
big: HTMLProps<'big', HTMLAttributes>;
blockquote: HTMLProps<'blockquote', HTMLAttributes>;
body: HTMLProps<'body', HTMLAttributes>;
br: HTMLProps<'br', HTMLAttributes>;
button: HTMLProps<'button', HTMLAttributes>;
canvas: HTMLProps<'canvas', HTMLAttributes>;
caption: HTMLProps<'caption', HTMLAttributes>;
cite: HTMLProps<'cite', HTMLAttributes>;
code: HTMLProps<'code', HTMLAttributes>;
col: HTMLProps<'col', HTMLAttributes>;
colgroup: HTMLProps<'colgroup', HTMLAttributes>;
data: HTMLProps<'data', HTMLAttributes>;
datalist: HTMLProps<'datalist', HTMLAttributes>;
dd: HTMLProps<'dd', HTMLAttributes>;
del: HTMLProps<'del', HTMLAttributes>;
details: HTMLProps<'details', HTMLAttributes>;
dfn: HTMLProps<'dfn', HTMLAttributes>;
dialog: HTMLProps<'dialog', HTMLAttributes>;
div: HTMLProps<'div', HTMLAttributes>;
dl: HTMLProps<'dl', HTMLAttributes>;
dt: HTMLProps<'dt', HTMLAttributes>;
em: HTMLProps<'em', HTMLAttributes>;
embed: HTMLProps<'embed', HTMLAttributes>;
fieldset: HTMLProps<'fieldset', HTMLAttributes>;
figcaption: HTMLProps<'figcaption', HTMLAttributes>;
figure: HTMLProps<'figure', HTMLAttributes>;
footer: HTMLProps<'footer', HTMLAttributes>;
form: HTMLProps<'form', HTMLAttributes>;
h1: HTMLProps<'h1', HTMLAttributes>;
h2: HTMLProps<'h2', HTMLAttributes>;
h3: HTMLProps<'h3', HTMLAttributes>;
h4: HTMLProps<'h4', HTMLAttributes>;
h5: HTMLProps<'h5', HTMLAttributes>;
h6: HTMLProps<'h6', HTMLAttributes>;
head: HTMLProps<'head', HTMLAttributes>;
header: HTMLProps<'header', HTMLAttributes>;
hgroup: HTMLProps<'hgroup', HTMLAttributes>;
hr: HTMLProps<'hr', HTMLAttributes>;
html: HTMLProps<'html', HTMLAttributes>;
i: HTMLProps<'i', HTMLAttributes>;
iframe: HTMLProps<'iframe', HTMLAttributes>;
img: HTMLProps<'img', HTMLAttributes>;
input: HTMLProps<'input', HTMLAttributes>;
ins: HTMLProps<'ins', HTMLAttributes>;
kbd: HTMLProps<'kbd', HTMLAttributes>;
keygen: HTMLProps<'keygen', HTMLAttributes>;
label: HTMLProps<'label', HTMLAttributes>;
legend: HTMLProps<'legend', HTMLAttributes>;
li: HTMLProps<'li', HTMLAttributes>;
link: HTMLProps<'link', HTMLAttributes>;
main: HTMLProps<'main', HTMLAttributes>;
map: HTMLProps<'map', HTMLAttributes>;
mark: HTMLProps<'mark', HTMLAttributes>;
menu: HTMLProps<'menu', HTMLAttributes>;
menuitem: HTMLProps<'menuitem', HTMLAttributes>;
meta: HTMLProps<'meta', HTMLAttributes>;
meter: HTMLProps<'meter', HTMLAttributes>;
nav: HTMLProps<'nav', HTMLAttributes>;
noscript: HTMLProps<'noscript', HTMLAttributes>;
object: HTMLProps<'object', HTMLAttributes>;
ol: HTMLProps<'ol', HTMLAttributes>;
optgroup: HTMLProps<'optgroup', HTMLAttributes>;
option: HTMLProps<'option', HTMLAttributes>;
output: HTMLProps<'output', HTMLAttributes>;
p: HTMLProps<'p', HTMLAttributes>;
param: HTMLProps<'param', HTMLAttributes>;
picture: HTMLProps<'picture', HTMLAttributes>;
pre: HTMLProps<'pre', HTMLAttributes>;
progress: HTMLProps<'progress', HTMLAttributes>;
q: HTMLProps<'q', HTMLAttributes>;
rp: HTMLProps<'rp', HTMLAttributes>;
rt: HTMLProps<'rt', HTMLAttributes>;
ruby: HTMLProps<'ruby', HTMLAttributes>;
s: HTMLProps<'s', HTMLAttributes>;
samp: HTMLProps<'samp', HTMLAttributes>;
slot: HTMLProps<'slot', HTMLAttributes>;
script: HTMLProps<'script', HTMLAttributes>;
section: HTMLProps<'section', HTMLAttributes>;
select: HTMLProps<'select', HTMLAttributes>;
small: HTMLProps<'small', HTMLAttributes>;
source: HTMLProps<'source', HTMLAttributes>;
span: HTMLProps<'span', HTMLAttributes>;
strong: HTMLProps<'strong', HTMLAttributes>;
style: HTMLProps<'style', HTMLAttributes>;
sub: HTMLProps<'sub', HTMLAttributes>;
summary: HTMLProps<'summary', HTMLAttributes>;
sup: HTMLProps<'sup', HTMLAttributes>;
table: HTMLProps<'table', HTMLAttributes>;
template: HTMLProps<'template', HTMLAttributes>;
tbody: HTMLProps<'tbody', HTMLAttributes>;
td: HTMLProps<'td', HTMLAttributes>;
textarea: HTMLProps<'textarea', HTMLAttributes>;
tfoot: HTMLProps<'tfoot', HTMLAttributes>;
th: HTMLProps<'th', HTMLAttributes>;
thead: HTMLProps<'thead', HTMLAttributes>;
time: HTMLProps<'time', HTMLAttributes>;
title: HTMLProps<'title', HTMLAttributes>;
tr: HTMLProps<'tr', HTMLAttributes>;
track: HTMLProps<'track', HTMLAttributes>;
u: HTMLProps<'u', HTMLAttributes>;
ul: HTMLProps<'ul', HTMLAttributes>;
var: HTMLProps<'var', HTMLAttributes>;
video: HTMLProps<'video', HTMLAttributes>;
wbr: HTMLProps<'wbr', HTMLAttributes>;
webview: HTMLProps<'webview', HTMLAttributes>;
// SVG
svg: HTMLProps<'svg', SVGAttributes>;
animate: HTMLProps<'animate', SVGAttributes>;
animateMotion: HTMLProps<'animateMotion', SVGAttributes>;
animateTransform: HTMLProps<'animateTransform', SVGAttributes>;
circle: HTMLProps<'circle', SVGAttributes>;
clipPath: HTMLProps<'clipPath', SVGAttributes>;
defs: HTMLProps<'defs', SVGAttributes>;
desc: HTMLProps<'desc', SVGAttributes>;
ellipse: HTMLProps<'ellipse', SVGAttributes>;
feBlend: HTMLProps<'feBlend', SVGAttributes>;
feColorMatrix: HTMLProps<'feColorMatrix', SVGAttributes>;
feComponentTransfer: HTMLProps<'feComponentTransfer', SVGAttributes>;
feComposite: HTMLProps<'feComposite', SVGAttributes>;
feConvolveMatrix: HTMLProps<'feConvolveMatrix', SVGAttributes>;
feDiffuseLighting: HTMLProps<'feDiffuseLighting', SVGAttributes>;
feDisplacementMap: HTMLProps<'feDisplacementMap', SVGAttributes>;
feDistantLight: HTMLProps<'feDistantLight', SVGAttributes>;
feDropShadow: HTMLProps<'feDropShadow', SVGAttributes>;
feFlood: HTMLProps<'feFlood', SVGAttributes>;
feFuncA: HTMLProps<'feFuncA', SVGAttributes>;
feFuncB: HTMLProps<'feFuncB', SVGAttributes>;
feFuncG: HTMLProps<'feFuncG', SVGAttributes>;
feFuncR: HTMLProps<'feFuncR', SVGAttributes>;
feGaussianBlur: HTMLProps<'feGaussianBlur', SVGAttributes>;
feImage: HTMLProps<'feImage', SVGAttributes>;
feMerge: HTMLProps<'feMerge', SVGAttributes>;
feMergeNode: HTMLProps<'feMergeNode', SVGAttributes>;
feMorphology: HTMLProps<'feMorphology', SVGAttributes>;
feOffset: HTMLProps<'feOffset', SVGAttributes>;
fePointLight: HTMLProps<'fePointLight', SVGAttributes>;
feSpecularLighting: HTMLProps<'feSpecularLighting', SVGAttributes>;
feSpotLight: HTMLProps<'feSpotLight', SVGAttributes>;
feTile: HTMLProps<'feTile', SVGAttributes>;
feTurbulence: HTMLProps<'feTurbulence', SVGAttributes>;
filter: HTMLProps<'filter', SVGAttributes>;
foreignObject: HTMLProps<'foreignObject', SVGAttributes>;
g: HTMLProps<'g', SVGAttributes>;
image: HTMLProps<'image', SVGAttributes>;
line: HTMLProps<'line', SVGAttributes>;
linearGradient: HTMLProps<'linearGradient', SVGAttributes>;
marker: HTMLProps<'marker', SVGAttributes>;
mask: HTMLProps<'mask', SVGAttributes>;
metadata: HTMLProps<'metadata', SVGAttributes>;
mpath: HTMLProps<'mpath', SVGAttributes>;
path: HTMLProps<'path', SVGAttributes>;
pattern: HTMLProps<'pattern', SVGAttributes>;
polygon: HTMLProps<'polygon', SVGAttributes>;
polyline: HTMLProps<'polyline', SVGAttributes>;
radialGradient: HTMLProps<'radialGradient', SVGAttributes>;
rect: HTMLProps<'rect', SVGAttributes>;
stop: HTMLProps<'stop', SVGAttributes>;
switch: HTMLProps<'switch', SVGAttributes>;
symbol: HTMLProps<'symbol', SVGAttributes>;
text: HTMLProps<'text', SVGAttributes>;
textPath: HTMLProps<'textPath', SVGAttributes>;
tspan: HTMLProps<'tspan', SVGAttributes>;
use: HTMLProps<'use', SVGAttributes>;
view: HTMLProps<'view', SVGAttributes>;
// Svelte specific
'svelte:window': HTMLProps<'svelte:window', HTMLAttributes>;
'svelte:body': HTMLProps<'svelte:body', HTMLAttributes>;
'svelte:document': HTMLProps<'svelte:document', HTMLAttributes>;
'svelte:fragment': { slot?: string };
'svelte:options': HTMLProps<'svelte:options', HTMLAttributes>;
'svelte:head': { [name: string]: any };
[name: string]: { [name: string]: any };
}
}
}

@ -0,0 +1,7 @@
<script>
import Bla from './Bla.svelte';
</script>
<Bla>
<button slot="foo" class:bar on:click={clickFn} let:bar let:clickFn>{bar}</button>
</Bla>

File diff suppressed because it is too large Load Diff

@ -18,8 +18,8 @@
},
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15",
"@supabase/supabase-js": "^2.31.0",
"@sveltejs/repl": "0.5.0",
"@supabase/supabase-js": "^2.33.1",
"@sveltejs/repl": "0.6.0",
"cookie": "^0.5.0",
"devalue": "^4.3.2",
"do-not-zip": "^1.0.0",
@ -29,32 +29,32 @@
"devDependencies": {
"@resvg/resvg-js": "^2.4.1",
"@sveltejs/adapter-vercel": "^3.0.3",
"@sveltejs/kit": "^1.22.4",
"@sveltejs/site-kit": "6.0.0-next.25",
"@sveltejs/vite-plugin-svelte": "^2.4.3",
"@sveltejs/kit": "^1.22.6",
"@sveltejs/site-kit": "6.0.0-next.32",
"@sveltejs/vite-plugin-svelte": "^2.4.5",
"@types/cookie": "^0.5.1",
"@types/node": "^20.4.7",
"@types/node": "^20.5.3",
"browserslist": "^4.21.10",
"degit": "^2.8.4",
"dotenv": "^16.3.1",
"jimp": "^0.22.10",
"lightningcss": "^1.21.5",
"magic-string": "^0.30.2",
"marked": "^6.0.0",
"prettier": "^3.0.1",
"lightningcss": "^1.21.7",
"magic-string": "^0.30.3",
"marked": "^7.0.4",
"prettier": "^3.0.2",
"prettier-plugin-svelte": "^3.0.3",
"sass": "^1.64.2",
"satori": "^0.10.2",
"sass": "^1.66.1",
"satori": "^0.10.3",
"satori-html": "^0.3.2",
"shelljs": "^0.8.5",
"shiki": "^0.14.3",
"shiki-twoslash": "^3.1.2",
"svelte": "workspace:*",
"svelte-check": "^3.4.6",
"svelte-check": "^3.5.0",
"svelte-preprocess": "^5.0.4",
"tiny-glob": "^0.2.9",
"typescript": "^5.1.6",
"vite": "^4.4.8",
"vite-imagetools": "^5.0.7"
"vite": "^4.4.9",
"vite-imagetools": "^5.0.8"
}
}

@ -0,0 +1,6 @@
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
return await resolve(event, {
preload: ({ type }) => type === 'js' || type === 'css' || type === 'font'
});
}

@ -76,7 +76,7 @@ export async function get_docs_data(base = CONTENT_BASE_PATHS.DOCS) {
slug: page_slug,
content: page_content,
category: category_title,
sections: get_sections(page_content),
sections: await get_sections(page_content),
path: `${app_base}/docs/${page_slug}`,
file: `${category_dir}/${filename}`
});
@ -99,9 +99,9 @@ export function get_docs_list(docs_data) {
}));
}
const titled = (str) =>
const titled = async (str) =>
removeMarkdown(
escape(markedTransform(str, { paragraph: (txt) => txt }))
escape(await markedTransform(str, { paragraph: (txt) => txt }))
.replace(/<\/?code>/g, '')
.replace(/&#39;/g, "'")
.replace(/&quot;/g, '"')
@ -111,7 +111,7 @@ const titled = (str) =>
);
/** @param {string} markdown */
function get_sections(markdown) {
async function get_sections(markdown) {
const lines = markdown.split('\n');
const root = /** @type {import('./types').Section} */ ({
title: 'Root',
@ -122,11 +122,11 @@ function get_sections(markdown) {
});
let currentNodes = [root];
lines.forEach((line) => {
for (const line of lines) {
const match = line.match(/^(#{2,4})\s(.*)/);
if (match) {
const level = match[1].length - 2;
const text = titled(match[2]);
const text = await titled(match[2]);
const slug = normalizeSlugify(text);
// Prepare new node
@ -149,7 +149,7 @@ function get_sections(markdown) {
// Add non-heading line to the text of the current section
currentNodes[currentNodes.length - 1].text += line + '\n';
}
});
}
return root.sections;
}

@ -5,6 +5,7 @@ export function load({ url }) {
const gist = query.get('gist');
const example = query.get('example');
const version = query.get('version');
const vim = query.get('vim');
// redirect to v2 REPL if appropriate
if (/^[^>]?[12]/.test(version)) {
@ -12,7 +13,12 @@ export function load({ url }) {
}
const id = gist || example || 'hello-world';
const q = version ? `?version=${version}` : ``;
throw redirect(301, `/repl/${id}${q}`);
// we need to filter out null values
const q = new URLSearchParams(
Object.entries({
version,
vim
}).filter(([, value]) => value !== null)
).toString();
throw redirect(301, `/repl/${id}?${q}`);
}

@ -0,0 +1,18 @@
import { browser } from '$app/environment';
export function load({ data, url }) {
// initialize vim with the search param
const vim_search_params = url.searchParams.get('vim');
let vim = vim_search_params !== null && vim_search_params !== 'false';
// when in the browser check if there's a local storage entry and eventually override
// vim if there's not a search params otherwise update the local storage
if (browser) {
const vim_local_storage = window.localStorage.getItem('svelte:vim-enabled');
if (vim_search_params !== null) {
window.localStorage.setItem('svelte:vim-enabled', vim.toString());
} else if (vim_local_storage) {
vim = vim_local_storage !== 'false';
}
}
return { ...data, vim };
}

@ -61,6 +61,8 @@
: `https://unpkg.com/svelte@${version}`;
$: relaxed = data.gist.relaxed || (data.user && data.user.id === data.gist.owner);
$: vim = data.vim;
</script>
<svelte:head>
@ -87,6 +89,7 @@
bind:this={repl}
{svelteUrl}
{relaxed}
{vim}
injectedJS={mapbox_setup}
showModified
showAst

@ -31,10 +31,6 @@
let selected = examples[0];
</script>
<svelte:head>
<link rel="prefetch" href="/fonts/overpass/overpass-latin-400.woff2" />
</svelte:head>
<Section --background="var(--sk-back-2)">
<h3>build with ease</h3>

@ -47,7 +47,7 @@ export async function content() {
blocks.push({
breadcrumbs: [...breadcrumbs, removeMarkdown(remove_TYPE(metadata.title) ?? '')],
href: get_href([slug]),
content: plaintext(intro),
content: await plaintext(intro),
rank
});
@ -67,7 +67,7 @@ export async function content() {
remove_TYPE(removeMarkdown(h2))
],
href: get_href([slug, normalizeSlugify(h2)]),
content: plaintext(intro),
content: await plaintext(intro),
rank
});
@ -83,7 +83,7 @@ export async function content() {
removeMarkdown(remove_TYPE(h3))
],
href: get_href([slug, normalizeSlugify(h2) + '-' + normalizeSlugify(h3)]),
content: plaintext(lines.join('\n').trim()),
content: await plaintext(lines.join('\n').trim()),
rank
});
}
@ -99,37 +99,39 @@ function remove_TYPE(str) {
}
/** @param {string} markdown */
function plaintext(markdown) {
async function plaintext(markdown) {
/** @param {unknown} text */
const block = (text) => `${text}\n`;
/** @param {string} text */
const inline = (text) => text;
return markedTransform(markdown, {
code: (source) => source.split('// ---cut---\n').pop(),
blockquote: block,
html: () => '\n',
heading: (text) => `${text}\n`,
hr: () => '',
list: block,
listitem: block,
checkbox: block,
paragraph: (text) => `${text}\n\n`,
table: block,
tablerow: block,
tablecell: (text, opts) => {
return text + ' ';
},
strong: inline,
em: inline,
codespan: inline,
br: () => '',
del: inline,
link: (href, title, text) => text,
image: (href, title, text) => text,
text: inline
})
return (
await markedTransform(markdown, {
code: (source) => source.split('// ---cut---\n').pop(),
blockquote: block,
html: () => '\n',
heading: (text) => `${text}\n`,
hr: () => '',
list: block,
listitem: block,
checkbox: block,
paragraph: (text) => `${text}\n\n`,
table: block,
tablerow: block,
tablecell: (text, opts) => {
return text + ' ';
},
strong: inline,
em: inline,
codespan: inline,
br: () => '',
del: inline,
link: (href, title, text) => text,
image: (href, title, text) => text,
text: inline
})
)
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&#(\d+);/g, (match, code) => {

@ -0,0 +1,5 @@
<svelte:head>
<meta name="robots" content="noindex">
</svelte:head>
<slot />

@ -1,2 +1,2 @@
User-agent: *
Disallow: /tutorial/* # new tutorial is at learn.svelte.dev
Disallow:

Loading…
Cancel
Save