diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 3c601a09..4b1ee918 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -261,6 +261,10 @@
"message": "Regexp is invalid.",
"description": "Validation message for a bad regexp in a style"
},
+ "styleBeautify": {
+ "message": "Beautify",
+ "description": "Label for the CSS-beautifier button on the edit style page"
+ },
"styleCancelEditLabel": {
"message": "Back to manage",
"description": "Label for cancel button for style editing"
diff --git a/edit.html b/edit.html
index 1cc4fe9c..d7ae3780 100644
--- a/edit.html
+++ b/edit.html
@@ -124,7 +124,7 @@
#sections > div:only-of-type .remove-section {
display: none;
}
- #sections > div .add-section {
+ #sections > div > button:not(:first-of-type) {
margin-left: 0.4rem;
}
.dirty > label::before {
@@ -316,6 +316,28 @@
text-align: left;
}
+ /************ CSS beautifier ************/
+ .beautify-options {
+ white-space: nowrap;
+ font-family: monospace;
+ }
+ .beautify-options div {
+ float: left;
+ }
+ .beautify-options div[newline="true"] + div {
+ clear: left;
+ }
+ .beautify-options div[newline="true"] + div span[indent] {
+ padding-left: 2rem;
+ }
+ .beautify-options span {
+ font-weight: bold;
+ }
+ .beautify-options select {
+ border: none;
+ background-color: rgba(0, 0, 0, 0.05);
+ }
+
/************ reponsive layouts ************/
@media(max-width:737px) {
#header {
@@ -425,7 +447,7 @@
diff --git a/edit.js b/edit.js
index 21be4680..492c4e1b 100644
--- a/edit.js
+++ b/edit.js
@@ -44,6 +44,7 @@ var sectionTemplate = tHTML('\
\
\
\
+ \
\
');
@@ -483,6 +484,7 @@ function addSection(event, section) {
div.querySelector(".applies-to-help").addEventListener("click", showAppliesToHelp, false);
div.querySelector(".remove-section").addEventListener("click", removeSection, false);
div.querySelector(".add-section").addEventListener("click", addSection, false);
+ div.querySelector(".beautify-section").addEventListener("click", beautify);
var codeElement = div.querySelector(".code");
var appliesTo = div.querySelector(".applies-to-list");
@@ -825,6 +827,61 @@ function gotoLintIssue(event) {
});
}
+function beautify(event) {
+ if (exports.css_beautify) { // thanks to csslint's definition of 'exports'
+ doBeautify();
+ } else {
+ var script = document.head.appendChild(document.createElement("script"));
+ script.src = "beautify/beautify-css.js";
+ script.onload = doBeautify;
+ }
+ function doBeautify() {
+ var tabs = prefs.getPref("editor.indentWithTabs");
+ var options = prefs.getPref("editor.beautify");
+ options.indent_size = tabs ? 1 : prefs.getPref("editor.tabSize");
+ options.indent_char = tabs ? "\t" : " ";
+
+ var section = querySelectorParent(event.target, "#sections > div");
+ var scope = section ? [getCodeMirrorForSection(section)] : editors;
+ scope.forEach(function(cm) {
+ setTimeout(function() {
+ var text = cm.getValue();
+ var newText = exports.css_beautify(text, options);
+ if (newText != text) {
+ cm.setValue(newText);
+ }
+ }, 0);
+ });
+
+ showHelp(t("styleBeautify"), "
" +
+ optionHtml(".selector1,", "selector_separator_newline") +
+ optionHtml(".selector2,", "newline_before_open_brace") +
+ optionHtml("{", "newline_after_open_brace") +
+ optionHtml("border: none;", "newline_between_properties", true) +
+ optionHtml("display: block;", "newline_before_close_brace", true) +
+ optionHtml("}", "newline_between_rules") +
+ "
");
+
+ document.querySelector(".beautify-options").addEventListener("change", function(event) {
+ var value = event.target.selectedIndex > 0;
+ options[event.target.dataset.option] = value;
+ prefs.setPref("editor.beautify", options);
+ event.target.parentNode.setAttribute("newline", value.toString());
+ doBeautify();
+ });
+
+ function optionHtml(label, optionName, indent) {
+ var value = options[optionName];
+ return "" +
+ "" + label + "" +
+ "
";
+ }
+ }
+}
+
window.addEventListener("load", init, false);
function init() {
@@ -883,6 +940,7 @@ function initHooks() {
});
document.getElementById("to-mozilla").addEventListener("click", showMozillaFormat, false);
document.getElementById("to-mozilla-help").addEventListener("click", showToMozillaHelp, false);
+ document.getElementById("beautify").addEventListener("click", beautify);
document.getElementById("save-button").addEventListener("click", save, false);
document.getElementById("sections-help").addEventListener("click", showSectionHelp, false);
document.getElementById("keyMap-help").addEventListener("click", showKeyMapHelp, false);
diff --git a/storage.js b/storage.js
index f7f03cdc..6cddff58 100644
--- a/storage.js
+++ b/storage.js
@@ -180,6 +180,15 @@ var prefs = {
"editor.tabSize": 4, // tab width, in spaces
"editor.keyMap": navigator.appVersion.indexOf("Windows") > 0 ? "sublime" : "default",
"editor.theme": "default", // CSS theme
+ "editor.beautify": { // CSS beautifier
+ selector_separator_newline: true,
+ newline_before_open_brace: false,
+ newline_after_open_brace: true,
+ newline_between_properties: true,
+ newline_before_close_brace: true,
+ newline_between_rules: false,
+ end_with_newline: false
+ },
NO_DEFAULT_PREFERENCE: "No default preference for '%s'",
UNHANDLED_DATA_TYPE: "Default '%s' is of type '%s' - what should be done with it?",