diff --git a/CHANGELOG.md b/CHANGELOG.md index 448e022..e3122b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## Unreleased +- Support crossorigin setting in push-manifest. + + ## [1.2.0] 2018-05-22 - Add `as=fetch` as a valid value for preload headers. diff --git a/src/push.ts b/src/push.ts index 2a992e2..45f4b1c 100644 --- a/src/push.ts +++ b/src/push.ts @@ -19,7 +19,13 @@ import * as validUrl from 'valid-url'; * JSON format for a multi-file push manifest. */ export interface PushManifestData { - [pattern: string]: {[resource: string]: {type: string; weight?: number;}} + [pattern: string]: { + [resource: string]: { + type: string; + crossorigin?: string; + weight?: number; + } + } } /** @@ -27,7 +33,8 @@ export interface PushManifestData { * should be pre-emptively pushed to the client via HTTP/2 server push. */ export class PushManifest { - private mapping = new Array<[RegExp, Map]>(); + private mapping = + new Array<[RegExp, Map]>(); /** * Create a new `PushManifest` from a JSON object which is expected to match @@ -55,11 +62,12 @@ export class PushManifest { const resources = new Map(); for (const resource of Object.keys(manifest[pattern])) { validatePath(resource); - const t = manifest[pattern][resource].type || ''; - if (!requestDestinations.has(t)) { - throw new Error(`invalid type: ${t}`); + const type = manifest[pattern][resource].type || ''; + const crossorigin = manifest[pattern][resource].crossorigin || null; + if (!requestDestinations.has(type)) { + throw new Error(`invalid type: ${type}`); } - resources.set(normalizePath(resource, basePath), {type: t}); + resources.set(normalizePath(resource, basePath), {type, crossorigin}); } if (resources.size) { let normalizedPattern; @@ -92,11 +100,14 @@ export class PushManifest { if (!resources || !pattern.test(normalizedPattern)) { continue; } - for (const [resource, {type}] of resources.entries()) { + for (const [resource, {type, crossorigin}] of resources.entries()) { let header = `<${resource}>; rel=preload`; if (type) { header += `; as=${type}`; } + if (crossorigin) { + header += `; crossorigin=${crossorigin}`; + } if (nopush) { header += `; nopush`; } diff --git a/src/test/push_test.ts b/src/test/push_test.ts index b4d9d83..1c68483 100644 --- a/src/test/push_test.ts +++ b/src/test/push_test.ts @@ -142,4 +142,21 @@ suite('PushManifest', function() { '; rel=preload; as=document; nopush', ]); }); + + test('crossorigin setting works', () => { + const manifest = new push.PushManifest({ + '/foo': { + '/a.html': {type: 'document'}, + '/b.html': {type: 'document', crossorigin: ''}, + '/c.html': {type: 'document', crossorigin: 'anonymous'}, + '/d.html': {type: 'document', crossorigin: 'use-credentials'}, + }, + }); + assert.deepEqual(manifest.linkHeaders('/foo'), [ + '; rel=preload; as=document', + '; rel=preload; as=document', + '; rel=preload; as=document; crossorigin=anonymous', + '; rel=preload; as=document; crossorigin=use-credentials', + ]); + }); });