0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 07:13:08 -05:00

Release v2.2.6

This commit is contained in:
Neil Jenkins 2024-02-01 11:51:02 +11:00
parent 6cfd85bd8e
commit b415665d01
13 changed files with 86 additions and 113 deletions

View file

@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file, starting fr
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.2.6] - 2024-02-01
### Fixed
- Fix Firefox cursor position after paste.
- Fix keyboard handling on some Android browsers
### Added
- Add undo point for automatic list creation.
## [2.2.5] - 2023-11-08 ## [2.2.5] - 2023-11-08
### Fixed ### Fixed

61
dist/squire-raw.js vendored
View file

@ -449,13 +449,14 @@
fixer = document.createTextNode(""); fixer = document.createTextNode("");
} }
} }
} else if (node instanceof Element && !node.querySelector("BR")) { } else if ((node instanceof Element || node instanceof DocumentFragment) && !node.querySelector("BR")) {
fixer = createElement("BR"); fixer = createElement("BR");
let parent = node; let parent = node;
let child; let child;
while ((child = parent.lastElementChild) && !isInline(child)) { while ((child = parent.lastElementChild) && !isInline(child)) {
parent = child; parent = child;
} }
node = parent;
} }
if (fixer) { if (fixer) {
try { try {
@ -1310,6 +1311,7 @@
} }
if (blockContentsAfterSplit && block) { if (blockContentsAfterSplit && block) {
const tempRange = range.cloneRange(); const tempRange = range.cloneRange();
fixCursor(blockContentsAfterSplit);
mergeWithBlock(block, blockContentsAfterSplit, tempRange, root); mergeWithBlock(block, blockContentsAfterSplit, tempRange, root);
range.setEnd(tempRange.endContainer, tempRange.endOffset); range.setEnd(tempRange.endContainer, tempRange.endOffset);
} }
@ -1862,10 +1864,13 @@
const text = (_a = block.textContent) == null ? void 0 : _a.trimEnd().replace(ZWS, ""); const text = (_a = block.textContent) == null ? void 0 : _a.trimEnd().replace(ZWS, "");
if (text === "*" || text === "1.") { if (text === "*" || text === "1.") {
event.preventDefault(); event.preventDefault();
self.insertPlainText(" ", false);
self._docWasChanged();
self.saveUndoState(range);
const walker = new TreeIterator(block, SHOW_TEXT); const walker = new TreeIterator(block, SHOW_TEXT);
let textNode; let textNode;
while (textNode = walker.nextNode()) { while (textNode = walker.nextNode()) {
textNode.data = cantFocusEmptyTextNodes ? ZWS : ""; detach(textNode);
} }
if (text === "*") { if (text === "*") {
self.makeUnorderedList(); self.makeUnorderedList();
@ -1898,41 +1903,12 @@
}; };
// source/keyboard/KeyHandlers.ts // source/keyboard/KeyHandlers.ts
var keys = {
8: "Backspace",
9: "Tab",
13: "Enter",
27: "Escape",
32: "Space",
33: "PageUp",
34: "PageDown",
37: "ArrowLeft",
38: "ArrowUp",
39: "ArrowRight",
40: "ArrowDown",
46: "Delete",
191: "/",
219: "[",
220: "\\",
221: "]"
};
var _onKey = function(event) { var _onKey = function(event) {
const code = event.keyCode;
let key = keys[code];
let modifiers = "";
const range = this.getSelection();
if (event.defaultPrevented) { if (event.defaultPrevented) {
return; return;
} }
if (!key) { let key = event.key;
key = String.fromCharCode(code).toLowerCase(); let modifiers = "";
if (!/^[A-Za-z0-9]$/.test(key)) {
key = "";
}
}
if (111 < code && code < 124) {
key = "F" + (code - 111);
}
if (key !== "Backspace" && key !== "Delete") { if (key !== "Backspace" && key !== "Delete") {
if (event.altKey) { if (event.altKey) {
modifiers += "Alt-"; modifiers += "Alt-";
@ -1951,11 +1927,12 @@
modifiers += "Shift-"; modifiers += "Shift-";
} }
key = modifiers + key; key = modifiers + key;
const range = this.getSelection();
if (this._keyHandlers[key]) { if (this._keyHandlers[key]) {
this._keyHandlers[key](this, event, range); this._keyHandlers[key](this, event, range);
} else if (!range.collapsed && // !event.isComposing stops us from blatting Kana-Kanji conversion in } else if (!range.collapsed && // !event.isComposing stops us from blatting Kana-Kanji conversion in
// Safari // Safari
!event.isComposing && !event.ctrlKey && !event.metaKey && (event.key || key).length === 1) { !event.isComposing && !event.ctrlKey && !event.metaKey && key.length === 1) {
this.saveUndoState(range); this.saveUndoState(range);
deleteContentsOfRange(range, this._root); deleteContentsOfRange(range, this._root);
this._ensureBottomLine(); this._ensureBottomLine();
@ -1968,7 +1945,7 @@
"Delete": Delete, "Delete": Delete,
"Tab": Tab, "Tab": Tab,
"Shift-Tab": ShiftTab, "Shift-Tab": ShiftTab,
"Space": Space, " ": Space,
"ArrowLeft"(self) { "ArrowLeft"(self) {
self._removeZWS(); self._removeZWS();
}, },
@ -2711,22 +2688,26 @@
* Leaves bookmark. * Leaves bookmark.
*/ */
_recordUndoState(range, replace) { _recordUndoState(range, replace) {
if (!this._isInUndoState || replace) { const isInUndoState = this._isInUndoState;
let undoIndex = this._undoIndex; if (!isInUndoState || replace) {
let undoIndex = this._undoIndex + 1;
const undoStack = this._undoStack; const undoStack = this._undoStack;
const undoConfig = this._config.undo; const undoConfig = this._config.undo;
const undoThreshold = undoConfig.documentSizeThreshold; const undoThreshold = undoConfig.documentSizeThreshold;
const undoLimit = undoConfig.undoLimit; const undoLimit = undoConfig.undoLimit;
if (!replace) {
undoIndex += 1;
}
if (undoIndex < this._undoStackLength) { if (undoIndex < this._undoStackLength) {
undoStack.length = this._undoStackLength = undoIndex; undoStack.length = this._undoStackLength = undoIndex;
} }
if (range) { if (range) {
this._saveRangeToBookmark(range); this._saveRangeToBookmark(range);
} }
if (isInUndoState) {
return this;
}
const html = this._getRawHTML(); const html = this._getRawHTML();
if (replace) {
undoIndex -= 1;
}
if (undoThreshold > -1 && html.length * 2 > undoThreshold) { if (undoThreshold > -1 && html.length * 2 > undoThreshold) {
if (undoLimit > -1 && undoIndex > undoLimit) { if (undoLimit > -1 && undoIndex > undoLimit) {
undoStack.splice(0, undoIndex - undoLimit); undoStack.splice(0, undoIndex - undoLimit);

61
dist/squire-raw.mjs vendored
View file

@ -447,13 +447,14 @@ var fixCursor = (node) => {
fixer = document.createTextNode(""); fixer = document.createTextNode("");
} }
} }
} else if (node instanceof Element && !node.querySelector("BR")) { } else if ((node instanceof Element || node instanceof DocumentFragment) && !node.querySelector("BR")) {
fixer = createElement("BR"); fixer = createElement("BR");
let parent = node; let parent = node;
let child; let child;
while ((child = parent.lastElementChild) && !isInline(child)) { while ((child = parent.lastElementChild) && !isInline(child)) {
parent = child; parent = child;
} }
node = parent;
} }
if (fixer) { if (fixer) {
try { try {
@ -1308,6 +1309,7 @@ var insertTreeFragmentIntoRange = (range, frag, root) => {
} }
if (blockContentsAfterSplit && block) { if (blockContentsAfterSplit && block) {
const tempRange = range.cloneRange(); const tempRange = range.cloneRange();
fixCursor(blockContentsAfterSplit);
mergeWithBlock(block, blockContentsAfterSplit, tempRange, root); mergeWithBlock(block, blockContentsAfterSplit, tempRange, root);
range.setEnd(tempRange.endContainer, tempRange.endOffset); range.setEnd(tempRange.endContainer, tempRange.endOffset);
} }
@ -1859,10 +1861,13 @@ var Space = (self, event, range) => {
const text = block.textContent?.trimEnd().replace(ZWS, ""); const text = block.textContent?.trimEnd().replace(ZWS, "");
if (text === "*" || text === "1.") { if (text === "*" || text === "1.") {
event.preventDefault(); event.preventDefault();
self.insertPlainText(" ", false);
self._docWasChanged();
self.saveUndoState(range);
const walker = new TreeIterator(block, SHOW_TEXT); const walker = new TreeIterator(block, SHOW_TEXT);
let textNode; let textNode;
while (textNode = walker.nextNode()) { while (textNode = walker.nextNode()) {
textNode.data = cantFocusEmptyTextNodes ? ZWS : ""; detach(textNode);
} }
if (text === "*") { if (text === "*") {
self.makeUnorderedList(); self.makeUnorderedList();
@ -1895,41 +1900,12 @@ var Space = (self, event, range) => {
}; };
// source/keyboard/KeyHandlers.ts // source/keyboard/KeyHandlers.ts
var keys = {
8: "Backspace",
9: "Tab",
13: "Enter",
27: "Escape",
32: "Space",
33: "PageUp",
34: "PageDown",
37: "ArrowLeft",
38: "ArrowUp",
39: "ArrowRight",
40: "ArrowDown",
46: "Delete",
191: "/",
219: "[",
220: "\\",
221: "]"
};
var _onKey = function(event) { var _onKey = function(event) {
const code = event.keyCode;
let key = keys[code];
let modifiers = "";
const range = this.getSelection();
if (event.defaultPrevented) { if (event.defaultPrevented) {
return; return;
} }
if (!key) { let key = event.key;
key = String.fromCharCode(code).toLowerCase(); let modifiers = "";
if (!/^[A-Za-z0-9]$/.test(key)) {
key = "";
}
}
if (111 < code && code < 124) {
key = "F" + (code - 111);
}
if (key !== "Backspace" && key !== "Delete") { if (key !== "Backspace" && key !== "Delete") {
if (event.altKey) { if (event.altKey) {
modifiers += "Alt-"; modifiers += "Alt-";
@ -1948,11 +1924,12 @@ var _onKey = function(event) {
modifiers += "Shift-"; modifiers += "Shift-";
} }
key = modifiers + key; key = modifiers + key;
const range = this.getSelection();
if (this._keyHandlers[key]) { if (this._keyHandlers[key]) {
this._keyHandlers[key](this, event, range); this._keyHandlers[key](this, event, range);
} else if (!range.collapsed && // !event.isComposing stops us from blatting Kana-Kanji conversion in } else if (!range.collapsed && // !event.isComposing stops us from blatting Kana-Kanji conversion in
// Safari // Safari
!event.isComposing && !event.ctrlKey && !event.metaKey && (event.key || key).length === 1) { !event.isComposing && !event.ctrlKey && !event.metaKey && key.length === 1) {
this.saveUndoState(range); this.saveUndoState(range);
deleteContentsOfRange(range, this._root); deleteContentsOfRange(range, this._root);
this._ensureBottomLine(); this._ensureBottomLine();
@ -1965,7 +1942,7 @@ var keyHandlers = {
"Delete": Delete, "Delete": Delete,
"Tab": Tab, "Tab": Tab,
"Shift-Tab": ShiftTab, "Shift-Tab": ShiftTab,
"Space": Space, " ": Space,
"ArrowLeft"(self) { "ArrowLeft"(self) {
self._removeZWS(); self._removeZWS();
}, },
@ -2708,22 +2685,26 @@ var Squire = class {
* Leaves bookmark. * Leaves bookmark.
*/ */
_recordUndoState(range, replace) { _recordUndoState(range, replace) {
if (!this._isInUndoState || replace) { const isInUndoState = this._isInUndoState;
let undoIndex = this._undoIndex; if (!isInUndoState || replace) {
let undoIndex = this._undoIndex + 1;
const undoStack = this._undoStack; const undoStack = this._undoStack;
const undoConfig = this._config.undo; const undoConfig = this._config.undo;
const undoThreshold = undoConfig.documentSizeThreshold; const undoThreshold = undoConfig.documentSizeThreshold;
const undoLimit = undoConfig.undoLimit; const undoLimit = undoConfig.undoLimit;
if (!replace) {
undoIndex += 1;
}
if (undoIndex < this._undoStackLength) { if (undoIndex < this._undoStackLength) {
undoStack.length = this._undoStackLength = undoIndex; undoStack.length = this._undoStackLength = undoIndex;
} }
if (range) { if (range) {
this._saveRangeToBookmark(range); this._saveRangeToBookmark(range);
} }
if (isInUndoState) {
return this;
}
const html = this._getRawHTML(); const html = this._getRawHTML();
if (replace) {
undoIndex -= 1;
}
if (undoThreshold > -1 && html.length * 2 > undoThreshold) { if (undoThreshold > -1 && html.length * 2 > undoThreshold) {
if (undoLimit > -1 && undoIndex > undoLimit) { if (undoLimit > -1 && undoIndex > undoLimit) {
undoStack.splice(0, undoIndex - undoLimit); undoStack.splice(0, undoIndex - undoLimit);

20
dist/squire.js vendored

File diff suppressed because one or more lines are too long

6
dist/squire.js.map vendored

File diff suppressed because one or more lines are too long

22
dist/squire.mjs vendored

File diff suppressed because one or more lines are too long

6
dist/squire.mjs.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"file":"KeyHandlers.d.ts","sourceRoot":"","sources":["../../../source/keyboard/KeyHandlers.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AA+BxC,QAAA,MAAM,MAAM,SAAmB,MAAM,SAAS,aAAa,KAAG,IAkE7D,CAAC;AAIF,KAAK,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAE7E,QAAA,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAoC3C,CAAC;AAyGF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC"} {"version":3,"file":"KeyHandlers.d.ts","sourceRoot":"","sources":["../../../source/keyboard/KeyHandlers.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAWxC,QAAA,MAAM,MAAM,SAAmB,MAAM,SAAS,aAAa,KAAG,IAkD7D,CAAC;AAIF,KAAK,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAE7E,QAAA,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAoC3C,CAAC;AAyGF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC"}

View file

@ -1 +1 @@
{"version":3,"file":"Space.d.ts","sourceRoot":"","sources":["../../../source/keyboard/Space.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAWxC,QAAA,MAAM,KAAK,SAAU,MAAM,SAAS,aAAa,SAAS,KAAK,KAAG,IA8DjE,CAAC;AAIF,OAAO,EAAE,KAAK,EAAE,CAAC"} {"version":3,"file":"Space.d.ts","sourceRoot":"","sources":["../../../source/keyboard/Space.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAWxC,QAAA,MAAM,KAAK,SAAU,MAAM,SAAS,aAAa,SAAS,KAAK,KAAG,IAiEjE,CAAC;AAIF,OAAO,EAAE,KAAK,EAAE,CAAC"}

View file

@ -1 +1 @@
{"version":3,"file":"MergeSplit.d.ts","sourceRoot":"","sources":["../../../source/node/MergeSplit.ts"],"names":[],"mappings":"AAaA,QAAA,MAAM,SAAS,SAAU,IAAI,KAAG,IAyC/B,CAAC;AAGF,QAAA,MAAM,YAAY,cACH,IAAI,QACT,OAAO,GAAG,gBAAgB,KACjC,IA6BF,CAAC;AAEF,QAAA,MAAM,KAAK,SACD,IAAI,UACF,MAAM,GAAG,IAAI,GAAG,IAAI,YAClB,IAAI,QACR,OAAO,GAAG,gBAAgB,KACjC,IAAI,GAAG,IAoDT,CAAC;AA0DF,QAAA,MAAM,YAAY,SAAU,IAAI,SAAS,KAAK,KAAG,IAahD,CAAC;AAEF,QAAA,MAAM,cAAc,UACT,IAAI,QACL,IAAI,SACH,KAAK,QACN,OAAO,KACd,IA4BF,CAAC;AAEF,QAAA,MAAM,eAAe,SAAU,IAAI,QAAQ,OAAO,KAAG,IAkCpD,CAAC;AAIF,OAAO,EACH,YAAY,EACZ,SAAS,EACT,eAAe,EACf,YAAY,EACZ,cAAc,EACd,KAAK,GACR,CAAC"} {"version":3,"file":"MergeSplit.d.ts","sourceRoot":"","sources":["../../../source/node/MergeSplit.ts"],"names":[],"mappings":"AAaA,QAAA,MAAM,SAAS,SAAU,IAAI,KAAG,IA6C/B,CAAC;AAGF,QAAA,MAAM,YAAY,cACH,IAAI,QACT,OAAO,GAAG,gBAAgB,KACjC,IA6BF,CAAC;AAEF,QAAA,MAAM,KAAK,SACD,IAAI,UACF,MAAM,GAAG,IAAI,GAAG,IAAI,YAClB,IAAI,QACR,OAAO,GAAG,gBAAgB,KACjC,IAAI,GAAG,IAoDT,CAAC;AA0DF,QAAA,MAAM,YAAY,SAAU,IAAI,SAAS,KAAK,KAAG,IAahD,CAAC;AAEF,QAAA,MAAM,cAAc,UACT,IAAI,QACL,IAAI,SACH,KAAK,QACN,OAAO,KACd,IA4BF,CAAC;AAEF,QAAA,MAAM,eAAe,SAAU,IAAI,QAAQ,OAAO,KAAG,IAkCpD,CAAC;AAIF,OAAO,EACH,YAAY,EACZ,SAAS,EACT,eAAe,EACf,YAAY,EACZ,cAAc,EACd,KAAK,GACR,CAAC"}

View file

@ -1 +1 @@
{"version":3,"file":"InsertDelete.d.ts","sourceRoot":"","sources":["../../../source/range/InsertDelete.ts"],"names":[],"mappings":"AAyBA,iBAAS,WAAW,CAAC,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC;AACvE,iBAAS,WAAW,CAChB,cAAc,EAAE,IAAI,EACpB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,IAAI,EAClB,SAAS,EAAE,MAAM,GAClB,KAAK,CAAC;AAiBT,QAAA,MAAM,iBAAiB,UAAW,KAAK,QAAQ,IAAI,KAAG,IAiDrD,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,sBAAsB,UACjB,KAAK,UACJ,IAAI,GAAG,IAAI,QACb,OAAO,KACd,gBA6CF,CAAC;AAuBF,QAAA,MAAM,qBAAqB,UAChB,KAAK,QACN,OAAO,KACd,gBA8GF,CAAC;AAIF,QAAA,MAAM,2BAA2B,UACtB,KAAK,QACN,gBAAgB,QAChB,OAAO,KACd,IAqIF,CAAC;AAIF,OAAO,EACH,WAAW,EACX,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,GAC9B,CAAC"} {"version":3,"file":"InsertDelete.d.ts","sourceRoot":"","sources":["../../../source/range/InsertDelete.ts"],"names":[],"mappings":"AAyBA,iBAAS,WAAW,CAAC,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC;AACvE,iBAAS,WAAW,CAChB,cAAc,EAAE,IAAI,EACpB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,IAAI,EAClB,SAAS,EAAE,MAAM,GAClB,KAAK,CAAC;AAiBT,QAAA,MAAM,iBAAiB,UAAW,KAAK,QAAQ,IAAI,KAAG,IAiDrD,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,sBAAsB,UACjB,KAAK,UACJ,IAAI,GAAG,IAAI,QACb,OAAO,KACd,gBA6CF,CAAC;AAuBF,QAAA,MAAM,qBAAqB,UAChB,KAAK,QACN,OAAO,KACd,gBA8GF,CAAC;AAIF,QAAA,MAAM,2BAA2B,UACtB,KAAK,QACN,gBAAgB,QAChB,OAAO,KACd,IAsIF,CAAC;AAIF,OAAO,EACH,WAAW,EACX,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,GAC9B,CAAC"}

View file

@ -1,6 +1,6 @@
{ {
"name": "squire-rte", "name": "squire-rte",
"version": "2.2.5", "version": "2.2.6",
"description": "Squire is an HTML5 rich text editor, which provides powerful cross-browser normalisation, whilst being supremely lightweight and flexible.", "description": "Squire is an HTML5 rich text editor, which provides powerful cross-browser normalisation, whilst being supremely lightweight and flexible.",
"main": "dist/squire.mjs", "main": "dist/squire.mjs",
"types": "dist/types/Squire.d.ts", "types": "dist/types/Squire.d.ts",