mirror of
https://github.com/fastmail/Squire.git
synced 2024-12-22 07:13:08 -05:00
Release v2.1.0
This commit is contained in:
parent
edde44a924
commit
befb652039
11 changed files with 4674 additions and 4410 deletions
|
@ -4,6 +4,15 @@ 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).
|
||||
|
||||
## [2.1.0] - 2023-09-19
|
||||
|
||||
### Added
|
||||
|
||||
- If you start a new line with "\*" then a space, Squire will now automatically
|
||||
set the format to an unordered list.
|
||||
- If you start a new line with "1." then a space, Squire will now automatically
|
||||
set the format to an ordered list.
|
||||
|
||||
## [2.0.3] - 2023-04-20
|
||||
|
||||
### Fixed
|
||||
|
|
23
dist/squire-raw.js
vendored
23
dist/squire-raw.js
vendored
|
@ -1816,16 +1816,37 @@
|
|||
};
|
||||
|
||||
// source/keyboard/Space.ts
|
||||
var Space = (self, _, range) => {
|
||||
var Space = (self, event, range) => {
|
||||
var _a;
|
||||
let node;
|
||||
const root = self._root;
|
||||
self._recordUndoState(range);
|
||||
self._getRangeAndRemoveBookmark(range);
|
||||
self._removeZWS();
|
||||
if (!range.collapsed) {
|
||||
deleteContentsOfRange(range, root);
|
||||
self._ensureBottomLine();
|
||||
self.setSelection(range);
|
||||
self._updatePath(range, true);
|
||||
} else if (rangeDoesEndAtBlockBoundary(range, root)) {
|
||||
const block = getStartBlockOfRange(range, root);
|
||||
if (block && block.nodeName !== "PRE") {
|
||||
const text = (_a = block.textContent) == null ? void 0 : _a.trimEnd();
|
||||
if (text === "*" || text === "1.") {
|
||||
event.preventDefault();
|
||||
const walker = new TreeIterator(block, SHOW_TEXT);
|
||||
let textNode;
|
||||
while (textNode = walker.nextNode()) {
|
||||
textNode.data = cantFocusEmptyTextNodes ? ZWS : "";
|
||||
}
|
||||
if (text === "*") {
|
||||
self.makeUnorderedList();
|
||||
} else {
|
||||
self.makeOrderedList();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
node = range.endContainer;
|
||||
if (range.endOffset === getLength(node)) {
|
||||
|
|
191
dist/squire-raw.mjs
vendored
191
dist/squire-raw.mjs
vendored
|
@ -4,10 +4,6 @@ var SHOW_TEXT = 4;
|
|||
var SHOW_ELEMENT_OR_TEXT = 5;
|
||||
var always = () => true;
|
||||
var TreeIterator = class {
|
||||
root;
|
||||
currentNode;
|
||||
nodeType;
|
||||
filter;
|
||||
constructor(root, nodeType, filter) {
|
||||
this.root = root;
|
||||
this.currentNode = root;
|
||||
|
@ -1818,16 +1814,36 @@ var ShiftTab = (self, event, range) => {
|
|||
};
|
||||
|
||||
// source/keyboard/Space.ts
|
||||
var Space = (self, _, range) => {
|
||||
var Space = (self, event, range) => {
|
||||
let node;
|
||||
const root = self._root;
|
||||
self._recordUndoState(range);
|
||||
self._getRangeAndRemoveBookmark(range);
|
||||
self._removeZWS();
|
||||
if (!range.collapsed) {
|
||||
deleteContentsOfRange(range, root);
|
||||
self._ensureBottomLine();
|
||||
self.setSelection(range);
|
||||
self._updatePath(range, true);
|
||||
} else if (rangeDoesEndAtBlockBoundary(range, root)) {
|
||||
const block = getStartBlockOfRange(range, root);
|
||||
if (block && block.nodeName !== "PRE") {
|
||||
const text = block.textContent?.trimEnd();
|
||||
if (text === "*" || text === "1.") {
|
||||
event.preventDefault();
|
||||
const walker = new TreeIterator(block, SHOW_TEXT);
|
||||
let textNode;
|
||||
while (textNode = walker.nextNode()) {
|
||||
textNode.data = cantFocusEmptyTextNodes ? ZWS : "";
|
||||
}
|
||||
if (text === "*") {
|
||||
self.makeUnorderedList();
|
||||
} else {
|
||||
self.makeOrderedList();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
node = range.endContainer;
|
||||
if (range.endOffset === getLength(node)) {
|
||||
|
@ -2029,26 +2045,80 @@ keyHandlers[ctrlKey + "y"] = keyHandlers[ctrlKey + "Shift-z"] = (self, event) =>
|
|||
|
||||
// source/Editor.ts
|
||||
var Squire = class {
|
||||
_root;
|
||||
_config;
|
||||
_isFocused;
|
||||
_lastSelection;
|
||||
_willRestoreSelection;
|
||||
_mayHaveZWS;
|
||||
_lastAnchorNode;
|
||||
_lastFocusNode;
|
||||
_path;
|
||||
_events;
|
||||
_undoIndex;
|
||||
_undoStack;
|
||||
_undoStackLength;
|
||||
_isInUndoState;
|
||||
_ignoreChange;
|
||||
_ignoreAllChanges;
|
||||
_isShiftDown;
|
||||
_keyHandlers;
|
||||
_mutation;
|
||||
constructor(root, config) {
|
||||
/**
|
||||
* Subscribing to these events won't automatically add a listener to the
|
||||
* document node, since these events are fired in a custom manner by the
|
||||
* editor code.
|
||||
*/
|
||||
this.customEvents = /* @__PURE__ */ new Set([
|
||||
"pathChange",
|
||||
"select",
|
||||
"input",
|
||||
"pasteImage",
|
||||
"undoStateChange"
|
||||
]);
|
||||
// ---
|
||||
this.startSelectionId = "squire-selection-start";
|
||||
this.endSelectionId = "squire-selection-end";
|
||||
/*
|
||||
linkRegExp = new RegExp(
|
||||
// Only look on boundaries
|
||||
'\\b(?:' +
|
||||
// Capture group 1: URLs
|
||||
'(' +
|
||||
// Add links to URLS
|
||||
// Starts with:
|
||||
'(?:' +
|
||||
// http(s):// or ftp://
|
||||
'(?:ht|f)tps?:\\/\\/' +
|
||||
// or
|
||||
'|' +
|
||||
// www.
|
||||
'www\\d{0,3}[.]' +
|
||||
// or
|
||||
'|' +
|
||||
// foo90.com/
|
||||
'[a-z0-9][a-z0-9.\\-]*[.][a-z]{2,}\\/' +
|
||||
')' +
|
||||
// Then we get one or more:
|
||||
'(?:' +
|
||||
// Run of non-spaces, non ()<>
|
||||
'[^\\s()<>]+' +
|
||||
// or
|
||||
'|' +
|
||||
// balanced parentheses (one level deep only)
|
||||
'\\([^\\s()<>]+\\)' +
|
||||
')+' +
|
||||
// And we finish with
|
||||
'(?:' +
|
||||
// Not a space or punctuation character
|
||||
'[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]' +
|
||||
// or
|
||||
'|' +
|
||||
// Balanced parentheses.
|
||||
'\\([^\\s()<>]+\\)' +
|
||||
')' +
|
||||
// Capture group 2: Emails
|
||||
')|(' +
|
||||
// Add links to emails
|
||||
'[\\w\\-.%+]+@(?:[\\w\\-]+\\.)+[a-z]{2,}\\b' +
|
||||
// Allow query parameters in the mailto: style
|
||||
'(?:' +
|
||||
'[?][^&?\\s]+=[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]+' +
|
||||
'(?:&[^&?\\s]+=[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]+)*' +
|
||||
')?' +
|
||||
'))',
|
||||
'i'
|
||||
);
|
||||
*/
|
||||
this.linkRegExp = /\b(?:((?:(?:ht|f)tps?:\/\/|www\d{0,3}[.]|[a-z0-9][a-z0-9.\-]*[.][a-z]{2,}\/)(?:[^\s()<>]+|\([^\s()<>]+\))+(?:[^\s?&`!()\[\]{};:'".,<>«»“”‘’]|\([^\s()<>]+\)))|([\w\-.%+]+@(?:[\w\-]+\.)+[a-z]{2,}\b(?:[?][^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+(?:&[^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+)*)?))/i;
|
||||
this.tagAfterSplit = {
|
||||
DT: "DD",
|
||||
DD: "DT",
|
||||
LI: "LI",
|
||||
PRE: "PRE"
|
||||
};
|
||||
this._root = root;
|
||||
this._config = this._makeConfig(config);
|
||||
this._isFocused = false;
|
||||
|
@ -2285,18 +2355,6 @@ var Squire = class {
|
|||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Subscribing to these events won't automatically add a listener to the
|
||||
* document node, since these events are fired in a custom manner by the
|
||||
* editor code.
|
||||
*/
|
||||
customEvents = /* @__PURE__ */ new Set([
|
||||
"pathChange",
|
||||
"select",
|
||||
"input",
|
||||
"pasteImage",
|
||||
"undoStateChange"
|
||||
]);
|
||||
addEventListener(type, fn) {
|
||||
let handlers = this._events.get(type);
|
||||
let target = this._root;
|
||||
|
@ -2368,9 +2426,6 @@ var Squire = class {
|
|||
removeZWS(this._root);
|
||||
this._mayHaveZWS = false;
|
||||
}
|
||||
// ---
|
||||
startSelectionId = "squire-selection-start";
|
||||
endSelectionId = "squire-selection-end";
|
||||
_saveRangeToBookmark(range) {
|
||||
let startNode = createElement("INPUT", {
|
||||
id: this.startSelectionId,
|
||||
|
@ -3311,58 +3366,6 @@ var Squire = class {
|
|||
true
|
||||
);
|
||||
}
|
||||
/*
|
||||
linkRegExp = new RegExp(
|
||||
// Only look on boundaries
|
||||
'\\b(?:' +
|
||||
// Capture group 1: URLs
|
||||
'(' +
|
||||
// Add links to URLS
|
||||
// Starts with:
|
||||
'(?:' +
|
||||
// http(s):// or ftp://
|
||||
'(?:ht|f)tps?:\\/\\/' +
|
||||
// or
|
||||
'|' +
|
||||
// www.
|
||||
'www\\d{0,3}[.]' +
|
||||
// or
|
||||
'|' +
|
||||
// foo90.com/
|
||||
'[a-z0-9][a-z0-9.\\-]*[.][a-z]{2,}\\/' +
|
||||
')' +
|
||||
// Then we get one or more:
|
||||
'(?:' +
|
||||
// Run of non-spaces, non ()<>
|
||||
'[^\\s()<>]+' +
|
||||
// or
|
||||
'|' +
|
||||
// balanced parentheses (one level deep only)
|
||||
'\\([^\\s()<>]+\\)' +
|
||||
')+' +
|
||||
// And we finish with
|
||||
'(?:' +
|
||||
// Not a space or punctuation character
|
||||
'[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]' +
|
||||
// or
|
||||
'|' +
|
||||
// Balanced parentheses.
|
||||
'\\([^\\s()<>]+\\)' +
|
||||
')' +
|
||||
// Capture group 2: Emails
|
||||
')|(' +
|
||||
// Add links to emails
|
||||
'[\\w\\-.%+]+@(?:[\\w\\-]+\\.)+[a-z]{2,}\\b' +
|
||||
// Allow query parameters in the mailto: style
|
||||
'(?:' +
|
||||
'[?][^&?\\s]+=[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]+' +
|
||||
'(?:&[^&?\\s]+=[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]+)*' +
|
||||
')?' +
|
||||
'))',
|
||||
'i'
|
||||
);
|
||||
*/
|
||||
linkRegExp = /\b(?:((?:(?:ht|f)tps?:\/\/|www\d{0,3}[.]|[a-z0-9][a-z0-9.\-]*[.][a-z]{2,}\/)(?:[^\s()<>]+|\([^\s()<>]+\))+(?:[^\s?&`!()\[\]{};:'".,<>«»“”‘’]|\([^\s()<>]+\)))|([\w\-.%+]+@(?:[\w\-]+\.)+[a-z]{2,}\b(?:[?][^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+(?:&[^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+)*)?))/i;
|
||||
addDetectedLinks(searchInNode, root) {
|
||||
const walker = new TreeIterator(
|
||||
searchInNode,
|
||||
|
@ -3480,12 +3483,6 @@ var Squire = class {
|
|||
createElement(config.blockTag, config.blockAttributes, children)
|
||||
);
|
||||
}
|
||||
tagAfterSplit = {
|
||||
DT: "DD",
|
||||
DD: "DT",
|
||||
LI: "LI",
|
||||
PRE: "PRE"
|
||||
};
|
||||
splitBlock(lineBreakOnly, range) {
|
||||
if (!range) {
|
||||
range = this.getSelection();
|
||||
|
|
22
dist/squire.js
vendored
22
dist/squire.js
vendored
File diff suppressed because one or more lines are too long
6
dist/squire.js.map
vendored
6
dist/squire.js.map
vendored
File diff suppressed because one or more lines are too long
22
dist/squire.mjs
vendored
22
dist/squire.mjs
vendored
File diff suppressed because one or more lines are too long
6
dist/squire.mjs.map
vendored
6
dist/squire.mjs.map
vendored
File diff suppressed because one or more lines are too long
2
dist/types/keyboard/Space.d.ts
vendored
2
dist/types/keyboard/Space.d.ts
vendored
|
@ -1,4 +1,4 @@
|
|||
import type { Squire } from '../Editor';
|
||||
declare const Space: (self: Squire, _: KeyboardEvent, range: Range) => void;
|
||||
declare const Space: (self: Squire, event: KeyboardEvent, range: Range) => void;
|
||||
export { Space };
|
||||
//# sourceMappingURL=Space.d.ts.map
|
2
dist/types/keyboard/Space.d.ts.map
vendored
2
dist/types/keyboard/Space.d.ts.map
vendored
|
@ -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;AAKxC,QAAA,MAAM,KAAK,SAAU,MAAM,KAAK,aAAa,SAAS,KAAK,KAAG,IA2C7D,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,IA+DjE,CAAC;AAIF,OAAO,EAAE,KAAK,EAAE,CAAC"}
|
8783
package-lock.json
generated
8783
package-lock.json
generated
File diff suppressed because it is too large
Load diff
18
package.json
18
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "squire-rte",
|
||||
"version": "2.0.3",
|
||||
"version": "2.1.0",
|
||||
"description": "Squire is an HTML5 rich text editor, which provides powerful cross-browser normalisation, whilst being supremely lightweight and flexible.",
|
||||
"main": "dist/squire.mjs",
|
||||
"types": "dist/types/Squire.d.ts",
|
||||
|
@ -32,17 +32,17 @@
|
|||
"@babel/core": "^7.20.12",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@types/jest": "^28.1.6",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.1",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
||||
"babel-jest": "^29.3.1",
|
||||
"esbuild": "^0.16.17",
|
||||
"esbuild": "^0.19.3",
|
||||
"eslint": "^8.31.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"jest": "^28.1.3",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.3.1",
|
||||
"prettier": "^2.8.2",
|
||||
"prettier": "^3.0.3",
|
||||
"tslib": "^2.0.1",
|
||||
"typescript": "^4.7.4"
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue