-
Notifications
You must be signed in to change notification settings - Fork 66
Normalize Sample Code URLs #979
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
marinaaisa
merged 6 commits into
swiftlang:main
from
marinaaisa:normalize-sample-code-url
Dec 10, 2025
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
34894e2
Normalize URL for CallToActionButton
marinaaisa 3101331
Add linksToAsset prop
marinaaisa bd04024
Apply linksToAsset to DownloadButton in Sample code
marinaaisa 226e773
Add isAbsoluteUrl helper function
marinaaisa 5a7aa9a
Normalize relative path
marinaaisa f910276
Add new test for simple-relative paths
marinaaisa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ import TechnologiesQueryParams from 'docc-render/constants/TechnologiesQueryPara | |
| let areEquivalentLocations; | ||
| let buildUrl; | ||
| let resolveAbsoluteUrl; | ||
| let isAbsoluteUrl; | ||
|
|
||
| const normalizePathMock = jest.fn().mockImplementation(n => n); | ||
|
|
||
|
|
@@ -29,6 +30,7 @@ function importDeps() { | |
| areEquivalentLocations, | ||
| buildUrl, | ||
| resolveAbsoluteUrl, | ||
| isAbsoluteUrl, | ||
| // eslint-disable-next-line global-require | ||
| } = require('@/utils/url-helper')); | ||
| } | ||
|
|
@@ -185,3 +187,35 @@ describe('resolveAbsoluteUrl', () => { | |
| .toBe('https://swift.org/foo/bar'); | ||
| }); | ||
| }); | ||
|
|
||
| describe('isAbsoluteUrl', () => { | ||
| beforeEach(() => { | ||
| importDeps(); | ||
| jest.clearAllMocks(); | ||
| }); | ||
|
|
||
| it('returns true for absolute URLs', () => { | ||
| expect(isAbsoluteUrl('https://example.com')).toBe(true); | ||
| expect(isAbsoluteUrl('https://example.com/path')).toBe(true); | ||
| }); | ||
|
|
||
| it('returns true for other protocol schemes', () => { | ||
| expect(isAbsoluteUrl('mailto:[email protected]')).toBe(true); | ||
| expect(isAbsoluteUrl('tel:+1234567890')).toBe(true); | ||
| }); | ||
|
|
||
| it('returns false for relative paths starting with /', () => { | ||
| expect(isAbsoluteUrl('/relative/path')).toBe(false); | ||
| expect(isAbsoluteUrl('/')).toBe(false); | ||
| }); | ||
|
|
||
| it('returns false for relative paths not starting with /', () => { | ||
| expect(isAbsoluteUrl('relative/path')).toBe(false); | ||
| expect(isAbsoluteUrl('./current/path')).toBe(false); | ||
| }); | ||
|
|
||
| it('returns false for empty or invalid URLs', () => { | ||
| expect(isAbsoluteUrl('')).toBe(false); | ||
| expect(isAbsoluteUrl('not-a-valid-url')).toBe(false); | ||
| }); | ||
| }); | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we even need to check for special flags or absolute URLs as a special case here? I think the logic should pretty much match up with the logic in components for image and video assets, which always "normalize" the URLs. I think the
normalizePathfunction should already be a noop for absolute URLs, and I don't think there's any special logic for assets vs documents with regards to a custom base path.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the
normalizePathfunction to work, the path needs to be relative. This means that we need to normalize the relative path first, to make sure that thenormalizePathfunction reads it as a relative path.An example is the
simpleRelativePathconst that I wrote in the tests, which value isfoo/bar:foo/barneeds to be normalize as a relative path to become/foo/barinstead.Otherwise
normalizePathwill think thatfoo/baris an absolute URL and it won't prefix thebaseUrl.The reason why I'm exiting early in the case of being a real absolute URL (by using the
isAbsoluteUrlfunction) is that, if we pass an absolute URL tonormalizeRelativePath, it will turn it into a relative path like/website.com/samplecodeand thennormalizePathwill prefix that path asbaseUrl/website.com/samplecode. We want to prevent this scenario.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative to this is to use the
isAbsoluteUrlfunction within thenormalizeRelativePath, so we will never accidentally turn an absolute URL into a relative path.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that's an issue for the existing
normalizePathfunction or we would have hit similar issues with external image/video assets where we already call this function on all URLs.Here's an example unit test showing the expected behavior for this function when called with an absolute URL:
swift-docc-render/tests/unit/utils/assets.spec.js
Line 68 in c781d37
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test is showing the expected behaviour for absolute URLs (like
website.com/samplecode), but by normalising the relative path it adds a slash in the URL (like/website.com/samplecode) and we want to prevent this.This works for images and videos, because we expect the relative path to always be correct. So we don't normalise the relative path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An absolute URL should have a scheme like https://website.com/samplecode.
We do already normalize relative paths for images/videos in that function by prepending the base URL (example). Absolute URLs with a scheme would be unaffected by this
normalizePathfunction as shown in the above linked unit test.I think the confusion is that we also have a different
normalizeRelativePathfunction (seen below in those tests) which normalizes relative paths to all be root relative (some/path=>/some/path).We can utilize both here as you've done, although it's slightly unfortunate if we're getting different styles of relative paths for sample code when compared to images/videos in the JSON.