mirror of
https://github.com/google/blockly.git
synced 2026-01-08 01:20:12 +01:00
fix: Create CSS vars for SVG patterns. (#8671)
This commit is contained in:
@@ -106,11 +106,7 @@ export abstract class Bubble implements IBubble, ISelectable {
|
|||||||
);
|
);
|
||||||
const embossGroup = dom.createSvgElement(
|
const embossGroup = dom.createSvgElement(
|
||||||
Svg.G,
|
Svg.G,
|
||||||
{
|
{'class': 'blocklyEmboss'},
|
||||||
'filter': `url(#${
|
|
||||||
this.workspace.getRenderer().getConstants().embossFilterId
|
|
||||||
})`,
|
|
||||||
},
|
|
||||||
this.svgRoot,
|
this.svgRoot,
|
||||||
);
|
);
|
||||||
this.tail = dom.createSvgElement(
|
this.tail = dom.createSvgElement(
|
||||||
|
|||||||
@@ -85,6 +85,10 @@ let content = `
|
|||||||
transition: transform .5s;
|
transition: transform .5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blocklyEmboss {
|
||||||
|
filter: var(--blocklyEmbossFilter);
|
||||||
|
}
|
||||||
|
|
||||||
.blocklyTooltipDiv {
|
.blocklyTooltipDiv {
|
||||||
background-color: #ffffc7;
|
background-color: #ffffc7;
|
||||||
border: 1px solid #ddc;
|
border: 1px solid #ddc;
|
||||||
@@ -138,6 +142,10 @@ let content = `
|
|||||||
border-color: inherit;
|
border-color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blocklyHighlighted>.blocklyPath {
|
||||||
|
filter: var(--blocklyEmbossFilter);
|
||||||
|
}
|
||||||
|
|
||||||
.blocklyHighlightedConnectionPath {
|
.blocklyHighlightedConnectionPath {
|
||||||
fill: none;
|
fill: none;
|
||||||
stroke: #fc3;
|
stroke: #fc3;
|
||||||
@@ -189,6 +197,7 @@ let content = `
|
|||||||
}
|
}
|
||||||
|
|
||||||
.blocklyDisabled>.blocklyPath {
|
.blocklyDisabled>.blocklyPath {
|
||||||
|
fill: var(--blocklyDisabledPattern);
|
||||||
fill-opacity: .5;
|
fill-opacity: .5;
|
||||||
stroke-opacity: .5;
|
stroke-opacity: .5;
|
||||||
}
|
}
|
||||||
|
|||||||
15
core/grid.ts
15
core/grid.ts
@@ -210,6 +210,9 @@ export class Grid {
|
|||||||
* @param rnd A random ID to append to the pattern's ID.
|
* @param rnd A random ID to append to the pattern's ID.
|
||||||
* @param gridOptions The object containing grid configuration.
|
* @param gridOptions The object containing grid configuration.
|
||||||
* @param defs The root SVG element for this workspace's defs.
|
* @param defs The root SVG element for this workspace's defs.
|
||||||
|
* @param injectionDiv The div containing the parent workspace and all related
|
||||||
|
* workspaces and block containers. CSS variables representing SVG patterns
|
||||||
|
* will be scoped to this container.
|
||||||
* @returns The SVG element for the grid pattern.
|
* @returns The SVG element for the grid pattern.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
@@ -217,6 +220,7 @@ export class Grid {
|
|||||||
rnd: string,
|
rnd: string,
|
||||||
gridOptions: GridOptions,
|
gridOptions: GridOptions,
|
||||||
defs: SVGElement,
|
defs: SVGElement,
|
||||||
|
injectionDiv?: HTMLElement,
|
||||||
): SVGElement {
|
): SVGElement {
|
||||||
/*
|
/*
|
||||||
<pattern id="blocklyGridPattern837493" patternUnits="userSpaceOnUse">
|
<pattern id="blocklyGridPattern837493" patternUnits="userSpaceOnUse">
|
||||||
@@ -247,6 +251,17 @@ export class Grid {
|
|||||||
// Edge 16 doesn't handle empty patterns
|
// Edge 16 doesn't handle empty patterns
|
||||||
dom.createSvgElement(Svg.LINE, {}, gridPattern);
|
dom.createSvgElement(Svg.LINE, {}, gridPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (injectionDiv) {
|
||||||
|
// Add CSS variables scoped to the injection div referencing the created
|
||||||
|
// patterns so that CSS can apply the patterns to any element in the
|
||||||
|
// injection div.
|
||||||
|
injectionDiv.style.setProperty(
|
||||||
|
'--blocklyGridPattern',
|
||||||
|
`url(#${gridPattern.id})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return gridPattern;
|
return gridPattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export function inject(
|
|||||||
* @param options Dictionary of options.
|
* @param options Dictionary of options.
|
||||||
* @returns Newly created SVG image.
|
* @returns Newly created SVG image.
|
||||||
*/
|
*/
|
||||||
function createDom(container: Element, options: Options): SVGElement {
|
function createDom(container: HTMLElement, options: Options): SVGElement {
|
||||||
// Sadly browsers (Chrome vs Firefox) are currently inconsistent in laying
|
// Sadly browsers (Chrome vs Firefox) are currently inconsistent in laying
|
||||||
// out content in RTL mode. Therefore Blockly forces the use of LTR,
|
// out content in RTL mode. Therefore Blockly forces the use of LTR,
|
||||||
// then manually positions content in RTL as needed.
|
// then manually positions content in RTL as needed.
|
||||||
@@ -132,7 +132,12 @@ function createDom(container: Element, options: Options): SVGElement {
|
|||||||
// https://neil.fraser.name/news/2015/11/01/
|
// https://neil.fraser.name/news/2015/11/01/
|
||||||
const rnd = String(Math.random()).substring(2);
|
const rnd = String(Math.random()).substring(2);
|
||||||
|
|
||||||
options.gridPattern = Grid.createDom(rnd, options.gridOptions, defs);
|
options.gridPattern = Grid.createDom(
|
||||||
|
rnd,
|
||||||
|
options.gridOptions,
|
||||||
|
defs,
|
||||||
|
container,
|
||||||
|
);
|
||||||
return svg;
|
return svg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +149,7 @@ function createDom(container: Element, options: Options): SVGElement {
|
|||||||
* @returns Newly created main workspace.
|
* @returns Newly created main workspace.
|
||||||
*/
|
*/
|
||||||
function createMainWorkspace(
|
function createMainWorkspace(
|
||||||
injectionDiv: Element,
|
injectionDiv: HTMLElement,
|
||||||
svg: SVGElement,
|
svg: SVGElement,
|
||||||
options: Options,
|
options: Options,
|
||||||
): WorkspaceSvg {
|
): WorkspaceSvg {
|
||||||
|
|||||||
@@ -926,8 +926,18 @@ export class ConstantProvider {
|
|||||||
* @param svg The root of the workspace's SVG.
|
* @param svg The root of the workspace's SVG.
|
||||||
* @param tagName The name to use for the CSS style tag.
|
* @param tagName The name to use for the CSS style tag.
|
||||||
* @param selector The CSS selector to use.
|
* @param selector The CSS selector to use.
|
||||||
|
* @param injectionDivIfIsParent The div containing the parent workspace and
|
||||||
|
* all related workspaces and block containers, if this renderer is for the
|
||||||
|
* parent workspace. CSS variables representing SVG patterns will be scoped
|
||||||
|
* to this container. Child workspaces should not override the CSS variables
|
||||||
|
* created by the parent and thus do not need access to the injection div.
|
||||||
*/
|
*/
|
||||||
createDom(svg: SVGElement, tagName: string, selector: string) {
|
createDom(
|
||||||
|
svg: SVGElement,
|
||||||
|
tagName: string,
|
||||||
|
selector: string,
|
||||||
|
injectionDivIfIsParent?: HTMLElement,
|
||||||
|
) {
|
||||||
this.injectCSS_(tagName, selector);
|
this.injectCSS_(tagName, selector);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1034,6 +1044,24 @@ export class ConstantProvider {
|
|||||||
this.disabledPattern = disabledPattern;
|
this.disabledPattern = disabledPattern;
|
||||||
|
|
||||||
this.createDebugFilter();
|
this.createDebugFilter();
|
||||||
|
|
||||||
|
if (injectionDivIfIsParent) {
|
||||||
|
// If this renderer is for the parent workspace, add CSS variables scoped
|
||||||
|
// to the injection div referencing the created patterns so that CSS can
|
||||||
|
// apply the patterns to any element in the injection div.
|
||||||
|
injectionDivIfIsParent.style.setProperty(
|
||||||
|
'--blocklyEmbossFilter',
|
||||||
|
`url(#${this.embossFilterId})`,
|
||||||
|
);
|
||||||
|
injectionDivIfIsParent.style.setProperty(
|
||||||
|
'--blocklyDisabledPattern',
|
||||||
|
`url(#${this.disabledPatternId})`,
|
||||||
|
);
|
||||||
|
injectionDivIfIsParent.style.setProperty(
|
||||||
|
'--blocklyDebugFilter',
|
||||||
|
`url(#${this.debugFilterId})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -173,13 +173,8 @@ export class PathObject implements IPathObject {
|
|||||||
|
|
||||||
updateHighlighted(enable: boolean) {
|
updateHighlighted(enable: boolean) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
this.svgPath.setAttribute(
|
|
||||||
'filter',
|
|
||||||
'url(#' + this.constants.embossFilterId + ')',
|
|
||||||
);
|
|
||||||
this.setClass_('blocklyHighlighted', true);
|
this.setClass_('blocklyHighlighted', true);
|
||||||
} else {
|
} else {
|
||||||
this.svgPath.setAttribute('filter', 'none');
|
|
||||||
this.setClass_('blocklyHighlighted', false);
|
this.setClass_('blocklyHighlighted', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,12 +201,6 @@ export class PathObject implements IPathObject {
|
|||||||
*/
|
*/
|
||||||
protected updateDisabled_(disabled: boolean) {
|
protected updateDisabled_(disabled: boolean) {
|
||||||
this.setClass_('blocklyDisabled', disabled);
|
this.setClass_('blocklyDisabled', disabled);
|
||||||
if (disabled) {
|
|
||||||
this.svgPath.setAttribute(
|
|
||||||
'fill',
|
|
||||||
'url(#' + this.constants.disabledPatternId + ')',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -78,13 +78,23 @@ export class Renderer implements IRegistrable {
|
|||||||
*
|
*
|
||||||
* @param svg The root of the workspace's SVG.
|
* @param svg The root of the workspace's SVG.
|
||||||
* @param theme The workspace theme object.
|
* @param theme The workspace theme object.
|
||||||
|
* @param injectionDivIfIsParent The div containing the parent workspace and
|
||||||
|
* all related workspaces and block containers, if this renderer is for the
|
||||||
|
* parent workspace. CSS variables representing SVG patterns will be scoped
|
||||||
|
* to this container. Child workspaces should not override the CSS variables
|
||||||
|
* created by the parent and thus do not need access to the injection div.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
createDom(svg: SVGElement, theme: Theme) {
|
createDom(
|
||||||
|
svg: SVGElement,
|
||||||
|
theme: Theme,
|
||||||
|
injectionDivIfIsParent?: HTMLElement,
|
||||||
|
) {
|
||||||
this.constants_.createDom(
|
this.constants_.createDom(
|
||||||
svg,
|
svg,
|
||||||
this.name + '-' + theme.name,
|
this.name + '-' + theme.name,
|
||||||
'.' + this.getClassName() + '.' + theme.getClassName(),
|
'.' + this.getClassName() + '.' + theme.getClassName(),
|
||||||
|
injectionDivIfIsParent,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,8 +103,17 @@ export class Renderer implements IRegistrable {
|
|||||||
*
|
*
|
||||||
* @param svg The root of the workspace's SVG.
|
* @param svg The root of the workspace's SVG.
|
||||||
* @param theme The workspace theme object.
|
* @param theme The workspace theme object.
|
||||||
|
* @param injectionDivIfIsParent The div containing the parent workspace and
|
||||||
|
* all related workspaces and block containers, if this renderer is for the
|
||||||
|
* parent workspace. CSS variables representing SVG patterns will be scoped
|
||||||
|
* to this container. Child workspaces should not override the CSS variables
|
||||||
|
* created by the parent and thus do not need access to the injection div.
|
||||||
*/
|
*/
|
||||||
refreshDom(svg: SVGElement, theme: Theme) {
|
refreshDom(
|
||||||
|
svg: SVGElement,
|
||||||
|
theme: Theme,
|
||||||
|
injectionDivIfIsParent?: HTMLElement,
|
||||||
|
) {
|
||||||
const previousConstants = this.getConstants();
|
const previousConstants = this.getConstants();
|
||||||
previousConstants.dispose();
|
previousConstants.dispose();
|
||||||
this.constants_ = this.makeConstants_();
|
this.constants_ = this.makeConstants_();
|
||||||
@@ -105,7 +124,7 @@ export class Renderer implements IRegistrable {
|
|||||||
this.constants_.randomIdentifier = previousConstants.randomIdentifier;
|
this.constants_.randomIdentifier = previousConstants.randomIdentifier;
|
||||||
this.constants_.setTheme(theme);
|
this.constants_.setTheme(theme);
|
||||||
this.constants_.init();
|
this.constants_.init();
|
||||||
this.createDom(svg, theme);
|
this.createDom(svg, theme, injectionDivIfIsParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -50,8 +50,12 @@ export class Renderer extends BaseRenderer {
|
|||||||
this.highlightConstants.init();
|
this.highlightConstants.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
override refreshDom(svg: SVGElement, theme: Theme) {
|
override refreshDom(
|
||||||
super.refreshDom(svg, theme);
|
svg: SVGElement,
|
||||||
|
theme: Theme,
|
||||||
|
injectionDiv: HTMLElement,
|
||||||
|
) {
|
||||||
|
super.refreshDom(svg, theme, injectionDiv);
|
||||||
this.getHighlightConstants().init();
|
this.getHighlightConstants().init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -675,8 +675,13 @@ export class ConstantProvider extends BaseConstantProvider {
|
|||||||
return utilsColour.blend('#000', colour, 0.25) || colour;
|
return utilsColour.blend('#000', colour, 0.25) || colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
override createDom(svg: SVGElement, tagName: string, selector: string) {
|
override createDom(
|
||||||
super.createDom(svg, tagName, selector);
|
svg: SVGElement,
|
||||||
|
tagName: string,
|
||||||
|
selector: string,
|
||||||
|
injectionDivIfIsParent?: HTMLElement,
|
||||||
|
) {
|
||||||
|
super.createDom(svg, tagName, selector, injectionDivIfIsParent);
|
||||||
/*
|
/*
|
||||||
<defs>
|
<defs>
|
||||||
... filters go here ...
|
... filters go here ...
|
||||||
@@ -795,6 +800,20 @@ export class ConstantProvider extends BaseConstantProvider {
|
|||||||
);
|
);
|
||||||
this.replacementGlowFilterId = replacementGlowFilter.id;
|
this.replacementGlowFilterId = replacementGlowFilter.id;
|
||||||
this.replacementGlowFilter = replacementGlowFilter;
|
this.replacementGlowFilter = replacementGlowFilter;
|
||||||
|
|
||||||
|
if (injectionDivIfIsParent) {
|
||||||
|
// If this renderer is for the parent workspace, add CSS variables scoped
|
||||||
|
// to the injection div referencing the created patterns so that CSS can
|
||||||
|
// apply the patterns to any element in the injection div.
|
||||||
|
injectionDivIfIsParent.style.setProperty(
|
||||||
|
'--blocklySelectedGlowFilter',
|
||||||
|
`url(#${this.selectedGlowFilterId})`,
|
||||||
|
);
|
||||||
|
injectionDivIfIsParent.style.setProperty(
|
||||||
|
'--blocklyReplacementGlowFilter',
|
||||||
|
`url(#${this.replacementGlowFilterId})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override getCSS_(selector: string) {
|
override getCSS_(selector: string) {
|
||||||
@@ -873,7 +892,7 @@ export class ConstantProvider extends BaseConstantProvider {
|
|||||||
|
|
||||||
// Disabled outline paths.
|
// Disabled outline paths.
|
||||||
`${selector} .blocklyDisabled > .blocklyOutlinePath {`,
|
`${selector} .blocklyDisabled > .blocklyOutlinePath {`,
|
||||||
`fill: url(#blocklyDisabledPattern${this.randomIdentifier})`,
|
`fill: var(--blocklyDisabledPattern)`,
|
||||||
`}`,
|
`}`,
|
||||||
|
|
||||||
// Insertion marker.
|
// Insertion marker.
|
||||||
@@ -881,6 +900,15 @@ export class ConstantProvider extends BaseConstantProvider {
|
|||||||
`fill-opacity: ${this.INSERTION_MARKER_OPACITY};`,
|
`fill-opacity: ${this.INSERTION_MARKER_OPACITY};`,
|
||||||
`stroke: none;`,
|
`stroke: none;`,
|
||||||
`}`,
|
`}`,
|
||||||
|
|
||||||
|
`${selector} .blocklySelected>.blocklyPath.blocklyPathSelected {`,
|
||||||
|
`fill: none;`,
|
||||||
|
`filter: var(--blocklySelectedGlowFilter);`,
|
||||||
|
`}`,
|
||||||
|
|
||||||
|
`${selector} .blocklyReplaceable>.blocklyPath {`,
|
||||||
|
`filter: var(--blocklyReplacementGlowFilter);`,
|
||||||
|
`}`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,11 +91,7 @@ export class PathObject extends BasePathObject {
|
|||||||
if (enable) {
|
if (enable) {
|
||||||
if (!this.svgPathSelected) {
|
if (!this.svgPathSelected) {
|
||||||
this.svgPathSelected = this.svgPath.cloneNode(true) as SVGElement;
|
this.svgPathSelected = this.svgPath.cloneNode(true) as SVGElement;
|
||||||
this.svgPathSelected.setAttribute('fill', 'none');
|
this.svgPathSelected.classList.add('blocklyPathSelected');
|
||||||
this.svgPathSelected.setAttribute(
|
|
||||||
'filter',
|
|
||||||
'url(#' + this.constants.selectedGlowFilterId + ')',
|
|
||||||
);
|
|
||||||
this.svgRoot.appendChild(this.svgPathSelected);
|
this.svgRoot.appendChild(this.svgPathSelected);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -108,14 +104,6 @@ export class PathObject extends BasePathObject {
|
|||||||
|
|
||||||
override updateReplacementFade(enable: boolean) {
|
override updateReplacementFade(enable: boolean) {
|
||||||
this.setClass_('blocklyReplaceable', enable);
|
this.setClass_('blocklyReplaceable', enable);
|
||||||
if (enable) {
|
|
||||||
this.svgPath.setAttribute(
|
|
||||||
'filter',
|
|
||||||
'url(#' + this.constants.replacementGlowFilterId + ')',
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.svgPath.removeAttribute('filter');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override updateShapeForInputHighlight(conn: Connection, enable: boolean) {
|
override updateShapeForInputHighlight(conn: Connection, enable: boolean) {
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
|||||||
* The first parent div with 'injectionDiv' in the name, or null if not set.
|
* The first parent div with 'injectionDiv' in the name, or null if not set.
|
||||||
* Access this with getInjectionDiv.
|
* Access this with getInjectionDiv.
|
||||||
*/
|
*/
|
||||||
private injectionDiv: Element | null = null;
|
private injectionDiv: HTMLElement | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Last known position of the page scroll.
|
* Last known position of the page scroll.
|
||||||
@@ -539,7 +539,12 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
|||||||
*/
|
*/
|
||||||
refreshTheme() {
|
refreshTheme() {
|
||||||
if (this.svgGroup_) {
|
if (this.svgGroup_) {
|
||||||
this.renderer.refreshDom(this.svgGroup_, this.getTheme());
|
const isParentWorkspace = this.options.parentWorkspace === null;
|
||||||
|
this.renderer.refreshDom(
|
||||||
|
this.svgGroup_,
|
||||||
|
this.getTheme(),
|
||||||
|
isParentWorkspace ? this.getInjectionDiv() : undefined,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update all blocks in workspace that have a style name.
|
// Update all blocks in workspace that have a style name.
|
||||||
@@ -636,20 +641,24 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
|||||||
// Before the SVG canvas, scale the coordinates.
|
// Before the SVG canvas, scale the coordinates.
|
||||||
scale = this.scale;
|
scale = this.scale;
|
||||||
}
|
}
|
||||||
|
let ancestor: Element = element;
|
||||||
do {
|
do {
|
||||||
// Loop through this block and every parent.
|
// Loop through this block and every parent.
|
||||||
const xy = svgMath.getRelativeXY(element);
|
const xy = svgMath.getRelativeXY(ancestor);
|
||||||
if (element === this.getCanvas() || element === this.getBubbleCanvas()) {
|
if (
|
||||||
|
ancestor === this.getCanvas() ||
|
||||||
|
ancestor === this.getBubbleCanvas()
|
||||||
|
) {
|
||||||
// After the SVG canvas, don't scale the coordinates.
|
// After the SVG canvas, don't scale the coordinates.
|
||||||
scale = 1;
|
scale = 1;
|
||||||
}
|
}
|
||||||
x += xy.x * scale;
|
x += xy.x * scale;
|
||||||
y += xy.y * scale;
|
y += xy.y * scale;
|
||||||
element = element.parentNode as SVGElement;
|
ancestor = ancestor.parentNode as Element;
|
||||||
} while (
|
} while (
|
||||||
element &&
|
ancestor &&
|
||||||
element !== this.getParentSvg() &&
|
ancestor !== this.getParentSvg() &&
|
||||||
element !== this.getInjectionDiv()
|
ancestor !== this.getInjectionDiv()
|
||||||
);
|
);
|
||||||
return new Coordinate(x, y);
|
return new Coordinate(x, y);
|
||||||
}
|
}
|
||||||
@@ -687,7 +696,7 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
|||||||
* @returns The first parent div with 'injectionDiv' in the name.
|
* @returns The first parent div with 'injectionDiv' in the name.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
getInjectionDiv(): Element {
|
getInjectionDiv(): HTMLElement {
|
||||||
// NB: it would be better to pass this in at createDom, but is more likely
|
// NB: it would be better to pass this in at createDom, but is more likely
|
||||||
// to break existing uses of Blockly.
|
// to break existing uses of Blockly.
|
||||||
if (!this.injectionDiv) {
|
if (!this.injectionDiv) {
|
||||||
@@ -695,7 +704,7 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
|||||||
while (element) {
|
while (element) {
|
||||||
const classes = element.getAttribute('class') || '';
|
const classes = element.getAttribute('class') || '';
|
||||||
if ((' ' + classes + ' ').includes(' injectionDiv ')) {
|
if ((' ' + classes + ' ').includes(' injectionDiv ')) {
|
||||||
this.injectionDiv = element;
|
this.injectionDiv = element as HTMLElement;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
element = element.parentNode as Element;
|
element = element.parentNode as Element;
|
||||||
@@ -739,7 +748,7 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
|||||||
* 'blocklyMutatorBackground'.
|
* 'blocklyMutatorBackground'.
|
||||||
* @returns The workspace's SVG group.
|
* @returns The workspace's SVG group.
|
||||||
*/
|
*/
|
||||||
createDom(opt_backgroundClass?: string, injectionDiv?: Element): Element {
|
createDom(opt_backgroundClass?: string, injectionDiv?: HTMLElement): Element {
|
||||||
if (!this.injectionDiv) {
|
if (!this.injectionDiv) {
|
||||||
this.injectionDiv = injectionDiv ?? null;
|
this.injectionDiv = injectionDiv ?? null;
|
||||||
}
|
}
|
||||||
@@ -765,8 +774,7 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (opt_backgroundClass === 'blocklyMainBackground' && this.grid) {
|
if (opt_backgroundClass === 'blocklyMainBackground' && this.grid) {
|
||||||
this.svgBackground_.style.fill =
|
this.svgBackground_.style.fill = 'var(--blocklyGridPattern)';
|
||||||
'url(#' + this.grid.getPatternId() + ')';
|
|
||||||
} else {
|
} else {
|
||||||
this.themeManager_.subscribe(
|
this.themeManager_.subscribe(
|
||||||
this.svgBackground_,
|
this.svgBackground_,
|
||||||
@@ -823,7 +831,12 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
|||||||
|
|
||||||
CursorClass && this.markerManager.setCursor(new CursorClass());
|
CursorClass && this.markerManager.setCursor(new CursorClass());
|
||||||
|
|
||||||
this.renderer.createDom(this.svgGroup_, this.getTheme());
|
const isParentWorkspace = this.options.parentWorkspace === null;
|
||||||
|
this.renderer.createDom(
|
||||||
|
this.svgGroup_,
|
||||||
|
this.getTheme(),
|
||||||
|
isParentWorkspace ? this.getInjectionDiv() : undefined,
|
||||||
|
);
|
||||||
return this.svgGroup_;
|
return this.svgGroup_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user