feature (orgmode): org mode on mobile: touching a heading/checkbox to

toggle and UI improvements
This commit is contained in:
Mickael KERJEAN 2018-05-01 00:10:53 +10:00
parent 633883544a
commit 716f90008f
3 changed files with 72 additions and 9 deletions

View file

@ -32,9 +32,15 @@ export class Editor extends React.Component {
editor: null,
filename: this.props.filename
};
this._refresh = this._refresh.bind(this);
}
_refresh(){
if(this.state.editor) this.state.editor.refresh();
}
componentDidMount(){
window.addEventListener('resize', this._refresh);
this.setState({loading: null, error: false}, () => {
window.setTimeout(() => {
if(this.state.loading === null) this.setState({loading: true});
@ -60,6 +66,7 @@ export class Editor extends React.Component {
this.props.onFoldChange(
org_shifttab(this.state.editor)
);
this.state.editor.refresh();
}
});
});
@ -70,17 +77,15 @@ export class Editor extends React.Component {
const size_small = 500;
let editor = CodeMirror(document.getElementById('editor'), {
value: this.props.content,
lineNumbers: document.body.offsetWidth > size_small ? true : false,
lineNumbers: true,
mode: mode,
keyMap: config.god_editor_mode ? "emacs" : "default",
lineWrapping: true,
foldGutter: {
minFoldSize: 1
},
foldOptions: {
widget: "..."
}
});
window._editor = editor;
if(!('ontouchstart' in window)) editor.focus();
@ -112,6 +117,7 @@ export class Editor extends React.Component {
}
componentWillUnmount(){
window.removeEventListener('resize', this._refresh);
this.state.editor.clearHistory();
}

View file

@ -35,6 +35,15 @@
padding: 5px;
}
/* HIDE LINE NUMBERS ON MOBILE */
// this hack is important as we rely on the dom to provide code folding for org mode
@media screen and (max-width: 400px) {
.CodeMirror-sizer{ margin-left: 0!important; }
.CodeMirror-gutters{ display: none; }
.CodeMirror-gutter-wrapper{ display: none; }
}
/* SEARCH */
.CodeMirror-dialog {
position: fixed;
@ -82,6 +91,9 @@
.cm-s-default .cm-header.cm-org-level-star{
color: #6f6f6f;
vertical-align: text-bottom;
display: inline-block;
padding-left: 4px;
margin-left: -4px;
}
.cm-s-default .cm-header.cm-org-todo{color: #FF8355; font-weight: normal;}
.cm-s-default .cm-header.cm-org-done{color: #3BB27C; font-weight: normal;}

View file

@ -17,7 +17,7 @@ CodeMirror.defineSimpleMode("orgmode", {
{regex: /(\~[^\~]+\~)/, token: ["comment"]},
{regex: /(\=[^\=]+\=)/, token: ["comment"]},
{regex: /\[\[[^\[\]]*\]\[[^\[\]]*\]\]/, token: "url"}, // links
{regex: /\[[xX\s]?\]/, token: 'qualifier'}, // checkbox
{regex: /\[[xX\s\-]?\]/, token: 'qualifier org-toggle'}, // checkbox
{regex: /\#\+BEGIN_[A-Z]*/, token: "comment", next: "env"}, // comments
{regex: /:?[A-Z_]+\:.*/, token: "comment"}, // property drawers
{regex: /(\#\+[A-Z_]*)(\:.*)/, token: ["keyword", 'qualifier']}, // environments
@ -120,12 +120,57 @@ CodeMirror.afterInit = function(editor, fn){
}
});
editor.on('touchstart', function(cm, e){
setTimeout(() => {
isFold(cm, cm.getCursor()) ? unfold(cm, cm.getCursor()) : fold(cm, cm.getCursor())
}, 150);
// Toggle headline on org mode by clicking on the heading ;)
editor.on('mousedown', toggleHandler);
editor.on('touchstart', toggleHandler);
function toggleHandler(cm, e){
const className = e.target.getAttribute('class');
if(/cm-org-level-star/.test(className) === true){
_foldHeadline(cm, e);
}else if(/cm-org-toggle/.test(className) === true){
_toggleCheckbox(cm, e);
}
function _foldHeadline(){
const line = _init(e);
if(line >= 0){
const cursor = {line: line, ch: 0};
isFold(cm, cursor) ? unfold(cm, cursor) : fold(cm, cursor);
}
}
function _toggleCheckbox(){
const line = _init(e),
reg = /\[(x|X|\s|\-)]/;
if(line > 0 && reg.test(e.target.innerHTML)){
const old = cm.getLine(line),
cursor = cm.getCursor(),
content = RegExp.$1.toLowerCase() === "x" ? old.replace(reg, "[ ]") : old.replace(reg, "[X]");
cm.replaceRange(content, {line: line, ch:0}, {line: line, ch: old.length});
cm.setCursor(cursor);
}
}
function _init(e){
if('ontouchstart' in window) e.preventDefault();
// yes it's dirty but well code mirror doesn't let us the choice
let line = parseInt(
e.target
.parentElement.parentElement.parentElement
.firstElementChild.firstElementChild.textContent
) - 1;
return line;
}
}
editor.on('gutterClick', function(cm, line){
const cursor = {line: line, ch: 0};
isFold(cm, cursor) ? unfold(cm, cursor) : fold(cm, cursor);
});
// fold everything except headers by default
editor.operation(function() {
for (var i = 0; i < editor.lineCount() ; i++) {