@wangeditor-next/plugin-attachment 6.1.1 → 6.3.0

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.
@@ -9,6 +9,8 @@
9
9
  */
10
10
  export declare const BOLD_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M707.872 484.64A254.88 254.88 0 0 0 768 320c0-141.152-114.848-256-256-256H192v896h384c141.152 0 256-114.848 256-256a256.096 256.096 0 0 0-124.128-219.36zM384 192h101.504c55.968 0 101.504 57.408 101.504 128s-45.536 128-101.504 128H384V192z m159.008 640H384v-256h159.008c58.464 0 106.016 57.408 106.016 128s-47.552 128-106.016 128z\"></path></svg>";
11
11
  export declare const UNDER_LINE_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M704 64l128 0 0 416c0 159.072-143.264 288-320 288s-320-128.928-320-288l0-416 128 0 0 416c0 40.16 18.24 78.688 51.36 108.512 36.896 33.216 86.848 51.488 140.64 51.488s103.744-18.304 140.64-51.488c33.12-29.792 51.36-68.352 51.36-108.512l0-416zM192 832l640 0 0 128-640 0z\"></path></svg>";
12
+ export declare const WAVY_UNDERLINE_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M64 704c64-96 128-96 192 0s128 96 192 0 128-96 192 0 128 96 192 0 128-96 192 0v128c-64 96-128 96-192 0s-128-96-192 0-128 96-192 0-128-96-192 0-128 96-192 0V704z\"></path></svg>";
13
+ export declare const EMPHASIS_DOT_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M256 128h128v512H256zM448 128h128v512H448zM640 128h128v512H640z\"></path><path d=\"M320 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM512 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM704 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0z\"></path></svg>";
12
14
  export declare const ITALIC_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M896 64v64h-128L448 896h128v64H128v-64h128L576 128h-128V64z\"></path></svg>";
13
15
  export declare const THROUGH_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M1024 512v64h-234.496c27.52 38.496 42.496 82.688 42.496 128 0 70.88-36.672 139.04-100.576 186.976C672.064 935.488 594.144 960 512 960s-160.064-24.512-219.424-69.024C228.64 843.04 192 774.88 192 704h128c0 69.376 87.936 128 192 128s192-58.624 192-128-87.936-128-192-128H0v-64h299.52a385.984 385.984 0 0 1-6.944-5.024C228.64 459.04 192 390.88 192 320s36.672-139.04 100.576-186.976C351.936 88.512 429.856 64 512 64s160.064 24.512 219.424 69.024C795.328 180.96 832 249.12 832 320h-128c0-69.376-87.936-128-192-128s-192 58.624-192 128 87.936 128 192 128c78.976 0 154.048 22.688 212.48 64H1024z\"></path></svg>";
14
16
  export declare const CODE_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M576 736l96 96 320-320L672 192l-96 96 224 224zM448 288l-96-96L32 512l320 320 96-96-224-224z\"></path></svg>";
@@ -90,6 +90,8 @@ declare const _default: {
90
90
  sup: string;
91
91
  through: string;
92
92
  underline: string;
93
+ wavyUnderline: string;
94
+ emphasisDot: string;
93
95
  };
