diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67e27f9..14aac4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
# Changelog
+## 0.8.6 - 2024-04-09
+
+### 🐛 Fix a bug
+
+- Don't apply base link url to full links
+- Fix full link detection
+- Fix initial setting of base link URLs again
+
+## 0.8.6 - 2024-04-09
+
+### 🐛 Fix a bug
+
+- Don't apply base link url to full links
+- Fix full link detection
+- Fix initial setting of base link URLs again
+
## 0.8.5 - 2024-04-09
### ✨ Introduce new features
diff --git a/CodeMirror6/CodeMirror6.csproj b/CodeMirror6/CodeMirror6.csproj
index a3d05eb..5ff7dae 100644
--- a/CodeMirror6/CodeMirror6.csproj
+++ b/CodeMirror6/CodeMirror6.csproj
@@ -9,7 +9,7 @@
GaelJ.BlazorCodeMirror6
true
GaelJ.BlazorCodeMirror6
- 0.8.5
+ 0.8.6
true
snupkg
true
diff --git a/CodeMirror6/NodeLib/src/CmHyperlink.ts b/CodeMirror6/NodeLib/src/CmHyperlink.ts
index 5b2b347..75dff9f 100644
--- a/CodeMirror6/NodeLib/src/CmHyperlink.ts
+++ b/CodeMirror6/NodeLib/src/CmHyperlink.ts
@@ -8,7 +8,6 @@ import {
ViewUpdate,
} from '@codemirror/view';
import { Extension, Range } from '@codemirror/state';
-import { CMInstances } from './CmInstance';
const linkSvgImage = ``;
const anyLinkRegexp = /(!?\[(?:[^\]]+)\]\([^\)]+\))|\b((?:https?:\/\/|ftp:\/\/|data:)[^\s]*)\b/gi;
@@ -34,16 +33,26 @@ class HyperLinkIcon extends WidgetType
}
toDOM() {
const link = document.createElement('a');
- const matchAll = this.state.url.matchAll(linkRegexp);
- const match = [...matchAll][0]
- if (match && match.length > 1) {
- const url = match[1];
- link.href = `${this.state.baseUrl}${url}`;
+ const matchUrlPart = this.state.url.matchAll(linkRegexp);
+ const matchUrl = [...matchUrlPart][0]
+ if (matchUrl && matchUrl.length > 1) {
+ const url = matchUrl[1];
+ if (url.includes('://') || url.startsWith('data:'))
+ link.href = url;
+ else
+ link.href = `${this.state.baseUrl}${url}`;
}
- else
- link.href = `${this.state.baseUrl}${this.state.url}`;
- if (link.href.endsWith('.md') && this.state.viewer)
+ else {
+ if (this.state.url.includes('://') || this.state.url.startsWith('data:'))
+ link.href = this.state.url;
+ else
+ link.href = `${this.state.baseUrl}${this.state.url}`;
+ }
+
+ // Open .md links in the optional markdown viewer
+ if (link.href.endsWith('.md') || link.href.includes('.md#') || link.href.includes('.md?'))
link.href = `${this.state.viewer}${encodeURIComponent(link.href)}`;
+
link.target = '_blank';
link.innerHTML = linkSvgImage;
link.className = 'cm-hyper-link-icon';
@@ -52,17 +61,15 @@ class HyperLinkIcon extends WidgetType
}
}
-function hyperLinkDecorations(view: EditorView, id: string)
+function hyperLinkDecorations(view: EditorView, basePathForLinks: string, markdownViewerPath: string)
{
const widgets: Array> = [];
const doc = view.state.doc.toString();
let match;
- const basePathForLinks = (CMInstances[id] !== undefined && CMInstances[id].config.basePathForLinks)
- ? CMInstances[id].config.basePathForLinks.replace(/\/+$/, '') + "/"
- : '';
- const markdownViewPath = (CMInstances[id] !== undefined && CMInstances[id].config.markdownViewPath)
- ? CMInstances[id].config.markdownViewPath
+ basePathForLinks = basePathForLinks
+ ? basePathForLinks.replace(/\/+$/, '') + "/"
: '';
+ markdownViewerPath = markdownViewerPath ?? ''
while ((match = anyLinkRegexp.exec(doc)) !== null) {
const from = match.index;
@@ -72,7 +79,7 @@ function hyperLinkDecorations(view: EditorView, id: string)
at: to,
url: match[0],
baseUrl: basePathForLinks,
- viewer: markdownViewPath,
+ viewer: markdownViewerPath,
}),
side: 1,
});
@@ -82,18 +89,18 @@ function hyperLinkDecorations(view: EditorView, id: string)
return Decoration.set(widgets);
}
-export function hyperLinkExtension(id: string)
+export function hyperLinkExtension(basePathForLinks: string, markdownViewerPath: string)
{
return ViewPlugin.fromClass(
class HyperLinkView {
decorator?: MatchDecorator;
decorations: DecorationSet;
constructor(view: EditorView) {
- this.decorations = hyperLinkDecorations(view, id);
+ this.decorations = hyperLinkDecorations(view, basePathForLinks, markdownViewerPath);
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
- this.decorations = hyperLinkDecorations(update.view, id);
+ this.decorations = hyperLinkDecorations(update.view, basePathForLinks, markdownViewerPath);
}
}
},
@@ -117,4 +124,5 @@ export const hyperLinkStyle = EditorView.baseTheme({
},
});
-export const hyperLink = (id: string) => [hyperLinkExtension(id), hyperLinkStyle];
+export const hyperLink = (basePathForLinks: string, markdownViewerPath: string) =>
+ [hyperLinkExtension(basePathForLinks, markdownViewerPath), hyperLinkStyle];
diff --git a/CodeMirror6/NodeLib/src/CmImages.ts b/CodeMirror6/NodeLib/src/CmImages.ts
index 7bbb27e..b3e1616 100644
--- a/CodeMirror6/NodeLib/src/CmImages.ts
+++ b/CodeMirror6/NodeLib/src/CmImages.ts
@@ -4,25 +4,27 @@ import { RangeSet, StateField } from '@codemirror/state'
import type { DecorationSet } from '@codemirror/view'
import { Decoration, EditorView, WidgetType, ViewUpdate } from '@codemirror/view'
import { buildWidget } from './lib/codemirror-kit'
-import { CMInstances } from './CmInstance'
-const imageWidget = (id: string, src: string, from: number) => buildWidget({
+const imageWidget = (basePathForLinks: string, src: string, from: number) => buildWidget({
src: src,
eq(other) {
return other.src === src
},
toDOM(view: EditorView) {
- const basePathForLinks = (CMInstances[id] !== undefined && CMInstances[id].config.basePathForLinks)
- ? CMInstances[id].config.basePathForLinks.replace(/\/+$/, '') + "/"
- : '';
+ basePathForLinks = basePathForLinks
+ ? basePathForLinks.replace(/\/+$/, '') + "/"
+ : '';
const container = document.createElement('div')
container.setAttribute('aria-hidden', 'true')
const image = container.appendChild(document.createElement('img'))
image.setAttribute('aria-hidden', 'true')
- image.src = `${basePathForLinks}${src}`
+ if (src.includes('://') || src.startsWith('data:'))
+ image.src = src;
+ else
+ image.src = `${basePathForLinks}${src}`
image.style.maxHeight = '320px'
image.style.maxWidth = 'calc(100% - 2em)'
image.style.objectFit = 'scale-down'
@@ -54,7 +56,7 @@ const imageWidget = (id: string, src: string, from: number) => buildWidget({
},
})
-export const dynamicImagesExtension = (id: string, enabled: boolean = true): Extension => {
+export const dynamicImagesExtension = (basePathForLinks: string, enabled: boolean = true): Extension => {
if (!enabled) {
return []
}
@@ -62,7 +64,7 @@ export const dynamicImagesExtension = (id: string, enabled: boolean = true): Ext
const imageRegex = /!\[.*?\]\((?.*?)\)/
const imageDecoration = (src: string, from: number) => Decoration.widget({
- widget: imageWidget(id, src, from),
+ widget: imageWidget(basePathForLinks, src, from),
side: -1,
block: true,
})
diff --git a/CodeMirror6/NodeLib/src/index.ts b/CodeMirror6/NodeLib/src/index.ts
index 1274850..7905761 100644
--- a/CodeMirror6/NodeLib/src/index.ts
+++ b/CodeMirror6/NodeLib/src/index.ts
@@ -109,7 +109,7 @@ export async function initCodeMirror(
createEditorWithId(id),
CMInstances[id].keymapCompartment.of(keymap.of(customLanguageKeyMap)),
CMInstances[id].languageCompartment.of(await getLanguage(id, initialConfig.languageName, initialConfig.fileNameOrExtension) ?? []),
- CMInstances[id].markdownStylingCompartment.of(initialConfig.languageName !== "Markdown" ? [] : autoFormatMarkdownExtensions(id, initialConfig.autoFormatMarkdown)),
+ CMInstances[id].markdownStylingCompartment.of(initialConfig.languageName !== "Markdown" ? [] : autoFormatMarkdownExtensions(id, initialConfig.previewImages, initialConfig.basePathForLinks, initialConfig.autoFormatMarkdown)),
CMInstances[id].tabSizeCompartment.of(EditorState.tabSize.of(initialConfig.tabSize)),
CMInstances[id].indentUnitCompartment.of(indentUnit.of(" ".repeat(initialConfig.indentationUnit))),
CMInstances[id].placeholderCompartment.of(placeholder(initialConfig.placeholder)),
@@ -138,7 +138,7 @@ export async function initCodeMirror(
CMInstances[id].dropCursorCompartment.of(initialConfig.dropCursor ? dropCursor() : []),
CMInstances[id].scrollPastEndCompartment.of(initialConfig.scrollPastEnd ? scrollPastEnd() : []),
CMInstances[id].highlightActiveLineCompartment.of(initialConfig.highlightActiveLine ? highlightActiveLine() : []),
- CMInstances[id].hyperLinksCompartment.of(hyperLink(id)),
+ CMInstances[id].hyperLinksCompartment.of(hyperLink(initialConfig.basePathForLinks, initialConfig.markdownViewPath)),
EditorView.updateListener.of(async (update) => { await updateListenerExtension(id, update) }),
linter(async view => maxDocLengthLintSource(id, view)),
@@ -361,7 +361,7 @@ export async function setConfiguration(id: string, newConfig: CmConfiguration) {
CMInstances[id].languageCompartment.reconfigure(language ?? []),
CMInstances[id].keymapCompartment.reconfigure(keymap.of(customLanguageKeyMap)),
languageChangeEffect.of(language?.language),
- CMInstances[id].markdownStylingCompartment.reconfigure(autoFormatMarkdownExtensions(id, newConfig.languageName === 'Markdown')),
+ CMInstances[id].markdownStylingCompartment.reconfigure(autoFormatMarkdownExtensions(id, newConfig.previewImages, newConfig.basePathForLinks, newConfig.languageName === 'Markdown')),
CMInstances[id].columnsStylingCompartment.reconfigure(
newConfig.languageName === "CSV" || newConfig.languageName === "TSV"
? [
@@ -378,7 +378,7 @@ export async function setConfiguration(id: string, newConfig: CmConfiguration) {
unfoldAll(CMInstances[id].view)
}
if (oldConfig.autoFormatMarkdown !== newConfig.autoFormatMarkdown || oldConfig.previewImages !== newConfig.previewImages || oldConfig.basePathForLinks !== newConfig.basePathForLinks) {
- effects.push(CMInstances[id].markdownStylingCompartment.reconfigure(autoFormatMarkdownExtensions(id, newConfig.autoFormatMarkdown)))
+ effects.push(CMInstances[id].markdownStylingCompartment.reconfigure(autoFormatMarkdownExtensions(id, newConfig.previewImages, newConfig.basePathForLinks, newConfig.autoFormatMarkdown)))
if (newConfig.languageName === "Markdown" && newConfig.autoFormatMarkdown)
foldMarkdownDiagramCodeBlocks(CMInstances[id].view)
else
@@ -399,7 +399,8 @@ export async function setConfiguration(id: string, newConfig: CmConfiguration) {
if (oldConfig.dropCursor !== newConfig.dropCursor) effects.push(CMInstances[id].dropCursorCompartment.reconfigure(newConfig.dropCursor ? dropCursor() : []))
if (oldConfig.scrollPastEnd !== newConfig.scrollPastEnd) effects.push(CMInstances[id].scrollPastEndCompartment.reconfigure(newConfig.scrollPastEnd ? scrollPastEnd() : []))
if (oldConfig.highlightActiveLine !== newConfig.highlightActiveLine) effects.push(CMInstances[id].highlightActiveLineCompartment.reconfigure(newConfig.highlightActiveLine ? highlightActiveLine() : []))
- if (oldConfig.basePathForLinks !== newConfig.basePathForLinks || oldConfig.markdownViewPath != newConfig.markdownViewPath) effects.push(CMInstances[id].hyperLinksCompartment.reconfigure(hyperLink(id)))
+ if (oldConfig.basePathForLinks !== newConfig.basePathForLinks || oldConfig.markdownViewPath != newConfig.markdownViewPath)
+ effects.push(CMInstances[id].hyperLinksCompartment.reconfigure(hyperLink(newConfig.basePathForLinks, newConfig.markdownViewPath)))
CMInstances[id].config = newConfig
if (effects.length > 0 || changes.length > 0)
@@ -476,10 +477,10 @@ function saveToLocalStorage(id: string) {
}
}
-const autoFormatMarkdownExtensions = (id: string, autoFormatMarkdown: boolean = true) => [
+const autoFormatMarkdownExtensions = (id: string, previewImages: boolean, basePathForLinks: string, autoFormatMarkdown: boolean = true) => [
getDynamicHeaderStyling(autoFormatMarkdown),
dynamicHrExtension(autoFormatMarkdown),
- dynamicImagesExtension(id, autoFormatMarkdown && CMInstances[id].config.previewImages === true),
+ dynamicImagesExtension(basePathForLinks, autoFormatMarkdown && previewImages === true),
dynamicDiagramsExtension(autoFormatMarkdown, CMInstances[id].setup.krokiUrl.replace(/\/$/, '')),
autocompletion({
override: [
diff --git a/Examples.BlazorServer/Examples.BlazorServer.csproj b/Examples.BlazorServer/Examples.BlazorServer.csproj
index 1076965..974d656 100644
--- a/Examples.BlazorServer/Examples.BlazorServer.csproj
+++ b/Examples.BlazorServer/Examples.BlazorServer.csproj
@@ -4,7 +4,7 @@
enable
false
enable
- 0.8.5
+ 0.8.6
diff --git a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
index 503b70e..56e5c8d 100644
--- a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
+++ b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
@@ -4,7 +4,7 @@
enable
enable
false
- 0.8.5
+ 0.8.6
diff --git a/Examples.BlazorWasm/Examples.BlazorWasm.csproj b/Examples.BlazorWasm/Examples.BlazorWasm.csproj
index 2d69736..4f19c2b 100644
--- a/Examples.BlazorWasm/Examples.BlazorWasm.csproj
+++ b/Examples.BlazorWasm/Examples.BlazorWasm.csproj
@@ -4,7 +4,7 @@
enable
enable
false
- 0.8.5
+ 0.8.6
diff --git a/Examples.Common/Examples.Common.csproj b/Examples.Common/Examples.Common.csproj
index 6fadd4f..f4123a4 100644
--- a/Examples.Common/Examples.Common.csproj
+++ b/Examples.Common/Examples.Common.csproj
@@ -5,7 +5,7 @@
enable
enable
false
- 0.8.5
+ 0.8.6
diff --git a/NEW_CHANGELOG.md b/NEW_CHANGELOG.md
index 2a4eb9d..91130bf 100644
--- a/NEW_CHANGELOG.md
+++ b/NEW_CHANGELOG.md
@@ -1,8 +1,5 @@
-### ✨ Introduce new features
-
-- Allow opening markdown links by passing them as query parameter value to a viewer URL + query parameter name + '='
-
### 🐛 Fix a bug
-- Update images when bath path for links is initially set
-- Update links when bath path for links is initially set
+- Don't apply base link url to full links
+- Fix full link detection
+- Fix initial setting of base link URLs again