chore: import upstream snapshot with attribution
RequirementsTest / build (windows-latest, 3.9) (push) Has been cancelled
RequirementsTest / build (macos-latest, 3.9) (push) Has been cancelled
RequirementsTest / build (ubuntu-latest, 3.9) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Pylint / build (3.9) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:18:32 +08:00
commit f0dfbfc3d7
1306 changed files with 364980 additions and 0 deletions
+525
View File
@@ -0,0 +1,525 @@
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Gulp script to build Blockly for Node & NPM.
*/
var gulp = require('gulp');
gulp.replace = require('gulp-replace');
gulp.rename = require('gulp-rename');
gulp.sourcemaps = require('gulp-sourcemaps');
var path = require('path');
var fs = require('fs');
var execSync = require('child_process').execSync;
var through2 = require('through2');
var closureCompiler = require('google-closure-compiler').gulp();
var closureDeps = require('google-closure-deps');
var packageJson = require('../../package.json');
var argv = require('yargs').argv;
////////////////////////////////////////////////////////////
// Build //
////////////////////////////////////////////////////////////
const licenseRegex = `\\/\\*\\*
\\* @license
\\* (Copyright \\d+ (Google LLC|Massachusetts Institute of Technology))
( \\* All rights reserved.
)? \\* SPDX-License-Identifier: Apache-2.0
\\*\\/`;
/**
* Helper method for stripping the Google's and MIT's Apache Licenses.
*/
function stripApacheLicense() {
// Strip out Google's and MIT's Apache licences.
// Closure Compiler preserves dozens of Apache licences in the Blockly code.
// Remove these if they belong to Google or MIT.
// MIT's permission to do this is logged in Blockly issue #2412.
return gulp.replace(new RegExp(licenseRegex, "g"), '\n\n\n\n');
// Replace with the same number of lines so that source-maps are not affected.
}
/**
* Closure compiler warning groups used to treat warnings as errors.
* For a full list of closure compiler groups, consult:
* https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/DiagnosticGroups.java#L113
*/
var JSCOMP_ERROR = [
'accessControls',
'checkPrototypalTypes',
'checkRegExp',
'checkTypes',
'checkVars',
'conformanceViolations',
'const',
'constantProperty',
'deprecated',
'deprecatedAnnotations',
'duplicateMessage',
'es5Strict',
'externsValidation',
'functionParams',
'globalThis',
'invalidCasts',
'misplacedTypeAnnotation',
// 'missingOverride',
'missingPolyfill',
'missingProperties',
'missingProvide',
'missingRequire',
'missingReturn',
// 'missingSourcesWarnings',
'moduleLoad',
'msgDescriptions',
'nonStandardJsDocs',
// 'polymer',
// 'reportUnknownTypes',
// 'strictCheckTypes',
// 'strictMissingProperties',
'strictModuleDepCheck',
// 'strictPrimitiveOperators',
// 'stricterMissingRequire',
'suspiciousCode',
'typeInvalidation',
'undefinedNames',
'undefinedVars',
'underscore',
'unknownDefines',
'unusedLocalVariables',
'unusedPrivateMembers',
'uselessCode',
'untranspilableFeatures',
'visibility'
];
/**
* Helper method for calling the Closure compiler.
* @param {*} compilerOptions
* @param {boolean=} opt_verbose Optional option for verbose logging
* @param {boolean=} opt_warnings_as_error Optional option for treating warnings
* as errors.
* @param {boolean=} opt_strict_typechecker Optional option for enabling strict
* type checking.
*/
function compile(compilerOptions, opt_verbose, opt_warnings_as_error,
opt_strict_typechecker) {
const options = {};
options.compilation_level = 'SIMPLE_OPTIMIZATIONS';
options.warning_level = opt_verbose ? 'VERBOSE' : 'DEFAULT';
options.language_in = 'ECMASCRIPT5_STRICT';
options.language_out = 'ECMASCRIPT5_STRICT';
options.rewrite_polyfills = false;
options.hide_warnings_for = 'node_modules';
if (opt_warnings_as_error || opt_strict_typechecker) {
options.jscomp_error = JSCOMP_ERROR;
if (opt_strict_typechecker) {
options.jscomp_error.push('strictCheckTypes');
}
}
const platform = ['native', 'java', 'javascript'];
return closureCompiler({...options, ...compilerOptions}, { platform });
}
/**
* Helper method for possibly adding the Closure library into a sources array.
* @param {Array.<string>} srcs
*/
function maybeAddClosureLibrary(srcs) {
if (argv.closureLibrary) {
// If you require Google's Closure library, you can include it in your
// build by adding the --closure-library flag.
// You will also need to include the "google-closure-library" in your list
// of devDependencies.
console.log('Including the google-closure-library in your build.');
if (!fs.existsSync('./node_modules/google-closure-library')) {
throw Error('You must add the google-closure-library to your ' +
'devDependencies in package.json, and run `npm install`.');
}
srcs.push('./node_modules/google-closure-library/closure/goog/**/**/*.js');
}
return srcs;
}
/**
* A helper method to return an closure compiler output wrapper that wraps the
* body in a Universal Module Definition.
* @param {string} namespace The export namespace.
* @param {Array.<Object>} dependencies An array of dependencies to inject.
*/
function outputWrapperUMD(namespace, dependencies) {
const amdDeps = dependencies.map(d => '\'' + d.amd + '\'' ).join(', ');
const cjsDeps = dependencies.map(d => `require('${d.cjs}')`).join(', ');
const browserDeps = dependencies.map(d => 'root.' + d.name).join(', ');
const imports = dependencies.map(d => d.name).join(', ');
return `// Do not edit this file; automatically generated by gulp.
/* eslint-disable */
;(function(root, factory) {
if (typeof define === 'function' && define.amd) { // AMD
define([${amdDeps}], factory);
} else if (typeof exports === 'object') { // Node.js
module.exports = factory(${cjsDeps});
} else { // Browser
root.${namespace} = factory(${browserDeps});
}
}(this, function(${imports}) {
%output%
return ${namespace};
}));
`;
};
/**
* This task builds Blockly's core files.
* blockly_compressed.js
*/
function buildCompressed() {
const defines = 'Blockly.VERSION="' + packageJson.version + '"';
return gulp.src(maybeAddClosureLibrary(['core/**/**/*.js']), {base: './'})
.pipe(stripApacheLicense())
.pipe(gulp.sourcemaps.init())
// Directories in Blockly are used to group similar files together
// but are not used to limit access with @package, instead the
// method means something is internal to Blockly and not a public
// API.
// Flatten all files so they're in the same directory, but ensure that
// files with the same name don't conflict.
.pipe(gulp.rename(function (p) {
var dirname = p.dirname.replace(
new RegExp(path.sep.replace(/\\/, '\\\\'), "g"), "-");
p.dirname = "";
p.basename = dirname + "-" + p.basename;
}))
.pipe(compile({
dependency_mode: 'PRUNE',
entry_point: './core-requires.js',
js_output_file: 'blockly_compressed.js',
externs: ['./externs/svg-externs.js', './externs/goog-externs.js'],
define: defines,
language_in:
argv.closureLibrary ? 'ECMASCRIPT_2015' : 'ECMASCRIPT5_STRICT',
output_wrapper: outputWrapperUMD('Blockly', [])
}, argv.verbose, argv.debug, argv.strict))
.pipe(gulp.sourcemaps.mapSources(function (sourcePath, file) {
return sourcePath.replace(/-/g, '/');
}))
.pipe(gulp.sourcemaps.write('.', {
includeContent: false,
sourceRoot: './'
}))
.pipe(gulp.dest('./'));
};
/**
* This task builds the Blockly's built in blocks.
* blocks_compressed.js
*/
function buildBlocks() {
return gulp.src(['blocks/*.js'], {base: './'})
.pipe(stripApacheLicense())
.pipe(gulp.sourcemaps.init())
.pipe(compile({
dependency_mode: 'NONE',
externs: ['./externs/goog-externs.js', './externs/block-externs.js'],
js_output_file: 'blocks_compressed.js',
output_wrapper: outputWrapperUMD('Blockly.Blocks', [{
name: 'Blockly',
amd: './blockly_compressed.js',
cjs: './blockly_compressed.js'
}])
}, argv.verbose, argv.debug, argv.strict))
.pipe(gulp.sourcemaps.write('.', {
includeContent: false,
sourceRoot: './'
}))
.pipe(gulp.dest('./'));
};
/**
* A helper method for building a Blockly code generator.
* @param {string} language Generator language.
* @param {string} namespace Language namespace.
*/
function buildGenerator(language, namespace) {
return gulp.src([`generators/${language}.js`, `generators/${language}/*.js`], {base: './'})
.pipe(stripApacheLicense())
.pipe(gulp.sourcemaps.init())
.pipe(compile({
dependency_mode: 'NONE',
externs: ['./externs/goog-externs.js', './externs/generator-externs.js'],
js_output_file: `${language}_compressed.js`,
output_wrapper: outputWrapperUMD(`Blockly.${namespace}`, [{
name: 'Blockly',
amd: './blockly_compressed.js',
cjs: './blockly_compressed.js'
}])
}, argv.verbose, argv.debug, argv.strict))
.pipe(gulp.sourcemaps.write('.', {
includeContent: false,
sourceRoot: './'
}))
.pipe(gulp.dest('./'));
};
/**
* This task builds the javascript generator.
* javascript_compressed.js
*/
function buildJavascript() {
return buildGenerator('javascript', 'JavaScript');
};
/**
* This task builds the python generator.
* python_compressed.js
*/
function buildPython() {
return buildGenerator('python', 'Python');
};
/**
* This task builds the php generator.
* php_compressed.js
*/
function buildPHP() {
return buildGenerator('php', 'PHP');
};
/**
* This task builds the lua generator.
* lua_compressed.js
*/
function buildLua() {
return buildGenerator('lua', 'Lua');
};
/**
* This task builds the dart generator:
* dart_compressed.js
*/
function buildDart() {
return buildGenerator('dart', 'Dart');
};
/**
* This tasks builds all the generators:
* javascript_compressed.js
* python_compressed.js
* php_compressed.js
* lua_compressed.js
* dart_compressed.js
*/
const buildGenerators = gulp.parallel(
buildJavascript,
buildPython,
buildPHP,
buildLua,
buildDart
);
/**
* This task builds Blockly's uncompressed file.
* blockly_uncompressed.js
*/
function buildUncompressed() {
const closurePath = argv.closureLibrary ?
'node_modules/google-closure-library/closure/goog' :
'closure/goog';
const header = `// Do not edit this file; automatically generated by gulp.
'use strict';
this.IS_NODE_JS = !!(typeof module !== 'undefined' && module.exports);
this.BLOCKLY_DIR = (function(root) {
if (!root.IS_NODE_JS) {
// Find name of current directory.
var scripts = document.getElementsByTagName('script');
var re = new RegExp('(.+)[\\\/]blockly_(.*)uncompressed\\\.js$');
for (var i = 0, script; script = scripts[i]; i++) {
var match = re.exec(script.src);
if (match) {
return match[1];
}
}
alert('Could not detect Blockly\\'s directory name.');
}
return '';
})(this);
this.BLOCKLY_BOOT = function(root) {
// Execute after Closure has loaded.
`;
const footer = `
delete root.BLOCKLY_DIR;
delete root.BLOCKLY_BOOT;
delete root.IS_NODE_JS;
};
if (this.IS_NODE_JS) {
this.BLOCKLY_BOOT(this);
module.exports = Blockly;
} else {
document.write('<script src="' + this.BLOCKLY_DIR +
'/${closurePath}/base.js"></script>');
document.write('<script>this.BLOCKLY_BOOT(this);</script>');
}
`;
let deps = [];
return gulp.src(maybeAddClosureLibrary(['core/**/**/*.js']))
.pipe(through2.obj((file, _enc, cb) => {
const result = closureDeps.parser.parseFile(file.path);
for (const dep of result.dependencies) {
deps.push(dep);
}
cb(null);
}))
.on('end', () => {
// Update the path to closure for any files that we don't know the full path
// of (parsed from a goog.addDependency call).
for (const dep of deps) {
dep.setClosurePath(closurePath);
}
const addDependency = closureDeps.depFile
.getDepFileText(closurePath, deps)
.replace(/\\/g, '\/');
const requires = `goog.addDependency("base.js", [], []);
// Load Blockly.
goog.require('Blockly.requires')
`;
fs.writeFileSync('blockly_uncompressed.js',
header +
addDependency +
requires +
footer);
});
};
/**
* This task builds Blockly's lang files.
* msg/*.js
*/
function buildLangfiles(done) {
// Run js_to_json.py
const jsToJsonCmd = `python ./scripts/i18n/js_to_json.py \
--input_file ${path.join('msg', 'messages.js')} \
--output_dir ${path.join('msg', 'json')} \
--quiet`;
execSync(jsToJsonCmd, { stdio: 'inherit' });
// Run create_messages.py
let json_files = fs.readdirSync(path.join('msg', 'json'));
json_files = json_files.filter(file => file.endsWith('json') &&
!(new RegExp(/(keys|synonyms|qqq|constants)\.json$/).test(file)));
json_files = json_files.map(file => path.join('msg', 'json', file));
const createMessagesCmd = `python ./scripts/i18n/create_messages.py \
--source_lang_file ${path.join('msg', 'json', 'en.json')} \
--source_synonym_file ${path.join('msg', 'json', 'synonyms.json')} \
--source_constants_file ${path.join('msg', 'json', 'constants.json')} \
--key_file ${path.join('msg', 'json', 'keys.json')} \
--output_dir ${path.join('msg', 'js')} \
--quiet ${json_files.join(' ')}`;
execSync(createMessagesCmd, { stdio: 'inherit' });
done();
};
/**
* This task builds Blockly core, blocks and generators together and uses
* closure compiler's ADVANCED_COMPILATION mode.
*/
function buildAdvancedCompilationTest() {
const srcs = [
'tests/compile/main.js',
'core/**/**/*.js',
'blocks/*.js',
'generators/**/*.js'];
return gulp.src(maybeAddClosureLibrary(srcs), {base: './'})
.pipe(stripApacheLicense())
.pipe(gulp.sourcemaps.init())
// Directories in Blockly are used to group similar files together
// but are not used to limit access with @package, instead the
// method means something is internal to Blockly and not a public
// API.
// Flatten all files so they're in the same directory, but ensure that
// files with the same name don't conflict.
.pipe(gulp.rename(function (p) {
if (p.dirname.indexOf('core') === 0) {
var dirname = p.dirname.replace(
new RegExp(path.sep.replace(/\\/, '\\\\'), "g"), "-");
p.dirname = "";
p.basename = dirname + "-" + p.basename;
}
}))
.pipe(compile({
dependency_mode: 'PRUNE',
compilation_level: 'ADVANCED_OPTIMIZATIONS',
entry_point: './tests/compile/main.js',
js_output_file: 'main_compressed.js',
externs: ['./externs/svg-externs.js', './externs/goog-externs.js'],
language_in:
argv.closureLibrary ? 'ECMASCRIPT_2015' : 'ECMASCRIPT5_STRICT'
}, argv.verbose, argv.strict))
.pipe(gulp.sourcemaps.mapSources(function (sourcePath, file) {
return sourcePath.replace(/-/g, '/');
}))
.pipe(gulp.sourcemaps.write('.', {
includeContent: false,
sourceRoot: '../../'
}))
.pipe(gulp.dest('./tests/compile/'));
}
/**
* This tasks builds Blockly's core files:
* blockly_compressed.js
* blocks_compressed.js
* blockly_uncompressed.js
*/
const buildCore = gulp.parallel(
buildCompressed,
buildBlocks,
buildUncompressed
);
/**
* This task builds all of Blockly:
* blockly_compressed.js
* blocks_compressed.js
* javascript_compressed.js
* python_compressed.js
* php_compressed.js
* lua_compressed.js
* dart_compressed.js
* blockly_uncompressed.js
* msg/json/*.js
*/
const build = gulp.parallel(
buildCore,
buildGenerators,
buildLangfiles
);
module.exports = {
build: build,
core: buildCore,
blocks: buildBlocks,
langfiles: buildLangfiles,
uncompressed: buildUncompressed,
compressed: buildCompressed,
generators: buildGenerators,
advancedCompilationTest: buildAdvancedCompilationTest,
}
+129
View File
@@ -0,0 +1,129 @@
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Git-related gulp tasks for Blockly.
*/
var gulp = require('gulp');
var execSync = require('child_process').execSync;
var typings = require('./typings');
var buildTasks = require('./build_tasks');
const upstream_url = "https://github.com/google/blockly.git";
// Stash current state, check out the named branch, and sync with
// google/blockly.
function syncBranch(branchName) {
return function(done) {
execSync('git stash save -m "Stash for sync"', { stdio: 'inherit' });
checkoutBranch(branchName);
execSync('git pull ' + upstream_url + ' ' + branchName,
{ stdio: 'inherit' });
execSync('git push origin ' + branchName, { stdio: 'inherit' });
done();
}
}
// Stash current state, check out develop, and sync with google/blockly.
function syncDevelop() {
return syncBranch('develop');
};
// Stash current state, check out master, and sync with google/blockly.
function syncMaster() {
return syncBranch('master');
};
// Helper function: get a name for a rebuild branch. Format: rebuild_mm_dd_yyyy.
function getRebuildBranchName() {
var date = new Date();
var mm = date.getMonth() + 1; // Month, 0-11
var dd = date.getDate(); // Day of the month, 1-31
var yyyy = date.getFullYear();
return 'rebuild_' + mm + '_' + dd + '_' + yyyy;
};
// Helper function: get a name for a rebuild branch. Format: rebuild_yyyy_mm.
function getRCBranchName() {
var date = new Date();
var mm = date.getMonth() + 1; // Month, 0-11
var yyyy = date.getFullYear();
return 'rc_' + yyyy + '_' + mm;
};
// If branch does not exist then create the branch.
// If branch exists switch to branch.
function checkoutBranch(branchName) {
execSync('git checkout ' + branchName + ' || git checkout -b ' + branchName,
{ stdio: 'inherit' });
}
// Switch to a new rebuild branch.
const preCompile = gulp.series(
syncDevelop(),
function(done) {
var branchName = getRebuildBranchName();
console.log('make-rebuild-branch: creating branch ' + branchName);
execSync('git checkout -b ' + branchName, { stdio: 'inherit' });
done();
}
);
// Build all files, types, and push to rebuild branch.
const postCompile = gulp.series(
buildTasks.build,
typings.typings,
function(done) {
console.log('push-rebuild-branch: committing rebuild');
execSync('git commit -am "Rebuild"', { stdio: 'inherit' });
var branchName = getRebuildBranchName();
execSync('git push origin ' + branchName, { stdio: 'inherit' });
console.log('Branch ' + branchName + ' pushed to GitHub.');
console.log('Next step: create a pull request against develop.');
done();
}
);
// Create and push an RC branch.
// Note that this pushes to google/blockly.
const createRC = gulp.series(
syncDevelop(),
function(done) {
var branchName = getRCBranchName();
execSync('git checkout -b ' + branchName, { stdio: 'inherit' });
execSync('git push ' + upstream_url + ' ' + branchName,
{ stdio: 'inherit' });
done();
}
);
// Update github pages with what is currently in develop.
const updateGithubPages = gulp.series(
function(done) {
execSync('git stash save -m "Stash for sync"', { stdio: 'inherit' });
execSync('git checkout gh-pages || git checkout -b gh-pages', { stdio: 'inherit' });
execSync('git fetch upstream', { stdio: 'inherit' });
execSync('git reset --hard upstream/develop', { stdio: 'inherit' });
done();
},
buildTasks.build,
function(done) {
execSync('git commit -am "Rebuild"', { stdio: 'inherit' });
execSync('git push ' + upstream_url + ' gh-pages --force', { stdio: 'inherit' });
done();
}
);
module.exports = {
syncDevelop: syncDevelop,
syncMaster: syncMaster,
createRC: createRC,
preCompile: preCompile,
postCompile: postCompile,
updateGithubPages: updateGithubPages
}
@@ -0,0 +1,21 @@
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Gulp tasks to check the licenses of Blockly dependencies.
*/
const jsgl = require('js-green-licenses');
function checkLicenses() {
const checker = new jsgl.LicenseChecker();
checker.setDefaultHandlers();
return checker.checkLocalDirectory('.');
};
module.exports = {
checkLicenses: checkLicenses
};
@@ -0,0 +1,397 @@
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Gulp tasks to package Blockly for distribution on NPM.
*/
var gulp = require('gulp');
gulp.concat = require('gulp-concat');
gulp.replace = require('gulp-replace');
gulp.rename = require('gulp-rename');
gulp.insert = require('gulp-insert');
gulp.umd = require('gulp-umd');
var path = require('path');
var fs = require('fs');
var packageJson = require('../../package.json');
const blocklyRoot = '../../';
// The destination path where all the NPM distribution files will go.
const packageDistribution = 'dist';
/**
* A helper method for wrapping a file into a Universal Module Definition.
* @param {string} namespace The export namespace.
* @param {Array.<Object>} dependencies An array of dependencies to inject.
*/
function packageUMD(namespace, dependencies) {
return gulp.umd({
dependencies: function () { return dependencies; },
namespace: function () { return namespace; },
exports: function () { return namespace; },
template: path.join(__dirname, `${blocklyRoot}/scripts/package/templates/umd.template`)
});
};
/**
* A helper method for wrapping a file into a CommonJS module for Node.js.
* @param {string} namespace The export namespace.
* @param {Array.<Object>} dependencies An array of dependencies to inject.
*/
function packageCommonJS(namespace, dependencies) {
return gulp.umd({
dependencies: function () { return dependencies; },
namespace: function () { return namespace; },
exports: function () { return namespace; },
template: path.join(__dirname, `${blocklyRoot}/scripts/package/templates/node.template`)
});
};
/**
* This task copies source files into the distribution directory.
*/
function packageSources() {
return gulp.src(['core/**/**.js', 'blocks/**.js', 'generators/**/**.js'],
{base: '.'})
.pipe(gulp.dest(packageDistribution));
};
/**
* This task copies the compressed files and their source maps into the
* distribution directory.
*/
function packageCompressed() {
return gulp.src('*_compressed.js?(.map)')
.pipe(gulp.dest(packageDistribution));
};
/**
* This task wraps scripts/package/blockly.js into a UMD module.
* @example import 'blockly/blockly';
*/
function packageBlockly() {
return gulp.src('scripts/package/blockly.js')
.pipe(packageUMD('Blockly', [{
name: 'Blockly',
amd: './blockly_compressed',
cjs: './blockly_compressed',
}]))
.pipe(gulp.rename('blockly.js'))
.pipe(gulp.dest(packageDistribution));
};
/**
* This task wraps scripts/package/blocks.js into a UMD module.
* @example import 'blockly/blocks';
*/
function packageBlocks() {
return gulp.src('scripts/package/blocks.js')
.pipe(packageUMD('Blockly.Blocks', [{
name: 'Blockly',
amd: './blocks_compressed',
cjs: './blocks_compressed',
}]))
.pipe(gulp.rename('blocks.js'))
.pipe(gulp.dest(packageDistribution));
};
/**
* This task wraps scripts/package/index.js into a UMD module.
* We implicitly require the Node entry point in CommonJS environments,
* and the Browser entry point for AMD environments.
* @example import * as Blockly from 'blockly';
*/
function packageIndex() {
return gulp.src('scripts/package/index.js')
.pipe(packageUMD('Blockly', [{
name: 'Blockly',
amd: './browser',
cjs: './node',
}]))
.pipe(gulp.rename('index.js'))
.pipe(gulp.dest(packageDistribution));
};
/**
* This task wraps scripts/package/browser/index.js into a UMD module.
* By default, the module includes Blockly core and built-in blocks,
* as well as the JavaScript code generator and the English block
* localization files.
* This module is configured (in package.json) to replaces the module
* built by package-node in browser environments.
* @example import * as Blockly from 'blockly/browser';
*/
function packageBrowser() {
return gulp.src('scripts/package/browser/index.js')
.pipe(packageUMD('Blockly', [{
name: 'Blockly',
amd: './core-browser',
cjs: './core-browser',
},{
name: 'En',
amd: './msg/en',
cjs: './msg/en',
},{
name: 'BlocklyBlocks',
amd: './blocks',
cjs: './blocks',
},{
name: 'BlocklyJS',
amd: './javascript',
cjs: './javascript',
}]))
.pipe(gulp.rename('browser.js'))
.pipe(gulp.dest(packageDistribution));
};
/**
* This task wraps scripts/package/browser/core.js into a UMD module.
* By default, the module includes the Blockly core package and a
* helper method to set the locale.
* This module is configured (in package.json) to replaces the module
* built by package-node-core in browser environments.
* @example import * as Blockly from 'blockly/core';
*/
function packageCore() {
return gulp.src('scripts/package/browser/core.js')
.pipe(packageUMD('Blockly', [{
name: 'Blockly',
amd: './blockly',
cjs: './blockly',
}]))
.pipe(gulp.rename('core-browser.js'))
.pipe(gulp.dest(packageDistribution));
};
/**
* This task wraps scripts/package/node/index.js into a CommonJS module for Node.js.
* By default, the module includes Blockly core and built-in blocks,
* as well as all the code generators and the English block localization files.
* This module is configured (in package.json) to be replaced by the module
* built by package-browser in browser environments.
* @example import * as Blockly from 'blockly/node';
*/
function packageNode() {
return gulp.src('scripts/package/node/index.js')
.pipe(packageCommonJS('Blockly', [{
name: 'Blockly',
cjs: './core',
},{
name: 'En',
cjs: './msg/en',
},{
name: 'BlocklyBlocks',
cjs: './blocks',
},{
name: 'BlocklyJS',
cjs: './javascript',
},{
name: 'BlocklyPython',
cjs: './python',
},{
name: 'BlocklyPHP',
cjs: './php',
},{
name: 'BlocklyLua',
cjs: './lua',
}, {
name: 'BlocklyDart',
cjs: './dart',
}]))
.pipe(gulp.rename('node.js'))
.pipe(gulp.dest(packageDistribution));
};
/**
* This task wraps scripts/package/node/core.js into a CommonJS module for Node.js.
* By default, the module includes the Blockly core package for Node.js
* and a helper method to set the locale.
* This module is configured (in package.json) to be replaced by the module
* built by package-core in browser environments.
* @example import * as Blockly from 'blockly/core';
*/
function packageNodeCore() {
return gulp.src('scripts/package/node/core.js')
.pipe(packageCommonJS('Blockly', [{
name: 'Blockly',
amd: './blockly',
cjs: './blockly',
}]))
.pipe(gulp.rename('core.js'))
.pipe(gulp.dest(packageDistribution));
};
/**
* A helper method for wrapping a generator file into a UMD module.
* @param {string} file Source file name.
* @param {string} rename Destination file name.
* @param {string} namespace Export namespace.
*/
function packageGenerator(file, rename, namespace) {
return gulp.src(`scripts/package/${rename}`)
.pipe(packageUMD(`Blockly${namespace}`, [{
name: 'Blockly',
amd: './core',
cjs: './core',
}, {
name: `Blockly${namespace}`,
amd: `./${file}`,
cjs: `./${file}`,
}]))
.pipe(gulp.rename(rename))
.pipe(gulp.dest(packageDistribution));
};
/**
* This task wraps javascript_compressed.js into a UMD module.
* @example import 'blockly/javascript';
*/
function packageJavascript() {
return packageGenerator('javascript_compressed.js', 'javascript.js', 'JavaScript');
};
/**
* This task wraps python_compressed.js into a UMD module.
* @example import 'blockly/python';
*/
function packagePython() {
return packageGenerator('python_compressed.js', 'python.js', 'Python');
};
/**
* This task wraps lua_compressed.js into a UMD module.
* @example import 'blockly/lua';
*/
function packageLua() {
return packageGenerator('lua_compressed.js', 'lua.js', 'Lua');
};
/**
* This task wraps dart_compressed.js into a UMD module.
* @example import 'blockly/dart';
*/
function packageDart() {
return packageGenerator('dart_compressed.js', 'dart.js', 'Dart');
};
/**
* This task wraps php_compressed.js into a UMD module.
* @example import 'blockly/php';
*/
function packagePHP() {
return packageGenerator('php_compressed.js', 'php.js', 'PHP');
};
/**
* This task wraps each of the msg/js/* files into a UMD module.
* @example import * as En from 'blockly/msg/en';
*/
function packageLocales() {
// Remove references to goog.provide and goog.require.
return gulp.src('msg/js/*.js')
.pipe(gulp.replace(/goog\.[^\n]+/g, ''))
.pipe(gulp.insert.prepend(`
var Blockly = {};Blockly.Msg={};`))
.pipe(packageUMD('Blockly.Msg', [{
name: 'Blockly',
amd: '../core',
cjs: '../core',
}]))
.pipe(gulp.dest(`${packageDistribution}/msg`));
};
/**
* This task creates a UMD bundle of Blockly which includes the Blockly
* core files, the built-in blocks, the JavaScript code generator and the
* English localization files.
* @example <script src="https://unpkg.com/blockly/blockly.min.js"></script>
*/
function packageUMDBundle() {
var srcs = [
'blockly_compressed.js',
'msg/js/en.js',
'blocks_compressed.js',
'javascript_compressed.js'
];
return gulp.src(srcs)
.pipe(gulp.concat('blockly.min.js'))
.pipe(gulp.dest(`${packageDistribution}`))
};
/**
* This task copies all the media/* files into the distribution directory.
*/
function packageMedia() {
return gulp.src('./media/*')
.pipe(gulp.dest(`${packageDistribution}/media`));
};
/**
* This task copies the package.json file into the distribution directory.
*/
function packageJSON(cb) {
const json = Object.assign({}, packageJson);
delete json['scripts'];
if (!fs.existsSync(packageDistribution)) {
fs.mkdirSync(packageDistribution);
}
fs.writeFileSync(`${packageDistribution}/package.json`,
JSON.stringify(json, null, 2));
cb();
};
/**
* This task copies the scripts/package/README.md file into the distribution directory.
* This file is what developers will see at https://www.npmjs.com/package/blockly.
*/
function packageReadme() {
return gulp.src('./scripts/package/README.md')
.pipe(gulp.dest(`${packageDistribution}`));
};
/**
* This task copies the typings/blockly.d.ts TypeScript definition file into the
* distribution directory.
* The bundled declaration file is referenced in package.json in the types property.
*/
function packageDTS() {
return gulp.src(['./typings/*.d.ts', './typings/msg/*.d.ts'], {base: './typings'})
.pipe(gulp.dest(`${packageDistribution}`));
};
/**
* This task prepares the NPM distribution files under the /dist directory.
*/
const package = gulp.parallel(
packageIndex,
packageSources,
packageCompressed,
packageBrowser,
packageNode,
packageCore,
packageNodeCore,
packageBlockly,
packageBlocks,
packageJavascript,
packagePython,
packageLua,
packageDart,
packagePHP,
packageLocales,
packageMedia,
packageUMDBundle,
packageJSON,
packageReadme,
packageDTS
);
module.exports = {
package: package,
};
+104
View File
@@ -0,0 +1,104 @@
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Gulp script to generate the Typescript definition file (d.ts)
* for Blockly.
*/
var gulp = require('gulp');
gulp.concat = require('gulp-concat');
var path = require('path');
var fs = require('fs');
var rimraf = require('rimraf');
var execSync = require('child_process').execSync;
// Generates the TypeScript definition file (d.ts) for Blockly.
// As well as generating the typings of each of the files under core/ and msg/,
// the script also pulls in a number of part files from typings/parts.
// This includes the header (incl License), additional useful interfaces
// including Blockly Options and Google Closure typings.
function typings() {
const tmpDir = './typings/tmp';
const blocklySrcs = [
"core/",
"core/events",
"core/keyboard_nav",
"core/renderers/common",
"core/renderers/measurables",
"core/theme",
"core/toolbox",
"core/interfaces",
"core/utils",
"msg/"
];
// Clean directory if exists.
if (fs.existsSync(tmpDir)) {
rimraf.sync(tmpDir);
}
fs.mkdirSync(tmpDir);
// Find all files that will be included in the typings file.
let files = [];
blocklySrcs.forEach((src) => {
files = files.concat(fs.readdirSync(src)
.filter(fn => fn.endsWith('.js'))
.map(fn => path.join(src, fn)));
});
// Generate typings file for each file.
files.forEach((file) => {
const typescriptFileName = `${path.join(tmpDir, file)}.d.ts`;
if (file.indexOf('core/msg.js') > -1) {
return;
}
const cmd = `node ./node_modules/typescript-closure-tools/definition-generator/src/main.js ${file} ${typescriptFileName}`;
console.log(`Generating typings for ${file}`);
execSync(cmd, { stdio: 'inherit' });
});
const srcs = [
'typings/templates/blockly-header.template',
'typings/templates/blockly-interfaces.template',
`${tmpDir}/core/**`,
`${tmpDir}/core/interfaces/**`,
`${tmpDir}/core/events/**`,
`${tmpDir}/core/keyboard_nav/**`,
`${tmpDir}/core/renderers/common/**`,
`${tmpDir}/core/renderers/measurables/**`,
`${tmpDir}/core/utils/**`,
`${tmpDir}/core/toolbox/**`,
`${tmpDir}/core/theme/**`,
`${tmpDir}/msg/**`
];
return gulp.src(srcs)
.pipe(gulp.concat('blockly.d.ts'))
.pipe(gulp.dest('typings'))
.on('end', function () {
// Clean up tmp directory.
if (fs.existsSync(tmpDir)) {
rimraf.sync(tmpDir);
}
});
};
// Generates the TypeScript definition files (d.ts) for Blockly locales.
function msgTypings(cb) {
const template = fs.readFileSync(path.join('typings/templates/msg.template'), 'utf-8');
const msgFiles = fs.readdirSync(path.join('msg', 'json'));
msgFiles.forEach(msg => {
const localeName = msg.substring(0, msg.indexOf('.json'));
const msgTypings = template.slice().replace(/<%= locale %>/gi, localeName);
fs.writeFileSync(path.join('typings', 'msg', localeName + '.d.ts'), msgTypings, 'utf-8');
})
cb();
}
module.exports = {
typings: typings,
msgTypings: msgTypings
};
+77
View File
@@ -0,0 +1,77 @@
# Blockly
Google's Blockly is a web-based, visual programming editor. Users can drag
blocks together to build programs. All code is free and open source.
The source for this module is in the [Blockly repo](http://github.com/google/blockly).
## Installation
You can install this package either via ``npm`` or ``unpkg``.
### npm
```bash
npm install blockly
```
### unpkg
```html
<script src="https://unpkg.com/blockly/blockly.min.js"></script>
```
## Example Usage
```js
import Blockly from 'blockly';
Blockly.inject('blocklyDiv', {
...
})
```
## Samples
For samples on how to integrate Blockly into your project, view the list of samples at [blockly-samples](https://github.com/google/blockly-samples).
### Importing Blockly
When you import Blockly with ``import * as Blockly from 'blockly';`` you'll get the default modules:
Blockly core, Blockly built-in blocks, the JavaScript generator and the English lang files.
If you need more flexibility, you'll want to define your imports more carefully:
#### Blockly Core
```js
import * as Blockly from 'blockly/core';
```
#### Blockly built in blocks
```js
import 'blockly/blocks';
```
#### Blockly Generators
If your application needs to generate code from the Blockly blocks, you'll want to include a generator.
```js
import 'blockly/python';
```
to include the Python generator, you can also import ``blockly/javascript``, ``blockly/php``, ``blockly/dart`` and ``blockly/lua``.
#### Blockly Languages
```js
import * as Fr from 'blockly/msg/fr';
Blockly.setLocale(Fr);
```
To import the French lang files. Once you've imported the specific lang module, you'll also want to set the locale in Blockly.
For a full list of supported Blockly locales, see: [https://github.com/google/blockly/tree/master/msg/js](https://github.com/google/blockly/tree/master/msg/js)
## License
Apache 2.0
+12
View File
@@ -0,0 +1,12 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Blockly module.
*/
/* eslint-disable */
'use strict';
+14
View File
@@ -0,0 +1,14 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Blockly Blocks module.
*/
/* eslint-disable */
'use strict';
Blockly.Blocks = {};
+21
View File
@@ -0,0 +1,21 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Blockly core module for the browser. It includes blockly.js
* and adds a helper method for setting the locale.
*/
/* eslint-disable */
'use strict';
// Add a helper method to set the Blockly locale.
Blockly.setLocale = function (locale) {
Blockly.Msg = Blockly.Msg || {};
Object.keys(locale).forEach(function (k) {
Blockly.Msg[k] = locale[k];
});
};
@@ -0,0 +1,24 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Blockly module for the browser. This includes Blockly core
* and built in blocks, the JavaScript code generator and the English block
* localization files.
*/
/* eslint-disable */
'use strict';
// Include the EN Locale by default.
Blockly.setLocale(En);
Blockly.Blocks = Blockly.Blocks || {};
Object.keys(BlocklyBlocks).forEach(function (k) {
Blockly.Blocks[k] = BlocklyBlocks[k];
});
Blockly.JavaScript = BlocklyJS;
+14
View File
@@ -0,0 +1,14 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Dart Generator module.
*/
/* eslint-disable */
'use strict';
Blockly.Dart = BlocklyDart;
+12
View File
@@ -0,0 +1,12 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Blockly module.
*/
/* eslint-disable */
'use strict';
+14
View File
@@ -0,0 +1,14 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview JavaScript Generator module.
*/
/* eslint-disable */
'use strict';
Blockly.JavaScript = BlocklyJavaScript;
+14
View File
@@ -0,0 +1,14 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Lua Generator module.
*/
/* eslint-disable */
'use strict';
Blockly.Lua = BlocklyLua;
+33
View File
@@ -0,0 +1,33 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Blockly core module for Node. It includes blockly-node.js
* and adds a helper method for setting the locale.
*/
/* eslint-disable */
'use strict';
// Add a helper method to set the Blockly locale.
Blockly.setLocale = function (locale) {
Blockly.Msg = Blockly.Msg || {};
Object.keys(locale).forEach(function (k) {
Blockly.Msg[k] = locale[k];
});
};
// Override textToDomDocument and provide Node.js alternatives to DOMParser and
// XMLSerializer.
if (typeof Blockly.utils.global.document !== 'object') {
Blockly.utils.global.DOMParser = require("jsdom/lib/jsdom/living").DOMParser;
Blockly.utils.global.XMLSerializer = require("jsdom/lib/jsdom/living").XMLSerializer;
var doc = Blockly.utils.xml.textToDomDocument(
'<xml xmlns="https://developers.google.com/blockly/xml"></xml>');
Blockly.utils.xml.document = function() {
return doc;
};
}
+31
View File
@@ -0,0 +1,31 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Blockly module for Node. It includes Blockly core,
* built-in blocks, all the generators and the English locale.
*/
/* eslint-disable */
'use strict';
// Include the EN Locale by default.
Blockly.setLocale(En);
Blockly.Blocks = Blockly.Blocks || {};
Object.keys(BlocklyBlocks).forEach(function (k) {
Blockly.Blocks[k] = BlocklyBlocks[k];
});
Blockly.JavaScript = BlocklyJS;
Blockly.Python = BlocklyPython;
Blockly.Lua = BlocklyLua;
Blockly.PHP = BlocklyPHP;
Blockly.Dart = BlocklyDart;
+14
View File
@@ -0,0 +1,14 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview PHP Generator module.
*/
/* eslint-disable */
'use strict';
Blockly.PHP = BlocklyPHP;
+14
View File
@@ -0,0 +1,14 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Python Generator module.
*/
/* eslint-disable */
'use strict';
Blockly.Python = BlocklyPython;
@@ -0,0 +1,5 @@
/* eslint-disable */
(function (<%= param %>){
<%= contents %>
module.exports = <%= exports %>;
})(<%= cjs %>);
@@ -0,0 +1,13 @@
/* eslint-disable */
;(function(root, factory) {
if (typeof define === 'function' && define.amd) { // AMD
define(<%= amd %>, factory);
} else if (typeof exports === 'object') { // Node.js
module.exports = factory(<%= cjs %>);
} else { // Browser
root.<%= namespace %> = factory(<%= global %>);
}
}(this, function(<%= param %>) {
<%= contents %>
return <%= exports %>;
}));