diff --git a/app/assets/javascripts/discourse-markdown-it/src/features/anchor.js b/app/assets/javascripts/discourse-markdown-it/src/features/anchor.js
index 78027d6f2f1..d9333da723f 100644
--- a/app/assets/javascripts/discourse-markdown-it/src/features/anchor.js
+++ b/app/assets/javascripts/discourse-markdown-it/src/features/anchor.js
@@ -5,6 +5,8 @@ export function setup(helper) {
helper.registerPlugin((md) => {
md.core.ruler.push("anchor", (state) => {
+ const postId = helper.getOptions().postId;
+
for (
let idx = 0, lvl = 0, headingId = 0;
idx < state.tokens.length;
@@ -45,6 +47,10 @@ export function setup(helper) {
slug = `${slug || "h"}-${++headingId}`;
+ if (postId) {
+ slug = `p-${postId}-${slug}`;
+ }
+
linkOpen.attrSet("name", slug);
linkOpen.attrSet("class", "anchor");
linkOpen.attrSet("href", "#" + slug);
diff --git a/app/assets/javascripts/discourse-markdown-it/src/options.js b/app/assets/javascripts/discourse-markdown-it/src/options.js
index 272c72da816..9ab36231bab 100644
--- a/app/assets/javascripts/discourse-markdown-it/src/options.js
+++ b/app/assets/javascripts/discourse-markdown-it/src/options.js
@@ -10,6 +10,7 @@ export default function buildOptions(state) {
lookupPrimaryUserGroup,
getTopicInfo,
topicId,
+ postId,
forceQuoteLink,
userId,
getCurrentUser,
@@ -48,6 +49,7 @@ export default function buildOptions(state) {
lookupPrimaryUserGroup,
getTopicInfo,
topicId,
+ postId,
forceQuoteLink,
userId,
getCurrentUser,
diff --git a/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js b/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js
index 3fc88d6008f..5641ba0c244 100644
--- a/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js
+++ b/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js
@@ -666,6 +666,15 @@ eviltrout
);
});
+ test("Heading anchors with post id", function (assert) {
+ assert.cookedOptions(
+ "# 1\n\n# one",
+ { postId: 1234 },
+ '1
\n' +
+ 'one
'
+ );
+ });
+
test("bold and italics", function (assert) {
assert.cooked(
'a "**hello**"',
diff --git a/app/models/post.rb b/app/models/post.rb
index cbf00888fac..7b2740e0f1b 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -325,6 +325,7 @@ class Post < ActiveRecord::Base
# is referencing.
options[:user_id] = self.last_editor_id
options[:omit_nofollow] = true if omit_nofollow?
+ options[:post_id] = self.id
if self.should_secure_uploads?
each_upload_url do |url|
diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb
index 0d5f9fbdcff..57968978a46 100644
--- a/lib/pretty_text.rb
+++ b/lib/pretty_text.rb
@@ -159,6 +159,7 @@ module PrettyText
# markdown_it_rules - An array of markdown rule names which will be applied to the markdown-it engine. Currently used by plugins to customize what markdown-it rules should be
# enabled when rendering markdown.
# topic_id - Topic id for the post being cooked.
+ # post_id - Post id for the post being cooked.
# user_id - User id for the post being cooked.
# force_quote_link - Always create the link to the quoted topic for [quote] bbcode. Normally this only happens
# if the topic_id provided is different from the [quote topic:X].
@@ -208,6 +209,7 @@ module PrettyText
JS
buffer << "__optInput.topicId = #{opts[:topic_id].to_i};\n" if opts[:topic_id]
+ buffer << "__optInput.postId = #{opts[:post_id].to_i};\n" if opts[:post_id]
if opts[:force_quote_link]
buffer << "__optInput.forceQuoteLink = #{opts[:force_quote_link]};\n"
diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb
index 1f78830c302..86910fa3256 100644
--- a/spec/models/post_spec.rb
+++ b/spec/models/post_spec.rb
@@ -1168,20 +1168,30 @@ RSpec.describe Post do
expect(post.cooked).to match(/noopener nofollow ugc/)
end
- it "passes the last_editor_id as the markdown user_id option" do
+ it "passes the last_editor_id as the markdown user_id option and post_id" do
post.save
post.reload
PostAnalyzer
.any_instance
.expects(:cook)
- .with(post.raw, { cook_method: Post.cook_methods[:regular], user_id: post.last_editor_id })
+ .with(
+ post.raw,
+ {
+ cook_method: Post.cook_methods[:regular],
+ user_id: post.last_editor_id,
+ post_id: post.id,
+ },
+ )
post.cook(post.raw)
user_editor = Fabricate(:user)
post.update!(last_editor_id: user_editor.id)
PostAnalyzer
.any_instance
.expects(:cook)
- .with(post.raw, { cook_method: Post.cook_methods[:regular], user_id: user_editor.id })
+ .with(
+ post.raw,
+ { cook_method: Post.cook_methods[:regular], user_id: user_editor.id, post_id: post.id },
+ )
post.cook(post.raw)
end