index.ts 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import { ModuleControl, queenApi } from "queenjs";
  2. import { reactive, toRaw } from "vue";
  3. import { EditorModule } from "../../module";
  4. const stylesKey: { [key: string]: any } = {
  5. fontSize: "font-size",
  6. fontFamily: "font-family",
  7. letterSpacing: "letter-spacing",
  8. lineHeight: "line-height",
  9. alignment: "text-align",
  10. fontColor: "color",
  11. textStroke: "-webkit-text-stroke",
  12. };
  13. export class TextEditorCtrl extends ModuleControl<EditorModule> {
  14. state = reactive({
  15. currEditor: null as any,
  16. });
  17. constructor(moduel: EditorModule) {
  18. super(moduel);
  19. }
  20. setCurrEditor(editor: any) {
  21. this.state.currEditor = editor;
  22. }
  23. async setLinkUrl() {
  24. const res = await queenApi.showInput({
  25. title: "请输入链接地址",
  26. defaultValue: "http://",
  27. });
  28. if (!res) {
  29. return;
  30. }
  31. if (!this.state.currEditor) {
  32. let alink = `<a href="${res}"><span style="font-size:14px">${res}</span></a>`;
  33. const compValue = this.store.currComp.value;
  34. const pTagReg = /(<p[\s\S]*?>)([\s\S]*?)(<\/p>)/gi;
  35. const blocks = compValue.match(pTagReg);
  36. if (!blocks) {
  37. return;
  38. }
  39. blocks[blocks.length - 1] = blocks[blocks.length - 1].replace(
  40. pTagReg,
  41. `$1$2${alink}$3`
  42. );
  43. this.actions.updateCompData(
  44. this.store.currComp,
  45. "value",
  46. blocks.join("")
  47. );
  48. return;
  49. }
  50. const editor = toRaw(this.state.currEditor);
  51. editor.execute("link", res);
  52. }
  53. setCompValueInReg(key: string, e: any) {
  54. const addTagsKey = ["bold", "italic", "underline", "strikethrough"];
  55. if (addTagsKey.includes(key)) {
  56. this.addCompValueTags(key, e);
  57. return;
  58. }
  59. const compValue = this.store.currComp.value;
  60. const pTagReg = /(<p[\s\S]*?>)([\s\S]*?)(<\/p>)/gi;
  61. const blocks = compValue.match(pTagReg);
  62. if (!blocks) {
  63. return;
  64. }
  65. const blockStyles = ["lineHeight", "alignment"];
  66. blocks.map((item: string, index: number) => {
  67. const isBlockStyle = blockStyles.includes(key);
  68. let stylesStr = null;
  69. if (isBlockStyle) {
  70. stylesStr = this.blockStyleChange(item, key, e);
  71. } else {
  72. stylesStr = this.spanStyleChange(item, key, e);
  73. }
  74. blocks[index] = stylesStr;
  75. });
  76. this.actions.updateCompData(this.store.currComp, "value", blocks.join(""));
  77. }
  78. blockStyleChange(item: string, key: string, e: any) {
  79. const pStyleReg = /<p[\s|\s]*style=[\s|\S]*?>/;
  80. let blockStr = item;
  81. const hasStyles = item.indexOf(stylesKey[key]);
  82. if (hasStyles != -1) {
  83. const regString = `(${stylesKey[key]}:)([\\s\\S]*?)(\\;)`;
  84. const styleReg = new RegExp(regString, "ig");
  85. blockStr = item.replace(styleReg, `$1${e.value}$3`);
  86. return blockStr;
  87. }
  88. if (pStyleReg.test(item)) {
  89. const addStyleReg = /(<p[\s|\s]*style=[\s|\S]*?)(">[\s|\S]*)/;
  90. blockStr = item.replace(addStyleReg, `$${stylesKey[key]}:${e.value};$2`);
  91. } else {
  92. const noStyleReg = /(<p[\s|\s]*)(>[\s|\S]*)/;
  93. blockStr = item.replace(
  94. noStyleReg,
  95. `$1 style="${stylesKey[key]}:${e.value};"$2`
  96. );
  97. }
  98. return blockStr;
  99. }
  100. spanStyleChange(item: string, key: string, e: any) {
  101. const pTagReg = /(<p[\s\S]*?>)([\s\S]*?)(<\/p>)/gi;
  102. let spanStr = item;
  103. const hasSpan: any = spanStr.indexOf("span");
  104. if (hasSpan == -1) {
  105. spanStr = spanStr.replace(
  106. pTagReg,
  107. '$1<span style="font-size:14px;">$2</span>$3'
  108. );
  109. }
  110. const hasStyles = item.indexOf(stylesKey[key]);
  111. if (hasStyles != -1) {
  112. const regString = `(${stylesKey[key]}:)([\\s\\S]*?)(\\;)`;
  113. const styleReg = new RegExp(regString, "ig");
  114. spanStr = spanStr.replace(styleReg, `$1${e.value}$3`);
  115. } else {
  116. const addStyleReg = /(<span\s*style=[\s|\S]*?)(">[\s|\S]*?<\/span>)/g;
  117. spanStr = spanStr.replace(
  118. addStyleReg,
  119. `$1${stylesKey[key]}:${e.value};$2`
  120. );
  121. }
  122. const noStyleReg = /(<span\s*?)(>[\s|\S]*?<\/span>)/g;
  123. spanStr = spanStr.replace(
  124. noStyleReg,
  125. `$1 style="${stylesKey[key]}:${e.value};">$2`
  126. );
  127. return spanStr;
  128. }
  129. addCompValueTags(key: string, e: any) {
  130. const compValue = this.store.currComp.value;
  131. const pTagReg = /(<p[\s\S]*?>)([\s\S]*?)(<\/p>)/gi;
  132. const blocks = compValue.match(pTagReg);
  133. if (!blocks) {
  134. return;
  135. }
  136. blocks.map((item: string, index: number) => {
  137. const hasSpan: any = item.indexOf("span");
  138. if (hasSpan != -1) {
  139. blocks[index] = this.formatSortTags(item, key, e);
  140. return;
  141. }
  142. const spanStr = item.replace(
  143. pTagReg,
  144. '$1<span style="font-size:14px;">$2</span>$3'
  145. );
  146. blocks[index] = this.formatSortTags(spanStr, key, e);
  147. });
  148. this.actions.updateCompData(this.store.currComp, "value", blocks.join(""));
  149. }
  150. formatSortTags(item: string, key: string, e: any) {
  151. const keyToTags: { [key: string]: any }[] = [
  152. {
  153. key: "italic",
  154. tag: "<i>",
  155. end: "</i>",
  156. },
  157. {
  158. key: "strikethrough",
  159. tag: "<s>",
  160. end: "</s>",
  161. },
  162. {
  163. key: "bold",
  164. tag: "<strong>",
  165. end: "</strong>",
  166. },
  167. {
  168. key: "underline",
  169. tag: "<u>",
  170. end: "</u>",
  171. },
  172. ];
  173. const spanTagReg = /([\s\S]*?<span[\s\S]*?>)([\s\S]*?)(<\/span>[\s\S]*?)/gi;
  174. let htmlStr = item;
  175. if (e.value) {
  176. const currTagIndex = keyToTags.findIndex((e: any) => {
  177. return e.key == key;
  178. });
  179. if (currTagIndex == -1) {
  180. return htmlStr;
  181. }
  182. if (htmlStr.indexOf(keyToTags[currTagIndex].tag) != -1) {
  183. return htmlStr;
  184. }
  185. if (currTagIndex == 0) {
  186. htmlStr = htmlStr.replace(
  187. spanTagReg,
  188. `$1${keyToTags[0].tag}$2${keyToTags[0].end}$3`
  189. );
  190. }
  191. if (currTagIndex > 0) {
  192. let prevTagIndex = currTagIndex - 1;
  193. let prevTag: any = null;
  194. for (let i = prevTagIndex; i >= 0; i--) {
  195. const hasTag: any = htmlStr.indexOf(keyToTags[prevTagIndex].tag);
  196. if (hasTag != -1) {
  197. prevTag = keyToTags[prevTagIndex];
  198. break;
  199. }
  200. }
  201. if (prevTag) {
  202. const regString = `([\\s\\S]*?)(${prevTag.tag})([\\s\\S]*?)(${prevTag.end})([\\s\\S]*?)`;
  203. const tempReg = new RegExp(regString, "ig");
  204. htmlStr = htmlStr.replace(
  205. tempReg,
  206. `$1$2${keyToTags[currTagIndex].tag}$3${keyToTags[currTagIndex].end}$4$5`
  207. );
  208. } else {
  209. htmlStr = htmlStr.replace(
  210. spanTagReg,
  211. `$1${keyToTags[currTagIndex].tag}$2${keyToTags[currTagIndex].end}$3`
  212. );
  213. }
  214. }
  215. } else {
  216. const currTag = keyToTags.find((e: any) => {
  217. return e.key == key;
  218. });
  219. if (!currTag) {
  220. return htmlStr;
  221. }
  222. const regString = `([\\s\\S]*?)(${currTag?.tag})([\\s\\S]*?)(${currTag?.end})([\\s\\S]*?)`;
  223. const tempReg = new RegExp(regString, "ig");
  224. htmlStr = htmlStr.replace(tempReg, "$1$3$5");
  225. }
  226. return htmlStr;
  227. }
  228. }