add block toolbar to create a code section
authorFrédéric Péters <fpeters@0d.be>
Thu, 4 Jun 2020 16:13:25 +0000 (18:13 +0200)
committerFrédéric Péters <fpeters@0d.be>
Thu, 4 Jun 2020 16:14:09 +0000 (18:14 +0200)
chloro/phyll/static/css/style.scss
chloro/phyll/static/js/chloro.js

index e3fb0af250a9d97b8c95f82f43a7b2cf10d0d841..9c912ba699db19ea2aeebd29125e7bbe6726c412 100644 (file)
@@ -183,7 +183,7 @@ footer {
        }
 }
 
        }
 }
 
-#style-popup {
+.style-popup {
        background: white;
        input {
                display: none;
        background: white;
        input {
                display: none;
@@ -200,7 +200,6 @@ footer {
        button {
                padding: 0;
                height: 2em;
        button {
                padding: 0;
                height: 2em;
-               width: 2em;
                text-align: center;
                background: #eee;
                border: 1px outset #ccc;
                text-align: center;
                background: #eee;
                border: 1px outset #ccc;
@@ -213,4 +212,7 @@ footer {
                        text-decoration: underline;
                }
        }
                        text-decoration: underline;
                }
        }
+       &.short button {
+               width: 2em;
+       }
 }
 }
index c997bc792f12b6da36a579b5380ffdebc6042eac..4030c7c600ab6a1c87bb2103621972a2c01b3133 100644 (file)
@@ -4,6 +4,7 @@ $(function() {
       var sel = document.getSelection();
       var anchorNode = sel.anchorNode;
       var prev_p = sel.anchorNode.previousSibling;
       var sel = document.getSelection();
       var anchorNode = sel.anchorNode;
       var prev_p = sel.anchorNode.previousSibling;
+      if (! prev_p) return;
       if (prev_p.tagName != 'P') {
         prev_p = $(prev_p).parents('p')[0];
       }
       if (prev_p.tagName != 'P') {
         prev_p = $(prev_p).parents('p')[0];
       }
@@ -17,6 +18,16 @@ $(function() {
     }
     return true;
   });
     }
     return true;
   });
+  $('div[contenteditable]').on('keyup', function(event) {
+    var sel = document.getSelection();
+    if (sel.anchorNode instanceof Element && sel.anchorOffset == 0 && sel.isCollapsed) {
+      // start of line
+      show_block_style_popup();
+    } else {
+      hide_block_style_popup();
+    }
+    return true;
+  });
 
   $('#save').on('click', function() {
     var text = $('div[contenteditable]')[0].innerHTML;
 
   $('#save').on('click', function() {
     var text = $('div[contenteditable]')[0].innerHTML;
@@ -29,6 +40,48 @@ $(function() {
     return false;
   });
 
     return false;
   });
 
+  var block_style_popup = null;
+  function block_style() {
+    var action = $(this).data('action');
+    var class_name = null;
+    if (action == 'code') {
+      action = 'pre';
+      class_name = 'screen';
+    }
+    document.execCommand('formatBlock', false, action);
+    var sel = window.getSelection();
+    if (class_name) {
+      $(sel.anchorNode).addClass(class_name);
+    }
+    var range = document.createRange();
+    range.setStart(sel.anchorNode, 0);
+    sel.removeAllRanges();
+    sel.addRange(range);
+    hide_block_style_popup();
+  }
+  function show_block_style_popup() {
+    if (block_style_popup === null) {
+      block_style_popup = $(
+                      '<div class="style-popup">' +
+                      '<button data-action="code">code</button>' +
+                      '</div>');
+      block_style_popup.hide();
+      block_style_popup.insertAfter($('.actions'));
+      block_style_popup.find('button').on('click', block_style);
+    }
+    block_style_popup.css('position', 'absolute');
+    var sel = window.getSelection();
+    var pos = $(sel.anchorNode).offset();
+    block_style_popup.css('top', pos.top - 33);
+    block_style_popup.css('left', pos.left);
+    block_style_popup.show();
+  }
+  function hide_block_style_popup() {
+    if (block_style_popup) {
+      $(block_style_popup).hide();
+    }
+  }
+
   var style_popup = null;
   function update_style() {
     var action = $(this).data('action');
   var style_popup = null;
   function update_style() {
     var action = $(this).data('action');
@@ -81,7 +134,7 @@ $(function() {
 
   function show_style_popup(sel) {
     if (style_popup === null) {
 
   function show_style_popup(sel) {
     if (style_popup === null) {
-      style_popup = $('<div id="style-popup">' +
+      style_popup = $('<div class="style-popup short">' +
                       '<button data-action="italic"><i>i</i></button>' +
                       '<button data-action="bold"><b>b</b></button>' +
                       '<button data-action="code">#</button>' +
                       '<button data-action="italic"><i>i</i></button>' +
                       '<button data-action="bold"><b>b</b></button>' +
                       '<button data-action="code">#</button>' +