94
96
  undo: {
95
97
  undo: string;
@@ -90,6 +90,8 @@ declare const _default: {
90
90
  sup: string;
91
91
  through: string;
92
92
  underline: string;
93
+ wavyUnderline: string;
94
+ emphasisDot: string;
93
95
  };
94
96
  undo: {
95
97
  undo: string;
@@ -12,6 +12,7 @@ declare class EditLinkMenu implements IModalMenu {
12
12
  readonly showModal = true;
13
13
  readonly modalWidth = 300;
14
14
  private $content;
15
+ private textInputId;
15
16
  private urlInputId;
16
17
  private buttonId;
17
18
  private getSelectedLinkElem;
@@ -9,6 +9,8 @@ export type StyledText = {
9
9
  italic?: boolean;
10
10
  through?: boolean;
11
11
  underline?: boolean;
12
+ wavyUnderline?: boolean;
13
+ emphasisDot?: boolean;
12
14
  sup?: boolean;
13
15
  sub?: boolean;
14
16
  };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @description lower dot emphasis menu
3
+ */
4
+ import BaseMenu from './BaseMenu';
5
+ declare class EmphasisDotMenu extends BaseMenu {
6
+ readonly mark = "emphasisDot";
7
+ readonly title: string;
8
+ readonly iconSvg = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M256 128h128v512H256zM448 128h128v512H448zM640 128h128v512H640z\"></path><path d=\"M320 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM512 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM704 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0z\"></path></svg>";
9
+ readonly hotkey = "";
10
+ }
11
+ export default EmphasisDotMenu;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @description wavy underline menu
3
+ */
4
+ import BaseMenu from './BaseMenu';
5
+ declare class WavyUnderlineMenu extends BaseMenu {
6
+ readonly mark = "wavyUnderline";
7
+ readonly title: string;
8
+ readonly iconSvg = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M64 704c64-96 128-96 192 0s128 96 192 0 128-96 192 0 128 96 192 0 128-96 192 0v128c-64 96-128 96-192 0s-128-96-192 0-128 96-192 0-128-96-192 0-128 96-192 0V704z\"></path></svg>";
9
+ readonly hotkey = "";
10
+ }
11
+ export default WavyUnderlineMenu;
@@ -5,11 +5,13 @@
5
5
  import BoldMenu from './BoldMenu';
6
6
  import ClearStyleMenu from './ClearStyleMenu';
7
7
  import CodeMenu from './CodeMenu';
8
+ import EmphasisDotMenu from './EmphasisDotMenu';
8
9
  import ItalicMenu from './ItalicMenu';
9
10
  import SubMenu from './SubMenu';
10
11
  import SupMenu from './SupMenu';
11
12
  import ThroughMenu from './ThroughMenu';
12
13
  import UnderlineMenu from './UnderlineMenu';
14
+ import WavyUnderlineMenu from './WavyUnderlineMenu';
13
15
  export declare const boldMenuConf: {
14
16
  key: string;
15
17
  factory(): BoldMenu;
@@ -30,6 +32,14 @@ export declare const underlineMenuConf: {
30
32
  key: string;
31
33
  factory(): UnderlineMenu;
32
34
  };
35
+ export declare const wavyUnderlineMenuConf: {
36
+ key: string;
37
+ factory(): WavyUnderlineMenu;
38
+ };
39
+ export declare const emphasisDotMenuConf: {
40
+ key: string;
41
+ factory(): EmphasisDotMenu;
42
+ };
33
43
  export declare const supMenuConf: {
34
44
  key: string;
35
45
  factory(): SupMenu;
@@ -2,6 +2,7 @@
2
2
  * @description render text style
3
3
  * @author wangfupeng
4
4
  */
5
+ import { IDomEditor } from '@wangeditor-next/core';
5
6
  import { Descendant } from 'slate';
6
7
  import { VNode } from 'snabbdom';
7
8
  /**
@@ -10,4 +11,4 @@ import { VNode } from 'snabbdom';
10
11
  * @param vnode vnode
11
12
  * @returns vnode
12
13
  */
13
- export declare function renderStyle(node: Descendant, vnode: VNode): VNode;
14
+ export declare function renderStyle(node: Descendant, vnode: VNode, editor?: IDomEditor): VNode;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @description CSS values shared by text-style render and HTML serialization
3
+ */
4
+ export declare const UNDERLINE_OFFSET = "0.15em";
5
+ export declare const WAVY_UNDERLINE_OFFSET = "0.3em";
6
+ export declare const WAVY_UNDERLINE_WITH_EMPHASIS_OFFSET = "0.8em";
7
+ export declare const EMPHASIS_DOT_WITH_WAVY_LINE_HEIGHT = "2";
8
+ export declare const UNDERLINE_OFFSET_CLASS = "w-e-text-style-underline-offset";
9
+ export declare const WAVY_UNDERLINE_CLASS = "w-e-text-style-wavy-underline";
10
+ export declare const WAVY_UNDERLINE_WITH_EMPHASIS_CLASS = "w-e-text-style-wavy-underline-with-emphasis";
11
+ export declare const EMPHASIS_DOT_CLASS = "w-e-text-style-emphasis-dot";
12
+ export declare const EMPHASIS_DOT_WITH_WAVY_CLASS = "w-e-text-style-emphasis-dot-with-wavy";
13
+ export declare const WAVY_UNDERLINE_STYLE: {
14
+ textDecorationLine: string;
15
+ textDecorationStyle: string;
16
+ textUnderlineOffset: string;
17
+ };
18
+ export declare const WAVY_UNDERLINE_STYLE_HTML = "text-decoration-line: underline; text-decoration-style: wavy; text-underline-offset: 0.3em;";
19
+ export declare const WAVY_UNDERLINE_WITH_EMPHASIS_STYLE: {
20
+ textUnderlineOffset: string;
21
+ textDecorationLine: string;
22
+ textDecorationStyle: string;
23
+ };
24
+ export declare const WAVY_UNDERLINE_WITH_EMPHASIS_STYLE_HTML = "text-decoration-line: underline; text-decoration-style: wavy; text-underline-offset: 0.8em;";
25
+ export declare const EMPHASIS_DOT_STYLE: {
26
+ textEmphasisStyle: string;
27
+ textEmphasisPosition: string;
28
+ };
29
+ export declare const EMPHASIS_DOT_STYLE_HTML = "text-emphasis-style: filled dot; text-emphasis-position: under left;";
30
+ export declare const EMPHASIS_DOT_WITH_WAVY_STYLE: {
31
+ lineHeight: string;
32
+ textEmphasisStyle: string;
33
+ textEmphasisPosition: string;
34
+ };
35
+ export declare const EMPHASIS_DOT_WITH_WAVY_STYLE_HTML = "text-emphasis-style: filled dot; text-emphasis-position: under left; line-height: 2;";
@@ -2,6 +2,7 @@
2
2
  * @description text to html
3
3
  * @author wangfupeng
4
4
  */
5
+ import { IDomEditor } from '@wangeditor-next/core';
5
6
  import { Descendant } from 'slate';
6
7
  /**
7
8
  * style to html
@@ -9,4 +10,4 @@ import { Descendant } from 'slate';
9
10
  * @param textHtml text html
10
11
  * @returns styled html
11
12
  */
12
- export declare function styleToHtml(textNode: Descendant, textHtml: string): string;
13
+ export declare function styleToHtml(textNode: Descendant, textHtml: string, editor?: IDomEditor): string;
@@ -10,7 +10,7 @@ import DOMText = globalThis.Text;
10
10
  import DOMRange = globalThis.Range;
11
11
  import DOMSelection = globalThis.Selection;
12
12
  import DOMStaticRange = globalThis.StaticRange;
13
- export { Dom7Array } from 'dom7';
13
+ export type { Dom7Array } from 'dom7';
14
14
  export default $;
15
15
  /**
16
16
  * 判断 str 是不是纯字符串,而不是 html tag
@@ -10,6 +10,6 @@ import DOMText = globalThis.Text;
10
10
  import DOMRange = globalThis.Range;
11
11
  import DOMSelection = globalThis.Selection;
12
12
  import DOMStaticRange = globalThis.StaticRange;
13
- export { Dom7Array } from 'dom7';
13
+ export type { Dom7Array } from 'dom7';
14
14
  export default $;
15
15
  export { DOMComment, DOMElement, DOMNode, DOMRange, DOMSelection, DOMStaticRange, DOMText, };
@@ -155,6 +155,8 @@ interface ICodeBlockConfig {
155
155
  export interface IMenuConfig {
156
156
  bold: ISingleMenuConfig;
157
157
  underline: ISingleMenuConfig;
158
+ wavyUnderline: ISingleMenuConfig;
159
+ emphasisDot: ISingleMenuConfig;
158
160
  italic: ISingleMenuConfig;
159
161
  through: ISingleMenuConfig;
160
162
  code: ISingleMenuConfig;
@@ -10,7 +10,7 @@ import DOMText = globalThis.Text;
10
10
  import DOMRange = globalThis.Range;
11
11
  import DOMSelection = globalThis.Selection;
12
12
  import DOMStaticRange = globalThis.StaticRange;
13
- export { Dom7Array } from 'dom7';
13
+ export type { Dom7Array } from 'dom7';
14
14
  export default $;
15
15
  export declare enum NodeType {
16
16
  ELEMENT_NODE = 1,
@@ -3,6 +3,13 @@
3
3
  * @author wangfupeng
4
4
  */
5
5
  import './assets/index.less';
6
+ import '@wangeditor-next/core/dist/css/style.css';
7
+ import '@wangeditor-next/basic-modules/dist/css/style.css';
8
+ import '@wangeditor-next/code-highlight/dist/css/style.css';
9
+ import '@wangeditor-next/list-module/dist/css/style.css';
10
+ import '@wangeditor-next/table-module/dist/css/style.css';
11
+ import '@wangeditor-next/upload-image-module/dist/css/style.css';
12
+ import '@wangeditor-next/video-module/dist/css/style.css';
6
13
  import './utils/browser-polyfill';
7
14
  import './utils/node-polyfill';
8
15
  import './locale/index';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@wangeditor-next/editor"),require("dom7"),require("snabbdom")):"function"==typeof define&&define.amd?define(["exports","@wangeditor-next/editor","dom7","snabbdom"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).WangEditorAttachmentPlugin={},e.editor,e.$,e.snabbdom)}(this,function(e,t,n,r){"use strict";t.i18nAddResources("en",{attachment:{upload:"Upload Attachment",download:"Download Attachment"}}),t.i18nAddResources("zh-CN",{attachment:{upload:"上传附件",download:"下载附件"}});var o={type:"attachment",elemToHtml:function(e,t){var n=e,r=n.link,o=void 0===r?"":r,i=n.fileName,a=void 0===i?"":i;return'<a data-w-e-type="attachment" data-w-e-is-void data-w-e-is-inline href="'.concat(o,'" download="').concat(a,'">').concat(a,"</a>")}};function i(){return{server:"",fieldName:"wangeditor-uploaded-attachment",maxFileSize:10485760,maxNumberOfFiles:5,allowedFileTypes:["*"],meta:{},metaWithUrl:!1,withCredentials:!1,timeout:3e4,onBeforeUpload:function(e){return e},onProgress:function(e){},onSuccess:function(e,t){},onFailed:function(e,t){},onError:function(e,t,n){},onInsertedAttachment:function(e){}}}var a=function(){function e(){this.title=t.t("attachment.download"),this.iconSvg='<svg viewBox="0 0 1024 1024"><path d="M736 448l-256 256-256-256h160V64h192v384z m-256 256H0v256h960v-256H480z m416 128h-128v-64h128v64z"></path></svg>',this.tag="button",this.alwaysEnable=!0}return e.prototype.getValue=function(e){var t=this.getSelectedElem(e);return null==t?"":t.link},e.prototype.isActive=function(e){return!1},e.prototype.exec=function(e,t){t&&"string"==typeof t&&window.open(t,"_blank")},e.prototype.isDisabled=function(e){var n=e.selection;return null==n||(!!t.SlateRange.isExpanded(n)||null==this.getSelectedElem(e))},e.prototype.getSelectedElem=function(e){var n=t.DomEditor.getSelectedNodeByType(e,"attachment");return null==n?null:n},e}();n.hide&&(n.fn.hide=n.hide),n.append&&(n.fn.append=n.append),n.click&&(n.fn.click=n.click),n.on&&(n.fn.on=n.on);var c=function(){return c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},c.apply(this,arguments)};function u(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function c(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(a,c)}u((r=r.apply(e,t||[])).next())})}function l(e,t){var n,r,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return a.next=c(0),a.throw=c(1),a.return=c(2),"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(c){return function(u){return function(c){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,c[0]&&(i=0)),i;)try{if(n=1,r&&(o=2&c[0]?r.return:c[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,c[1])).done)return o;switch(r=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return i.label++,{value:c[1],done:!1};case 5:i.label++,r=c[1],c=[0];continue;case 7:c=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==c[0]&&2!==c[0])){i=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){i.label=c[1];break}if(6===c[0]&&i.label<o[1]){i.label=o[1],o=c;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(c);break}o[2]&&i.ops.pop(),i.trys.pop();continue}c=t.call(e,i)}catch(e){c=[6,e],r=0}finally{n=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,u])}}}function s(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function d(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=s(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise(function(r,o){(function(e,t,n,r){Promise.resolve(r).then(function(t){e({value:t,done:n})},t)})(r,o,(t=e[n](t)).done,t.value)})}}}function f(e){var t={server:"",fieldName:"wangeditor-uploaded-attachment",maxFileSize:10485760,maxNumberOfFiles:5,allowedFileTypes:["*"],meta:{},metaWithUrl:!1,withCredentials:!1,timeout:3e4,onBeforeUpload:function(e){return e},onProgress:function(e){},onSuccess:function(e,t){},onFailed:function(e,t){},onError:function(e,t,n){},onInsertedAttachment:function(e){}},n=e.getMenuConfig("uploadAttachment");return c(c({},t),n||{})}function p(e,t,n){if(t&&n){e.restoreSelection();var r={type:"attachment",fileName:t,link:n,children:[{text:""}]};e.insertNode(r),e.move(1);var o=f(e).onInsertedAttachment;o&&o(r)}}"function"==typeof SuppressedError&&SuppressedError;var m=new WeakMap;function h(e){var n=m.get(e);if(null!=n)return n;var r=f(e),o=r.customInsert,i=r.onError,a=r.onFailed,u=r.onProgress,l=r.onSuccess;return n=t.createUploader(c(c({},r),{onProgress:function(t){e.showProgressBar(t),u&&u(t)},onSuccess:function(t,n){if(o)return o(n,t,function(t,n){return p(e,t,n)}),void l(t,n);var r=n||{},i=r.errno,c=void 0===i?1:i,u=r.data;if(0===c){var s=(void 0===u?{}:u).url,d=void 0===s?"":s;p(e,(null==t?void 0:t.name)||"",d),l(t,n)}else a(t,n)},onError:function(e,t,n){i(e,t,n)}}),e),m.set(e,n),n}function y(e,t){return u(this,void 0,void 0,function(){var n,r;return l(this,function(o){switch(o.label){case 0:return n=h(e),r=t.map(function(e){return{name:e.name,type:e.type,size:e.size,data:e}}),n.addFiles(r),[4,n.upload()];case 1:return o.sent(),[2]}})})}var v=function(){function e(){this.title=t.t("attachment.upload"),this.iconSvg='<svg viewBox="0 0 1024 1024"><path d="M665.821116 327.053068l-64.958782-64.926783-324.79391 324.729911c-53.822991 53.790991-53.822991 141.053355 0 194.844347s141.053355 53.790991 194.876346 0l389.752692-389.688693a229.531696 229.531696 0 0 0 0-324.729912 229.627694 229.627694 0 0 0-324.761911 0L126.727224 476.458266l-0.863984 0.831985c-125.085655 125.085655-125.085655 327.833853 0 452.887508 125.053655 125.053655 327.865853 125.053655 452.983507 0l0.831984-0.863984 0.031999 0.032 279.322763-279.290764-64.990781-64.926782-279.322763 279.258764-0.831984 0.831984a228.731711 228.731711 0 0 1-323.065943 0 228.603714 228.603714 0 0 1 0-322.969944l0.895983-0.831985-0.031999-0.063998L600.958332 132.208721c53.694993-53.726993 141.149353-53.726993 194.876346 0s53.694993 141.149353 0 194.844347L406.081986 716.741761c-17.919664 17.919664-47.039118 17.919664-64.958782 0a45.983138 45.983138 0 0 1 0-64.926783L665.917114 327.053068z"></path></svg>',this.tag="button"}return e.prototype.getValue=function(e){return""},e.prototype.isActive=function(e){return!1},e.prototype.exec=function(e,t){var r=this.getMenuConfig(e),o=r.allowedFileTypes,i=void 0===o?[]:o,a=r.customBrowseAndUpload;if(a)a(function(t,n){return p(e,t,n)});else{var c="";i.length>0&&(c='accept="'.concat(i.join(", "),'"'));var s=n("body"),m=n('<input type="file" '.concat(c," multiple/>"));m.hide(),s.append(m),m.click(),m.on("change",function(){var t=m[0].files;!function(e,t){u(this,void 0,void 0,function(){var n,r,o,i,a,c,u,s,m,h,v,g;return l(this,function(l){switch(l.label){case 0:if(null==t)return[2];n=Array.prototype.slice.call(t),r=f(e).customUpload,o=[],l.label=1;case 1:l.trys.push([1,8,9,14]),i=!0,a=d(n),l.label=2;case 2:return[4,a.next()];case 3:return c=l.sent(),(m=c.done)?[3,7]:(g=c.value,i=!1,u=g,r?[4,r(u,function(t,n){return p(e,t,n)},e)]:[3,5]);case 4:return l.sent(),[3,6];case 5:o.push(u),l.label=6;case 6:return i=!0,[3,2];case 7:return[3,14];case 8:return s=l.sent(),h={error:s},[3,14];case 9:return l.trys.push([9,,12,13]),i||m||!(v=a.return)?[3,11]:[4,v.call(a)];case 10:l.sent(),l.label=11;case 11:return[3,13];case 12:if(h)throw h.error;return[7];case 13:return[7];case 14:return o.length>0?[4,y(e,o)]:[3,16];case 15:l.sent(),l.label=16;case 16:return[2]}})})}(e,t)})}},e.prototype.isDisabled=function(e){var n=e.selection;if(null==n)return!0;if(t.SlateRange.isExpanded(n))return!0;var r=t.DomEditor.getSelectedElems(e);return!!r.some(function(t){return e.isVoid(t)})||!!r.some(function(e){return"pre"===t.DomEditor.getNodeType(e)})},e.prototype.getMenuConfig=function(e){return e.getMenuConfig("uploadAttachment")},e}();var g={editorPlugin:function(e){var n=e.isInline,r=e.isVoid,o=e;return o.isInline=function(e){return"attachment"===t.DomEditor.getNodeType(e)||n(e)},o.isVoid=function(e){return"attachment"===t.DomEditor.getNodeType(e)||r(e)},o},renderElems:[{type:"attachment",renderElem:function(e,n,o){var i=o.isDisabled(),a=t.DomEditor.isNodeSelected(o,e),c=e,u=c.fileName,l=void 0===u?"":u,s=c.link,d=void 0===s?"":s;return r.h("span",{props:{contentEditable:!1},style:{display:"inline-block",marginLeft:"3px",marginRight:"3px",border:a&&!i?"2px solid var(--w-e-textarea-selected-border-color)":"2px solid transparent",borderRadius:"3px",padding:"0 3px",backgroundColor:"var(--w-e-textarea-slight-bg-color)",cursor:i?"pointer":"inherit"},on:{click:function(){i&&d&&window.open(d,"_blank")}}},[r.h("span",{style:{marginRight:"0.2em",opacity:"0.7"}},"file"),l])}}],elemsToHtml:[o],parseElemsHtml:[{selector:'a[data-w-e-type="attachment"]',parseElemHtml:function(e,t,n){return{type:"attachment",link:e.getAttribute("href")||"",fileName:e.getAttribute("download")||"",children:[{text:""}]}}}],menus:[{key:"uploadAttachment",factory:function(){return new v},config:{server:"",fieldName:"wangeditor-uploaded-attachment",maxFileSize:10485760,maxNumberOfFiles:5,allowedFileTypes:["*"],meta:{},metaWithUrl:!1,withCredentials:!1,timeout:3e4,onBeforeUpload:function(e){return e},onProgress:function(e){},onSuccess:function(e,t){},onFailed:function(e,t){},onError:function(e,t,n){},onInsertedAttachment:function(e){}}},{key:"downloadAttachment",factory:function(){return new a}}]};e.default=g,e.genUploadAttachmentMenuConfig=i,Object.defineProperty(e,"__esModule",{value:!0})});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@wangeditor-next/editor"),require("dom7"),require("snabbdom")):"function"==typeof define&&define.amd?define(["exports","@wangeditor-next/editor","dom7","snabbdom"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).WangEditorAttachmentPlugin={},e.wangEditor,e.$,e.snabbdom)}(this,function(e,t,n,r){"use strict";t.i18nAddResources("en",{attachment:{upload:"Upload Attachment",download:"Download Attachment"}}),t.i18nAddResources("zh-CN",{attachment:{upload:"上传附件",download:"下载附件"}});var o={type:"attachment",elemToHtml:function(e,t){var n=e,r=n.link,o=void 0===r?"":r,i=n.fileName,a=void 0===i?"":i;return'<a data-w-e-type="attachment" data-w-e-is-void data-w-e-is-inline href="'.concat(o,'" download="').concat(a,'">').concat(a,"</a>")}};function i(){return{server:"",fieldName:"wangeditor-uploaded-attachment",maxFileSize:10485760,maxNumberOfFiles:5,allowedFileTypes:["*"],meta:{},metaWithUrl:!1,withCredentials:!1,timeout:3e4,onBeforeUpload:function(e){return e},onProgress:function(e){},onSuccess:function(e,t){},onFailed:function(e,t){},onError:function(e,t,n){},onInsertedAttachment:function(e){}}}var a=function(){function e(){this.title=t.t("attachment.download"),this.iconSvg='<svg viewBox="0 0 1024 1024"><path d="M736 448l-256 256-256-256h160V64h192v384z m-256 256H0v256h960v-256H480z m416 128h-128v-64h128v64z"></path></svg>',this.tag="button",this.alwaysEnable=!0}return e.prototype.getValue=function(e){var t=this.getSelectedElem(e);return null==t?"":t.link},e.prototype.isActive=function(e){return!1},e.prototype.exec=function(e,t){t&&"string"==typeof t&&window.open(t,"_blank")},e.prototype.isDisabled=function(e){var n=e.selection;return null==n||(!!t.SlateRange.isExpanded(n)||null==this.getSelectedElem(e))},e.prototype.getSelectedElem=function(e){var n=t.DomEditor.getSelectedNodeByType(e,"attachment");return null==n?null:n},e}();n.hide&&(n.fn.hide=n.hide),n.append&&(n.fn.append=n.append),n.click&&(n.fn.click=n.click),n.on&&(n.fn.on=n.on);var c=function(){return c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},c.apply(this,arguments)};function u(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function c(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(a,c)}u((r=r.apply(e,t||[])).next())})}function l(e,t){var n,r,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return a.next=c(0),a.throw=c(1),a.return=c(2),"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(c){return function(u){return function(c){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,c[0]&&(i=0)),i;)try{if(n=1,r&&(o=2&c[0]?r.return:c[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,c[1])).done)return o;switch(r=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return i.label++,{value:c[1],done:!1};case 5:i.label++,r=c[1],c=[0];continue;case 7:c=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==c[0]&&2!==c[0])){i=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){i.label=c[1];break}if(6===c[0]&&i.label<o[1]){i.label=o[1],o=c;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(c);break}o[2]&&i.ops.pop(),i.trys.pop();continue}c=t.call(e,i)}catch(e){c=[6,e],r=0}finally{n=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,u])}}}function s(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function d(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=s(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise(function(r,o){(function(e,t,n,r){Promise.resolve(r).then(function(t){e({value:t,done:n})},t)})(r,o,(t=e[n](t)).done,t.value)})}}}function f(e){var t={server:"",fieldName:"wangeditor-uploaded-attachment",maxFileSize:10485760,maxNumberOfFiles:5,allowedFileTypes:["*"],meta:{},metaWithUrl:!1,withCredentials:!1,timeout:3e4,onBeforeUpload:function(e){return e},onProgress:function(e){},onSuccess:function(e,t){},onFailed:function(e,t){},onError:function(e,t,n){},onInsertedAttachment:function(e){}},n=e.getMenuConfig("uploadAttachment");return c(c({},t),n||{})}function p(e,t,n){if(t&&n){e.restoreSelection();var r={type:"attachment",fileName:t,link:n,children:[{text:""}]};e.insertNode(r),e.move(1);var o=f(e).onInsertedAttachment;o&&o(r)}}"function"==typeof SuppressedError&&SuppressedError;var m=new WeakMap;function h(e){var n=m.get(e);if(null!=n)return n;var r=f(e),o=r.customInsert,i=r.onError,a=r.onFailed,u=r.onProgress,l=r.onSuccess;return n=t.createUploader(c(c({},r),{onProgress:function(t){e.showProgressBar(t),u&&u(t)},onSuccess:function(t,n){if(o)return o(n,t,function(t,n){return p(e,t,n)}),void l(t,n);var r=n||{},i=r.errno,c=void 0===i?1:i,u=r.data;if(0===c){var s=(void 0===u?{}:u).url,d=void 0===s?"":s;p(e,(null==t?void 0:t.name)||"",d),l(t,n)}else a(t,n)},onError:function(e,t,n){i(e,t,n)}}),e),m.set(e,n),n}function y(e,t){return u(this,void 0,void 0,function(){var n,r;return l(this,function(o){switch(o.label){case 0:return n=h(e),r=t.map(function(e){return{name:e.name,type:e.type,size:e.size,data:e}}),n.addFiles(r),[4,n.upload()];case 1:return o.sent(),[2]}})})}var v=function(){function e(){this.title=t.t("attachment.upload"),this.iconSvg='<svg viewBox="0 0 1024 1024"><path d="M665.821116 327.053068l-64.958782-64.926783-324.79391 324.729911c-53.822991 53.790991-53.822991 141.053355 0 194.844347s141.053355 53.790991 194.876346 0l389.752692-389.688693a229.531696 229.531696 0 0 0 0-324.729912 229.627694 229.627694 0 0 0-324.761911 0L126.727224 476.458266l-0.863984 0.831985c-125.085655 125.085655-125.085655 327.833853 0 452.887508 125.053655 125.053655 327.865853 125.053655 452.983507 0l0.831984-0.863984 0.031999 0.032 279.322763-279.290764-64.990781-64.926782-279.322763 279.258764-0.831984 0.831984a228.731711 228.731711 0 0 1-323.065943 0 228.603714 228.603714 0 0 1 0-322.969944l0.895983-0.831985-0.031999-0.063998L600.958332 132.208721c53.694993-53.726993 141.149353-53.726993 194.876346 0s53.694993 141.149353 0 194.844347L406.081986 716.741761c-17.919664 17.919664-47.039118 17.919664-64.958782 0a45.983138 45.983138 0 0 1 0-64.926783L665.917114 327.053068z"></path></svg>',this.tag="button"}return e.prototype.getValue=function(e){return""},e.prototype.isActive=function(e){return!1},e.prototype.exec=function(e,t){var r=this.getMenuConfig(e),o=r.allowedFileTypes,i=void 0===o?[]:o,a=r.customBrowseAndUpload;if(a)a(function(t,n){return p(e,t,n)});else{var c="";i.length>0&&(c='accept="'.concat(i.join(", "),'"'));var s=n("body"),m=n('<input type="file" '.concat(c," multiple/>"));m.hide(),s.append(m),m.click(),m.on("change",function(){var t=m[0].files;!function(e,t){u(this,void 0,void 0,function(){var n,r,o,i,a,c,u,s,m,h,v,g;return l(this,function(l){switch(l.label){case 0:if(null==t)return[2];n=Array.prototype.slice.call(t),r=f(e).customUpload,o=[],l.label=1;case 1:l.trys.push([1,8,9,14]),i=!0,a=d(n),l.label=2;case 2:return[4,a.next()];case 3:return c=l.sent(),(m=c.done)?[3,7]:(g=c.value,i=!1,u=g,r?[4,r(u,function(t,n){return p(e,t,n)},e)]:[3,5]);case 4:return l.sent(),[3,6];case 5:o.push(u),l.label=6;case 6:return i=!0,[3,2];case 7:return[3,14];case 8:return s=l.sent(),h={error:s},[3,14];case 9:return l.trys.push([9,,12,13]),i||m||!(v=a.return)?[3,11]:[4,v.call(a)];case 10:l.sent(),l.label=11;case 11:return[3,13];case 12:if(h)throw h.error;return[7];case 13:return[7];case 14:return o.length>0?[4,y(e,o)]:[3,16];case 15:l.sent(),l.label=16;case 16:return[2]}})})}(e,t)})}},e.prototype.isDisabled=function(e){var n=e.selection;if(null==n)return!0;if(t.SlateRange.isExpanded(n))return!0;var r=t.DomEditor.getSelectedElems(e);return!!r.some(function(t){return e.isVoid(t)})||!!r.some(function(e){return"pre"===t.DomEditor.getNodeType(e)})},e.prototype.getMenuConfig=function(e){return e.getMenuConfig("uploadAttachment")},e}();var g={editorPlugin:function(e){var n=e.isInline,r=e.isVoid,o=e;return o.isInline=function(e){return"attachment"===t.DomEditor.getNodeType(e)||n(e)},o.isVoid=function(e){return"attachment"===t.DomEditor.getNodeType(e)||r(e)},o},renderElems:[{type:"attachment",renderElem:function(e,n,o){var i=o.isDisabled(),a=t.DomEditor.isNodeSelected(o,e),c=e,u=c.fileName,l=void 0===u?"":u,s=c.link,d=void 0===s?"":s;return r.h("span",{props:{contentEditable:!1},style:{display:"inline-block",marginLeft:"3px",marginRight:"3px",border:a&&!i?"2px solid var(--w-e-textarea-selected-border-color)":"2px solid transparent",borderRadius:"3px",padding:"0 3px",backgroundColor:"var(--w-e-textarea-slight-bg-color)",cursor:i?"pointer":"inherit"},on:{click:function(){i&&d&&window.open(d,"_blank")}}},[r.h("span",{style:{marginRight:"0.2em",opacity:"0.7"}},"file"),l])}}],elemsToHtml:[o],parseElemsHtml:[{selector:'a[data-w-e-type="attachment"]',parseElemHtml:function(e,t,n){return{type:"attachment",link:e.getAttribute("href")||"",fileName:e.getAttribute("download")||"",children:[{text:""}]}}}],menus:[{key:"uploadAttachment",factory:function(){return new v},config:{server:"",fieldName:"wangeditor-uploaded-attachment",maxFileSize:10485760,maxNumberOfFiles:5,allowedFileTypes:["*"],meta:{},metaWithUrl:!1,withCredentials:!1,timeout:3e4,onBeforeUpload:function(e){return e},onProgress:function(e){},onSuccess:function(e,t){},onFailed:function(e,t){},onError:function(e,t,n){},onInsertedAttachment:function(e){}}},{key:"downloadAttachment",factory:function(){return new a}}]};e.default=g,e.genUploadAttachmentMenuConfig=i,Object.defineProperty(e,"__esModule",{value:!0})});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/module/local.ts","../src/module/elem-to-html.ts","../src/module/menu/config.ts","../src/constants/icon-svg.ts","../src/module/menu/DownloadAttachment.ts","../src/utils/dom.ts","../src/module/menu/helper.ts","../src/module/menu/UploadAttachment.ts","../src/module/render-elem.ts","../src/module/index.ts","../src/module/plugin.ts","../src/module/parse-elem-html.ts","../src/module/menu/index.ts"],"sourcesContent":["/**\n * @description 多语言\n * @author wangfupeng\n */\n\nimport { i18nAddResources } from '@wangeditor-next/editor'\n\ni18nAddResources('en', {\n attachment: {\n upload: 'Upload Attachment',\n download: 'Download Attachment',\n },\n})\n\ni18nAddResources('zh-CN', {\n attachment: {\n upload: '上传附件',\n download: '下载附件',\n },\n})\n","/**\n * @description elem to html\n * @author wangfupeng\n */\n\nimport { SlateElement } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from './custom-types'\n\n// 生成 html 的函数\nfunction attachmentToHtml(elem: SlateElement, _childrenHtml: string): string {\n const { link = '', fileName = '' } = elem as AttachmentElement\n\n return `<a data-w-e-type=\"attachment\" data-w-e-is-void data-w-e-is-inline href=\"${link}\" download=\"${fileName}\">${fileName}</a>`\n}\n\n// 配置\nconst conf = {\n type: 'attachment', // 节点 type ,重要!!!\n elemToHtml: attachmentToHtml,\n}\n\nexport default conf\n","/**\n * @description menu config\n * @author wangfupeng\n */\n\nimport { IDomEditor, IUploadConfig } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from '../custom-types'\n\ntype InsertFn = (fileName: string, link: string) => void\n\n// 在通用 uploadConfig 上,扩展 attachment 相关配置\nexport type IUploadConfigForAttachment = Omit<\n IUploadConfig,\n 'customInsert' | 'customUpload' | 'customBrowseAndUpload'\n> & {\n // 用户自定义插入附件\n customInsert?: (res: any, file: any, insertFn: InsertFn) => void\n // 用户自定义上传附件\n customUpload?: (file: File, insertFn: InsertFn, editor: IDomEditor) => void | Promise<void>\n // 自定义选择附件,如图床\n customBrowseAndUpload?: (insertFn: InsertFn) => void\n // 插入之后的回调\n onInsertedAttachment?: (elem: AttachmentElement) => void\n}\n\nexport function genUploadAttachmentMenuConfig(): IUploadConfigForAttachment {\n return {\n server: '',\n fieldName: 'wangeditor-uploaded-attachment',\n maxFileSize: 10 * 1024 * 1024,\n maxNumberOfFiles: 5,\n allowedFileTypes: ['*'],\n meta: {},\n metaWithUrl: false,\n withCredentials: false,\n timeout: 30 * 1000,\n\n onBeforeUpload: (files: any) => files,\n onProgress: (_progress: number) => {\n /* on progress */\n },\n onSuccess: (_file: any, _res: any) => {\n /* on success */\n },\n onFailed: (_file: any, _res: any) => {\n /* on failed */\n },\n onError: (_file: any, _err: any, _res: any) => {\n /* on error */\n /* on timeout */\n },\n\n onInsertedAttachment(_elem: AttachmentElement) {\n // 插入文件之后的 callback\n },\n }\n}\n","/**\n * @description icon svg\n * @author wangfupeng\n */\n\n// 附件\nexport const ATTACHMENT_SVG = '<svg viewBox=\"0 0 1024 1024\"><path d=\"M665.821116 327.053068l-64.958782-64.926783-324.79391 324.729911c-53.822991 53.790991-53.822991 141.053355 0 194.844347s141.053355 53.790991 194.876346 0l389.752692-389.688693a229.531696 229.531696 0 0 0 0-324.729912 229.627694 229.627694 0 0 0-324.761911 0L126.727224 476.458266l-0.863984 0.831985c-125.085655 125.085655-125.085655 327.833853 0 452.887508 125.053655 125.053655 327.865853 125.053655 452.983507 0l0.831984-0.863984 0.031999 0.032 279.322763-279.290764-64.990781-64.926782-279.322763 279.258764-0.831984 0.831984a228.731711 228.731711 0 0 1-323.065943 0 228.603714 228.603714 0 0 1 0-322.969944l0.895983-0.831985-0.031999-0.063998L600.958332 132.208721c53.694993-53.726993 141.149353-53.726993 194.876346 0s53.694993 141.149353 0 194.844347L406.081986 716.741761c-17.919664 17.919664-47.039118 17.919664-64.958782 0a45.983138 45.983138 0 0 1 0-64.926783L665.917114 327.053068z\"></path></svg>'\n\n// 下载\nexport const DOWNLOAD_SVG = '<svg viewBox=\"0 0 1024 1024\"><path d=\"M736 448l-256 256-256-256h160V64h192v384z m-256 256H0v256h960v-256H480z m416 128h-128v-64h128v64z\"></path></svg>'\n","/**\n * @description download attachment menu\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu,\n IDomEditor,\n SlateRange,\n t,\n} from '@wangeditor-next/editor'\n\nimport { DOWNLOAD_SVG } from '../../constants/icon-svg'\nimport { AttachmentElement } from '../custom-types'\n\nclass DownloadAttachmentMenu implements IButtonMenu {\n readonly title = t('attachment.download')\n\n readonly iconSvg = DOWNLOAD_SVG\n\n readonly tag = 'button'\n\n readonly alwaysEnable = true\n\n getValue(editor: IDomEditor): string | boolean {\n const attachmentElem = this.getSelectedElem(editor)\n\n if (attachmentElem == null) { return '' }\n return attachmentElem.link\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 任何时候,都不用激活 menu\n return false\n }\n\n exec(_editor: IDomEditor, value: string | boolean) {\n if (!value) { return }\n if (typeof value !== 'string') { return }\n window.open(value, '_blank')\n }\n\n isDisabled(editor: IDomEditor): boolean {\n const { selection } = editor\n\n if (selection == null) { return true }\n if (SlateRange.isExpanded(selection)) { return true }\n\n // 未匹配到 attachment node 则禁用\n const attachmentElem = this.getSelectedElem(editor)\n\n if (attachmentElem == null) { return true }\n\n return false\n }\n\n private getSelectedElem(editor: IDomEditor): AttachmentElement | null {\n const node = DomEditor.getSelectedNodeByType(editor, 'attachment')\n\n if (node == null) { return null }\n return node as AttachmentElement\n }\n}\n\nexport default DownloadAttachmentMenu\n","/**\n * @description DOM 操作\n * @author wangfupeng\n */\n\nimport $, {\n append, click, hide, on,\n} from 'dom7'\n\nif (hide) { $.fn.hide = hide }\nif (append) { $.fn.append = append }\nif (click) { $.fn.click = click }\nif (on) { $.fn.on = on }\n\nexport { Dom7Array } from 'dom7'\nexport default $\n\n// COMPAT: This is required to prevent TypeScript aliases from doing some very\n// weird things for Slate's types with the same name as globals. (2019/11/27)\n// https://github.com/microsoft/TypeScript/issues/35002\nimport DOMNode = globalThis.Node\nimport DOMComment = globalThis.Comment\nimport DOMElement = globalThis.Element\nimport DOMText = globalThis.Text\nimport DOMRange = globalThis.Range\nimport DOMSelection = globalThis.Selection\nimport DOMStaticRange = globalThis.StaticRange\n\nexport {\n DOMComment,\n DOMElement,\n DOMNode,\n DOMRange,\n DOMSelection,\n DOMStaticRange,\n DOMText,\n}\n","/**\n * @description helper fns\n * @author wangfupeng\n */\n\nimport { createUploader, IDomEditor } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from '../custom-types'\nimport {\n genUploadAttachmentMenuConfig,\n IUploadConfigForAttachment,\n} from './config'\n\nfunction getUploadAttachmentMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {\n const defaultConfig = genUploadAttachmentMenuConfig()\n const menuConfig = editor.getMenuConfig('uploadAttachment') as Partial<IUploadConfigForAttachment>\n\n return {\n ...defaultConfig,\n ...(menuConfig || {}),\n }\n}\n\n/**\n * 插入 attachment 节点\n * @param fileName fileName\n * @param link link\n */\nexport function insertAttachment(editor: IDomEditor, fileName: string, link: string) {\n if (!fileName || !link) { return }\n\n // 还原选区\n editor.restoreSelection()\n\n // 插入节点\n const attachmentElem: AttachmentElement = {\n type: 'attachment',\n fileName,\n link,\n children: [{ text: '' }],\n }\n\n editor.insertNode(attachmentElem)\n editor.move(1)\n\n // 回调\n const { onInsertedAttachment } = getUploadAttachmentMenuConfig(editor)\n\n if (onInsertedAttachment) { onInsertedAttachment(attachmentElem) }\n}\n\n// 存储 editor uploader 的关系 - 缓存 uploader ,不重复创建\nconst EDITOR_TO_UPLOADER_MAP = new WeakMap<IDomEditor, any>()\n\n/**\n * 获取 uploader 实例(并通过 editor 缓存)\n * @param editor editor\n */\nfunction getUploader(editor: IDomEditor) {\n let uploader = EDITOR_TO_UPLOADER_MAP.get(editor)\n\n if (uploader != null) { return uploader }\n\n const menuConfig = getUploadAttachmentMenuConfig(editor)\n const {\n customInsert,\n onError,\n onFailed,\n onProgress,\n onSuccess,\n } = menuConfig\n\n // 上传完成之后\n const successHandler = (file: any, res: any) => {\n // 预期 res 格式:\n // 成功:{ errno: 0, data: { url } }\n // 失败:{ errno: !0, message: '失败信息' }\n if (customInsert) {\n customInsert(res, file, (fileName: string, link: string) => insertAttachment(editor, fileName, link))\n onSuccess(file, res)\n return\n }\n\n const { errno = 1, data = {} } = res || {}\n\n if (errno !== 0) {\n onFailed(file, res)\n return\n }\n\n const { url = '' } = data as { url?: string }\n\n insertAttachment(editor, file?.name || '', url)\n onSuccess(file, res)\n }\n\n // progress 显示进度条\n const progressHandler = (progress: number) => {\n editor.showProgressBar(progress)\n\n if (onProgress) { onProgress(progress) }\n }\n\n // onError 提示错误\n const errorHandler = (file: any, err: any, res: any) => {\n onError(file, err, res)\n }\n\n uploader = createUploader(\n {\n ...menuConfig,\n onProgress: progressHandler,\n onSuccess: successHandler,\n onError: errorHandler,\n } as any,\n editor,\n )\n\n EDITOR_TO_UPLOADER_MAP.set(editor, uploader)\n\n return uploader\n}\n\n/**\n * 上传文件\n * @param editor editor\n * @param files files\n */\nasync function uploadFile(editor: IDomEditor, files: File[]) {\n const uploader = getUploader(editor)\n const uploadList = files.map(file => ({\n name: file.name,\n type: file.type,\n size: file.size,\n data: file,\n }))\n\n uploader.addFiles(uploadList)\n await uploader.upload()\n}\n\n/**\n * 上传附件文件\n * @param editor editor\n * @param files files\n */\nexport async function uploadAttachments(\n editor: IDomEditor,\n files: FileList | File[] | null,\n) {\n if (files == null) { return }\n const fileList = Array.prototype.slice.call(files) as File[]\n\n // 获取菜单配置\n const { customUpload } = getUploadAttachmentMenuConfig(editor)\n const uploadFileList: File[] = []\n\n // 按顺序上传\n for await (const file of fileList) {\n if (customUpload) {\n // 自定义上传\n await customUpload(\n file,\n (fileName: string, link: string) => insertAttachment(editor, fileName, link),\n editor,\n )\n } else {\n // 默认上传\n uploadFileList.push(file)\n }\n }\n\n if (uploadFileList.length > 0) {\n await uploadFile(editor, uploadFileList)\n }\n}\n","/**\n * @description upload attachment menu\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu,\n IDomEditor,\n SlateRange,\n t,\n} from '@wangeditor-next/editor'\n\nimport { ATTACHMENT_SVG } from '../../constants/icon-svg'\nimport $ from '../../utils/dom'\nimport { IUploadConfigForAttachment } from './config'\nimport { insertAttachment, uploadAttachments } from './helper'\n\nclass UploadAttachmentMenu implements IButtonMenu {\n readonly title = t('attachment.upload')\n\n readonly iconSvg = ATTACHMENT_SVG\n\n readonly tag = 'button'\n\n getValue(_editor: IDomEditor): string | boolean {\n // 无需获取 val\n return ''\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 任何时候,都不用激活 menu\n return false\n }\n\n exec(editor: IDomEditor, _value: string | boolean) {\n const {\n allowedFileTypes = [],\n customBrowseAndUpload,\n } = this.getMenuConfig(editor)\n\n // 自定义选择文件、并上传,如图床\n if (customBrowseAndUpload) {\n customBrowseAndUpload((fileName: string, link: string) => insertAttachment(editor, fileName, link))\n return\n }\n\n // 设置选择文件的类型\n let acceptAttr = ''\n\n if (allowedFileTypes.length > 0) {\n acceptAttr = `accept=\"${allowedFileTypes.join(', ')}\"`\n }\n\n // 添加 file input(每次重新创建 input)\n const $body = $('body')\n const $inputFile = $(`<input type=\"file\" ${acceptAttr} multiple/>`)\n\n $inputFile.hide()\n $body.append($inputFile)\n $inputFile.click()\n // 选中文件\n $inputFile.on('change', () => {\n const files = ($inputFile[0] as HTMLInputElement).files\n\n uploadAttachments(editor, files)\n })\n }\n\n isDisabled(editor: IDomEditor): boolean {\n const { selection } = editor\n\n if (selection == null) { return true }\n if (SlateRange.isExpanded(selection)) { return true }\n\n const selectedElems = DomEditor.getSelectedElems(editor)\n const hasVoidElem = selectedElems.some(elem => editor.isVoid(elem))\n\n if (hasVoidElem) { return true }\n\n const hasPreElem = selectedElems.some(elem => DomEditor.getNodeType(elem) === 'pre')\n\n if (hasPreElem) { return true }\n\n return false\n }\n\n private getMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {\n return editor.getMenuConfig('uploadAttachment') as IUploadConfigForAttachment\n }\n}\n\nexport default UploadAttachmentMenu\n","/**\n * @description render elem\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor, SlateElement } from '@wangeditor-next/editor'\nimport { h, VNode } from 'snabbdom'\n\nimport { AttachmentElement } from './custom-types'\n\nfunction renderAttachment(elem: SlateElement, _children: VNode[] | null, editor: IDomEditor): VNode {\n const isDisabled = editor.isDisabled()\n const selected = DomEditor.isNodeSelected(editor, elem)\n const { fileName = '', link = '' } = elem as AttachmentElement\n\n const vnode = h(\n 'span',\n {\n props: {\n contentEditable: false,\n },\n style: {\n display: 'inline-block',\n marginLeft: '3px',\n marginRight: '3px',\n border: selected && !isDisabled\n ? '2px solid var(--w-e-textarea-selected-border-color)'\n : '2px solid transparent',\n borderRadius: '3px',\n padding: '0 3px',\n backgroundColor: 'var(--w-e-textarea-slight-bg-color)',\n cursor: isDisabled ? 'pointer' : 'inherit',\n },\n on: {\n // disable 时,点击下载附件\n click() {\n if (!isDisabled) { return }\n if (link) {\n window.open(link, '_blank')\n }\n },\n },\n },\n [\n h('span', {\n style: {\n marginRight: '0.2em',\n opacity: '0.7',\n },\n }, 'file'),\n fileName,\n ],\n )\n\n return vnode\n}\n\nconst conf = {\n type: 'attachment',\n renderElem: renderAttachment,\n}\n\nexport default conf\n","/**\n * @description attachment module entry\n * @author wangfupeng\n */\n\nimport './local'\n\nimport { IModuleConf } from '@wangeditor-next/editor'\n\nimport elemToHtmlConf from './elem-to-html'\nimport {\n downloadAttachmentMenuConf,\n uploadAttachmentMenuConf,\n} from './menu/index'\nimport parseHtmlConf from './parse-elem-html'\nimport withAttachment from './plugin'\nimport renderElemConf from './render-elem'\n\nconst module: Partial<IModuleConf> = {\n editorPlugin: withAttachment,\n renderElems: [renderElemConf],\n elemsToHtml: [elemToHtmlConf],\n parseElemsHtml: [parseHtmlConf],\n menus: [uploadAttachmentMenuConf, downloadAttachmentMenuConf],\n}\n\nexport default module\n","/**\n * @description attachment plugin\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor } from '@wangeditor-next/editor'\n\nfunction withAttachment<T extends IDomEditor>(editor: T) {\n const { isInline, isVoid } = editor\n const newEditor = editor\n\n // 重写 isInline\n newEditor.isInline = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'attachment') {\n return true\n }\n\n return isInline(elem)\n }\n\n // 重写 isVoid\n newEditor.isVoid = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'attachment') {\n return true\n }\n\n return isVoid(elem)\n }\n\n return newEditor\n}\n\nexport default withAttachment\n","/**\n * @description parse elem html\n * @author wangfupeng\n */\n\nimport { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor-next/editor'\n\nimport { DOMElement } from '../utils/dom'\nimport { AttachmentElement } from './custom-types'\n\nfunction parseHtml(\n elem: DOMElement,\n _children: SlateDescendant[],\n _editor: IDomEditor,\n): SlateElement {\n const link = elem.getAttribute('href') || ''\n const fileName = elem.getAttribute('download') || ''\n\n return {\n type: 'attachment',\n link,\n fileName,\n children: [{ text: '' }], // void node 必须有一个空白 text\n } as AttachmentElement\n}\n\nconst parseHtmlConf = {\n selector: 'a[data-w-e-type=\"attachment\"]',\n parseElemHtml: parseHtml,\n}\n\nexport default parseHtmlConf\n","/**\n * @description menu entry\n * @author wangfupeng\n */\n\nimport { genUploadAttachmentMenuConfig } from './config'\nimport DownloadAttachmentMenu from './DownloadAttachment'\nimport UploadAttachmentMenu from './UploadAttachment'\n\nexport const uploadAttachmentMenuConf = {\n key: 'uploadAttachment',\n factory() {\n return new UploadAttachmentMenu()\n },\n\n // 默认菜单配置,将存储在 editorConfig.MENU_CONF[key] 中\n // 创建编辑器时,可通过 editorConfig.MENU_CONF[key] = {...} 来修改\n config: genUploadAttachmentMenuConfig(),\n}\n\nexport const downloadAttachmentMenuConf = {\n key: 'downloadAttachment',\n factory() {\n return new DownloadAttachmentMenu()\n },\n}\n"],"names":["i18nAddResources","attachment","upload","download","conf","type","elemToHtml","elem","_childrenHtml","_a","_b","link","_c","fileName","concat","genUploadAttachmentMenuConfig","server","fieldName","maxFileSize","maxNumberOfFiles","allowedFileTypes","meta","metaWithUrl","withCredentials","timeout","onBeforeUpload","files","onProgress","_progress","onSuccess","_file","_res","onFailed","onError","_err","onInsertedAttachment","_elem","DownloadAttachmentMenu","this","title","t","iconSvg","tag","alwaysEnable","prototype","getValue","editor","attachmentElem","getSelectedElem","isActive","_editor","exec","value","window","open","isDisabled","selection","SlateRange","isExpanded","node","DomEditor","getSelectedNodeByType","hide","$","fn","append","click","on","getUploadAttachmentMenuConfig","defaultConfig","menuConfig","getMenuConfig","__assign","insertAttachment","restoreSelection","children","text","insertNode","move","EDITOR_TO_UPLOADER_MAP","WeakMap","getUploader","uploader","get","customInsert","createUploader","progress","showProgressBar","file","res","errno","data","_d","url","name","err","set","uploadFile","uploadList","map","size","addFiles","sent","UploadAttachmentMenu","_value","customBrowseAndUpload","acceptAttr","length","join","$body","$inputFile","fileList","Array","slice","call","customUpload","uploadFileList","fileList_1","__asyncValues","fileList_1_1","_e","push","uploadAttachments","selectedElems","getSelectedElems","some","isVoid","getNodeType","module","editorPlugin","isInline","newEditor","renderElems","renderElem","_children","selected","isNodeSelected","h","props","contentEditable","style","display","marginLeft","marginRight","border","borderRadius","padding","backgroundColor","cursor","opacity","elemsToHtml","elemToHtmlConf","parseElemsHtml","selector","parseElemHtml","getAttribute","menus","key","factory","config"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/module/local.ts","../src/module/elem-to-html.ts","../src/module/menu/config.ts","../src/constants/icon-svg.ts","../src/module/menu/DownloadAttachment.ts","../src/utils/dom.ts","../src/module/menu/helper.ts","../src/module/menu/UploadAttachment.ts","../src/module/render-elem.ts","../src/module/index.ts","../src/module/plugin.ts","../src/module/parse-elem-html.ts","../src/module/menu/index.ts"],"sourcesContent":["/**\n * @description 多语言\n * @author wangfupeng\n */\n\nimport { i18nAddResources } from '@wangeditor-next/editor'\n\ni18nAddResources('en', {\n attachment: {\n upload: 'Upload Attachment',\n download: 'Download Attachment',\n },\n})\n\ni18nAddResources('zh-CN', {\n attachment: {\n upload: '上传附件',\n download: '下载附件',\n },\n})\n","/**\n * @description elem to html\n * @author wangfupeng\n */\n\nimport { SlateElement } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from './custom-types'\n\n// 生成 html 的函数\nfunction attachmentToHtml(elem: SlateElement, _childrenHtml: string): string {\n const { link = '', fileName = '' } = elem as AttachmentElement\n\n return `<a data-w-e-type=\"attachment\" data-w-e-is-void data-w-e-is-inline href=\"${link}\" download=\"${fileName}\">${fileName}</a>`\n}\n\n// 配置\nconst conf = {\n type: 'attachment', // 节点 type ,重要!!!\n elemToHtml: attachmentToHtml,\n}\n\nexport default conf\n","/**\n * @description menu config\n * @author wangfupeng\n */\n\nimport { IDomEditor, IUploadConfig } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from '../custom-types'\n\ntype InsertFn = (fileName: string, link: string) => void\n\n// 在通用 uploadConfig 上,扩展 attachment 相关配置\nexport type IUploadConfigForAttachment = Omit<\n IUploadConfig,\n 'customInsert' | 'customUpload' | 'customBrowseAndUpload'\n> & {\n // 用户自定义插入附件\n customInsert?: (res: any, file: any, insertFn: InsertFn) => void\n // 用户自定义上传附件\n customUpload?: (file: File, insertFn: InsertFn, editor: IDomEditor) => void | Promise<void>\n // 自定义选择附件,如图床\n customBrowseAndUpload?: (insertFn: InsertFn) => void\n // 插入之后的回调\n onInsertedAttachment?: (elem: AttachmentElement) => void\n}\n\nexport function genUploadAttachmentMenuConfig(): IUploadConfigForAttachment {\n return {\n server: '',\n fieldName: 'wangeditor-uploaded-attachment',\n maxFileSize: 10 * 1024 * 1024,\n maxNumberOfFiles: 5,\n allowedFileTypes: ['*'],\n meta: {},\n metaWithUrl: false,\n withCredentials: false,\n timeout: 30 * 1000,\n\n onBeforeUpload: (files: any) => files,\n onProgress: (_progress: number) => {\n /* on progress */\n },\n onSuccess: (_file: any, _res: any) => {\n /* on success */\n },\n onFailed: (_file: any, _res: any) => {\n /* on failed */\n },\n onError: (_file: any, _err: any, _res: any) => {\n /* on error */\n /* on timeout */\n },\n\n onInsertedAttachment(_elem: AttachmentElement) {\n // 插入文件之后的 callback\n },\n }\n}\n","/**\n * @description icon svg\n * @author wangfupeng\n */\n\n// 附件\nexport const ATTACHMENT_SVG = '<svg viewBox=\"0 0 1024 1024\"><path d=\"M665.821116 327.053068l-64.958782-64.926783-324.79391 324.729911c-53.822991 53.790991-53.822991 141.053355 0 194.844347s141.053355 53.790991 194.876346 0l389.752692-389.688693a229.531696 229.531696 0 0 0 0-324.729912 229.627694 229.627694 0 0 0-324.761911 0L126.727224 476.458266l-0.863984 0.831985c-125.085655 125.085655-125.085655 327.833853 0 452.887508 125.053655 125.053655 327.865853 125.053655 452.983507 0l0.831984-0.863984 0.031999 0.032 279.322763-279.290764-64.990781-64.926782-279.322763 279.258764-0.831984 0.831984a228.731711 228.731711 0 0 1-323.065943 0 228.603714 228.603714 0 0 1 0-322.969944l0.895983-0.831985-0.031999-0.063998L600.958332 132.208721c53.694993-53.726993 141.149353-53.726993 194.876346 0s53.694993 141.149353 0 194.844347L406.081986 716.741761c-17.919664 17.919664-47.039118 17.919664-64.958782 0a45.983138 45.983138 0 0 1 0-64.926783L665.917114 327.053068z\"></path></svg>'\n\n// 下载\nexport const DOWNLOAD_SVG = '<svg viewBox=\"0 0 1024 1024\"><path d=\"M736 448l-256 256-256-256h160V64h192v384z m-256 256H0v256h960v-256H480z m416 128h-128v-64h128v64z\"></path></svg>'\n","/**\n * @description download attachment menu\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu,\n IDomEditor,\n SlateRange,\n t,\n} from '@wangeditor-next/editor'\n\nimport { DOWNLOAD_SVG } from '../../constants/icon-svg'\nimport { AttachmentElement } from '../custom-types'\n\nclass DownloadAttachmentMenu implements IButtonMenu {\n readonly title = t('attachment.download')\n\n readonly iconSvg = DOWNLOAD_SVG\n\n readonly tag = 'button'\n\n readonly alwaysEnable = true\n\n getValue(editor: IDomEditor): string | boolean {\n const attachmentElem = this.getSelectedElem(editor)\n\n if (attachmentElem == null) { return '' }\n return attachmentElem.link\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 任何时候,都不用激活 menu\n return false\n }\n\n exec(_editor: IDomEditor, value: string | boolean) {\n if (!value) { return }\n if (typeof value !== 'string') { return }\n window.open(value, '_blank')\n }\n\n isDisabled(editor: IDomEditor): boolean {\n const { selection } = editor\n\n if (selection == null) { return true }\n if (SlateRange.isExpanded(selection)) { return true }\n\n // 未匹配到 attachment node 则禁用\n const attachmentElem = this.getSelectedElem(editor)\n\n if (attachmentElem == null) { return true }\n\n return false\n }\n\n private getSelectedElem(editor: IDomEditor): AttachmentElement | null {\n const node = DomEditor.getSelectedNodeByType(editor, 'attachment')\n\n if (node == null) { return null }\n return node as AttachmentElement\n }\n}\n\nexport default DownloadAttachmentMenu\n","/**\n * @description DOM 操作\n * @author wangfupeng\n */\n\nimport $, {\n append, click, hide, on,\n} from 'dom7'\n\nif (hide) { $.fn.hide = hide }\nif (append) { $.fn.append = append }\nif (click) { $.fn.click = click }\nif (on) { $.fn.on = on }\n\nexport type { Dom7Array } from 'dom7'\nexport default $\n\n// COMPAT: This is required to prevent TypeScript aliases from doing some very\n// weird things for Slate's types with the same name as globals. (2019/11/27)\n// https://github.com/microsoft/TypeScript/issues/35002\nimport DOMNode = globalThis.Node\nimport DOMComment = globalThis.Comment\nimport DOMElement = globalThis.Element\nimport DOMText = globalThis.Text\nimport DOMRange = globalThis.Range\nimport DOMSelection = globalThis.Selection\nimport DOMStaticRange = globalThis.StaticRange\n\nexport {\n DOMComment,\n DOMElement,\n DOMNode,\n DOMRange,\n DOMSelection,\n DOMStaticRange,\n DOMText,\n}\n","/**\n * @description helper fns\n * @author wangfupeng\n */\n\nimport { createUploader, IDomEditor } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from '../custom-types'\nimport {\n genUploadAttachmentMenuConfig,\n IUploadConfigForAttachment,\n} from './config'\n\nfunction getUploadAttachmentMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {\n const defaultConfig = genUploadAttachmentMenuConfig()\n const menuConfig = editor.getMenuConfig('uploadAttachment') as Partial<IUploadConfigForAttachment>\n\n return {\n ...defaultConfig,\n ...(menuConfig || {}),\n }\n}\n\n/**\n * 插入 attachment 节点\n * @param fileName fileName\n * @param link link\n */\nexport function insertAttachment(editor: IDomEditor, fileName: string, link: string) {\n if (!fileName || !link) { return }\n\n // 还原选区\n editor.restoreSelection()\n\n // 插入节点\n const attachmentElem: AttachmentElement = {\n type: 'attachment',\n fileName,\n link,\n children: [{ text: '' }],\n }\n\n editor.insertNode(attachmentElem)\n editor.move(1)\n\n // 回调\n const { onInsertedAttachment } = getUploadAttachmentMenuConfig(editor)\n\n if (onInsertedAttachment) { onInsertedAttachment(attachmentElem) }\n}\n\n// 存储 editor uploader 的关系 - 缓存 uploader ,不重复创建\nconst EDITOR_TO_UPLOADER_MAP = new WeakMap<IDomEditor, any>()\n\n/**\n * 获取 uploader 实例(并通过 editor 缓存)\n * @param editor editor\n */\nfunction getUploader(editor: IDomEditor) {\n let uploader = EDITOR_TO_UPLOADER_MAP.get(editor)\n\n if (uploader != null) { return uploader }\n\n const menuConfig = getUploadAttachmentMenuConfig(editor)\n const {\n customInsert,\n onError,\n onFailed,\n onProgress,\n onSuccess,\n } = menuConfig\n\n // 上传完成之后\n const successHandler = (file: any, res: any) => {\n // 预期 res 格式:\n // 成功:{ errno: 0, data: { url } }\n // 失败:{ errno: !0, message: '失败信息' }\n if (customInsert) {\n customInsert(res, file, (fileName: string, link: string) => insertAttachment(editor, fileName, link))\n onSuccess(file, res)\n return\n }\n\n const { errno = 1, data = {} } = res || {}\n\n if (errno !== 0) {\n onFailed(file, res)\n return\n }\n\n const { url = '' } = data as { url?: string }\n\n insertAttachment(editor, file?.name || '', url)\n onSuccess(file, res)\n }\n\n // progress 显示进度条\n const progressHandler = (progress: number) => {\n editor.showProgressBar(progress)\n\n if (onProgress) { onProgress(progress) }\n }\n\n // onError 提示错误\n const errorHandler = (file: any, err: any, res: any) => {\n onError(file, err, res)\n }\n\n uploader = createUploader(\n {\n ...menuConfig,\n onProgress: progressHandler,\n onSuccess: successHandler,\n onError: errorHandler,\n } as any,\n editor,\n )\n\n EDITOR_TO_UPLOADER_MAP.set(editor, uploader)\n\n return uploader\n}\n\n/**\n * 上传文件\n * @param editor editor\n * @param files files\n */\nasync function uploadFile(editor: IDomEditor, files: File[]) {\n const uploader = getUploader(editor)\n const uploadList = files.map(file => ({\n name: file.name,\n type: file.type,\n size: file.size,\n data: file,\n }))\n\n uploader.addFiles(uploadList)\n await uploader.upload()\n}\n\n/**\n * 上传附件文件\n * @param editor editor\n * @param files files\n */\nexport async function uploadAttachments(\n editor: IDomEditor,\n files: FileList | File[] | null,\n) {\n if (files == null) { return }\n const fileList = Array.prototype.slice.call(files) as File[]\n\n // 获取菜单配置\n const { customUpload } = getUploadAttachmentMenuConfig(editor)\n const uploadFileList: File[] = []\n\n // 按顺序上传\n for await (const file of fileList) {\n if (customUpload) {\n // 自定义上传\n await customUpload(\n file,\n (fileName: string, link: string) => insertAttachment(editor, fileName, link),\n editor,\n )\n } else {\n // 默认上传\n uploadFileList.push(file)\n }\n }\n\n if (uploadFileList.length > 0) {\n await uploadFile(editor, uploadFileList)\n }\n}\n","/**\n * @description upload attachment menu\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu,\n IDomEditor,\n SlateRange,\n t,\n} from '@wangeditor-next/editor'\n\nimport { ATTACHMENT_SVG } from '../../constants/icon-svg'\nimport $ from '../../utils/dom'\nimport { IUploadConfigForAttachment } from './config'\nimport { insertAttachment, uploadAttachments } from './helper'\n\nclass UploadAttachmentMenu implements IButtonMenu {\n readonly title = t('attachment.upload')\n\n readonly iconSvg = ATTACHMENT_SVG\n\n readonly tag = 'button'\n\n getValue(_editor: IDomEditor): string | boolean {\n // 无需获取 val\n return ''\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 任何时候,都不用激活 menu\n return false\n }\n\n exec(editor: IDomEditor, _value: string | boolean) {\n const {\n allowedFileTypes = [],\n customBrowseAndUpload,\n } = this.getMenuConfig(editor)\n\n // 自定义选择文件、并上传,如图床\n if (customBrowseAndUpload) {\n customBrowseAndUpload((fileName: string, link: string) => insertAttachment(editor, fileName, link))\n return\n }\n\n // 设置选择文件的类型\n let acceptAttr = ''\n\n if (allowedFileTypes.length > 0) {\n acceptAttr = `accept=\"${allowedFileTypes.join(', ')}\"`\n }\n\n // 添加 file input(每次重新创建 input)\n const $body = $('body')\n const $inputFile = $(`<input type=\"file\" ${acceptAttr} multiple/>`)\n\n $inputFile.hide()\n $body.append($inputFile)\n $inputFile.click()\n // 选中文件\n $inputFile.on('change', () => {\n const files = ($inputFile[0] as HTMLInputElement).files\n\n uploadAttachments(editor, files)\n })\n }\n\n isDisabled(editor: IDomEditor): boolean {\n const { selection } = editor\n\n if (selection == null) { return true }\n if (SlateRange.isExpanded(selection)) { return true }\n\n const selectedElems = DomEditor.getSelectedElems(editor)\n const hasVoidElem = selectedElems.some(elem => editor.isVoid(elem))\n\n if (hasVoidElem) { return true }\n\n const hasPreElem = selectedElems.some(elem => DomEditor.getNodeType(elem) === 'pre')\n\n if (hasPreElem) { return true }\n\n return false\n }\n\n private getMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {\n return editor.getMenuConfig('uploadAttachment') as IUploadConfigForAttachment\n }\n}\n\nexport default UploadAttachmentMenu\n","/**\n * @description render elem\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor, SlateElement } from '@wangeditor-next/editor'\nimport { h, VNode } from 'snabbdom'\n\nimport { AttachmentElement } from './custom-types'\n\nfunction renderAttachment(elem: SlateElement, _children: VNode[] | null, editor: IDomEditor): VNode {\n const isDisabled = editor.isDisabled()\n const selected = DomEditor.isNodeSelected(editor, elem)\n const { fileName = '', link = '' } = elem as AttachmentElement\n\n const vnode = h(\n 'span',\n {\n props: {\n contentEditable: false,\n },\n style: {\n display: 'inline-block',\n marginLeft: '3px',\n marginRight: '3px',\n border: selected && !isDisabled\n ? '2px solid var(--w-e-textarea-selected-border-color)'\n : '2px solid transparent',\n borderRadius: '3px',\n padding: '0 3px',\n backgroundColor: 'var(--w-e-textarea-slight-bg-color)',\n cursor: isDisabled ? 'pointer' : 'inherit',\n },\n on: {\n // disable 时,点击下载附件\n click() {\n if (!isDisabled) { return }\n if (link) {\n window.open(link, '_blank')\n }\n },\n },\n },\n [\n h('span', {\n style: {\n marginRight: '0.2em',\n opacity: '0.7',\n },\n }, 'file'),\n fileName,\n ],\n )\n\n return vnode\n}\n\nconst conf = {\n type: 'attachment',\n renderElem: renderAttachment,\n}\n\nexport default conf\n","/**\n * @description attachment module entry\n * @author wangfupeng\n */\n\nimport './local'\n\nimport { IModuleConf } from '@wangeditor-next/editor'\n\nimport elemToHtmlConf from './elem-to-html'\nimport {\n downloadAttachmentMenuConf,\n uploadAttachmentMenuConf,\n} from './menu/index'\nimport parseHtmlConf from './parse-elem-html'\nimport withAttachment from './plugin'\nimport renderElemConf from './render-elem'\n\nconst module: Partial<IModuleConf> = {\n editorPlugin: withAttachment,\n renderElems: [renderElemConf],\n elemsToHtml: [elemToHtmlConf],\n parseElemsHtml: [parseHtmlConf],\n menus: [uploadAttachmentMenuConf, downloadAttachmentMenuConf],\n}\n\nexport default module\n","/**\n * @description attachment plugin\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor } from '@wangeditor-next/editor'\n\nfunction withAttachment<T extends IDomEditor>(editor: T) {\n const { isInline, isVoid } = editor\n const newEditor = editor\n\n // 重写 isInline\n newEditor.isInline = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'attachment') {\n return true\n }\n\n return isInline(elem)\n }\n\n // 重写 isVoid\n newEditor.isVoid = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'attachment') {\n return true\n }\n\n return isVoid(elem)\n }\n\n return newEditor\n}\n\nexport default withAttachment\n","/**\n * @description parse elem html\n * @author wangfupeng\n */\n\nimport { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor-next/editor'\n\nimport { DOMElement } from '../utils/dom'\nimport { AttachmentElement } from './custom-types'\n\nfunction parseHtml(\n elem: DOMElement,\n _children: SlateDescendant[],\n _editor: IDomEditor,\n): SlateElement {\n const link = elem.getAttribute('href') || ''\n const fileName = elem.getAttribute('download') || ''\n\n return {\n type: 'attachment',\n link,\n fileName,\n children: [{ text: '' }], // void node 必须有一个空白 text\n } as AttachmentElement\n}\n\nconst parseHtmlConf = {\n selector: 'a[data-w-e-type=\"attachment\"]',\n parseElemHtml: parseHtml,\n}\n\nexport default parseHtmlConf\n","/**\n * @description menu entry\n * @author wangfupeng\n */\n\nimport { genUploadAttachmentMenuConfig } from './config'\nimport DownloadAttachmentMenu from './DownloadAttachment'\nimport UploadAttachmentMenu from './UploadAttachment'\n\nexport const uploadAttachmentMenuConf = {\n key: 'uploadAttachment',\n factory() {\n return new UploadAttachmentMenu()\n },\n\n // 默认菜单配置,将存储在 editorConfig.MENU_CONF[key] 中\n // 创建编辑器时,可通过 editorConfig.MENU_CONF[key] = {...} 来修改\n config: genUploadAttachmentMenuConfig(),\n}\n\nexport const downloadAttachmentMenuConf = {\n key: 'downloadAttachment',\n factory() {\n return new DownloadAttachmentMenu()\n },\n}\n"],"names":["i18nAddResources","attachment","upload","download","conf","type","elemToHtml","elem","_childrenHtml","_a","_b","link","_c","fileName","concat","genUploadAttachmentMenuConfig","server","fieldName","maxFileSize","maxNumberOfFiles","allowedFileTypes","meta","metaWithUrl","withCredentials","timeout","onBeforeUpload","files","onProgress","_progress","onSuccess","_file","_res","onFailed","onError","_err","onInsertedAttachment","_elem","DownloadAttachmentMenu","this","title","t","iconSvg","tag","alwaysEnable","prototype","getValue","editor","attachmentElem","getSelectedElem","isActive","_editor","exec","value","window","open","isDisabled","selection","SlateRange","isExpanded","node","DomEditor","getSelectedNodeByType","hide","$","fn","append","click","on","getUploadAttachmentMenuConfig","defaultConfig","menuConfig","getMenuConfig","__assign","insertAttachment","restoreSelection","children","text","insertNode","move","EDITOR_TO_UPLOADER_MAP","WeakMap","getUploader","uploader","get","customInsert","createUploader","progress","showProgressBar","file","res","errno","data","_d","url","name","err","set","uploadFile","uploadList","map","size","addFiles","sent","UploadAttachmentMenu","_value","customBrowseAndUpload","acceptAttr","length","join","$body","$inputFile","fileList","Array","slice","call","customUpload","uploadFileList","fileList_1","__asyncValues","fileList_1_1","_e","push","uploadAttachments","selectedElems","getSelectedElems","some","isVoid","getNodeType","module","editorPlugin","isInline","newEditor","renderElems","renderElem","_children","selected","isNodeSelected","h","props","contentEditable","style","display","marginLeft","marginRight","border","borderRadius","padding","backgroundColor","cursor","opacity","elemsToHtml","elemToHtmlConf","parseElemsHtml","selector","parseElemHtml","getAttribute","menus","key","factory","config"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/module/local.ts","../src/module/elem-to-html.ts","../src/module/menu/config.ts","../src/constants/icon-svg.ts","../src/module/menu/DownloadAttachment.ts","../src/utils/dom.ts","../src/module/menu/helper.ts","../src/module/menu/UploadAttachment.ts","../src/module/render-elem.ts","../src/module/index.ts","../src/module/plugin.ts","../src/module/parse-elem-html.ts","../src/module/menu/index.ts"],"sourcesContent":["/**\n * @description 多语言\n * @author wangfupeng\n */\n\nimport { i18nAddResources } from '@wangeditor-next/editor'\n\ni18nAddResources('en', {\n attachment: {\n upload: 'Upload Attachment',\n download: 'Download Attachment',\n },\n})\n\ni18nAddResources('zh-CN', {\n attachment: {\n upload: '上传附件',\n download: '下载附件',\n },\n})\n","/**\n * @description elem to html\n * @author wangfupeng\n */\n\nimport { SlateElement } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from './custom-types'\n\n// 生成 html 的函数\nfunction attachmentToHtml(elem: SlateElement, _childrenHtml: string): string {\n const { link = '', fileName = '' } = elem as AttachmentElement\n\n return `<a data-w-e-type=\"attachment\" data-w-e-is-void data-w-e-is-inline href=\"${link}\" download=\"${fileName}\">${fileName}</a>`\n}\n\n// 配置\nconst conf = {\n type: 'attachment', // 节点 type ,重要!!!\n elemToHtml: attachmentToHtml,\n}\n\nexport default conf\n","/**\n * @description menu config\n * @author wangfupeng\n */\n\nimport { IDomEditor, IUploadConfig } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from '../custom-types'\n\ntype InsertFn = (fileName: string, link: string) => void\n\n// 在通用 uploadConfig 上,扩展 attachment 相关配置\nexport type IUploadConfigForAttachment = Omit<\n IUploadConfig,\n 'customInsert' | 'customUpload' | 'customBrowseAndUpload'\n> & {\n // 用户自定义插入附件\n customInsert?: (res: any, file: any, insertFn: InsertFn) => void\n // 用户自定义上传附件\n customUpload?: (file: File, insertFn: InsertFn, editor: IDomEditor) => void | Promise<void>\n // 自定义选择附件,如图床\n customBrowseAndUpload?: (insertFn: InsertFn) => void\n // 插入之后的回调\n onInsertedAttachment?: (elem: AttachmentElement) => void\n}\n\nexport function genUploadAttachmentMenuConfig(): IUploadConfigForAttachment {\n return {\n server: '',\n fieldName: 'wangeditor-uploaded-attachment',\n maxFileSize: 10 * 1024 * 1024,\n maxNumberOfFiles: 5,\n allowedFileTypes: ['*'],\n meta: {},\n metaWithUrl: false,\n withCredentials: false,\n timeout: 30 * 1000,\n\n onBeforeUpload: (files: any) => files,\n onProgress: (_progress: number) => {\n /* on progress */\n },\n onSuccess: (_file: any, _res: any) => {\n /* on success */\n },\n onFailed: (_file: any, _res: any) => {\n /* on failed */\n },\n onError: (_file: any, _err: any, _res: any) => {\n /* on error */\n /* on timeout */\n },\n\n onInsertedAttachment(_elem: AttachmentElement) {\n // 插入文件之后的 callback\n },\n }\n}\n","/**\n * @description icon svg\n * @author wangfupeng\n */\n\n// 附件\nexport const ATTACHMENT_SVG = '<svg viewBox=\"0 0 1024 1024\"><path d=\"M665.821116 327.053068l-64.958782-64.926783-324.79391 324.729911c-53.822991 53.790991-53.822991 141.053355 0 194.844347s141.053355 53.790991 194.876346 0l389.752692-389.688693a229.531696 229.531696 0 0 0 0-324.729912 229.627694 229.627694 0 0 0-324.761911 0L126.727224 476.458266l-0.863984 0.831985c-125.085655 125.085655-125.085655 327.833853 0 452.887508 125.053655 125.053655 327.865853 125.053655 452.983507 0l0.831984-0.863984 0.031999 0.032 279.322763-279.290764-64.990781-64.926782-279.322763 279.258764-0.831984 0.831984a228.731711 228.731711 0 0 1-323.065943 0 228.603714 228.603714 0 0 1 0-322.969944l0.895983-0.831985-0.031999-0.063998L600.958332 132.208721c53.694993-53.726993 141.149353-53.726993 194.876346 0s53.694993 141.149353 0 194.844347L406.081986 716.741761c-17.919664 17.919664-47.039118 17.919664-64.958782 0a45.983138 45.983138 0 0 1 0-64.926783L665.917114 327.053068z\"></path></svg>'\n\n// 下载\nexport const DOWNLOAD_SVG = '<svg viewBox=\"0 0 1024 1024\"><path d=\"M736 448l-256 256-256-256h160V64h192v384z m-256 256H0v256h960v-256H480z m416 128h-128v-64h128v64z\"></path></svg>'\n","/**\n * @description download attachment menu\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu,\n IDomEditor,\n SlateRange,\n t,\n} from '@wangeditor-next/editor'\n\nimport { DOWNLOAD_SVG } from '../../constants/icon-svg'\nimport { AttachmentElement } from '../custom-types'\n\nclass DownloadAttachmentMenu implements IButtonMenu {\n readonly title = t('attachment.download')\n\n readonly iconSvg = DOWNLOAD_SVG\n\n readonly tag = 'button'\n\n readonly alwaysEnable = true\n\n getValue(editor: IDomEditor): string | boolean {\n const attachmentElem = this.getSelectedElem(editor)\n\n if (attachmentElem == null) { return '' }\n return attachmentElem.link\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 任何时候,都不用激活 menu\n return false\n }\n\n exec(_editor: IDomEditor, value: string | boolean) {\n if (!value) { return }\n if (typeof value !== 'string') { return }\n window.open(value, '_blank')\n }\n\n isDisabled(editor: IDomEditor): boolean {\n const { selection } = editor\n\n if (selection == null) { return true }\n if (SlateRange.isExpanded(selection)) { return true }\n\n // 未匹配到 attachment node 则禁用\n const attachmentElem = this.getSelectedElem(editor)\n\n if (attachmentElem == null) { return true }\n\n return false\n }\n\n private getSelectedElem(editor: IDomEditor): AttachmentElement | null {\n const node = DomEditor.getSelectedNodeByType(editor, 'attachment')\n\n if (node == null) { return null }\n return node as AttachmentElement\n }\n}\n\nexport default DownloadAttachmentMenu\n","/**\n * @description DOM 操作\n * @author wangfupeng\n */\n\nimport $, {\n append, click, hide, on,\n} from 'dom7'\n\nif (hide) { $.fn.hide = hide }\nif (append) { $.fn.append = append }\nif (click) { $.fn.click = click }\nif (on) { $.fn.on = on }\n\nexport { Dom7Array } from 'dom7'\nexport default $\n\n// COMPAT: This is required to prevent TypeScript aliases from doing some very\n// weird things for Slate's types with the same name as globals. (2019/11/27)\n// https://github.com/microsoft/TypeScript/issues/35002\nimport DOMNode = globalThis.Node\nimport DOMComment = globalThis.Comment\nimport DOMElement = globalThis.Element\nimport DOMText = globalThis.Text\nimport DOMRange = globalThis.Range\nimport DOMSelection = globalThis.Selection\nimport DOMStaticRange = globalThis.StaticRange\n\nexport {\n DOMComment,\n DOMElement,\n DOMNode,\n DOMRange,\n DOMSelection,\n DOMStaticRange,\n DOMText,\n}\n","/**\n * @description helper fns\n * @author wangfupeng\n */\n\nimport { createUploader, IDomEditor } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from '../custom-types'\nimport {\n genUploadAttachmentMenuConfig,\n IUploadConfigForAttachment,\n} from './config'\n\nfunction getUploadAttachmentMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {\n const defaultConfig = genUploadAttachmentMenuConfig()\n const menuConfig = editor.getMenuConfig('uploadAttachment') as Partial<IUploadConfigForAttachment>\n\n return {\n ...defaultConfig,\n ...(menuConfig || {}),\n }\n}\n\n/**\n * 插入 attachment 节点\n * @param fileName fileName\n * @param link link\n */\nexport function insertAttachment(editor: IDomEditor, fileName: string, link: string) {\n if (!fileName || !link) { return }\n\n // 还原选区\n editor.restoreSelection()\n\n // 插入节点\n const attachmentElem: AttachmentElement = {\n type: 'attachment',\n fileName,\n link,\n children: [{ text: '' }],\n }\n\n editor.insertNode(attachmentElem)\n editor.move(1)\n\n // 回调\n const { onInsertedAttachment } = getUploadAttachmentMenuConfig(editor)\n\n if (onInsertedAttachment) { onInsertedAttachment(attachmentElem) }\n}\n\n// 存储 editor uploader 的关系 - 缓存 uploader ,不重复创建\nconst EDITOR_TO_UPLOADER_MAP = new WeakMap<IDomEditor, any>()\n\n/**\n * 获取 uploader 实例(并通过 editor 缓存)\n * @param editor editor\n */\nfunction getUploader(editor: IDomEditor) {\n let uploader = EDITOR_TO_UPLOADER_MAP.get(editor)\n\n if (uploader != null) { return uploader }\n\n const menuConfig = getUploadAttachmentMenuConfig(editor)\n const {\n customInsert,\n onError,\n onFailed,\n onProgress,\n onSuccess,\n } = menuConfig\n\n // 上传完成之后\n const successHandler = (file: any, res: any) => {\n // 预期 res 格式:\n // 成功:{ errno: 0, data: { url } }\n // 失败:{ errno: !0, message: '失败信息' }\n if (customInsert) {\n customInsert(res, file, (fileName: string, link: string) => insertAttachment(editor, fileName, link))\n onSuccess(file, res)\n return\n }\n\n const { errno = 1, data = {} } = res || {}\n\n if (errno !== 0) {\n onFailed(file, res)\n return\n }\n\n const { url = '' } = data as { url?: string }\n\n insertAttachment(editor, file?.name || '', url)\n onSuccess(file, res)\n }\n\n // progress 显示进度条\n const progressHandler = (progress: number) => {\n editor.showProgressBar(progress)\n\n if (onProgress) { onProgress(progress) }\n }\n\n // onError 提示错误\n const errorHandler = (file: any, err: any, res: any) => {\n onError(file, err, res)\n }\n\n uploader = createUploader(\n {\n ...menuConfig,\n onProgress: progressHandler,\n onSuccess: successHandler,\n onError: errorHandler,\n } as any,\n editor,\n )\n\n EDITOR_TO_UPLOADER_MAP.set(editor, uploader)\n\n return uploader\n}\n\n/**\n * 上传文件\n * @param editor editor\n * @param files files\n */\nasync function uploadFile(editor: IDomEditor, files: File[]) {\n const uploader = getUploader(editor)\n const uploadList = files.map(file => ({\n name: file.name,\n type: file.type,\n size: file.size,\n data: file,\n }))\n\n uploader.addFiles(uploadList)\n await uploader.upload()\n}\n\n/**\n * 上传附件文件\n * @param editor editor\n * @param files files\n */\nexport async function uploadAttachments(\n editor: IDomEditor,\n files: FileList | File[] | null,\n) {\n if (files == null) { return }\n const fileList = Array.prototype.slice.call(files) as File[]\n\n // 获取菜单配置\n const { customUpload } = getUploadAttachmentMenuConfig(editor)\n const uploadFileList: File[] = []\n\n // 按顺序上传\n for await (const file of fileList) {\n if (customUpload) {\n // 自定义上传\n await customUpload(\n file,\n (fileName: string, link: string) => insertAttachment(editor, fileName, link),\n editor,\n )\n } else {\n // 默认上传\n uploadFileList.push(file)\n }\n }\n\n if (uploadFileList.length > 0) {\n await uploadFile(editor, uploadFileList)\n }\n}\n","/**\n * @description upload attachment menu\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu,\n IDomEditor,\n SlateRange,\n t,\n} from '@wangeditor-next/editor'\n\nimport { ATTACHMENT_SVG } from '../../constants/icon-svg'\nimport $ from '../../utils/dom'\nimport { IUploadConfigForAttachment } from './config'\nimport { insertAttachment, uploadAttachments } from './helper'\n\nclass UploadAttachmentMenu implements IButtonMenu {\n readonly title = t('attachment.upload')\n\n readonly iconSvg = ATTACHMENT_SVG\n\n readonly tag = 'button'\n\n getValue(_editor: IDomEditor): string | boolean {\n // 无需获取 val\n return ''\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 任何时候,都不用激活 menu\n return false\n }\n\n exec(editor: IDomEditor, _value: string | boolean) {\n const {\n allowedFileTypes = [],\n customBrowseAndUpload,\n } = this.getMenuConfig(editor)\n\n // 自定义选择文件、并上传,如图床\n if (customBrowseAndUpload) {\n customBrowseAndUpload((fileName: string, link: string) => insertAttachment(editor, fileName, link))\n return\n }\n\n // 设置选择文件的类型\n let acceptAttr = ''\n\n if (allowedFileTypes.length > 0) {\n acceptAttr = `accept=\"${allowedFileTypes.join(', ')}\"`\n }\n\n // 添加 file input(每次重新创建 input)\n const $body = $('body')\n const $inputFile = $(`<input type=\"file\" ${acceptAttr} multiple/>`)\n\n $inputFile.hide()\n $body.append($inputFile)\n $inputFile.click()\n // 选中文件\n $inputFile.on('change', () => {\n const files = ($inputFile[0] as HTMLInputElement).files\n\n uploadAttachments(editor, files)\n })\n }\n\n isDisabled(editor: IDomEditor): boolean {\n const { selection } = editor\n\n if (selection == null) { return true }\n if (SlateRange.isExpanded(selection)) { return true }\n\n const selectedElems = DomEditor.getSelectedElems(editor)\n const hasVoidElem = selectedElems.some(elem => editor.isVoid(elem))\n\n if (hasVoidElem) { return true }\n\n const hasPreElem = selectedElems.some(elem => DomEditor.getNodeType(elem) === 'pre')\n\n if (hasPreElem) { return true }\n\n return false\n }\n\n private getMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {\n return editor.getMenuConfig('uploadAttachment') as IUploadConfigForAttachment\n }\n}\n\nexport default UploadAttachmentMenu\n","/**\n * @description render elem\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor, SlateElement } from '@wangeditor-next/editor'\nimport { h, VNode } from 'snabbdom'\n\nimport { AttachmentElement } from './custom-types'\n\nfunction renderAttachment(elem: SlateElement, _children: VNode[] | null, editor: IDomEditor): VNode {\n const isDisabled = editor.isDisabled()\n const selected = DomEditor.isNodeSelected(editor, elem)\n const { fileName = '', link = '' } = elem as AttachmentElement\n\n const vnode = h(\n 'span',\n {\n props: {\n contentEditable: false,\n },\n style: {\n display: 'inline-block',\n marginLeft: '3px',\n marginRight: '3px',\n border: selected && !isDisabled\n ? '2px solid var(--w-e-textarea-selected-border-color)'\n : '2px solid transparent',\n borderRadius: '3px',\n padding: '0 3px',\n backgroundColor: 'var(--w-e-textarea-slight-bg-color)',\n cursor: isDisabled ? 'pointer' : 'inherit',\n },\n on: {\n // disable 时,点击下载附件\n click() {\n if (!isDisabled) { return }\n if (link) {\n window.open(link, '_blank')\n }\n },\n },\n },\n [\n h('span', {\n style: {\n marginRight: '0.2em',\n opacity: '0.7',\n },\n }, 'file'),\n fileName,\n ],\n )\n\n return vnode\n}\n\nconst conf = {\n type: 'attachment',\n renderElem: renderAttachment,\n}\n\nexport default conf\n","/**\n * @description attachment module entry\n * @author wangfupeng\n */\n\nimport './local'\n\nimport { IModuleConf } from '@wangeditor-next/editor'\n\nimport elemToHtmlConf from './elem-to-html'\nimport {\n downloadAttachmentMenuConf,\n uploadAttachmentMenuConf,\n} from './menu/index'\nimport parseHtmlConf from './parse-elem-html'\nimport withAttachment from './plugin'\nimport renderElemConf from './render-elem'\n\nconst module: Partial<IModuleConf> = {\n editorPlugin: withAttachment,\n renderElems: [renderElemConf],\n elemsToHtml: [elemToHtmlConf],\n parseElemsHtml: [parseHtmlConf],\n menus: [uploadAttachmentMenuConf, downloadAttachmentMenuConf],\n}\n\nexport default module\n","/**\n * @description attachment plugin\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor } from '@wangeditor-next/editor'\n\nfunction withAttachment<T extends IDomEditor>(editor: T) {\n const { isInline, isVoid } = editor\n const newEditor = editor\n\n // 重写 isInline\n newEditor.isInline = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'attachment') {\n return true\n }\n\n return isInline(elem)\n }\n\n // 重写 isVoid\n newEditor.isVoid = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'attachment') {\n return true\n }\n\n return isVoid(elem)\n }\n\n return newEditor\n}\n\nexport default withAttachment\n","/**\n * @description parse elem html\n * @author wangfupeng\n */\n\nimport { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor-next/editor'\n\nimport { DOMElement } from '../utils/dom'\nimport { AttachmentElement } from './custom-types'\n\nfunction parseHtml(\n elem: DOMElement,\n _children: SlateDescendant[],\n _editor: IDomEditor,\n): SlateElement {\n const link = elem.getAttribute('href') || ''\n const fileName = elem.getAttribute('download') || ''\n\n return {\n type: 'attachment',\n link,\n fileName,\n children: [{ text: '' }], // void node 必须有一个空白 text\n } as AttachmentElement\n}\n\nconst parseHtmlConf = {\n selector: 'a[data-w-e-type=\"attachment\"]',\n parseElemHtml: parseHtml,\n}\n\nexport default parseHtmlConf\n","/**\n * @description menu entry\n * @author wangfupeng\n */\n\nimport { genUploadAttachmentMenuConfig } from './config'\nimport DownloadAttachmentMenu from './DownloadAttachment'\nimport UploadAttachmentMenu from './UploadAttachment'\n\nexport const uploadAttachmentMenuConf = {\n key: 'uploadAttachment',\n factory() {\n return new UploadAttachmentMenu()\n },\n\n // 默认菜单配置,将存储在 editorConfig.MENU_CONF[key] 中\n // 创建编辑器时,可通过 editorConfig.MENU_CONF[key] = {...} 来修改\n config: genUploadAttachmentMenuConfig(),\n}\n\nexport const downloadAttachmentMenuConf = {\n key: 'downloadAttachment',\n factory() {\n return new DownloadAttachmentMenu()\n },\n}\n"],"names":["i18nAddResources","attachment","upload","download","conf","type","elemToHtml","elem","_childrenHtml","_a","_b","link","_c","fileName","concat","genUploadAttachmentMenuConfig","server","fieldName","maxFileSize","maxNumberOfFiles","allowedFileTypes","meta","metaWithUrl","withCredentials","timeout","onBeforeUpload","files","onProgress","_progress","onSuccess","_file","_res","onFailed","onError","_err","onInsertedAttachment","_elem","DownloadAttachmentMenu","this","title","t","iconSvg","tag","alwaysEnable","prototype","getValue","editor","attachmentElem","getSelectedElem","isActive","_editor","exec","value","window","open","isDisabled","selection","SlateRange","isExpanded","node","DomEditor","getSelectedNodeByType","hide","$","fn","append","click","on","getUploadAttachmentMenuConfig","defaultConfig","menuConfig","getMenuConfig","__assign","insertAttachment","restoreSelection","children","text","insertNode","move","EDITOR_TO_UPLOADER_MAP","WeakMap","uploadFile","uploader","get","customInsert","createUploader","progress","showProgressBar","file","res","errno","data","_d","url","name","err","set","getUploader","uploadList","map","size","addFiles","sent","UploadAttachmentMenu","_value","customBrowseAndUpload","acceptAttr","length","join","$body","$inputFile","fileList","Array","slice","call","customUpload","uploadFileList","fileList_1","__asyncValues","fileList_1_1","_e","push","uploadAttachments","selectedElems","getSelectedElems","some","isVoid","getNodeType","module","editorPlugin","isInline","newEditor","renderElems","renderElem","_children","selected","isNodeSelected","h","props","contentEditable","style","display","marginLeft","marginRight","border","borderRadius","padding","backgroundColor","cursor","opacity","elemsToHtml","elemToHtmlConf","parseElemsHtml","selector","parseElemHtml","getAttribute","menus","key","factory","config"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/module/local.ts","../src/module/elem-to-html.ts","../src/module/menu/config.ts","../src/constants/icon-svg.ts","../src/module/menu/DownloadAttachment.ts","../src/utils/dom.ts","../src/module/menu/helper.ts","../src/module/menu/UploadAttachment.ts","../src/module/render-elem.ts","../src/module/index.ts","../src/module/plugin.ts","../src/module/parse-elem-html.ts","../src/module/menu/index.ts"],"sourcesContent":["/**\n * @description 多语言\n * @author wangfupeng\n */\n\nimport { i18nAddResources } from '@wangeditor-next/editor'\n\ni18nAddResources('en', {\n attachment: {\n upload: 'Upload Attachment',\n download: 'Download Attachment',\n },\n})\n\ni18nAddResources('zh-CN', {\n attachment: {\n upload: '上传附件',\n download: '下载附件',\n },\n})\n","/**\n * @description elem to html\n * @author wangfupeng\n */\n\nimport { SlateElement } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from './custom-types'\n\n// 生成 html 的函数\nfunction attachmentToHtml(elem: SlateElement, _childrenHtml: string): string {\n const { link = '', fileName = '' } = elem as AttachmentElement\n\n return `<a data-w-e-type=\"attachment\" data-w-e-is-void data-w-e-is-inline href=\"${link}\" download=\"${fileName}\">${fileName}</a>`\n}\n\n// 配置\nconst conf = {\n type: 'attachment', // 节点 type ,重要!!!\n elemToHtml: attachmentToHtml,\n}\n\nexport default conf\n","/**\n * @description menu config\n * @author wangfupeng\n */\n\nimport { IDomEditor, IUploadConfig } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from '../custom-types'\n\ntype InsertFn = (fileName: string, link: string) => void\n\n// 在通用 uploadConfig 上,扩展 attachment 相关配置\nexport type IUploadConfigForAttachment = Omit<\n IUploadConfig,\n 'customInsert' | 'customUpload' | 'customBrowseAndUpload'\n> & {\n // 用户自定义插入附件\n customInsert?: (res: any, file: any, insertFn: InsertFn) => void\n // 用户自定义上传附件\n customUpload?: (file: File, insertFn: InsertFn, editor: IDomEditor) => void | Promise<void>\n // 自定义选择附件,如图床\n customBrowseAndUpload?: (insertFn: InsertFn) => void\n // 插入之后的回调\n onInsertedAttachment?: (elem: AttachmentElement) => void\n}\n\nexport function genUploadAttachmentMenuConfig(): IUploadConfigForAttachment {\n return {\n server: '',\n fieldName: 'wangeditor-uploaded-attachment',\n maxFileSize: 10 * 1024 * 1024,\n maxNumberOfFiles: 5,\n allowedFileTypes: ['*'],\n meta: {},\n metaWithUrl: false,\n withCredentials: false,\n timeout: 30 * 1000,\n\n onBeforeUpload: (files: any) => files,\n onProgress: (_progress: number) => {\n /* on progress */\n },\n onSuccess: (_file: any, _res: any) => {\n /* on success */\n },\n onFailed: (_file: any, _res: any) => {\n /* on failed */\n },\n onError: (_file: any, _err: any, _res: any) => {\n /* on error */\n /* on timeout */\n },\n\n onInsertedAttachment(_elem: AttachmentElement) {\n // 插入文件之后的 callback\n },\n }\n}\n","/**\n * @description icon svg\n * @author wangfupeng\n */\n\n// 附件\nexport const ATTACHMENT_SVG = '<svg viewBox=\"0 0 1024 1024\"><path d=\"M665.821116 327.053068l-64.958782-64.926783-324.79391 324.729911c-53.822991 53.790991-53.822991 141.053355 0 194.844347s141.053355 53.790991 194.876346 0l389.752692-389.688693a229.531696 229.531696 0 0 0 0-324.729912 229.627694 229.627694 0 0 0-324.761911 0L126.727224 476.458266l-0.863984 0.831985c-125.085655 125.085655-125.085655 327.833853 0 452.887508 125.053655 125.053655 327.865853 125.053655 452.983507 0l0.831984-0.863984 0.031999 0.032 279.322763-279.290764-64.990781-64.926782-279.322763 279.258764-0.831984 0.831984a228.731711 228.731711 0 0 1-323.065943 0 228.603714 228.603714 0 0 1 0-322.969944l0.895983-0.831985-0.031999-0.063998L600.958332 132.208721c53.694993-53.726993 141.149353-53.726993 194.876346 0s53.694993 141.149353 0 194.844347L406.081986 716.741761c-17.919664 17.919664-47.039118 17.919664-64.958782 0a45.983138 45.983138 0 0 1 0-64.926783L665.917114 327.053068z\"></path></svg>'\n\n// 下载\nexport const DOWNLOAD_SVG = '<svg viewBox=\"0 0 1024 1024\"><path d=\"M736 448l-256 256-256-256h160V64h192v384z m-256 256H0v256h960v-256H480z m416 128h-128v-64h128v64z\"></path></svg>'\n","/**\n * @description download attachment menu\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu,\n IDomEditor,\n SlateRange,\n t,\n} from '@wangeditor-next/editor'\n\nimport { DOWNLOAD_SVG } from '../../constants/icon-svg'\nimport { AttachmentElement } from '../custom-types'\n\nclass DownloadAttachmentMenu implements IButtonMenu {\n readonly title = t('attachment.download')\n\n readonly iconSvg = DOWNLOAD_SVG\n\n readonly tag = 'button'\n\n readonly alwaysEnable = true\n\n getValue(editor: IDomEditor): string | boolean {\n const attachmentElem = this.getSelectedElem(editor)\n\n if (attachmentElem == null) { return '' }\n return attachmentElem.link\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 任何时候,都不用激活 menu\n return false\n }\n\n exec(_editor: IDomEditor, value: string | boolean) {\n if (!value) { return }\n if (typeof value !== 'string') { return }\n window.open(value, '_blank')\n }\n\n isDisabled(editor: IDomEditor): boolean {\n const { selection } = editor\n\n if (selection == null) { return true }\n if (SlateRange.isExpanded(selection)) { return true }\n\n // 未匹配到 attachment node 则禁用\n const attachmentElem = this.getSelectedElem(editor)\n\n if (attachmentElem == null) { return true }\n\n return false\n }\n\n private getSelectedElem(editor: IDomEditor): AttachmentElement | null {\n const node = DomEditor.getSelectedNodeByType(editor, 'attachment')\n\n if (node == null) { return null }\n return node as AttachmentElement\n }\n}\n\nexport default DownloadAttachmentMenu\n","/**\n * @description DOM 操作\n * @author wangfupeng\n */\n\nimport $, {\n append, click, hide, on,\n} from 'dom7'\n\nif (hide) { $.fn.hide = hide }\nif (append) { $.fn.append = append }\nif (click) { $.fn.click = click }\nif (on) { $.fn.on = on }\n\nexport type { Dom7Array } from 'dom7'\nexport default $\n\n// COMPAT: This is required to prevent TypeScript aliases from doing some very\n// weird things for Slate's types with the same name as globals. (2019/11/27)\n// https://github.com/microsoft/TypeScript/issues/35002\nimport DOMNode = globalThis.Node\nimport DOMComment = globalThis.Comment\nimport DOMElement = globalThis.Element\nimport DOMText = globalThis.Text\nimport DOMRange = globalThis.Range\nimport DOMSelection = globalThis.Selection\nimport DOMStaticRange = globalThis.StaticRange\n\nexport {\n DOMComment,\n DOMElement,\n DOMNode,\n DOMRange,\n DOMSelection,\n DOMStaticRange,\n DOMText,\n}\n","/**\n * @description helper fns\n * @author wangfupeng\n */\n\nimport { createUploader, IDomEditor } from '@wangeditor-next/editor'\n\nimport { AttachmentElement } from '../custom-types'\nimport {\n genUploadAttachmentMenuConfig,\n IUploadConfigForAttachment,\n} from './config'\n\nfunction getUploadAttachmentMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {\n const defaultConfig = genUploadAttachmentMenuConfig()\n const menuConfig = editor.getMenuConfig('uploadAttachment') as Partial<IUploadConfigForAttachment>\n\n return {\n ...defaultConfig,\n ...(menuConfig || {}),\n }\n}\n\n/**\n * 插入 attachment 节点\n * @param fileName fileName\n * @param link link\n */\nexport function insertAttachment(editor: IDomEditor, fileName: string, link: string) {\n if (!fileName || !link) { return }\n\n // 还原选区\n editor.restoreSelection()\n\n // 插入节点\n const attachmentElem: AttachmentElement = {\n type: 'attachment',\n fileName,\n link,\n children: [{ text: '' }],\n }\n\n editor.insertNode(attachmentElem)\n editor.move(1)\n\n // 回调\n const { onInsertedAttachment } = getUploadAttachmentMenuConfig(editor)\n\n if (onInsertedAttachment) { onInsertedAttachment(attachmentElem) }\n}\n\n// 存储 editor uploader 的关系 - 缓存 uploader ,不重复创建\nconst EDITOR_TO_UPLOADER_MAP = new WeakMap<IDomEditor, any>()\n\n/**\n * 获取 uploader 实例(并通过 editor 缓存)\n * @param editor editor\n */\nfunction getUploader(editor: IDomEditor) {\n let uploader = EDITOR_TO_UPLOADER_MAP.get(editor)\n\n if (uploader != null) { return uploader }\n\n const menuConfig = getUploadAttachmentMenuConfig(editor)\n const {\n customInsert,\n onError,\n onFailed,\n onProgress,\n onSuccess,\n } = menuConfig\n\n // 上传完成之后\n const successHandler = (file: any, res: any) => {\n // 预期 res 格式:\n // 成功:{ errno: 0, data: { url } }\n // 失败:{ errno: !0, message: '失败信息' }\n if (customInsert) {\n customInsert(res, file, (fileName: string, link: string) => insertAttachment(editor, fileName, link))\n onSuccess(file, res)\n return\n }\n\n const { errno = 1, data = {} } = res || {}\n\n if (errno !== 0) {\n onFailed(file, res)\n return\n }\n\n const { url = '' } = data as { url?: string }\n\n insertAttachment(editor, file?.name || '', url)\n onSuccess(file, res)\n }\n\n // progress 显示进度条\n const progressHandler = (progress: number) => {\n editor.showProgressBar(progress)\n\n if (onProgress) { onProgress(progress) }\n }\n\n // onError 提示错误\n const errorHandler = (file: any, err: any, res: any) => {\n onError(file, err, res)\n }\n\n uploader = createUploader(\n {\n ...menuConfig,\n onProgress: progressHandler,\n onSuccess: successHandler,\n onError: errorHandler,\n } as any,\n editor,\n )\n\n EDITOR_TO_UPLOADER_MAP.set(editor, uploader)\n\n return uploader\n}\n\n/**\n * 上传文件\n * @param editor editor\n * @param files files\n */\nasync function uploadFile(editor: IDomEditor, files: File[]) {\n const uploader = getUploader(editor)\n const uploadList = files.map(file => ({\n name: file.name,\n type: file.type,\n size: file.size,\n data: file,\n }))\n\n uploader.addFiles(uploadList)\n await uploader.upload()\n}\n\n/**\n * 上传附件文件\n * @param editor editor\n * @param files files\n */\nexport async function uploadAttachments(\n editor: IDomEditor,\n files: FileList | File[] | null,\n) {\n if (files == null) { return }\n const fileList = Array.prototype.slice.call(files) as File[]\n\n // 获取菜单配置\n const { customUpload } = getUploadAttachmentMenuConfig(editor)\n const uploadFileList: File[] = []\n\n // 按顺序上传\n for await (const file of fileList) {\n if (customUpload) {\n // 自定义上传\n await customUpload(\n file,\n (fileName: string, link: string) => insertAttachment(editor, fileName, link),\n editor,\n )\n } else {\n // 默认上传\n uploadFileList.push(file)\n }\n }\n\n if (uploadFileList.length > 0) {\n await uploadFile(editor, uploadFileList)\n }\n}\n","/**\n * @description upload attachment menu\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu,\n IDomEditor,\n SlateRange,\n t,\n} from '@wangeditor-next/editor'\n\nimport { ATTACHMENT_SVG } from '../../constants/icon-svg'\nimport $ from '../../utils/dom'\nimport { IUploadConfigForAttachment } from './config'\nimport { insertAttachment, uploadAttachments } from './helper'\n\nclass UploadAttachmentMenu implements IButtonMenu {\n readonly title = t('attachment.upload')\n\n readonly iconSvg = ATTACHMENT_SVG\n\n readonly tag = 'button'\n\n getValue(_editor: IDomEditor): string | boolean {\n // 无需获取 val\n return ''\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 任何时候,都不用激活 menu\n return false\n }\n\n exec(editor: IDomEditor, _value: string | boolean) {\n const {\n allowedFileTypes = [],\n customBrowseAndUpload,\n } = this.getMenuConfig(editor)\n\n // 自定义选择文件、并上传,如图床\n if (customBrowseAndUpload) {\n customBrowseAndUpload((fileName: string, link: string) => insertAttachment(editor, fileName, link))\n return\n }\n\n // 设置选择文件的类型\n let acceptAttr = ''\n\n if (allowedFileTypes.length > 0) {\n acceptAttr = `accept=\"${allowedFileTypes.join(', ')}\"`\n }\n\n // 添加 file input(每次重新创建 input)\n const $body = $('body')\n const $inputFile = $(`<input type=\"file\" ${acceptAttr} multiple/>`)\n\n $inputFile.hide()\n $body.append($inputFile)\n $inputFile.click()\n // 选中文件\n $inputFile.on('change', () => {\n const files = ($inputFile[0] as HTMLInputElement).files\n\n uploadAttachments(editor, files)\n })\n }\n\n isDisabled(editor: IDomEditor): boolean {\n const { selection } = editor\n\n if (selection == null) { return true }\n if (SlateRange.isExpanded(selection)) { return true }\n\n const selectedElems = DomEditor.getSelectedElems(editor)\n const hasVoidElem = selectedElems.some(elem => editor.isVoid(elem))\n\n if (hasVoidElem) { return true }\n\n const hasPreElem = selectedElems.some(elem => DomEditor.getNodeType(elem) === 'pre')\n\n if (hasPreElem) { return true }\n\n return false\n }\n\n private getMenuConfig(editor: IDomEditor): IUploadConfigForAttachment {\n return editor.getMenuConfig('uploadAttachment') as IUploadConfigForAttachment\n }\n}\n\nexport default UploadAttachmentMenu\n","/**\n * @description render elem\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor, SlateElement } from '@wangeditor-next/editor'\nimport { h, VNode } from 'snabbdom'\n\nimport { AttachmentElement } from './custom-types'\n\nfunction renderAttachment(elem: SlateElement, _children: VNode[] | null, editor: IDomEditor): VNode {\n const isDisabled = editor.isDisabled()\n const selected = DomEditor.isNodeSelected(editor, elem)\n const { fileName = '', link = '' } = elem as AttachmentElement\n\n const vnode = h(\n 'span',\n {\n props: {\n contentEditable: false,\n },\n style: {\n display: 'inline-block',\n marginLeft: '3px',\n marginRight: '3px',\n border: selected && !isDisabled\n ? '2px solid var(--w-e-textarea-selected-border-color)'\n : '2px solid transparent',\n borderRadius: '3px',\n padding: '0 3px',\n backgroundColor: 'var(--w-e-textarea-slight-bg-color)',\n cursor: isDisabled ? 'pointer' : 'inherit',\n },\n on: {\n // disable 时,点击下载附件\n click() {\n if (!isDisabled) { return }\n if (link) {\n window.open(link, '_blank')\n }\n },\n },\n },\n [\n h('span', {\n style: {\n marginRight: '0.2em',\n opacity: '0.7',\n },\n }, 'file'),\n fileName,\n ],\n )\n\n return vnode\n}\n\nconst conf = {\n type: 'attachment',\n renderElem: renderAttachment,\n}\n\nexport default conf\n","/**\n * @description attachment module entry\n * @author wangfupeng\n */\n\nimport './local'\n\nimport { IModuleConf } from '@wangeditor-next/editor'\n\nimport elemToHtmlConf from './elem-to-html'\nimport {\n downloadAttachmentMenuConf,\n uploadAttachmentMenuConf,\n} from './menu/index'\nimport parseHtmlConf from './parse-elem-html'\nimport withAttachment from './plugin'\nimport renderElemConf from './render-elem'\n\nconst module: Partial<IModuleConf> = {\n editorPlugin: withAttachment,\n renderElems: [renderElemConf],\n elemsToHtml: [elemToHtmlConf],\n parseElemsHtml: [parseHtmlConf],\n menus: [uploadAttachmentMenuConf, downloadAttachmentMenuConf],\n}\n\nexport default module\n","/**\n * @description attachment plugin\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor } from '@wangeditor-next/editor'\n\nfunction withAttachment<T extends IDomEditor>(editor: T) {\n const { isInline, isVoid } = editor\n const newEditor = editor\n\n // 重写 isInline\n newEditor.isInline = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'attachment') {\n return true\n }\n\n return isInline(elem)\n }\n\n // 重写 isVoid\n newEditor.isVoid = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'attachment') {\n return true\n }\n\n return isVoid(elem)\n }\n\n return newEditor\n}\n\nexport default withAttachment\n","/**\n * @description parse elem html\n * @author wangfupeng\n */\n\nimport { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor-next/editor'\n\nimport { DOMElement } from '../utils/dom'\nimport { AttachmentElement } from './custom-types'\n\nfunction parseHtml(\n elem: DOMElement,\n _children: SlateDescendant[],\n _editor: IDomEditor,\n): SlateElement {\n const link = elem.getAttribute('href') || ''\n const fileName = elem.getAttribute('download') || ''\n\n return {\n type: 'attachment',\n link,\n fileName,\n children: [{ text: '' }], // void node 必须有一个空白 text\n } as AttachmentElement\n}\n\nconst parseHtmlConf = {\n selector: 'a[data-w-e-type=\"attachment\"]',\n parseElemHtml: parseHtml,\n}\n\nexport default parseHtmlConf\n","/**\n * @description menu entry\n * @author wangfupeng\n */\n\nimport { genUploadAttachmentMenuConfig } from './config'\nimport DownloadAttachmentMenu from './DownloadAttachment'\nimport UploadAttachmentMenu from './UploadAttachment'\n\nexport const uploadAttachmentMenuConf = {\n key: 'uploadAttachment',\n factory() {\n return new UploadAttachmentMenu()\n },\n\n // 默认菜单配置,将存储在 editorConfig.MENU_CONF[key] 中\n // 创建编辑器时,可通过 editorConfig.MENU_CONF[key] = {...} 来修改\n config: genUploadAttachmentMenuConfig(),\n}\n\nexport const downloadAttachmentMenuConf = {\n key: 'downloadAttachment',\n factory() {\n return new DownloadAttachmentMenu()\n },\n}\n"],"names":["i18nAddResources","attachment","upload","download","conf","type","elemToHtml","elem","_childrenHtml","_a","_b","link","_c","fileName","concat","genUploadAttachmentMenuConfig","server","fieldName","maxFileSize","maxNumberOfFiles","allowedFileTypes","meta","metaWithUrl","withCredentials","timeout","onBeforeUpload","files","onProgress","_progress","onSuccess","_file","_res","onFailed","onError","_err","onInsertedAttachment","_elem","DownloadAttachmentMenu","this","title","t","iconSvg","tag","alwaysEnable","prototype","getValue","editor","attachmentElem","getSelectedElem","isActive","_editor","exec","value","window","open","isDisabled","selection","SlateRange","isExpanded","node","DomEditor","getSelectedNodeByType","hide","$","fn","append","click","on","getUploadAttachmentMenuConfig","defaultConfig","menuConfig","getMenuConfig","__assign","insertAttachment","restoreSelection","children","text","insertNode","move","EDITOR_TO_UPLOADER_MAP","WeakMap","uploadFile","uploader","get","customInsert","createUploader","progress","showProgressBar","file","res","errno","data","_d","url","name","err","set","getUploader","uploadList","map","size","addFiles","sent","UploadAttachmentMenu","_value","customBrowseAndUpload","acceptAttr","length","join","$body","$inputFile","fileList","Array","slice","call","customUpload","uploadFileList","fileList_1","__asyncValues","fileList_1_1","_e","push","uploadAttachments","selectedElems","getSelectedElems","some","isVoid","getNodeType","module","editorPlugin","isInline","newEditor","renderElems","renderElem","_children","selected","isNodeSelected","h","props","contentEditable","style","display","marginLeft","marginRight","border","borderRadius","padding","backgroundColor","cursor","opacity","elemsToHtml","elemToHtmlConf","parseElemsHtml","selector","parseElemHtml","getAttribute","menus","key","factory","config"],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  * @author wangfupeng
