add mini-style popup to live edit
authorFrédéric Péters <fpeters@0d.be>
Thu, 4 Jun 2020 13:32:38 +0000 (15:32 +0200)
committerFrédéric Péters <fpeters@0d.be>
Thu, 4 Jun 2020 13:32:56 +0000 (15:32 +0200)
chloro/phyll/static/css/style.scss
chloro/phyll/static/js/chloro.js

index 5e2f05b..50b7bf0 100644 (file)
@@ -62,6 +62,7 @@ main, footer {
 }
 
 main {
+       position: relative;
        background: #fafaff;
        min-height: 70vh;
        clip-path: polygon(0px 0px, 96.35% -24px, 101.99% 7.86%, 100.61% 103.56%, 10% 100%, 0% 100%, 0px 0px);
@@ -181,3 +182,19 @@ footer {
                font-size: 100%;
        }
 }
+
+#style-popup {
+       background: white;
+       button {
+               padding: 0;
+               height: 2em;
+               width: 2em;
+               text-align: center;
+               background: #eee;
+               border: 1px outset #ccc;
+               margin-right: 1px;
+               &:hover {
+                       background: #ccc;
+               }
+       }
+}
index 9988be4..066c573 100644 (file)
@@ -17,6 +17,7 @@ $(function() {
     }
     return true;
   });
+
   $('#save').on('click', function() {
     var text = $('div[contenteditable]')[0].innerHTML;
     $.post('api-save/', {text: text}).fail(function() {
@@ -24,4 +25,42 @@ $(function() {
     });
     return false;
   });
+
+  var style_popup = null;
+  function update_style() {
+    var action = $(this).data('action');
+    var param = null;
+    if (action == 'code') {
+      action = 'insertHTML';
+      param = $('<code></code>', {text: window.getSelection().toString()})[0].outerHTML;
+    }
+    document.execCommand(action, false, param);
+  }
+
+  function show_style_popup(sel) {
+    if (style_popup === null) {
+      style_popup = $('<div id="style-popup">' +
+                      '<button data-action="italic"><i>i</i></button>' +
+                      '<button data-action="bold"><b>b</b></button>' +
+                      '<button data-action="code">#</button>' +
+                      '<button data-action="removeFormat">×</button>' +
+                      '</div>');
+      style_popup.hide();
+      style_popup.insertAfter($('div[contenteditable]'));
+      style_popup.find('button').on('click', update_style);
+    }
+    style_popup.css('position', 'absolute');
+    var pos = sel.getRangeAt(0).getClientRects()[0];
+    style_popup.css('top', pos.top + window.scrollY - $('main').offset().top - 33);
+    style_popup.css('left', pos.left + window.scrollX - $('main').offset().left);
+    style_popup.show();
+  };
+  $(document).on('selectionchange', function(event) {
+    var sel = window.getSelection();
+    if ($(sel.anchorNode).parents('div[contenteditable]').length && sel.toString()) {
+      show_style_popup(sel);
+    } else if (style_popup) {
+      $(style_popup).hide();
+    }
+  });
 });