Skip to content

Commit

Permalink
Merge pull request #51 from pinecone-router/fix-directives-order
Browse files Browse the repository at this point in the history
Fix directives being dependent on attributes order
  • Loading branch information
rehhouari authored Feb 10, 2025
2 parents 47cf824 + 9de4dcd commit 6631781
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 91 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [5.4.0] - 2025-02-10

### Fixed

- Fixed run order of directives, x-route > x-handler > x-template. no longer dependent on attribute order.
- This fixes errors due to automatic attribute ordering when doing an astro build.

## [5.3.0] - 2025-02-04

### Changed
Expand Down Expand Up @@ -412,3 +419,4 @@ It's mostly backward compatible but need a few tweaks:
[5.2.1]: https://github.com/pinecone-router/router/compare/5.2.0..5.2.1
[5.2.2]: https://github.com/pinecone-router/router/compare/5.2.1..5.2.2
[5.3.0]: https://github.com/pinecone-router/router/compare/5.2.2..5.3.0
[5.4.0]: https://github.com/pinecone-router/router/compare/5.3.0..5.4.0
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<img src="https://github.com/pinecone-router/router/blob/main/.github/pinecone-router-social-card-alt-big.png?raw=true" title="Pinecone Router logo with the text: The extendable client-side router for Alpine.js">
</p>

