Field textinput pixel perfect input (#3443)

* Fix sizing of text input field in zelos, pixel perfect input in other browsers
This commit is contained in:
Sam El-Husseini
2019-11-14 16:13:22 -08:00
committed by GitHub
parent d8476306f4
commit 139382e009
8 changed files with 31 additions and 39 deletions

View File

@@ -360,7 +360,7 @@ Blockly.Css.CONTENT = [
'fill: #000;',
'}',
'.blocklyEditableText:hover>rect {',
'.blocklyEditableText:not(.editing):hover>rect {',
'stroke: #fff;',
'stroke-width: 2;',
'}',
@@ -427,6 +427,7 @@ Blockly.Css.CONTENT = [
'padding: 0;',
'width: 100%;',
'text-align: center;',
'display: block;',
'}',
/* Edge and IE introduce a close icon when the input value is longer than a

View File

@@ -917,7 +917,7 @@ Blockly.Field.prototype.setTooltip = function(newTip) {
* to the SVG root of the field. When this element is
* clicked on an editable field, the editor will open.
* @return {!Element} Element to bind click handler to.
* @private
* @protected
*/
Blockly.Field.prototype.getClickTarget_ = function() {
return this.clickTarget_ || this.getSvgRoot();

View File

@@ -248,14 +248,7 @@ Blockly.FieldTextInput.prototype.render_ = function() {
// This logic is done in render_ rather than doValueInvalid_ or
// doValueUpdate_ so that the code is more centralized.
if (this.isBeingEdited_) {
if (this.sourceBlock_.RTL) {
// in RTL, we need to let the browser reflow before resizing
// in order to get the correct bounding box of the borderRect
// avoiding issue #2777.
setTimeout(this.resizeEditor_.bind(this), 0);
} else {
this.resizeEditor_();
}
this.resizeEditor_();
var htmlInput = /** @type {!HTMLElement} */(this.htmlInput_);
if (!this.isTextValid_) {
Blockly.utils.dom.addClass(htmlInput, 'blocklyInvalidInput');
@@ -340,6 +333,8 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) {
Blockly.FieldTextInput.prototype.widgetCreate_ = function() {
var div = Blockly.WidgetDiv.DIV;
Blockly.utils.dom.addClass(this.getClickTarget_(), 'editing');
var htmlInput = /** @type {HTMLInputElement} */ (document.createElement('input'));
htmlInput.className = 'blocklyHtmlInput';
htmlInput.setAttribute('spellcheck', this.spellcheck_);
@@ -366,13 +361,7 @@ Blockly.FieldTextInput.prototype.widgetCreate_ = function() {
htmlInput.untypedDefaultValue_ = this.value_;
htmlInput.oldValue_ = null;
if (Blockly.utils.userAgent.GECKO) {
// In FF, ensure the browser reflows before resizing to avoid issue #2777.
setTimeout(this.resizeEditor_.bind(this), 0);
} else {
this.resizeEditor_();
}
this.resizeEditor_();
this.bindInputEvents_(htmlInput);
@@ -402,6 +391,8 @@ Blockly.FieldTextInput.prototype.widgetDispose_ = function() {
style.height = 'auto';
style.fontSize = '';
this.htmlInput_ = null;
Blockly.utils.dom.removeClass(this.getClickTarget_(), 'editing');
};
/**
@@ -481,6 +472,7 @@ Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(_e) {
var value = this.getValueFromEditorText_(text);
this.setValue(value);
this.forceRerender();
this.resizeEditor_();
Blockly.Events.setGroup(false);
}
};
@@ -529,17 +521,6 @@ Blockly.FieldTextInput.prototype.resizeEditor_ = function() {
var x = this.sourceBlock_.RTL ? bBox.right - div.offsetWidth : bBox.left;
var xy = new Blockly.utils.Coordinate(x, bBox.top);
// Shift by a few pixels to line up exactly.
xy.y += 1;
if (Blockly.utils.userAgent.GECKO && Blockly.WidgetDiv.DIV.style.top) {
// Firefox mis-reports the location of the border by a pixel
// once the WidgetDiv is moved into position.
xy.x -= 1;
xy.y -= 1;
}
if (Blockly.utils.userAgent.WEBKIT) {
xy.y -= 3;
}
div.style.left = xy.x + 'px';
div.style.top = xy.y + 'px';
};
@@ -638,21 +619,15 @@ Blockly.FieldTextInput.prototype.getValueFromEditorText_ = function(text) {
*/
Blockly.FieldTextInput.prototype.getScaledBBox = function() {
if (this.fullBlockClickTarget_) {
var heightWidth = this.sourceBlock_.getHeightWidth();
var xy = this.getClickTarget_().getBoundingClientRect();
} else {
var heightWidth = this.borderRect_.getBBox();
var xy = this.borderRect_.getBoundingClientRect();
}
var scale = this.sourceBlock_.workspace.scale;
var xy = this.getAbsoluteXY_();
var scaledHeight = heightWidth.height * scale;
var scaledWidth = heightWidth.width * scale;
return {
top: xy.y,
bottom: xy.y + scaledHeight,
bottom: xy.y + xy.height,
left: xy.x,
right: xy.x + scaledWidth
right: xy.x + xy.width
};
};

View File

@@ -214,7 +214,7 @@ Blockly.blockRendering.ConstantProvider = function() {
* set to false.
* @type {number}
*/
this.FIELD_TEXT_BASELINE_Y = 13;
this.FIELD_TEXT_BASELINE_Y = Blockly.utils.userAgent.GECKO ? 12 : 13.09;
/**
* A field's text element's dominant baseline.

View File

@@ -201,10 +201,14 @@ suite('Angle Fields', function() {
this.angleField.htmlInput_ = Object.create(null);
this.angleField.htmlInput_.oldValue_ = '1';
this.angleField.htmlInput_.untypedDefaultValue_ = 1;
this.stub = sinon.stub(this.angleField, 'resizeEditor_');
});
teardown(function() {
this.angleField.setValidator(null);
this.angleField.htmlInput_ = null;
if (this.stub) {
this.stub.restore();
}
});
suite('Null Validator', function() {
setup(function() {

View File

@@ -329,10 +329,14 @@ suite('Number Fields', function() {
this.numberField.htmlInput_ = Object.create(null);
this.numberField.htmlInput_.oldValue_ = '1';
this.numberField.htmlInput_.untypedDefaultValue_ = 1;
this.stub = sinon.stub(this.numberField, 'resizeEditor_');
});
teardown(function() {
this.numberField.setValidator(null);
this.numberField.htmlInput_ = null;
if (this.stub) {
this.stub.restore();
}
});
suite('Null Validator', function() {
setup(function() {

View File

@@ -161,10 +161,14 @@ suite('Text Input Fields', function() {
this.textInputField.htmlInput_ = Object.create(null);
this.textInputField.htmlInput_.oldValue_ = 'value';
this.textInputField.htmlInput_.untypedDefaultValue_ = 'value';
this.stub = sinon.stub(this.textInputField, 'resizeEditor_');
});
teardown(function() {
this.textInputField.setValidator(null);
Blockly.FieldTextInput.htmlInput_ = null;
if (this.stub) {
this.stub.restore();
}
});
suite('Null Validator', function() {
setup(function() {
@@ -233,6 +237,7 @@ suite('Text Input Fields', function() {
FIELD_TEXT_FONTWEIGHT: 'normal',
FIELD_TEXT_FONTFAMILY: 'sans-serif'
};
field.clickTarget_ = document.createElement('div');
Blockly.WidgetDiv.DIV = document.createElement('div');
this.stub = sinon.stub(field, 'resizeEditor_');
};

View File

@@ -38,9 +38,12 @@ suite('Procedures', function() {
context.defBlock.setFieldValue(startName, 'NAME');
context.callBlock = new Blockly.Block(this.workspace, context.callType);
context.callBlock.setFieldValue(startName, 'NAME');
context.stub = sinon.stub(
context.defBlock.getField('NAME'), 'resizeEditor_');
func.call(context);
context.defBlock.dispose();
context.callBlock.dispose();
context.stub.restore();
}
};
});