4
4
  */
5
5
  import $ from 'dom7';
6
- export { Dom7Array } from 'dom7';
6
+ export type { Dom7Array } from 'dom7';
7
7
  export default $;
8
8
  import DOMNode = globalThis.Node;
9
9
  import DOMComment = globalThis.Comment;
@@ -10,7 +10,7 @@ import DOMText = globalThis.Text;
10
10
  import DOMRange = globalThis.Range;
11
11
  import DOMSelection = globalThis.Selection;
12
12
  import DOMStaticRange = globalThis.StaticRange;
13
- export { Dom7Array } from 'dom7';
13
+ export type { Dom7Array } from 'dom7';
14
14
  export default $;
15
15
  /**
16
16
  * 获取 tagName lower-case
@@ -8,18 +8,9 @@ export interface WithTableOptions {
8
8
  tr: ElementType;
9
9
  table: ElementType;
10
10
  tbody: ElementType;
11
- tfoot: ElementType;
12
- thead: ElementType;
11
+ tfoot?: ElementType;
12
+ thead?: ElementType;
13
13
  };
14
14
  }
15
- export declare const DEFAULT_WITH_TABLE_OPTIONS: {
16
- blocks: {
17
- td: string;
18
- th: string;
19
- content: string;
20
- tr: string;
21
- table: string;
22
- tbody: string;
23
- };
24
- };
15
+ export declare const DEFAULT_WITH_TABLE_OPTIONS: WithTableOptions;
25
16
  export {};
@@ -3,5 +3,5 @@
3
3
  * @author wangfupeng
4
4
  */
