Note: it disables advanced optimizations by default.
Why:
* To give users better control over how optimizations are applied.
margin-top: 0;
}
+select {
+ font-size: 16px;
+}
+
.logo__link {
background: url(../img/logo.svg) no-repeat center 55%;
display: block;
.drag-target {
border: 5px dashed hsl(0, 0%, 90%);
margin-bottom: 2rem;
+ padding: 1rem;
+ position: relative;
+}
+
+.dropped-files {
+ list-style: none;
min-height: 10rem;
}
-.drag-target:empty:before {
+.dropped-files:empty:before {
content: attr(title);
color: hsl(0, 0%, 15%);
display: block;
font-weight: bold;
- height: inherit;
- padding-top: 3rem;
+ height: 10rem;
+ line-height: 12rem;
text-align: center;
text-transform: uppercase;
}
-.dropped-files {
- list-style: none;
- padding: 1rem;
-}
-
.dropped-files__file {
padding: 0.25rem 0.5rem;
}
margin-left: 0.5rem;
}
+.settings:not(.settings--collapsed) {
+ border-top: 3px solid hsl(0, 0%, 90%);
+ margin-top: 2rem;
+ padding: 1rem 0 0;
+}
+
+.settings--collapsed {
+ cursor: pointer;
+ height: 1rem;
+}
+
+.settings--collapsed:before {
+ background: url(../img/gear.svg) center center no-repeat;
+ bottom: 1rem;
+ content: " ";
+ display: block;
+ height: 1.5rem;
+ right: 1rem;
+ position: absolute;
+ width: 1.5rem;
+}
+
+.settings--collapsed > .settings__group {
+ display: none;
+}
+
+.settings__group {
+ border: none;
+}
+
+.settings__group {
+ padding: 0.25rem 0 0.25rem 0.75rem;
+}
+
+.settings__group:not(:last-child) {
+ border-left: 0.25rem solid hsl(198, 76%, 52%);
+ margin-bottom: 0.5rem;
+}
+
+.settings__group__wrapper:not(:last-child) {
+ margin-bottom: 0.25rem;
+}
+
+.settings__option--version {
+ width: 100%;
+}
+
+.settings__option--checkbox {
+ vertical-align: 1px;
+}
+
+.settings__option--checkbox:disabled + .settings__label {
+ color: hsl(0, 0%, 40%);
+}
+
+.settings__option--precision {
+ text-align: center;
+ width: 2.5rem;
+}
+
+.settings__option--compatibility {
+ width: 100%;
+}
+
+.settings__option--keep-special-comments {
+ width: 100%;
+}
+
+.settings__option--apply {
+ background: transparent;
+ border: 1px solid hsl(0, 0%, 80%);
+ float: right;
+ padding: 0.5rem 1rem;
+}
+
.clipboard-copy {
border: none;
height: 2rem;
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px" height="24px" viewBox="0 0 24 24"><g >
+<path fill="#343434" d="M23,14v-4h-3.262c-0.189-0.732-0.477-1.422-0.852-2.058l2.306-2.306l-2.828-2.828l-2.306,2.306
+C15.422,4.739,14.732,4.451,14,4.262V1h-4v3.262C9.268,4.451,8.578,4.739,7.942,5.114L5.636,2.808L2.808,5.636l2.306,2.306
+C4.739,8.578,4.451,9.268,4.262,10H1v4h3.262c0.189,0.732,0.477,1.422,0.852,2.058l-2.306,2.306l2.828,2.828l2.306-2.306
+c0.635,0.375,1.326,0.663,2.058,0.852V23h4v-3.262c0.732-0.189,1.422-0.477,2.058-0.852l2.306,2.306l2.828-2.828l-2.306-2.306
+c0.375-0.635,0.663-1.326,0.852-2.058H23z M12,15c-1.657,0-3-1.343-3-3s1.343-3,3-3s3,1.343,3,3S13.657,15,12,15z"/>
+</g></svg>
\ No newline at end of file
<link rel="stylesheet" type="text/css" href="css/home.css"/>
<script src="js/optimizer.js"></script>
<script src="js/drag-drop.js"></script>
+ <script src="js/settings.js"></script>
</head>
<body>
<h1 class="logo">
<a class="logo__link" href="//github.com/jakubpawlowicz/clean-css" title="Go to clean-css project page">Go to clean-css project page</a>
</h1>
<article class="content">
- <ol class="drag-target dropped-files" title="Drop your files here to optimize them"></ol>
+ <section class="drag-target">
+ <ol class="dropped-files" title="Drop your files here to optimize them"></ol>
+ <form class="settings settings--collapsed">
+ <fieldset class="settings__group">
+ <select class="settings__option settings__option--version" name="version">
+ <option value="v3.4.20" selected>3.4.20 (latest)</option>
+ </select>
+ </fieldset>
+ <fieldset class="settings__group settings__group--advanced">
+ <div class="settings__group__wrapper">
+ <input class="settings__option settings__option--checkbox settings__option--advanced" type="checkbox" id="advanced" name="advanced" />
+ <label class="settings__label" for="advanced">advanced optimizations</label>
+ </div>
+ <div class="settings__group__wrapper">
+ <input class="settings__option settings__option--checkbox" type="checkbox" id="aggressive_merging" name="aggressive-merging" disabled />
+ <label class="settings__label" for="aggressive_merging">aggressive merging</label>
+ </div>
+ <div class="settings__group__wrapper">
+ <input class="settings__option settings__option--checkbox" type="checkbox" id="media_merging" name="media-merging" disabled />
+ <label class="settings__label" for="media_merging">@media merging</label>
+ </div>
+ <div class="settings__group__wrapper">
+ <input class="settings__option settings__option--checkbox" type="checkbox" id="restructuring" name="restructuring" disabled />
+ <label class="settings__label" for="restructuring">restructuring</label>
+ </div>
+ <div class="settings__group__wrapper">
+ <input class="settings__option settings__option--checkbox" type="checkbox" id="shorthand_compacting" name="shorthand-compacting" disabled />
+ <label class="settings__label" for="shorthand_compacting">shorthand compacting</label>
+ </div>
+ </fieldset>
+ <fieldset class="settings__group">
+ <div class="settings__group__wrapper">
+ <input class="settings__option" type="checkbox" id="keep_breaks" name="keep-breaks" checked />
+ <label class="settings__label" for="keep_breaks">keep line breaks</label>
+ </div>
+ <div class="settings__group__wrapper">
+ <input class="settings__option settings__option--precision" type="number" min="-1" max="999999" id="rounding_precision" name="rounding-precision" value="2" />
+ <label class="settings__label" for="rounding_precision">rounding precision</label>
+ </div>
+ <div class="settings__group__wrapper">
+ <select class="settings__option settings__option--compatibility" id="compatibility" name="compatibility">
+ <option value="" selected>Modern browsers compatibility</option>
+ <option value="ie8">Modern browsers & Internet Explorer 8 compatibility</option>
+ <option value="ie7">Modern browsers & Internet Explorer 7/8 compatibility</option>
+ </select>
+ </div>
+ <div class="settings__group__wrapper">
+ <select class="settings__option settings__option--keep-special-comments" id="keep_special_comments" name="keep-special-comments">
+ <option value="*" selected>Keep all special comments</option>
+ <option value="1">Remove all special but one special comment</option>
+ <option value="0">Remove all special comments</option>
+ </select>
+ </div>
+ </fieldset>
+ <fieldset class="settings__group">
+ <input class="settings__option settings__option--apply" type="button" name="" value="Apply"/>
+ </fieldset>
+ </form>
+ </section>
<p class="legend">
CSS optimizing happens directly in your browser using a browser-compatible build of clean-css. If you miss any functionality, you are more than welcome to <a href="//github.com/jakubpawlowicz/clean-css/tree/master/docs">add it</a>!
</p>
window.addEventListener('DOMContentLoaded', function () {
var dragTarget = document.querySelector('.drag-target')
+ var dropContainer = document.querySelector('.dropped-files')
dragTarget.addEventListener('dragenter', fileDraggedIn, false)
dragTarget.addEventListener('dragover', fileDraggedOver, false)
- dragTarget.addEventListener('drop', fileDropped(dragTarget), false)
+ dragTarget.addEventListener('drop', fileDropped(dropContainer), false)
Optimizer.oncomplete = optimizationCompleted
})
switch (event.data.command) {
case 'optimize':
- new CleanCSS().minify(event.data.input, function (error, output) {
+ new CleanCSS(event.data.options).minify(event.data.input, function (error, output) {
postMessage({
command: 'optimized',
id: event.data.id,
Optimizer = {
+ options: null, // see setOptionsFrom in settings.js
+
start: function () {
this.worker = new Worker('./js/optimizer-worker.js')
this.worker.onmessage = function (event) {
this.worker.postMessage({
command: 'optimize',
id: id,
- input: styles
+ input: styles,
+ options: this.options
})
},
--- /dev/null
+(function () {
+ function show(settingsForm) {
+ return function (event) {
+ if (event.target.classList.contains('settings__option--apply'))
+ return
+
+ if (settingsForm.classList.contains('settings--collapsed')) {
+ event.preventDefault()
+ settingsForm.classList.remove('settings--collapsed')
+ }
+ }
+ }
+
+ function hide(settingsForm) {
+ return function (event) {
+ event.preventDefault()
+ settingsForm.classList.add('settings--collapsed')
+ }
+ }
+
+ function setOptionsFrom(settingsForm) {
+ return function () {
+ Optimizer.options = {
+ advanced: settingsForm.querySelector('[name=advanced]').checked,
+ aggressiveMerging: settingsForm.querySelector('[name=aggressive-merging]').checked,
+ compatibility: settingsForm.querySelector('[name=compatibility]').value,
+ keepBreaks: settingsForm.querySelector('[name=keep-breaks]').checked,
+ keepSpecialComments: keepSpecialCommentsFrom(settingsForm.querySelector('[name=keep-special-comments]').value),
+ mediaMerging: settingsForm.querySelector('[name=media-merging]').checked,
+ processImport: false,
+ rebase: false,
+ restructuring: settingsForm.querySelector('[name=restructuring]').checked,
+ roundingPrecision: parseInt(settingsForm.querySelector('[name=rounding-precision]').value),
+ shorthandCompacting: settingsForm.querySelector('[name=shorthand-compacting]').checked
+ }
+ }
+ }
+
+ function keepSpecialCommentsFrom(value) {
+ if (/^\d+$/.test(value)) {
+ return parseInt(value)
+ } else {
+ return value
+ }
+ }
+
+ function toggleAdvancedOptionsIn(settingsForm) {
+ var checkboxNodes = settingsForm.querySelectorAll('.settings__group--advanced .settings__option--checkbox')
+
+ return function () {
+ Array.prototype.slice.call(checkboxNodes, 1).forEach(function (node) {
+ node.disabled = !node.disabled
+ node.checked = !node.checked
+ })
+ }
+ }
+
+ window.addEventListener('DOMContentLoaded', function () {
+ var settingsForm = document.querySelector('.settings')
+ var applySettingsButton = settingsForm.querySelector('.settings__option--apply')
+ var advancedOptionNode = settingsForm.querySelector('.settings__option--advanced')
+
+ settingsForm.addEventListener('click', show(settingsForm), false)
+ applySettingsButton.addEventListener('click', hide(settingsForm), false)
+ applySettingsButton.addEventListener('click', setOptionsFrom(settingsForm), false)
+ advancedOptionNode.addEventListener('click', toggleAdvancedOptionsIn(settingsForm), false)
+
+ setOptionsFrom(settingsForm)()
+ })
+})()