diff --git a/src/css/components/_settings.scss b/src/css/components/_settings.scss
index 361671386..5faff2095 100644
--- a/src/css/components/_settings.scss
+++ b/src/css/components/_settings.scss
@@ -64,11 +64,12 @@
color: #767676;
}
-.setting-reset-row {
+.setting-actions {
padding: 12px 16px 16px;
text-align: right;
}
+.setting-download,
.setting-reset {
text-transform: uppercase;
color: #fff;
diff --git a/src/index.html b/src/index.html
index f7766fc7b..392aeb66a 100644
--- a/src/index.html
+++ b/src/index.html
@@ -152,7 +152,8 @@
Features
{% endfor %}
-
diff --git a/src/js/page/ui/settings.js b/src/js/page/ui/settings.js
index cac3d1a01..87dfe9435 100644
--- a/src/js/page/ui/settings.js
+++ b/src/js/page/ui/settings.js
@@ -1,4 +1,5 @@
import { createNanoEvents } from 'nanoevents';
+import { download } from '../../utils/download.js';
import { domReady } from '../utils.js';
import MaterialSlider from './material-slider.js';
import Ripple from './ripple.js';
@@ -18,12 +19,16 @@ export default class Settings {
];
const scroller = this.container.querySelector('.settings-scroller');
+ const exportBtn = this.container.querySelector('.setting-export');
const resetBtn = this.container.querySelector('.setting-reset');
const ranges = this.container.querySelectorAll('input[type=range]');
this._resetRipple = new Ripple();
resetBtn.append(this._resetRipple.container);
+ this._exportRipple = new Ripple();
+ exportBtn.append(this._exportRipple.container);
+
// map real range elements to Slider instances
this._sliderMap = new WeakMap();
@@ -33,9 +38,10 @@ export default class Settings {
}
this.container.addEventListener('input', (event) =>
- this._onChange(event),
+ this._onChange(event)
);
resetBtn.addEventListener('click', () => this._onReset());
+ exportBtn.addEventListener('click', () => this._onExport());
// TODO: revisit this
// Stop double-tap text selection.
@@ -55,7 +61,7 @@ export default class Settings {
if (event.target.type === 'range') {
this._throttleTimeout = setTimeout(
() => this.emitter.emit('change'),
- 150,
+ 150
);
} else {
this.emitter.emit('change');
@@ -83,6 +89,41 @@ export default class Settings {
this.emitter.emit('change');
}
+ _onExport() {
+ this._exportRipple.animate();
+
+ const { fingerprint, multipass, pretty, ...settings } = this.getSettings();
+ const floatPrecision = Number(settings.floatPrecision);
+ const plugins = [];
+
+ for (const [name, active] of Object.entries(settings.plugins)) {
+ if (!active) continue;
+
+ const plugin = {
+ name,
+ params: {},
+ };
+
+ plugin.params.floatPrecision =
+ plugin.name === 'cleanupNumericValues' && floatPrecision === 0
+ ? 1
+ : floatPrecision;
+
+ plugins.push(plugin);
+ }
+
+ const file = 'module.exports = ' + JSON.stringify({
+ multipass,
+ plugins,
+ js2svg: {
+ indent: ' ',
+ pretty,
+ },
+ }, null, 2)
+
+ download('svgo.config.js', file)
+ }
+
setSettings(settings) {
for (const inputEl of this._globalInputs) {
if (!(inputEl.name in settings)) continue;
diff --git a/src/js/utils/download.js b/src/js/utils/download.js
new file mode 100644
index 000000000..2bd609c54
--- /dev/null
+++ b/src/js/utils/download.js
@@ -0,0 +1,15 @@
+export function download(filename, text) {
+ const element = document.createElement('a');
+ element.setAttribute(
+ 'href',
+ 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)
+ );
+ element.setAttribute('download', filename);
+
+ element.style.display = 'none';
+ document.body.appendChild(element);
+
+ element.click();
+
+ document.body.removeChild(element);
+}