Working implementation of editing.

This commit is contained in:
Edward Betts 2019-04-26 12:56:53 +01:00
parent b3a28fbcb0
commit 994fccf764
5 changed files with 53 additions and 22 deletions

View file

@ -83,6 +83,10 @@ def apply_edits(spans, edits):
if edit['op'] == 'insert': if edit['op'] == 'insert':
spans = apply_insert(spans, edit) spans = apply_insert(spans, edit)
continue continue
if edit['op'] == 'replace':
spans = apply_delete(spans, edit)
spans = apply_insert(spans, edit)
continue
return spans return spans

View file

@ -16,3 +16,6 @@ class Span:
def end(self) -> int: def end(self) -> int:
return self.start + self.length return self.start + self.length
def for_edl(self) -> str:
return f'{self.url},start={self.start},length={self.length}'

View file

@ -21,7 +21,7 @@ var changes = document.getElementById("changes");
var edits = []; var edits = [];
editor.value = text;; editor.value = text;
function update_list_of_edits() { function update_list_of_edits() {
changes.innerHTML = null; changes.innerHTML = null;
@ -29,11 +29,11 @@ function update_list_of_edits() {
var update; var update;
var start = edit.start + 1; var start = edit.start + 1;
if (edit.op == 'insert') { if (edit.op == 'insert') {
update = start + ' insert: [' + edit.new + ']'; update = start + ' insert: [' + JSON.stringify(edit.new) + ']';
} else if (edit.op == 'delete') { } else if (edit.op == 'delete') {
update = start + ' delete: [' + edit.old + ']'; update = start + ' delete: [' + JSON.stringify(edit.old) + ']';
} else if (edit.op == 'replace') { } else if (edit.op == 'replace') {
update = start + ' replace: [' + edit.old + '] with [' + edit.new + ']'; update = start + ' replace: [' + JSON.stringify(edit.old) + '] with [' + JSON.stringify(edit.new) + ']';
} }
var div = document.createElement("div"); var div = document.createElement("div");
div.innerHTML = update; div.innerHTML = update;
@ -52,7 +52,7 @@ function update_buttons () {
} }
function update(e) { function update(e) {
var current = editor.value; var current = editor.value.replace(/\n/g, '\r\n');
if (current == text) // no change if (current == text) // no change
return return

View file

@ -16,14 +16,18 @@
<div class="col-8"> <div class="col-8">
<p> <p>
{#
<button class="btn btn-primary save-btn" id="save-btn" disabled>save, continue editing</button> <button class="btn btn-primary save-btn" id="save-btn" disabled>save, continue editing</button>
<button type="submit" class="btn btn-primary save-btn" id="finish-btn" disabled>save and finish</button> #}
<a href="{{ doc.url }}" class="btn btn-secondary" id="cancel-btn">back to view page</a> <button type="submit" class="btn btn-primary save-btn" id="finish-btn" disabled>save changes</button>
<a href="{{ doc.url }}" class="btn btn-secondary" id="cancel-btn">forget changes</a>
</p> </p>
<textarea id="editor" rows="16" class="w-100" autofocus></textarea> <textarea id="editor" rows="16" class="w-100" autofocus></textarea>
</div> </div>
<div class="col-4" id="changes"> <div class="col-4">
<h4>changes</h4>
<div id="changes"></div>
</div> </div>
</div> </div>
@ -33,7 +37,7 @@
{% block scripts %} {% block scripts %}
<script> <script>
var text = {{ doc_text.replace('\r\n', '\n')|tojson }}; var text = {{ doc_text|tojson }};
</script> </script>
<script src="{{ url_for('static', filename='js/xanaedit.js') }}"></script> <script src="{{ url_for('static', filename='js/xanaedit.js') }}"></script>
{% endblock %} {% endblock %}

View file

@ -20,7 +20,6 @@ from functools import wraps
from .utils import nbsp_at_start from .utils import nbsp_at_start
from itsdangerous import URLSafeTimedSerializer from itsdangerous import URLSafeTimedSerializer
# from sqlalchemy_continuum import version_class # from sqlalchemy_continuum import version_class
from pprint import pformat
import json import json
import re import re
@ -413,8 +412,13 @@ def create_xanapage_from_sourcedoc(username, hashid):
flash('New xanapage created.') flash('New xanapage created.')
return redirect(page.url) return redirect(page.url)
@bp.route('/<username>/<hashid>/xanaedit') @bp.route('/<username>/<hashid>/xanaedit', methods=['GET', 'POST'])
def xanaedit_item(username, hashid): def xanaedit_item(username, hashid):
if request.method == 'POST':
save_xanaedit(username, hashid)
return redirect(url_for('xanaedit_item', username=username, hashid=hashid))
doc = get_xanapage(username, hashid) doc = get_xanapage(username, hashid)
spans = list(fulfil_edl(doc.text)) spans = list(fulfil_edl(doc.text))
@ -422,29 +426,45 @@ def xanaedit_item(username, hashid):
return render_template('xanaedit.html', doc=doc, doc_text=doc_text) return render_template('xanaedit.html', doc=doc, doc_text=doc_text)
@bp.route('/<username>/<hashid>/xanaedit', methods=['POST'])
def save_xanaedit(username, hashid): def save_xanaedit(username, hashid):
# doc = get_xanapage(username, hashid) page = get_xanapage(username, hashid)
edits = json.loads(request.form['edits']) current_edl = parse_edl(page.text)
return jsonify(edits=edits)
@bp.route('/<username>/<hashid>/finish', methods=['POST'])
def finish_xanaedit(username, hashid):
doc = get_xanapage(username, hashid)
current_edl = parse_edl(doc.text)
spans = [Span(*span) for span in current_edl['spans']] spans = [Span(*span) for span in current_edl['spans']]
edits = json.loads(request.form['edits']) edits = json.loads(request.form['edits'])
new_text = '' new_text = ''
new_text_pos = 0 new_text_pos = 0
for edit in edits: for edit in edits:
if edit['op'] != 'insert': if edit['op'] not in ('insert', 'replace'):
continue continue
new_text += edit['new'] new_text += edit['new']
edit['span'] = Span('placeholder', new_text_pos, len(edit['new'])) edit['span'] = Span('placeholder', new_text_pos, len(edit['new']))
new_text_pos += len(edit['new']) new_text_pos += len(edit['new'])
spans = apply_edits(spans, edits) spans = apply_edits(spans, edits)
return Response(pformat(spans), mimetype='text/plain')
new_src_doc = SourceDoc(user=current_user, text=new_text)
session.add(new_src_doc)
session.commit()
for span in spans:
if span.url == 'placeholder':
span.url = new_src_doc.external_url
new_edl = ''.join(f'span: {span.for_edl()}\n' for span in spans)
page.text = new_edl
session.commit()
flash('Edits saved.')
return page
@bp.route('/<username>/<hashid>/finish', methods=['POST'])
def finish_xanaedit(username, hashid):
page = save_xanaedit(username, hashid)
return redirect(page.url)
@bp.route('/<username>/<hashid>/edit', methods=['GET', 'POST']) @bp.route('/<username>/<hashid>/edit', methods=['GET', 'POST'])
def edit_item(username, hashid): def edit_item(username, hashid):