--- /dev/null
+// from django/contrib/admin/static/admin/js/urlify.js
+var LATIN_MAP = {
+ 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE',
+ 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I',
+ 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O',
+ 'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U',
+ 'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à': 'a',
+ 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c',
+ 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i',
+ 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o',
+ 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',
+ 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
+};
+
+function downcode(string) {
+ return string.toLowerCase().replace(/[^A-Za-z0-9\[\] ]/g,function(a){ return LATIN_MAP[a]||a }).replace(/[^-\w\s]/g, '').replace(/^\s+|\s+$/g, '').replace(/[-\s]+/g, '-');
+};
+
+function remove_auto_anchors() {
+ $('div#main-content .wiki-anchor-auto').each(function(idx, anchor) {
+ $(anchor).parent().removeAttr('id');
+ $(anchor).remove();
+ });
+}
+
+function auto_anchors() {
+ $('div#main-content div.textcell h1, div#main-content div.textcell h2, div#main-content div.textcell h3').each(function(idx, elem) {
+ var $elem = $(elem);
+ if ($elem.attr('id')) return;
+ if ($elem.find('.wiki-anchor').length) return;
+ $elem.attr('id', downcode($elem.text()));
+ $('<a class="wiki-anchor wiki-anchor-auto" href="#' + $elem.attr('id') + '">¶</a>').appendTo($elem);
+ });
+}
+
+(function(window, document, undefined) {
+ var Phylly = {
+ BLOCKS: [
+ {name: 'intertitre', tag: 'h4', klass: 'intertitle'},
+ {name: 'code', tag: 'PRE', klass: 'code'},
+ {name: 'note', tag: 'DIV', subtag: true, klass: 'note'},
+ ],
+ input_event: function(event) {
+ if (event.originalEvent.inputType != "insertParagraph") return true;
+ 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];
+ }
+ var title_match = prev_p.innerText.match(/^(h[1-6]). /);
+ if (title_match) {
+ var title = document.createElement(title_match[1]);
+ title.innerHTML = prev_p.innerHTML;
+ title.textContent = title.textContent.slice(4);
+ prev_p.replaceWith(title);
+ }
+ return true;
+ },
+
+ init: function() {
+ $(document).on('selectionchange', function(event) {
+ if ($('input[name=link-target].shown').length) {
+ return;
+ }
+ var sel = window.getSelection();
+ if ($(sel.anchorNode).parents('div[contenteditable]').length && sel.toString()) {
+ show_style_popup(sel);
+ } else if (style_popup) {
+ $(style_popup).hide();
+ }
+ });
+ },
+
+ off: function() {
+ $(document).off('selectionchange');
+ },
+
+ bind_events: function(elem) {
+ $(elem).on('input', Phylly.input_event);
+ $(elem).on('keyup click', update_block_style_popup);
+ },
+
+ unbind_events: function(elem) {
+ $(elem).off('input');
+ $(elem).off('keyup click');
+ },
+
+ }
+ window.Phylly = Phylly;
+
+ function get_contenteditable_subnode(node) {
+ if (node === null) return null;
+ if (node.parentNode.contentEditable === 'true') return node;
+ return get_contenteditable_subnode(node.parentNode);
+ }
+ function get_active_block(node) {
+ var main_node = get_contenteditable_subnode(node);
+ if (main_node === null) return null;
+ for (const block of Phylly.BLOCKS) {
+ if (main_node.tagName === block.tag && main_node.classList.contains(block.klass))
+ return block;
+ }
+ return null;
+ }
+
+ var block_style_popup = null;
+ function block_style() {
+ var sel = window.getSelection();
+ var current_anchor = sel.anchorNode;
+ if (this.classList.contains('on')) { // toggle off
+ if (this.action_block.subtag) {
+ // unwrap
+ var main_node = get_contenteditable_subnode(current_anchor);
+ $(current_anchor).detach().insertAfter(main_node);
+ } else {
+ document.execCommand('formatBlock', false, 'p');
+ current_anchor = sel.anchorNode;
+ }
+ } else {
+ action = this.action_block.subtag || this.action_block.tag;
+ if (this.action_block.subtag) {
+ // enclose current tag into a new parent;
+ var new_parent = document.createElement(this.action_block.tag);
+ new_parent.className = this.action_block.klass;
+ $(current_anchor).wrap(new_parent);
+ } else {
+ document.execCommand('formatBlock', false, this.action_block.tag);
+ sel.anchorNode.className = this.action_block.klass;
+ current_anchor = sel.anchorNode;
+ }
+ }
+ var range = document.createRange();
+ range.setStart(current_anchor, 0);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ update_block_style_popup();
+ }
+ function update_block_style_popup() {
+ var sel = window.getSelection();
+ if (! ((sel.anchorNode instanceof Element && (sel.anchorOffset == 0 && sel.isCollapsed)) || get_active_block(sel.anchorNode))) {
+ if (block_style_popup) {
+ $(block_style_popup).hide();
+ }
+ return true;
+ }
+ if (block_style_popup === null) {
+ block_style_popup = $('<div class="block-style-popup"></div>');
+ for (const block of Phylly.BLOCKS) {
+ var button = document.createElement('button');
+ button.action_block = block;
+ button.dataset.action = block.name;
+ button.textContent = block.name;
+ block_style_popup.append(button);
+ }
+ block_style_popup.hide();
+ block_style_popup.insertAfter(document.body);
+ block_style_popup.find('button').on('click', block_style);
+ }
+ block_style_popup.css('position', 'absolute');
+ var block = get_active_block(sel.anchorNode);
+ block_style_popup.find('button').removeClass('on');
+ if (block) {
+ block_style_popup.find('[data-action=' + block.name + ']').addClass('on');
+ block_style_popup.addClass('selected');
+ } else {
+ block_style_popup.removeClass('selected');
+ }
+ var anchor = get_contenteditable_subnode(sel.anchorNode);
+ var pos = $(anchor).offset();
+ block_style_popup.css('top', pos.top - 33);
+ block_style_popup.css('left', pos.left);
+ block_style_popup.show();
+ return true;
+ }
+
+ 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;
+ }
+ if (action == 'createLink') {
+ var sel = window.getSelection();
+ var $input = $('input[name=link-target]');
+ $input[0]._range = sel.getRangeAt(0);
+ if (sel.anchorNode instanceof Element) {
+ var elem = sel.anchorNode.childNodes[sel.anchorOffset];
+ if (elem.tagName == 'A') {
+ $input.val(elem.href);
+ }
+ }
+ $input.addClass('shown');
+ $input.focus();
+ return;
+ }
+ document.execCommand(action, false, param);
+ }
+ function validate_link(ev) {
+ var charCode = typeof ev.which == "number" ? ev.which : ev.keyCode;
+ if (ev.key == "Enter") {
+ var $input = $(this);
+ var range = this._range;
+ var url = $input.val();
+ $input.removeClass('shown');
+ var sel = window.getSelection();
+ sel.addRange(this._range);
+ if (url) {
+ document.execCommand('createLink', false, url);
+ } else {
+ document.execCommand('unlink', false, null);
+ }
+ sel.empty();
+ $input.val('');
+ }
+ }
+ function focusout_link(ev) {
+ var $input = $(this);
+ $input.removeClass('shown');
+ var range = this._range;
+ var sel = window.getSelection();
+ sel.addRange(this._range);
+ }
+
+ function show_style_popup(sel) {
+ if (style_popup === null) {
+ style_popup = $('<div class="inline-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>' +
+ '<button data-action="createLink">a</button>' +
+ '<input name="link-target"/>' +
+ '</div>');
+ style_popup.hide();
+ style_popup.insertAfter(document.body);
+ style_popup.find('button').on('click', update_style);
+ style_popup.find('[name=link-target]').on('keypress', validate_link).on('focusout', focusout_link);
+ }
+ style_popup.css('position', 'absolute');
+ var pos = sel.getRangeAt(0).getClientRects()[0];
+ style_popup.css('top', pos.top + window.scrollY - 33);
+ style_popup.css('left', pos.left + window.scrollX);
+ style_popup.show();
+ };
+}(window, document));
+
+$(function() {
+ $('#quickedit input').on('change', function() {
+ var enable = $(this).is(':checked');
+ if (enable) {
+ remove_auto_anchors();
+ $('div[data-edit-url] > div').each(function(i, elem) {
+ $(elem).attr('contenteditable', 'true');
+ var $button = $('<button class="save">Enregistrer</button>');
+ $button[0].div_zone = elem;
+ elem.edit_url = $(elem).parents('[data-edit-url]').data('edit-url');
+ $button.insertAfter(elem);
+ });
+ Phylly.init(),
+ $('div[data-edit-url] > div').each(function(i, elem) {
+ Phylly.bind_events(elem);
+ });
+ $('.save').on('click', function() {
+ var csrf = $('[name=csrfmiddlewaretoken]').val();
+ attr = this.div_zone.edit_url.replace(/^.*(data_textcell.*)\//, 'c$1-text');
+ var params = {};
+ params[attr] = this.div_zone.innerHTML;
+ params['csrfmiddlewaretoken'] = csrf;
+ $.post(this.div_zone.edit_url, params).fail(function() {
+ $(this).css('background', 'red');
+ });
+ return false;
+ });
+ } else {
+ auto_anchors();
+ Phylly.off(),
+ $('button.save').remove();
+ $('div[data-edit-url] > div').each(function(i, elem) {
+ $(elem).attr('contenteditable', 'false');
+ Phylly.unbind_events(elem);
+ });
+ }
+ });
+ $('#quickedit input').trigger('change');
+});