mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
CSS in renderers (#3446)
* Have each renderer declare some CSS that is specific to the renderer.
This commit is contained in:
29
core/css.js
29
core/css.js
@@ -77,6 +77,7 @@ Blockly.Css.inject = function(hasCss, pathToMedia) {
|
||||
|
||||
// Inject CSS tag at start of head.
|
||||
var cssNode = document.createElement('style');
|
||||
cssNode.id = 'blockly-common-style';
|
||||
var cssTextNode = document.createTextNode(text);
|
||||
cssNode.appendChild(cssTextNode);
|
||||
document.head.insertBefore(cssNode, document.head.firstChild);
|
||||
@@ -254,11 +255,6 @@ Blockly.Css.CONTENT = [
|
||||
'stroke-width: 1;',
|
||||
'}',
|
||||
|
||||
'.injectionDiv:not(.zelos-renderer) .blocklySelected>.blocklyPath {',
|
||||
'stroke: #fc3;',
|
||||
'stroke-width: 3px;',
|
||||
'}',
|
||||
|
||||
'.blocklySelected>.blocklyPathLight {',
|
||||
'display: none;',
|
||||
'}',
|
||||
@@ -334,13 +330,6 @@ Blockly.Css.CONTENT = [
|
||||
'display: none;',
|
||||
'}',
|
||||
|
||||
'.blocklyText {',
|
||||
'cursor: default;',
|
||||
'fill: #fff;',
|
||||
'font-family: sans-serif;',
|
||||
'font-size: 11pt;',
|
||||
'}',
|
||||
|
||||
'.blocklyMultilineText {',
|
||||
'font-family: monospace;',
|
||||
'}',
|
||||
@@ -349,22 +338,6 @@ Blockly.Css.CONTENT = [
|
||||
'pointer-events: none;',
|
||||
'}',
|
||||
|
||||
'.blocklyNonEditableText>rect,',
|
||||
'.blocklyEditableText>rect {',
|
||||
'fill: #fff;',
|
||||
'fill-opacity: .6;',
|
||||
'}',
|
||||
|
||||
'.blocklyNonEditableText>text,',
|
||||
'.blocklyEditableText>text {',
|
||||
'fill: #000;',
|
||||
'}',
|
||||
|
||||
'.blocklyEditableText:not(.editing):hover>rect {',
|
||||
'stroke: #fff;',
|
||||
'stroke-width: 2;',
|
||||
'}',
|
||||
|
||||
'.blocklyBubbleText {',
|
||||
'fill: #000;',
|
||||
'}',
|
||||
|
||||
@@ -101,15 +101,16 @@ Blockly.blockRendering.init = function(name) {
|
||||
/**
|
||||
* Wrap the renderer constructor into a temporary constructor
|
||||
* function so the closure compiler treats it as a constructor.
|
||||
* @param {string} name The renderer name.
|
||||
* @constructor
|
||||
* @extends {Blockly.blockRendering.Renderer}
|
||||
*/
|
||||
var rendererCtor = function() {
|
||||
rendererCtor.superClass_.constructor.call(this);
|
||||
var rendererCtor = function(name) {
|
||||
rendererCtor.superClass_.constructor.call(this, name);
|
||||
};
|
||||
Blockly.utils.object.inherits(rendererCtor,
|
||||
Blockly.blockRendering.rendererMap_[name]);
|
||||
var renderer = new rendererCtor();
|
||||
var renderer = new rendererCtor(name);
|
||||
renderer.init();
|
||||
return renderer;
|
||||
};
|
||||
|
||||
@@ -161,7 +161,6 @@ Blockly.blockRendering.ConstantProvider = function() {
|
||||
/**
|
||||
* Point size of text. Should match blocklyText's font-size in CSS.
|
||||
* @type {number}
|
||||
* @const
|
||||
*/
|
||||
this.FIELD_TEXT_FONTSIZE = 11;
|
||||
|
||||
@@ -174,14 +173,12 @@ Blockly.blockRendering.ConstantProvider = function() {
|
||||
/**
|
||||
* Text font weight. Should match blocklyText's font-weight in CSS.
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
this.FIELD_TEXT_FONTWEIGHT = 'normal';
|
||||
|
||||
/**
|
||||
* Text font family. Should match blocklyText's font-family in CSS.
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
this.FIELD_TEXT_FONTFAMILY = 'sans-serif';
|
||||
|
||||
|
||||
@@ -35,10 +35,18 @@ goog.requireType('Blockly.blockRendering.Debug');
|
||||
|
||||
/**
|
||||
* The base class for a block renderer.
|
||||
* @param {string} name The renderer name.
|
||||
* @package
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.blockRendering.Renderer = function() {
|
||||
Blockly.blockRendering.Renderer = function(name) {
|
||||
|
||||
/**
|
||||
* The renderer name.
|
||||
* @type {string}
|
||||
* @protected
|
||||
*/
|
||||
this.name_ = name;
|
||||
|
||||
/**
|
||||
* The renderer's constant provider.
|
||||
@@ -55,6 +63,7 @@ Blockly.blockRendering.Renderer = function() {
|
||||
Blockly.blockRendering.Renderer.prototype.init = function() {
|
||||
this.constants_ = this.makeConstants_();
|
||||
this.constants_.init();
|
||||
this.injectCSS_(this.getCSS_());
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -139,6 +148,66 @@ Blockly.blockRendering.Renderer.prototype.getConstants = function() {
|
||||
(this.constants_));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get any renderer specific CSS to inject when the renderer is initialized.
|
||||
* @return {!Array.<string>} Array of CSS strings.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.blockRendering.Renderer.prototype.getCSS_ = function() {
|
||||
var selector = '.' + this.name_ + '-renderer';
|
||||
var constants = this.getConstants();
|
||||
return [
|
||||
/* eslint-disable indent */
|
||||
selector + ' .blocklyText {',
|
||||
'cursor: default;',
|
||||
'fill: #fff;',
|
||||
'font-family: ' + constants.FIELD_TEXT_FONTFAMILY + ';',
|
||||
'font-size: ' + constants.FIELD_TEXT_FONTSIZE + 'pt;',
|
||||
'font-weight: ' + constants.FIELD_TEXT_FONTWEIGHT + ';',
|
||||
'}',
|
||||
selector + ' .blocklyNonEditableText>rect,',
|
||||
selector + ' .blocklyEditableText>rect {',
|
||||
'fill: #fff;',
|
||||
'fill-opacity: .6;',
|
||||
'}',
|
||||
|
||||
selector + ' .blocklyNonEditableText>text,',
|
||||
selector + ' .blocklyEditableText>text {',
|
||||
'fill: #000;',
|
||||
'}',
|
||||
|
||||
selector + ' .blocklyEditableText:not(.editing):hover>rect {',
|
||||
'stroke: #fff;',
|
||||
'stroke-width: 2;',
|
||||
'}',
|
||||
selector + ' .blocklySelected>.blocklyPath {',
|
||||
'stroke: #fc3;',
|
||||
'stroke-width: 3px;',
|
||||
'}',
|
||||
/* eslint-enable indent */
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get any renderer specific CSS to inject when the renderer is initialized.
|
||||
* @param {!Array.<string>} cssArray Array of CSS strings.
|
||||
* @private
|
||||
*/
|
||||
Blockly.blockRendering.Renderer.prototype.injectCSS_ = function(cssArray) {
|
||||
var cssNodeId = 'blockly-renderer-style-' + this.name_;
|
||||
if (document.getElementById(cssNodeId)) {
|
||||
// Already injected.
|
||||
return;
|
||||
}
|
||||
var text = cssArray.join('\n');
|
||||
// Inject CSS tag at start of head.
|
||||
var cssNode = document.createElement('style');
|
||||
cssNode.id = cssNodeId;
|
||||
var cssTextNode = document.createTextNode(text);
|
||||
cssNode.appendChild(cssTextNode);
|
||||
document.head.insertBefore(cssNode, document.head.firstChild);
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine whether or not to highlight a connection.
|
||||
* @param {Blockly.Connection} _conn The connection to determine whether or not
|
||||
|
||||
@@ -35,12 +35,13 @@ goog.require('Blockly.utils.object');
|
||||
|
||||
/**
|
||||
* The geras renderer.
|
||||
* @param {string} name The renderer name.
|
||||
* @package
|
||||
* @constructor
|
||||
* @extends {Blockly.blockRendering.Renderer}
|
||||
*/
|
||||
Blockly.geras.Renderer = function() {
|
||||
Blockly.geras.Renderer.superClass_.constructor.call(this);
|
||||
Blockly.geras.Renderer = function(name) {
|
||||
Blockly.geras.Renderer.superClass_.constructor.call(this, name);
|
||||
|
||||
/**
|
||||
* The renderer's highlight constant provider.
|
||||
|
||||
@@ -30,12 +30,13 @@ goog.require('Blockly.utils.object');
|
||||
|
||||
/**
|
||||
* The thrasos renderer.
|
||||
* @param {string} name The renderer name.
|
||||
* @package
|
||||
* @constructor
|
||||
* @extends {Blockly.blockRendering.Renderer}
|
||||
*/
|
||||
Blockly.thrasos.Renderer = function() {
|
||||
Blockly.thrasos.Renderer.superClass_.constructor.call(this);
|
||||
Blockly.thrasos.Renderer = function(name) {
|
||||
Blockly.thrasos.Renderer.superClass_.constructor.call(this, name);
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.thrasos.Renderer,
|
||||
Blockly.blockRendering.Renderer);
|
||||
|
||||
@@ -159,6 +159,16 @@ Blockly.zelos.ConstantProvider = function() {
|
||||
*/
|
||||
this.FULL_BLOCK_FIELDS = true;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.FIELD_TEXT_FONTSIZE = 12;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.FIELD_TEXT_FONTWEIGHT = 'bold';
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
|
||||
@@ -35,12 +35,13 @@ goog.require('Blockly.zelos.CursorSvg');
|
||||
|
||||
/**
|
||||
* The zelos renderer.
|
||||
* @param {string} name The renderer name.
|
||||
* @package
|
||||
* @constructor
|
||||
* @extends {Blockly.blockRendering.Renderer}
|
||||
*/
|
||||
Blockly.zelos.Renderer = function() {
|
||||
Blockly.zelos.Renderer.superClass_.constructor.call(this);
|
||||
Blockly.zelos.Renderer = function(name) {
|
||||
Blockly.zelos.Renderer.superClass_.constructor.call(this, name);
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.zelos.Renderer,
|
||||
Blockly.blockRendering.Renderer);
|
||||
@@ -122,4 +123,27 @@ Blockly.zelos.Renderer.prototype.shouldInsertDraggedBlock = function(_block,
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.zelos.Renderer.prototype.getCSS_ = function() {
|
||||
var selector = '.' + this.name_ + '-renderer';
|
||||
var constants = this.getConstants();
|
||||
return [
|
||||
/* eslint-disable indent */
|
||||
selector + ' .blocklyText {',
|
||||
'cursor: default;',
|
||||
'fill: #fff;',
|
||||
'font-family: ' + constants.FIELD_TEXT_FONTFAMILY + ';',
|
||||
'font-size: ' + constants.FIELD_TEXT_FONTSIZE + 'pt;',
|
||||
'font-weight: ' + constants.FIELD_TEXT_FONTWEIGHT + ';',
|
||||
'}',
|
||||
|
||||
selector + ' .blocklyDropdownText {',
|
||||
'fill: #fff !important;',
|
||||
'}',
|
||||
/* eslint-enable indent */
|
||||
];
|
||||
};
|
||||
|
||||
Blockly.blockRendering.register('zelos', Blockly.zelos.Renderer);
|
||||
|
||||
@@ -80,15 +80,19 @@ function workspaceToSvg_(workspace, callback, customCss) {
|
||||
svg.setAttribute('viewBox',
|
||||
x + ' ' + y + ' ' + width + ' ' + height);
|
||||
|
||||
svg.setAttribute('class', 'blocklySvg');
|
||||
svg.setAttribute('class', 'blocklySvg ' +
|
||||
(workspace.options.renderer || 'geras') + '-renderer ' +
|
||||
(workspace.getTheme ? workspace.getTheme().name + '-theme' : ''));
|
||||
svg.setAttribute('width', width);
|
||||
svg.setAttribute('height', height);
|
||||
svg.setAttribute("style", 'background-color: transparent');
|
||||
|
||||
var css = [].slice.call(document.head.querySelectorAll('style'))
|
||||
.filter(function(el) { return /\.blocklySvg/.test(el.innerText); })[0];
|
||||
.filter(function(el) { return /\.blocklySvg/.test(el.innerText) ||
|
||||
(el.id.indexOf('blockly-') === 0); }).map(function(el) {
|
||||
return el.innerText; }).join('\n');
|
||||
var style = document.createElement('style');
|
||||
style.innerHTML = css.innerText + '\n' + customCss;
|
||||
style.innerHTML = css + '\n' + customCss;
|
||||
svg.insertBefore(style, svg.firstChild);
|
||||
|
||||
var svgAsXML = (new XMLSerializer).serializeToString(svg);
|
||||
|
||||
Reference in New Issue
Block a user