start overlay support

master
Lucas Duailibe 2018-04-19 18:57:11 -03:00
parent 9ca95011c0
commit c794de0e9f
2 changed files with 107 additions and 6 deletions

View File

@ -121,7 +121,7 @@ class Playground extends React.Component {
<div className="editors">
<InputPanel
mode={util.getCodemirrorMode(options.parser)}
rulerColumn={options.printWidth}
ruler={options.printWidth}
value={content}
placeholder={getCodeSample(options.parser)}
onChange={this.setContent}
@ -135,13 +135,13 @@ class Playground extends React.Component {
<OutputPanel
mode={util.getCodemirrorMode(options.parser)}
value={formatted}
rulerColumn={options.printWidth}
ruler={options.printWidth}
/>
{editorState.showSecondFormat ? (
<OutputPanel
mode={util.getCodemirrorMode(options.parser)}
value={getSecondFormat(formatted, debug.reformatted)}
rulerColumn={options.printWidth}
ruler={options.printWidth}
/>
) : null}
</div>

View File

@ -7,12 +7,13 @@ class CodeMirrorPanel extends React.Component {
this._textareaRef = React.createRef();
this._codeMirror = null;
this._cached = "";
this._overlay = null;
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
const options = Object.assign({}, this.props);
delete options.rulerColumn;
delete options.ruler;
delete options.rulerColor;
delete options.value;
delete options.onChange;
@ -26,6 +27,7 @@ class CodeMirrorPanel extends React.Component {
this._codeMirror.on("change", this.handleChange);
this.updateValue(this.props.value || "");
this.updateOverlay();
}
componentWillUnmount() {
@ -35,6 +37,13 @@ class CodeMirrorPanel extends React.Component {
componentDidUpdate(prevProps) {
if (this.props.readOnly && this.props.value !== this._cached) {
this.updateValue(this.props.value);
this.updateOverlay();
}
if (
this.props.overlayStart !== prevProps.overlayStart ||
this.props.overlayEnd !== this.props.overlayEnd
) {
this.updateOverlay();
}
if (this.props.mode !== prevProps.mode) {
this._codeMirror.setOption("mode", this.props.mode);
@ -42,7 +51,7 @@ class CodeMirrorPanel extends React.Component {
if (this.props.placeholder !== prevProps.placeholder) {
this._codeMirror.setOption("placeholder", this.props.placeholder);
}
if (this.props.rulerColumn !== prevProps.rulerColumn) {
if (this.props.ruler !== prevProps.ruler) {
this._codeMirror.setOption("rulers", [makeRuler(this.props)]);
}
}
@ -52,6 +61,20 @@ class CodeMirrorPanel extends React.Component {
this._codeMirror.setValue(value);
}
updateOverlay() {
if (!this.props.readOnly) {
if (this._overlay) {
this._codeMirror.removeOverlay(this._overlay);
}
const [start, end] = getIndexPosition(this.props.value, [
this.props.overlayStart,
this.props.overlayEnd
]);
this._overlay = createOverlay(start, end);
this._codeMirror.addOverlay(this._overlay);
}
}
handleChange(doc, change) {
if (change.origin !== "setValue") {
this._cached = doc.getValue();
@ -68,8 +91,56 @@ class CodeMirrorPanel extends React.Component {
}
}
function getIndexPosition(text, indexes) {
indexes = indexes.slice().sort();
let line = 0;
let count = 0;
let lineStart = 0;
const result = [];
while (indexes.length) {
const index = indexes.shift();
while (count < index && count < text.length) {
count++;
if (text[count] === "\n") {
line++;
lineStart = count;
}
}
result.push({ line, pos: count - lineStart });
}
return result;
}
function createOverlay(start, end) {
return {
token(stream) {
const line = stream.lineOracle.line;
if (line < start.line || line > end.line) {
stream.skipToEnd();
} else if (line === start.line && stream.pos < start.pos) {
stream.pos = start.pos;
} else if (line === end.line) {
if (stream.pos < end.pos) {
stream.pos = end.pos;
return "searching";
} else {
stream.skipToEnd();
}
} else {
stream.skipToEnd();
return "searching";
}
}
};
}
function makeRuler(props) {
return { column: props.rulerColumn, color: props.rulerColor };
return { column: props.ruler, color: props.rulerColor };
}
export function InputPanel(props) {
@ -82,6 +153,8 @@ export function InputPanel(props) {
showCursorWhenSelecting={true}
tabWidth={2}
rulerColor="#eeeeee"
rangeStart={5}
rangeEnd={25}
{...props}
/>
);
@ -108,3 +181,31 @@ export function DebugPanel({ value }) {
/>
);
}
function stringify(obj, replacer, spaces, cycleReplacer) {
return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
}
function serializer(replacer, cycleReplacer) {
var stack = [],
keys = [];
if (cycleReplacer == null)
cycleReplacer = function(key, value) {
if (stack[0] === value) return "[Circular ~]";
return (
"[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]"
);
};
return function(key, value) {
if (stack.length > 0) {
var thisPos = stack.indexOf(this);
~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value);
} else stack.push(value);
return replacer == null ? value : replacer.call(this, key, value);
};
}