Skip to content

Commit

Permalink
Changes in the updatePageLinks logic. Value for data-navigo and ignor…
Browse files Browse the repository at this point in the history
…ing target=_blank links #263
  • Loading branch information
Krasimir Tsonev committed Jan 13, 2021
1 parent f95258f commit d3e0ec2
Show file tree
Hide file tree
Showing 14 changed files with 163 additions and 19 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 8.5.0

* `data-navigo` now accepts a `"false"` (as string) argument.
* links with `target="_blank"` are ignored.

## 8.4.4

ES build. Fixing #261.
Expand Down
7 changes: 7 additions & 0 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- [Removing a route](#removing-a-route)
- [Navigating between routes](#navigating-between-routes)
- [Augment your `<a>` tags](#augment-your-a-tags)
- [`data-navigo` with value](#data-navigo-with-value)
- [Passing options to the `navigate` method](#passing-options-to-the-navigate-method)
- [Resolving routes](#resolving-routes)
- [Resolve options](#resolve-options)
Expand Down Expand Up @@ -317,6 +318,12 @@ When Navigo is initialized checks the page for such tags and attaches `click` ha

Navigo has a method called `updatePageLinks` which you have to call every time when you change the DOM and you expect to see new links on the page. Because Navigo is not wired to a rendering engine doesn't really know about the DOM manipulations. It does though makes an assumption - after each of your route handlers there is a `updatePageLinks` call. The router expects that after the successful route resolving the DOM is updated and calls that function again. Feel free to fire `updatePageLinks` multiple times on the same DOM tree. There will be just one `click` handler attached to your links.

*Links with `target="_blank"` are ignored even if they have `data-navigo` attribute.*

### `data-navigo` with value

If you use `data-navigo="false"` the link will be ignored by Navigo and if there was a click handler for it the handler will be removed.

### Passing options to the `navigate` method

As we learned above, when a link with `data-navigo` attribute is clicked the `navigate` method of the router gets executed. That same method accepts options and if you want to pass some of them use the following syntax:
Expand Down
17 changes: 14 additions & 3 deletions lib/es/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,18 @@ function Navigo(appRoute, resolveOptions) {
function updatePageLinks() {
if (!isWindowAvailable) return;
findLinks().forEach(function (link) {
if ("false" === link.getAttribute("data-navigo") || "_blank" === link.getAttribute("target")) {
if (link.hasListenerAttached) {
link.removeEventListener("click", link.navigoHandler);
}

return;
}

if (!link.hasListenerAttached) {
link.addEventListener("click", function (e) {
link.hasListenerAttached = true;

link.navigoHandler = function (e) {
if ((e.ctrlKey || e.metaKey) && e.target.tagName.toLowerCase() === "a") {
return false;
}
Expand All @@ -195,8 +205,9 @@ function Navigo(appRoute, resolveOptions) {
e.stopPropagation();
self.navigate((0, _utils.clean)(location), options);
}
});
link.hasListenerAttached = true;
};

link.addEventListener("click", link.navigoHandler);
}
});
return self;
Expand Down
17 changes: 14 additions & 3 deletions lib/navigo.amd.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/navigo.amd.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/navigo.amd.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/navigo.amd.min.js.map

Large diffs are not rendered by default.

17 changes: 14 additions & 3 deletions lib/navigo.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/navigo.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/navigo.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/navigo.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
@@ -1,6 +1,6 @@
{
"name": "navigo",
"version": "8.4.4",
"version": "8.5.0",
"description": "A simple vanilla JavaScript router",
"main": "lib/navigo.js",
"browser": "lib/navigo.min.js",
Expand Down
89 changes: 89 additions & 0 deletions src/__tests__/updatePageLinks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,4 +264,93 @@ describe("Given the Navigo library", () => {
}, 50);
});
});
describe("when the value of data-navigo is set to `false`", () => {
it("should skip the link", () => {
const querySelectorAll = jest.spyOn(document, "querySelectorAll");
let handler;

// @ts-ignore
querySelectorAll.mockImplementationOnce(() => {
return [
{
addEventListener(eventType, h) {
handler = h;
},
getAttribute(attr) {
if (attr === "href") {
return "/foo/bar";
} else if (attr === "data-navigo") {
return "false";
}
},
},
];
});

new Navigo("/app");

expect(handler).toEqual(undefined);
querySelectorAll.mockRestore();
});
});
describe("when set data-navigo to `false` later on", () => {
it("should remove the listener from the link", () => {
const querySelectorAll = jest.spyOn(document, "querySelectorAll");
let count = 0;
const addEventListener = jest.fn();
const removeEventListener = jest.fn();
const link = {
addEventListener,
removeEventListener,
getAttribute(attr) {
count += 1;
if (attr === "href") {
return "/foo/bar";
} else if (attr === "data-navigo") {
if (count === 1) return "";
return "false";
}
},
};

// @ts-ignore
querySelectorAll.mockImplementation(() => [link]);

const r: NavigoRouter = new Navigo("/app");
r.updatePageLinks();

expect(addEventListener).toBeCalledTimes(1);
expect(removeEventListener).toBeCalledTimes(1);
querySelectorAll.mockRestore();
});
});
describe('when we have `target="_blank"` attribute', () => {
it("should skip the link", () => {
const querySelectorAll = jest.spyOn(document, "querySelectorAll");
let handler;

// @ts-ignore
querySelectorAll.mockImplementationOnce(() => {
return [
{
addEventListener(eventType, h) {
handler = h;
},
getAttribute(attr) {
if (attr === "href") {
return "/foo/bar";
} else if (attr === "target") {
return "_blank";
}
},
},
];
});

new Navigo("/app");

expect(handler).toEqual(undefined);
querySelectorAll.mockRestore();
});
});
});
16 changes: 13 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,18 @@ export default function Navigo(
function updatePageLinks() {
if (!isWindowAvailable) return;
findLinks().forEach((link) => {
if (
"false" === link.getAttribute("data-navigo") ||
"_blank" === link.getAttribute("target")
) {
if (link.hasListenerAttached) {
link.removeEventListener("click", link.navigoHandler);
}
return;
}
if (!link.hasListenerAttached) {
link.addEventListener("click", function (e) {
link.hasListenerAttached = true;
link.navigoHandler = function (e) {
if (
(e.ctrlKey || e.metaKey) &&
e.target.tagName.toLowerCase() === "a"
Expand All @@ -233,8 +243,8 @@ export default function Navigo(
e.stopPropagation();
self.navigate(clean(location), options);
}
});
link.hasListenerAttached = true;
};
link.addEventListener("click", link.navigoHandler);
}
});
return self;
Expand Down

0 comments on commit d3e0ec2

Please sign in to comment.