-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Add linksInNewTab config option of whether or not to open links in a new tab or not #659
Conversation
NTS: when finalized and merged go back to CDN (i.e. reverse |
👍 |
|
@chjj Could you please provide a reference? For me this seems to be not deprecated (e.g. on HTML5 Spec or W3Schools. Well of course there are lots of use cases where you want to open specific links (e.g. that were rendered via marked) in a new tab. For example I'm currently building a webapp where informations about documents are shown. These informations are written in Markdown and parsed with marked. However, if the user clicks on a link in the informations about a document he just wants to open that link in the foreground but don't want to leave the app completely (because he may want to open multiple documents). So in fact, this is a very important standard for me and I think for other too. |
@julmot, very interesting, the last time I looked at the whatwg spec (probably 2 or 3 years ago), target=_blank was deprecated. I'll reconsider. As a side node, I'd like to see the mailing list posts that got this back into the spec. |
Ok so can we integrate |
e.g. page content may not want it, user comments definetly want it. I wish github did it in issues/pull requests (but not README.md) so I don't lose my spot in a thread when checking out a related link. Since it doesn't change default behavior no one will be surprised and its there if they do end up needing it. If there is a better way than target="_blank" cool, we can just update this change later once that is discovered and everyone will start rendering the latest hotness :) |
This would be helpful, and what @drmuey says seems true (won't break prior code). 👍 |
Any updates on this? It is not the first time that this is a requirement for a project. |
I have some use cases where this would be helpful. Please read .. And then merge :) |
linksInNewTab is not working for me. Is there a later version that I'm supposed to install instead of the default version that comes when you npm install? |
Any chances to get this merged ? |
So, I need this and will be manually pulling code from this PR into a project. @chjj, if you need another use case, here's one: I'm working on a Sandstorm app package. Sandstorm runs web apps in a sandbox, and restricts their behavior in the frame in which they live. External links only work in Sandstorm apps if they open in a new tab, therefore, all links for this app must have this behavior. Code I am integrating from a non-Sandstorm version of this app uses marked.js, so in order for their code to work correctly in the Sandstorm version, I need this option. |
This is fixed due to @drmuey's markedjs/marked#659 which has not been merged with marked.js. I minified this change and pasted it into the minified version of the file originally included with the PR to Scrumblr, so only God knows what version of marked.js this now is.
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 have tested this PR in a project, and it works great and solves my problem.
Closing as stale, merge conflicts, and not sure if defined by targeted specs (see #956). |
It wouldn't be stale if it hadn't been ignored. This is a feature multiple projects have had to patch in as part of using this project. |
This is a key need, and really belongs on some sort of roadmap, even if this PR is now too old to be merged directly. |
@ocdtrekkie: Not ignored - the Marked project itself also went stale - see #956. Thank you for the feedback. Would you be willing to create an issue? Maybe link to where in the CommonMark or GFM specifications the |
ps. I'm also inclined, as appears to be @chjj (the owner of the project - see previous comment), to question why we would modify Markdown, in general, to have that capability. It begins to tighly couple (limit) Markdown to literal HTML output and would want to see the discussion around that decision. |
chjj's primary concern above was whether or not target="_blank" was deprecated. It's still the way things are done today though, and other commenters satisfactorily responded that it was not. My point is primarily usability: A significant percentage of people parsing content with Markdown will be doing so inside apps that process user content... where they are likely to want to be able to implement Open in New Tab. As designed, this feature:
It is hard to argue that an optional feature "tightly couples" or "limits" the project in any way, especially when there's significant practical use for the feature. I mean, to be honest, I don't have the time to invest significantly in pursuing and arguing this further, but a "mark as stale and close" something with significant user interest and impact, despite being offered up as a PR that worked as it was, was something that warranted commentary. |
Out of curiosity, what would you expect Marked users who require this functionality to do to solve this issue other than add this option? |
@ocdtrekkie: That's fair regarding not wanting to make the time to argue it further; having said that, my natural curiosity requires me to ask: Why open the can then?
If one of the specs had something like a flag to set it might be a different subject.
But, I don't think that will happen anytime soon because it takes Markdown from being a generic way to markup a document (without HTML) and turns it into a way to write HTML specifically. imho |
I'm one of those people who had to monkeypatch the marked.Renderer link function to add target="_blank". I can live with my monkeypatch, though of course if the link function is changed significantly then my code will break. @joshbruce You might have lots of downloads, and not hear much about this issue, because this is sort of a low-level library, so when it's used, it's just kind of buried deep in a project. Not many people rummage around in the config options of all their included libraries to look for one specific option. Also, about the UI history of _blank -- yes, it can be abused, and has been. However, here's my use-case: I want to use it site-wide on my site where links are for help, and are not the kind of link where I'm possibly sending the user away to read another tangential article from my own. |
@christiansimms: I concur with the low-level assessment - and why the downloads might be high despite people not even being aware they are using it. So far, the hope is to keep it that way - #965. Of course, that also gives us more reason not to include features that go too far afield of the specs - for better or worse. All the changes we are making now are done with the hope of maintaining backward compatibility. We also have plans to make Marked a little bit easier to customize - maybe the target blank possibility could be there. Thank you for the use case. What's the rationale behind using Marked to do that during processing instead of something like this after the fact: document.getElementsByTagName('a').forEach(function(elem) {
elem.setAttribute('target', '_blank');
}); Not tested or anything, just asking the question. This way the functionality of setting target blank is completely independent of Marked...you could grab a different Markdown processor and not have to change that bit?? And, of course, you can add exclusion logic and cases. Again, just curious to gain a better understanding of the rationale behind the choice to use Marked for this functionality. |
@joshbruce Again, I don't see any sense or reason in your justification of "keeping people unaware they are using it", as a reason to neglect a completely optional feature that has no effect by default. Similarly, there is no backward compatibility concern for a feature that explicitly requires the developer enable it, by setting an option flag that didn't exist before. I also specified my use case over a year ago, and it is similarly not for "ego" reasons: I ported an app that uses Marked (called Scrumblr) over to Sandstorm.io, a platform for web apps, where the apps operate inside a frame. Sandstorm.io does not permit external links or content in the frame for security reasons, so external links only actually work if they have target="_blank". Your solution may work, I don't know. I am not super familiar with Scrumblr's code to begin with. This PR was an incredibly easy to use solution to the problem at hand. |
@ocdtrekkie: My reply was mainly for @christiansimms to gain better understanding for his use case and rationale, apologies for not making that more clear. Having said that, have I fundamentally wronged you in some way here? You seem awful antagonistic and I'm trying to figure out why. You appear to be trying to make this personal (happens a lot in our industry, unfortunately). As though I said, "Oh, he wants it, therefore, I'm just gonna close it." And your language choice of "your justification" - "your solution" and so on further seems to bring up feelings of "making it personal". I also never said I wanted to "keep people unaware" - I was agreeing with @christiansimms that most people, in general, just are simply unaware; and that Marked is a low-level library with a single responsibility (SOLID). Further, we do have plans to make it more open to extension; therefore, someone can create a wrapper to customize the output...as opposed to asking Marked to do more than quickly and accurately comply with various Markdown specifications. I don't know what battles you are fighting but this one doesn't seem to be with me. (I also wasn't here a year ago and have read, reviewed, triaged, closed, and merged over 600 issues and PRs in the last ~45 days with help from some wonderful contributors; so, please afford me - and us - the courtesy of at least a respectful and civil discourse - I don't have to be here trying to help ressurect this project or community - and neither do any of the rest of us. We can all go back to not getting any new releases and having over 700 issues and 300+ PRs. Thank you for your consideration on this matter.) I don't know anything about Sandstorm.io and how it works; therefore, I am unable to help on that score. Having said that, it's definitely something to consider once we get beyond the hurdles of complying with CommonMark and GFM (0.4.0 milestone) and move into the 0.5.0 milestone. Maybe @Feder1co5oave, @UziTech, or @KostyaTretyak can be of assistance - again, as I don't know Sandstorm.io at all, but definitely understand the security desire...having said that, if a simple target blank can make it happen, I do question how secure that really is. |
I am not attempting to be antagonistic, but you seem to be repeatedly bringing up justifications for not implementing this feature that are not accurate. (Such as backwards compatibility being a concern with a feature that is 100% backwards compatible with existing users since it does nothing unless explicitly set.) "Your justification" and "your solution" is hardly an antagonistic language choice, I was referring to your justification and your solution, which hence, uses the pronoun "your". (As opposed to something like "the" solution, which would sound like a definitive result, which does not exist in a discussion.) The point of target=_blank being required in Sandstorm is that anything inside the Sandstorm frame should be on Sandstorm's server. If an external page could be present inside Sandstorm, it could emulate the app you are using, while actually being on someone else's server. Mind you, the point is less that "target=_blank is important for security", so much that it is "target=_blank is needed for external links to work in Sandstorm", as an explanation for why I need it. This was important to explain because you seemed to suggest (if I may argue, slightly antagonistically) that the primary use case for target=_blank may be "for lack of a better term, ego". |
Note that I understand you are trying to get this project back on track, and I sympathize with the amount of work you are going through. I just think this issue should not have been closed, when it significantly deserves revisiting, and while merge conflicts exist for this PR, it is likely this PR would be the base of any resubmission of this feature that is merge-able with the current version. |
Also, since it's exceedingly small of a patch, I compared the code of this PR to the current version of Marked: The merge conflict is in the readme, specifically that since this PR was made documentation of the xhtml: option was added in the same spot the linksinNewTab option would also be documented. There is no code conflict. |
Oh, also where defaults are set, the baseUrl: has been added since, where linksinNewTab: is added as well. But again, these aren't really code conflicts, such as a minor editing issue since the PR is so old. https://github.com/chjj/marked/blob/master/lib/marked.js#L1333 |
@joshbruce Yes your post-processing code should work. However, I'm using a JavaScript framework (Angular here, but there are similar others like Vue) and wrote a component which runs marked. In general with these frameworks, you're not supposed to directly change the Html (since these frameworks do low-level things to the html inside the browser, like virtual Dom, making intermediate html tags/attributes, etc.). |
Thank @ocdtrekkie - I understand that you don't believe it should have been closed. Having said that, ultimately, I do and do kind of act as a tie breaker.
If you would like this functionality, create an Issue and we can consider the proposal. Until then, the decision to close this PR will stand for a combination of reasons. Another submitter of a PR that got closed in the last wave made the comment that he could not justify keeping the branch alive and up to date since there was no movement (notice the submitter, @drmuey, is not here making the arguments or fixes to the PR?). (Apologies, but now it's my turn to be slightly atagonistic, I thought you didn't have time for this? Yet here we are.) @christiansimms: Thanks. Yeah. My project uses Angular right now and we are going to be using SimpleMDE as an editor - SimpleMDE uses Marked. I try to adhere to what I call the community principle (if you create or acquire it, you help maintain it) - that's why I came here actually. That sounds like an interesting component. I thought Angular components lived in the shadow DOM (or whatever marketing is calling it these days). Therefore, we should still have the ability to observe and respond to click events - at which point we don't need target blank in the anchor - instead could use prevent default and go from there. Can you post a Gist? |
Well, I don't have a way to address point 3, but point 4 is now in #1030. |
@ocdtrekkie: Saw that. Thank you very much! Will label it shortly. |
@joshbruce I am trying to figure out how to make a test. Is it just to have a .md file that implements the feature, and then the .html being an output of it? The Smartypants test (https://raw.githubusercontent.com/chjj/marked/master/test/new/smartypants.md) seems to document how to enable an option, so this should be easy to add. |
Happy to freshen the pull request so it's clean and add tests (I didn't see PR requirements doc, apologies). Regarding UX:
Regarding MD specs:
|
@joshbruce I made a simplemde component, it's here: SimpleMDEComponent. As for your idea of overriding click events -- I don't think I can. My use case is: trusted users create Markdown content using SimpleMDE, and I save that in a database. Later, other users view the Html rendering of that content. That's when I want to change the link behavior. I use marked to dump the html rendering into the browser. That rendering is sort of an opaque blob (I just jam the whole thing as one big string to [innerHTML]), so I cannot intercept click events using Angular. (Unless I use jQuery to post-process displayed Html, which they recommend against in Angular.) |
@drmuey: Can you confirm, this is an all or nothing solution as well? (Also see #1030, if you haven't already.) Appreciate the verification regarding a config setting - not part of a spec. Our focus right now, per #956, is on complying with specs - not new features; so, this gives us time to consider and weigh the options. One of the things I noticed from reading all the issues related to why Marked went stale is that it seemed like we started adding a lot of new features - those features started introducing bugs and whatnot. This seems to have overwhelmed the community; so, it makes me slightly concerned about extending too far beyond the specs - none of us really has time to mantain a library that can do all things for all people (for lack of a better way of saying it). Having said that, we've added #1030 to the 0.5.0 milestone, which will begin ramping up after the 0.4.0 milestone is sorted (no known issues with CommonMark and GFM). @christiansimms: Is this the code (or component) you would like this functionality to exist? |
@joshbruce Sorry that code is not directly using marked, I just linked it because you said you were thinking about using SimpleMDE in the future. My code which uses marked is in that same repository, but not easily linked (it's actually just a function and not a real Angular component by itself), and I'm sure you're busy. I tried to explain how I use marked, and believe it's a common way that people use it. Just trying to explain why I hope this feature is eventually added. |
We seem to be creating conflict over breadcrums guys 😆 @joshbruce is right about one thing: it's better to decouple as mush as possible marked from the generation of html code. We should focus on parsing, and that's what specifications are about. In fact they never dictate how to generate html, but disambiguate how markdown code is to be interpreted into an abstract syntax tree. From that, you then generate output however you want. Renderers are good. They allow you to change the way marked generates html code. The simpler the default renderer, the easier it is to override it. var renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
var out = marked.Renderer.prototype.link.apply(this, arguments);
return out.replace(/^<a/, '<a target="_blank"');
} But this is ugly. So let's say we add the Yet, this is a feature being requested since a long time ago. And it doesn't change the default behavior. I personally would never use it as it is. I hate when new tabs are opened without a good reasons. But it is sometimes logical to open a link in a new tab. For example if it is an external link. So if we decide to merge this, why not empower it and provide a regex as an alternative to a simple boolean, such that when links match the regex, they get opened in a new tab? Too much? |
I tested locally in the project I wanted to use this with:
setOptions
: links opens in a new tab/windowsetOptions
: links open in the same tab/windowAlso, checked the README entry by looking at it on github.
Unit tests would be nice but I don't have time to grok how the tests work in this repo and other stuff is also not unit tested (e.g.
smartLists
)