add mini-style popup to live edit
[chloro.git] / chloro / phyll / static / js / chloro.js
1 $(function() {
2   $('div[contenteditable]').on('input', function(event) {
3     if (event.originalEvent.inputType == "insertParagraph") {
4       var sel = document.getSelection();
5       var anchorNode = sel.anchorNode;
6       var prev_p = sel.anchorNode.previousSibling;
7       if (prev_p.tagName != 'P') {
8         prev_p = $(prev_p).parents('p')[0];
9       }
10       var title_match = prev_p.innerText.match(/^(h[1-6]). /);
11       if (title_match) {
12         var title = document.createElement(title_match[1]);
13         title.innerHTML = prev_p.innerHTML;
14         title.textContent = title.textContent.slice(4);
15         prev_p.replaceWith(title);
16       }
17     }
18     return true;
19   });
20
21   $('#save').on('click', function() {
22     var text = $('div[contenteditable]')[0].innerHTML;
23     $.post('api-save/', {text: text}).fail(function() {
24       $('#save').css('background', 'red');
25     });
26     return false;
27   });
28
29   var style_popup = null;
30   function update_style() {
31     var action = $(this).data('action');
32     var param = null;
33     if (action == 'code') {
34       action = 'insertHTML';
35       param = $('<code></code>', {text: window.getSelection().toString()})[0].outerHTML;
36     }
37     document.execCommand(action, false, param);
38   }
39
40   function show_style_popup(sel) {
41     if (style_popup === null) {
42       style_popup = $('<div id="style-popup">' +
43                       '<button data-action="italic"><i>i</i></button>' +
44                       '<button data-action="bold"><b>b</b></button>' +
45                       '<button data-action="code">#</button>' +
46                       '<button data-action="removeFormat">×</button>' +
47                       '</div>');
48       style_popup.hide();
49       style_popup.insertAfter($('div[contenteditable]'));
50       style_popup.find('button').on('click', update_style);
51     }
52     style_popup.css('position', 'absolute');
53     var pos = sel.getRangeAt(0).getClientRects()[0];
54     style_popup.css('top', pos.top + window.scrollY - $('main').offset().top - 33);
55     style_popup.css('left', pos.left + window.scrollX - $('main').offset().left);
56     style_popup.show();
57   };
58   $(document).on('selectionchange', function(event) {
59     var sel = window.getSelection();
60     if ($(sel.anchorNode).parents('div[contenteditable]').length && sel.toString()) {
61       show_style_popup(sel);
62     } else if (style_popup) {
63       $(style_popup).hide();
64     }
65   });
66 });