[![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/pinecone-router/router?color=%2337C8AB&label=version&sort=semver)](https://github.com/pinecone-router/router/tree/5.3.0)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/pinecone-router?color=37C8AB)](https://bundlephobia.com/result?p=pinecone-router@5.3.0)
[![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/pinecone-router/router?color=%2337C8AB&label=version&sort=semver)](https://github.com/pinecone-router/router/tree/5.4.0)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/pinecone-router?color=37C8AB)](https://bundlephobia.com/result?p=pinecone-router@5.4.0)
[![Downloads from JSDelivr](https://data.jsdelivr.com/v1/package/npm/pinecone-router/badge?style=rounded)](https://www.jsdelivr.com/package/npm/pinecone-router)
[![npm](https://img.shields.io/npm/dm/pinecone-router?color=37C8AB&label=npm&logo=npm&logoColor=37C8AB)](https://npmjs.com/package/pinecone-router)
[![Changelog](https://img.shields.io/badge/change-log-%2337C8AB)](/CHANGELOG.md)
Expand Down Expand Up @@ -38,13 +38,13 @@ An easy to use but feature-packed router for Alpine.js.
Include the following `<script>` tag in the `<head>` of your document, **before Alpine.js**:

```html
<script src="https://cdn.jsdelivr.net/npm/pinecone-router@5.3.0/dist/router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pinecone-router@5.4.0/dist/router.min.js"></script>
```

**ES6 Module on the browser:**

```javascript
import PineconeRouter from 'https://cdn.jsdelivr.net/npm/pinecone-router@5.3.0/dist/router.esm.js'
import PineconeRouter from 'https://cdn.jsdelivr.net/npm/pinecone-router@5.4.0/dist/router.esm.js'
import Alpine from 'https://esm.sh/alpinejs'
Alpine.plugin(PineconeRouter)
Alpine.start()
Expand Down
2 changes: 1 addition & 1 deletion dist/router.esm.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/router.esm.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/router.min.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/router.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "The extendable client-side router for Alpine.js.",
"license": "MIT",
"author": "Rafik El Hadi Houari <[email protected]>",
"version": "5.3.0",
"version": "5.4.0",
"repository": {
"type": "git",
"url": "https://github.com/pinecone-router/router"
Expand Down
156 changes: 78 additions & 78 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ declare global {

export default function (Alpine) {
const PineconeRouter = Alpine.reactive(<Window['PineconeRouter']>{
version: '5.3.0',
version: '5.4.0',
name: 'pinecone-router',

settings: <Settings>{
Expand Down Expand Up @@ -282,69 +282,78 @@ export default function (Alpine) {
}

Alpine.directive(
'route',
'template',
(
el: HTMLTemplateElement,
{ expression, modifiers },
{ effect, cleanup },
{ modifiers, expression },
{ Alpine, effect, evaluate, cleanup },
) => {
let path = expression
if (!el._x_PineconeRouter_route)
throw new Error(
'Pinecone Router: x-template must be used on the same element as x-route.',
)

middleware('onBeforeRouteProcessed', el, path)
if (el.content.firstElementChild != null)
throw new Error(
'Pinecone Router: x-template cannot be used alongside an inline template (template element should not have a child).',
)

if (path.indexOf('#') > -1) {
if (
!(expression.startsWith('[') && expression.endsWith(']')) &&
!(expression.startsWith('Array(') && expression.endsWith(')'))
) {
expression = `['${expression}']`
}

let evaluatedExpression = evaluate(expression)

let urls: string[]

if (typeof evaluatedExpression == 'object')
urls = evaluatedExpression
else {
throw new Error(
`Pinecone Router: A route's path may not have a hash character.`,
`Pinecone Router: Invalid template type: ${typeof evaluatedExpression}.`,
)
}

let target =
modifierValue(modifiers, 'target', null) ??
window.PineconeRouter.settings.templateTargetId
let targetEl = document.getElementById(target)

if (target && !targetEl)
throw new Error(
"Pinecone Router: Can't find an element with the suplied target ID: " +
target +
'',
)

let routeIndex = null

if (path != 'notfound') {
// if specified add the basePath
path = addBasePath(path)
// register the new route if possible
routeIndex = PineconeRouter.add(path)
if (modifiers.includes('preload')) {
loadAll(el, urls, false)
}

// add template to the route
let path = el._x_PineconeRouter_route
let route =
PineconeRouter.routes[routeIndex] ?? PineconeRouter.notfound

// set the path in the element so it is used by other directives
el._x_PineconeRouter_route = path
path == 'notfound'
? PineconeRouter.notfound
: PineconeRouter.routes[findRouteIndex(path)]
route.templates = urls

if (el.content.firstElementChild != null) {
Alpine.nextTick(() => {
effect(() => {
let found =
route.handlersDone &&
PineconeRouter.context.route == path
found
? showAll(el, expression, null, targetEl)
: hide(el)
})
Alpine.nextTick(() => {
effect(() => {
let found =
route.handlersDone &&
PineconeRouter.context.route == route.path
found ? showAll(el, expression, urls, targetEl) : hide(el)
})
}
})

cleanup(() => {
el._x_PineconeRouter_undoTemplate &&
el._x_PineconeRouter_undoTemplate()
PineconeRouter.remove(path)
delete el._x_PineconeRouter_route
})

middleware('onAfterRouteProcessed', el, path)
},
)

Expand Down Expand Up @@ -394,83 +403,74 @@ export default function (Alpine) {
route.handlersDone = true
route.cancelHandlers = false
})
})
}).before('template')

Alpine.directive(
'template',
'route',
(
el: HTMLTemplateElement,
{ modifiers, expression },
{ Alpine, effect, evaluate, cleanup },
{ expression, modifiers },
{ effect, cleanup },
) => {
if (!el._x_PineconeRouter_route)
throw new Error(
'Pinecone Router: x-template must be used on the same element as x-route.',
)

if (el.content.firstElementChild != null)
throw new Error(
'Pinecone Router: x-template cannot be used alongside an inline template (template element should not have a child).',
)

if (
!(expression.startsWith('[') && expression.endsWith(']')) &&
!(expression.startsWith('Array(') && expression.endsWith(')'))
) {
expression = `['${expression}']`
}

let evaluatedExpression = evaluate(expression)
let path = expression

let urls: string[]
middleware('onBeforeRouteProcessed', el, path)

if (typeof evaluatedExpression == 'object')
urls = evaluatedExpression
else {
if (path.indexOf('#') > -1) {
throw new Error(
`Pinecone Router: Invalid handler type: ${typeof evaluatedExpression}.`,
`Pinecone Router: A route's path may not have a hash character.`,
)
}

let target =
modifierValue(modifiers, 'target', null) ??
window.PineconeRouter.settings.templateTargetId
let targetEl = document.getElementById(target)

if (target && !targetEl)
throw new Error(
"Pinecone Router: Can't find an element with the suplied target ID: " +
target +
'',
)

if (modifiers.includes('preload')) {
loadAll(el, urls, false)
let routeIndex = null

if (path != 'notfound') {
// if specified add the basePath
path = addBasePath(path)
// register the new route if possible
routeIndex = PineconeRouter.add(path)
}

// add template to the route
let path = el._x_PineconeRouter_route
let route =
path == 'notfound'
? PineconeRouter.notfound
: PineconeRouter.routes[findRouteIndex(path)]
route.templates = urls
PineconeRouter.routes[routeIndex] ?? PineconeRouter.notfound

Alpine.nextTick(() => {
effect(() => {
let found =
route.handlersDone &&
PineconeRouter.context.route == route.path
found ? showAll(el, expression, urls, targetEl) : hide(el)
// set the path in the element so it is used by other directives
el._x_PineconeRouter_route = path

if (el.content.firstElementChild != null) {
Alpine.nextTick(() => {
effect(() => {
let found =
route.handlersDone &&
PineconeRouter.context.route == path
found
? showAll(el, expression, null, targetEl)
: hide(el)
})
})
})
}

cleanup(() => {
el._x_PineconeRouter_undoTemplate &&
el._x_PineconeRouter_undoTemplate()
PineconeRouter.remove(path)
delete el._x_PineconeRouter_route
})

middleware('onAfterRouteProcessed', el, path)
},
)
).before('handler')

Alpine.$router = PineconeRouter.context
Alpine.magic('router', () => PineconeRouter.context)
Expand Down

0 comments on commit 6631781

Please sign in to comment.