@instructure/canvas-rce
Version:
A component wrapping Canvas's usage of Tinymce
121 lines (120 loc) • 3.54 kB
JavaScript
import _pt from "prop-types";
/*
* Copyright (C) 2019 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useState } from 'react';
import FindReplaceTray from './FindReplaceTray';
export default function FindReplaceTrayController({
plugin,
onDismiss,
initialText = '',
undoManager,
getSelectionContext
}) {
// this component really just exists to make the index easier to track
const [findIndex, setFindIndex] = useState(0);
const [findCount, setFindCount] = useState(0);
const [selectionContext, setSelectionContext] = useState(['', '']);
const updateSelectionContext = () => {
const srText = getSelectionContext();
setSelectionContext(srText);
};
const newFindIndex = direction => {
let newIndex = 0;
if (findCount === 0) {
newIndex = 0;
} else if (direction === 1) {
// at max count, wrap back to 1
if (findIndex === findCount) {
newIndex = 1;
} else newIndex = findIndex + 1;
} else if (direction === -1) {
// at 1, wrap back to max
if (findIndex === 1) {
newIndex = findCount;
} else newIndex = findIndex - 1;
}
return newIndex;
};
const done = () => {
plugin.done(false);
setFindCount(0);
setFindIndex(0);
setSelectionContext([]);
};
const handleDismiss = () => {
done();
onDismiss();
};
const handleNext = () => {
plugin.next();
setFindIndex(newFindIndex(1));
updateSelectionContext();
};
const handlePrevious = () => {
plugin.prev();
setFindIndex(newFindIndex(-1));
updateSelectionContext();
};
const handleFind = text => {
if (!text) {
done();
} else {
const count = plugin.find(text);
setFindCount(count);
const index = count ? 1 : 0;
setFindIndex(index);
updateSelectionContext();
}
};
const handleReplace = (text, forward = true, all = false) => {
if (!text) return;
undoManager?.add();
plugin.replace(text, forward, all);
if (findCount === 1 || all) {
done();
return;
}
// we can't just find again, because that will reset index to 1
let newIndex;
const newFindCount = findCount - 1;
if (forward) {
newIndex = findIndex === findCount ? 1 : findIndex;
} else {
newIndex = findIndex === 1 ? newFindCount : findIndex - 1;
}
setFindCount(newFindCount);
setFindIndex(newIndex);
updateSelectionContext();
};
return /*#__PURE__*/React.createElement(FindReplaceTray, {
onRequestClose: handleDismiss,
onNext: handleNext,
onPrevious: handlePrevious,
onFind: handleFind,
onReplace: handleReplace,
index: findIndex,
max: findCount,
initialText: initialText,
selectionContext: selectionContext
});
}
FindReplaceTrayController.propTypes = {
onDismiss: _pt.func.isRequired,
initialText: _pt.string,
getSelectionContext: _pt.func.isRequired
};