Giter Club home page Giter Club logo

Comments (14)

developit avatar developit commented on July 19, 2024 6

@ShimShamSam String.protoype.link is provided by the browser, it's not modifiable. The reason we can't add global options like that is because the size impact would be enormous. Just for the snippet you posted, we'd have to add serialization support for arbitrary attributes, classify tokens as named entities ("link"), etc - essentially that would require an AST, and this module just can't afford that. The reason snarkdown is small is because of design decisions, not just compact code - breaking out of those design decisions/constraints makes it just another Markdown parser, and in that regard a fairly poor one.

Now that I'm maintaining a fair number of these micro-modules, I've been finding it difficult to explain the importance of constraints. Everyone has a set of features they want, and no two people want the same set. The problem is, a project with the goal of being minimal simply cannot accommodate the superset of features that would provide everyone with their desired features - that would make it a normal module, not a minimal one. There are already excellent Markdown parser modules out there that do these things better than Snarkdown - it's important to understand that small modules are by nature an exercise in tradeoff management.

from snarkdown.

ShimShamSam avatar ShimShamSam commented on July 19, 2024 5

I would go a step further and ask that we can also modify the link's rel attribute so we can add things like nofollow, noopener, etc...

from snarkdown.

developit avatar developit commented on July 19, 2024 4

FWIW here's a function that would do it after innerHTML:

div.innerHTML = snarkdown(md);
retarget(div);

function retarget(el) {
  if (el.nodeName==='A' && !el.target && el.origin!==location.origin) {
    el.setAttribute('target', '_blank');
    el.setAttribute('rel', 'noreferrer noopener');
  }
  for (let i=el.children.length; i--; ) retarget(el.children[i]);
}

Personally I think it's nice to be able to take advantage of DOM traversal here.

from snarkdown.

developit avatar developit commented on July 19, 2024 2

@abhishiv I like the idea, but it's probably impossible to convert tokens to nice function names like that given the filesize.

Currently it'd be like:

snarkdown(str, (md, html) => {
  return html.replace(/^<a /, '<a target="_blank" rel="nofollow" ')
});

edit: @tunnckoCore pretty much exactly what I was thinking haha. just would do it after all the blocks.

Just thinking though, you could pretty much apply that transformation anyway:

let html = snarkdown(md).replace(
    /(<a href="(https?:)?\/\/.*?")>/g,
    '$1 target="_blank" rel="nofollow">'
);

edit 2: here's Showdown's target="_blank" plugin

from snarkdown.

developit avatar developit commented on July 19, 2024 1

Seems like a good idea, though maybe a little bit presumptive? An option seems good.
Also, this library actually uses a little-known method String.prototype.link to generate HTML links with proper encoding, and there's no option to add attributes. Will have to switch to an inline creation in order to get the target attribute.
https://github.com/developit/snarkdown/blob/master/snarkdown.js#L82

FWIW I tend to pipe the output of this lib into something that converts the HTML to Virtual DOM, which makes it super easy to attach arbitrary behavior (and attributes) to any element.

from snarkdown.

ShimShamSam avatar ShimShamSam commented on July 19, 2024 1

If links are already being processed by their own logic (currently String.prototype.link), it makes sense to allow devs to hook into it. Running a regexp replace on the entire output to fix links seems inefficient.

Why not just add some global options to the parse function? Something like:

snarkdown(text, {
    links : {
        nofollow : true,
        noopener : true,
    }
});

from snarkdown.

developit avatar developit commented on July 19, 2024

@ShimShamSam yup - I had originally tested out a target change, but then realized target isn't good enough on it's own since that's actually a vulnerability without proper rel set.

I want to collect some use-cases here: are you guys piping the HTML straight into the DOM, or through something like a VDOM renderer?

from snarkdown.

ShimShamSam avatar ShimShamSam commented on July 19, 2024

I use templates for a project, not a virtual DOM, so I'm ultimately setting innerHTML directly.

from snarkdown.

developit avatar developit commented on July 19, 2024

Ah ok, that helps me understand. Maybe we can add something really low-level like a "chunk processor" API. Just thinking of ways to keep the size down. Issue I ran into immediately after adding target="_blank" was that it doesn't make sense for same-domain and #anchor links.

from snarkdown.

abhishiv avatar abhishiv commented on July 19, 2024

@developit yeah same for me, setting innerHTML.

What about a url builder?

  md.parse(str, {
    linkBuilder: function(href) {
      return {target: "_blank", rel: "nofollow"}
    }
  })

from snarkdown.

tunnckoCore avatar tunnckoCore commented on July 19, 2024

Yea maybe we can allow kinda "plugin" api. Just a function or array as second argument which will be passed with the token in final else {} (after all the if else-es)

edit: @abhishiv seems like a too much code :D but yea, maybe

from snarkdown.

tunnckoCore avatar tunnckoCore commented on July 19, 2024

Mm, maybe. I was thinking to pass the token array to that transform function, too. But, not sure because... nah.. maybe would need too much docs which token is what 😆

Just thinking though, you could pretty much apply that transformation anyway:

Yea.. So it just ends up that it should be enough to say (and emphasize somewhere) that Snarkdown does not do anything so magical and relies absolutely on RegExps, and so you can just continue to do regex things after it returns its result, haha.

edit: but yea, people likes "plugins", haha

from snarkdown.

ShimShamSam avatar ShimShamSam commented on July 19, 2024

String.protoype.link is provided by the browser, it's not modifiable.

I know that. What I meant was we already have branching logic that says "this is a link, do x". Being able to hook into that should be as easy as setting a few options. Are you open to a pull request so I can take a stab at it?

from snarkdown.

developit avatar developit commented on July 19, 2024

I'm always happy to review a PR, just I don't want to give you the impression it's going to be something we can necessarily merge. There's very little that can be done to mitigate the file size hit it will incur, which I am fairly certain makes it a non-starter.

from snarkdown.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.