Skip to content

Commit

Permalink
Merge pull request #60 from rolandschuetz/BUGFIX/node-with-hash-handling
Browse files Browse the repository at this point in the history
BUGFIX: Prevent the node editor from breaking for nodes with hashes
  • Loading branch information
Alvadda authored Jan 21, 2025
2 parents d27fbba + de2f695 commit 2722095
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 6 deletions.
9 changes: 9 additions & 0 deletions Neos.Ui/core/src/application/LinkTypes/Asset/Asset.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ describe('LinkType: Asset', () => {
.toBe(true);
});

it('is not satisfied by asset:// links with a hash', () => {
const link = {
href: 'asset://97c9a6e3-4b50-4559-9f60-b5ad68f25758#section'
};

expect(Asset.isSuitableFor(link))
.toBe(false);
});

it('is not satisfied by mailto: links', () => {
const link = {
href: 'mailto:[email protected]'
Expand Down
2 changes: 1 addition & 1 deletion Neos.Ui/core/src/application/LinkTypes/Asset/Asset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type AssetLinkModel = {
export const Asset = makeLinkType<AssetLinkModel>('Sitegeist.Archaeopteryx:Asset', ({createError}) => ({
supportedLinkOptions: ['title', 'targetBlank', 'relNofollow'],

isSuitableFor: (link: ILink) => link.href.startsWith('asset://'),
isSuitableFor: (link: ILink) => link.href.startsWith('asset://') && !link.href.includes('#'),

useResolvedModel: (link: ILink) => {
const match = /asset:\/\/(.*)/.exec(link.href);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
jest.mock('@neos-project/neos-ui-backend-connector', () => ({}), { virtual: true });
jest.mock('@neos-project/react-ui-components', () => ({}));
jest.mock('@sitegeist/archaeopteryx-custom-node-tree', () => ({}));
jest.mock('@neos-project/neos-ui-redux-store', () => ({}), { virtual: true });
jest.mock('@neos-project/neos-ui-editors', () => ({}), { virtual: true });

jest.mock('../../../presentation', () => ({}));

import '@testing-library/jest-dom/extend-expect';

import {CustomLink} from './CustomLink';


describe('LinkType: Node', () => {
it('is not satisfied by http:// links', () => {
const link = {
href: 'http://www.example.com'
};

expect(CustomLink.isSuitableFor(link))
.toBe(false);
});

it('is not satisfied by https:// links', () => {
const link = {
href: 'https://www.example.com'
};

expect(CustomLink.isSuitableFor(link))
.toBe(false);
});

it('is not satisfied by node:// links', () => {
const link = {
href: 'node://97c9a6e3-4b50-4559-9f60-b5ad68f25758'
};

expect(CustomLink.isSuitableFor(link))
.toBe(false);
});

it('is satisfied by node:// links with a hash', () => {
const link = {
href: 'node://97c9a6e3-4b50-4559-9f60-b5ad68f25758#section'
};

expect(CustomLink.isSuitableFor(link))
.toBe(true);
});

it('is not satisfied by asset:// links', () => {
const link = {
href: 'asset://97c9a6e3-4b50-4559-9f60-b5ad68f25758'
};

expect(CustomLink.isSuitableFor(link))
.toBe(false);
});

it('is satisfied by asset:// links with a hash', () => {
const link = {
href: 'asset://97c9a6e3-4b50-4559-9f60-b5ad68f25758#section'
};

expect(CustomLink.isSuitableFor(link))
.toBe(true);
});

it('is not satisfied by mailto: links', () => {
const link = {
href: 'mailto:[email protected]'
};

expect(CustomLink.isSuitableFor(link))
.toBe(false);
});

it('is satisfied by invalid links', () => {
const link = {
href: 'Think of Beethoven\'s 5th: foo foo foo bar'
};

expect(CustomLink.isSuitableFor(link))
.toBe(true);
});

it('is not satisfied by tel: links', () => {
const link = {
href: 'tel:+491258795857'
};

expect(CustomLink.isSuitableFor(link))
.toBe(false);
});
});
10 changes: 7 additions & 3 deletions Neos.Ui/core/src/application/LinkTypes/CustomLink/CustomLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ type CustomLinkModel = {
}

export const CustomLink = makeLinkType<CustomLinkModel>('Sitegeist.Archaeopteryx:CustomLink', ({createError}) => ({
isSuitableFor: (link: ILink) => !link.href.startsWith('asset://') && !link.href.startsWith('mailto:')
&& !link.href.startsWith('node://') && !link.href.startsWith('tel:')
&& !link.href.startsWith('http://') && !link.href.startsWith('https://'),
isSuitableFor: (link: ILink) => {
if ((link.href.startsWith('asset://') || link.href.startsWith('node://')) && link.href.includes('#')) {
return true;
}
return !link.href.startsWith('node://') && !link.href.startsWith('asset://') && !link.href.startsWith('mailto:')
&& !link.href.startsWith('tel:') && !link.href.startsWith('http://') && !link.href.startsWith('https://');
},

useResolvedModel: (link: ILink) => {
return Process.success({
Expand Down
9 changes: 9 additions & 0 deletions Neos.Ui/core/src/application/LinkTypes/Node/Node.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ describe('LinkType: Node', () => {
.toBe(true);
});

it('is not satisfied by node:// links with a hash', () => {
const link = {
href: 'node://97c9a6e3-4b50-4559-9f60-b5ad68f25758#section'
};

expect(Node.isSuitableFor(link))
.toBe(false);
});

it('is not satisfied by asset:// links', () => {
const link = {
href: 'asset://97c9a6e3-4b50-4559-9f60-b5ad68f25758'
Expand Down
2 changes: 1 addition & 1 deletion Neos.Ui/core/src/application/LinkTypes/Node/Node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const Node = makeLinkType<NodeLinkModel, NodeLinkOptions>(
({ createError }) => ({
supportedLinkOptions: ["anchor", "title", "targetBlank", "relNofollow"],

isSuitableFor: (link: ILink) => link.href.startsWith("node://"),
isSuitableFor: (link: ILink) => link.href.startsWith("node://") && !link.href.includes('#'),

useResolvedModel: (link: ILink) => {
const match = /node:\/\/(.*)/.exec(link.href);
Expand Down
9 changes: 9 additions & 0 deletions Neos.Ui/core/src/application/LinkTypes/Web/Web.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ describe('LinType: Web', () => {
.toBe(true);
});

it('is satisfied by https:// links with a hash', () => {
const link = {
href: 'https://www.example.com#section'
};

expect(Web.isSuitableFor(link))
.toBe(true);
});

it('is not satisfied by node:// links', () => {
const link = {
href: 'node://97c9a6e3-4b50-4559-9f60-b5ad68f25758'
Expand Down
2 changes: 1 addition & 1 deletion Resources/Public/JavaScript/Plugin.js

Large diffs are not rendered by default.

0 comments on commit 2722095

Please sign in to comment.