5
5
  import $ from 'dom7';
6
- export { Dom7Array } from 'dom7';
6
+ export type { Dom7Array } from 'dom7';
7
7
  export default $;
@@ -11,7 +11,7 @@ import DOMText = globalThis.Text;
11
11
  import DOMRange = globalThis.Range;
12
12
  import DOMSelection = globalThis.Selection;
13
13
  import DOMStaticRange = globalThis.StaticRange;
14
- export { Dom7Array } from 'dom7';
14
+ export type { Dom7Array } from 'dom7';
15
15
  export default $;
16
16
  /**
17
17
  * 获取 tagName lower-case
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wangeditor-next/plugin-attachment",
3
- "version": "6.1.1",
3
+ "version": "6.3.0",
4
4
  "description": "wangEditor attachment plugin",
5
5
  "author": "cycleccc <2991205548@qq.com>",
6
6
  "type": "module",
@@ -14,8 +14,7 @@
14
14
  "types": "./dist/plugin-attachment/src/index.d.ts",
15
15
  "import": "./dist/index.mjs",
16
16
  "require": "./dist/index.js"
17
- },
18
- "./dist/css/style.css": "./dist/css/style.css"
17
+ }
19
18
  },
20
19
  "directories": {
21
20
  "lib": "dist"
@@ -36,7 +35,7 @@
36
35
  "peerDependencies": {
37
36
  "dom7": "^3.0.0 || ^4.0.0",
38
37
  "snabbdom": "^3.6.0",
39
- "@wangeditor-next/editor": "^6.1.1"
38
+ "@wangeditor-next/editor": "^6.3.0"
40
39
  },
41
40
  "devDependencies": {
42
41
  "@wangeditor-next-shared/rollup-config": "^0.0.2"