pxx-vue-quill 1.0.97 → 1.0.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue-quill.umd.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Copyright (c) 2025 Pxx-Team
|
|
9
9
|
* Released under the MIT license
|
|
10
|
-
* Date: 2025-09-
|
|
10
|
+
* Date: 2025-09-09T11:01:46.299Z
|
|
11
11
|
*/
|
|
12
12
|
(function (global, factory) {
|
|
13
13
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) :
|
|
@@ -18444,7 +18444,7 @@
|
|
|
18444
18444
|
full: [
|
|
18445
18445
|
['bold', 'italic', 'underline'],
|
|
18446
18446
|
[{ color: [] }],
|
|
18447
|
-
['
|
|
18447
|
+
['customLink'],
|
|
18448
18448
|
[{ list: 'ordered' }, { list: 'bullet' }],
|
|
18449
18449
|
['image'],
|
|
18450
18450
|
['undo', 'redo'],
|
|
@@ -18517,8 +18517,9 @@
|
|
|
18517
18517
|
]),
|
|
18518
18518
|
vue.h('span', { class: 'ql-formats' }, [
|
|
18519
18519
|
vue.h('button', {
|
|
18520
|
-
class: 'ql-
|
|
18521
|
-
type: 'button'
|
|
18520
|
+
class: 'ql-customLink',
|
|
18521
|
+
type: 'button',
|
|
18522
|
+
onClick: () => emit('toolClick', 'customLink')
|
|
18522
18523
|
}, '')
|
|
18523
18524
|
]),
|
|
18524
18525
|
vue.h('span', { class: 'ql-formats' }, [
|
|
@@ -18590,6 +18591,80 @@
|
|
|
18590
18591
|
}
|
|
18591
18592
|
});
|
|
18592
18593
|
|
|
18594
|
+
const CustomLink = vue.defineComponent({
|
|
18595
|
+
name: 'CustomLink',
|
|
18596
|
+
props: {
|
|
18597
|
+
visible: {
|
|
18598
|
+
type: Boolean,
|
|
18599
|
+
default: false
|
|
18600
|
+
},
|
|
18601
|
+
position: {
|
|
18602
|
+
type: Object,
|
|
18603
|
+
default: () => ({ top: 0, left: 0 })
|
|
18604
|
+
},
|
|
18605
|
+
linkUrl: {
|
|
18606
|
+
type: String,
|
|
18607
|
+
default: ''
|
|
18608
|
+
},
|
|
18609
|
+
linkText: {
|
|
18610
|
+
type: String,
|
|
18611
|
+
default: ''
|
|
18612
|
+
}
|
|
18613
|
+
},
|
|
18614
|
+
emits: ['save', 'update:linkUrl', 'update:linkText'],
|
|
18615
|
+
setup(props, { emit }) {
|
|
18616
|
+
const localLinkUrl = vue.computed({
|
|
18617
|
+
get() {
|
|
18618
|
+
return props.linkUrl;
|
|
18619
|
+
},
|
|
18620
|
+
set(val) {
|
|
18621
|
+
emit('update:linkUrl', val);
|
|
18622
|
+
},
|
|
18623
|
+
});
|
|
18624
|
+
const localLinkText = vue.computed({
|
|
18625
|
+
get() {
|
|
18626
|
+
return props.linkText;
|
|
18627
|
+
},
|
|
18628
|
+
set(val) {
|
|
18629
|
+
emit('update:linkText', val);
|
|
18630
|
+
},
|
|
18631
|
+
});
|
|
18632
|
+
const handleSave = () => {
|
|
18633
|
+
emit('save', {
|
|
18634
|
+
url: localLinkUrl.value,
|
|
18635
|
+
text: localLinkText.value
|
|
18636
|
+
});
|
|
18637
|
+
};
|
|
18638
|
+
return () => {
|
|
18639
|
+
if (!props.visible)
|
|
18640
|
+
return null;
|
|
18641
|
+
return vue.h('div', {
|
|
18642
|
+
class: 'ql-custom-link',
|
|
18643
|
+
style: {
|
|
18644
|
+
top: `${props.position.top}px`,
|
|
18645
|
+
left: `${props.position.left}px`,
|
|
18646
|
+
},
|
|
18647
|
+
onClick: (event) => {
|
|
18648
|
+
event.stopPropagation();
|
|
18649
|
+
}
|
|
18650
|
+
}, [
|
|
18651
|
+
vue.h('input', {
|
|
18652
|
+
type: 'text',
|
|
18653
|
+
value: localLinkUrl.value,
|
|
18654
|
+
placeholder: '请输入链接',
|
|
18655
|
+
onInput: (e) => {
|
|
18656
|
+
localLinkUrl.value = e.target.value;
|
|
18657
|
+
}
|
|
18658
|
+
}),
|
|
18659
|
+
vue.h('button', {
|
|
18660
|
+
class: 'custom-link-btn',
|
|
18661
|
+
onClick: handleSave
|
|
18662
|
+
}, '确定'),
|
|
18663
|
+
]);
|
|
18664
|
+
};
|
|
18665
|
+
}
|
|
18666
|
+
});
|
|
18667
|
+
|
|
18593
18668
|
var dist = {};
|
|
18594
18669
|
|
|
18595
18670
|
var Options = {};
|
|
@@ -20241,6 +20316,64 @@
|
|
|
20241
20316
|
};
|
|
20242
20317
|
}
|
|
20243
20318
|
|
|
20319
|
+
function useLinkClick(editor, initialHandleCustomLink) {
|
|
20320
|
+
const quillRef = vue.ref(null);
|
|
20321
|
+
const handleCustomLinkRef = vue.ref(initialHandleCustomLink || null);
|
|
20322
|
+
const handleLinkClick = (event) => {
|
|
20323
|
+
if (!quillRef.value || !handleCustomLinkRef.value)
|
|
20324
|
+
return;
|
|
20325
|
+
const target = event.target;
|
|
20326
|
+
if (target.tagName === 'A') {
|
|
20327
|
+
event.preventDefault();
|
|
20328
|
+
event.stopPropagation();
|
|
20329
|
+
try {
|
|
20330
|
+
const linkElement = target;
|
|
20331
|
+
const linkUrl = linkElement.getAttribute('href') || '';
|
|
20332
|
+
const linkText = linkElement.textContent || '';
|
|
20333
|
+
const range = quillRef.value.getSelection();
|
|
20334
|
+
if (range) {
|
|
20335
|
+
const [blot] = quillRef.value.getLeaf(range.index);
|
|
20336
|
+
if (blot && blot.parent && blot.parent.domNode.tagName === 'A') {
|
|
20337
|
+
const linkBlot = blot.parent;
|
|
20338
|
+
const linkIndex = quillRef.value.getIndex(linkBlot);
|
|
20339
|
+
const linkLength = linkBlot.length();
|
|
20340
|
+
quillRef.value.setSelection(linkIndex, linkLength);
|
|
20341
|
+
handleCustomLinkRef.value(true, { url: linkUrl, text: linkText });
|
|
20342
|
+
}
|
|
20343
|
+
}
|
|
20344
|
+
}
|
|
20345
|
+
catch (error) {
|
|
20346
|
+
console.warn('选中链接失败:', error);
|
|
20347
|
+
}
|
|
20348
|
+
}
|
|
20349
|
+
};
|
|
20350
|
+
const addLinkClickListener = () => {
|
|
20351
|
+
if (!quillRef.value)
|
|
20352
|
+
return;
|
|
20353
|
+
vue.nextTick(() => {
|
|
20354
|
+
var _a;
|
|
20355
|
+
const editorElement = (_a = editor.value) === null || _a === void 0 ? void 0 : _a.querySelector('.ql-editor');
|
|
20356
|
+
if (editorElement) {
|
|
20357
|
+
editorElement.removeEventListener('click', handleLinkClick);
|
|
20358
|
+
editorElement.addEventListener('click', handleLinkClick);
|
|
20359
|
+
}
|
|
20360
|
+
});
|
|
20361
|
+
};
|
|
20362
|
+
const setQuill = (quillInstance) => {
|
|
20363
|
+
quillRef.value = quillInstance;
|
|
20364
|
+
};
|
|
20365
|
+
const setHandleCustomLink = (fn) => {
|
|
20366
|
+
handleCustomLinkRef.value = fn;
|
|
20367
|
+
};
|
|
20368
|
+
return {
|
|
20369
|
+
quillRef,
|
|
20370
|
+
setQuill,
|
|
20371
|
+
setHandleCustomLink,
|
|
20372
|
+
handleLinkClick,
|
|
20373
|
+
addLinkClickListener
|
|
20374
|
+
};
|
|
20375
|
+
}
|
|
20376
|
+
|
|
20244
20377
|
const boldSVG = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="18" height="18" viewBox="0 0 18 18"><g><g style="opacity:0;"><rect x="0" y="0" width="18" height="18" rx="0" fill="#FFFFFF" fill-opacity="1"/></g><g><path d="M6.794999938146972,7.7800002288818355L9.045000038146974,7.7800002288818355Q9.855000038146972,7.7800002288818355,10.230000038146972,7.442500128881836Q10.605000038146972,7.105000028881836,10.605000038146972,6.505000128881836Q10.605000038146972,6.114999728881836,10.440000038146973,5.860000628881836Q10.275000138146972,5.6050005288818365,9.929999838146973,5.470000228881836Q9.585000038146973,5.335000028881836,9.045000038146974,5.335000028881836L7.139999938146973,5.335000028881836L7.139999938146973,3.385000228881836L9.045000038146974,3.385000228881836Q10.034999838146973,3.385000228881836,10.852499938146973,3.797500608881836Q11.670000038146974,4.2100000388818355,12.142499938146972,4.922500628881836Q12.614999738146974,5.635000228881836,12.614999738146974,6.505000128881836Q12.614999738146974,7.375000028881836,12.142499938146972,8.042500028881836Q11.670000038146974,8.710000028881836,10.860000138146972,9.070000128881837Q10.050000238146973,9.430000328881835,9.045000038146974,9.430000328881835L6.794999938146972,9.430000328881835L6.794999938146972,7.7800002288818355ZM7.139999938146973,12.550000228881835L9.329999938146972,12.550000228881835Q9.900000138146972,12.550000228881835,10.327499838146974,12.354999528881836Q10.755000138146972,12.159999828881835,10.987500238146973,11.807499928881835Q11.219999838146972,11.454999928881836,11.219999838146972,11.020000428881836Q11.219999838146972,10.600000428881836,10.987500238146973,10.232500028881836Q10.755000138146972,9.864999728881836,10.327499838146974,9.647500028881836Q9.900000138146972,9.430000328881835,9.329999938146972,9.430000328881835L6.975000038146972,9.430000328881835L6.975000038146972,7.7800002288818355L9.329999938146972,7.7800002288818355Q10.349999938146972,7.7800002288818355,11.250000038146972,8.200000328881835Q12.149999638146973,8.620000328881837,12.690000538146972,9.362500228881835Q13.229999538146973,10.104999528881836,13.229999538146973,11.034999828881837Q13.229999538146973,11.949999828881836,12.690000538146972,12.752500528881836Q12.149999638146973,13.555000228881836,11.250000038146972,14.027500228881836Q10.349999938146972,14.500000228881836,9.329999938146972,14.500000228881836L7.139999938146973,14.500000228881836L7.139999938146973,12.550000228881835ZM7.064999938146973,14.500000228881836Q6.284999968146972,14.500000228881836,5.872500058146973,14.095000228881837Q5.460000038146973,13.689999228881836,5.460000038146973,12.895000428881836L5.460000038146973,4.989999728881836Q5.460000038146973,4.195000648881836,5.872500058146973,3.789999958881836Q6.284999968146972,3.385000228881836,7.064999938146973,3.385000228881836L7.469999838146973,3.385000228881836L7.469999838146973,14.500000228881836L7.064999938146973,14.500000228881836Z" fill="#555555" fill-opacity="1"/></g></g></svg>`;
|
|
20245
20378
|
const italicSVG = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="18" height="18" viewBox="0 0 18 18"><g><g style="opacity:0;"><rect x="0" y="0" width="18" height="18" rx="0" fill="#FFFFFF" fill-opacity="1"/></g><g><path d="M8,3Q7.9015086,3,7.8049095,3.019214718Q7.7083106,3.038429435,7.6173165,3.076120459Q7.5263224,3.11381148,7.4444296,3.16853037Q7.3625371,3.2232492600000002,7.2928932,3.2928932Q7.2232492,3.36253715,7.1685302,3.4444297600000002Q7.1138113999999995,3.52632231,7.0761204,3.61731648Q7.0384293,3.70831072,7.0192146,3.80490965Q6.99999994,3.90150857,7,4Q6.99999994,4.0984913,7.0192146,4.1950902Q7.0384293,4.291689,7.0761204,4.3826833Q7.1138113999999995,4.4736774,7.1685302,4.5555699Q7.2232492,4.6374626,7.2928932,4.7071065999999995Q7.3625371,4.7767504,7.4444296,4.8314693Q7.5263224,4.8861883,7.6173165,4.9238794Q7.7083106,4.9615704,7.8049096,4.9807851Q7.9015086,4.9999999,8,5L9.137146,5L8,13L7,13Q6.90150857,13,6.80490965,13.019215Q6.70831072,13.038429,6.6173164799999995,13.07612Q6.52632231,13.113811,6.44442973,13.16853Q6.36253715,13.223249,6.2928932,13.292892Q6.22324926,13.362536,6.16853037,13.444429Q6.11381148,13.526321,6.076120459,13.617315Q6.038429435,13.708309,6.019214718,13.804909Q6,13.901508,6,14Q6,14.098491,6.019214718,14.195089Q6.038429435,14.291689,6.076120459,14.382683Q6.11381148,14.473677,6.16853037,14.555569Q6.22324926,14.637462,6.2928932,14.707106Q6.36253715,14.77675,6.44442976,14.831469Q6.52632231,14.886187,6.6173164799999995,14.923878Q6.70831072,14.961569,6.80490965,14.980784Q6.90150857,15,7,15L11,15Q11.0984912,15,11.1950898,14.980784Q11.2916889,14.961569,11.382682800000001,14.923878Q11.473677200000001,14.886187,11.5555696,14.831469Q11.6374626,14.77675,11.7071066,14.707106Q11.7767506,14.637462,11.8314691,14.555569Q11.8861876,14.473677,11.9238791,14.382683Q11.9615698,14.291689,11.9807849,14.195089Q12,14.098491,12,14Q12,13.901508,11.9807849,13.804909Q11.9615698,13.708309,11.9238791,13.617315Q11.8861876,13.526321,11.8314691,13.444428Q11.7767506,13.362536,11.7071066,13.292892Q11.6374626,13.223249,11.5555701,13.16853Q11.473677200000001,13.113811,11.382682800000001,13.07612Q11.2916889,13.038429,11.1950903,13.019215Q11.0984912,13,11,13L9.8626451,13L11,5L12,5Q12.0984907,4.9999999,12.1950893,4.9807851Q12.2916884,4.9615703,12.382682800000001,4.9238793Q12.4736767,4.8861883,12.5555696,4.8314693Q12.6374621,4.7767504,12.7071061,4.7071065999999995Q12.776750100000001,4.6374626,12.831468600000001,4.5555699Q12.8861876,4.4736774,12.9238787,4.3826833Q12.9615698,4.291689,12.9807849,4.1950902Q12.999999500000001,4.0984913,13,4Q12.999999500000001,3.90150857,12.980784400000001,3.80490965Q12.9615698,3.70831072,12.9238787,3.61731648Q12.8861876,3.52632231,12.8314691,3.44442973Q12.7767506,3.36253715,12.7071066,3.2928932Q12.6374626,3.2232492600000002,12.5555696,3.16853037Q12.4736767,3.11381148,12.382682800000001,3.076120459Q12.2916884,3.038429435,12.1950898,3.019214718Q12.0984907,3,12,3L8,3Z" fill-rule="evenodd" fill="#555555" fill-opacity="1"/></g></g></svg>`;
|
|
20246
20379
|
const underlineSVG = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="18" height="18" viewBox="0 0 18 18"><g><g style="opacity:0;"><rect x="0" y="0" width="18" height="18" rx="0" fill="#FFFFFF" fill-opacity="1"/></g><g><path d="M5.000117301940918,14.500022450683593L5.000117301940918,14.500022450683593Q5.000117301940918,14.450777450683594,5.009724660740918,14.402477450683593Q5.019332019940918,14.354177450683594,5.038177530940918,14.308679450683593Q5.057023040940918,14.263182450683594,5.084382488940918,14.222236450683594Q5.111741931940918,14.181290450683594,5.146563901940918,14.146469450683593Q5.181385871940918,14.111646450683594,5.222332181940918,14.084286450683594Q5.263278451940918,14.056927450683594,5.308775541940918,14.038082450683595Q5.354272661940918,14.019237450683594,5.402572121940918,14.009630450683593Q5.450871581940918,14.000022450683593,5.500117301940918,14.000022450683593L12.500117301940918,14.000022450683593Q12.549362201940918,14.000022450683593,12.597661501940918,14.009629450683594Q12.645960801940918,14.019237450683594,12.691457701940918,14.038082450683595Q12.736954701940917,14.056926450683594,12.777901601940918,14.084285450683593Q12.818847701940918,14.111645450683593,12.853670101940917,14.146468450683594Q12.888492101940919,14.181289450683593,12.915851601940918,14.222235450683593Q12.943210601940919,14.263181450683593,12.962056201940918,14.308679450683593Q12.980901701940919,14.354177450683594,12.990509501940917,14.402477450683593Q13.00011680194092,14.450777450683594,13.000117301940918,14.500022450683593L13.000117301940918,14.500022450683593Q13.00011680194092,14.549268450683593,12.990509001940918,14.597566450683594Q12.980901701940919,14.645866450683593,12.962056201940918,14.691363450683594Q12.943210601940919,14.736860450683594,12.915851601940918,14.777807450683595Q12.888492101940919,14.818753450683595,12.853670101940917,14.853575450683593Q12.818847701940918,14.888397450683593,12.777901601940918,14.915756450683594Q12.736954701940917,14.943115450683594,12.691457701940918,14.961960450683593Q12.645960801940918,14.980806450683593,12.597661501940918,14.990413450683594Q12.549362201940918,15.000021450683594,12.500117301940918,15.000022450683593L5.500117301940918,15.000022450683593Q5.450871581940918,15.000021450683594,5.402572121940918,14.990414450683593Q5.354272661940918,14.980806450683593,5.308775541940918,14.961960450683593Q5.263278451940918,14.943115450683594,5.222332161940918,14.915756450683594Q5.181385871940918,14.888397450683593,5.146563901940918,14.853574450683594Q5.111741931940918,14.818752450683593,5.084382488940918,14.777806450683594Q5.057023040940918,14.736860450683594,5.038177530940918,14.691363450683594Q5.019332019940918,14.645866450683593,5.009724660740918,14.597567450683593Q5.000117301940918,14.549268450683593,5.000117301940918,14.500022450683593ZM5.045039176940918,3.548906330683594Q5.045039176940918,3.1015625006835936,5.283039211940918,2.8637809706835937Q5.521039131940918,2.6259994506835938,5.969039081940918,2.6259994506835938L5.997039201940918,2.6259994506835938Q6.445039201940918,2.6259994506835938,6.6830393019409176,2.8637809706835937Q6.921039201940918,3.1015625006835936,6.921039201940918,3.548906330683594L6.921039201940918,9.010000250683593Q6.921039201940918,9.737999950683594,7.180039401940919,10.255999550683594Q7.439039201940918,10.774000150683595,7.908039101940918,11.053999950683593Q8.377039001940918,11.333999650683594,8.993039101940917,11.333999650683594Q9.609039301940918,11.333999650683594,10.085039101940918,11.060999850683594Q10.561039401940917,10.788000150683594,10.820039301940918,10.263000450683593Q11.079039101940918,9.737999950683594,11.079039101940918,9.010000250683593L11.079039101940918,3.548906330683594Q11.079039101940918,3.1015625006835936,11.317039501940918,2.8637809706835937Q11.555039401940917,2.6259994506835938,12.003039401940917,2.6259994506835938L12.031039201940917,2.6259994506835938Q12.479039201940918,2.6259994506835938,12.717039101940918,2.8637809706835937Q12.955039001940918,3.1015625006835936,12.955039001940918,3.548906330683594L12.955039001940918,9.010000250683593Q12.955039001940918,10.144000050683594,12.416039501940919,11.095999750683594Q11.877039901940918,12.048000350683594,10.967039101940918,12.600999850683595Q10.057039301940918,13.154000450683593,8.993039101940917,13.154000450683593Q7.929039001940918,13.154000450683593,7.0190392019409185,12.600999850683595Q6.109039201940918,12.048000350683594,5.577039361940918,11.095999750683594Q5.045039176940918,10.144000050683594,5.045039176940918,9.010000250683593L5.045039176940918,3.548906330683594Z" fill="#555555" fill-opacity="1"/></g></g></svg>`;
|
|
@@ -20334,7 +20467,14 @@
|
|
|
20334
20467
|
const showMoreToolbar = vue.ref(false);
|
|
20335
20468
|
const canUndo = vue.ref(false);
|
|
20336
20469
|
const canRedo = vue.ref(false);
|
|
20470
|
+
const showLinkDialog = vue.ref(false);
|
|
20471
|
+
const linkUrl = vue.ref('');
|
|
20472
|
+
const linkText = vue.ref('');
|
|
20473
|
+
const canUseLink = vue.ref(false);
|
|
20474
|
+
const linkPosition = vue.ref({ top: 0, left: 0 });
|
|
20475
|
+
const savedRange = vue.ref(null);
|
|
20337
20476
|
const { setQuill, removeQuillBlotFormatter, configureBlotFormatter, applyImageStyle, registerBlotFormatter, getBlotFormatterConfig } = useBlotFormatter(editor, props.enableImageResize);
|
|
20477
|
+
const { setQuill: setLinkQuill, setHandleCustomLink, addLinkClickListener } = useLinkClick(editor);
|
|
20338
20478
|
vue.onMounted(() => {
|
|
20339
20479
|
initialize();
|
|
20340
20480
|
});
|
|
@@ -20379,6 +20519,7 @@
|
|
|
20379
20519
|
icons['underline'] = underlineSVG;
|
|
20380
20520
|
icons['more'] = moreSVG;
|
|
20381
20521
|
icons['link'] = linkSVG;
|
|
20522
|
+
icons['customLink'] = linkSVG;
|
|
20382
20523
|
icons['undo'] = undoSVG;
|
|
20383
20524
|
icons['redo'] = redoSVG;
|
|
20384
20525
|
icons['ocr'] = ocrSVG;
|
|
@@ -20408,6 +20549,7 @@
|
|
|
20408
20549
|
if (toolbar) {
|
|
20409
20550
|
const undoBtn = toolbar.querySelector('.ql-undo');
|
|
20410
20551
|
const redoBtn = toolbar.querySelector('.ql-redo');
|
|
20552
|
+
const customLinkBtn = toolbar.querySelector('.ql-customLink');
|
|
20411
20553
|
if (undoBtn) {
|
|
20412
20554
|
if (canUndo.value) {
|
|
20413
20555
|
undoBtn.classList.remove('ql-disabled');
|
|
@@ -20426,10 +20568,19 @@
|
|
|
20426
20568
|
}
|
|
20427
20569
|
redoBtn.disabled = !canRedo.value;
|
|
20428
20570
|
}
|
|
20571
|
+
if (customLinkBtn) {
|
|
20572
|
+
if (canUseLink.value) {
|
|
20573
|
+
customLinkBtn.classList.remove('ql-disabled');
|
|
20574
|
+
}
|
|
20575
|
+
else {
|
|
20576
|
+
customLinkBtn.classList.add('ql-disabled');
|
|
20577
|
+
}
|
|
20578
|
+
customLinkBtn.disabled = !canUseLink.value;
|
|
20579
|
+
}
|
|
20429
20580
|
}
|
|
20430
20581
|
};
|
|
20431
20582
|
const initialize = () => {
|
|
20432
|
-
var _a
|
|
20583
|
+
var _a;
|
|
20433
20584
|
if (!editor.value)
|
|
20434
20585
|
return;
|
|
20435
20586
|
if (props.enableImageResize) {
|
|
@@ -20439,20 +20590,28 @@
|
|
|
20439
20590
|
setIcons();
|
|
20440
20591
|
quill = new Quill(editor.value, options);
|
|
20441
20592
|
setQuill(quill);
|
|
20442
|
-
|
|
20443
|
-
|
|
20444
|
-
toolbar.style.display = 'none';
|
|
20445
|
-
}
|
|
20593
|
+
setLinkQuill(quill);
|
|
20594
|
+
controlToolbarVisible(false);
|
|
20446
20595
|
setContents(props.content);
|
|
20447
20596
|
quill.on('text-change', handleTextChange);
|
|
20448
20597
|
quill.on('selection-change', handleSelectionChange);
|
|
20449
20598
|
quill.on('editor-change', handleEditorChange);
|
|
20450
20599
|
quill.on('text-change', updateHistoryState);
|
|
20451
20600
|
quill.on('selection-change', updateHistoryState);
|
|
20601
|
+
addLinkClickListener();
|
|
20452
20602
|
updateHistoryState();
|
|
20453
|
-
const toolbarDom = (
|
|
20454
|
-
|
|
20455
|
-
|
|
20603
|
+
const toolbarDom = (_a = quill.getModule('toolbar')) === null || _a === void 0 ? void 0 : _a.container;
|
|
20604
|
+
vue.nextTick(() => {
|
|
20605
|
+
const customLinkBtn = toolbarDom.querySelector('.ql-customLink');
|
|
20606
|
+
if (customLinkBtn) {
|
|
20607
|
+
customLinkBtn.addEventListener('click', (e) => {
|
|
20608
|
+
e.preventDefault();
|
|
20609
|
+
e.stopPropagation();
|
|
20610
|
+
if (canUseLink.value) {
|
|
20611
|
+
handleCustomLink(true);
|
|
20612
|
+
}
|
|
20613
|
+
});
|
|
20614
|
+
}
|
|
20456
20615
|
});
|
|
20457
20616
|
const tooltipInput = toolbarDom.querySelector('.ql-tooltip input');
|
|
20458
20617
|
if (tooltipInput) {
|
|
@@ -20488,6 +20647,11 @@
|
|
|
20488
20647
|
...toolbarOptions.full,
|
|
20489
20648
|
],
|
|
20490
20649
|
handlers: {
|
|
20650
|
+
customLink: function () {
|
|
20651
|
+
if (canUseLink.value) {
|
|
20652
|
+
handleCustomLink(true);
|
|
20653
|
+
}
|
|
20654
|
+
},
|
|
20491
20655
|
redo: function () {
|
|
20492
20656
|
var _a;
|
|
20493
20657
|
if (canRedo.value) {
|
|
@@ -20565,22 +20729,25 @@
|
|
|
20565
20729
|
preview.setAttribute('href', 'javascript:void(0)');
|
|
20566
20730
|
preview.setAttribute('target', '_self');
|
|
20567
20731
|
};
|
|
20732
|
+
const controlToolbarVisible = (visible) => {
|
|
20733
|
+
var _a;
|
|
20734
|
+
const toolbar = (_a = quill === null || quill === void 0 ? void 0 : quill.getModule('toolbar')) === null || _a === void 0 ? void 0 : _a.container;
|
|
20735
|
+
if (toolbar) {
|
|
20736
|
+
toolbar.style.display = visible ? 'block' : 'none';
|
|
20737
|
+
props.needCollapse && (showMoreToolbar.value = false);
|
|
20738
|
+
ctx.emit('toolbarVisibleChange', visible);
|
|
20739
|
+
}
|
|
20740
|
+
};
|
|
20568
20741
|
const isEditorFocus = vue.ref();
|
|
20569
20742
|
const handleSelectionChange = (range, oldRange, source) => {
|
|
20570
|
-
var _a;
|
|
20571
20743
|
observeTooltip();
|
|
20572
20744
|
isEditorFocus.value = !!(quill === null || quill === void 0 ? void 0 : quill.hasFocus());
|
|
20573
|
-
|
|
20574
|
-
if (
|
|
20575
|
-
|
|
20576
|
-
|
|
20577
|
-
|
|
20578
|
-
|
|
20579
|
-
else {
|
|
20580
|
-
toolbar.style.display = 'none';
|
|
20581
|
-
showMoreToolbar.value = false;
|
|
20582
|
-
ctx.emit('toolbarVisibleChange', true);
|
|
20583
|
-
}
|
|
20745
|
+
canUseLink.value = !!(range && range.length > 0);
|
|
20746
|
+
if (isEditorFocus.value) {
|
|
20747
|
+
controlToolbarVisible(true);
|
|
20748
|
+
}
|
|
20749
|
+
else {
|
|
20750
|
+
controlToolbarVisible(false);
|
|
20584
20751
|
}
|
|
20585
20752
|
ctx.emit('selectionChange', { range, oldRange, source });
|
|
20586
20753
|
};
|
|
@@ -20710,6 +20877,79 @@
|
|
|
20710
20877
|
else if (tool === 'more') {
|
|
20711
20878
|
showMoreToolbar.value = !showMoreToolbar.value;
|
|
20712
20879
|
}
|
|
20880
|
+
else if (tool === 'customLink') {
|
|
20881
|
+
handleCustomLink(true);
|
|
20882
|
+
}
|
|
20883
|
+
};
|
|
20884
|
+
const calculateSelectionPosition = (range) => {
|
|
20885
|
+
if (!quill)
|
|
20886
|
+
return { top: 0, left: 0 };
|
|
20887
|
+
const selectionRange = range || quill.getSelection();
|
|
20888
|
+
if (!selectionRange || selectionRange.length === 0)
|
|
20889
|
+
return { top: 0, left: 0 };
|
|
20890
|
+
try {
|
|
20891
|
+
const bounds = quill.getBounds(selectionRange.index, selectionRange.length);
|
|
20892
|
+
return {
|
|
20893
|
+
top: bounds.top + bounds.height + 5,
|
|
20894
|
+
left: bounds.left
|
|
20895
|
+
};
|
|
20896
|
+
}
|
|
20897
|
+
catch (error) {
|
|
20898
|
+
console.warn('计算选中位置时出错:', error);
|
|
20899
|
+
return { top: 0, left: 0 };
|
|
20900
|
+
}
|
|
20901
|
+
};
|
|
20902
|
+
const handleCustomLink = (bool, linkInfo) => {
|
|
20903
|
+
if (!quill)
|
|
20904
|
+
return;
|
|
20905
|
+
if (bool) {
|
|
20906
|
+
controlToolbarVisible(false);
|
|
20907
|
+
if (linkInfo) {
|
|
20908
|
+
linkUrl.value = linkInfo.url;
|
|
20909
|
+
linkText.value = linkInfo.text;
|
|
20910
|
+
const range = quill.getSelection();
|
|
20911
|
+
savedRange.value = range ? { ...range } : null;
|
|
20912
|
+
}
|
|
20913
|
+
else {
|
|
20914
|
+
const range = quill.getSelection();
|
|
20915
|
+
if (range && range.length > 0) {
|
|
20916
|
+
savedRange.value = { ...range };
|
|
20917
|
+
const selectedText = quill.getText(range.index, range.length);
|
|
20918
|
+
linkText.value = selectedText;
|
|
20919
|
+
}
|
|
20920
|
+
else {
|
|
20921
|
+
savedRange.value = range ? { ...range } : null;
|
|
20922
|
+
linkText.value = '';
|
|
20923
|
+
}
|
|
20924
|
+
}
|
|
20925
|
+
const range = quill.getSelection();
|
|
20926
|
+
linkPosition.value = calculateSelectionPosition(range || undefined);
|
|
20927
|
+
}
|
|
20928
|
+
else {
|
|
20929
|
+
savedRange.value = null;
|
|
20930
|
+
}
|
|
20931
|
+
showLinkDialog.value = bool;
|
|
20932
|
+
};
|
|
20933
|
+
setHandleCustomLink(handleCustomLink);
|
|
20934
|
+
const saveLink = (data) => {
|
|
20935
|
+
console.log("data", data);
|
|
20936
|
+
if (!quill || !data.url.trim())
|
|
20937
|
+
return;
|
|
20938
|
+
const range = savedRange.value;
|
|
20939
|
+
if (!range)
|
|
20940
|
+
return;
|
|
20941
|
+
if (range.length > 0) {
|
|
20942
|
+
quill.formatText(range.index, range.length, 'link', data.url);
|
|
20943
|
+
}
|
|
20944
|
+
else {
|
|
20945
|
+
const text = data.text || data.url;
|
|
20946
|
+
quill.insertText(range.index, text, { link: data.url });
|
|
20947
|
+
quill.setSelection(range.index + text.length, 0);
|
|
20948
|
+
}
|
|
20949
|
+
showLinkDialog.value = false;
|
|
20950
|
+
linkUrl.value = '';
|
|
20951
|
+
linkText.value = '';
|
|
20952
|
+
savedRange.value = null;
|
|
20713
20953
|
};
|
|
20714
20954
|
vue.watch(() => props.content, (newContent) => {
|
|
20715
20955
|
if (!quill || internalModelEquals(newContent))
|
|
@@ -20730,6 +20970,11 @@
|
|
|
20730
20970
|
showMoreToolbar,
|
|
20731
20971
|
canUndo,
|
|
20732
20972
|
canRedo,
|
|
20973
|
+
canUseLink,
|
|
20974
|
+
showLinkDialog,
|
|
20975
|
+
linkUrl,
|
|
20976
|
+
linkText,
|
|
20977
|
+
linkPosition,
|
|
20733
20978
|
getEditor,
|
|
20734
20979
|
getToolbar,
|
|
20735
20980
|
getQuill,
|
|
@@ -20742,12 +20987,18 @@
|
|
|
20742
20987
|
getText,
|
|
20743
20988
|
setText,
|
|
20744
20989
|
reinit,
|
|
20745
|
-
moreToolbarToolClick
|
|
20990
|
+
moreToolbarToolClick,
|
|
20991
|
+
saveLink,
|
|
20992
|
+
handleCustomLink
|
|
20746
20993
|
};
|
|
20747
20994
|
},
|
|
20748
20995
|
render() {
|
|
20749
20996
|
return [
|
|
20750
|
-
vue.h('div', {
|
|
20997
|
+
vue.h('div', {
|
|
20998
|
+
class: this.editorWrapClass, onClick: () => {
|
|
20999
|
+
this.handleCustomLink(false);
|
|
21000
|
+
}
|
|
21001
|
+
}, [
|
|
20751
21002
|
this.$props.needCollapse && this.$props.editorKey && vue.h(MoreToolbar, {
|
|
20752
21003
|
editorKey: String(this.$props.editorKey),
|
|
20753
21004
|
needCollapse: this.needCollapse,
|
|
@@ -20760,8 +21011,19 @@
|
|
|
20760
21011
|
}
|
|
20761
21012
|
}),
|
|
20762
21013
|
vue.h('div', {
|
|
20763
|
-
ref: 'editor',
|
|
21014
|
+
ref: 'editor',
|
|
21015
|
+
style: { position: 'relative' },
|
|
21016
|
+
...this.$attrs
|
|
20764
21017
|
}),
|
|
21018
|
+
vue.h(CustomLink, {
|
|
21019
|
+
visible: this.showLinkDialog,
|
|
21020
|
+
position: this.linkPosition,
|
|
21021
|
+
linkUrl: this.linkUrl,
|
|
21022
|
+
linkText: this.linkText,
|
|
21023
|
+
'onUpdate:linkUrl': (value) => { this.linkUrl = value; },
|
|
21024
|
+
'onUpdate:linkText': (value) => { this.linkText = value; },
|
|
21025
|
+
onSave: this.saveLink,
|
|
21026
|
+
})
|
|
20765
21027
|
]),
|
|
20766
21028
|
];
|
|
20767
21029
|
},
|