wed
Version:
Wed is a schema-aware editor for XML documents.
248 lines • 8.94 kB
JavaScript
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
define(["require", "exports", "bootbox", "jquery", "./interactivity", "./search-replace"], function (require, exports, bootbox, jquery_1, interactivity_1, search_replace_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
bootbox = __importStar(bootbox);
jquery_1 = __importDefault(jquery_1);
exports.Direction = search_replace_1.Direction;
const dialogTemplate = `
<form>
<div class='form-group'>
<label>Search for:</label>
<input type='text' name='search' class='form-control'>
</div>
<div class='form-group'>
<label>Replace with:</label>
<input type='text' name='replace' class='form-control'>
</div>
<div class='radio'>
<span>Direction:</span>
<div>
<label class='radio-inline'>
<input type='radio' name='direction' value='forward'> Forward
</label>
</div>
<div>
<label class='radio-inline'>
<input type='radio' name='direction' value='backwards'> Backwards
</label>
<div>
</div>
<div class='radio'>
<span>Context:</span>
<div>
<label class='radio-inline'>
<input type='radio' name='context' value='text' checked>
Only element text
</label>
</div>
<div>
<label class='radio-inline'>
<input type='radio' name='context' value='attributes'>
Only attributes values
</label>
</div>
</div>
</form>`;
/**
* Brings up a search and replace dialog box to allow the user to search through
* a document. See the section on "Dialog Search" in the editor's embedded help
* for details of how it works for users.
*/
class DialogSearchReplace {
/**
* @param editor The editor for which we are searching.
*
* @param scroller The scroller holding the document being searched.
*
* @param direction The direction of the search.
*/
constructor(editor, scroller, direction) {
this.search = new search_replace_1.SearchReplace(editor, scroller);
const body = jquery_1.default(dialogTemplate)[0];
const dialog = this.dialog = bootbox.dialog({
title: "Search/Replace",
message: body,
onEscape: true,
backdrop: false,
size: "small",
buttons: {
find: {
label: "Find",
className: "btn-primary",
callback: this.onFind.bind(this),
},
replaceFind: {
label: "Replace and Find",
className: "btn-default replace-and-find",
callback: this.onReplaceAndFind.bind(this),
},
replaceAll: {
label: "Replace All",
className: "btn-default replace-all",
callback: this.onReplaceAll.bind(this),
},
close: {
label: "Close",
},
},
});
interactivity_1.makeResizable(dialog);
interactivity_1.makeDraggable(dialog);
const directionItems = body.elements
.namedItem("direction");
this.forwardRadioButton = directionItems[0];
this.backwardRadioButton = directionItems[1];
const contextItems = body.elements
.namedItem("context");
this.textRadioButton = contextItems[0];
this.attributeRadioButton = contextItems[1];
let toCheck;
switch (direction) {
case search_replace_1.Direction.FORWARD:
toCheck = this.forwardRadioButton;
break;
case search_replace_1.Direction.BACKWARDS:
toCheck = this.backwardRadioButton;
break;
default:
const d = direction;
throw new Error(`unknown direction: ${d}`);
}
toCheck.checked = true;
dialog.on("hidden.bs.modal", () => {
this.search.clearHighlight();
// Return the focus to the editor.
editor.caretManager.focusInputField();
});
const searchField = this.searchField =
body.elements.namedItem("search");
const $searchField = jquery_1.default(searchField);
$searchField.on("input", this.onSearchInput.bind(this));
const replaceField = this.replaceField =
body.elements.namedItem("replace");
const $replaceField = jquery_1.default(replaceField);
$replaceField.on("input", this.onReplaceInput.bind(this));
this.replaceButton =
dialog[0].querySelector(".replace-and-find");
this.replaceAll =
dialog[0].querySelector(".replace-all");
this.updateButtons();
}
/**
* @returns The search option to pass to the search engine, given the user
* choices.
*/
getSearchOptions() {
let direction;
if (this.forwardRadioButton.checked) {
direction = search_replace_1.Direction.FORWARD;
}
else if (this.backwardRadioButton.checked) {
direction = search_replace_1.Direction.BACKWARDS;
}
else {
throw new Error("cannot determine direction");
}
let context;
if (this.textRadioButton.checked) {
context = search_replace_1.Context.TEXT;
}
else if (this.attributeRadioButton.checked) {
context = search_replace_1.Context.ATTRIBUTE_VALUES;
}
else {
throw new Error("cannot determine context");
}
return {
direction,
context,
};
}
/**
* Processes clicks on the "Find" button: searches the document and updates
* the buttons.
*/
onFind() {
this.next();
this.updateButtons();
return false;
}
/**
* Updates the disabled status of the buttons depending on how the input
* elements are set.
*/
updateButtons() {
const fieldFilled = this.replaceField.value !== "";
this.replaceButton.disabled = !(fieldFilled && this.search.canReplace);
this.replaceAll.disabled = !fieldFilled;
}
/**
* Processes clicks on the "Replace and Find" button: replaces the current hit
* and find the next one.
*/
onReplaceAndFind() {
this.replace();
this.onFind();
return false;
}
/**
* Processes clicks on the "Replace All" button: replaces all replaceable
* hits.
*/
onReplaceAll() {
if (this.search.current === undefined) {
this.onFind();
}
while (this.search.current !== null) {
if (this.search.canReplace) {
this.replace();
}
this.next();
}
this.updateButtons();
return false;
}
/**
* Replaces the current hit.
*/
replace() {
this.search.replace(this.replaceField.value);
}
/**
* Moves to the next hit in the direction specified by the user.
*/
next() {
this.search.next(this.getSearchOptions());
}
/**
* Processes an ``input`` event on the search field. May change the currently
* highlighted hit.
*/
onSearchInput() {
const value = this.searchField.value;
if (value !== this.previousSearchValue) {
this.previousSearchValue = value;
this.search.updatePattern(value, this.getSearchOptions());
this.updateButtons();
}
}
/**
* Processes an ``input`` event on the replace field. Updates the buttons.
*/
onReplaceInput() {
this.updateButtons();
}
}
exports.DialogSearchReplace = DialogSearchReplace;
});
//# sourceMappingURL=dialog-search-replace.js.map