mirror of
https://github.com/google/blockly.git
synced 2026-01-10 18:37:09 +01:00
Attempt to work around the IE/Edge bug where getComputedTextLength() throws an exception when the SVG node is not visible. This workaround forces a re-render, which in turn, forces a re-calculation of the node width once a block is inserted into the workspace SVG. This workaround is only executed on IE and Edge. See https://groups.google.com/forum/#!topic/blockly/T8IR4t4xAIY for the initial discussion of this issue.
This commit is contained in:
@@ -29,6 +29,8 @@ goog.provide('Blockly.BlockSvg.render');
|
||||
|
||||
goog.require('Blockly.BlockSvg');
|
||||
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
// UI constants for rendering blocks.
|
||||
/**
|
||||
@@ -314,6 +316,13 @@ Blockly.BlockSvg.prototype.renderFields_ =
|
||||
if (!root) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Force a width re-calculation on IE and Edge to get around the issue
|
||||
// described in Blockly.Field.getCachedWidth
|
||||
if (goog.userAgent.IE || goog.userAgent.EDGE) {
|
||||
field.updateWidth();
|
||||
}
|
||||
|
||||
if (this.RTL) {
|
||||
cursorX -= field.renderSep + field.renderWidth;
|
||||
root.setAttribute('transform',
|
||||
|
||||
@@ -295,6 +295,15 @@ Blockly.Field.prototype.render_ = function() {
|
||||
var textNode = document.createTextNode(this.getDisplayText_());
|
||||
this.textElement_.appendChild(textNode);
|
||||
|
||||
this.updateWidth();
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates thw width of the field. This calls getCachedWidth which won't cache
|
||||
* the approximated width on IE/Edge when `getComputedTextLength` fails. Once
|
||||
* it eventually does succeed, the result will be cached.
|
||||
**/
|
||||
Blockly.Field.prototype.updateWidth = function() {
|
||||
var width = Blockly.Field.getCachedWidth(this.textElement_);
|
||||
if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('width',
|
||||
@@ -306,24 +315,36 @@ Blockly.Field.prototype.render_ = function() {
|
||||
/**
|
||||
* Gets the width of a text element, caching it in the process.
|
||||
* @param {!Element} textElement An SVG 'text' element.
|
||||
* @retur {number} Width of element.
|
||||
* @return {number} Width of element.
|
||||
*/
|
||||
Blockly.Field.getCachedWidth = function(textElement) {
|
||||
var key = textElement.textContent + '\n' + textElement.className.baseVal;
|
||||
if (Blockly.Field.cacheWidths_ && Blockly.Field.cacheWidths_[key]) {
|
||||
var width = Blockly.Field.cacheWidths_[key];
|
||||
} else {
|
||||
try {
|
||||
var width = textElement.getComputedTextLength();
|
||||
} catch (e) {
|
||||
// MSIE 11 is known to throw "Unexpected call to method or property
|
||||
// access." if Blockly is hidden.
|
||||
var width = textElement.textContent.length * 8;
|
||||
}
|
||||
if (Blockly.Field.cacheWidths_) {
|
||||
Blockly.Field.cacheWidths_[key] = width;
|
||||
var width;
|
||||
|
||||
// Return the cached width if it exists.
|
||||
if (Blockly.Field.cacheWidths_) {
|
||||
width = Blockly.Field.cacheWidths_[key];
|
||||
if (width) {
|
||||
return width;
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to compute fetch the width of the SVG text element.
|
||||
try {
|
||||
width = textElement.getComputedTextLength();
|
||||
} catch (e) {
|
||||
// MSIE 11 and Edge are known to throw "Unexpected call to method or
|
||||
// property access." if the block is hidden. Instead, use an
|
||||
// approximation and do not cache the result. At some later point in time
|
||||
// when the block is inserted into the visible DOM, this method will be
|
||||
// called again and, at that point in time, will not throw an exception.
|
||||
return textElement.textContent.length * 8;
|
||||
}
|
||||
|
||||
// Cache the computed width and return.
|
||||
if (Blockly.Field.cacheWidths_) {
|
||||
Blockly.Field.cacheWidths_[key] = width;
|
||||
}
|
||||
return width;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ goog.provide('Blockly.Xml');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
@@ -367,6 +368,11 @@ Blockly.Xml.domToBlock = function(xmlBlock, workspace) {
|
||||
setTimeout(function() {
|
||||
if (topBlock.workspace) { // Check that the block hasn't been deleted.
|
||||
topBlock.setConnectionsHidden(false);
|
||||
// Force a render on IE and Edge to get around the issue described in
|
||||
// Blockly.Field.getCachedWidth
|
||||
if (goog.userAgent.IE || goog.userAgent.EDGE) {
|
||||
topBlock.render();
|
||||
}
|
||||
}
|
||||
}, 1);
|
||||
topBlock.updateDisabled();
|
||||
|
||||
Reference in New Issue
Block a user