Move formulabar edit field to separate file

Signed-off-by: Szymon Kłos <szymon.klos@collabora.com>
Change-Id: Ia4d5f1c8547cf329c5f624ad09ac9049bdda62f7
This commit is contained in:
Szymon Kłos 2023-03-09 11:27:03 +01:00 committed by Szymon Kłos
parent d06f539943
commit 1665d6e7bc
5 changed files with 234 additions and 181 deletions

View file

@ -331,6 +331,7 @@ COOL_JS_LST =\
src/control/Control.AlertDialog.js \
src/control/ColorPicker.js \
src/control/jsdialog/Widget.LanguageSelector.js \
src/control/jsdialog/Widget.FormulabarEdit.js \
src/control/jsdialog/Widget.MultilineEdit.js \
src/control/jsdialog/Widget.TreeView.js \
src/control/Control.JSDialog.js \

View file

@ -68,7 +68,7 @@ L.Control.FormulaBarJSDialog = L.Control.extend({
},
{
id: 'sc_input_window',
type: 'multilineedit',
type: 'formulabaredit',
text: text ? text : '',
rawKeyEvents: window.mode.isDesktop() ? true : undefined,
useTextInput: window.mode.isDesktop() ? undefined : true
@ -92,7 +92,7 @@ L.Control.FormulaBarJSDialog = L.Control.extend({
command: '.uno:FunctionDialog'
}, {
id: 'sc_input_window',
type: 'multilineedit',
type: 'formulabaredit',
text: text ? text : '',
rawKeyEvents: undefined,
useTextInput: true

View file

@ -65,7 +65,7 @@ L.Control.JSDialogBuilder = L.Control.extend({
// list of types which can have multiple children but are not considered as containers
this._nonContainerType = ['buttonbox', 'treelistbox', 'iconview', 'combobox', 'listbox',
'scrollwindow', 'grid', 'tabcontrol', 'multilineedit'];
'scrollwindow', 'grid', 'tabcontrol', 'multilineedit', 'formulabaredit'];
this._controlHandlers = {};
this._controlHandlers['radiobutton'] = this._radiobuttonControl;
@ -75,6 +75,7 @@ L.Control.JSDialogBuilder = L.Control.extend({
this._controlHandlers['metricfield'] = this._metricfieldControl;
this._controlHandlers['formattedfield'] = this._formattedfieldControl;
this._controlHandlers['edit'] = this._editControl;
this._controlHandlers['formulabaredit'] = JSDialog.formulabarEdit;
this._controlHandlers['multilineedit'] = JSDialog.multilineEdit;
this._controlHandlers['pushbutton'] = this._pushbuttonControl;
this._controlHandlers['okbutton'] = this._pushbuttonControl;

View file

@ -0,0 +1,225 @@
/* -*- js-indent-level: 8 -*- */
/*
* JSDialog.FormulabarEdit - text field in the fromulabar
*
* Example JSON:
* {
* id: 'id',
* type: 'formulabaredit',
* test: 'text content\nsecond line',
* useTextInput: true,
* rawKeyEvents: false,
* cursor: true,
* enabled: false
* }
*
* 'useTextInput' instead of typing into field, key events are sent using L.TextInput
* 'rawKeyEvents' instead of typing into field, key events are sent only to the server using jsdialog events
* 'cursor' specifies if user can type into the field or it is readonly
* 'enabled' editable field can be temporarily disabled
*
* Copyright the Collabora Online contributors.
*
* SPDX-License-Identifier: MPL-2.0
*/
/* global JSDialog UNOKey UNOModifier */
function _sendSelection(edit, builder) {
var currentText = edit.value;
var startPos = edit.selectionStart;
var endPos = edit.selectionEnd;
var startPara = 0;
var endPara = 0;
if (currentText.indexOf('\n') >= 0) {
var currentPos = 0;
var found = currentText.indexOf('\n', currentPos);
while (startPos > found) {
if (found === -1)
break;
currentPos = found + 1;
startPara++;
found = currentText.indexOf('\n', currentPos);
}
startPos -= currentPos;
currentPos = 0;
found = currentText.indexOf('\n', currentPos);
while (endPos > found) {
if (found === -1)
break;
currentPos = found + 1;
endPara++;
found = currentText.indexOf('\n', currentPos);
}
endPos -= currentPos;
}
var selection = startPos + ';' + endPos + ';' + startPara + ';' + endPara;
builder.callback('edit', 'textselection', edit, selection, builder);
}
function _formulabarEditControl(parentContainer, data, builder) {
var controlType = 'textarea';
if (data.cursor && (data.cursor === 'false' || data.cursor === false))
controlType = 'p';
var edit = L.DomUtil.create(controlType, 'ui-textarea ' + builder.options.cssClass, parentContainer);
if (controlType === 'textarea')
edit.value = builder._cleanText(data.text);
else
{
data.text = data.text.replace(/(?:\r\n|\r|\n)/g, '<br>');
edit.textContent = builder._cleanText(data.text);
}
edit.id = data.id;
if (data.enabled === 'false' || data.enabled === false)
edit.disabled = true;
if (data.useTextInput) {
// uses TextInput.js logic and events handling (IME for mobile/touch devices)
edit.addEventListener('input', builder.map._textInput._onInput.bind(builder.map._textInput));
edit.addEventListener('beforeinput', builder.map._textInput._onBeforeInput.bind(builder.map._textInput));
} else if (data.rawKeyEvents) {
// sends key events over jsdialog
var modifier = 0;
edit.addEventListener('keydown', function(event) {
if (edit.disabled) {
event.preventDefault();
return;
}
if (event.key === 'Enter') {
builder.callback('edit', 'keypress', edit, UNOKey.RETURN | modifier, builder);
event.preventDefault();
} else if (event.key === 'Escape' || event.key === 'Esc') {
builder.callback('edit', 'keypress', edit, UNOKey.ESCAPE | modifier, builder);
event.preventDefault();
} else if (event.key === 'Left' || event.key === 'ArrowLeft') {
builder.callback('edit', 'keypress', edit, UNOKey.LEFT | modifier, builder);
event.preventDefault();
} else if (event.key === 'Right' || event.key === 'ArrowRight') {
builder.callback('edit', 'keypress', edit, UNOKey.RIGHT | modifier, builder);
event.preventDefault();
} else if (event.key === 'Up' || event.key === 'ArrowUp') {
setTimeout(function () { _sendSelection(edit, builder); }, 0);
} else if (event.key === 'Down' || event.key === 'ArrowDown') {
setTimeout(function () { _sendSelection(edit, builder); }, 0);
} else if (event.key === 'Home') {
builder.callback('edit', 'keypress', edit, UNOKey.HOME | modifier, builder);
event.preventDefault();
} else if (event.key === 'End') {
builder.callback('edit', 'keypress', edit, UNOKey.END | modifier, builder);
event.preventDefault();
} else if (event.key === 'Backspace') {
builder.callback('edit', 'keypress', edit, UNOKey.BACKSPACE | modifier, builder);
event.preventDefault();
} else if (event.key === 'Delete') {
builder.callback('edit', 'keypress', edit, UNOKey.DELETE | modifier, builder);
event.preventDefault();
} else if (event.key === 'Space') {
builder.callback('edit', 'keypress', edit, UNOKey.SPACE | modifier, builder);
event.preventDefault();
} else if (event.key === 'Tab') {
builder.callback('edit', 'keypress', edit, UNOKey.TAB | modifier, builder);
event.preventDefault();
} else if (event.key === 'Shift') {
modifier = modifier | UNOModifier.SHIFT;
event.preventDefault();
} else if (event.key === 'Control') {
modifier = modifier | UNOModifier.CTRL;
event.preventDefault();
} else if (event.key === 'a' && event.ctrlKey) {
builder.callback('edit', 'keypress', edit, UNOKey.A | UNOModifier.CTRL, builder);
}
});
edit.addEventListener('keyup', function(event) {
if (edit.disabled) {
event.preventDefault();
return;
}
if (event.key === 'Shift') {
modifier = modifier & (~UNOModifier.SHIFT);
event.preventDefault();
} else if (event.key === 'Control') {
modifier = modifier & (~UNOModifier.CTRL);
event.preventDefault();
}
});
edit.addEventListener('blur', function() {
modifier = 0;
});
edit.addEventListener('keypress', function(event) {
if (edit.disabled) {
event.preventDefault();
return;
}
if (event.key === 'Enter' ||
event.key === 'Escape' ||
event.key === 'Esc' ||
event.key === 'Left' ||
event.key === 'ArrowLeft' ||
event.key === 'Right' ||
event.key === 'ArrowRight' ||
event.key === 'Up' ||
event.key === 'ArrowUp' ||
event.key === 'Down' ||
event.key === 'ArrowDown' ||
event.key === 'Home' ||
event.key === 'End' ||
event.key === 'Backspace' ||
event.key === 'Delete' ||
event.key === 'Space' ||
event.key === 'Tab') {
// skip
} else {
var keyCode = event.keyCode;
if (event.ctrlKey) {
keyCode = event.key.toUpperCase().charCodeAt(0);
keyCode = builder.map.keyboard._toUNOKeyCode(keyCode);
keyCode |= UNOModifier.CTRL;
}
builder.callback('edit', 'keypress', edit, keyCode, builder);
}
event.preventDefault();
});
}
if (data.rawKeyEvents || data.useTextInput) {
edit.addEventListener('mouseup', function(event) {
if (edit.disabled) {
event.preventDefault();
return;
}
builder.callback('edit', 'grab_focus', edit, null, builder);
_sendSelection(event.target, builder);
event.preventDefault();
});
}
if (data.hidden)
L.DomUtil.addClass(edit, 'hidden');
return false;
}
JSDialog.formulabarEdit = function (parentContainer, data, builder) {
var buildInnerData = _formulabarEditControl(parentContainer, data, builder);
return buildInnerData;
};

View file

@ -7,14 +7,10 @@
* id: 'id',
* type: 'multilineedit',
* test: 'text content\nsecond line',
* useTextInput: true,
* rawKeyEvents: false,
* cursor: true,
* enabled: false
* }
*
* 'useTextInput' instead of typing into field, key events are sent using L.TextInput
* 'rawKeyEvents' instead of typing into field, key events are sent only to the server using jsdialog events
*
* 'cursor' specifies if user can type into the field or it is readonly
* 'enabled' editable field can be temporarily disabled
*
@ -23,44 +19,7 @@
* SPDX-License-Identifier: MPL-2.0
*/
/* global JSDialog UNOKey UNOModifier */
function _sendSelection(edit, builder) {
var currentText = edit.value;
var startPos = edit.selectionStart;
var endPos = edit.selectionEnd;
var startPara = 0;
var endPara = 0;
if (currentText.indexOf('\n') >= 0) {
var currentPos = 0;
var found = currentText.indexOf('\n', currentPos);
while (startPos > found) {
if (found === -1)
break;
currentPos = found + 1;
startPara++;
found = currentText.indexOf('\n', currentPos);
}
startPos -= currentPos;
currentPos = 0;
found = currentText.indexOf('\n', currentPos);
while (endPos > found) {
if (found === -1)
break;
currentPos = found + 1;
endPara++;
found = currentText.indexOf('\n', currentPos);
}
endPos -= currentPos;
}
var selection = startPos + ';' + endPos + ';' + startPara + ';' + endPara;
builder.callback('edit', 'textselection', edit, selection, builder);
}
/* global JSDialog */
function _multiLineEditControl(parentContainer, data, builder, callback) {
var controlType = 'textarea';
@ -86,143 +45,10 @@ function _multiLineEditControl(parentContainer, data, builder, callback) {
edit.addEventListener('change', function() {
if (callback)
callback(this.value);
if (data.rawKeyEvents || data.useTextInput) {
// here event.keyCode has some non-ascii code
} else
builder.callback('edit', 'change', edit, this.value, builder);
builder.callback('edit', 'change', edit, this.value, builder);
});
if (data.useTextInput) {
// uses TextInput.js logic and events handling (IME for mobile/touch devices)
edit.addEventListener('input', builder.map._textInput._onInput.bind(builder.map._textInput));
edit.addEventListener('beforeinput', builder.map._textInput._onBeforeInput.bind(builder.map._textInput));
} else if (data.rawKeyEvents) {
// sends key events over jsdialog
var modifier = 0;
edit.addEventListener('keydown', function(event) {
if (edit.disabled) {
event.preventDefault();
return;
}
if (event.key === 'Enter') {
builder.callback('edit', 'keypress', edit, UNOKey.RETURN | modifier, builder);
event.preventDefault();
} else if (event.key === 'Escape' || event.key === 'Esc') {
builder.callback('edit', 'keypress', edit, UNOKey.ESCAPE | modifier, builder);
event.preventDefault();
} else if (event.key === 'Left' || event.key === 'ArrowLeft') {
builder.callback('edit', 'keypress', edit, UNOKey.LEFT | modifier, builder);
event.preventDefault();
} else if (event.key === 'Right' || event.key === 'ArrowRight') {
builder.callback('edit', 'keypress', edit, UNOKey.RIGHT | modifier, builder);
event.preventDefault();
} else if (event.key === 'Up' || event.key === 'ArrowUp') {
setTimeout(function () { _sendSelection(edit, builder); }, 0);
} else if (event.key === 'Down' || event.key === 'ArrowDown') {
setTimeout(function () { _sendSelection(edit, builder); }, 0);
} else if (event.key === 'Home') {
builder.callback('edit', 'keypress', edit, UNOKey.HOME | modifier, builder);
event.preventDefault();
} else if (event.key === 'End') {
builder.callback('edit', 'keypress', edit, UNOKey.END | modifier, builder);
event.preventDefault();
} else if (event.key === 'Backspace') {
builder.callback('edit', 'keypress', edit, UNOKey.BACKSPACE | modifier, builder);
event.preventDefault();
} else if (event.key === 'Delete') {
builder.callback('edit', 'keypress', edit, UNOKey.DELETE | modifier, builder);
event.preventDefault();
} else if (event.key === 'Space') {
builder.callback('edit', 'keypress', edit, UNOKey.SPACE | modifier, builder);
event.preventDefault();
} else if (event.key === 'Tab') {
builder.callback('edit', 'keypress', edit, UNOKey.TAB | modifier, builder);
event.preventDefault();
} else if (event.key === 'Shift') {
modifier = modifier | UNOModifier.SHIFT;
event.preventDefault();
} else if (event.key === 'Control') {
modifier = modifier | UNOModifier.CTRL;
event.preventDefault();
} else if (event.key === 'a' && event.ctrlKey) {
builder.callback('edit', 'keypress', edit, UNOKey.A | UNOModifier.CTRL, builder);
}
});
edit.addEventListener('keyup', function(event) {
if (edit.disabled) {
event.preventDefault();
return;
}
if (event.key === 'Shift') {
modifier = modifier & (~UNOModifier.SHIFT);
event.preventDefault();
} else if (event.key === 'Control') {
modifier = modifier & (~UNOModifier.CTRL);
event.preventDefault();
}
});
edit.addEventListener('blur', function() {
modifier = 0;
});
edit.addEventListener('keypress', function(event) {
if (edit.disabled) {
event.preventDefault();
return;
}
if (event.key === 'Enter' ||
event.key === 'Escape' ||
event.key === 'Esc' ||
event.key === 'Left' ||
event.key === 'ArrowLeft' ||
event.key === 'Right' ||
event.key === 'ArrowRight' ||
event.key === 'Up' ||
event.key === 'ArrowUp' ||
event.key === 'Down' ||
event.key === 'ArrowDown' ||
event.key === 'Home' ||
event.key === 'End' ||
event.key === 'Backspace' ||
event.key === 'Delete' ||
event.key === 'Space' ||
event.key === 'Tab') {
// skip
} else {
var keyCode = event.keyCode;
if (event.ctrlKey) {
keyCode = event.key.toUpperCase().charCodeAt(0);
keyCode = builder.map.keyboard._toUNOKeyCode(keyCode);
keyCode |= UNOModifier.CTRL;
}
builder.callback('edit', 'keypress', edit, keyCode, builder);
}
event.preventDefault();
});
}
if (data.rawKeyEvents || data.useTextInput) {
edit.addEventListener('mouseup', function(event) {
if (edit.disabled) {
event.preventDefault();
return;
}
builder.callback('edit', 'grab_focus', edit, null, builder);
_sendSelection(event.target, builder);
event.preventDefault();
});
}
if (data.hidden)
L.DomUtil.addClass(edit, 'hidden');