@opentiny/fluent-editor 3.18.4 → 3.19.0-alpha.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.
package/index.es.js CHANGED
@@ -4854,7 +4854,7 @@ Block$4.blotName = "block";
4854
4854
  Block$4.tagName = "P";
4855
4855
  Block$4.defaultChild = Break$1;
4856
4856
  Block$4.allowedChildren = [Break$1, Inline$3, EmbedBlot$1, Text$1];
4857
- class BlockEmbed extends EmbedBlot$1 {
4857
+ class BlockEmbed$1 extends EmbedBlot$1 {
4858
4858
  attach() {
4859
4859
  super.attach();
4860
4860
  this.attributes = new AttributorStore$1(this.domNode);
@@ -4895,7 +4895,7 @@ class BlockEmbed extends EmbedBlot$1 {
4895
4895
  }
4896
4896
  }
4897
4897
  }
4898
- BlockEmbed.scope = Scope$1.BLOCK_BLOT;
4898
+ BlockEmbed$1.scope = Scope$1.BLOCK_BLOT;
4899
4899
  function blockDelta(blot) {
4900
4900
  let filter = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
4901
4901
  return blot.descendants(LeafBlot$1).reduce((delta, leaf2) => {
@@ -5720,7 +5720,7 @@ class Editor {
5720
5720
  deleteDelta.retain(length);
5721
5721
  if (typeof op.insert === "string") {
5722
5722
  const text = op.insert;
5723
- isImplicitNewlineAppended = !text.endsWith("\n") && (scrollLength <= index || !!this.scroll.descendant(BlockEmbed, index)[0]);
5723
+ isImplicitNewlineAppended = !text.endsWith("\n") && (scrollLength <= index || !!this.scroll.descendant(BlockEmbed$1, index)[0]);
5724
5724
  this.scroll.insertAt(index, text);
5725
5725
  const [line, offset] = this.scroll.line(index);
5726
5726
  let formats = deepmerge({}, bubbleFormats(line));
@@ -5737,7 +5737,7 @@ class Editor {
5737
5737
  return index;
5738
5738
  const isInlineEmbed = this.scroll.query(key, Scope$1.INLINE) != null;
5739
5739
  if (isInlineEmbed) {
5740
- if (scrollLength <= index || !!this.scroll.descendant(BlockEmbed, index)[0]) {
5740
+ if (scrollLength <= index || !!this.scroll.descendant(BlockEmbed$1, index)[0]) {
5741
5741
  isImplicitNewlineAppended = true;
5742
5742
  }
5743
5743
  } else if (index > 0) {
@@ -6103,7 +6103,7 @@ class Module$5 {
6103
6103
  }
6104
6104
  __publicField(Module$5, "DEFAULTS", {});
6105
6105
  const GUARD_TEXT = "\uFEFF";
6106
- class Embed$6 extends EmbedBlot$1 {
6106
+ class Embed$5 extends EmbedBlot$1 {
6107
6107
  constructor(scroll, node) {
6108
6108
  super(scroll, node);
6109
6109
  this.contentNode = document.createElement("span");
@@ -6196,7 +6196,7 @@ class Composition {
6196
6196
  }
6197
6197
  handleCompositionStart(event) {
6198
6198
  const blot = event.target instanceof Node ? this.scroll.find(event.target, true) : null;
6199
- if (blot && !(blot instanceof Embed$6)) {
6199
+ if (blot && !(blot instanceof Embed$5)) {
6200
6200
  this.emitter.emit(Emitter.events.COMPOSITION_BEFORE_START, event);
6201
6201
  this.scroll.batchStart();
6202
6202
  this.emitter.emit(Emitter.events.COMPOSITION_START, event);
@@ -6907,7 +6907,7 @@ function shiftRange(range, index, lengthOrSource, source2) {
6907
6907
  class Container$2 extends ContainerBlot$1 {
6908
6908
  }
6909
6909
  function isLine$1(blot) {
6910
- return blot instanceof Block$4 || blot instanceof BlockEmbed;
6910
+ return blot instanceof Block$4 || blot instanceof BlockEmbed$1;
6911
6911
  }
6912
6912
  function isUpdatable(blot) {
6913
6913
  return typeof blot.updateContent === "function";
@@ -6950,7 +6950,7 @@ class Scroll extends ScrollBlot$1 {
6950
6950
  const [last] = this.line(index + length);
6951
6951
  super.deleteAt(index, length);
6952
6952
  if (last != null && first !== last && offset > 0) {
6953
- if (first instanceof BlockEmbed || last instanceof BlockEmbed) {
6953
+ if (first instanceof BlockEmbed$1 || last instanceof BlockEmbed$1) {
6954
6954
  this.optimize();
6955
6955
  return;
6956
6956
  }
@@ -7004,7 +7004,7 @@ class Scroll extends ScrollBlot$1 {
7004
7004
  this.batchStart();
7005
7005
  const first = renderBlocks.shift();
7006
7006
  if (first) {
7007
- const shouldInsertNewlineChar = first.type === "block" && (first.delta.length() === 0 || !this.descendant(BlockEmbed, index)[0] && index < this.length());
7007
+ const shouldInsertNewlineChar = first.type === "block" && (first.delta.length() === 0 || !this.descendant(BlockEmbed$1, index)[0] && index < this.length());
7008
7008
  const delta2 = first.type === "block" ? first.delta : new Delta$7().insert({
7009
7009
  [first.key]: first.value
7010
7010
  });
@@ -7127,7 +7127,7 @@ class Scroll extends ScrollBlot$1 {
7127
7127
  }
7128
7128
  }
7129
7129
  updateEmbedAt(index, key, change) {
7130
- const [blot] = this.descendant((b) => b instanceof BlockEmbed, index);
7130
+ const [blot] = this.descendant((b) => b instanceof BlockEmbed$1, index);
7131
7131
  if (blot && blot.statics.blotName === key && isUpdatable(blot)) {
7132
7132
  blot.updateContent(change);
7133
7133
  }
@@ -7218,7 +7218,7 @@ __publicField(Scroll, "blotName", "scroll");
7218
7218
  __publicField(Scroll, "className", "ql-editor");
7219
7219
  __publicField(Scroll, "tagName", "DIV");
7220
7220
  __publicField(Scroll, "defaultChild", Block$4);
7221
- __publicField(Scroll, "allowedChildren", [Block$4, BlockEmbed, Container$2]);
7221
+ __publicField(Scroll, "allowedChildren", [Block$4, BlockEmbed$1, Container$2]);
7222
7222
  function insertInlineContents(parent, index, inlineContents) {
7223
7223
  inlineContents.reduce((index2, op) => {
7224
7224
  const length = Delta$8.exports.Op.length(op);
@@ -8510,7 +8510,7 @@ function matchNewline(node, delta, scroll) {
8510
8510
  return delta.insert("\n");
8511
8511
  }
8512
8512
  const match2 = scroll.query(nextSibling);
8513
- if (match2 && match2.prototype instanceof BlockEmbed) {
8513
+ if (match2 && match2.prototype instanceof BlockEmbed$1) {
8514
8514
  return delta.insert("\n");
8515
8515
  }
8516
8516
  nextSibling = nextSibling.firstChild;
@@ -8968,11 +8968,11 @@ class UINode extends Module$5 {
8968
8968
  }
8969
8969
  Quill.register({
8970
8970
  "blots/block": Block$4,
8971
- "blots/block/embed": BlockEmbed,
8971
+ "blots/block/embed": BlockEmbed$1,
8972
8972
  "blots/break": Break$1,
8973
8973
  "blots/container": Container$2,
8974
8974
  "blots/cursor": Cursor,
8975
- "blots/embed": Embed$6,
8975
+ "blots/embed": Embed$5,
8976
8976
  "blots/inline": Inline$3,
8977
8977
  "blots/scroll": Scroll,
8978
8978
  "blots/text": Text$1,
@@ -9147,7 +9147,7 @@ class Underline extends Inline$3 {
9147
9147
  }
9148
9148
  __publicField(Underline, "blotName", "underline");
9149
9149
  __publicField(Underline, "tagName", "U");
9150
- class Formula extends Embed$6 {
9150
+ class Formula extends Embed$5 {
9151
9151
  static create(value) {
9152
9152
  if (window.katex == null) {
9153
9153
  throw new Error("Formula module requires KaTeX.");
@@ -9216,7 +9216,7 @@ class Image extends EmbedBlot$1 {
9216
9216
  __publicField(Image, "blotName", "image");
9217
9217
  __publicField(Image, "tagName", "IMG");
9218
9218
  const ATTRIBUTES$5 = ["height", "width"];
9219
- class Video$1 extends BlockEmbed {
9219
+ class Video$1 extends BlockEmbed$1 {
9220
9220
  static create(value) {
9221
9221
  const node = super.create(value);
9222
9222
  node.setAttribute("frameborder", "0");
@@ -11186,6 +11186,7 @@ const FULLSCREEN_ICON = `<svg xmlns="http://www.w3.org/2000/svg" class="icon" wi
11186
11186
  <path fill="#333333" d="M64 384h96V160h224.2V64H64zM639.8 64v96H864v224h96V64zM864 864H639.8v96H960V639.61h-96zM160 639.61H64V960h320.2v-96H160z"/>
11187
11187
  </svg>`;
11188
11188
  const TRIANGLE_DOWN_ICON = `<i class="icon-triangle-down"></i>`;
11189
+ const FORMAT_PAINTER_ICON = `<svg viewBox="0 0 32 32"><path fill="currentColor" d="M28.83 23.17L23 17.33V13a1 1 0 0 0-.29-.71l-10-10a1 1 0 0 0-1.42 0l-9 9a1 1 0 0 0 0 1.42l10 10A1 1 0 0 0 13 23h4.34l5.83 5.84a4 4 0 0 0 5.66-5.66ZM6 10.41l2.29 2.3l1.42-1.42L7.41 9L9 7.41l4.29 4.3l1.42-1.42L10.41 6L12 4.41L18.59 11L11 18.59L4.41 12Zm21.41 17a2 2 0 0 1-2.82 0l-6.13-6.12a1.8 1.8 0 0 0-.71-.29h-4.34l-1-1L20 12.41l1 1v4.34a1 1 0 0 0 .29.7l6.12 6.14a2 2 0 0 1 0 2.82"/></svg>`;
11189
11190
  const Delta$6 = Quill.imports["delta"];
11190
11191
  function hexToRgbA(hex) {
11191
11192
  let color;
@@ -11559,7 +11560,8 @@ const ICONS_CONFIG = {
11559
11560
  fullscreen: FULLSCREEN_ICON,
11560
11561
  emoji: EMOJI_ICON,
11561
11562
  help: HELP_ICON,
11562
- screenshot: SCREENSHOT_ICON
11563
+ screenshot: SCREENSHOT_ICON,
11564
+ "format-painter": FORMAT_PAINTER_ICON
11563
11565
  };
11564
11566
  const TABLE_RIGHT_MENU_CONFIG = {
11565
11567
  copyCells: {
@@ -12224,10 +12226,10 @@ function renderStyles(html) {
12224
12226
  iframe.parentNode.removeChild(iframe);
12225
12227
  return convertedString;
12226
12228
  }
12227
- const Embed$5 = Quill.imports["blots/embed"];
12229
+ const Embed$4 = Quill.imports["blots/embed"];
12228
12230
  const Inline$2 = Quill.imports["blots/inline"];
12229
12231
  const ATTRIBUTES$4 = ["alt", "height", "width", "image-id"];
12230
- const _CustomImage = class extends Embed$5 {
12232
+ const _CustomImage = class extends Embed$4 {
12231
12233
  static create(value) {
12232
12234
  const node = super.create(value);
12233
12235
  const url = typeof value === "string" ? value : value.src;
@@ -13136,8 +13138,8 @@ const emojiMap = {};
13136
13138
  emojiList.forEach((emojiListObject) => {
13137
13139
  emojiMap[emojiListObject.name] = emojiListObject;
13138
13140
  });
13139
- const Embed$4 = Quill.imports["blots/embed"];
13140
- class EmojiBlot extends Embed$4 {
13141
+ const Embed$3 = Quill.imports["blots/embed"];
13142
+ class EmojiBlot extends Embed$3 {
13141
13143
  static create(value) {
13142
13144
  const node = super.create();
13143
13145
  if (typeof value === "object") {
@@ -13562,9 +13564,9 @@ function fnUpdateEmojiContainer(emojiFilter, panel, quill) {
13562
13564
  fnEmojiElementsToPanel(type, panel, quill);
13563
13565
  }
13564
13566
  var Emoji = { EmojiBlot, ShortNameEmoji, ToolbarEmoji };
13565
- const Embed$3 = Quill.imports["blots/embed"];
13567
+ const Embed$2 = Quill.imports["blots/embed"];
13566
13568
  const FILE_ATTRIBUTES = ["id", "title", "size", "lastModified"];
13567
- class File$1 extends Embed$3 {
13569
+ class File$1 extends Embed$2 {
13568
13570
  static create(value) {
13569
13571
  const node = super.create(value);
13570
13572
  const size = value.size / 1024;
@@ -14095,7 +14097,10 @@ class Tooltip extends BaseTooltip {
14095
14097
  );
14096
14098
  }
14097
14099
  save() {
14098
- let { value } = this.textbox;
14100
+ let value = this.textbox.value;
14101
+ if (!value)
14102
+ return;
14103
+ this.textbox.value = "";
14099
14104
  switch (this.root.getAttribute("data-mode")) {
14100
14105
  case "link": {
14101
14106
  const { scrollTop } = this.quill.root;
@@ -14119,9 +14124,6 @@ class Tooltip extends BaseTooltip {
14119
14124
  break;
14120
14125
  }
14121
14126
  case "formula": {
14122
- if (!value) {
14123
- break;
14124
- }
14125
14127
  const range = this.quill.getSelection(true);
14126
14128
  if (!isNullOrUndefined(range)) {
14127
14129
  const index = range.index + range.length;
@@ -14138,6 +14140,16 @@ class Tooltip extends BaseTooltip {
14138
14140
  }
14139
14141
  break;
14140
14142
  }
14143
+ case "video": {
14144
+ const range = this.quill.getSelection(true);
14145
+ this.quill.insertText(range.index, "\n", Emitter.sources.USER);
14146
+ this.quill.insertEmbed(range.index + 1, "video", { src: value }, Emitter.sources.USER);
14147
+ this.quill.insertText(range.index + 2, "\n", Emitter.sources.USER);
14148
+ this.quill.setSelection(range.index + 3, Emitter.sources.SILENT);
14149
+ this.textbox.value = "";
14150
+ this.hide();
14151
+ break;
14152
+ }
14141
14153
  }
14142
14154
  }
14143
14155
  position(reference) {
@@ -14234,8 +14246,8 @@ SnowTheme$1.prototype.extendToolbar = function(toolbar) {
14234
14246
  const ON_MENTION_LINK_REMOVE = "mention-link/remove";
14235
14247
  const MENTION_CHAR = "mentionChar";
14236
14248
  const DEFAULT_MENTION_CHAR = "@";
14237
- const Embed$2 = Quill.imports["blots/embed"];
14238
- class MentionLink extends Embed$2 {
14249
+ const Embed$1 = Quill.imports["blots/embed"];
14250
+ class MentionLink extends Embed$1 {
14239
14251
  constructor(scroll, domNode, data) {
14240
14252
  super(scroll, domNode, data);
14241
14253
  this.mentionData = data;
@@ -14591,8 +14603,8 @@ class Mention {
14591
14603
  this.quill.setSelection(this.latestMentionCharPos + 1, Quill.sources.API);
14592
14604
  }
14593
14605
  }
14594
- const Embed$1 = Quill.imports["blots/embed"];
14595
- class SoftBreak extends Embed$1 {
14606
+ const Embed = Quill.imports["blots/embed"];
14607
+ class SoftBreak extends Embed {
14596
14608
  static create() {
14597
14609
  const node = super.create();
14598
14610
  return node;
@@ -50839,24 +50851,23 @@ class BetterToolbar extends Toolbar {
50839
50851
  this.controls.push([format, input]);
50840
50852
  }
50841
50853
  }
50842
- const Embed = Quill.imports["blots/embed"];
50854
+ const BlockEmbed = Quill.imports["blots/block/embed"];
50843
50855
  const VIDEO_ATTRIBUTES = ["id", "title", "src"];
50844
- class Video extends Embed {
50856
+ class Video extends BlockEmbed {
50845
50857
  static sanitize(url) {
50846
50858
  return sanitize(url, this.PROTOCOL_WHITELIST) ? url : this.SANITIZED_URL;
50847
50859
  }
50848
50860
  static create(value) {
50849
50861
  const node = super.create(value);
50850
- node.setAttribute("contenteditable", false);
50862
+ node.setAttribute("contenteditable", "false");
50851
50863
  node.setAttribute("controls", "controls");
50852
50864
  VIDEO_ATTRIBUTES.forEach((key) => {
50853
50865
  if (value[key]) {
50854
50866
  switch (key) {
50855
- case "src": {
50867
+ case "src":
50856
50868
  const src = Video.sanitize(value[key]);
50857
50869
  node.setAttribute(key, src);
50858
50870
  break;
50859
- }
50860
50871
  case "title":
50861
50872
  node.setAttribute(key, value[key]);
50862
50873
  break;
@@ -50877,22 +50888,81 @@ class Video extends Embed {
50877
50888
  });
50878
50889
  return formats;
50879
50890
  }
50880
- static formats(domNode) {
50881
- const formats = {};
50882
- VIDEO_ATTRIBUTES.forEach((key) => {
50883
- const value = domNode.getAttribute(key) || domNode.dataset[key];
50884
- if (value) {
50885
- formats[key] = value;
50886
- }
50887
- });
50888
- return formats;
50889
- }
50890
50891
  }
50891
50892
  Video.blotName = "video";
50892
50893
  Video.tagName = "VIDEO";
50893
50894
  Video.SANITIZED_URL = "about:blank";
50894
50895
  Video.PROTOCOL_WHITELIST = ["http", "https"];
50895
50896
  Video.className = "ql-video-item";
50897
+ class FormatPainter {
50898
+ constructor(quill) {
50899
+ this.quill = quill;
50900
+ this.isFormatterLock = false;
50901
+ this.isFormating = false;
50902
+ this.rangeFormat = {};
50903
+ this.btnActive = () => {
50904
+ setTimeout(() => {
50905
+ this.formatterBtn.classList.add("ql-active");
50906
+ }, 0);
50907
+ };
50908
+ this.btnRemoveActive = () => {
50909
+ setTimeout(() => {
50910
+ this.formatterBtn.classList.remove("ql-active");
50911
+ }, 0);
50912
+ };
50913
+ this.bindFormatSelect = () => {
50914
+ const range = this.quill.getSelection();
50915
+ if (range.length === 0)
50916
+ return;
50917
+ this.rangeFormat = this.quill.getFormat(range);
50918
+ this.isFormating = true;
50919
+ this.quill.on(Quill.events.SELECTION_CHANGE, this.formatRange);
50920
+ this.btnActive();
50921
+ };
50922
+ this.unbindFormatSelect = () => {
50923
+ this.quill.off(Quill.events.SELECTION_CHANGE, this.formatRange);
50924
+ this.rangeFormat = void 0;
50925
+ this.btnRemoveActive();
50926
+ this.isFormating = false;
50927
+ this.isFormatterLock = false;
50928
+ };
50929
+ this.formatRange = (range) => {
50930
+ if (!range)
50931
+ return;
50932
+ this.quill.removeFormat(range.index, range.length);
50933
+ for (const format in this.rangeFormat) {
50934
+ this.quill.format(format, this.rangeFormat[format], Quill.sources.USER);
50935
+ }
50936
+ if (!this.isFormatterLock) {
50937
+ this.unbindFormatSelect();
50938
+ } else {
50939
+ this.btnActive();
50940
+ }
50941
+ };
50942
+ this.quill = quill;
50943
+ const toolbar = this.quill.getModule("toolbar");
50944
+ this.formatterBtn = toolbar.container.querySelector(".ql-format-painter");
50945
+ if (toolbar && this.formatterBtn) {
50946
+ this.formatterBtn.addEventListener("dblclick", () => {
50947
+ if (this.isFormatterLock) {
50948
+ this.unbindFormatSelect();
50949
+ return;
50950
+ }
50951
+ this.isFormatterLock = true;
50952
+ this.bindFormatSelect();
50953
+ });
50954
+ this.formatterBtn.addEventListener("click", () => {
50955
+ if (!this.isFormating) {
50956
+ this.bindFormatSelect();
50957
+ } else {
50958
+ this.unbindFormatSelect();
50959
+ }
50960
+ });
50961
+ }
50962
+ }
50963
+ }
50964
+ FormatPainter.toolName = "format-painter";
50965
+ FormatPainter.moduleName = "format-painter";
50896
50966
  const registerModules = function() {
50897
50967
  const FontClass2 = Quill.imports["formats/font"];
50898
50968
  FontClass2.whitelist = FONT_FAMILY_CONFIG;
@@ -50906,6 +50976,11 @@ const registerModules = function() {
50906
50976
  const SnowTheme2 = Quill.imports["themes/snow"];
50907
50977
  SnowTheme2.DEFAULTS = {
50908
50978
  modules: {
50979
+ keyboard: {
50980
+ bindings: {
50981
+ ...BetterTable.keyboardBindings
50982
+ }
50983
+ },
50909
50984
  toolbar: {
50910
50985
  handlers: {
50911
50986
  ...SnowTheme2.DEFAULTS.modules.toolbar.handlers,
@@ -50984,7 +51059,8 @@ const registerModules = function() {
50984
51059
  right: '<i class="icon-text-align-right"></i>'
50985
51060
  }
50986
51061
  }
50987
- }
51062
+ },
51063
+ "format-painter": {}
50988
51064
  }
50989
51065
  };
50990
51066
  Quill.register(
@@ -51007,7 +51083,8 @@ const registerModules = function() {
51007
51083
  "modules/emoji-toolbar": Emoji.ToolbarEmoji,
51008
51084
  "modules/emoji-shortname": Emoji.ShortNameEmoji,
51009
51085
  "modules/link": Link,
51010
- "modules/syntax": CustomSyntax
51086
+ "modules/syntax": CustomSyntax,
51087
+ "modules/format-painter": FormatPainter
51011
51088
  },
51012
51089
  true
51013
51090
  );