Use generics to derive SVG element type (#4036)

* Encapsulate type in a generic to automatically derive type of SVG element when using createSvgElement
This commit is contained in:
Sam El-Husseini
2020-07-13 10:40:31 -07:00
committed by GitHub
parent e4bbd451a3
commit 0f3db47fa5
39 changed files with 564 additions and 278 deletions

View File

@@ -1019,7 +1019,8 @@ Blockly.blockRendering.ConstantProvider.prototype.createDom = function(svg,
... filters go here ...
</defs>
*/
var defs = Blockly.utils.dom.createSvgElement('defs', {}, svg);
var defs = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.DEFS, {}, svg);
/*
<filter id="blocklyEmbossFilter837493">
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur" />
@@ -1034,11 +1035,14 @@ Blockly.blockRendering.ConstantProvider.prototype.createDom = function(svg,
k1="0" k2="1" k3="1" k4="0" />
</filter>
*/
var embossFilter = Blockly.utils.dom.createSvgElement('filter',
var embossFilter = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FILTER,
{'id': 'blocklyEmbossFilter' + this.randomIdentifier}, defs);
Blockly.utils.dom.createSvgElement('feGaussianBlur',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEGAUSSIANBLUR,
{'in': 'SourceAlpha', 'stdDeviation': 1, 'result': 'blur'}, embossFilter);
var feSpecularLighting = Blockly.utils.dom.createSvgElement('feSpecularLighting',
var feSpecularLighting = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FESPECULARLIGHTING,
{
'in': 'blur',
'surfaceScale': 1,
@@ -1048,16 +1052,19 @@ Blockly.blockRendering.ConstantProvider.prototype.createDom = function(svg,
'result': 'specOut'
},
embossFilter);
Blockly.utils.dom.createSvgElement('fePointLight',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEPOINTLIGHT,
{'x': -5000, 'y': -10000, 'z': 20000}, feSpecularLighting);
Blockly.utils.dom.createSvgElement('feComposite',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FECOMPOSITE,
{
'in': 'specOut',
'in2': 'SourceAlpha',
'operator': 'in',
'result': 'specOut'
}, embossFilter);
Blockly.utils.dom.createSvgElement('feComposite',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FECOMPOSITE,
{
'in': 'SourceGraphic',
'in2': 'specOut',
@@ -1077,22 +1084,26 @@ Blockly.blockRendering.ConstantProvider.prototype.createDom = function(svg,
<path d="M 0 0 L 10 10 M 10 0 L 0 10" stroke="#cc0" />
</pattern>
*/
var disabledPattern = Blockly.utils.dom.createSvgElement('pattern',
var disabledPattern = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATTERN,
{
'id': 'blocklyDisabledPattern' + this.randomIdentifier,
'patternUnits': 'userSpaceOnUse',
'width': 10,
'height': 10
}, defs);
Blockly.utils.dom.createSvgElement('rect',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{'width': 10, 'height': 10, 'fill': '#aaa'}, disabledPattern);
Blockly.utils.dom.createSvgElement('path',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATH,
{'d': 'M 0 0 L 10 10 M 10 0 L 0 10', 'stroke': '#cc0'}, disabledPattern);
this.disabledPatternId = disabledPattern.id;
this.disabledPattern_ = disabledPattern;
if (Blockly.blockRendering.Debug) {
var debugFilter = Blockly.utils.dom.createSvgElement('filter',
var debugFilter = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FILTER,
{
'id': 'blocklyDebugFilter' + this.randomIdentifier,
'height': '160%',
@@ -1103,21 +1114,26 @@ Blockly.blockRendering.ConstantProvider.prototype.createDom = function(svg,
defs);
// Set all gaussian blur pixels to 1 opacity before applying flood
var debugComponentTransfer = Blockly.utils.dom.createSvgElement(
'feComponentTransfer', {'result': 'outBlur'}, debugFilter);
Blockly.utils.dom.createSvgElement('feFuncA',
Blockly.utils.dom.SvgElementType.FECOMPONENTTRANSFER, {
'result': 'outBlur'
}, debugFilter);
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEFUNCA,
{
'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'
},
debugComponentTransfer);
// Color the highlight
Blockly.utils.dom.createSvgElement('feFlood',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEFLOOD,
{
'flood-color': '#ff0000',
'flood-opacity': 0.5,
'result': 'outColor'
},
debugFilter);
Blockly.utils.dom.createSvgElement('feComposite',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FECOMPOSITE,
{
'in': 'outColor', 'in2': 'outBlur',
'operator': 'in', 'result': 'outGlow'

View File

@@ -99,7 +99,8 @@ Blockly.blockRendering.Debug.prototype.drawSpacerRow = function(row, cursorY, is
cursorY -= height;
}
this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'rowSpacerRect blockRenderDebug',
'x': isRtl ? -(row.xPos + row.width) : row.xPos,
@@ -133,7 +134,8 @@ Blockly.blockRendering.Debug.prototype.drawSpacerElem = function(elem, rowHeight
xPos = -(xPos + width);
}
var yPos = elem.centerline - elem.height / 2;
this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'elemSpacerRect blockRenderDebug',
'x': xPos,
@@ -161,7 +163,8 @@ Blockly.blockRendering.Debug.prototype.drawRenderedElem = function(elem, isRtl)
xPos = -(xPos + elem.width);
}
var yPos = elem.centerline - elem.height / 2;
this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'rowRenderingRect blockRenderDebug',
'x': xPos,
@@ -177,7 +180,8 @@ Blockly.blockRendering.Debug.prototype.drawRenderedElem = function(elem, isRtl)
if (Blockly.blockRendering.Types.isField(elem) &&
elem.field instanceof Blockly.FieldLabel) {
var baseline = this.constants_.FIELD_TEXT_BASELINE;
this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'rowRenderingRect blockRenderDebug',
'x': xPos,
@@ -233,7 +237,8 @@ Blockly.blockRendering.Debug.prototype.drawConnection = function(conn) {
colour = 'goldenrod';
fill = colour;
}
this.debugElements_.push(Blockly.utils.dom.createSvgElement('circle',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.CIRCLE,
{
'class': 'blockRenderDebug',
'cx': conn.offsetInBlock_.x,
@@ -256,7 +261,8 @@ Blockly.blockRendering.Debug.prototype.drawRenderedRow = function(row, cursorY,
if (!Blockly.blockRendering.Debug.config.rows) {
return;
}
this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'elemRenderingRect blockRenderDebug',
'x': isRtl ? -(row.xPos + row.width) : row.xPos,
@@ -274,7 +280,8 @@ Blockly.blockRendering.Debug.prototype.drawRenderedRow = function(row, cursorY,
}
if (Blockly.blockRendering.Debug.config.connectedBlockBounds) {
this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'connectedBlockWidth blockRenderDebug',
'x': isRtl ? -(row.xPos + row.widthWithConnectedBlocks) : row.xPos,
@@ -328,7 +335,8 @@ Blockly.blockRendering.Debug.prototype.drawBoundingBox = function(info) {
// Bounding box without children.
var xPos = info.RTL ? -info.width : 0;
var yPos = 0;
this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'blockBoundingBox blockRenderDebug',
'x': xPos,
@@ -345,7 +353,8 @@ Blockly.blockRendering.Debug.prototype.drawBoundingBox = function(info) {
if (Blockly.blockRendering.Debug.config.connectedBlockBounds) {
// Bounding box with children.
xPos = info.RTL ? -info.widthWithChildren : 0;
this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect',
this.debugElements_.push(Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'blockRenderDebug',
'x': xPos,

View File

@@ -124,8 +124,8 @@ Blockly.blockRendering.MarkerSvg.prototype.createDom = function() {
Blockly.blockRendering.MarkerSvg.CURSOR_CLASS :
Blockly.blockRendering.MarkerSvg.MARKER_CLASS;
this.svgGroup_ =
Blockly.utils.dom.createSvgElement('g', {
this.svgGroup_ = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.G, {
'class': className
}, null);
@@ -588,7 +588,8 @@ Blockly.blockRendering.MarkerSvg.prototype.createDomInternal_ = function() {
</g>
*/
this.markerSvg_ = Blockly.utils.dom.createSvgElement('g',
this.markerSvg_ = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.G,
{
'width': this.constants_.CURSOR_WS_WIDTH,
'height': this.constants_.WS_CURSOR_HEIGHT
@@ -596,7 +597,8 @@ Blockly.blockRendering.MarkerSvg.prototype.createDomInternal_ = function() {
// A horizontal line used to represent a workspace coordinate or next
// connection.
this.markerSvgLine_ = Blockly.utils.dom.createSvgElement('rect',
this.markerSvgLine_ = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'width': this.constants_.CURSOR_WS_WIDTH,
'height': this.constants_.WS_CURSOR_HEIGHT,
@@ -605,7 +607,8 @@ Blockly.blockRendering.MarkerSvg.prototype.createDomInternal_ = function() {
this.markerSvg_);
// A filled in rectangle used to represent a stack.
this.markerSvgRect_ = Blockly.utils.dom.createSvgElement('rect',
this.markerSvgRect_ = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.RECT,
{
'class': 'blocklyVerticalMarker',
'rx': 10, 'ry': 10,
@@ -614,7 +617,8 @@ Blockly.blockRendering.MarkerSvg.prototype.createDomInternal_ = function() {
this.markerSvg_);
// A filled in puzzle piece used to represent an input value.
this.markerInput_ = Blockly.utils.dom.createSvgElement('path',
this.markerInput_ = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATH,
{
'transform': '',
'style': 'display: none'
@@ -623,7 +627,8 @@ Blockly.blockRendering.MarkerSvg.prototype.createDomInternal_ = function() {
// A path used to represent a previous connection and a block, an output
// connection and a block, or a block.
this.markerBlock_ = Blockly.utils.dom.createSvgElement('path',
this.markerBlock_ = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATH,
{
'transform': '',
'style': 'display: none',
@@ -635,12 +640,15 @@ Blockly.blockRendering.MarkerSvg.prototype.createDomInternal_ = function() {
// Markers and stack markers don't blink.
if (this.isCursor()) {
var blinkProperties = this.getBlinkProperties_();
Blockly.utils.dom.createSvgElement('animate', blinkProperties,
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.ANIMATE, blinkProperties,
this.markerSvgLine_);
Blockly.utils.dom.createSvgElement('animate', blinkProperties,
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.ANIMATE, blinkProperties,
this.markerInput_);
blinkProperties['attributeName'] = 'stroke';
Blockly.utils.dom.createSvgElement('animate', blinkProperties,
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.ANIMATE, blinkProperties,
this.markerBlock_);
}

View File

@@ -46,7 +46,8 @@ Blockly.blockRendering.PathObject = function(root, style, constants) {
* @type {!SVGElement}
* @package
*/
this.svgPath = Blockly.utils.dom.createSvgElement('path',
this.svgPath = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATH,
{'class': 'blocklyPath'}, this.svgRoot);
/**

View File

@@ -48,7 +48,8 @@ Blockly.geras.PathObject = function(root, style, constants) {
* @type {SVGElement}
* @package
*/
this.svgPathDark = Blockly.utils.dom.createSvgElement('path',
this.svgPathDark = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATH,
{'class': 'blocklyPathDark', 'transform': 'translate(1,1)'},
this.svgRoot);
@@ -57,7 +58,8 @@ Blockly.geras.PathObject = function(root, style, constants) {
* @type {!SVGElement}
* @package
*/
this.svgPath = Blockly.utils.dom.createSvgElement('path',
this.svgPath = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATH,
{'class': 'blocklyPath'}, this.svgRoot);
/**
@@ -65,7 +67,8 @@ Blockly.geras.PathObject = function(root, style, constants) {
* @type {SVGElement}
* @package
*/
this.svgPathLight = Blockly.utils.dom.createSvgElement('path',
this.svgPathLight = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATH,
{'class': 'blocklyPathLight'}, this.svgRoot);
/**

View File

@@ -806,10 +806,12 @@ Blockly.zelos.ConstantProvider.prototype.createDom = function(svg,
... filters go here ...
</defs>
*/
var defs = Blockly.utils.dom.createSvgElement('defs', {}, svg);
var defs = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.DEFS, {}, svg);
// Using a dilate distorts the block shape.
// Instead use a gaussian blur, and then set all alpha to 1 with a transfer.
var selectedGlowFilter = Blockly.utils.dom.createSvgElement('filter',
var selectedGlowFilter = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FILTER,
{
'id': 'blocklySelectedGlowFilter' + this.randomIdentifier,
'height': '160%',
@@ -818,7 +820,8 @@ Blockly.zelos.ConstantProvider.prototype.createDom = function(svg,
x: '-40%'
},
defs);
Blockly.utils.dom.createSvgElement('feGaussianBlur',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEGAUSSIANBLUR,
{
'in': 'SourceGraphic',
'stdDeviation': this.SELECTED_GLOW_SIZE
@@ -826,21 +829,26 @@ Blockly.zelos.ConstantProvider.prototype.createDom = function(svg,
selectedGlowFilter);
// Set all gaussian blur pixels to 1 opacity before applying flood
var selectedComponentTransfer = Blockly.utils.dom.createSvgElement(
'feComponentTransfer', {'result': 'outBlur'}, selectedGlowFilter);
Blockly.utils.dom.createSvgElement('feFuncA',
Blockly.utils.dom.SvgElementType.FECOMPONENTTRANSFER, {
'result': 'outBlur'
}, selectedGlowFilter);
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEFUNCA,
{
'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'
},
selectedComponentTransfer);
// Color the highlight
Blockly.utils.dom.createSvgElement('feFlood',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEFLOOD,
{
'flood-color': this.SELECTED_GLOW_COLOUR,
'flood-opacity': 1,
'result': 'outColor'
},
selectedGlowFilter);
Blockly.utils.dom.createSvgElement('feComposite',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FECOMPOSITE,
{
'in': 'outColor', 'in2': 'outBlur',
'operator': 'in', 'result': 'outGlow'
@@ -851,7 +859,8 @@ Blockly.zelos.ConstantProvider.prototype.createDom = function(svg,
// Using a dilate distorts the block shape.
// Instead use a gaussian blur, and then set all alpha to 1 with a transfer.
var replacementGlowFilter = Blockly.utils.dom.createSvgElement('filter',
var replacementGlowFilter = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FILTER,
{
'id': 'blocklyReplacementGlowFilter' + this.randomIdentifier,
'height': '160%',
@@ -860,7 +869,8 @@ Blockly.zelos.ConstantProvider.prototype.createDom = function(svg,
x: '-40%'
},
defs);
Blockly.utils.dom.createSvgElement('feGaussianBlur',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEGAUSSIANBLUR,
{
'in': 'SourceGraphic',
'stdDeviation': this.REPLACEMENT_GLOW_SIZE
@@ -868,27 +878,33 @@ Blockly.zelos.ConstantProvider.prototype.createDom = function(svg,
replacementGlowFilter);
// Set all gaussian blur pixels to 1 opacity before applying flood
var replacementComponentTransfer = Blockly.utils.dom.createSvgElement(
'feComponentTransfer', {'result': 'outBlur'}, replacementGlowFilter);
Blockly.utils.dom.createSvgElement('feFuncA',
Blockly.utils.dom.SvgElementType.FECOMPONENTTRANSFER, {
'result': 'outBlur'
}, replacementGlowFilter);
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEFUNCA,
{
'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'
},
replacementComponentTransfer);
// Color the highlight
Blockly.utils.dom.createSvgElement('feFlood',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FEFLOOD,
{
'flood-color': this.REPLACEMENT_GLOW_COLOUR,
'flood-opacity': 1,
'result': 'outColor'
},
replacementGlowFilter);
Blockly.utils.dom.createSvgElement('feComposite',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FECOMPOSITE,
{
'in': 'outColor', 'in2': 'outBlur',
'operator': 'in', 'result': 'outGlow'
},
replacementGlowFilter);
Blockly.utils.dom.createSvgElement('feComposite',
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.FECOMPOSITE,
{
'in': 'SourceGraphic', 'in2': 'outGlow',
'operator': 'over',

View File

@@ -111,17 +111,19 @@ Blockly.zelos.MarkerSvg.prototype.createDomInternal_ = function() {
Blockly.zelos.MarkerSvg.superClass_.createDomInternal_.call(this);
this.markerCircle_ = Blockly.utils.dom.createSvgElement('circle', {
'r': this.constants_.CURSOR_RADIUS,
'style': 'display: none',
'stroke-width': this.constants_.CURSOR_STROKE_WIDTH
},
this.markerSvg_);
this.markerCircle_ = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.CIRCLE, {
'r': this.constants_.CURSOR_RADIUS,
'style': 'display: none',
'stroke-width': this.constants_.CURSOR_STROKE_WIDTH
},
this.markerSvg_);
// Markers and stack cursors don't blink.
if (this.isCursor()) {
var blinkProperties = this.getBlinkProperties_();
Blockly.utils.dom.createSvgElement('animate', blinkProperties,
Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.ANIMATE, blinkProperties,
this.markerCircle_);
}

View File

@@ -218,12 +218,13 @@ Blockly.zelos.PathObject.prototype.setOutlinePath = function(name, pathString) {
*/
Blockly.zelos.PathObject.prototype.getOutlinePath_ = function(name) {
if (!this.outlines_[name]) {
this.outlines_[name] = Blockly.utils.dom.createSvgElement('path', {
'class': 'blocklyOutlinePath',
// IE doesn't like paths without the data definition, set empty default
'd': ''
},
this.svgRoot);
this.outlines_[name] = Blockly.utils.dom.createSvgElement(
Blockly.utils.dom.SvgElementType.PATH, {
'class': 'blocklyOutlinePath',
// IE doesn't like paths without the data definition, set empty default
'd': ''
},
this.svgRoot);
}
if (this.remainingOutlines_) {
delete this.remainingOutlines_[name];