mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-07 16:22:42 +00:00
Merge branch 'master' into metadata-document-block
# Conflicts: # package-lock.json
This commit is contained in:
33
changelog.md
33
changelog.md
@@ -3,11 +3,12 @@ h5 {
|
|||||||
font-size: .35cm !important;
|
font-size: .35cm !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.taskList li {
|
.page ul ul {
|
||||||
list-style-type : none;
|
margin-left: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.taskList li input {
|
.taskList li input {
|
||||||
|
list-style-type : none;
|
||||||
margin-left : -0.52cm;
|
margin-left : -0.52cm;
|
||||||
transform: translateY(.05cm);
|
transform: translateY(.05cm);
|
||||||
filter: brightness(1.1) drop-shadow(1px 2px 1px #222);
|
filter: brightness(1.1) drop-shadow(1px 2px 1px #222);
|
||||||
@@ -33,6 +34,34 @@ pre {
|
|||||||
## changelog
|
## changelog
|
||||||
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
|
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
|
||||||
|
|
||||||
|
### Tuesday 07/12/2021 - v3.0.5
|
||||||
|
{{taskList
|
||||||
|
* [x] Fixed paragraph spacing for **note** and **descriptive** boxes in V3.
|
||||||
|
|
||||||
|
Fixes issues: [#1836](https://github.com/naturalcrit/homebrewery/issues/1836)
|
||||||
|
|
||||||
|
* [x] Added a whole bunch of hotkeys:
|
||||||
|
|
||||||
|
* Page Break `CTRL + ENTER`
|
||||||
|
* Column Break `CTRL + SHIFT + ENTER`
|
||||||
|
* Bulleted Lists `CTRL + L`
|
||||||
|
* Numbered Lists `CTRL + SHIFT + L`
|
||||||
|
* Headers `CTRL + SHIFT + (1-6)`
|
||||||
|
* Underline `CTRL + U`
|
||||||
|
* Link `CTRL + K`
|
||||||
|
* Non-breaking space (\ ) `CTRL + .`
|
||||||
|
* Add Horizontal Space `CTRL + SHIFT + .`
|
||||||
|
* Remove Horizontal Space `CTRL + SHIFT + ,`
|
||||||
|
* Curly Span `CTRL + M`
|
||||||
|
* Curly Div `CTRL + SHIFT + M`
|
||||||
|
|
||||||
|
* [x] Fixed page numbers in the editor panel getting scrambled when scrolling up and down.
|
||||||
|
|
||||||
|
* [x] Faster swapping between tabs on long brews.
|
||||||
|
|
||||||
|
* [x] Better error messages for common issue with Google Drive credentials expiring.
|
||||||
|
}}
|
||||||
|
|
||||||
### Wednesday 17/11/2021 - v3.0.4
|
### Wednesday 17/11/2021 - v3.0.4
|
||||||
{{taskList
|
{{taskList
|
||||||
* [x] Fixed incorrect sorting of Google brews by page count and views on the user page.
|
* [x] Fixed incorrect sorting of Google brews by page count and views on the user page.
|
||||||
|
|||||||
@@ -107,67 +107,69 @@ const Editor = createClass({
|
|||||||
if(this.state.view === 'text') {
|
if(this.state.view === 'text') {
|
||||||
const codeMirror = this.refs.codeEditor.codeMirror;
|
const codeMirror = this.refs.codeEditor.codeMirror;
|
||||||
|
|
||||||
//reset custom text styles
|
codeMirror.operation(()=>{ // Batch CodeMirror styling
|
||||||
const customHighlights = codeMirror.getAllMarks().filter((mark)=>!mark.__isFold); //Don't undo code folding
|
//reset custom text styles
|
||||||
for (let i=0;i<customHighlights.length;i++) customHighlights[i].clear();
|
const customHighlights = codeMirror.getAllMarks().filter((mark)=>!mark.__isFold); //Don't undo code folding
|
||||||
|
for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear();
|
||||||
|
|
||||||
const lineNumbers = _.reduce(this.props.brew.text.split('\n'), (r, line, lineNumber)=>{
|
let editorPageCount = 2; // start page count from page 2
|
||||||
|
|
||||||
//reset custom line styles
|
_.forEach(this.props.brew.text.split('\n'), (line, lineNumber)=>{
|
||||||
codeMirror.removeLineClass(lineNumber, 'background');
|
|
||||||
codeMirror.removeLineClass(lineNumber, 'text');
|
|
||||||
|
|
||||||
// Legacy Codemirror styling
|
//reset custom line styles
|
||||||
if(this.props.renderer == 'legacy') {
|
codeMirror.removeLineClass(lineNumber, 'background');
|
||||||
if(line.includes('\\page')){
|
codeMirror.removeLineClass(lineNumber, 'text');
|
||||||
|
|
||||||
|
// Styling for \page breaks
|
||||||
|
if((this.props.renderer == 'legacy' && line.includes('\\page')) ||
|
||||||
|
(this.props.renderer == 'V3' && line.match(/^\\page$/))) {
|
||||||
|
|
||||||
|
// add back the original class 'background' but also add the new class '.pageline'
|
||||||
codeMirror.addLineClass(lineNumber, 'background', 'pageLine');
|
codeMirror.addLineClass(lineNumber, 'background', 'pageLine');
|
||||||
r.push(lineNumber);
|
const pageCountElement = Object.assign(document.createElement('span'), {
|
||||||
}
|
className : 'editor-page-count',
|
||||||
}
|
textContent : editorPageCount
|
||||||
|
});
|
||||||
|
codeMirror.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement);
|
||||||
|
|
||||||
// New Codemirror styling for V3 renderer
|
editorPageCount += 1;
|
||||||
if(this.props.renderer == 'V3') {
|
};
|
||||||
if(line.match(/^\\page$/)){
|
|
||||||
codeMirror.addLineClass(lineNumber, 'background', 'pageLine');
|
|
||||||
r.push(lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(line.match(/^\\column$/)){
|
// New Codemirror styling for V3 renderer
|
||||||
codeMirror.addLineClass(lineNumber, 'text', 'columnSplit');
|
if(this.props.renderer == 'V3') {
|
||||||
r.push(lineNumber);
|
if(line.match(/^\\column$/)){
|
||||||
}
|
codeMirror.addLineClass(lineNumber, 'text', 'columnSplit');
|
||||||
|
|
||||||
// Highlight inline spans {{content}}
|
|
||||||
if(line.includes('{{') && line.includes('}}')){
|
|
||||||
const regex = /{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])*\s*|}}/g;
|
|
||||||
let match;
|
|
||||||
let blockCount = 0;
|
|
||||||
while ((match = regex.exec(line)) != null) {
|
|
||||||
if(match[0].startsWith('{')) {
|
|
||||||
blockCount += 1;
|
|
||||||
} else {
|
|
||||||
blockCount -= 1;
|
|
||||||
}
|
|
||||||
if(blockCount < 0) {
|
|
||||||
blockCount = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
codeMirror.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: 'inline-block' });
|
|
||||||
}
|
}
|
||||||
} else if(line.trimLeft().startsWith('{{') || line.trimLeft().startsWith('}}')){
|
|
||||||
// Highlight block divs {{\n Content \n}}
|
|
||||||
let endCh = line.length+1;
|
|
||||||
|
|
||||||
const match = line.match(/^ *{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])* *$|^ *}}$/);
|
// Highlight inline spans {{content}}
|
||||||
if(match)
|
if(line.includes('{{') && line.includes('}}')){
|
||||||
endCh = match.index+match[0].length;
|
const regex = /{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])*\s*|}}/g;
|
||||||
codeMirror.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' });
|
let match;
|
||||||
|
let blockCount = 0;
|
||||||
|
while ((match = regex.exec(line)) != null) {
|
||||||
|
if(match[0].startsWith('{')) {
|
||||||
|
blockCount += 1;
|
||||||
|
} else {
|
||||||
|
blockCount -= 1;
|
||||||
|
}
|
||||||
|
if(blockCount < 0) {
|
||||||
|
blockCount = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
codeMirror.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: 'inline-block' });
|
||||||
|
}
|
||||||
|
} else if(line.trimLeft().startsWith('{{') || line.trimLeft().startsWith('}}')){
|
||||||
|
// Highlight block divs {{\n Content \n}}
|
||||||
|
let endCh = line.length+1;
|
||||||
|
|
||||||
|
const match = line.match(/^ *{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])* *$|^ *}}$/);
|
||||||
|
if(match)
|
||||||
|
endCh = match.index+match[0].length;
|
||||||
|
codeMirror.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
});
|
||||||
return r;
|
|
||||||
}, []);
|
|
||||||
return lineNumbers;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -5,17 +5,13 @@
|
|||||||
|
|
||||||
.codeEditor{
|
.codeEditor{
|
||||||
height : 100%;
|
height : 100%;
|
||||||
counter-reset : page;
|
|
||||||
counter-increment : page;
|
|
||||||
.pageLine{
|
.pageLine{
|
||||||
background : #33333328;
|
background : #33333328;
|
||||||
border-top : #339 solid 1px;
|
border-top : #339 solid 1px;
|
||||||
&:after{
|
}
|
||||||
content : counter(page);
|
.editor-page-count{
|
||||||
counter-increment : page;
|
color : grey;
|
||||||
float : right;
|
float : right;
|
||||||
color : gray;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.columnSplit{
|
.columnSplit{
|
||||||
font-style : italic;
|
font-style : italic;
|
||||||
|
|||||||
@@ -349,14 +349,14 @@ const EditPage = createClass({
|
|||||||
</Nav.item>;
|
</Nav.item>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.state.errors.status == '403' && this.state.errors.response.body.errors[0].reason == 'insufficientPermissions'){
|
if(this.state.errors.response.req.url.match(/^\/api\/.*Google.*$/m)){
|
||||||
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
|
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
|
||||||
Oops!
|
Oops!
|
||||||
<div className='errorContainer' onClick={this.clearErrors}>
|
<div className='errorContainer' onClick={this.clearErrors}>
|
||||||
Looks like your Google credentials have
|
Looks like your Google credentials have
|
||||||
expired! Visit the log in page to sign out
|
expired! Visit our log in page to sign out
|
||||||
and sign back in with Google
|
and sign back in with Google,
|
||||||
to save this to Google Drive!
|
then try saving again!
|
||||||
<a target='_blank' rel='noopener noreferrer'
|
<a target='_blank' rel='noopener noreferrer'
|
||||||
href={`https://www.naturalcrit.com/login?redirect=${this.state.url}`}>
|
href={`https://www.naturalcrit.com/login?redirect=${this.state.url}`}>
|
||||||
<div className='confirm'>
|
<div className='confirm'>
|
||||||
|
|||||||
@@ -226,14 +226,14 @@ const NewPage = createClass({
|
|||||||
</Nav.item>;
|
</Nav.item>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.state.errors.status == '403' && this.state.errors.response.body.errors[0].reason == 'insufficientPermissions'){
|
if(this.state.errors.response.req.url.match(/^\/api\/.*Google.*$/m)){
|
||||||
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
|
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
|
||||||
Oops!
|
Oops!
|
||||||
<div className='errorContainer' onClick={this.clearErrors}>
|
<div className='errorContainer' onClick={this.clearErrors}>
|
||||||
Looks like your Google credentials have
|
Looks like your Google credentials have
|
||||||
expired! Visit the log in page to sign out
|
expired! Visit our log in page to sign out
|
||||||
and sign back in with Google
|
and sign back in with Google,
|
||||||
to save this to Google Drive!
|
then try saving again!
|
||||||
<a target='_blank' rel='noopener noreferrer'
|
<a target='_blank' rel='noopener noreferrer'
|
||||||
href={`https://www.naturalcrit.com/login?redirect=${this.state.url}`}>
|
href={`https://www.naturalcrit.com/login?redirect=${this.state.url}`}>
|
||||||
<div className='confirm'>
|
<div className='confirm'>
|
||||||
|
|||||||
9718
package-lock.json
generated
9718
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "homebrewery",
|
"name": "homebrewery",
|
||||||
"description": "Create authentic looking D&D homebrews using only markdown",
|
"description": "Create authentic looking D&D homebrews using only markdown",
|
||||||
"version": "3.0.4",
|
"version": "3.0.5",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.11.x"
|
"node": "16.11.x"
|
||||||
},
|
},
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
"marked": "3.0.8",
|
"marked": "3.0.8",
|
||||||
"markedLegacy": "npm:marked@^0.3.19",
|
"markedLegacy": "npm:marked@^0.3.19",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"mongoose": "^6.0.14",
|
"mongoose": "^6.0.15",
|
||||||
"nanoid": "3.1.30",
|
"nanoid": "3.1.30",
|
||||||
"nconf": "^0.11.3",
|
"nconf": "^0.11.3",
|
||||||
"prop-types": "15.7.2",
|
"prop-types": "15.7.2",
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^8.3.0",
|
"eslint": "^8.4.1",
|
||||||
"eslint-plugin-react": "^7.27.1",
|
"eslint-plugin-react": "^7.27.1",
|
||||||
"pico-check": "^2.1.3"
|
"pico-check": "^2.1.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable max-lines */
|
||||||
require('./codeEditor.less');
|
require('./codeEditor.less');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const createClass = require('create-react-class');
|
const createClass = require('create-react-class');
|
||||||
@@ -74,18 +75,50 @@ const CodeEditor = createClass({
|
|||||||
tabSize : 2,
|
tabSize : 2,
|
||||||
historyEventDelay : 250,
|
historyEventDelay : 250,
|
||||||
extraKeys : {
|
extraKeys : {
|
||||||
'Ctrl-B' : this.makeBold,
|
'Ctrl-B' : this.makeBold,
|
||||||
'Cmd-B' : this.makeBold,
|
'Cmd-B' : this.makeBold,
|
||||||
'Ctrl-I' : this.makeItalic,
|
'Ctrl-I' : this.makeItalic,
|
||||||
'Cmd-I' : this.makeItalic,
|
'Cmd-I' : this.makeItalic,
|
||||||
'Ctrl-M' : this.makeSpan,
|
'Ctrl-U' : this.makeUnderline,
|
||||||
'Cmd-M' : this.makeSpan,
|
'Cmd-U' : this.makeUnderline,
|
||||||
'Ctrl-/' : this.makeComment,
|
'Ctrl-.' : this.makeNbsp,
|
||||||
'Cmd-/' : this.makeComment,
|
'Cmd-.' : this.makeNbsp,
|
||||||
'Ctrl-[' : this.foldAllCode,
|
'Shift-Ctrl-.' : this.makeSpace,
|
||||||
'Cmd-[' : this.foldAllCode,
|
'Shift-Cmd-.' : this.makeSpace,
|
||||||
'Ctrl-]' : this.unfoldAllCode,
|
'Shift-Ctrl-,' : this.removeSpace,
|
||||||
'Cmd-]' : this.unfoldAllCode
|
'Shift-Cmd-,' : this.removeSpace,
|
||||||
|
'Ctrl-M' : this.makeSpan,
|
||||||
|
'Cmd-M' : this.makeSpan,
|
||||||
|
'Shift-Ctrl-M' : this.makeDiv,
|
||||||
|
'Shift-Cmd-M' : this.makeDiv,
|
||||||
|
'Ctrl-/' : this.makeComment,
|
||||||
|
'Cmd-/' : this.makeComment,
|
||||||
|
'Ctrl-K' : this.makeLink,
|
||||||
|
'Cmd-K' : this.makeLink,
|
||||||
|
'Ctrl-L' : ()=>this.makeList('UL'),
|
||||||
|
'Cmd-L' : ()=>this.makeList('UL'),
|
||||||
|
'Shift-Ctrl-L' : ()=>this.makeList('OL'),
|
||||||
|
'Shift-Cmd-L' : ()=>this.makeList('OL'),
|
||||||
|
'Shift-Ctrl-1' : ()=>this.makeHeader(1),
|
||||||
|
'Shift-Ctrl-2' : ()=>this.makeHeader(2),
|
||||||
|
'Shift-Ctrl-3' : ()=>this.makeHeader(3),
|
||||||
|
'Shift-Ctrl-4' : ()=>this.makeHeader(4),
|
||||||
|
'Shift-Ctrl-5' : ()=>this.makeHeader(5),
|
||||||
|
'Shift-Ctrl-6' : ()=>this.makeHeader(6),
|
||||||
|
'Shift-Cmd-1' : ()=>this.makeHeader(1),
|
||||||
|
'Shift-Cmd-2' : ()=>this.makeHeader(2),
|
||||||
|
'Shift-Cmd-3' : ()=>this.makeHeader(3),
|
||||||
|
'Shift-Cmd-4' : ()=>this.makeHeader(4),
|
||||||
|
'Shift-Cmd-5' : ()=>this.makeHeader(5),
|
||||||
|
'Shift-Cmd-6' : ()=>this.makeHeader(6),
|
||||||
|
'Shift-Ctrl-Enter' : this.newColumn,
|
||||||
|
'Shift-Cmd-Enter' : this.newColumn,
|
||||||
|
'Ctrl-Enter' : this.newPage,
|
||||||
|
'Cmd-Enter' : this.newPage,
|
||||||
|
'Ctrl-[' : this.foldAllCode,
|
||||||
|
'Cmd-[' : this.foldAllCode,
|
||||||
|
'Ctrl-]' : this.unfoldAllCode,
|
||||||
|
'Cmd-]' : this.unfoldAllCode
|
||||||
},
|
},
|
||||||
foldGutter : true,
|
foldGutter : true,
|
||||||
foldOptions : {
|
foldOptions : {
|
||||||
@@ -117,6 +150,14 @@ const CodeEditor = createClass({
|
|||||||
this.updateSize();
|
this.updateSize();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
makeHeader : function (number) {
|
||||||
|
const selection = this.codeMirror.getSelection();
|
||||||
|
const header = Array(number).fill('#').join('');
|
||||||
|
this.codeMirror.replaceSelection(`${header} ${selection}`, 'around');
|
||||||
|
const cursor = this.codeMirror.getCursor();
|
||||||
|
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch + selection.length + number + 1 });
|
||||||
|
},
|
||||||
|
|
||||||
makeBold : function() {
|
makeBold : function() {
|
||||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '**' && selection.slice(-2) === '**';
|
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '**' && selection.slice(-2) === '**';
|
||||||
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `**${selection}**`, 'around');
|
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `**${selection}**`, 'around');
|
||||||
@@ -127,14 +168,55 @@ const CodeEditor = createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
makeItalic : function() {
|
makeItalic : function() {
|
||||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 1) === '_' && selection.slice(-1) === '_';
|
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 1) === '*' && selection.slice(-1) === '*';
|
||||||
this.codeMirror.replaceSelection(t ? selection.slice(1, -1) : `_${selection}_`, 'around');
|
this.codeMirror.replaceSelection(t ? selection.slice(1, -1) : `*${selection}*`, 'around');
|
||||||
if(selection.length === 0){
|
if(selection.length === 0){
|
||||||
const cursor = this.codeMirror.getCursor();
|
const cursor = this.codeMirror.getCursor();
|
||||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 1 });
|
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 1 });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
makeNbsp : function() {
|
||||||
|
this.codeMirror.replaceSelection(' ', 'end');
|
||||||
|
},
|
||||||
|
|
||||||
|
makeSpace : function() {
|
||||||
|
const selection = this.codeMirror.getSelection();
|
||||||
|
const t = selection.slice(0, 8) === '{{width:' && selection.slice(0 -4) === '% }}';
|
||||||
|
if(t){
|
||||||
|
const percent = parseInt(selection.slice(8, -4)) + 10;
|
||||||
|
this.codeMirror.replaceSelection(percent < 90 ? `{{width:${percent}% }}` : '{{width:100% }}', 'around');
|
||||||
|
} else {
|
||||||
|
this.codeMirror.replaceSelection(`{{width:10% }}`, 'around');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
removeSpace : function() {
|
||||||
|
const selection = this.codeMirror.getSelection();
|
||||||
|
const t = selection.slice(0, 8) === '{{width:' && selection.slice(0 -4) === '% }}';
|
||||||
|
if(t){
|
||||||
|
const percent = parseInt(selection.slice(8, -4)) - 10;
|
||||||
|
this.codeMirror.replaceSelection(percent > 10 ? `{{width:${percent}% }}` : '', 'around');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
newColumn : function() {
|
||||||
|
this.codeMirror.replaceSelection('\n\\column\n\n', 'end');
|
||||||
|
},
|
||||||
|
|
||||||
|
newPage : function() {
|
||||||
|
this.codeMirror.replaceSelection('\n\\page\n\n', 'end');
|
||||||
|
},
|
||||||
|
|
||||||
|
makeUnderline : function() {
|
||||||
|
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 3) === '<u>' && selection.slice(-4) === '</u>';
|
||||||
|
this.codeMirror.replaceSelection(t ? selection.slice(3, -4) : `<u>${selection}</u>`, 'around');
|
||||||
|
if(selection.length === 0){
|
||||||
|
const cursor = this.codeMirror.getCursor();
|
||||||
|
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 4 });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
makeSpan : function() {
|
makeSpan : function() {
|
||||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}';
|
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}';
|
||||||
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `{{ ${selection}}}`, 'around');
|
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `{{ ${selection}}}`, 'around');
|
||||||
@@ -144,12 +226,72 @@ const CodeEditor = createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
makeComment : function() {
|
makeDiv : function() {
|
||||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 4) === '<!--' && selection.slice(-3) === '-->';
|
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}';
|
||||||
this.codeMirror.replaceSelection(t ? selection.slice(4, -3) : `<!-- ${selection} -->`, 'around');
|
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `{{\n${selection}\n}}`, 'around');
|
||||||
if(selection.length === 0){
|
if(selection.length === 0){
|
||||||
const cursor = this.codeMirror.getCursor();
|
const cursor = this.codeMirror.getCursor();
|
||||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 4 });
|
this.codeMirror.setCursor({ line: cursor.line - 1, ch: cursor.ch }); // set to -2? if wanting to enter classes etc. if so, get rid of first \n when replacing selection
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
makeComment : function() {
|
||||||
|
let regex;
|
||||||
|
let cursorPos;
|
||||||
|
let newComment;
|
||||||
|
const selection = this.codeMirror.getSelection();
|
||||||
|
if(this.props.language === 'gfm'){
|
||||||
|
regex = /^\s*(<!--\s?)(.*?)(\s?-->)\s*$/gs;
|
||||||
|
cursorPos = 4;
|
||||||
|
newComment = `<!-- ${selection} -->`;
|
||||||
|
} else {
|
||||||
|
regex = /^\s*(\/\*\s?)(.*?)(\s?\*\/)\s*$/gs;
|
||||||
|
cursorPos = 3;
|
||||||
|
newComment = `/* ${selection} */`;
|
||||||
|
}
|
||||||
|
this.codeMirror.replaceSelection(regex.test(selection) == true ? selection.replace(regex, '$2') : newComment, 'around');
|
||||||
|
if(selection.length === 0){
|
||||||
|
const cursor = this.codeMirror.getCursor();
|
||||||
|
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - cursorPos });
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
makeLink : function() {
|
||||||
|
const isLink = /^\[(.*)\]\((.*)\)$/;
|
||||||
|
const selection = this.codeMirror.getSelection().trim();
|
||||||
|
let match;
|
||||||
|
if(match = isLink.exec(selection)){
|
||||||
|
const altText = match[1];
|
||||||
|
const url = match[2];
|
||||||
|
this.codeMirror.replaceSelection(`${altText} ${url}`);
|
||||||
|
const cursor = this.codeMirror.getCursor();
|
||||||
|
this.codeMirror.setSelection({ line: cursor.line, ch: cursor.ch - url.length }, { line: cursor.line, ch: cursor.ch });
|
||||||
|
} else {
|
||||||
|
this.codeMirror.replaceSelection(`[${selection || 'alt text'}](url)`);
|
||||||
|
const cursor = this.codeMirror.getCursor();
|
||||||
|
this.codeMirror.setSelection({ line: cursor.line, ch: cursor.ch - 4 }, { line: cursor.line, ch: cursor.ch - 1 });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
makeList : function(listType) {
|
||||||
|
const selectionStart = this.codeMirror.getCursor('from'), selectionEnd = this.codeMirror.getCursor('to');
|
||||||
|
this.codeMirror.setSelection(
|
||||||
|
{ line: selectionStart.line, ch: 0 },
|
||||||
|
{ line: selectionEnd.line, ch: this.codeMirror.getLine(selectionEnd.line).length }
|
||||||
|
);
|
||||||
|
const newSelection = this.codeMirror.getSelection();
|
||||||
|
|
||||||
|
const regex = /^\d+\.\s|^-\s/gm;
|
||||||
|
if(newSelection.match(regex) != null){ // if selection IS A LIST
|
||||||
|
this.codeMirror.replaceSelection(newSelection.replace(regex, ''), 'around');
|
||||||
|
} else { // if selection IS NOT A LIST
|
||||||
|
listType == 'UL' ? this.codeMirror.replaceSelection(newSelection.replace(/^/gm, `- `), 'around') :
|
||||||
|
this.codeMirror.replaceSelection(newSelection.replace(/^/gm, (()=>{
|
||||||
|
let n = 1;
|
||||||
|
return ()=>{
|
||||||
|
return `${n++}. `;
|
||||||
|
};
|
||||||
|
})()), 'around');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user