beautify.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. global CodeMirror loadScript css_beautify
  3. global editors getSectionForChild showHelp
  4. */
  5. 'use strict';
  6. function beautify(event) {
  7. loadScript('/vendor-overwrites/beautify/beautify-css-mod.js')
  8. .then(() => {
  9. if (!window.css_beautify && window.exports) {
  10. window.css_beautify = window.exports.css_beautify;
  11. }
  12. })
  13. .then(doBeautify);
  14. function doBeautify() {
  15. const tabs = prefs.get('editor.indentWithTabs');
  16. const options = prefs.get('editor.beautify');
  17. options.indent_size = tabs ? 1 : prefs.get('editor.tabSize');
  18. options.indent_char = tabs ? '\t' : ' ';
  19. const section = getSectionForChild(event.target);
  20. const scope = section ? [section.CodeMirror] : editors;
  21. showHelp(t('styleBeautify'), '<div class="beautify-options">' +
  22. optionHtml('.selector1,', 'selector_separator_newline') +
  23. optionHtml('.selector2,', 'newline_before_open_brace') +
  24. optionHtml('{', 'newline_after_open_brace') +
  25. optionHtml('border: none;', 'newline_between_properties', true) +
  26. optionHtml('display: block;', 'newline_before_close_brace', true) +
  27. optionHtml('}', 'newline_between_rules') +
  28. `<label style="display: block; clear: both;">
  29. <input data-option="indent_conditional" type="checkbox"
  30. ${options.indent_conditional !== false ? 'checked' : ''}>
  31. <svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>` +
  32. t('styleBeautifyIndentConditional') + '</label>' +
  33. '</div>' +
  34. '<div><button role="undo"></button></div>');
  35. $('#help-popup').className = 'wide';
  36. const undoButton = $('#help-popup button[role="undo"]');
  37. undoButton.textContent = t(scope.length === 1 ? 'undo' : 'undoGlobal');
  38. undoButton.addEventListener('click', () => {
  39. let undoable = false;
  40. scope.forEach(cm => {
  41. if (cm.beautifyChange && cm.beautifyChange[cm.changeGeneration()]) {
  42. delete cm.beautifyChange[cm.changeGeneration()];
  43. cm.undo();
  44. cm.scrollIntoView(cm.getCursor());
  45. undoable |= cm.beautifyChange[cm.changeGeneration()];
  46. }
  47. });
  48. undoButton.disabled = !undoable;
  49. });
  50. scope.forEach(cm => {
  51. setTimeout(() => {
  52. const pos = options.translate_positions =
  53. [].concat.apply([], cm.doc.sel.ranges.map(r =>
  54. [Object.assign({}, r.anchor), Object.assign({}, r.head)]));
  55. const text = cm.getValue();
  56. const newText = css_beautify(text, options);
  57. if (newText !== text) {
  58. if (!cm.beautifyChange || !cm.beautifyChange[cm.changeGeneration()]) {
  59. // clear the list if last change wasn't a css-beautify
  60. cm.beautifyChange = {};
  61. }
  62. cm.setValue(newText);
  63. const selections = [];
  64. for (let i = 0; i < pos.length; i += 2) {
  65. selections.push({anchor: pos[i], head: pos[i + 1]});
  66. }
  67. cm.setSelections(selections);
  68. cm.beautifyChange[cm.changeGeneration()] = true;
  69. undoButton.disabled = false;
  70. }
  71. }, 0);
  72. });
  73. $('.beautify-options').onchange = ({target}) => {
  74. const value = target.type === 'checkbox' ? target.checked : target.selectedIndex > 0;
  75. prefs.set('editor.beautify', Object.assign(options, {[target.dataset.option]: value}));
  76. if (target.parentNode.hasAttribute('newline')) {
  77. target.parentNode.setAttribute('newline', value.toString());
  78. }
  79. doBeautify();
  80. };
  81. function optionHtml(label, optionName, indent) {
  82. const value = options[optionName];
  83. return '<div newline="' + value.toString() + '">' +
  84. '<span' + (indent ? ' indent' : '') + '>' + label + '</span>' +
  85. '<div class="select-resizer">' +
  86. '<select data-option="' + optionName + '">' +
  87. '<option' + (value ? '' : ' selected') + '>&nbsp;</option>' +
  88. '<option' + (value ? ' selected' : '') + '>\\n</option>' +
  89. '</select>' +
  90. '<svg class="svg-icon select-arrow" viewBox="0 0 1792 1792">' +
  91. '<path fill-rule="evenodd" d="M1408 704q0 26-19 45l-448 448q-19 19-45 ' +
  92. '19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/>' +
  93. '</svg>' +
  94. '</div>' +
  95. '</div>';
  96. }
  97. }
  98. }