mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-13 11:35:28 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62b8a79e9f | ||
|
|
7f255563a4 | ||
|
|
32f4a50f25 | ||
|
|
b1a9be2dc3 | ||
|
|
c5456d3033 | ||
|
|
9b33dad589 | ||
|
|
4315a46ff2 | ||
|
|
0fb5827968 | ||
|
|
f9bf23dc43 | ||
|
|
611017fd28 | ||
|
|
72b265a35f | ||
|
|
e0d533f2ea | ||
|
|
dba83641e4 | ||
|
|
14e5c8e761 | ||
|
|
cbbf4a95db | ||
|
|
55b7ffd2ed | ||
|
|
9f4d4e70de | ||
|
|
deef1bbfcf | ||
|
|
17b0fc0d0c | ||
|
|
3c44c511e4 | ||
|
|
7cf1b9613a |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,5 +1,26 @@
|
||||
# sapper changelog
|
||||
|
||||
## 0.17.1
|
||||
|
||||
* Print which file is causing build errors/warnings ([#371](https://github.com/sveltejs/sapper/pull/371))
|
||||
|
||||
## 0.17.0
|
||||
|
||||
* Use `cheap-watch` instead of `chokidar` ([#364](https://github.com/sveltejs/sapper/issues/364))
|
||||
|
||||
## 0.16.1
|
||||
|
||||
* Fix file watching regression in previous version
|
||||
|
||||
## 0.16.0
|
||||
|
||||
* Slim down installed package ([#363](https://github.com/sveltejs/sapper/pull/363))
|
||||
|
||||
## 0.15.8
|
||||
|
||||
* Only set `preloading: true` on navigation, not prefetch ([#352](https://github.com/sveltejs/sapper/issues/352))
|
||||
* Provide fallback for missing preload errors ([#361](https://github.com/sveltejs/sapper/pull/361))
|
||||
|
||||
## 0.15.7
|
||||
|
||||
* Strip leading slash from redirects ([#291](https://github.com/sveltejs/sapper/issues/291))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
--require source-map-support/register
|
||||
--require ts-node/register
|
||||
--recursive
|
||||
test/unit/*/*.js
|
||||
test/unit/*/*.ts
|
||||
test/common/test.js
|
||||
3103
package-lock.json
generated
3103
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
55
package.json
55
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sapper",
|
||||
"version": "0.15.7",
|
||||
"version": "0.17.1",
|
||||
"description": "Military-grade apps, engineered by Svelte",
|
||||
"main": "dist/middleware.ts.js",
|
||||
"bin": {
|
||||
@@ -19,50 +19,53 @@
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-colors": "^2.0.1",
|
||||
"cheerio": "^1.0.0-rc.2",
|
||||
"chokidar": "^2.0.3",
|
||||
"html-minifier": "^3.5.16",
|
||||
"source-map-support": "^0.5.6",
|
||||
"tslib": "^1.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/glob": "^5.0.34",
|
||||
"@types/mkdirp": "^0.5.2",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^10.7.1",
|
||||
"@types/rimraf": "^2.0.2",
|
||||
"cheap-watch": "^0.3.0",
|
||||
"compression": "^1.7.1",
|
||||
"cookie": "^0.3.1",
|
||||
"devalue": "^1.0.4",
|
||||
"glob": "^7.1.2",
|
||||
"html-minifier": "^3.5.16",
|
||||
"eslint": "^4.13.1",
|
||||
"eslint-plugin-import": "^2.12.0",
|
||||
"express": "^4.16.3",
|
||||
"kleur": "^2.0.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mocha": "^5.2.0",
|
||||
"nightmare": "^3.0.0",
|
||||
"node-fetch": "^2.1.1",
|
||||
"npm-run-all": "^4.1.3",
|
||||
"polka": "^0.4.0",
|
||||
"port-authority": "^1.0.5",
|
||||
"pretty-bytes": "^5.0.0",
|
||||
"pretty-ms": "^3.1.0",
|
||||
"require-relative": "^0.8.7",
|
||||
"rimraf": "^2.6.2",
|
||||
"sade": "^1.4.1",
|
||||
"sander": "^0.6.0",
|
||||
"source-map-support": "^0.5.6",
|
||||
"tslib": "^1.9.1",
|
||||
"url-parse": "^1.2.0",
|
||||
"webpack-format-messages": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/glob": "^5.0.34",
|
||||
"@types/mkdirp": "^0.5.2",
|
||||
"@types/rimraf": "^2.0.2",
|
||||
"compression": "^1.7.1",
|
||||
"eslint": "^4.13.1",
|
||||
"eslint-plugin-import": "^2.12.0",
|
||||
"express": "^4.16.3",
|
||||
"mocha": "^5.2.0",
|
||||
"nightmare": "^3.0.0",
|
||||
"npm-run-all": "^4.1.3",
|
||||
"polka": "^0.4.0",
|
||||
"rollup": "^0.59.2",
|
||||
"rollup-plugin-commonjs": "^9.1.3",
|
||||
"rollup-plugin-json": "^3.0.0",
|
||||
"rollup-plugin-node-resolve": "^3.3.0",
|
||||
"rollup-plugin-string": "^2.0.2",
|
||||
"rollup-plugin-typescript": "^0.8.1",
|
||||
"sade": "^1.4.1",
|
||||
"sander": "^0.6.0",
|
||||
"serve-static": "^1.13.2",
|
||||
"svelte": "^2.6.3",
|
||||
"svelte-loader": "^2.9.0",
|
||||
"tiny-glob": "^0.2.2",
|
||||
"ts-node": "^7.0.1",
|
||||
"typescript": "^2.8.3",
|
||||
"url-parse": "^1.2.0",
|
||||
"walk-sync": "^0.3.2",
|
||||
"webpack": "^4.8.3"
|
||||
"webpack": "^4.8.3",
|
||||
"webpack-format-messages": "^2.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"cy:open": "cypress open",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import typescript from 'rollup-plugin-typescript';
|
||||
import string from 'rollup-plugin-string';
|
||||
import json from 'rollup-plugin-json';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import pkg from './package.json';
|
||||
|
||||
@@ -44,6 +45,7 @@ export default [
|
||||
include: '**/*.md'
|
||||
}),
|
||||
json(),
|
||||
resolve(),
|
||||
commonjs(),
|
||||
typescript({
|
||||
typescript: require('typescript')
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as path from 'path';
|
||||
import mkdirp from 'mkdirp';
|
||||
import rimraf from 'rimraf';
|
||||
import { EventEmitter } from 'events';
|
||||
import { minify_html } from './utils/minify_html';
|
||||
import minify_html from './utils/minify_html';
|
||||
import { create_compilers, create_main_manifests, create_routes, create_serviceworker_manifest } from '../core';
|
||||
import * as events from './interfaces';
|
||||
|
||||
|
||||
@@ -119,21 +119,30 @@ class Watcher extends EventEmitter {
|
||||
this.dev_server = new DevServer(dev_port);
|
||||
|
||||
this.filewatchers.push(
|
||||
watch_files(locations.routes(), ['add', 'unlink'], () => {
|
||||
const routes = create_routes();
|
||||
create_main_manifests({ routes, dev_port });
|
||||
|
||||
try {
|
||||
watch_dir(
|
||||
locations.routes(),
|
||||
({ path: file, stats }) => {
|
||||
if (stats.isDirectory()) {
|
||||
return path.basename(file)[0] !== '_';
|
||||
}
|
||||
return true;
|
||||
},
|
||||
() => {
|
||||
const routes = create_routes();
|
||||
create_main_manifests({ routes, dev_port });
|
||||
} catch (err) {
|
||||
this.emit('error', <events.ErrorEvent>{
|
||||
message: err.message
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
watch_files(`${locations.app()}/template.html`, ['change'], () => {
|
||||
try {
|
||||
const routes = create_routes();
|
||||
create_main_manifests({ routes, dev_port });
|
||||
} catch (err) {
|
||||
this.emit('error', <events.ErrorEvent>{
|
||||
message: err.message
|
||||
});
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
fs.watch(`${locations.app()}/template.html`, () => {
|
||||
this.dev_server.send({
|
||||
action: 'reload'
|
||||
});
|
||||
@@ -453,20 +462,32 @@ class DevServer {
|
||||
|
||||
function noop() {}
|
||||
|
||||
function watch_files(pattern: string, events: string[], callback: () => void) {
|
||||
const chokidar = require('chokidar');
|
||||
function watch_dir(
|
||||
dir: string,
|
||||
filter: ({ path, stats }: { path: string, stats: fs.Stats }) => boolean,
|
||||
callback: () => void
|
||||
) {
|
||||
let watch;
|
||||
let closed = false;
|
||||
|
||||
const watcher = chokidar.watch(pattern, {
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
disableGlobbing: true
|
||||
});
|
||||
import('cheap-watch').then(CheapWatch => {
|
||||
if (closed) return;
|
||||
|
||||
events.forEach(event => {
|
||||
watcher.on(event, callback);
|
||||
watch = new CheapWatch({ dir, filter, debounce: 50 });
|
||||
|
||||
watch.on('+', ({ isNew }) => {
|
||||
if (isNew) callback();
|
||||
});
|
||||
|
||||
watch.on('-', callback);
|
||||
|
||||
watch.init();
|
||||
});
|
||||
|
||||
return {
|
||||
close: () => watcher.close()
|
||||
close: () => {
|
||||
if (watch) watch.close();
|
||||
closed = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import * as child_process from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as sander from 'sander';
|
||||
import cheerio from 'cheerio';
|
||||
import URL from 'url-parse';
|
||||
import fetch from 'node-fetch';
|
||||
import * as ports from 'port-authority';
|
||||
import { EventEmitter } from 'events';
|
||||
import { minify_html } from './utils/minify_html';
|
||||
import clean_html from './utils/clean_html';
|
||||
import minify_html from './utils/minify_html';
|
||||
import Deferred from './utils/Deferred';
|
||||
import * as events from './interfaces';
|
||||
|
||||
@@ -123,15 +123,26 @@ async function execute(emitter: EventEmitter, {
|
||||
if (range === 2) {
|
||||
if (r.headers.get('Content-Type') === 'text/html') {
|
||||
const body = await r.text();
|
||||
const $ = cheerio.load(body);
|
||||
const urls: URL[] = [];
|
||||
|
||||
const base = new URL($('base').attr('href') || '/', url.href);
|
||||
const cleaned = clean_html(body);
|
||||
|
||||
$('a[href]').each((i: number, $a) => {
|
||||
const url = new URL($a.attribs.href, base.href);
|
||||
if (url.origin === origin) urls.push(url);
|
||||
});
|
||||
const base_match = /<base ([\s\S]+?)>/m.exec(cleaned);
|
||||
const base_href = base_match && get_href(base_match[1]);
|
||||
const base = new URL(base_href || '/', url.href);
|
||||
|
||||
let match;
|
||||
let pattern = /<a ([\s\S]+?)>/gm;
|
||||
|
||||
while (match = pattern.exec(cleaned)) {
|
||||
const attrs = match[1];
|
||||
const href = get_href(attrs);
|
||||
|
||||
if (href) {
|
||||
const url = new URL(href, base.href);
|
||||
if (url.origin === origin) urls.push(url);
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(urls.map(handle));
|
||||
}
|
||||
@@ -147,3 +158,8 @@ async function execute(emitter: EventEmitter, {
|
||||
})
|
||||
.then(() => proc.kill());
|
||||
}
|
||||
|
||||
function get_href(attrs: string) {
|
||||
const match = /href\s*=\s*(?:"(.+?)"|'(.+?)'|([^\s>]+))/.exec(attrs);
|
||||
return match[1] || match[2] || match[3];
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import * as glob from 'glob';
|
||||
import { locations } from '../config';
|
||||
import { create_routes } from '../core';
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ export type InvalidEvent = {
|
||||
|
||||
export type BuildEvent = {
|
||||
type: string;
|
||||
errors: Array<{ message: string, duplicate: boolean }>;
|
||||
warnings: Array<{ message: string, duplicate: boolean }>;
|
||||
errors: Array<{ file: string, message: string, duplicate: boolean }>;
|
||||
warnings: Array<{ file: string, message: string, duplicate: boolean }>;
|
||||
duration: number;
|
||||
webpack_stats: any;
|
||||
}
|
||||
|
||||
7
src/api/utils/clean_html.ts
Normal file
7
src/api/utils/clean_html.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export default function clean_html(html: string) {
|
||||
return html
|
||||
.replace(/<!\[CDATA\[[\s\S]*?\]\]>/gm, '')
|
||||
.replace(/(<script[\s\S]*?>)[\s\S]*?<\/script>/gm, '$1</' + 'script>')
|
||||
.replace(/(<style[\s\S]*?>)[\s\S]*?<\/style>/gm, '$1</' + 'style>')
|
||||
.replace(/<!--[\s\S]*?-->/gm, '');
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { minify } from 'html-minifier';
|
||||
|
||||
export function minify_html(html: string) {
|
||||
export default function minify_html(html: string) {
|
||||
return minify(html, {
|
||||
collapseBooleanAttributes: true,
|
||||
collapseWhitespace: true,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import sade from 'sade';
|
||||
import * as colors from 'ansi-colors';
|
||||
import colors from 'kleur';
|
||||
import prettyMs from 'pretty-ms';
|
||||
import * as pkg from '../package.json';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { build as _build } from '../api/build';
|
||||
import * as colors from 'ansi-colors';
|
||||
import colors from 'kleur';
|
||||
import { locations } from '../config';
|
||||
|
||||
export function build() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as path from 'path';
|
||||
import * as colors from 'ansi-colors';
|
||||
import colors from 'kleur';
|
||||
import * as child_process from 'child_process';
|
||||
import prettyMs from 'pretty-ms';
|
||||
import { dev as _dev } from '../api/dev';
|
||||
@@ -13,7 +13,7 @@ export function dev(opts: { port: number, open: boolean }) {
|
||||
|
||||
watcher.on('ready', (event: events.ReadyEvent) => {
|
||||
if (first) {
|
||||
console.log(`${colors.bold.cyan(`> Listening on http://localhost:${event.port}`)}`);
|
||||
console.log(colors.bold.cyan(`> Listening on http://localhost:${event.port}`));
|
||||
if (opts.open) child_process.exec(`open http://localhost:${event.port}`);
|
||||
first = false;
|
||||
}
|
||||
@@ -35,20 +35,21 @@ export function dev(opts: { port: number, open: boolean }) {
|
||||
});
|
||||
|
||||
watcher.on('error', (event: events.ErrorEvent) => {
|
||||
console.log(`${colors.red(`✗ ${event.type}`)}`);
|
||||
console.log(`${colors.red(event.message)}`);
|
||||
console.log(colors.red(`✗ ${event.type}`));
|
||||
console.log(colors.red(event.message));
|
||||
});
|
||||
|
||||
watcher.on('fatal', (event: events.FatalEvent) => {
|
||||
console.log(`${colors.bold.red(`> ${event.message}`)}`);
|
||||
console.log(colors.bold.red(`> ${event.message}`));
|
||||
if (event.log) console.log(event.log);
|
||||
});
|
||||
|
||||
watcher.on('build', (event: events.BuildEvent) => {
|
||||
if (event.errors.length) {
|
||||
console.log(`${colors.bold.red(`✗ ${event.type}`)}`);
|
||||
console.log(colors.bold.red(`✗ ${event.type}`));
|
||||
|
||||
event.errors.filter(e => !e.duplicate).forEach(error => {
|
||||
if (error.file) console.log(colors.bold(error.file));
|
||||
console.log(error.message);
|
||||
});
|
||||
|
||||
@@ -57,9 +58,10 @@ export function dev(opts: { port: number, open: boolean }) {
|
||||
console.log(`${hidden} duplicate ${hidden === 1 ? 'error' : 'errors'} hidden\n`);
|
||||
}
|
||||
} else if (event.warnings.length) {
|
||||
console.log(`${colors.bold.yellow(`• ${event.type}`)}`);
|
||||
console.log(colors.bold.yellow(`• ${event.type}`));
|
||||
|
||||
event.warnings.filter(e => !e.duplicate).forEach(warning => {
|
||||
if (warning.file) console.log(colors.bold(warning.file));
|
||||
console.log(warning.message);
|
||||
});
|
||||
|
||||
@@ -72,7 +74,7 @@ export function dev(opts: { port: number, open: boolean }) {
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(`${colors.bold.red(`> ${err.message}`)}`);
|
||||
console.log(colors.bold.red(`> ${err.message}`));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { exporter as _exporter } from '../api/export';
|
||||
import * as colors from 'ansi-colors';
|
||||
import colors from 'kleur';
|
||||
import prettyBytes from 'pretty-bytes';
|
||||
import { locations } from '../config';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as child_process from 'child_process';
|
||||
import * as colors from 'ansi-colors';
|
||||
import colors from 'kleur';
|
||||
import * as ports from 'port-authority';
|
||||
|
||||
export async function start(dir: string, opts: { port: number, open: boolean }) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as fs from 'fs';
|
||||
import * as colors from 'ansi-colors';
|
||||
import colors from 'kleur';
|
||||
|
||||
export default async function upgrade() {
|
||||
const upgraded = [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as glob from 'glob';
|
||||
import glob from 'tiny-glob/sync.js';
|
||||
import { posixify, write_if_changed } from './utils';
|
||||
import { dev, locations } from '../config';
|
||||
import { Page, PageComponent, ServerRoute } from '../interfaces';
|
||||
@@ -9,24 +9,27 @@ export function create_main_manifests({ routes, dev_port }: {
|
||||
routes: { components: PageComponent[], pages: Page[], server_routes: ServerRoute[] };
|
||||
dev_port?: number;
|
||||
}) {
|
||||
const path_to_routes = path.relative(`${locations.app()}/manifest`, locations.routes());
|
||||
const manifest_dir = path.join(locations.app(), 'manifest');
|
||||
if (!fs.existsSync(manifest_dir)) fs.mkdirSync(manifest_dir);
|
||||
|
||||
const path_to_routes = path.relative(manifest_dir, locations.routes());
|
||||
|
||||
const client_manifest = generate_client(routes, path_to_routes, dev_port);
|
||||
const server_manifest = generate_server(routes, path_to_routes);
|
||||
|
||||
write_if_changed(
|
||||
`${locations.app()}/manifest/default-layout.html`,
|
||||
`${manifest_dir}/default-layout.html`,
|
||||
`<svelte:component this={child.component} {...child.props}/>`
|
||||
);
|
||||
write_if_changed(`${locations.app()}/manifest/client.js`, client_manifest);
|
||||
write_if_changed(`${locations.app()}/manifest/server.js`, server_manifest);
|
||||
write_if_changed(`${manifest_dir}/client.js`, client_manifest);
|
||||
write_if_changed(`${manifest_dir}/server.js`, server_manifest);
|
||||
}
|
||||
|
||||
export function create_serviceworker_manifest({ routes, client_files }: {
|
||||
routes: { components: PageComponent[], pages: Page[], server_routes: ServerRoute[] };
|
||||
client_files: string[];
|
||||
}) {
|
||||
const assets = glob.sync('**', { cwd: 'assets', nodir: true });
|
||||
const assets = glob('**', { cwd: 'assets', filesOnly: true });
|
||||
|
||||
let code = `
|
||||
// This file is generated by Sapper — do not edit it!
|
||||
@@ -42,11 +45,6 @@ export function create_serviceworker_manifest({ routes, client_files }: {
|
||||
write_if_changed(`${locations.app()}/manifest/service-worker.js`, code);
|
||||
}
|
||||
|
||||
function right_pad(str: string, len: number) {
|
||||
while (str.length < len) str += ' ';
|
||||
return str;
|
||||
}
|
||||
|
||||
function generate_client(
|
||||
routes: { root: PageComponent, components: PageComponent[], pages: Page[], server_routes: ServerRoute[] },
|
||||
path_to_routes: string,
|
||||
|
||||
@@ -4,11 +4,6 @@ import { locations } from '../config';
|
||||
import { Page, PageComponent, ServerRoute } from '../interfaces';
|
||||
import { posixify } from './utils';
|
||||
|
||||
const default_layout_file = posixify(path.resolve(
|
||||
__dirname,
|
||||
'../components/default-layout.html'
|
||||
));
|
||||
|
||||
export default function create_routes(cwd = locations.routes()) {
|
||||
const components: PageComponent[] = [];
|
||||
const pages: Page[] = [];
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import * as sander from 'sander';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const previous_contents = new Map();
|
||||
|
||||
export function write_if_changed(file: string, code: string) {
|
||||
if (code !== previous_contents.get(file)) {
|
||||
previous_contents.set(file, code);
|
||||
sander.writeFileSync(file, code);
|
||||
fs.writeFileSync(file, code);
|
||||
fudge_mtime(file);
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,8 @@ export function posixify(file: string) {
|
||||
|
||||
export function fudge_mtime(file: string) {
|
||||
// need to fudge the mtime so that webpack doesn't go doolally
|
||||
const { atime, mtime } = sander.statSync(file);
|
||||
sander.utimesSync(
|
||||
const { atime, mtime } = fs.statSync(file);
|
||||
fs.utimesSync(
|
||||
file,
|
||||
new Date(atime.getTime() - 999999),
|
||||
new Date(mtime.getTime() - 999999)
|
||||
|
||||
@@ -299,13 +299,10 @@ function get_page_handler(
|
||||
parts: [
|
||||
{ name: null, component: error_route }
|
||||
]
|
||||
}, req, res, statusCode, error);
|
||||
}, req, res, statusCode, error || new Error('Unknown error in preload function'));
|
||||
}
|
||||
|
||||
function handle_page(page: Page, req: Req, res: ServerResponse, status = 200, error: Error | string = null) {
|
||||
const get_params = page.parts[page.parts.length - 1].params || (() => ({}));
|
||||
const match = error ? null : page.pattern.exec(req.path);
|
||||
|
||||
const chunks: Record<string, string | string[]> = get_chunks();
|
||||
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
@@ -391,6 +388,8 @@ function get_page_handler(
|
||||
})
|
||||
: {};
|
||||
|
||||
const match = error ? null : page.pattern.exec(req.path);
|
||||
|
||||
Promise.all([root_preloaded].concat(page.parts.map(part => {
|
||||
if (!part) return null;
|
||||
|
||||
|
||||
@@ -136,10 +136,6 @@ function prepare_page(target: Target): Promise<{
|
||||
data?: any;
|
||||
nullable_depth?: number;
|
||||
}> {
|
||||
if (root) {
|
||||
root.set({ preloading: true });
|
||||
}
|
||||
|
||||
const { page, path, query } = target;
|
||||
const new_segments = path.split('/').filter(Boolean);
|
||||
let changed_from = 0;
|
||||
@@ -285,6 +281,9 @@ async function navigate(target: Target, id: number): Promise<any> {
|
||||
|
||||
cid = id;
|
||||
|
||||
if (root) {
|
||||
root.set({ preloading: true });
|
||||
}
|
||||
const loaded = prefetching && prefetching.href === target.url.href ?
|
||||
prefetching.promise :
|
||||
prepare_page(target);
|
||||
|
||||
26
test/unit/clean_html/index.ts
Normal file
26
test/unit/clean_html/index.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as assert from 'assert';
|
||||
import clean_html from '../../../src/api/utils/clean_html';
|
||||
|
||||
describe('clean_html', () => {
|
||||
const samples = path.join(__dirname, 'samples');
|
||||
|
||||
fs.readdirSync(samples).forEach(dir => {
|
||||
if (dir[0] === '.') return;
|
||||
|
||||
it(dir, () => {
|
||||
const input = fs.readFileSync(`${samples}/${dir}/input.html`, 'utf-8');
|
||||
const expected = fs.readFileSync(`${samples}/${dir}/output.html`, 'utf-8');
|
||||
|
||||
const actual = clean_html(input);
|
||||
|
||||
fs.writeFileSync(`${samples}/${dir}/.actual.html`, actual);
|
||||
|
||||
assert.equal(
|
||||
actual.replace(/\s+$/gm, ''),
|
||||
expected.replace(/\s+$/gm, '')
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
14
test/unit/clean_html/samples/removes-cdata/.actual.html
Normal file
14
test/unit/clean_html/samples/removes-cdata/.actual.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<math>
|
||||
<ms></ms>
|
||||
<mo>+</mo>
|
||||
<mn>3</mn>
|
||||
<mo>=</mo>
|
||||
<ms></ms>
|
||||
</math>
|
||||
</body>
|
||||
</html>
|
||||
14
test/unit/clean_html/samples/removes-cdata/input.html
Normal file
14
test/unit/clean_html/samples/removes-cdata/input.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<math>
|
||||
<ms><![CDATA[x<y]]></ms>
|
||||
<mo>+</mo>
|
||||
<mn>3</mn>
|
||||
<mo>=</mo>
|
||||
<ms><![CDATA[x<y3]]></ms>
|
||||
</math>
|
||||
</body>
|
||||
</html>
|
||||
14
test/unit/clean_html/samples/removes-cdata/output.html
Normal file
14
test/unit/clean_html/samples/removes-cdata/output.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<math>
|
||||
<ms></ms>
|
||||
<mo>+</mo>
|
||||
<mn>3</mn>
|
||||
<mo>=</mo>
|
||||
<ms></ms>
|
||||
</math>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<a href="keep-me">keep me</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
9
test/unit/clean_html/samples/removes-comments/input.html
Normal file
9
test/unit/clean_html/samples/removes-comments/input.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<a href="keep-me">keep me</a>
|
||||
<!-- <a href="delete-me">delete me</a> -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<a href="keep-me">keep me</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script></script>
|
||||
|
||||
<script></script>
|
||||
|
||||
<script src="attributes-are-preserved.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
console.log('this should be deleted');
|
||||
</script>
|
||||
|
||||
<script>
|
||||
console.log('so should this');
|
||||
</script>
|
||||
|
||||
<script src="attributes-are-preserved.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script></script>
|
||||
|
||||
<script></script>
|
||||
|
||||
<script src="attributes-are-preserved.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,6 +1,6 @@
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
const { create_routes } = require('../../../dist/core.ts.js');
|
||||
import * as path from 'path';
|
||||
import * as assert from 'assert';
|
||||
import create_routes from '../../../src/core/create_routes';
|
||||
|
||||
describe('create_routes', () => {
|
||||
it('creates routes', () => {
|
||||
Reference in New Issue
Block a user