Skip to content

Commit

Permalink
Add css loading ability
Browse files Browse the repository at this point in the history
  • Loading branch information
jakewhiteley committed Aug 9, 2023
1 parent 1bd99c3 commit 55a27cc
Show file tree
Hide file tree
Showing 16 changed files with 138 additions and 12 deletions.
2 changes: 1 addition & 1 deletion dist/taxi.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/taxi.esm.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/taxi.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/taxi.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/taxi.modern.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/taxi.modern.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/taxi.umd.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/taxi.umd.js.map

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions docs/_data/nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
"name": "Reloading JS",
"slug": "reloading-js"
},
{
"name": "Reloading CSS",
"slug": "reloading-css"
},
{
"name": "API & Events",
"slug": "api-events"
Expand Down
3 changes: 3 additions & 0 deletions docs/_includes/nav.njk
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@
</div>

<div class="flex items-center">
<span class="js-version translate-y-px mr-4 lg:mr-8 hidden sm:block"></span>

<a class="h-8 hidden sm:flex mr-4 lg:mr-8 items-center" href="https://github.com/craftedbygc/taxi" target="_blank" aria-label="View taxi on github.com" title="View taxi on github.com">
<span class="text-xs px-2 font-bold font-mono py-0.5 border-2 border-black dark:text-white mr-3 inline-flex items-center">
<span class="js-stars translate-y-px"></span>
<svg class="w-3 h-3 ml-1 fill-black dark:fill-white" height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 473.486 473.486" xml:space="preserve"><polygon points="473.486,182.079 310.615,157.952 235.904,11.23 162.628,158.675 0,184.389 117.584,299.641 91.786,462.257 237.732,386.042 384.416,460.829 357.032,298.473 "/></svg>
</span>

<svg class="w-8 h-8 fill-black dark:fill-white" xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" transform="scale(64)" />
</svg>
Expand Down
15 changes: 15 additions & 0 deletions docs/assets/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,27 @@ E.on('DOMContentLoaded', window, function () {

//star count
const starcount = document.querySelector('.js-stars')
const version = document.querySelector('.js-version')

fetch('https://api.github.com/repos/craftedbygc/taxi')
.then((response) => response.json())
.then((data) => {
if (!data.message) {
starcount.innerHTML = convertStars(data.stargazers_count)
} else {
throw new Error('GitHub API hates me')
}
})
.catch((error) => {
console.error('Error:', error);
starcount.parentElement.remove()
})

fetch('https://registry.npmjs.org/@unseenco/taxi/latest')
.then((response) => response.json())
.then((data) => {
if (data.version) {
version.innerHTML = `v${data.version}`
}
})
.catch((error) => {
Expand Down
11 changes: 11 additions & 0 deletions docs/how-to-use.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,17 @@ If you want to disable this or want to implement your own preloading strategy, s
Please see [Reloading JS]({{ global.url }}/reloading-js/) for more information.


<div class="border rounded-sm p-4 mt-16">
<div class="text-sm mb-2 font-bold">What's next:</div>
<div>
<a href="{{ global.url }}/renderers/">Renderers</a>
</div>
</div>

### reloadCssFilter `bool|function(element: HTMLLinkElement)`
Please see [Reloading CSS]({{ global.url }}/reloading-css/) for more information.


<div class="border rounded-sm p-4 mt-16">
<div class="text-sm mb-2 font-bold">What's next:</div>
<div>
Expand Down
58 changes: 58 additions & 0 deletions docs/reloading-css.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
layout: layouts/base.njk
title: Reloading CSS
---

# Running CSS on New Pages
Similarly to [Reloading JS]({{ global.url }}/reloading-js/) Taxi can also reload and run CSS present from the next page after navigation.

If enabled, this feature will run just after the `NAVIGATE_IN` event, after the new content has been appended to the DOM, but before the `Renderer.onEnter` method is called.

## Choosing which stylesheets are reloaded
By default, only stylesheets with the `data-taxi-reload` attribute are reloaded after a navigation.

```html
<!-- reloaded -->
<link rel="stylesheet" href="/foo.css" data-taxi-reload />

<!-- this is not reloaded -->
<link rel="stylesheet" href="/bar.css" />
```

If using the super cool [astro](https://astro.build/) or some other build tool which outputs per-page/component CSS, `reloadCssFilter` accepts a callback function to filter styles on the new page and decide which to load.

Your callback is passed the `link` element, and must return a boolean indicating whether the stylesheet should be reloaded or not (you could check the src or id attributes for example).

Here is the default callback for `reloadCssFilter`:

```js
(element) => element.dataset.taxiReload !== undefined
```

and here is a custom example which loads everything:
```js
import { Core } from '@unseenco/taxi'

const taxi = new Core({
reloadCssFilter: (element) => true
})
```


## Disabling this feature
Just set `reloadCssFilter` to false when initing Taxi:

```js
import { Core } from '@unseenco/taxi'

const taxi = new Core({
reloadCssFilter: false
})
```

<div class="border rounded-sm p-4 mt-16">
<div class="text-sm mb-2 font-bold">What's next:</div>
<div>
<a href="{{ global.url }}/api-events/">API & Events</a>
</div>
</div>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@unseenco/taxi",
"description": "A modern page transition library which supports routing, preloading, and additional script reloading.",
"version": "1.4.0",
"version": "1.5.0",
"license": "GPL-3.0-or-later",
"source": "src/taxi.js",
"main": "src/taxi.js",
Expand Down
13 changes: 12 additions & 1 deletion src/Core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* @property {typeof Renderer|Renderer} renderer
* @property {Document|Node} page
* @property {array} scripts
* @property {HTMLLinkElement[]} styles
* @property {string} finalUrl
* @property {boolean} skipCache
* @property {string} title
Expand All @@ -19,7 +20,8 @@ export default class Core {
* enablePrefetch?: boolean,
* renderers?: Object.<string, typeof Renderer>,
* transitions?: Object.<string, typeof Transition>,
* reloadJsFilter?: boolean|function(HTMLElement): boolean
* reloadJsFilter?: boolean|function(HTMLElement): boolean,
* reloadCssFilter?: boolean|function(HTMLLinkElement): boolean
* }} parameters
*/
constructor(parameters?: {
Expand All @@ -35,6 +37,7 @@ export default class Core {
[x: string]: typeof Transition;
};
reloadJsFilter?: boolean | ((arg0: HTMLElement) => boolean);
reloadCssFilter?: boolean | ((arg0: HTMLLinkElement) => boolean);
});
isTransitioning: boolean;
/**
Expand All @@ -60,6 +63,7 @@ export default class Core {
defaultTransition: typeof Transition;
wrapper: Element;
reloadJsFilter: boolean | ((element: HTMLElement) => boolean);
reloadCssFilter: boolean | ((arg0: HTMLLinkElement) => boolean) | ((element: HTMLLinkElement) => true);
removeOldContent: boolean;
allowInterruption: boolean;
bypassCache: boolean;
Expand Down Expand Up @@ -162,6 +166,12 @@ export default class Core {
* @param {HTMLElement[]} cachedScripts
*/
loadScripts(cachedScripts: HTMLElement[]): void;
/**
* Load up styles from the target page if needed
*
* @param {HTMLLinkElement[]} cachedStyles
*/
loadStyles(cachedStyles: HTMLLinkElement[]): void;
/**
* @private
* @param {string} links
Expand Down Expand Up @@ -207,6 +217,7 @@ export type CacheEntry = {
renderer: typeof Renderer | Renderer;
page: Document | Node;
scripts: any[];
styles: HTMLLinkElement[];
finalUrl: string;
skipCache: boolean;
title: string;
Expand Down
28 changes: 26 additions & 2 deletions src/Core.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const IN_PROGRESS = 'A transition is currently in progress'
* @property {typeof Renderer|Renderer} renderer
* @property {Document|Node} page
* @property {array} scripts
* @property {HTMLLinkElement[]} styles
* @property {string} finalUrl
* @property {boolean} skipCache
* @property {string} title
Expand Down Expand Up @@ -46,7 +47,8 @@ export default class Core {
* enablePrefetch?: boolean,
* renderers?: Object.<string, typeof Renderer>,
* transitions?: Object.<string, typeof Transition>,
* reloadJsFilter?: boolean|function(HTMLElement): boolean
* reloadJsFilter?: boolean|function(HTMLElement): boolean,
* reloadCssFilter?: boolean|function(HTMLLinkElement): boolean
* }} parameters
*/
constructor(parameters = {}) {
Expand All @@ -62,7 +64,8 @@ export default class Core {
transitions = {
default: Transition
},
reloadJsFilter = (element) => element.dataset.taxiReload !== undefined
reloadJsFilter = (element) => element.dataset.taxiReload !== undefined,
reloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined
} = parameters

this.renderers = renderers
Expand All @@ -71,6 +74,7 @@ export default class Core {
this.defaultTransition = this.transitions.default || Transition
this.wrapper = document.querySelector('[data-taxi]')
this.reloadJsFilter = reloadJsFilter
this.reloadCssFilter = reloadCssFilter
this.removeOldContent = removeOldContent
this.allowInterruption = allowInterruption
this.bypassCache = bypassCache
Expand Down Expand Up @@ -295,6 +299,10 @@ export default class Core {
this.loadScripts(entry.scripts)
}

if (this.reloadCssFilter) {
this.loadStyles(entry.styles)
}

// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL
if (trigger !== 'popstate' && url.raw !== entry.finalUrl) {
window.history.replaceState({}, '', entry.finalUrl)
Expand Down Expand Up @@ -341,6 +349,21 @@ export default class Core {
}
}

/**
* Load up styles from the target page if needed
*
* @param {HTMLLinkElement[]} cachedStyles
*/
loadStyles(cachedStyles) {
const currentStyles = Array.from(document.querySelectorAll('link[rel="stylesheet"]')).filter(this.reloadCssFilter)

cachedStyles.forEach(el => {
if (el.href && !currentStyles.find((link) => link.href === el.href)) {
document.body.append(el)
}
})
}

/**
* @private
* @param {string} links
Expand Down Expand Up @@ -516,6 +539,7 @@ export default class Core {
finalUrl: url,
skipCache: content.hasAttribute('data-taxi-nocache'),
scripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],
styles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel="stylesheet"]')).filter(this.reloadCssFilter) : [],
title: page.title,
renderer: new Renderer({
wrapper: this.wrapper,
Expand Down

0 comments on commit 55a27cc

Please sign in to comment.