Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions plugins/find-and-replace.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@
border: 0;
}

.code-input_find-and-replace_dialog input:hover {
outline: none;
}

.code-input_find-and-replace_dialog input.code-input_find-and-replace_error {
color: #ff0000aa;
}
Expand Down
3 changes: 2 additions & 1 deletion plugins/find-and-replace.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ codeInput.plugins.FindAndReplace = class extends codeInput.Plugin {
const findInput = document.createElement('input');
const findCaseSensitiveCheckbox = document.createElement('input');
const findRegExpCheckbox = document.createElement('input');
// TODO in next major version: use more semantic HTML element than code
const matchDescription = document.createElement('code');
matchDescription.setAttribute("aria-live", "assertive"); // Screen reader must read the number of matches found.

Expand Down Expand Up @@ -240,7 +241,7 @@ codeInput.plugins.FindAndReplace = class extends codeInput.Plugin {
findRegExpCheckbox.title = this.instructions.findRegExp;
findRegExpCheckbox.classList.add("code-input_find-and-replace_reg-exp-checkbox");

matchDescription.textContent = "Search for matches in your code.";
matchDescription.textContent = this.instructions.start;
matchDescription.classList.add("code-input_find-and-replace_match-description");


Expand Down
15 changes: 10 additions & 5 deletions plugins/go-to-line.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
.code-input_go-to-line_dialog {
position: absolute;
top: 0; right: 14px;
height: 28px;
padding: 6px;
padding-top: 8px;
border: solid 1px #00000044;
Expand Down Expand Up @@ -48,10 +47,6 @@
color: #ff0000aa;
}

.code-input_go-to-line_dialog input:focus {
outline: none;
}

/* Cancel icon */
.code-input_go-to-line_dialog span {
display: inline-block;
Expand All @@ -75,3 +70,13 @@
opacity: .8;
background-color: #00000018;
}

/* For backwards compatibility, p element on the same level as buttons rather than
buttons being nested inside other element like in FindAndReplace. */
.code-input_go-to-line_dialog p {
font-family: monospace;
width: 264px;
margin: 0;
overflow: hidden;
white-space: wrap;
}
41 changes: 36 additions & 5 deletions plugins/go-to-line.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
instructions = {
closeDialog: "Close Dialog and Return to Editor",
input: "Line:Column / Line no. then Enter",
guidanceFormat: "Wrong format. Enter a line number (e.g. 1) or a line number then colon then column number (e.g. 1:3).",
guidanceLineRange: (current, max) => { return `Line number (currently ${current}) should be between 1 and ${max} inclusive.` },
guidanceColumnRange: (line, current, max) => { return `On line ${line}, column number (currently ${current}) should be between 1 and ${max} inclusive.` },
guidanceValidLine: (line, column) => { return `Press Enter to go to line ${line}.` },
guidanceValidColumn: (line, column) => { return `Press Enter to go to line ${line}, column ${column}.` },
};

/**
Expand All @@ -33,32 +38,51 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {

/* Called with a dialog box keyup event to check the validity of the line number entered and submit the dialog if Enter is pressed */
checkPrompt(dialog, event) {
if (event.key == 'Escape') return this.cancelPrompt(dialog, event);

// Line number(:column number)
const lines = dialog.textarea.value.split('\n');
const maxLineNo = lines.length;
const lineNo = Number(dialog.input.value.split(':')[0]);
let columnNo = 0; // Means go to start of indented line
let maxColumnNo = 1;
const querySplitByColons = dialog.input.value.split(':');
if(querySplitByColons.length > 2) return dialog.input.classList.add('code-input_go-to-line_error');

if (event.key == 'Escape') return this.cancelPrompt(dialog, event);
// Invalid format
if(querySplitByColons.length > 2 || !/^[0-9:]*$/.test(dialog.input.value)) {
dialog.guidance.textContent = this.instructions.guidanceFormat;
return dialog.input.classList.add('code-input_go-to-line_error');
}

// Number(s) present
if (dialog.input.value) {
if (!/^[0-9:]*$/.test(dialog.input.value) || lineNo < 1 || lineNo > maxLineNo) {
if (lineNo < 1 || lineNo > maxLineNo) {
// Out-of-range line number
dialog.guidance.textContent = this.instructions.guidanceLineRange(lineNo, maxLineNo);
return dialog.input.classList.add('code-input_go-to-line_error');
} else {
// Check if line:column
// Check if line:column - if so calculate column number
if(querySplitByColons.length >= 2) {
columnNo = Number(querySplitByColons[1]);
maxColumnNo = lines[lineNo-1].length;
maxColumnNo = lines[lineNo-1].length+1; // column 1 always works since at start of line
}
if(columnNo < 0 || columnNo > maxColumnNo) {
dialog.guidance.textContent = this.instructions.guidanceColumnRange(lineNo, columnNo, maxColumnNo);
return dialog.input.classList.add('code-input_go-to-line_error');
} else {
if(columnNo === 0) {
// No column specified, or 0 which for backwards compatibility acts
// like none selected
dialog.guidance.textContent = this.instructions.guidanceValidLine(lineNo);
} else {
dialog.guidance.textContent = this.instructions.guidanceValidColumn(lineNo, columnNo);
}
dialog.input.classList.remove('code-input_go-to-line_error');
}
}
} else {
// No value
dialog.guidance.textContent = "";
}

if (event.key == 'Enter') {
Expand Down Expand Up @@ -91,6 +115,7 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
const textarea = codeInput.textareaElement;

const dialog = document.createElement('div');

const input = document.createElement('input');

// TODO: Make a button element (semantic HTML for accessibility) in next major version
Expand All @@ -100,15 +125,21 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
cancel.setAttribute("tabindex", 0); // Visible to keyboard navigation
cancel.setAttribute("title", this.instructions.closeDialog);

const guidance = document.createElement('p');
guidance.setAttribute("aria-live", "assertive"); // Screen reader must read the status message.
guidance.textContent = "";

dialog.appendChild(input);
dialog.appendChild(cancel);
dialog.appendChild(guidance);

dialog.className = 'code-input_go-to-line_dialog';
input.spellcheck = false;
input.placeholder = this.instructions.input;
dialog.codeInput = codeInput;
dialog.textarea = textarea;
dialog.input = input;
dialog.guidance = guidance;

input.addEventListener('keypress', (event) => {
/* Stop enter from submitting form */
Expand Down