From 994fccf764d90da68745cf8f24bc8350808e951e Mon Sep 17 00:00:00 2001 From: Edward Betts <edward@4angle.com> Date: Fri, 26 Apr 2019 12:56:53 +0100 Subject: [PATCH] Working implementation of editing. --- sourcing/edit.py | 4 +++ sourcing/span.py | 3 +++ sourcing/static/js/xanaedit.js | 10 +++---- sourcing/templates/xanaedit.html | 12 ++++++--- sourcing/view.py | 46 +++++++++++++++++++++++--------- 5 files changed, 53 insertions(+), 22 deletions(-) diff --git a/sourcing/edit.py b/sourcing/edit.py index 653c458..5f6cf1d 100644 --- a/sourcing/edit.py +++ b/sourcing/edit.py @@ -83,6 +83,10 @@ def apply_edits(spans, edits): if edit['op'] == 'insert': spans = apply_insert(spans, edit) continue + if edit['op'] == 'replace': + spans = apply_delete(spans, edit) + spans = apply_insert(spans, edit) + continue return spans diff --git a/sourcing/span.py b/sourcing/span.py index 08f9cd8..5d0a6e4 100644 --- a/sourcing/span.py +++ b/sourcing/span.py @@ -16,3 +16,6 @@ class Span: def end(self) -> int: return self.start + self.length + + def for_edl(self) -> str: + return f'{self.url},start={self.start},length={self.length}' diff --git a/sourcing/static/js/xanaedit.js b/sourcing/static/js/xanaedit.js index 3e117fe..1172f95 100644 --- a/sourcing/static/js/xanaedit.js +++ b/sourcing/static/js/xanaedit.js @@ -21,7 +21,7 @@ var changes = document.getElementById("changes"); var edits = []; -editor.value = text;; +editor.value = text; function update_list_of_edits() { changes.innerHTML = null; @@ -29,11 +29,11 @@ function update_list_of_edits() { var update; var start = edit.start + 1; if (edit.op == 'insert') { - update = start + ' insert: [' + edit.new + ']'; + update = start + ' insert: [' + JSON.stringify(edit.new) + ']'; } else if (edit.op == 'delete') { - update = start + ' delete: [' + edit.old + ']'; + update = start + ' delete: [' + JSON.stringify(edit.old) + ']'; } 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"); div.innerHTML = update; @@ -52,7 +52,7 @@ function update_buttons () { } function update(e) { - var current = editor.value; + var current = editor.value.replace(/\n/g, '\r\n'); if (current == text) // no change return diff --git a/sourcing/templates/xanaedit.html b/sourcing/templates/xanaedit.html index 01bce88..a798903 100644 --- a/sourcing/templates/xanaedit.html +++ b/sourcing/templates/xanaedit.html @@ -16,14 +16,18 @@ <div class="col-8"> <p> + {# <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> <textarea id="editor" rows="16" class="w-100" autofocus></textarea> </div> - <div class="col-4" id="changes"> + <div class="col-4"> + <h4>changes</h4> + <div id="changes"></div> </div> </div> @@ -33,7 +37,7 @@ {% block scripts %} <script> -var text = {{ doc_text.replace('\r\n', '\n')|tojson }}; +var text = {{ doc_text|tojson }}; </script> <script src="{{ url_for('static', filename='js/xanaedit.js') }}"></script> {% endblock %} diff --git a/sourcing/view.py b/sourcing/view.py index 28fa72a..ab465de 100644 --- a/sourcing/view.py +++ b/sourcing/view.py @@ -20,7 +20,6 @@ from functools import wraps from .utils import nbsp_at_start from itsdangerous import URLSafeTimedSerializer # from sqlalchemy_continuum import version_class -from pprint import pformat import json import re @@ -413,8 +412,13 @@ def create_xanapage_from_sourcedoc(username, hashid): flash('New xanapage created.') return redirect(page.url) -@bp.route('/<username>/<hashid>/xanaedit') +@bp.route('/<username>/<hashid>/xanaedit', methods=['GET', 'POST']) 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) 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) -@bp.route('/<username>/<hashid>/xanaedit', methods=['POST']) def save_xanaedit(username, hashid): - # doc = get_xanapage(username, hashid) - edits = json.loads(request.form['edits']) - 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) + page = get_xanapage(username, hashid) + current_edl = parse_edl(page.text) spans = [Span(*span) for span in current_edl['spans']] edits = json.loads(request.form['edits']) new_text = '' new_text_pos = 0 for edit in edits: - if edit['op'] != 'insert': + if edit['op'] not in ('insert', 'replace'): continue new_text += edit['new'] edit['span'] = Span('placeholder', new_text_pos, len(edit['new'])) new_text_pos += len(edit['new']) 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']) def edit_item(username, hashid):