laobubu / HyperMD

A WYSIWYG Markdown Editor for browsers. Break the Wall between writing and previewing.
MIT License
1.47k stars 137 forks source link

fold addon: be able to do custom action on click #20

Closed nokola closed 6 years ago

nokola commented 6 years ago

In fold.js supports Ctrl+click to open links, and "break mark" for images.

// current behavior: around line 214 in fold.js:
    img.addEventListener("click", function (ev) {
      if (ev.ctrlKey || ev.altKey) {
        window.open(url, "_blank")
        ev.preventDefault()
        return
      }
      breakMark(cm, marker, 1)
      cm.focus()
    }, false)

With small extension in fold.js, it will make it possible to support thumbnail scenarios. For example I'm looking to support this:

  1. Person drag-drops BigFile.jpg into code editor
  2. Using the new insert-file.ts addon we discussed, I create BigFilethumb.jpg and BigFile.jpg I upload both files to server, but in markdown show:
  3. Person clicks on bigfilethumb.jpg's image in HyperMD --> the editor opens full resolution BigFile.jpg If person uses Ctrl+click, we show the text.

To have universal solution, perhaps we add the option to have click handled in options like this?

const cm = CodeMirror(myDiv, {
...
   hmdFold: {
      click: (type: "link" | "image", url: string, ev: KeyboardEvent): boolean
   }

click() handler will return true if it handles the event, and no further processing is needed click() handler returns false to show codemirror test (the "breakMark(...)" code will execute)

Example click handler:

function click(type: "link" | "image", url: string, ev: KeyboardEvent): boolean {
    if (ev.ctrlKey || ev.altKey) {
        return false; // let editor handle, will show markdown text
    }

    if (type === "image") {
        url = url.replace("__thumb__", ""); // switch to full size image
    }

    // open link or full image in new tab
    window.open(url, "_tab");
    ev.preventDefault();
    return true;
}
nokola commented 6 years ago

I noticed that clicking on link (not the icon) is actually in the click addon - would be nice to have similar option for a click() handler there as well (or maybe refactor part of click addon into fold addon or vice versa?)

laobubu commented 6 years ago

Yes. the click handler will be introduced in next version (TypeScript ver). Click add-on only works when user clicks on text, not image. If you want to handle events on images, try adding a capturing (not bubbling) event listener.

laobubu commented 6 years ago

Custom Click Handler is now avaliable in v0.3.0

A simple demo can be found here http://laobubu.net/HyperMD/?directOpen#./docs/index.md

...or just put this into your js...

cm.setOption("hmdClick", clickHandler)

function clickHandler(info, cm) {
  if (info.type === "link" || info.type === "url") {
    var url = info.url
    if ((info.ctrlKey || info.altKey) && /hotdog/i.test(url)) {
      alert("You can't access urls containing HotDog")
      return false
    }
  }
}