From 58fd0d68bc8b46b23f8cdc65190f08d4e524eb57 Mon Sep 17 00:00:00 2001 From: Ulrich-Matthias Schäfer Date: Wed, 28 Nov 2018 12:57:52 +0100 Subject: Fix build chain so that we now have multiple builds. Details below: - svg.js: The esm bundle - svg.min.js: The bundle for all browsers for maximum support - svg.node.js: The bundle for node - polyfill.js: Using svg.min.js requires this polyfill in case the Browser does not understand all of ./config/polyfillList.js - polyfillIE.js: This is required when you use IE11 (polyfill.js still required) Please note, that not all test pass for IE11 due to its rounding issues and wrong calculation of bbox. Also note, that `defaultPrevented` is not working for CustomEvents in IE11. --- .config/karma.conf.common.js | 4 +- .config/karma.conf.js | 10 +- .config/karma.conf.saucelabs.js | 39 +- .config/polyfillList.js | 9 +- .config/polyfillListIE.js | 31 + .config/pretest.js | 24 +- .config/rollup.config.js | 174 +- .config/rollup.polyfills.js | 36 +- .travis.yml | 7 +- bower.json | 4 +- dirty.html | 59 +- dist/polyfills.js | 2 +- dist/polyfillsIE.js | 1 + dist/svg.js | 12176 +++++++++++++++++++------------------- dist/svg.js.map | 1 + dist/svg.min.js | 3 + dist/svg.min.js.map | 1 + dist/svg.node.js | 6430 ++++++++++++++++++++ dist/svg.node.js.map | 1 + package-lock.json | 48 +- package.json | 29 +- spec/SpecRunner.html | 4 +- spec/spec/arrange.js | 15 +- spec/spec/event.js | 3 +- spec/spec/helper.js | 2 +- spec/spec/morphing.js | 20 +- spec/spec/runner.js | 10 +- spec/spec/svg.js | 4 +- src/animation/Morphable.js | 9 +- src/main.js | 1 + src/polyfills/children.js | 8 + src/polyfills/innerHTML.js | 95 + src/utils/adopter.js | 2 +- src/utils/methods.js | 13 +- 34 files changed, 12813 insertions(+), 6462 deletions(-) create mode 100644 .config/polyfillListIE.js create mode 100644 dist/polyfillsIE.js create mode 100644 dist/svg.js.map create mode 100644 dist/svg.min.js create mode 100644 dist/svg.min.js.map create mode 100644 dist/svg.node.js create mode 100644 dist/svg.node.js.map create mode 100644 src/polyfills/children.js create mode 100644 src/polyfills/innerHTML.js diff --git a/.config/karma.conf.common.js b/.config/karma.conf.common.js index 56c249f..a89c8e6 100644 --- a/.config/karma.conf.common.js +++ b/.config/karma.conf.common.js @@ -31,7 +31,7 @@ module.exports = function (config) { included: false, served: true }, - 'dist/svg.js', + 'dist/svg.min.js', 'spec/spec/*.js' ], @@ -61,6 +61,6 @@ module.exports = function (config) { concurrency: cpuCount || Infinity, // list of files to exclude - exclude: [], + exclude: [] } } diff --git a/.config/karma.conf.js b/.config/karma.conf.js index 57cf14f..ccda070 100644 --- a/.config/karma.conf.js +++ b/.config/karma.conf.js @@ -23,7 +23,7 @@ module.exports = function (config) { // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { - 'dist/svg.js': ['coverage'] + 'dist/svg.min.js': ['coverage'] }, // this specifies which plugins karma should load @@ -35,7 +35,7 @@ module.exports = function (config) { 'karma-chrome-launcher', 'karma-coverage', 'karma-firefox-launcher', - 'karma-jasmine', + 'karma-jasmine' ], // test results reporter to use @@ -48,15 +48,15 @@ module.exports = function (config) { // Specify a reporter type. type: 'lcov', dir: 'coverage/', - subdir: function(browser) { + subdir: function (browser) { // normalization process to keep a consistent browser name accross different OS - return browser.toLowerCase().split(/[ /-]/)[0]; // output the results into: './coverage/firefox/' + return browser.toLowerCase().split(/[ /-]/)[0] // output the results into: './coverage/firefox/' } }, // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: [chromeBin, 'FirefoxHeadless'], + browsers: [chromeBin, 'FirefoxHeadless'] }) ) } diff --git a/.config/karma.conf.saucelabs.js b/.config/karma.conf.saucelabs.js index 922d749..089f25a 100644 --- a/.config/karma.conf.saucelabs.js +++ b/.config/karma.conf.saucelabs.js @@ -9,8 +9,8 @@ const karmaCommon = require('./karma.conf.common.js') const SauceLabsLaunchers = { /** Real mobile devices are not available * Your account does not have access to Android devices. - * Please contact sales@saucelabs.com to add this feature to your account.*/ - /*sl_android_chrome: { + * Please contact sales@saucelabs.com to add this feature to your account. */ + /* sl_android_chrome: { base: 'SauceLabs', appiumVersion: '1.5.3', deviceName: 'Samsung Galaxy S7 Device', @@ -18,13 +18,13 @@ const SauceLabsLaunchers = { browserName: 'Chrome', platformVersion: '6.0', platformName: 'Android' - },*/ + }, */ /* sl_android: { base: 'SauceLabs', browserName: 'Android', deviceName: 'Android Emulator', deviceOrientation: 'portrait' - },*/ + }, */ SL_firefox_latest: { base: 'SauceLabs', browserName: 'firefox', @@ -39,7 +39,7 @@ const SauceLabsLaunchers = { base: 'SauceLabs', browserName: 'internet explorer', version: '11.0' - },/* + }/* sl_windows_edge: { base: 'SauceLabs', browserName: 'MicrosoftEdge', @@ -83,12 +83,10 @@ const SauceLabsLaunchers = { } */ } - -module.exports = function(config) { - +module.exports = function (config) { if (!process.env.SAUCE_USERNAME || !process.env.SAUCE_ACCESS_KEY) { - console.error("SAUCE_USERNAME and SAUCE_ACCESS_KEY must be provided as environment variables.") - console.warn("Aborting Sauce Labs test") + console.error('SAUCE_USERNAME and SAUCE_ACCESS_KEY must be provided as environment variables.') + console.warn('Aborting Sauce Labs test') process.exit(1) } const settings = Object.assign(karmaCommon(config), { @@ -104,7 +102,7 @@ module.exports = function(config) { // get possible karma plugins by `ls node_modules | grep 'karma-*'` plugins: [ 'karma-jasmine', - 'karma-sauce-launcher', + 'karma-sauce-launcher' ], // logLevel: config.LOG_DEBUG, @@ -119,15 +117,15 @@ module.exports = function(config) { // start these browsers browsers: Object.keys(SauceLabsLaunchers), sauceLabs: { - testName: 'SVG.js Unit Tests', - // connectOptions: { - // noSslBumpDomains: "all" - // }, - // connectOptions: { - // port: 5757, - // logfile: 'sauce_connect.log' - // }, - }, + testName: 'SVG.js Unit Tests' + // connectOptions: { + // noSslBumpDomains: "all" + // }, + // connectOptions: { + // port: 5757, + // logfile: 'sauce_connect.log' + // }, + } // The number of disconnections tolerated. // browserDisconnectTolerance: 0, // well, sometimes it helps to just restart @@ -144,5 +142,4 @@ module.exports = function(config) { console.log(settings) config.set(settings) - } diff --git a/.config/polyfillList.js b/.config/polyfillList.js index 34ef4b6..37f80bd 100644 --- a/.config/polyfillList.js +++ b/.config/polyfillList.js @@ -1,11 +1,8 @@ -import 'core-js/modules/es6.function.name' +import 'core-js/modules/es6.object.assign' import 'core-js/modules/es6.object.keys' +import 'core-js/modules/es6.function.name' import 'core-js/modules/es6.symbol' import 'core-js/modules/es6.set' import 'core-js/modules/es7.array.includes' import 'core-js/modules/es6.string.includes' -import 'core-js/modules/es6.array.iterator' -import 'core-js/modules/es7.object.entries' -import 'core-js/modules/es6.object.assign' -import CustomEventPolyfill from '@target/custom-event-polyfill' -CustomEventPolyfill() +import 'core-js/modules/es6.array.from' diff --git a/.config/polyfillListIE.js b/.config/polyfillListIE.js new file mode 100644 index 0000000..dbffbc5 --- /dev/null +++ b/.config/polyfillListIE.js @@ -0,0 +1,31 @@ +/* global SVGElement */ +/* eslint no-new-object: "off" */ + +import CustomEventPolyfill from '@target/custom-event-polyfill/src/index.js6' +import children from '../src/polyfills/children.js' + +/* IE 11 has no innerHTML on SVGElement */ +import '../src/polyfills/innerHTML.js' + +/* IE 11 has no correct CustomEvent implementation */ +CustomEventPolyfill() + +/* IE 11 has no children on SVGElement */ +try { + if (!SVGElement.prototype.children) { + Object.defineProperty(SVGElement.prototype, 'children', { + get: function () { return children(this) } + }) + } +} catch (e) {} + +/* IE 11 cannot handle getPrototypeOf(not_obj) */ +try { + delete Object.getPrototypeOf('test') +} catch (e) { + var old = Object.getPrototypeOf + Object.getPrototypeOf = function (o) { + if (typeof o !== 'object') o = new Object(o) + return old.call(this, o) + } +} diff --git a/.config/pretest.js b/.config/pretest.js index 834e8d8..23b989e 100644 --- a/.config/pretest.js +++ b/.config/pretest.js @@ -1,20 +1,20 @@ +/* global XMLHttpRequest */ 'use strict' -function get(uri) { - var xhr = new XMLHttpRequest() - xhr.open('GET', uri, false) - xhr.send() - if(xhr.status !== 200) - console.error('SVG.js fixture could not be loaded. Tests will fail.') - return xhr.responseText +function get (uri) { + var xhr = new XMLHttpRequest() + xhr.open('GET', uri, false) + xhr.send() + if (xhr.status !== 200) { console.error('SVG.js fixture could not be loaded. Tests will fail.') } + return xhr.responseText } -function main() { - var style = document.createElement("style") - document.head.appendChild(style) - style.sheet.insertRule( get('/fixtures/fixture.css'), 0 ) +function main () { + var style = document.createElement('style') + document.head.appendChild(style) + style.sheet.insertRule(get('/fixtures/fixture.css'), 0) - document.body.innerHTML = get('/fixtures/fixture.svg') + document.body.innerHTML = get('/fixtures/fixture.svg') } main() diff --git a/.config/rollup.config.js b/.config/rollup.config.js index b7ad5d8..32096e5 100644 --- a/.config/rollup.config.js +++ b/.config/rollup.config.js @@ -1,7 +1,10 @@ import babel from 'rollup-plugin-babel' import * as pkg from '../package.json' -// import filesize from 'rollup-plugin-filesize' -import { terser } from 'rollup-plugin-terser' +import filesize from 'rollup-plugin-filesize' +// import { terser } from 'rollup-plugin-terser' +import resolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs' +import { uglify } from 'rollup-plugin-uglify' const buildDate = Date() @@ -18,94 +21,97 @@ const headerLong = `/*! const headerShort = `/*! ${pkg.name} v${pkg.version} ${pkg.license}*/;` +const getBabelConfig = (esm, targets = { esmodules: true }, corejs = false) => babel({ + include: 'src/**', + runtimeHelpers: true, + babelrc: false, + presets: [['@babel/preset-env', { + modules: false, + targets: esm ? targets : pkg.browserslist, + useBuiltIns: 'usage' + }]], + plugins: [['@babel/plugin-transform-runtime', { + corejs: corejs, + helpers: true, + useESModules: true + }]] +}) + +// When few of these get mangled nothing works anymore +// We loose literally nothing by let these unmangled +const classes = [ + 'A', + 'ClipPath', + 'Defs', + 'Element', + 'G', + 'Image', + 'Marker', + 'Path', + 'Polygon', + 'Rect', + 'Stop', + 'Svg', + 'Text', + 'Tspan', + 'Circle', + 'Container', + 'Dom', + 'Ellipse', + 'Gradient', + 'Line', + 'Mask', + 'Pattern', + 'Polyline', + 'Shape', + 'Style', + 'Symbol', + 'TextPath', + 'Use' +] + const config = esm => ({ - input: './src/svg.js', + input: esm ? './src/main.js' : './src/svg.js', output: { file: esm ? './dist/svg.js' : './dist/svg.min.js', name: 'SVG', - sourceMap: !esm, + sourcemap: 'external', format: esm ? 'esm' : 'iife', - banner: esm ? headerShort : headerLong, - plugins: - esm - ? [] - : [ - babel({ - include: 'src/**', - runtimeHelpers: true, - babelrc: false, - presets: [["@babel/preset-env", { - modules: false, - targets: { - ie: 9, - chrome: 49, - edge: 14, - firefox: 45, - safari: 10 - }, - useBuiltIns: 'usage' - }]] - }), - terser() - ] - } + banner: esm ? headerLong : headerShort + }, + plugins: [ + resolve({ browser: true }), + commonjs(), + getBabelConfig(esm), + filesize(), + esm ? {} : uglify({ + mangle: { + reserved: classes + }, + output: { + preamble: headerShort + } + }) + ] }) -const modes = [true, false] +const nodeConfig = () => ({ + input: './src/main.js', + output: { + file: './dist/svg.node.js', + name: 'SVG', + sourcemap: 'external', + format: 'cjs', + banner: headerLong + }, + plugins: [ + resolve(), + commonjs(), + getBabelConfig(true, 'maintained node versions'), + filesize() + ] +}) -// console.log(modes.map(config)) -export default modes.map(config) +const modes = [true, false] -// export default [ -// { -// input: './src/svg.js', -// output: { -// file: 'dist/svg.js', -// name: 'SVG', -// sourceMap: true, -// format: 'iife', -// banner: headerLong -// }, -// plugins: [ -// // resolve({browser: true}), -// // commonjs(), -// babel({ -// include: 'src/**', -// runtimeHelpers: true, -// babelrc: false, -// presets: [["@babel/preset-env", { -// modules: false, -// targets: { -// ie: "9" -// }, -// useBuiltIns: 'usage' -// }]], -// }), -// filesize() -// ] -// },{ -// input: './.config/polyfills.js', -// output: { -// file: 'dist/polyfills.js', -// name: 'SVG', -// sourceMap: true, -// format: 'umd', -// banner: headerLong -// }, -// treeshake: false, -// plugins: [ -// // babel({ -// // runtimeHelpers: true, -// // babelrc: false, -// // presets: [["@babel/preset-env", { -// // modules: false, -// // targets: { -// // ie: "11" -// // }, -// // useBuiltIns: 'usage' -// // }]], -// // }), -// filesize() -// ] -// }, -// ] +export default modes.map(config).concat(nodeConfig()) diff --git a/.config/rollup.polyfills.js b/.config/rollup.polyfills.js index 810db91..1df059a 100644 --- a/.config/rollup.polyfills.js +++ b/.config/rollup.polyfills.js @@ -1,20 +1,22 @@ -import { uglify } from "rollup-plugin-uglify" import resolve from 'rollup-plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' +import { terser } from 'rollup-plugin-terser' +import filesize from 'rollup-plugin-filesize' -export default [ - { - input: './.config/polyfillList.js', - output: { - file: 'dist/polyfills.js', - name: 'polyfills', - sourceMap: 'external', - format: 'iife' - }, - plugins: [ - resolve({browser: true}), - commonjs(), - uglify() - ] - } -] +// We dont need babel. All polyfills are compatible +const config = (ie) => ({ + input: ie ? './.config/polyfillListIE.js' : './.config/polyfillList.js', + output: { + file: ie ? 'dist/polyfillsIE.js' : 'dist/polyfills.js', + sourceMap: false, + format: 'iife' + }, + plugins: [ + resolve({ browser: true }), + commonjs(), + terser(), + filesize() + ] +}) + +export default [false, true].map(config) diff --git a/.travis.yml b/.travis.yml index 9b7ad70..2a833bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,12 @@ node_js: - "stable" script: - npm run build - - npm run test:ci + - npm run test +# - npm run test:ci # - cat coverage/firefox/lcov.info | node_modules/.bin/coveralls addons: -# firefox: "latest" -# chrome: "stable" + firefox: "latest" + chrome: "stable" # hosts: # - karmalocal.com before_install: diff --git a/bower.json b/bower.json index 8480d11..83a41a3 100644 --- a/bower.json +++ b/bower.json @@ -7,7 +7,7 @@ "Jon Ege Ronnenberg " ], "description": "A lightweight library for manipulating and animating SVG", - "main": "dist/svg.js", + "main": "dist/svg.min.js", "keywords": [ "svg", "vector", "graphics" ], @@ -18,4 +18,4 @@ "src/", "gulpfile.js" ] -} \ No newline at end of file +} diff --git a/dirty.html b/dirty.html index 3fd1412..900c738 100644 --- a/dirty.html +++ b/dirty.html @@ -4,7 +4,9 @@ - + + + @@ -29,27 +31,30 @@ +
- + -