mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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_');
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user