Skip to content
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

URL anchors not handled #161

Closed
raf64flo opened this issue Jun 7, 2019 · 12 comments
Closed

URL anchors not handled #161

raf64flo opened this issue Jun 7, 2019 · 12 comments
Labels
duplicate Issue already been reported

Comments

@raf64flo
Copy link

raf64flo commented Jun 7, 2019

Hello,

I've a markdown document loaded from assets of the application (via remote src). The md file contains inner links via simple HTML anchors such as: a [name](#name)...

Those are not resolved correctly and links to the host root (ie. http://localhost:4000/#name) instead of keeping the page's URL, expecting : http://localhost:4000/help#name

I've tried to give it a specific baseUrl: '/help' (in app.module.ts), but no way to get it working.

Do you have any idea of what I could miss?

@jfcere
Copy link
Owner

jfcere commented Jun 7, 2019

Hi @raf64flo, using pure HTML anchor tag should fix your issue if it is an option ...

<a href="#name">Name</a>

I'll look further about the [name](#name) syntax but this is really something related to marked.js

@raf64flo
Copy link
Author

Hi @jfcere

Thanks for the suggestion, I've tried using a pure HTML anchor but the result is the same. As if the markdown builder did not resolve the route of the component when converting the markdown in HTML.

The only way to get the anchor as expected is to hard set the /help path in the markdown's anchor, but as it might be used in different paths, I'd prefer to only use inner anchors.

Is there anything to configure in the component for instance to make the markdown comply with the app's route?

@jfcere
Copy link
Owner

jfcere commented Jun 13, 2019

Sorry to hear that, I've been reallllllly busy recently but I should find some times to look at it soon.

@raf64flo
Copy link
Author

No need to apologize, thanks to provide such library, it is very useful and the documentation is a great help!

I'm struggling with another issue, but I believe it is related to the way I deploy the frontend assets in my Spring Boot app, because in development mode it works as a charm (minus the anchor issue), so I don't think if it worth to create another issue here.

@Razkaroth
Copy link

Razkaroth commented Jun 13, 2019 via email

@raf64flo
Copy link
Author

Good catch @Razkaroth indeed, I've given it some tries and my tests show that:

  • using standardized <a href="#name"> allows to scroll to the <div id="name"> but the browser back button is not handled correctly (ie. the URL fragment disappears, but we don't move back to the previous position in the page).
  • using <a routerLink=/help fragment=#name works as expected ONLY if we configure the Router to scroll to the fragment as following:
@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      scrollPositionRestoration: 'enabled',
      anchorScrolling: 'enabled',
    })
  ],
  exports: [RouterModule]
})

Source: https://medium.com/lacolaco-blog/introduce-router-scroller-in-angular-v6-1-ef34278461e9

Anyway, this would need to change the way HTML is generated by ngx-markdown and fetch the current route & context path. Perhaps by playing with platformLocation.pathname and router.url imported from:

import {PlatformLocation} from '@angular/common';
import {Router} from '@angular/router';

?

@Razkaroth
Copy link

Razkaroth commented Jun 15, 2019

@raf64flo I think that if you set the anchors as [text](/help#name), this renderer override might be a solution:

export function markedOptionsFactory(): MarkedOptions {
  const renderer = new MarkedRenderer();

  renderer.link = (href: string, title: string, text: string) => {
    if (href.startsWith('/')){
        const url = href.split('#')[0];
        const fragment = href.split('#')[1];
        
        return `<a routerLink=${url} fragment=#${fragment}>${text}</a>`;
    }
    return `<a href="${href}" target="_blank" rel="noopener noreferrer">${text}</a>`;
};
return {
    renderer: renderer
};
}

If it is a relative link, it uses routerLinks, otherwise, it goes ahead to a simple anchor tag.

@raf64flo
Copy link
Author

raf64flo commented Jun 17, 2019

@Razkaroth I fear the angular parsing comes before (at compilation time) the rendering of markdown (at runtime?), hence ignores the output of the renderer.

It produces safe angular syntax (if generated code is copied outside of <markdown> tag, it works), but the output HTML is ignored by the browser, only the value of ${text} is visible in the page.

Were you able to make this renderer generated code correctly interpreted by the angular compiler?

@raf64flo
Copy link
Author

I'm struggling with another issue, but I believe it is related to the way I deploy the frontend assets in my Spring Boot app, because in development mode it works as a charm (minus the anchor issue), so I don't think if it worth to create another issue here.

Indeed, I had a custom IndexFilter class on Spring Boot side which forwards all GET requests to non-static and non-api resources to index.html. This filter was necessary to support deep-linking for URLs generated by the Angular router, but .md was missing from the extension list...

I should be able to use remote loading of Markdown now! Even if this does not resolve the anchor issue.

@raf64flo
Copy link
Author

OK I've found a workaround even if it doesn't handle very well the HistoryBrowser (the back at top on the page after selecting an anchor is not done).

I've played with the renderer facility as following:

export function markedOptionsFactory(): MarkedOptions {

  const renderer = new MarkedRenderer();

  renderer.link = (href: string, title: string, text: string) => {
    if (href.startsWith('#')) {
      const fragment = href.split('#')[1];
      return `<a href="${location.pathname}#${fragment}">${text}</a>`;
    }
    return `<a href="${href}" target="_blank" >${text}</a>`;
  };
  return {
    renderer: renderer
  };
}

@maxime1992
Copy link
Contributor

Hi! Has anyone found a solution to this? I'm really stuck :(

@jfcere
Copy link
Owner

jfcere commented Jan 12, 2020

Closing for duplicate so that everybody can follow up and participate on the same issue.

Please refer to issue #125.

@jfcere jfcere closed this as completed Jan 12, 2020
@jfcere jfcere added the duplicate Issue already been reported label Jan 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate Issue already been reported
Projects
None yet
Development

No branches or pull requests

4 participants