Skip to content

Commit

Permalink
feat: 没有选中文字的时候点击工具栏会自动选中光标附近的文字或行
Browse files Browse the repository at this point in the history
Fixed: #261
  • Loading branch information
sunsonliu committed Jul 9, 2022
1 parent 43e4e90 commit 7fe3b70
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 75 deletions.
11 changes: 5 additions & 6 deletions src/toolbars/hooks/Bold.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 加粗按钮
*/
Expand All @@ -30,14 +31,12 @@ export default class Bold extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
const $selection = getSelection(this.editor.editor, selection) || '加粗';
// 如果选中的文本中已经有加粗语法了,则去掉加粗语法
if (/^\s*(\*\*|__)[\s\S]+(\1)/.test(selection)) {
return selection.replace(/(^)(\s*)(\*\*|__)([^\n]+)(\3)(\s*)($)/gm, '$1$4$7');
if (/^\s*(\*\*|__)[\s\S]+(\1)/.test($selection)) {
return $selection.replace(/(^)(\s*)(\*\*|__)([^\n]+)(\3)(\s*)($)/gm, '$1$4$7');
}
let $selection = selection ? selection : '加粗';
// 反之加上加粗语法
$selection = $selection.replace(/(^)([^\n]+)($)/gm, '$1**$2**$3');
return $selection;
return $selection.replace(/(^)([^\n]+)($)/gm, '$1**$2**$3');
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/toolbars/hooks/Color.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 插入字体颜色或者字体背景颜色的按钮
*/
Expand All @@ -33,10 +34,10 @@ export default class Color extends MenuBase {
* @returns 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '', event) {
const text = selection ? selection : '字体颜色或背景';
const $selection = getSelection(this.editor.editor, selection) || '字体颜色或背景';
if (event) {
// 暂存选中的文本内容
this.bubbleColor.setSelection(text);
this.bubbleColor.setSelection($selection);

// 定位调色盘应该出现的位置
// 该按钮可能出现在顶部工具栏,
Expand Down
19 changes: 13 additions & 6 deletions src/toolbars/hooks/H1.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 插入1级标题
*/
Expand All @@ -30,12 +31,18 @@ export default class H1 extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
// TODO: 1、改成获取整行内容进行判断; 2、根据#号个数判断是增加#号还是删除#号还是编辑#号
if (/^\s*(#+)\s*[\s\S]+/.test(selection)) {
return selection.replace(/(^\s*)(#+)(\s*)([\s\S]+$)/gm, '$1$4');
const $selection = getSelection(this.editor.editor, selection, 'line', true) || '标题';
// 如果有选中的内容,则根据选中的内容进行判断
if (/^\s*(#+)\s*.+/.test($selection)) {
// 如果选中的内容里有标题语法,并且标记级别与目标一致,则去掉标题语法
// 反之,修改标题级别与目标一致
let needClean = true;
const tmp = $selection.replace(/(^\s*)(#+)(\s*)(.+$)/gm, (w, m1, m2, m3, m4) => {
needClean = needClean ? m2 === '#' : false;
return `${m1}#${m3}${m4}`;
});
return !needClean ? tmp : $selection.replace(/(^\s*)(#+)(\s*)(.+$)/gm, '$1$4');
}
let $selection = selection ? selection : '标题';
$selection = $selection.replace(/(^)([\s]*)([^\n]+)($)/gm, '$1# $3$4');
return $selection;
return $selection.replace(/(^)([\s]*)([^\n]+)($)/gm, '$1# $3$4');
}
}
19 changes: 13 additions & 6 deletions src/toolbars/hooks/H2.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 插入2级标题
*/
Expand All @@ -30,12 +31,18 @@ export default class H2 extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
// TODO: 1、改成获取整行内容进行判断; 2、根据#号个数判断是增加#号还是删除#号还是编辑#号
if (/^\s*(#+)\s*[\s\S]+/.test(selection)) {
return selection.replace(/(^\s*)(#+)(\s*)([\s\S]+$)/gm, '$1$4');
const $selection = getSelection(this.editor.editor, selection, 'line', true) || '标题';
// 如果有选中的内容,则根据选中的内容进行判断
if (/^\s*(#+)\s*.+/.test($selection)) {
// 如果选中的内容里有标题语法,并且标记级别与目标一致,则去掉标题语法
// 反之,修改标题级别与目标一致
let needClean = true;
const tmp = $selection.replace(/(^\s*)(#+)(\s*)(.+$)/gm, (w, m1, m2, m3, m4) => {
needClean = needClean ? m2 === '##' : false;
return `${m1}##${m3}${m4}`;
});
return !needClean ? tmp : $selection.replace(/(^\s*)(#+)(\s*)(.+$)/gm, '$1$4');
}
let $selection = selection ? selection : '标题';
$selection = $selection.replace(/(^)([\s]*)([^\n]+)($)/gm, '$1## $3$4');
return $selection;
return $selection.replace(/(^)([\s]*)([^\n]+)($)/gm, '$1## $3$4');
}
}
19 changes: 13 additions & 6 deletions src/toolbars/hooks/H3.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 插入3级标题
*/
Expand All @@ -30,12 +31,18 @@ export default class H3 extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
// TODO: 1、改成获取整行内容进行判断; 2、根据#号个数判断是增加#号还是删除#号还是编辑#号
if (/^\s*(#+)\s*[\s\S]+/.test(selection)) {
return selection.replace(/(^\s*)(#+)(\s*)([\s\S]+$)/gm, '$1$4');
const $selection = getSelection(this.editor.editor, selection, 'line', true) || '标题';
// 如果有选中的内容,则根据选中的内容进行判断
if (/^\s*(#+)\s*.+/.test($selection)) {
// 如果选中的内容里有标题语法,并且标记级别与目标一致,则去掉标题语法
// 反之,修改标题级别与目标一致
let needClean = true;
const tmp = $selection.replace(/(^\s*)(#+)(\s*)(.+$)/gm, (w, m1, m2, m3, m4) => {
needClean = needClean ? m2 === '###' : false;
return `${m1}###${m3}${m4}`;
});
return !needClean ? tmp : $selection.replace(/(^\s*)(#+)(\s*)(.+$)/gm, '$1$4');
}
let $selection = selection ? selection : '标题';
$selection = $selection.replace(/(^)([\s]*)([^\n]+)($)/gm, '$1### $3$4');
return $selection;
return $selection.replace(/(^)([\s]*)([^\n]+)($)/gm, '$1### $3$4');
}
}
28 changes: 14 additions & 14 deletions src/toolbars/hooks/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 插入1级~5级标题
*/
Expand Down Expand Up @@ -41,11 +42,7 @@ export default class Header extends MenuBase {
*/
$getFlagStr(shortKey) {
const test = +(typeof shortKey === 'string' ? shortKey.replace(/[^0-9]+([0-9])/g, '$1') : shortKey);
let header = '#';
for (let i = 1; i < test; i++) {
header += '#';
}
return header;
return '#'.repeat(test ? test : 1);
}

/**
Expand All @@ -55,16 +52,19 @@ export default class Header extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
// TODO: 1、改成获取整行内容进行判断; 2、根据#号个数判断是增加#号还是删除#号还是编辑#号
// 如果选中的内容里有标题语法,则直接去掉该语法
if (/^\s*(#+)\s*[\s\S]+/.test(selection)) {
return selection.replace(/(^\s*)(#+)(\s*)([\s\S]+$)/gm, '$1$4');
}
const $selection = getSelection(this.editor.editor, selection, 'line', true) || '标题';
const header = this.$getFlagStr(shortKey);
let $selection = selection ? selection : '标题';
// 如果选中的内容里不包含标题语法,则添加标题语法
$selection = $selection.replace(/(^)([\s]*)([^\n]+)($)/gm, `$1${header} $3$4`);
return $selection;
if (/^\s*(#+)\s*.+/.test($selection)) {
// 如果选中的内容里有标题语法,并且标记级别与目标一致,则去掉标题语法
// 反之,修改标题级别与目标一致
let needClean = true;
const tmp = $selection.replace(/(^\s*)(#+)(\s*)(.+$)/gm, (w, m1, m2, m3, m4) => {
needClean = needClean ? m2.length === header.length : false;
return `${m1}${header}${m3}${m4}`;
});
return !needClean ? tmp : $selection.replace(/(^\s*)(#+)(\s*)(.+$)/gm, '$1$4');
}
return $selection.replace(/(^)([\s]*)([^\n]+)($)/gm, `$1${header} $3$4`);
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/toolbars/hooks/Italic.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 插入斜体的按钮
*/
Expand All @@ -30,12 +31,11 @@ export default class Italic extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
if (/^\s*(\*|_)[\s\S]+(\1)/.test(selection)) {
return selection.replace(/(^)(\s*)(\*|_)([^\n]+)(\3)(\s*)($)/gm, '$1$4$7');
const $selection = getSelection(this.editor.editor, selection) || '斜体';
if (/^\s*(\*|_)[\s\S]+(\1)/.test($selection)) {
return $selection.replace(/(^)(\s*)(\*|_)([^\n]+)(\3)(\s*)($)/gm, '$1$4$7');
}
let $selection = selection ? selection : '斜体';
$selection = $selection.replace(/(^)([^\n]+)($)/gm, '$1 *$2* $3');
return $selection;
return $selection.replace(/(^)([^\n]+)($)/gm, '$1 *$2* $3');
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/toolbars/hooks/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 插入有序/无序/checklist列表的按钮
*/
Expand Down Expand Up @@ -76,11 +77,11 @@ export default class List extends MenuBase {
*/
onClick(selection, shortKey = '') {
const listType = [null, 'ol', 'ul', 'checklist']; // 下标1, 2, 3生效
let $selection = selection;
const $selection = getSelection(this.editor.editor, selection, 'line', true);
const [before] = $selection.match(/^\n*/);
const [after] = $selection.match(/\n*$/);
if (listType[shortKey] !== null) {
$selection = `${before}${this.$dealSelection($selection, listType[shortKey])}${after}`;
return `${before}${this.$dealSelection($selection, listType[shortKey])}${after}`;
}
return $selection;
}
Expand Down
12 changes: 6 additions & 6 deletions src/toolbars/hooks/Quote.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 插入“引用”的按钮
*/
Expand All @@ -29,14 +30,13 @@ export default class Quote extends MenuBase {
* @returns
*/
onClick(selection) {
let $selection = selection ? selection : '引用';
const $selection = getSelection(this.editor.editor, selection, 'line', true) || '引用';
const isWrapped = $selection.split('\n').every((text) => /^\s*>[^\n]+$/.exec(text));
// decrease level when all lines in selection are quote
if (isWrapped) {
$selection = $selection.replace(/(^\s*)>\s*([^\n]+)($)/gm, '$1$2$3').replace(/\n+$/, '\n\n');
} else {
$selection = $selection.replace(/(^)([^\n]+)($)/gm, '$1> $2$3').replace(/\n+$/, '\n\n');
// 去掉>号
return $selection.replace(/(^\s*)>\s*([^\n]+)($)/gm, '$1$2$3').replace(/\n+$/, '\n\n');
}
return $selection;
// 给每一行增加>号
return $selection.replace(/(^)([^\n]+)($)/gm, '$1> $2$3').replace(/\n+$/, '\n\n');
}
}
22 changes: 14 additions & 8 deletions src/toolbars/hooks/Size.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';

export default class Size extends MenuBase {
constructor(editor) {
Expand Down Expand Up @@ -41,13 +42,18 @@ export default class Size extends MenuBase {
}

onClick(selection, shortKey = '17') {
// if(/^\s*(![0-9]+)[\s\S]+(!)/.test(selection)) {
// selection = selection.replace(/(^)(\s*)(![0-9]+)([^\n]+)(!)(\s*)($)/gm, '$1$4$7');
// return selection;
// }else {
let $selection = selection ? selection : '字号';
$selection = $selection.replace(/(^)([^\n]+)($)/gm, `$1 !${shortKey} $2! $3`);
return $selection;
// }
const $selection = getSelection(this.editor.editor, selection) || '字号';
// 如果选中的内容里有字号语法,则直接去掉该语法
if (/^\s*(![0-9]+)[\s\S]+(!)/.test(selection)) {
// 如果选中的内容里有字号语法,并且字号与目标一致,则去掉字号语法
// 反之,修改字号与目标一致
let needClean = true;
const tmp = $selection.replace(/(^)(\s*)(![0-9]+)([^\n]+)(!)(\s*)($)/gm, (w, m1, m2, m3, m4, m5, m6, m7) => {
needClean = needClean ? m3 === `!${shortKey}` : false;
return `${m1}${m2}!${shortKey}${m4}${m5}${m6}${m7}`;
});
return !needClean ? tmp : $selection.replace(/(^)(\s*)(![0-9]+\s*)([^\n]+)(!)(\s*)($)/gm, '$1$4$7');
}
return $selection.replace(/(^)([^\n]+)($)/gm, `$1 !${shortKey} $2! $3`);
}
}
7 changes: 3 additions & 4 deletions src/toolbars/hooks/Strikethrough.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 删除线的按钮
*/
Expand All @@ -30,13 +31,11 @@ export default class Strikethrough extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
const $selection = getSelection(this.editor.editor, selection) || '删除线';
// 如果被选中的文本中包含删除线语法,则去掉删除线语法
if (/(~~)[\s\S]+(\1)/.test(selection)) {
return selection.replace(/[\s]*(~~)([\s\S]+)(\1)[\s]*/g, '$2');
}
let $selection = selection ? selection : '删除线';
// 反之加上删除线语法
$selection = $selection.replace(/(^)[\s]*([\s\S]+)[\s]*($)/g, '$1 ~~$2~~ $3');
return $selection;
return $selection.replace(/(^)[\s]*([\s\S]+)[\s]*($)/g, '$1 ~~$2~~ $3');
}
}
11 changes: 5 additions & 6 deletions src/toolbars/hooks/Sub.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 下标的按钮
**/
Expand All @@ -30,13 +31,11 @@ export default class Sub extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
const $selection = getSelection(this.editor.editor, selection) || '下标';
// 如果选中的内容里有下标的语法,则认为是要去掉下标语法
if (/^\s*(\^\^)[\s\S]+(\1)/.test(selection)) {
return selection.replace(/(^)(\s*)(\^\^)([^\n]+)(\3)(\s*)($)/gm, '$1$4$7');
if (/^\s*(\^\^)[\s\S]+(\1)/.test($selection)) {
return $selection.replace(/(^)(\s*)(\^\^)([^\n]+)(\3)(\s*)($)/gm, '$1$4$7');
}
let $selection = selection ? selection : '下标';
// 反之加上下标语法
$selection = $selection.replace(/(^)([^\n]+)($)/gm, '$1 ^^$2^^ $3');
return $selection;
return $selection.replace(/(^)([^\n]+)($)/gm, '$1 ^^$2^^ $3');
}
}
7 changes: 3 additions & 4 deletions src/toolbars/hooks/Sup.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import MenuBase from '@/toolbars/MenuBase';
import { getSelection } from '@/utils/selection';
/**
* 上标的按钮
**/
Expand All @@ -30,13 +31,11 @@ export default class Sup extends MenuBase {
* @returns {string} 回填到编辑器光标位置/选中文本区域的内容
*/
onClick(selection, shortKey = '') {
const $selection = getSelection(this.editor.editor, selection) || '上标';
// 如果选中的内容里有上标的语法,则认为是要去掉上标语法
if (/^\s*(\^)[\s\S]+(\1)/.test(selection)) {
return selection.replace(/(^)(\s*)(\^)([^\n]+)(\3)(\s*)($)/gm, '$1$4$7');
}
let $selection = selection ? selection : '上标';
// 反之加上上标语法
$selection = $selection.replace(/(^)([^\n]+)($)/gm, '$1 ^$2^ $3');
return $selection;
return $selection.replace(/(^)([^\n]+)($)/gm, '$1 ^$2^ $3');
}
}
Loading

0 comments on commit 7fe3b70

Please sign in to comment.