533 lines
15 KiB
JavaScript
533 lines
15 KiB
JavaScript
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2024
|
|
*
|
|
* This program is a free software product. You can redistribute it and/or
|
|
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
|
* version 3 as published by the Free Software Foundation. In accordance with
|
|
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
|
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
|
* of any third-party rights.
|
|
*
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
|
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
|
* street, Riga, Latvia, EU, LV-1050.
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of the Program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU AGPL version 3.
|
|
*
|
|
* Pursuant to Section 7(b) of the License you must retain the original Product
|
|
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
|
* grant you any rights under trademark law for use of our trademarks.
|
|
*
|
|
* All the Product's GUI elements, including illustrations and icon sets, as
|
|
* well as technical writing content are licensed under the terms of the
|
|
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
|
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
*
|
|
*/
|
|
|
|
module.exports = function(grunt) {
|
|
function loadConfig(pathConfigs, name) {
|
|
let config;
|
|
try {
|
|
const file = path.join(pathConfigs, name + '.json');
|
|
if (grunt.file.exists(file)) {
|
|
config = grunt.file.readJSON(file);
|
|
grunt.log.ok((name + ' config loaded successfully').green);
|
|
}
|
|
} catch (e) {
|
|
grunt.log.error().writeln(('could not load' + name + 'config file').red);
|
|
}
|
|
return config;
|
|
}
|
|
function fixPath(obj, basePath = '') {
|
|
function fixPathArray(arrPaths, basePath = '') {
|
|
arrPaths.forEach((element, index) => {
|
|
arrPaths[index] = path.join(basePath, element);
|
|
});
|
|
}
|
|
if (Array.isArray(obj))
|
|
return fixPathArray(obj, basePath);
|
|
for (let prop in obj) {
|
|
fixPath(obj[prop], basePath);
|
|
}
|
|
}
|
|
function fixUrl(arrPaths, basePath = '') {
|
|
const url = require('url');
|
|
arrPaths.forEach((element, index) => {
|
|
arrPaths[index] = url.resolve(basePath, element);
|
|
});
|
|
}
|
|
function getConfigs() {
|
|
const configs = new CConfig(grunt.option('src') || '../');
|
|
|
|
let addons = grunt.option('addon') || [];
|
|
if (!Array.isArray(addons)) {
|
|
addons = [addons];
|
|
}
|
|
addons.forEach(element => configs.append(grunt.file.isDir(element) ? element : path.join('../../', element)));
|
|
|
|
return configs;
|
|
}
|
|
function writeScripts(config, name) {
|
|
const develop = '../develop/sdkjs/';
|
|
const fileName = 'scripts.js';
|
|
let files = ['../vendor/polyfill.js', '../common/AllFonts.js'];
|
|
if (grunt.option('compiled')) {
|
|
//todo set window['AscNotLoadAllScript'] = false; (in applyDocumentChanges.js)
|
|
files.push(deploy + name + '/sdk-all-min.js');
|
|
} else {
|
|
files = files.concat(['../common/applyDocumentChanges.js'], getFilesMin(config), getFilesAll(config));
|
|
}
|
|
fixUrl(files, '../../../../sdkjs/build/');
|
|
|
|
grunt.file.write(path.join(develop, name, fileName), 'var sdk_scripts = [\n\t"' + files.join('",\n\t"') + '"\n];');
|
|
}
|
|
|
|
function CConfig(pathConfigs) {
|
|
this.externs = null;
|
|
this.word = null;
|
|
this.cell = null;
|
|
this.slide = null;
|
|
this.visio = null;
|
|
|
|
this.append(pathConfigs);
|
|
}
|
|
|
|
CConfig.prototype.append = function (basePath = '') {
|
|
const pathConfigs = path.join(basePath, 'configs');
|
|
|
|
function appendOption(name) {
|
|
const option = loadConfig(pathConfigs, name);
|
|
if (!option)
|
|
return;
|
|
|
|
fixPath(option, basePath);
|
|
|
|
if (!this[name]) {
|
|
this[name] = option;
|
|
return;
|
|
}
|
|
|
|
function mergeProps(base, addon) {
|
|
for (let prop in addon)
|
|
{
|
|
if (Array.isArray(addon[prop])) {
|
|
base[prop] = Array.isArray(base[prop]) ? base[prop].concat(addon[prop]) : addon[prop];
|
|
} else {
|
|
if (!base[prop])
|
|
base[prop] = {};
|
|
mergeProps(base[prop], addon[prop]);
|
|
}
|
|
}
|
|
}
|
|
|
|
mergeProps(this[name], option);
|
|
}
|
|
|
|
appendOption.call(this, 'externs');
|
|
appendOption.call(this, 'word');
|
|
appendOption.call(this, 'cell');
|
|
appendOption.call(this, 'slide');
|
|
appendOption.call(this, 'visio');
|
|
};
|
|
CConfig.prototype.valid = function () {
|
|
return this.externs && this.word && this.cell && this.slide && this.visio;
|
|
};
|
|
|
|
function getExterns(config) {
|
|
var externs = config['externs'];
|
|
var result = [];
|
|
for (var i = 0; i < externs.length; ++i) {
|
|
result.push('--externs=' + externs[i]);
|
|
}
|
|
return result;
|
|
}
|
|
function getFilesMin(config) {
|
|
var result = config['min'];
|
|
if (grunt.option('mobile')) {
|
|
result = config['mobile_banners']['min'].concat(result);
|
|
}
|
|
if (grunt.option('desktop')) {
|
|
result = result.concat(config['desktop']['min']);
|
|
}
|
|
return result;
|
|
}
|
|
function getFilesAll(config) {
|
|
var result = config['common'];
|
|
if (grunt.option('mobile')) {
|
|
result = config['mobile_banners']['common'].concat(result);
|
|
|
|
var excludeFiles = config['exclude_mobile'];
|
|
result = result.filter(function(item) {
|
|
return -1 === excludeFiles.indexOf(item);
|
|
});
|
|
result = result.concat(config['mobile']);
|
|
}
|
|
if (grunt.option('desktop')) {
|
|
result = result.concat(config['desktop']['common']);
|
|
}
|
|
return result;
|
|
}
|
|
const path = require('path');
|
|
const deploy = '../deploy/sdkjs/';
|
|
const word = path.join(deploy, 'word');
|
|
const cell = path.join(deploy, 'cell');
|
|
const slide = path.join(deploy, 'slide');
|
|
const visio = path.join(deploy, 'visio');
|
|
|
|
const level = grunt.option('level') || 'ADVANCED';
|
|
const formatting = grunt.option('formatting') || '';
|
|
|
|
require('google-closure-compiler').grunt(grunt, {
|
|
platform: ['native', 'java'],
|
|
extraArguments: ['-Xms2048m']
|
|
});
|
|
|
|
grunt.loadNpmTasks('grunt-contrib-clean');
|
|
grunt.loadNpmTasks('grunt-contrib-copy');
|
|
|
|
const configs = getConfigs();
|
|
if (!configs.valid()) {
|
|
return;
|
|
}
|
|
const otherFiles = [
|
|
{
|
|
cwd: '../common/',
|
|
src: [
|
|
'Drawings/Format/path-boolean-min.js',
|
|
'Charts/ChartStyles.js',
|
|
'SmartArts/SmartArtData/*',
|
|
'SmartArts/SmartArtDrawing/*',
|
|
'Images/*',
|
|
'Images/placeholders/*',
|
|
'Images/content_controls/*',
|
|
'Images/cursors/*',
|
|
'Images/reporter/*',
|
|
'Images/icons/*',
|
|
'Native/*.js',
|
|
'libfont/engine/*',
|
|
'spell/spell/*',
|
|
'hash/hash/*',
|
|
'zlib/engine/*',
|
|
'serviceworker/*'
|
|
],
|
|
dest: path.join(deploy, 'common'),
|
|
name: 'common'
|
|
},
|
|
{
|
|
cwd: '../cell/css',
|
|
src: ['*.css'],
|
|
dest: path.join(cell, 'css'),
|
|
name: 'cell-css'
|
|
},
|
|
{
|
|
cwd: '../slide/themes',
|
|
src: ['**/**'],
|
|
dest: path.join(slide, 'themes'),
|
|
name: 'slide-themes'
|
|
},
|
|
{
|
|
cwd: '../pdf/',
|
|
src: [
|
|
'src/engine/*',
|
|
'src/annotations/stamps/*.json'
|
|
],
|
|
dest: path.join(deploy, 'pdf'),
|
|
name: 'pdf'
|
|
}
|
|
];
|
|
const configWord = configs.word['sdk'];
|
|
const configCell = configs.cell['sdk'];
|
|
const configSlide = configs.slide['sdk'];
|
|
const configVisio = configs.visio['sdk'];
|
|
|
|
const compilerArgs = getExterns(configs.externs);
|
|
if (formatting) {
|
|
compilerArgs.push('--formatting=' + formatting);
|
|
}
|
|
const appCopyright = process.env['APP_COPYRIGHT'] || "Copyright (C) Ascensio System SIA 2012-" + grunt.template.today('yyyy') +". All rights reserved";
|
|
const publisherUrl = process.env['PUBLISHER_URL'] || "https://www.onlyoffice.com/";
|
|
const companyName = process.env['COMPANY_NAME'] || 'onlyoffice';
|
|
const version = process.env['PRODUCT_VERSION'] || '0.0.0';
|
|
const buildNumber = process.env['BUILD_NUMBER'] || '0';
|
|
const beta = grunt.option('beta') || 'false';
|
|
|
|
let license = grunt.file.read(path.join('./license.header'));
|
|
license = license.replace('@@AppCopyright', appCopyright);
|
|
license = license.replace('@@PublisherUrl', publisherUrl);
|
|
license = license.replace('@@Version', version);
|
|
license = license.replace('@@Build', buildNumber);
|
|
|
|
function getCompileConfig(sdkmin, sdkall, outmin, outall, name, pathPrefix) {
|
|
const args = compilerArgs.concat (
|
|
`--define=window.AscCommon.g_cCompanyName='${companyName}'`,
|
|
`--define=window.AscCommon.g_cProductVersion='${version}'`,
|
|
`--define=window.AscCommon.g_cBuildNumber='${buildNumber}'`,
|
|
`--define=window.AscCommon.g_cIsBeta='${beta}'`,
|
|
'--rewrite_polyfills=true',
|
|
'--warning_level=QUIET',
|
|
'--language_out=ECMASCRIPT5',
|
|
'--compilation_level=' + level,
|
|
...sdkmin.map((file) => ('--js=' + file)),
|
|
`--chunk=${outmin}:${sdkmin.length}`,
|
|
`--chunk_wrapper=${outmin}:${license}\n%s`,
|
|
...sdkall.map((file) => ('--js=' + file)),
|
|
`--chunk=${outall}:${sdkall.length}:${outmin}`,
|
|
`--chunk_wrapper=${outall}:${license}\n(function(window, undefined) {%s})(window);`,
|
|
`--chunk_output_path_prefix=${pathPrefix}`);
|
|
if (grunt.option('map')) {
|
|
grunt.file.mkdir(path.join('./maps'));
|
|
args.push('--property_renaming_report=' + path.join(`maps/${name}.props.js.map`));
|
|
args.push('--variable_renaming_report=' + path.join(`maps/${name}.vars.js.map`));
|
|
args.push('--create_source_map=' + path.join(`%outname%.map`));
|
|
args.push('--source_map_format=V3');
|
|
args.push('--source_map_include_content=true');
|
|
}
|
|
return {
|
|
'closure-compiler': {
|
|
js: {
|
|
options: {
|
|
args: args,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
grunt.registerTask('compile-word', 'Compile Word SDK', function () {
|
|
grunt.initConfig(getCompileConfig(getFilesMin(configWord), getFilesAll(configWord), 'sdk-all-min', 'sdk-all', 'word', path.join(word , '/')));
|
|
grunt.task.run('closure-compiler');
|
|
});
|
|
grunt.registerTask('compile-cell', 'Compile Cell SDK', function () {
|
|
grunt.initConfig(getCompileConfig(getFilesMin(configCell), getFilesAll(configCell), 'sdk-all-min', 'sdk-all', 'cell', path.join(cell , '/')));
|
|
grunt.task.run('closure-compiler');
|
|
});
|
|
grunt.registerTask('compile-slide', 'Compile Slide SDK', function () {
|
|
grunt.initConfig(getCompileConfig(getFilesMin(configSlide), getFilesAll(configSlide), 'sdk-all-min', 'sdk-all', 'slide', path.join(slide , '/')));
|
|
grunt.task.run('closure-compiler');
|
|
});
|
|
grunt.registerTask('compile-visio', 'Compile Visio SDK', function () {
|
|
grunt.initConfig(getCompileConfig(getFilesMin(configVisio), getFilesAll(configVisio), 'sdk-all-min', 'sdk-all', 'visio', path.join(visio , '/')));
|
|
grunt.task.run('closure-compiler');
|
|
});
|
|
grunt.registerTask('copy-maps', 'Copy maps from deploy to build', function() {
|
|
grunt.initConfig({
|
|
copy: {
|
|
word: {
|
|
files: [
|
|
{
|
|
expand: true,
|
|
cwd: word,
|
|
src: [
|
|
'sdk-all-min.js.map',
|
|
'sdk-all.js.map',
|
|
],
|
|
dest: 'maps',
|
|
rename: function (dest, src) {
|
|
return path.join(dest , src.replace('sdk', 'word'));
|
|
}
|
|
}
|
|
]
|
|
},
|
|
cell: {
|
|
files: [
|
|
{
|
|
expand: true,
|
|
cwd: cell,
|
|
src: [
|
|
'sdk-all-min.js.map',
|
|
'sdk-all.js.map',
|
|
],
|
|
dest: 'maps',
|
|
rename: function (dest, src) {
|
|
return path.join(dest , src.replace('sdk', 'cell'));
|
|
}
|
|
}
|
|
]
|
|
},
|
|
slide: {
|
|
files: [
|
|
{
|
|
expand: true,
|
|
cwd: slide,
|
|
src: [
|
|
'sdk-all-min.js.map',
|
|
'sdk-all.js.map',
|
|
],
|
|
dest: 'maps',
|
|
rename: function (dest, src) {
|
|
return path.join(dest , src.replace('sdk', 'slide'));
|
|
}
|
|
}
|
|
]
|
|
},
|
|
visio: {
|
|
files: [
|
|
{
|
|
expand: true,
|
|
cwd: visio,
|
|
src: [
|
|
'sdk-all-min.js.map',
|
|
'sdk-all.js.map',
|
|
],
|
|
dest: 'maps',
|
|
rename: function (dest, src) {
|
|
return path.join(dest , src.replace('sdk', 'visio'));
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
clean: {
|
|
deploy: {
|
|
options: {
|
|
force: true
|
|
},
|
|
src: [
|
|
path.join(word, 'sdk-all-min.js.map'),
|
|
path.join(word, 'sdk-all.js.map'),
|
|
path.join(cell, 'sdk-all-min.js.map'),
|
|
path.join(cell, 'sdk-all.js.map'),
|
|
path.join(slide, 'sdk-all-min.js.map'),
|
|
path.join(slide, 'sdk-all.js.map'),
|
|
path.join(visio, 'sdk-all-min.js.map'),
|
|
path.join(visio, 'sdk-all.js.map'),
|
|
]
|
|
}
|
|
}
|
|
});
|
|
grunt.task.run('copy', 'clean');
|
|
});
|
|
grunt.registerTask('compile-sdk', ['compile-word', 'compile-cell', 'compile-slide', 'compile-visio']);
|
|
grunt.registerTask('clean-deploy', 'Clean deploy folder before deploying', function () {
|
|
grunt.initConfig({
|
|
clean: {
|
|
deploy: {
|
|
options: {
|
|
force: true
|
|
},
|
|
src: [
|
|
deploy
|
|
]
|
|
}
|
|
}
|
|
});
|
|
grunt.task.run('clean');
|
|
});
|
|
const glob = require('glob');
|
|
const ignoreFiles = ['jquery_native', 'fonts_ie', 'spell_ie', 'engine_ie', 'zlib_ie', 'drawingfile_ie', 'themes'];
|
|
/**
|
|
* @param {string[]} paths
|
|
* @param {string} cwd
|
|
* @return {[string[], string[]]}
|
|
*/
|
|
function splitJSFiles(paths, cwd) {
|
|
const jsFiles = [];
|
|
const noJSFiles = [];
|
|
paths.forEach((p) => {
|
|
glob.sync(p, {
|
|
cwd: cwd,
|
|
}).forEach((f) => {
|
|
if (path.extname(f) === '.js' && !ignoreFiles.includes(path.parse(f).name)) {
|
|
jsFiles.push(path.join(f));
|
|
} else {
|
|
noJSFiles.push(path.join(f));
|
|
}
|
|
})
|
|
});
|
|
return [jsFiles, noJSFiles];
|
|
}
|
|
function getOtherCompileConfig(o, jsFile) {
|
|
return {
|
|
'closure-compiler': {
|
|
js: {
|
|
options: {
|
|
args: [
|
|
'--language_out=ECMASCRIPT5',
|
|
'--compilation_level=WHITESPACE_ONLY',
|
|
'--rewrite_polyfills=true',
|
|
'--warning_level=QUIET',
|
|
`--js=${path.join(o.cwd, jsFile)}`,
|
|
`--js_output_file=${path.join(o.dest, jsFile)}`,
|
|
`--output_wrapper=${license}\n%output%`
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function getOtherCopyConfig(o, noJSFiles) {
|
|
return {
|
|
copy: {
|
|
sdkjs: {
|
|
files: noJSFiles.map(f => ({
|
|
expand: true,
|
|
cwd: o.cwd,
|
|
src: f,
|
|
dest: o.dest
|
|
}))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
grunt.registerTask('copy-other', 'Copy other SDK files', function () {
|
|
const compilerTasks = [];
|
|
const copyTasks = [];
|
|
otherFiles.forEach((o) => {
|
|
const [jsFiles, noJSFiles] = splitJSFiles(o.src, o.cwd);
|
|
if (jsFiles.length !== 0) {
|
|
jsFiles.forEach((f) => {
|
|
grunt.registerTask(`compile-${path.join(o.dest, f)}`, `Compiling ${path.join(o.dest, f)}`, function() {
|
|
grunt.initConfig(getOtherCompileConfig(o, f));
|
|
grunt.task.run('closure-compiler');
|
|
});
|
|
compilerTasks.push(`compile-${path.join(o.dest, f)}`);
|
|
});
|
|
}
|
|
if (noJSFiles.length !== 0) {
|
|
grunt.registerTask(`copy-${path.normalize(o.name)}`, `Copying files ${path.normalize(o.name)}`, function() {
|
|
grunt.initConfig(getOtherCopyConfig(o, noJSFiles));
|
|
grunt.task.run('copy');
|
|
});
|
|
copyTasks.push(`copy-${path.normalize(o.name)}`);
|
|
}
|
|
});
|
|
grunt.task.run(compilerTasks);
|
|
grunt.task.run(copyTasks);
|
|
});
|
|
grunt.registerTask('clean-develop', 'Clean develop scripts', function () {
|
|
const develop = '../develop/sdkjs/';
|
|
grunt.initConfig({
|
|
clean: {
|
|
tmp: {
|
|
options: {
|
|
force: true
|
|
}, src: [develop]
|
|
}
|
|
}
|
|
});
|
|
grunt.task.run('clean');
|
|
});
|
|
grunt.registerTask('build-develop', 'Build develop scripts', function () {
|
|
const configs = getConfigs();
|
|
if (!configs.valid()) {
|
|
return;
|
|
}
|
|
|
|
writeScripts(configs.word['sdk'], 'word');
|
|
writeScripts(configs.cell['sdk'], 'cell');
|
|
writeScripts(configs.slide['sdk'], 'slide');
|
|
writeScripts(configs.visio['sdk'], 'visio');
|
|
});
|
|
const defaultTasks = ['clean-deploy', 'compile-sdk', 'copy-other'];
|
|
if (grunt.option('map')) {
|
|
defaultTasks.push('copy-maps');
|
|
}
|
|
grunt.registerTask('default', defaultTasks);
|
|
grunt.registerTask('develop', ['clean-develop', 'build-develop']);
|
|
};
|