انقر للتعديل

:information_source: Summary Clicking in the textarea in the composer will select the corresponding line in the preview pane, and vice versa.
:hammer_and_wrench: Repository Link https://github.com/thijsbrilleman/discourse-click-to-edit
:open_book: Install Guide How to install plugins in Discourse

click-to-edit - 1080WebShareName-2

Features

Clicking in the textarea in the composer will select the corresponding line in the preview pane, and vice versa.

26 إعجابًا

Very nice addition to the core editing of Discourse. Thank you for creating it.

5 إعجابات

Seems like something that should be pr welcome, though I have no say in that.

6 إعجابات

Hello :wave: Thanks, this is really cool :tada: I am just thinking that it would be awesome to make it as a theme component. :slightly_smiling_face:

7 إعجابات

It doesn’t work too well on iPad, because it is choosing whole text when writing. It looks very odd.

3 إعجابات

Thanks, and I agree. Will look into it as soon as I have time. You’d always be welcome to file a pull request.

This currently is intended behavior, but I am of course open to better ideas. What sort of visual queue would you recommend?

إعجابَين (2)

It would show as pasted text when something is really selected. Then there would be action and response.

Curious, why is this a plugin vs theme component? All this tokens can be generated client side no?

Nice job btw, love that you are leaning on line numbers injected by the markdown engine.

4 إعجابات

Thank you Sam.

As you might have noticed, the data-ln attributes are present in the cooked html generated and stored on the server as well.

I implemented this behavior, so that later on I could extend the plugin to allow reliable insertion/editing of fragments from the topic view page, equivalent to the edit-button shown below (but a bit more robust):

The image is a screenshot of a web browser showing a quote soaking window with options to edit, copy, and quote.  (Captioned by AI)

It’s been a year since I wrote it, but if I remember correctly, to that end in plugin.rb the line

register_asset "vendor/javascripts/markdown-it-line-numbers.js", :vendored_pretty_text

is required to make sure the MarkdownIt extension also runs server-side when cooking the html.

I have not found the time required to implement the extended edit feature though, so if that requirement is dropped it could be converted to a component I guess.

5 إعجابات

@sam I’m looking into converting it into a theme component, but I’m unable to figure out how to get this code executed in the context of a markdownit plugin:

// javascripts/lib/discourse-markdown/initialize_markdownit_plugin.js:

export function setup(helper) {
    helper.registerPlugin(markdownitLineNumbers); // markdownitLineNumbers already available
}

I have the suspicion that the line in the plugin I wrote earlier sprinkles some client-side magic as well:

# plugin.rb

register_asset "vendor/javascripts/markdown-it-line-numbers.js", :vendored_pretty_text`

Do you have any clue?

Not sure, will ping the team.

إعجابَين (2)

I believe this is because it is currently restricted to plugins scope only. It would work without that check. (This code has been introduced in this commit)

I wanted to integrate line-number for another component, but I did not want to make a plugin, so I gave up on it. It would be super cool if markdown features could be supported in theme components!

On a side note, a great feature that you proposed here – very nice. :+1: :rocket:

4 إعجابات

Ah yes, this clears it up.

Looking at this code, it might be possible to manually inject the markdown plugin from the theme component at run-time, but this would be pretty hacky. I’ll await the verdict from the core team before trying to implement it.

4 إعجابات

Our markdown pipeline runs both on the client (for preview), and on the server (to pre-render the HTML for posts). So that’s why it’s designed for plugins only - they’re the only ones which can inject code on the server-side.

Now… this case is quite unusual, since the extension is only needed in the composer, and not on the server. So doing it from a theme component should be feasible.

Did you have a particular strategy in mind for this?

5 إعجابات

This seems like something that would have wide appeal. It can be hard to find your place in a long post. Might it be pr-welcome ?

5 إعجابات

Override this function in the original codebase:

// discourse/app/assets/javascripts/discourse/app/components/d-editor.js
async cachedCookAsync(text, options) {
  this._cachedCookFunction ||= await generateCookFunction(options || {});
  return await this._cachedCookFunction(text);
}

with a theme component initializer:

export default {
  name: "d-editor-cached-cook-async-override",
  initialize() {
    const dEditor = require("discourse/components/d-editor").default;
    dEditor.reopen({
      cachedCookAsync(text, options) {
        // duplicate code here to return an altered cook function
      },
    });
  },
};

It would mean quite a bit of code duplication, if it’d work at all. Dirty, dirty.

4 إعجابات

Hmm yeah, agreed - definitely not ideal. Duplicating the code might not even be possible, because the markdown-it modules are loaded asynchronously, and aren’t part of the amd module system which themes/plugins have direct access to. :thinking:

Building a system to allow themes to contribute client-side-only md transformations could be cool, although the use-cases are fairly limited. In 99% of cases, people want md transforms to apply server-side as well.

So I think, for now, sticking with a plugin is probably the best approach.

5 إعجابات

I wonder if this kind of decoration should be applied regardless though?

Eg:

<p data-source-line="0">.....</p>

The extra data attribute will assist a lot of internal implementations we have, like, for example, not showing autocomplete when you are inside a code block. Also quoting and quick edit become much easier.

The trivial implementation carries almost no extra weight, but allows us to delete a pile of source code.

7 إعجابات

We had this in the past (behind a flag), but it was removed in this commit. I found this screenshot from some internal discussions about that feature:

i.e. the perf issue was with the scroll syncing code, not the injection of the line-numbers :ok_hand:

So yeah, I have no objection to adding the data-source-line injection into core, as long as it’s only added in preview. Is it something you’d be interested in making a PR for @pipkin?

4 إعجابات

Gladly! Happy to be able to give something back to you guys.

6 إعجابات