From d94a4c581fa5f71bd4556ef17387855fe15e6266 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Mon, 3 Jun 2024 13:16:57 +0100 Subject: [PATCH] Added TK support to subtitle closes https://linear.app/tryghost/issue/MOM-176 - display TK next to subtitle field as per the title field - include subtitle TK in the pre-publish TK check --- .../components/gh-koenig-editor-lexical.hbs | 45 +++++---- ghost/admin/app/controllers/lexical-editor.js | 92 +++++++++++-------- ghost/admin/app/styles/layouts/editor.css | 4 + ghost/admin/app/templates/lexical-editor.hbs | 9 +- ghost/admin/tests/acceptance/editor-test.js | 34 +++++++ 5 files changed, 124 insertions(+), 60 deletions(-) diff --git a/ghost/admin/app/components/gh-koenig-editor-lexical.hbs b/ghost/admin/app/components/gh-koenig-editor-lexical.hbs index 4438538c3e..54bfea5a58 100644 --- a/ghost/admin/app/components/gh-koenig-editor-lexical.hbs +++ b/ghost/admin/app/components/gh-koenig-editor-lexical.hbs @@ -58,23 +58,34 @@ /> {{#if (feature 'editorSubtitle')}} - - {{#if @excerptErrorMessage}} -
- {{@excerptErrorMessage}} -
- {{/if}} +
+ + {{#if @excerptErrorMessage}} +
+ {{@excerptErrorMessage}} +
+ {{/if}} + {{#if @excerptHasTk}} +
+ TK +
+ {{/if}} +

{{/if}} diff --git a/ghost/admin/app/controllers/lexical-editor.js b/ghost/admin/app/controllers/lexical-editor.js index d42bdd6c36..232bd144ab 100644 --- a/ghost/admin/app/controllers/lexical-editor.js +++ b/ghost/admin/app/controllers/lexical-editor.js @@ -102,6 +102,45 @@ const messageMap = { } }; +function textHasTk(text) { + let matchArr = TK_REGEX.exec(text); + + if (matchArr === null) { + return false; + } + + function isValidMatch(match) { + // negative lookbehind isn't supported before Safari 16.4 + // so we capture the preceding char and test it here + if (match[1] && match[1].trim() && WORD_CHAR_REGEX.test(match[1])) { + return false; + } + + // we also check any following char in code to avoid an overly + // complex regex when looking for word-chars following the optional + // trailing symbol char + if (match[4] && match[4].trim() && WORD_CHAR_REGEX.test(match[4])) { + return false; + } + + return true; + } + + // our regex will match invalid TKs because we can't use negative lookbehind + // so we need to loop through the matches discarding any that are invalid + // and moving on to any subsequent matches + while (matchArr !== null && !isValidMatch(matchArr)) { + text = text.slice(matchArr.index + matchArr[0].length - 1); + matchArr = TK_REGEX.exec(text); + } + + if (matchArr === null) { + return false; + } + + return true; +} + @classic export default class LexicalEditorController extends Controller { @controller application; @@ -225,48 +264,23 @@ export default class LexicalEditorController extends Controller { @computed('post.titleScratch') get titleHasTk() { - let text = this.post.titleScratch; - let matchArr = TK_REGEX.exec(text); - - if (matchArr === null) { - return false; - } - - function isValidMatch(match) { - // negative lookbehind isn't supported before Safari 16.4 - // so we capture the preceding char and test it here - if (match[1] && match[1].trim() && WORD_CHAR_REGEX.test(match[1])) { - return false; - } - - // we also check any following char in code to avoid an overly - // complex regex when looking for word-chars following the optional - // trailing symbol char - if (match[4] && match[4].trim() && WORD_CHAR_REGEX.test(match[4])) { - return false; - } - - return true; - } - - // our regex will match invalid TKs because we can't use negative lookbehind - // so we need to loop through the matches discarding any that are invalid - // and moving on to any subsequent matches - while (matchArr !== null && !isValidMatch(matchArr)) { - text = text.slice(matchArr.index + matchArr[0].length - 1); - matchArr = TK_REGEX.exec(text); - } - - if (matchArr === null) { - return false; - } - - return true; + return textHasTk(this.post.titleScratch); } - @computed('titleHasTk', 'postTkCount', 'featureImageTkCount') + @computed('post.customExcerpt') + get excerptHasTk() { + if (!this.feature.editorSubtitle) { + return false; + } + + return textHasTk(this.post.customExcerpt || ''); + } + + @computed('titleHasTk', 'excerptHasTk', 'postTkCount', 'featureImageTkCount') get tkCount() { - return (this.titleHasTk ? 1 : 0) + this.postTkCount + this.featureImageTkCount; + const titleTk = this.titleHasTk ? 1 : 0; + const excerptTk = (this.feature.editorSubtitle && this.excerptHasTk) ? 1 : 0; + return titleTk + excerptTk + this.postTkCount + this.featureImageTkCount; } @action diff --git a/ghost/admin/app/styles/layouts/editor.css b/ghost/admin/app/styles/layouts/editor.css index da7cb96587..ecfd29a829 100644 --- a/ghost/admin/app/styles/layouts/editor.css +++ b/ghost/admin/app/styles/layouts/editor.css @@ -839,6 +839,10 @@ body[data-user-is-dragging] .gh-editor-feature-image-dropzone { cursor: pointer; } +.gh-editor .tk-indicator-subtitle { + top: -1px; +} + .gh-editor-feature-image-container .tk-indicator { top: 0; padding: 0 .4rem; diff --git a/ghost/admin/app/templates/lexical-editor.hbs b/ghost/admin/app/templates/lexical-editor.hbs index 77847a47eb..bd9d5d51e7 100644 --- a/ghost/admin/app/templates/lexical-editor.hbs +++ b/ghost/admin/app/templates/lexical-editor.hbs @@ -61,14 +61,15 @@ --}}