From f499ee9347f539c36f3846fdc41020f2320bae77 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C5=81ukasz=20Rekucki?= <lrekucki@gmail.com> Date: Sat, 10 Apr 2010 21:10:07 +0200 Subject: [PATCH 1/1] * End of javascript refactoring: both editors, history and gallery work as expected. * Minor refactoring to wiki views. * Added views and vstorage support for taging history. * Other minor changes in vstorage. --- apps/wiki/forms.py | 12 +- apps/wiki/models.py | 27 +- .../wiki/templates/wiki/document_details.html | 29 +- apps/wiki/templates/wiki/history_view.html | 30 +- apps/wiki/templates/wiki/save_dialog.html | 42 ++- apps/wiki/urls.py | 2 +- apps/wiki/views.py | 131 ++++---- lib/test_vstorage.py | 87 ++++- lib/vstorage.py | 40 ++- platforma/settings.py | 16 +- platforma/static/css/dialogs.css | 5 + platforma/static/css/history.css | 174 +++++----- platforma/static/css/html.css | 315 ++++++++---------- platforma/static/css/master.css | 20 +- platforma/static/css/xmlcolors_15032010.css | 6 +- platforma/static/js/slugify.js | 4 +- platforma/static/js/wiki/base.js | 241 +++++++++++++- platforma/static/js/wiki/diff_view.js | 11 +- platforma/static/js/wiki/history_view.js | 199 ++++++----- platforma/static/js/wiki/main.js | 143 +++----- platforma/static/js/wiki/save_dialog.js | 26 +- platforma/static/js/wiki/scan_gallery.js | 283 +++++++--------- platforma/static/js/wiki/source_editor.js | 88 ++--- platforma/static/js/wiki/summary_view.js | 10 +- platforma/static/js/wiki/wikiapi.js | 65 ++-- platforma/static/js/wiki/wysiwyg_editor.js | 198 +++++------ platforma/templates/base.html | 3 +- 27 files changed, 1316 insertions(+), 891 deletions(-) diff --git a/apps/wiki/forms.py b/apps/wiki/forms.py index ca219889..236c3f0e 100644 --- a/apps/wiki/forms.py +++ b/apps/wiki/forms.py @@ -35,6 +35,14 @@ class DocumentForm(forms.Form): parent =self.cleaned_data['revision'] ) return storage.get(self.cleaned_data['name']) + +class DocumentTagForm(forms.Form): + TAGS = ( + ("publish", "Do publikacji"), + ) + + tag = forms.ChoiceField(choices = TAGS) + version = forms.IntegerField(widget = forms.HiddenInput) class DocumentTextSaveForm(forms.Form): """ @@ -55,16 +63,16 @@ class DocumentTextSaveForm(forms.Form): id = forms.CharField(widget=forms.HiddenInput) parent_revision = forms.IntegerField(widget=forms.HiddenInput) + text = forms.CharField(widget=forms.HiddenInput) author = forms.CharField( required = False, label = _(u"Autor"), help_text = _(u"Twoje imie i nazwisko lub email.") - ) comment = forms.CharField( - required = False, + required = True, widget=forms.Textarea, label = _(u"Twój komentarz"), help_text = _(u"Opisz w miarÄ dokÅadnie swoje zmiany."), diff --git a/apps/wiki/models.py b/apps/wiki/models.py index 22a81196..a530916f 100644 --- a/apps/wiki/models.py +++ b/apps/wiki/models.py @@ -4,10 +4,16 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # import re +import os import vstorage from vstorage import DocumentNotFound from wiki import settings +from django.http import Http404 + +import logging +logger = logging.getLogger("fnp.wiki") + class DocumentStorage(object): def __init__(self, path): self.vstorage = vstorage.VersionedStorage(path) @@ -18,6 +24,12 @@ class DocumentStorage(object): else: text = self.vstorage.revision_text(name, revision) return Document(self, name = name, text = text) + + def get_or_404(self, *args, **kwargs): + try: + return self.get(*args, **kwargs) + except DocumentNotFound: + raise Http404 def put(self, document, author, comment, parent): self.vstorage.save_text( @@ -52,7 +64,12 @@ class Document(object): try: return self.storage._info(self.name)[0] except DocumentNotFound: - return - 1 + return -1 + + def add_tag(self, tag): + """ Add document specific tag """ + logger.debug("Adding tag %s to doc %s version %d", tag, self.name, self.revision) + self.storage.vstorage.add_page_tag(self.name, self.revision, tag) @property def plain_text(self): @@ -70,8 +87,12 @@ class Document(object): except ValueError: continue - if 'gallery' not in result: - result['gallery'] = (settings.GALLERY_URL + self.name).replace(' ', '_') + gallery = result.get('gallery', self.name.replace(' ', '_')) + + if gallery.startswith('/'): + gallery = os.path.basename(gallery) + + result['gallery'] = gallery if 'title' not in result: result['title'] = self.name.title() diff --git a/apps/wiki/templates/wiki/document_details.html b/apps/wiki/templates/wiki/document_details.html index d077e7db..cbed276c 100644 --- a/apps/wiki/templates/wiki/document_details.html +++ b/apps/wiki/templates/wiki/document_details.html @@ -23,7 +23,7 @@ </div> </div> -<div id="document-meta" +<div id="document-meta" data-document-name="{{ document.name }}" style="display:none"> {% for k, v in document_meta.items %} @@ -36,33 +36,35 @@ <div id="tools"> <a href="{{ REDMINE_URL }}projects/wl-publikacje/wiki/Pomoc" target="_blank">Pomoc</a> | {% include "registration/head_login.html" %} - | Wersja: <span id="document-revision">{{ document_info.revision }}</span> + | Wersja: <span id="document-revision">unknown</span> | <button style="margin-left: 6px" id="save-button"> Zapisz </button> </div> - <ol id="tabs"> - - <li id="SummaryPerspective-tab" - data-ui-related="summary-view-editor" data-ui-jsclass="SummaryPerspective"> + <ol id="tabs"> + <li id="SummaryPerspective" + data-ui-related="summary-view-editor" + data-ui-jsclass="SummaryPerspective"> <span>{{ document_meta.title }}</span> </li> - <li id="VisualPerspective-tab" - data-ui-related="simple-editor" data-ui-jsclass="VisualPerspective"> + <li id="VisualPerspective" + data-ui-related="simple-editor" + data-ui-jsclass="VisualPerspective"> <span>Edytor</span> </li> - <li id="HistoryPerspective-tab" + <li id="HistoryPerspective" data-ui-related="history-view-editor" data-ui-jsclass="HistoryPerspective"> - Historia + <span>Historia</span> </li> - <li id="CodeMirrorPerspective-tab" - data-ui-related="source-editor" data-ui-jsclass="CodeMirrorPerspective"> - Kod źródÅowy + <li id="CodeMirrorPerspective" + data-ui-related="source-editor" + data-ui-jsclass="CodeMirrorPerspective"> + <span>Kod źródÅowy</span> </li> </ol> </div> @@ -117,4 +119,5 @@ </div> </div> {% include "wiki/save_dialog.html" %} +{% include "wiki/tag_dialog.html" %} {% endblock %} \ No newline at end of file diff --git a/apps/wiki/templates/wiki/history_view.html b/apps/wiki/templates/wiki/history_view.html index c14cb4de..36be4873 100644 --- a/apps/wiki/templates/wiki/history_view.html +++ b/apps/wiki/templates/wiki/history_view.html @@ -1,19 +1,27 @@ <div id="history-view-editor" class="editor" style="display: none"> <div class="toolbar"> <button type="button" id="make-diff-button">Porównaj</button> + <button type="button" id="tag-changeset-button">Oznacz wersje</button> </div> <div id="history-view"> - <p class="message-box" style="display:none;"> - </p> - <div class="row-stub" style="display: none;"> - <span class="tag" data-stub-target="data-version-tag" data-stub-value="tag">dodaj tag</span> - <span data-stub-value="version"></span>: <span data-stub-value="description"></span> - (<span data-stub-value="author"></span>, <span data-stub-value="date"></span>) - </div> - <div id="changes-list"> - </div> - <p> - + <p class="message-box" style="display:none;"></p> + + <table id="changes-list-container"> + <tbody id="changes-list"> + </tbody> + <tbody style="display: none;"> + <tr class="entry row-stub"> + <td data-stub-value="version"></td> + <td> + <span data-stub-value="description"></span> + <br /> + <span data-stub-value="author"></span>, <span data-stub-value="date"></span> + </td> + <td data-stub-value="tag"> + </td> + </tr> + </tbody> + </table> <div id="diff-view"> </div> </div> diff --git a/apps/wiki/templates/wiki/save_dialog.html b/apps/wiki/templates/wiki/save_dialog.html index f49db3f5..aba61cca 100644 --- a/apps/wiki/templates/wiki/save_dialog.html +++ b/apps/wiki/templates/wiki/save_dialog.html @@ -1,24 +1,40 @@ -<div id="save_dialog" class="dialog"> - <p>{{ text_save_form.comment.label }}</p> - <p class="help_text">{{text_save_form.comment.help_text}}</p> - {{ text_save_form.comment }} +<div id="save_dialog" class="dialog" data-ui-jsclass="SaveDialog"> + <form method="POST" action=""> + <p>{{ forms.text_save.comment.label }}</p> + <p class="help_text"> + {{ forms.text_save.comment.help_text}} + <span data-ui-error-for="{{ forms.text_save.comment.name }}"> </span> + </p> + {{forms.text_save.comment }} + + {% if request.user.is_anonymous %} <p> - {{ text_save_form.author.label }}: - {{ text_save_form.author }} - <span class="help_text">{{ text_save_form.author.help_text }}</span> + {{ forms.text_save.author.label }}: + {{ forms.text_save.author }} + <span class="help_text">{{ forms.text_save.author.help_text }}</span> + <span data-ui-error-for="{{ forms.text_save.author.name }}"> </span> </p> {% else %} <p> - {{ text_save_form.stage_completed.label }}: - {{ text_save_form.stage_completed }} - <span class="help_text">{{ text_save_form.stage_completed.help_text }}</span> + {{ forms.text_save.stage_completed.label }}: + {{ forms.text_save.stage_completed }} + <span class="help_text">{{ forms.text_save.stage_completed.help_text }}</span> + <span data-ui-error-for="{{ forms.text_save.stage_completed.name }}"> </span> </p> {% endif %} + + {% for f in forms.text_save.hidden_fields %} + {{ f }} + {% endfor %} + + <p data-ui-error-for="__all__"> </p> + <p class="action_area"> - <button type="submit" class="ok-button">Zapisz</button> - <button class="cancel-button">Anuluj</button> - </p> + <button type="submit" class"ok" data-ui-action="save">Zapisz</button> + <button type="button" class="cancel" data-ui-action="cancel">Anuluj</button> + </p> + </form> </div> diff --git a/apps/wiki/urls.py b/apps/wiki/urls.py index 0c6393cf..b319465c 100644 --- a/apps/wiki/urls.py +++ b/apps/wiki/urls.py @@ -12,7 +12,7 @@ urlpatterns = patterns('wiki.views', 'document_text', name="wiki_text"), url(r'^(?P<name>[^/]+)/publish/(?P<version>\d+)$', 'document_publish', name="wiki_publish"), - url(r'^(?P<name>[^/]+)/diff/(?P<revA>\d+)/(?P<revB>\d+)$', + url(r'^(?P<name>[^/]+)/diff$', 'document_diff', name="wiki_diff"), url(r'^(?P<name>[^/]+)$', 'document_detail', name="wiki_details"), diff --git a/apps/wiki/views.py b/apps/wiki/views.py index 5bf3ce4d..29039b71 100644 --- a/apps/wiki/views.py +++ b/apps/wiki/views.py @@ -2,11 +2,12 @@ import os from django.conf import settings from django.views.generic.simple import direct_to_template -from django.http import HttpResponse, Http404 -from django.utils import simplejson as json +from django.views.decorators.http import require_POST +from .helpers import JSONResponse, JSONFormInvalid, JSONServerError +from django import http -from wiki.models import Document, DocumentNotFound, getstorage -from wiki.forms import DocumentForm, DocumentTextSaveForm +from wiki.models import getstorage +from wiki.forms import DocumentForm, DocumentTextSaveForm, DocumentTagForm from datetime import datetime from django.utils.encoding import smart_unicode import wlapi @@ -24,12 +25,6 @@ import operator MAX_LAST_DOCS = 10 -class DateTimeEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, datetime): - return datetime.ctime(obj) + " " + (datetime.tzname(obj) or 'GMT') - return json.JSONEncoder.default(self, obj) - @never_cache def document_list(request, template_name = 'wiki/document_list.html'): # TODO: find a way to cache "Storage All" @@ -42,10 +37,7 @@ def document_list(request, template_name = 'wiki/document_list.html'): @never_cache def document_detail(request, name, template_name = 'wiki/document_details.html'): - try: - document = getstorage().get(name) - except DocumentNotFound: - raise Http404 + document = getstorage().get_or_404(name) access_time = datetime.now() last_documents = request.session.get("wiki_last_docs", {}) @@ -60,90 +52,115 @@ def document_detail(request, name, template_name = 'wiki/document_details.html') 'document': document, 'document_info': document.info, 'document_meta': document.meta, - 'text_save_form': DocumentTextSaveForm(), + 'forms': {"text_save": DocumentTextSaveForm(), "add_tag": DocumentTagForm() }, }) @never_cache -def document_text(request, name): - try: - document = getstorage().get(name) - except DocumentNotFound: - raise Http404 +def document_text(request, name): + storage = getstorage() + document = storage.get_or_404(name) if request.method == 'POST': - form = DocumentForm(request.POST, instance = document) - if form.is_valid(): - document = form.save(document_author = request.user.username) - return HttpResponse(json.dumps({'text': document.plain_text, 'meta': document.meta(), 'revision': document.revision()})) + form = DocumentTextSaveForm(request.POST) + + if form.is_valid(): + revision = form.cleaned_data['parent_revision'] + document.text = form.cleaned_data['text'] + + storage.put(document, + author = form.cleaned_data['author'] or request.user.username, + comment = form.cleaned_data['comment'], + parent = revision + ) + + return JSONResponse({ + 'text': document.plain_text if revision != document.revision() else None, + 'meta': document.meta(), + 'revision': document.revision() + }) else: - return HttpResponse(json.dumps({'errors': list(form.errors)})) + return JSONFormInvalid(form) else: - return HttpResponse(json.dumps({'text': document.plain_text, 'meta': document.meta(), 'revision': document.revision()})) + return JSONResponse({ + 'text': document.plain_text, + 'meta': document.meta(), + 'revision': document.revision() + }) @never_cache def document_gallery(request, directory): try: + base_url = ''.join(( + smart_unicode(settings.MEDIA_URL), + smart_unicode(settings.FILEBROWSER_DIRECTORY), + smart_unicode(directory))) + base_dir = os.path.join( smart_unicode(settings.MEDIA_ROOT), smart_unicode(settings.FILEBROWSER_DIRECTORY), - smart_unicode(directory) ) + smart_unicode(directory)) - def map_to_url(filename): - - return '%s%s%s/%s' % ( - smart_unicode(settings.MEDIA_URL), - smart_unicode(settings.FILEBROWSER_DIRECTORY), - smart_unicode(directory), - smart_unicode(filename) - ) + def map_to_url(filename): + return "%s/%s" % (base_url, smart_unicode(filename)) def is_image(filename): return os.path.splitext(f)[1].lower() in (u'.jpg', u'.jpeg', u'.png') images = [ map_to_url(f) for f in map(smart_unicode, os.listdir(base_dir)) if is_image(f) ] images.sort() - return HttpResponse(json.dumps(images)) + return JSONResponse(images) except (IndexError, OSError), exc: import traceback traceback.print_exc() - - raise Http404 + raise http.Http404 @never_cache -def document_diff(request, name, revA, revB): - storage = getstorage() - docA = storage.get(name, int(revA)) - docB = storage.get(name, int(revB)) +def document_diff(request, name): + storage = getstorage() + revA = int(request.GET.get('from', 0)) + revB = int(request.GET.get('to', 0)) - return HttpResponse(nice_diff.html_diff_table(docA.plain_text.splitlines(), + if revA > revB: + revA, revB = revB, revA + + if revB == 0: + revB = None + + docA = storage.get_or_404(name, int(revA)) + docB = storage.get_or_404(name, int(revB)) + + return http.HttpResponse(nice_diff.html_diff_table(docA.plain_text.splitlines(), docB.plain_text.splitlines()) ) @never_cache def document_history(request, name): storage = getstorage() + return JSONResponse(storage.history(name)) + +@require_POST +def document_add_tag(request, name): + storage = getstorage() - return HttpResponse( - json.dumps(storage.history(name), cls=DateTimeEncoder), - mimetype='application/json') - + form = DocumentTagForm(request.POST) + if form.is_valid(): + doc = storage.get_or_404(name, form.cleaned_data['version']) + doc.add_tag(form.cleaned_data['tag']) + return JSONResponse({"message": _("Tag added")}) + else: + return JSONFormInvalid(form) -@never_cache +@require_POST def document_publish(request, name, version): storage = getstorage() # get the document - try: - document = storage.get(name, revision = int(version)) - except DocumentNotFound: - raise Http404 + document = storage.get_or_404(name, revision = int(version)) api = wlapi.WLAPI(settings.WL_API_CONFIG) try: - result = {"success": True, "result": api.publish_book(document)} - except wlapi.APICallException, e: - result = {"success": False, "reason": str(e)} - - return HttpResponse( json.dumps(result), mimetype='application/json') \ No newline at end of file + return JSONResponse({"result": api.publish_book(document)}) + except wlapi.APICallException, e: + return JSONServerError({"message": str(e)}) \ No newline at end of file diff --git a/lib/test_vstorage.py b/lib/test_vstorage.py index 00df2f69..eaea46f4 100644 --- a/lib/test_vstorage.py +++ b/lib/test_vstorage.py @@ -44,7 +44,7 @@ class TestVersionedStorage(object): comment = comment, parent=-1) saved = self.repo.open_page(title).read() - assert saved == text + assert_equal(saved, text) def test_save_text_noparent(self): text = u"test text" @@ -57,7 +57,7 @@ class TestVersionedStorage(object): comment = comment, parent=None) saved = self.repo.open_page(title).read() - assert saved == text + assert_equal(saved, text) def test_save_merge_no_conflict(self): text = u"test\ntext" @@ -71,7 +71,7 @@ class TestVersionedStorage(object): text = text, author = author, comment = comment, parent=-1) saved = self.repo.open_page(title).read() - assert saved == text + assert_equal(saved, text) def test_save_merge_line_conflict(self): text = u"test\ntest\n" @@ -129,7 +129,86 @@ text self.repo.save_text(title = u'Python!', text = u'ham and spam') current_repo_revision = self.repo.repo_revision() same_repo = vstorage.VersionedStorage(self.repo_path) - assert same_repo.repo_revision() == current_repo_revision + assert_equal(same_repo.repo_revision(), current_repo_revision) + + + def test_history(self): + COMMITS = [ + {"author": "bunny", "text":"1", "comment": "Oh yeah!"}, + {"author": "frank", "text":"2", "comment": "Second is the best!"}, + {"text":"3", "comment": "Third"}, # anonymous + {"author": "welma", "text":"4", "comment": "Fourth"}, + ] + + for commit in COMMITS: + self.repo.save_text(title = u"Sample", **commit) + + for n, entry in enumerate(reversed(list(self.repo.page_history(u"Sample")))): + assert_equal(entry["version"], n) + assert_equal(entry["author"], COMMITS[n].get("author", "anonymous") ) + assert_equal(entry["description"], COMMITS[n]["comment"]) + assert_equal(entry["tag"], []) + + +class TestVSTags(object): + + TITLE_1 = "Sample" + + COMMITS = [ + {"author": "bunny", "text":"1", "comment": "Oh yeah!"}, + {"author": "frank", "text":"2", "comment": "Second is the best!"}, + {"text":"3", "comment": "Third"}, # anonymous + {"author": "welma", "text":"4", "comment": "Fourth"}, + ] + + def setUp(self): + self.repo_path = tempfile.mkdtemp() + self.repo = vstorage.VersionedStorage(self.repo_path) + + # generate some history + for commit in self.COMMITS: + self.repo.save_text(title = u"Sample", **commit) + + # verify + for n, entry in enumerate(reversed(list(self.repo.page_history(self.TITLE_1)))): + assert_equal(entry["tag"], []) + + def tearDown(self): + clear_directory(self.repo_path) + + def test_add_tag(self): + TAG_USER = "mike_the_tagger" + TAG_NAME = "production" + TAG_VERSION = 2 + + # Add tag + self.repo.add_page_tag(self.TITLE_1, TAG_VERSION, TAG_NAME, TAG_USER) + + # check history again + history = list(self.repo.page_history(self.TITLE_1)) + for entry in reversed(history): + if entry["version"] == TAG_VERSION: + assert_equal(entry["tag"], [TAG_NAME]) + else: + assert_equal(entry["tag"], []) + + def test_add_many_tags(self): + TAG_USER = "mike_the_tagger" + tags = [ + (2, "production", "mike"), + (2, "finished", "jeremy"), + (0, "original", "jeremy"), + ] + + + for rev, name, user in tags: + self.repo.add_page_tag(self.TITLE_1, rev, name, user) + + # check history again + history = list(self.repo.page_history(self.TITLE_1)) + for entry in reversed(history): + expected = [ tag[1] for tag in tags if tag[0] == entry["version"] ] + assert_equal(set(entry["tag"]), set(expected)) if __name__ == '__main__': diff --git a/lib/vstorage.py b/lib/vstorage.py index 527a245d..319a0f12 100644 --- a/lib/vstorage.py +++ b/lib/vstorage.py @@ -325,7 +325,7 @@ class VersionedStorage(object): """ return guess_mime(self._file_path(title)) - def _find_filectx(self, title): + def _find_filectx(self, title, rev = None): """Find the last revision in which the file existed.""" repo_file = self._title_to_file(title) @@ -338,14 +338,18 @@ class VersionedStorage(object): for parent in changectx.parents(): if parent != changectx: stack.append(parent) - return changectx[repo_file] + + try: + fctx = changectx[repo_file] + return fctx if rev is None else fctx.filectx(rev) + except IndexError, LookupError: + raise DocumentNotFound() def page_history(self, title): """Iterate over the page's history.""" filectx_tip = self._find_filectx(title) - if filectx_tip is None: - return + maxrev = filectx_tip.filerev() minrev = 0 for rev in range(maxrev, minrev - 1, -1): @@ -354,31 +358,37 @@ class VersionedStorage(object): author = unicode(filectx.user(), "utf-8", 'replace').split('<')[0].strip() comment = unicode(filectx.description(), "utf-8", 'replace') - tags = filectx.changectx().tags() + tags = [t.rsplit('#', 1)[-1] for t in filectx.changectx().tags() if '#' in t] + yield { "version": rev, "date": date, "author": author, "description": comment, - "tag": tags[0] if tags else None, + "tag": tags, } def page_revision(self, title, rev): """Get unicode contents of specified revision of the page.""" - - filectx_tip = self._find_filectx(title) - if filectx_tip is None: - raise DocumentNotFound() - try: - data = filectx_tip.filectx(rev).data() - except IndexError: - raise DocumentNotFound() - return data + return self._find_filectx(title, rev).data() def revision_text(self, title, rev): data = self.page_revision(title, rev) text = unicode(data, self.charset, 'replace') return text + + @with_working_copy_locked + def add_page_tag(self, title, rev, tag, user = "<wiki>", doctag = True): + if doctag: + tag = "{title}#{tag}".format(**locals()) + + message = "Assigned tag {tag} to version {rev} of {title}".format(**locals()) + + fctx = self._find_filectx(title, rev) + self.repo.tag( + names = tag, node = fctx.node(), local = False, + user = user, message = message, date = None + ) def history(self): """Iterate over the history of entire wiki.""" diff --git a/platforma/settings.py b/platforma/settings.py index 0290dd88..88141489 100644 --- a/platforma/settings.py +++ b/platforma/settings.py @@ -132,13 +132,13 @@ COMPRESS_CSS = { } COMPRESS_JS = { - # everything except codemirror and jquery (which we take from google) + # everything except codemirror 'detail': { 'source_filenames': ( - #'js/jquery-1.4.2.min.js', + 'js/jquery-1.4.2.min.js', 'js/jquery.autocomplete.js', 'js/jquery.blockui.js', - 'js/jquery.elastic.js', + 'js/jquery.elastic.js', 'js/button_scripts.js', 'js/slugify.js', @@ -146,18 +146,26 @@ COMPRESS_JS = { 'js/wiki/wikiapi.js', 'js/wiki/base.js', 'js/wiki/xslt.js', + + # dialogs + 'js/wiki/save_dialog.js', + + # views 'js/wiki/history_view.js', 'js/wiki/summary_view.js', 'js/wiki/source_editor.js', 'js/wiki/wysiwyg_editor.js', 'js/wiki/scan_gallery.js', + 'js/wiki/diff_view.js', + + # bootstrap 'js/wiki/main.js', ), 'output_filename': 'compressed/detail_scripts_?.js', }, 'listing': { 'source_filenames': ( - # 'js/jquery-1.4.2.min.js', + 'js/jquery-1.4.2.min.js', 'js/slugify.js', ), 'output_filename': 'compressed/listing_scripts_?.js', diff --git a/platforma/static/css/dialogs.css b/platforma/static/css/dialogs.css index 026fc9dc..9d03435a 100644 --- a/platforma/static/css/dialogs.css +++ b/platforma/static/css/dialogs.css @@ -25,3 +25,8 @@ .dialog p { margin: 0.5em; } + +*[data-ui-error-for] { + color: red; + font-weight: bold; +} diff --git a/platforma/static/css/history.css b/platforma/static/css/history.css index 5028e230..b3191165 100644 --- a/platforma/static/css/history.css +++ b/platforma/static/css/history.css @@ -5,133 +5,151 @@ bottom: 0px; left: 0px; right: 0px; - z-index: 1; + z-index: 1; } /* * File History */ +#changes-list-container { + margin: 1em auto; + width: 70%; +} + +table#changes-list-container { + border-spacing: 0px 15px; +} + #changes-list { - margin: 0.5em 0.2em; + margin: 0.5em 0.2em; +} + +#changes-list td { + padding: 0.5em 1em; +} + +#changes-list .entry { + position: relative; + padding: 0.5em; + padding-left: 3em; + margin: 0.5em; } -#changes-list div { - position: relative; - padding: 0.5em; - margin: 0.5em; +#changes-list .entry:hover { + background-color: #f0f0f0; } -#changes-list div:hover { - background-color: #f0f0f0; +#changes-list .entry.selected { + background-color: #ffec63; } -#changes-list div.selected { - background-color: #ffec63; +#changes-list .tag { + display: inline-block; + visibility: hidden; + width: 60px; + margin: 0 0.5em 0 0; + font-size: 11px; + padding: 3px 2px; + text-align: center; + color: black; + background: #add8e6; + cursor: pointer; + vertical-align: middle; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + border-radius: 10px; } -#changes-list span.tag { - display: inline-block; - visibility: hidden; - width: 60px; - margin: 0 0.5em 0 0; - font-size: 11px; - padding: 3px 2px; - text-align: center; - color: black; - background: #add8e6; - cursor: pointer; - vertical-align: middle; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; - border-radius: 10px; +#changes-list .entry:hover .tag { + visibility: visible; } -#changes-list div:hover span.tag { - visibility: visible; +#changes-list .tag:hover { + background: #bde8f6; } -#changes-list span.tag:hover { - background: #bde8f6; +#changes-list *[data-version-tag] { + visibility: visible; + border: 1px solid black; + color: black; } -#changes-list span[data-version-tag] { - visibility: visible; - border: 1px solid black; - - color: black; +#changes-list *[data-stub-value = +'version'] { + font-weight: bold; } -#changes-list span[data-stub-value='version'] { - font-weight: bold; +#changes-list td[data-stub-value = +'version'] { + vertical-align: text-top; } -#changes-list span[data-stub-value='date'], -#changes-list span[data-stub-value='author'] -{ - font-size: 11px; - color: gray; +#changes-list *[data-stub-value = +'date'], #changes-list *[data-stub-value = 'author'] { + font-size: 11px; + color: gray; } - - -/* + +/* * Graphical DIFF view - * + * */ #history-view .diff_table { - width: 90%; + width: 90%; } - .diff_table { - border-width: 1px; - border-style: solid; - border-color: black; - empty-cells: show; - border-spacing: 0px; +.editor.DiffPerspective { + overflow-y: scroll; +} + +.diff_table { + border-width: 1px; + border-style: solid; + border-color: black; + empty-cells: show; + border-spacing: 0px; } .diff_table td { - border-width: 0px 1px 1px 0px; - border-style: dotted; - border-color: grey; - - font-size: 10px; - line-height: 20px; - font-family: monospace; - padding: 0px; - white-space:pre-line; - /*word-wrap:break-word; - word-break:break-all; */ + border-width: 0px 1px 1px 0px; + border-style: dotted; + border-color: grey; + font-size: 10px; + line-height: 20px; + font-family: monospace; + padding: 0px; + white-space: pre-line; + /*word-wrap:break-word; + word-break:break-all; */ } .diff_table th { - border-width: 0px 1px 1px 0px; - border-style: solid; - border-color: black; - background: #e5ffe5; + border-width: 0px 1px 1px 0px; + border-style: solid; + border-color: black; + background: #e5ffe5; } - -/* .diff_table td.left, .diff_table td.right { - width: 50%; -}*/ +/* .diff_table td.left, .diff_table td.right { + width: 50%; + }*/ .diff_table tr.change { - background-color: #dcdcdc; - + background-color: #dcdcdc; } .diff_mark { - display: inline-block; - padding: 2px; + display: inline-block; + padding: 2px; } .diff_mark_removed { - background-color: #ff9c94; + background-color: #ff9c94; } .diff_mark_added { - background-color: #90ee90; + background-color: #90ee90; } .diff_mark_changed { - background-color: yellow; + background-color: yellow; } \ No newline at end of file diff --git a/platforma/static/css/html.css b/platforma/static/css/html.css index df8c54c6..ba0f8535 100644 --- a/platforma/static/css/html.css +++ b/platforma/static/css/html.css @@ -1,5 +1,4 @@ /* Style widoku HTML. Nie należy tu ustawiaÄ position ani marginesów */ - .htmlview { counter-reset: main; font-size: 16px; @@ -7,42 +6,43 @@ line-height: 1.5em; padding: 3em; padding-left: 45px; - overflow-y: scroll; - overflow-x: auto; + overflow-y: scroll; + overflow-x: auto; } .htmlview[data-tag-names-visible] { - padding-left: 90px; -} - -.htmlview[data-tag-names-visible] *[x-editable]:not(*[x-common])::before { - display: block; - float: left; - clear: left; - content: attr(x-node); - font-weight: bold; - font-style: normal; - font-variant:normal; - font-size: 8px; - line-height: 8px; - margin-bottom: 4px; - - padding: 3px 4px; - vertical-align: super; - background-color:#add8e6; - margin-left: -80px; - width: 70px; - text-align: center; - - -webkit-border-radius: 4px; -} - -.htmlview *[x-node='RDF'] { + padding-left: 90px; +} + +/* + .htmlview[data-tag-names-visible] *[x-editable]:not(*[x-common])::before { + display: block; + float: left; + clear: left; + content: attr(x-node); + font-weight: bold; + font-style: normal; + font-variant:normal; + font-size: 8px; + line-height: 8px; + margin-bottom: 4px; + + padding: 3px 4px; + vertical-align: super; + background-color:#add8e6; + margin-left: -80px; + width: 70px; + text-align: center; + + -webkit-border-radius: 4px; + } + */ +.htmlview *[x-node = 'RDF'] { display: none; } .htmlview * { - position: relative; + position: relative; } .htmlview div { @@ -142,7 +142,7 @@ } .htmlview .podtytul { - /* */ + /* */ } .htmlview .didaskalia { @@ -155,49 +155,55 @@ } .htmlview .strofa { - margin: 1.5em 0 0.5em auto; + margin: 1.5em 0 0.5em auto; } /* wersy */ -.htmlview .strofa .wers_wciety, .htmlview .strofa .wers_wciety[data-wlf-typ='1'] { - margin-left: 1em; +.htmlview .strofa .wers_wciety, .htmlview .strofa .wers_wciety[data-wlf-typ = +'1'] { + margin-left: 1em; } -.htmlview .strofa .wers_wciety[data-wlf-typ='2'] { - margin-left: 2em; +.htmlview .strofa .wers_wciety[data-wlf-typ = +'2'] { + margin-left: 2em; } -.htmlview .strofa .wers_wciety[data-wlf-typ='3'] { - margin-left: 3em; +.htmlview .strofa .wers_wciety[data-wlf-typ = +'3'] { + margin-left: 3em; } -.htmlview .strofa .wers_wciety[data-wlf-typ='4'] { - margin-left: 4em; +.htmlview .strofa .wers_wciety[data-wlf-typ = +'4'] { + margin-left: 4em; } -.htmlview .strofa .wers_wciety[data-wlf-typ='5'] { - margin-left: 5em; +.htmlview .strofa .wers_wciety[data-wlf-typ = +'5'] { + margin-left: 5em; } -.htmlview .strofa .wers_wciety[data-wlf-typ='6'] { - margin-left: 6em; +.htmlview .strofa .wers_wciety[data-wlf-typ = +'6'] { + margin-left: 6em; } /* bÅÄdne wersy */ -.htmlview *:not(.strofa) > *[x-verse]::after { - content: "Ten wers znajduje siÄ poza strofÄ ."; - display: inline; - background: red; - font-size: 8pt; - border: 1px solid black; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; - padding: 1px 1em; - margin-left: 1em; - vertical-align: super; +.htmlview *: +not(.strofa) > *[x-verse]::after { + content: "Ten wers znajduje siÄ poza strofÄ ."; + display: inline; + background: red; + font-size: 8pt; + border: 1px solid black; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + padding: 1px 1em; + margin-left: 1em; + vertical-align: super; } - .htmlview .kwestia .strofa { margin: 0; } @@ -223,8 +229,7 @@ padding-bottom: 1.5em; } -.htmlview div.nota p, -.htmlview div.dedykacja p { +.htmlview div.nota p, .htmlview div.dedykacja p { text-align: right; font-style: italic; } @@ -255,10 +260,7 @@ font-style: italic; } -.htmlview .mat, -.htmlview .slowo_obce, -.htmlview .tytul_dziela, -.htmlview .didaskalia { +.htmlview .mat, .htmlview .slowo_obce, .htmlview .tytul_dziela, .htmlview .didaskalia { font-style: italic; } @@ -278,73 +280,64 @@ margin: 1em; } - .parse-warning .message { +.parse-warning .message { color: purple; font-weight: bold; } /* Uwaga/Extra */ - .htmlview .uwaga { - background-color: #96e0e4; - border: 1px solid black; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; - display: block; - font-size: 10pt; - line-height: 12pt; - padding: 2px 1em; - float: right; - max-width: 20%; - max-height: 24pt; - margin-left: 0.5em; - overflow: hidden; + background-color: #96e0e4; + border: 1px solid black; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + display: block; + font-size: 10pt; + line-height: 12pt; + padding: 2px 1em; + float: right; + max-width: 20%; + max-height: 24pt; + margin-left: 0.5em; + overflow: hidden; } .utwor > .uwaga { - float: none; - padding: 0.5em 1em; - margin: 1em; - max-width: 100%; - max-height: 100%; + float: none; + padding: 0.5em 1em; + margin: 1em; + max-width: 100%; + max-height: 100%; } .htmlview .uwaga:hover { - max-height: 100%; + max-height: 100%; } - /* Motywy */ /* ======================== */ /* = Footnotes and themes = */ /* ======================== */ - .htmlview .begin, .htmlview .end { background: green; } .htmlview .motyw { /* position: absolute; */ - float: right; left: auto; clear: right; - width: 10em; - font-weight: normal; font-size: 13px; line-height: 18px; font-variant: normal; text-decoration: none; - - background-color: #fff; - -/* border: 1px solid gray; - - border-right: none; -*/ + /* border: 1px solid gray; + + border-right: none; + */ z-index: 1; -moz-user-select: -moz-none; -webkit-user-select: none; @@ -359,15 +352,14 @@ margin-top: 0.2em; } -/* +/* * Przypisy */ - /* Znaczniki w tekÅcie */ -.htmlview .annotation { +.htmlview .annotation { vertical-align: super; text-decoration: none; -/* font-size: 10px; */ + /* font-size: 10px; */ } .htmlview .annotation:before { @@ -378,7 +370,6 @@ .htmlview .annotation:hover { background-color: #96e0e4; } - *.htmlview *.annotation-inline-box { position: static; } @@ -386,33 +377,25 @@ /* * Przypisy w tekÅcie */ - .htmlview .annotation-inline-box > span[x-annotation-box] - { - display: none; - position: absolute; - - width: 300px; - - font-size: 10pt; - line-height: 12pt; - font-weight: normal; - font-style: normal; - - background: #fffe93; - border-color: black; - border-width: 1px; - border-style: solid; - border-radius: 10px; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; - - padding: 3px 5px; - - text-decoration: none; - - z-index: 1000; - } - +.htmlview .annotation-inline-box > span[x-annotation-box] { + display: none; + position: absolute; + width: 300px; + font-size: 10pt; + line-height: 12pt; + font-weight: normal; + font-style: normal; + background: #fffe93; + border-color: black; + border-width: 1px; + border-style: solid; + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + padding: 3px 5px; + text-decoration: none; + z-index: 1000; +} /* * Przypisy na koÅcu utworu (aktualnie nieuzywane) @@ -433,7 +416,6 @@ left: -0.4em; width: 2.5em; text-align: right; - } .htmlview .annotations-block .annotation-backref:before { @@ -444,8 +426,7 @@ /* * EDITABLE ELEMENTS */ - -.htmlview *[x-editable] { +.htmlview *[x-editable] { position: relative; padding: 2px; margin-left: 0; @@ -453,13 +434,11 @@ } /* focused editable element */ -.htmlview *[x-editable]:hover -{ +.htmlview *[x-editable]:hover { z-index: 900; -} +} -.htmlview *[x-editable][x-open] -{ +.htmlview *[x-editable][x-open] { visibility: hidden; } @@ -469,17 +448,16 @@ left: -1px; width: 72px; height: 21px; - display: block; -/* margin: 4px 0 2px 0;*/ + /* margin: 4px 0 2px 0;*/ padding: 5px 5px 2px 5px; border: none; background-color: #FAFAFA; - -/* z-index: 3000;*/ -/* color: #FFF; - z-index: 1500; -*/ border: 1px solid #DDD; + /* z-index: 3000;*/ + /* color: #FFF; + z-index: 1500; + */ + border: 1px solid #DDD; border-bottom: none; } @@ -488,7 +466,7 @@ } .edit-button:hover, .edit-button:active, .delete-button:hover, .delete-button:active, .accept-button:hover, .accept-button:active { -/* color: #FFF;*/ + /* color: #FFF;*/ background-color: #999; color: #FFF; } @@ -513,6 +491,7 @@ .htmlview *[x-editable][x-open] > .default-menu { visibility: hidden; } + .htmlview *[x-editable][x-open] *[x-annotation-box] > .default-menu { visibility: hidden; } @@ -520,6 +499,7 @@ .htmlview *[x-editable] > .edit-menu { visibility: hidden; } + .htmlview *[x-editable] *[x-annotation-box] > .edit-menu { visibility: hidden; } @@ -527,6 +507,7 @@ .htmlview *[x-editable][x-open] > .edit-menu { visibility: visible; } + .htmlview *[x-editable][x-open] *[x-annotation-box] > .edit-menu { visibility: visible; } @@ -535,53 +516,45 @@ border: 0px; background-color: gray; padding: 1px; - z-index: 2000; position: absolute; } -.html-editarea textarea -{ +.html-editarea textarea { position: absolute; top: 0; - margin: 0px; padding: 0px; - width: 100%; height: 100%; - z-index: 0; font-size: 10pt; -/* background-color: ivory;*/ + /* background-color: ivory;*/ } .htmlview .out-of-flow-text { - display: block; - font-face: monospace; + display: block; + font-face: monospace; border: 2px solid red !important; - white-space: pre-line; + white-space: pre-line; } .htmlview .out-of-flow-text::before { - content: "Tekst w tej ramce nie jest otagowany!"; - background-color: #ff6c6c; - color: black; - - font-size: 10pt; - line-height: 12pt; - border: 1px solid black; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; - padding: 5px 1em; - margin: 0em; - margin-left: 1em; - - text-align: justify; - - display: inline; - float: right; - max-width: 25%; + content: "Tekst w tej ramce nie jest otagowany!"; + background-color: #ff6c6c; + color: black; + font-size: 10pt; + line-height: 12pt; + border: 1px solid black; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + padding: 5px 1em; + margin: 0em; + margin-left: 1em; + text-align: justify; + display: inline; + float: right; + max-width: 25%; } .unknown-tag { diff --git a/platforma/static/css/master.css b/platforma/static/css/master.css index 68d82190..5f3fe964 100644 --- a/platforma/static/css/master.css +++ b/platforma/static/css/master.css @@ -69,7 +69,7 @@ body { right: 0px; left: 0px; height: 30px; - border-bottom: 1px solid #999; + border-bottom: 1px solid #999; margin: 0; padding: 0; @@ -102,13 +102,16 @@ body { #tabs { overflow: hidden; margin: 0; - height: 30px; + padding: 0; + height: 31px; + border: 0px; padding-left: 1em; } #tabs li { - height: 24px; - margin-top: 6px; + height: 18px; + margin-top: 6px; + margin-bottom: 0px; -webkit-user-select: none; cursor: pointer; @@ -128,7 +131,8 @@ body { -moz-box-shadow: 1px -1px 2px rgba(127, 127, 127, 0.25); -webkit-box-shadow: 1px -1px 2px rgba(127, 127, 127, 0.25); - border: 1px solid #999; + border: 1px solid #999; + border-bottom-width: 0px; -moz-border-radius: 4px 4px 0px 0px; -webkit-border-radius: 4px; -webkit-border-bottom-left-radius: 0px; @@ -277,6 +281,12 @@ p { margin: 0;} padding-right: 5px; } +img.tabclose { + padding-left: 8px; + width: 10px; + height: 10px; +} + /* * HTML Editor view diff --git a/platforma/static/css/xmlcolors_15032010.css b/platforma/static/css/xmlcolors_15032010.css index 5a2d7ccc..099f94aa 100644 --- a/platforma/static/css/xmlcolors_15032010.css +++ b/platforma/static/css/xmlcolors_15032010.css @@ -1,13 +1,11 @@ .editbox { margin: .4em; margin-top: 5px; - margin-left: 45px; + margin-left: 5px; padding: 0; - font-family:"Lucida Console", monospace; font-size: 13px; - line-height: 18px; - + line-height: 18px; color: black; } diff --git a/platforma/static/js/slugify.js b/platforma/static/js/slugify.js index b000b648..8be7758a 100644 --- a/platforma/static/js/slugify.js +++ b/platforma/static/js/slugify.js @@ -121,4 +121,6 @@ return s; } -})() +})(); + + diff --git a/platforma/static/js/wiki/base.js b/platforma/static/js/wiki/base.js index 535749c8..429b0e66 100644 --- a/platforma/static/js/wiki/base.js +++ b/platforma/static/js/wiki/base.js @@ -1,15 +1,121 @@ (function($) -{ - $.wiki = {}; +{ + var noop = function() { }; - $.wiki.Perspective = function(document, callback) { - // initialization + $.wiki = { + perspectives: {}, + cls: {} }; - $.wiki.Perspective.toString = function() { - return this.perspective_id; + $.wiki.activePerspective = function() { + return this.perspectives[$("#tabs li.active").attr('id')]; + }; + + $.wiki.exitContext = function() { + var ap = this.activePerspective(); + if(ap) ap.onExit(); + return ap; + }; + + $.wiki.enterContext = function(ap) { + if(ap) ap.onEnter(); + }; + + $.wiki.isDirty = function() { + var ap = this.activePerspective(); + return (!!CurrentDocument && CurrentDocument.has_local_changes) || ap.dirty(); + }; + + $.wiki.newTab = function(doc, title, klass) { + var base_id = 'id' + Math.floor(Math.random()* 5000000000); + var id = (''+klass)+'_' + base_id; + var $tab = $('<li id="'+id+'" data-ui-related="'+base_id+'" data-ui-jsclass="'+klass+'" >' + + title + '<img src="/static/icons/close.png" class="tabclose"></li>'); + var $view = $('<div class="editor '+klass+'" id="'+base_id+'"> </div>'); + + this.perspectives[id] = new $.wiki[klass]({ + doc: doc, + id: id, + base_id: base_id, + }); + + $('#tabs').append($tab); + $view.hide().appendTo('#editor'); + return { + tab: $tab[0], + view: $view[0], + }; + }; + + $.wiki.initTab = function(options) { + var klass = $(options.tab).attr('data-ui-jsclass'); + + return new $.wiki[klass]({ + doc: options.doc, + id: $(options.tab).attr('id'), + callback: function() { + $.wiki.perspectives[this.perspective_id] = this; + if(options.callback) + options.callback.call(this); + } + }); + }; + + $.wiki.perspectiveForTab = function(tab) { // element or id + return this.perspectives[ $(tab).attr('id')]; } + $.wiki.switchToTab = function(tab){ + var self = this; + var $tab = $(tab); + + if($tab.length != 1) + $tab = $(DEFAULT_PERSPECTIVE); + + var $old = $('#tabs li').filter('.active'); + + $old.each(function(){ + $(this).removeClass('active'); + $('#' + $(this).attr('data-ui-related')).hide(); + self.perspectives[$(this).attr('id')].onExit(); + }); + + /* show new */ + $tab.addClass('active'); + $('#' + $tab.attr('data-ui-related')).show(); + + console.log($tab); + console.log($.wiki.perspectives); + + $.wiki.perspectives[$tab.attr('id')].onEnter(); + }; + + /* + * Basic perspective. + */ + $.wiki.Perspective = function(options) { + if(!options) return; + + this.doc = options.doc; + if (options.id) { + this.perspective_id = options.id; + } + else { + this.perspective_id = ''; + } + + if(options.callback) + options.callback.call(this); + }; + + $.wiki.Perspective.prototype.toString = function() { + return this.perspective_id; + }; + + $.wiki.Perspective.prototype.dirty = function() { + return true; + }; + $.wiki.Perspective.prototype.onEnter = function () { // called when perspective in initialized if (this.perspective_id) { @@ -21,8 +127,13 @@ $.wiki.Perspective.prototype.onExit = function () { // called when user switches to another perspective + document.location.hash = ''; }; + $.wiki.Perspective.prototype.destroy = function() { + // pass + }; + $.wiki.Perspective.prototype.freezeState = function () { // free UI state (don't store data here) }; @@ -31,6 +142,9 @@ // restore UI state }; + /* + * Stub rendering (used in generating history) + */ $.wiki.renderStub = function($container, $stub, data) { var $elem = $stub.clone(); @@ -57,5 +171,120 @@ $elem.show(); return $elem; }; + + /* + * Dialogs + */ + function GenericDialog(element) { + if(!element) return; + + var self = this; + + self.$elem = $(element); + + if(!self.$elem.attr('data-ui-initialized')) { + console.log("Initializing dialog", this); + self.initialize(); + self.$elem.attr('data-ui-initialized', true); + } + + self.show(); + }; + + GenericDialog.prototype = { + + /* + * Steps to follow when the dialog in first loaded on page. + */ + initialize: function(){ + var self = this; + + /* bind buttons */ + $('button[data-ui-action]', self.$elem).click(function(event) { + event.preventDefault(); + + var action = $(this).attr('data-ui-action'); + console.log("Button pressed, action: ", action); + + try { + self[action + "Action"].call(self); + } catch(e) { + console.log("Action failed:", e); + // always hide on cancel + if(action == 'cancel') + self.hide(); + } + }); + }, + + /* + * Prepare dialog for user. Clear any unnessary data. + */ + show: function() { + $.blockUI({ + message: this.$elem, + css: { + 'top': '25%', + 'left': '25%', + 'width': '50%' + } + }); + }, + + hide: function(){ + $.unblockUI(); + }, + + cancelAction: function() { + this.hide(); + }, + + doneAction: function() { + this.hide(); + }, + + clearForm: function() { + $("*[data-ui-error-for]", this.$elem).text(''); + }, + reportErrors: function(errors) { + var global = $("*[data-ui-error-for='__all__']", this.$elem); + var unassigned = []; + + for (var field_name in errors) + { + var span = $("*[data-ui-error-for='"+field_name+"']", this.$elem); + + if(!span.length) { + unassigned.push(field_name); + continue; + } + + span.text(errors[field_name].join(' ')); + } + + if(unassigned.length > 0) + global.text( global.text() + 'W formularzu wystÄ piÅy bÅÄdy'); + } + }; + + $.wiki.cls.GenericDialog = GenericDialog; + + $.wiki.showDialog = function(selector) { + var elem = $(selector); + + if(elem.length != 1) { + console.log("Failed to show dialog:", selector, elem); + return false; + } + + try { + var klass = elem.attr('data-ui-jsclass') + return new $.wiki.cls[klass](elem); + } catch(e) { + console.log("Failed to show dialog", selector, klass, e); + return false; + } + }; + })(jQuery); diff --git a/platforma/static/js/wiki/diff_view.js b/platforma/static/js/wiki/diff_view.js index 3eafd135..d6e71a68 100644 --- a/platforma/static/js/wiki/diff_view.js +++ b/platforma/static/js/wiki/diff_view.js @@ -1,8 +1,11 @@ (function($){ function DiffPerspective(options) { - var old_callback = options.callback || function() {}; + var old_callback = options.callback || function() {}; + var self = this; + options.callback = function(){ + self.base_id = options.base_id; old_callback.call(this); }; @@ -15,9 +18,13 @@ // must }; + DiffPerspective.prototype.destroy = function() { + $('#' + this.base_id).remove(); + $('#' + this.perspective_id).remove(); + }; + DiffPerspective.prototype.onEnter = function(success, failure){ $.wiki.Perspective.prototype.onEnter.call(this); - console.log("Entered diff view"); }; diff --git a/platforma/static/js/wiki/history_view.js b/platforma/static/js/wiki/history_view.js index 0f35ca3b..2ee4558e 100644 --- a/platforma/static/js/wiki/history_view.js +++ b/platforma/static/js/wiki/history_view.js @@ -1,58 +1,37 @@ (function($){ - - function fetchDiff(success, failed){ - var changelist = $('#changes-list'); - - var selected = $('div.selected', changelist); - - if (selected.length != 2) { - window.alert("Musisz zaznaczyÄ dokÅadnie dwie wersje do porównania."); - if(failed) failed(); - } - - $.blockUI({ - message: 'Wczytywanie porównania...' - }); - - $.ajax({ - method: "GET", - url: document.location.href + '/diff/' + rev_a.val() + '/' + rev_b.val(), - dataType: 'html', - error: function(){ - $.unblockUI(); - if(failed) failed('Nie udaÅo siÄ wczytaÄ porównania z serwera.'); - }, - success: function(data){ - var diffview = $('#diff-view'); - diffview.html(data); - diffview.show(); - $.unblockUI(); - if(success) success(data); - } - }); - } - function HistoryPerspective(doc, callback) { - this.perspective_id = 'HistoryPerspective'; - this.doc = doc; - - // first time page is rendered - $('#make-diff-button').click(fetchDiff); - - $('#changes-list div').live('click', function() { - var $this = $(this); - if($this.hasClass('selected')) - return $this.removeClass('selected'); - - if($("#changes-list div.selected").length < 2) - return $this.addClass('selected'); - }); + function HistoryPerspective(options) { + var old_callback = options.callback || function() {}; - $('#changes-list span.tag').live('click', function(event) { - return false; - }); + options.callback = function() { + var self = this; + + // first time page is rendered + $('#make-diff-button').click(function() { + self.makeDiff(); + }); + + $('#tag-changeset-button').click(function() { + self.showTagForm(); + }); + + $('#changes-list .entry').live('click', function(){ + var $this = $(this); + if ($this.hasClass('selected')) + return $this.removeClass('selected'); + + if ($("#changes-list .entry.selected").length < 2) + return $this.addClass('selected'); + }); + + $('#changes-list span.tag').live('click', function(event){ + return false; + }); + + old_callback.call(this); + } - callback.call(this); + $.wiki.Perspective.call(this, options); }; HistoryPerspective.prototype = new $.wiki.Perspective(); @@ -61,46 +40,106 @@ // must }; - HistoryPerspective.prototype.onEnter = function(success, failure) - { - $.wiki.Perspective.prototype.onEnter.call(this); - + HistoryPerspective.prototype.onEnter = function(success, failure){ + $.wiki.Perspective.prototype.onEnter.call(this); + $.blockUI({ message: 'OdÅwieżanie historii...' }); - - function _finalize(s) { - $.unblockUI(); - - if(s) { if(success) success(); } - else { if(failure) failure(); } - } - function _failure(doc, message) { - $('#history-view .message-box').html('Nie udaÅo siÄ odÅwieżyÄ historii:' + message).show(); - _finalize(false); + function _finalize(s){ + $.unblockUI(); + + if (s) { + if (success) + success(); + } + else { + if (failure) + failure(); + } + } + + function _failure(doc, message){ + $('#history-view .message-box').html('Nie udaÅo siÄ odÅwieżyÄ historii:' + message).show(); + _finalize(false); }; - - function _success(doc, data) { - $('#history-view .message-box').hide(); + + function _success(doc, data){ + $('#history-view .message-box').hide(); var changes_list = $('#changes-list'); - var $stub = $('#history-view .row-stub'); + var $stub = $('#history-view .row-stub'); changes_list.html(''); - + $.each(data, function(){ - $.wiki.renderStub(changes_list, $stub, this); + $.wiki.renderStub(changes_list, $stub, this); }); - - $('span[data-version-tag]', changes_list).each(function() { - $(this).text($(this).attr('data-version-tag')); - }); - - _finalize(true); + + $('span[data-version-tag]', changes_list).each(function(){ + $(this).text($(this).attr('data-version-tag')); + }); + + _finalize(true); }; + + return this.doc.fetchHistory({ + success: _success, + failure: _failure + }); + }; + + HistoryPerspective.prototype.showTagForm = function(){ + var selected = $('#changes-list .entry.selected'); + + if (selected.length != 1) { + window.alert("Musisz dokÅadnie jednÄ wersjÄ do oznaczenia."); + return; + } - return this.doc.fetchHistory({success: _success, failure: _failure}); - }; + var version = parseInt($("*[data-stub-value='version']", selected[0]).text()); + var dialog = $('#add_tag_dialog'); - $.wiki.HistoryPerspective = HistoryPerspective; + $("input[name='version']", dialog).val(version); + + console.log($('form', dialog).serialize()); + + $.blockUI({ + message: dialog + }); + }; + HistoryPerspective.prototype.makeDiff = function() { + var changelist = $('#changes-list'); + var selected = $('.entry.selected', changelist); + + if (selected.length != 2) { + window.alert("Musisz zaznaczyÄ dokÅadnie dwie wersje do porównania."); + return; + } + + $.blockUI({ + message: 'Wczytywanie porównania...' + }); + + var rev_from = $("*[data-stub-value='version']", selected[1]).text(); + var rev_to = $("*[data-stub-value='version']", selected[0]).text(); + + return this.doc.fetchDiff({ + from: rev_from, + to: rev_to, + success: function(doc, data){ + var result = $.wiki.newTab(doc, ''+rev_from +' -> ' + rev_to, 'DiffPerspective'); + + $(result.view).html(data); + $.wiki.switchToTab(result.tab); + $.unblockUI(); + }, + failure: function(doc){ + $.unblockUI(); + } + }); + }; + + $.wiki.HistoryPerspective = HistoryPerspective; + })(jQuery); diff --git a/platforma/static/js/wiki/main.js b/platforma/static/js/wiki/main.js index 802926c2..ef127e37 100644 --- a/platforma/static/js/wiki/main.js +++ b/platforma/static/js/wiki/main.js @@ -1,4 +1,3 @@ - if (!window.console) { window.console = { log: function(){ @@ -6,74 +5,30 @@ if (!window.console) { } } -THEMES = ['Alkohol', 'Ambicja', 'AnioÅ', 'Antysemityzm', 'Arkadia', 'Artysta', 'BezdomnoÅÄ', 'BezpieczeÅstwo', 'Bieda', 'Bijatyka', 'BÅazen', 'BÅÄ dzenie', 'BÅoto', 'Bogactwo', 'Bóg', 'Brat', 'Bunt', 'Buntownik', 'Burza', 'Car', 'Carpe diem', 'CiemnoÅÄ', 'CieÅ', 'Cisza', 'ChciwoÅÄ', 'Chleb', 'ChÅop', 'Choroba', 'Chrystus', 'Chrzest', 'CiaÅo', 'Cierpienie', 'Cmentarz', 'Cnota', 'Córka', 'Cud', 'Czarownika', 'Czary', 'Czas', 'Czyn', 'CzyÅciec', 'Dama', 'Danse macabre', 'Deszcz', 'DiabeÅ', 'Dobro', 'Dom', 'DorosÅoÅÄ', 'Drzewo', 'Duch', 'Dusza', 'Duma', 'Dworek', 'Dworzanin', 'Dwór', 'DzieciÅstwo', 'Dziecko', 'Dziedzictwo', 'Dziewictwo', 'DźwiÄk', 'Egzorcyzm', 'Elita', 'Emigrant', 'FaÅsz', 'Filozof', 'Fircyk', 'Flirt', 'GÅupiec', 'GÅupota', 'GÅód', 'Gospodarz', 'Gospodyni', 'GoÅÄ', 'Gotycyzm', 'Góra', 'Gra', 'Grób', 'Grzech', 'GrzecznoÅÄ', 'Gwiazda', 'Handel', 'HaÅba', 'Historia', 'Honor', 'Idealista', 'ImiÄ', 'Interes', 'JabÅka', 'Jedzenie', 'JesieÅ', 'Kaleka', 'Kara', 'Karczma', 'KlÄska', 'KÅamstwo', 'KÅótnia', 'Kobieta', 'Kobieta demoniczna', 'Kobieta "upadÅa"', 'Kochanek', 'Kochanek romantyczny', 'Kolonializm', 'Kondycja ludzka', 'Konflikt', 'Konflikt wewnÄtrzny', 'Koniec Åwiata', 'KoÅ', 'KorzyÅÄ', 'Kot', 'Kradzież', 'Krew', 'Król', 'Krzywda', 'KsiÄ dz', 'KsiÄ Å¼ka', 'KsiÄżyc', 'Kuchnia', 'Kuszenie', 'Kwiaty', 'Labirynt', 'Las', 'Lato', 'Lekarz', 'Lenistwo', 'List', 'Liberat', 'Los', 'Lud', 'Lustro', 'Åzy', 'MaÅżeÅstwo', 'Marzenie', 'Maska', 'Maszyna', 'Matka', 'Matka Boska', 'MÄ droÅÄ', 'MÄ Å¼', 'Melancholia', 'MÄdrzec', 'MÄżczyzna', 'Miasto', 'Mieszczanin', 'MiÅosierdzie', 'MiÅoÅÄ', 'MiÅoÅÄ niespeÅniona', 'MiÅoÅÄ platoniczna', 'MiÅoÅÄ romantyczna', 'MiÅoÅÄ silniejsza niż ÅmierÄ', 'MiÅoÅÄ speÅniona', 'MiÅoÅÄ tragiczna', 'Mizoginia', 'MÅodoÅÄ', 'Moda', 'Modlitwa', 'Morderstwo', 'Morze', 'Motyl', 'Mucha', 'Muzyka', 'Narodziny', 'Naród', 'Natura', 'Nauczyciel', 'Nauczycielka', 'Nauka', 'NiebezpieczeÅstwo', 'Niedziela', 'Niemiec', 'NienawiÅÄ', 'NieÅmiertelnoÅÄ', 'Niewola', 'Noc', 'Nuda', 'Obcy', 'ObÅok', 'ObowiÄ zek', 'Obraz Åwiata', 'ObrzÄdy', 'Obyczaje', 'Obywatel', 'Odrodzenie przez grób', 'Odwaga', 'Ofiara', 'OgieÅ', 'Ogród', 'Ojciec', 'Ojczyzna', 'Oko', 'OkrÄt', 'OkrucieÅstwo', 'Omen', 'Opieka', 'Organizm', 'OtchÅaÅ', 'PajÄ k', 'PamiÄÄ', 'Pan', 'Panna mÅoda', 'PaÅstwo', 'Patriota', 'PiekÅo', 'Pielgrzym', 'PieniÄ dz', 'Pies', 'PiÄtno', 'PijaÅstwo', 'Piwnica', 'Plotka', 'PobożnoÅÄ', 'PocaÅunek', 'Pochlebstwo', 'Poeta', 'Poetka', 'Poezja', 'Podróż', 'PodstÄp', 'Pogrzeb', 'Pojedynek', 'Pokora', 'Pokusa', 'Polak', 'Polityka', 'Polowanie', 'Polska', 'Portret', 'Porwanie', 'PoÅwiÄcenie', 'Potwór', 'Powstanie', 'Powstaniec', 'Pozory', 'Pozycja spoÅeczna', 'Pożar', 'PoÅ¼Ä danie', 'Praca', 'Praca u podstaw', 'Praca organiczna', 'Prawda', 'Prawnik', 'Prometeusz', 'Proroctwo', 'Prorok', 'PróżnoÅÄ', 'Przebranie', 'Przeczucie', 'Przedmurze chrzeÅcijaÅstwa', 'PrzekleÅstwo', 'Przekupstwo', 'Przemiana', 'Przemijanie', 'Przemoc', 'PrzestrzeÅ', 'PrzyjaźÅ', 'Przyroda nieożywiona', 'PrzysiÄga', 'Przywódca', 'Ptak', 'Pustynia', 'Pycha', 'Raj', 'Realista', 'Religia', 'Rewolucja', 'Robak', 'Robotnik', 'Rodzina', 'Rosja', 'Rosjanin', 'RoÅliny', 'Rozczarowanie', 'Rozpacz', 'Rozstanie', 'Rozum', 'Ruiny', 'Rycerz', 'Rzeka', 'Salon', 'Samobójstwo', 'Samolubstwo', 'Samotnik', 'SamotnoÅÄ', 'Sarmata', 'SÄ siad', 'SÄ d', 'SÄ d Ostateczny', 'Sen', 'Serce', 'SÄdzia', 'Sielanka', 'Sierota', 'SiÅa', 'Siostra', 'SÅawa', 'SÅoÅce', 'SÅowo', 'SÅuga', 'SÅużalczoÅÄ', 'SkÄ piec', 'Sobowtór', 'SpoÅecznik', 'Spowiedź', 'SprawiedliwoÅÄ', 'StaroÅÄ', 'Strach', 'Strój', 'Stworzenie', 'Sumienie', 'Swaty', 'Syberia', 'Syn', 'Syn marnotrawny', 'Syzyf', 'Szaleniec', 'SzaleÅstwo', 'Szantaż', 'Szatan', 'SzczÄÅcie', 'SzkoÅa', 'Szlachcic', 'Szpieg', 'Sztuka', 'Ålub', 'Åmiech', 'ÅmierÄ', 'ÅmierÄ bohaterska', 'Åpiew', 'ÅwiatÅo', 'ÅwiÄtoszek', 'ÅwiÄty', 'Åwit', 'Tajemnica', 'Taniec', 'Tchórzostwo', 'Teatr', 'Testament', 'TÄsknota', 'Theatrum mundi', 'TÅum', 'Trucizna', 'Trup', 'TwórczoÅÄ', 'UczeÅ', 'Uczta', 'Uroda', 'Umiarkowanie', 'Upadek', 'Upiór', 'UrzÄdnik', 'Vanitas', 'Walka', 'Walka klas', 'Wampir', 'Warszawa', 'WÄ Å¼', 'Wdowa', 'Wdowiec', 'Wesele', 'Wiatr', 'WiernoÅÄ', 'Wierzenia', 'WieÅ', 'Wiedza', 'Wieża Babel', 'WiÄzienie', 'WiÄzieÅ', 'Wina', 'Wino', 'Wiosna', 'Wizja', 'WÅadza', 'WÅasnoÅÄ', 'Woda', 'Wojna', 'Wojna pokoleÅ', 'WolnoÅÄ', 'Wróg', 'Wspomnienia', 'WspóÅpraca', 'Wygnanie', 'Wyrzuty sumienia', 'Wyspa', 'Wzrok', 'Zabawa', 'Zabobony', 'Zamek', 'ZarÄczyny', 'ZaÅwiaty', 'ZazdroÅÄ', 'Zbawienie', 'Zbrodnia', 'Zbrodniarz', 'Zdrada', 'Zdrowie', 'Zemsta', 'ZesÅaniec', 'Ziarno', 'Ziemia', 'Zima', 'ZÅo', 'ZÅodziej', 'ZÅoty wiek', 'Zmartwychwstanie', 'ZwÄ tpienie', 'ZwierzÄta', 'ZwyciÄstwo', 'Å»aÅoba', 'Å»ebrak', 'Å»oÅnierz', 'Å»ona', 'Å»ycie jako wÄdrówka', 'Å»ycie snem', 'Å»yd', 'Å»ywioÅy', 'OÅwiadczyny']; +var DEFAULT_PERSPECTIVE = "#SummaryPerspective"; + +THEMES = [ + 'Alkohol', 'Ambicja', 'AnioÅ', 'Antysemityzm', 'Arkadia', 'Artysta', 'BezdomnoÅÄ', 'BezpieczeÅstwo', 'Bieda', 'Bijatyka', 'BÅazen', 'BÅÄ dzenie', 'BÅoto', 'Bogactwo', 'Bóg', 'Brat', 'Bunt', 'Buntownik', 'Burza', 'Car', 'Carpe diem', 'CiemnoÅÄ', 'CieÅ', 'Cisza', 'ChciwoÅÄ', 'Chleb', 'ChÅop', 'Choroba', 'Chrystus', 'Chrzest', 'CiaÅo', 'Cierpienie', 'Cmentarz', 'Cnota', 'Córka', 'Cud', 'Czarownika', 'Czary', 'Czas', 'Czyn', 'CzyÅciec', 'Dama', 'Danse macabre', 'Deszcz', 'DiabeÅ', 'Dobro', 'Dom', 'DorosÅoÅÄ', 'Drzewo', 'Duch', 'Dusza', 'Duma', 'Dworek', 'Dworzanin', 'Dwór', 'DzieciÅstwo', 'Dziecko', 'Dziedzictwo', 'Dziewictwo', 'DźwiÄk', 'Egzorcyzm', 'Elita', 'Emigrant', 'FaÅsz', 'Filozof', 'Fircyk', 'Flirt', 'GÅupiec', 'GÅupota', 'GÅód', 'Gospodarz', 'Gospodyni', 'GoÅÄ', 'Gotycyzm', 'Góra', 'Gra', 'Grób', 'Grzech', 'GrzecznoÅÄ', 'Gwiazda', 'Handel', 'HaÅba', 'Historia', 'Honor', 'Idealista', 'ImiÄ', 'Interes', 'JabÅka', 'Jedzenie', 'JesieÅ', 'Kaleka', 'Kara', 'Karczma', 'KlÄska', 'KÅamstwo', 'KÅótnia', 'Kobieta', 'Kobieta demoniczna', 'Kobieta "upadÅa"', 'Kochanek', 'Kochanek romantyczny', 'Kolonializm', 'Kondycja ludzka', 'Konflikt', 'Konflikt wewnÄtrzny', 'Koniec Åwiata', 'KoÅ', 'KorzyÅÄ', 'Kot', 'Kradzież', 'Krew', 'Król', 'Krzywda', 'KsiÄ dz', 'KsiÄ Å¼ka', 'KsiÄżyc', 'Kuchnia', 'Kuszenie', 'Kwiaty', 'Labirynt', 'Las', 'Lato', 'Lekarz', 'Lenistwo', 'List', 'Liberat', 'Los', 'Lud', 'Lustro', 'Åzy', 'MaÅżeÅstwo', 'Marzenie', 'Maska', 'Maszyna', 'Matka', 'Matka Boska', 'MÄ droÅÄ', 'MÄ Å¼', 'Melancholia', 'MÄdrzec', 'MÄżczyzna', 'Miasto', 'Mieszczanin', 'MiÅosierdzie', 'MiÅoÅÄ', 'MiÅoÅÄ niespeÅniona', 'MiÅoÅÄ platoniczna', 'MiÅoÅÄ romantyczna', 'MiÅoÅÄ silniejsza niż ÅmierÄ', 'MiÅoÅÄ speÅniona', 'MiÅoÅÄ tragiczna', 'Mizoginia', 'MÅodoÅÄ', 'Moda', 'Modlitwa', 'Morderstwo', 'Morze', 'Motyl', 'Mucha', 'Muzyka', 'Narodziny', 'Naród', 'Natura', 'Nauczyciel', 'Nauczycielka', 'Nauka', 'NiebezpieczeÅstwo', 'Niedziela', 'Niemiec', 'NienawiÅÄ', 'NieÅmiertelnoÅÄ', 'Niewola', 'Noc', 'Nuda', 'Obcy', 'ObÅok', 'ObowiÄ zek', 'Obraz Åwiata', 'ObrzÄdy', 'Obyczaje', 'Obywatel', 'Odrodzenie przez grób', 'Odwaga', 'Ofiara', 'OgieÅ', 'Ogród', 'Ojciec', 'Ojczyzna', 'Oko', 'OkrÄt', 'OkrucieÅstwo', 'Omen', 'Opieka', 'Organizm', 'OtchÅaÅ', 'PajÄ k', 'PamiÄÄ', 'Pan', 'Panna mÅoda', 'PaÅstwo', 'Patriota', 'PiekÅo', 'Pielgrzym', 'PieniÄ dz', 'Pies', 'PiÄtno', 'PijaÅstwo', 'Piwnica', 'Plotka', 'PobożnoÅÄ', 'PocaÅunek', 'Pochlebstwo', 'Poeta', 'Poetka', 'Poezja', 'Podróż', 'PodstÄp', 'Pogrzeb', 'Pojedynek', 'Pokora', 'Pokusa', 'Polak', 'Polityka', 'Polowanie', 'Polska', 'Portret', 'Porwanie', 'PoÅwiÄcenie', 'Potwór', 'Powstanie', 'Powstaniec', 'Pozory', 'Pozycja spoÅeczna', 'Pożar', 'PoÅ¼Ä danie', 'Praca', 'Praca u podstaw', 'Praca organiczna', 'Prawda', 'Prawnik', 'Prometeusz', 'Proroctwo', 'Prorok', 'PróżnoÅÄ', 'Przebranie', 'Przeczucie', 'Przedmurze chrzeÅcijaÅstwa', 'PrzekleÅstwo', 'Przekupstwo', 'Przemiana', 'Przemijanie', 'Przemoc', 'PrzestrzeÅ', 'PrzyjaźÅ', 'Przyroda nieożywiona', 'PrzysiÄga', 'Przywódca', 'Ptak', 'Pustynia', 'Pycha', 'Raj', 'Realista', 'Religia', 'Rewolucja', 'Robak', 'Robotnik', 'Rodzina', 'Rosja', 'Rosjanin', 'RoÅliny', 'Rozczarowanie', 'Rozpacz', 'Rozstanie', 'Rozum', 'Ruiny', 'Rycerz', 'Rzeka', 'Salon', 'Samobójstwo', 'Samolubstwo', 'Samotnik', 'SamotnoÅÄ', 'Sarmata', 'SÄ siad', 'SÄ d', 'SÄ d Ostateczny', 'Sen', 'Serce', 'SÄdzia', 'Sielanka', 'Sierota', 'SiÅa', 'Siostra', 'SÅawa', 'SÅoÅce', 'SÅowo', 'SÅuga', 'SÅużalczoÅÄ', 'SkÄ piec', 'Sobowtór', 'SpoÅecznik', 'Spowiedź', 'SprawiedliwoÅÄ', 'StaroÅÄ', 'Strach', 'Strój', 'Stworzenie', 'Sumienie', 'Swaty', 'Syberia', 'Syn', 'Syn marnotrawny', 'Syzyf', 'Szaleniec', 'SzaleÅstwo', 'Szantaż', 'Szatan', 'SzczÄÅcie', 'SzkoÅa', 'Szlachcic', 'Szpieg', 'Sztuka', 'Ålub', 'Åmiech', 'ÅmierÄ', 'ÅmierÄ bohaterska', 'Åpiew', 'ÅwiatÅo', 'ÅwiÄtoszek', 'ÅwiÄty', 'Åwit', 'Tajemnica', 'Taniec', 'Tchórzostwo', 'Teatr', 'Testament', 'TÄsknota', 'Theatrum mundi', 'TÅum', 'Trucizna', 'Trup', 'TwórczoÅÄ', 'UczeÅ', 'Uczta', 'Uroda', 'Umiarkowanie', 'Upadek', 'Upiór', 'UrzÄdnik', 'Vanitas', 'Walka', 'Walka klas', 'Wampir', 'Warszawa', 'WÄ Å¼', 'Wdowa', 'Wdowiec', 'Wesele', 'Wiatr', 'WiernoÅÄ', 'Wierzenia', 'WieÅ', 'Wiedza', 'Wieża Babel', 'WiÄzienie', 'WiÄzieÅ', 'Wina', 'Wino', 'Wiosna', 'Wizja', 'WÅadza', 'WÅasnoÅÄ', 'Woda', 'Wojna', 'Wojna pokoleÅ', 'WolnoÅÄ', 'Wróg', 'Wspomnienia', 'WspóÅpraca', 'Wygnanie', 'Wyrzuty sumienia', 'Wyspa', 'Wzrok', 'Zabawa', 'Zabobony', 'Zamek', 'ZarÄczyny', 'ZaÅwiaty', 'ZazdroÅÄ', 'Zbawienie', 'Zbrodnia', 'Zbrodniarz', 'Zdrada', 'Zdrowie', 'Zemsta', 'ZesÅaniec', 'Ziarno', 'Ziemia', 'Zima', 'ZÅo', 'ZÅodziej', 'ZÅoty wiek', 'Zmartwychwstanie', 'ZwÄ tpienie', 'ZwierzÄta', 'ZwyciÄstwo', 'Å»aÅoba', 'Å»ebrak', 'Å»oÅnierz', 'Å»ona', 'Å»ycie jako wÄdrówka', 'Å»ycie snem', 'Å»yd', 'Å»ywioÅy', 'OÅwiadczyny' +]; $(function() { var tabs = $('ol#tabs li'); - var perspectives = {}; var gallery = null; - var wikidoc = new $.wikiapi.WikiDocument("document-meta"); + CurrentDocument = new $.wikiapi.WikiDocument("document-meta"); $.blockUI.defaults.baseZ = 10000; - - function activePerspective() { - return perspectives[$("#tabs " + document.location.hash + "-tab").attr('data-ui-jsclass')]; - }; - + function initialize() { - gallery = new $.wiki.ScanGalleryPerspective(wikidoc); + gallery = new $.wiki.ScanGalleryPerspective({ + doc: CurrentDocument + }); /* The save button */ $('#save-button').click(function(event){ event.preventDefault(); - $.blockUI({ - message: $('#save_dialog'), - css: { - 'top': '25%', - 'left': '25%', - 'width': '50%' - } - }); - }); - - $('#save_dialog .ok-button').click(function(){ - $.blockUI({ - message: 'Zapisywanie...' - }); - - var ap = activePerspective(); - - /* exit perspective */ - ap.onExit(); - - function finalize() { - ap.onEnter(); - $.unblockUI(); - }; - - wikidoc.save({ - comment: $("#komentarz").text(), - success: function(doc, changed, info){ - console.log(info); - $.blockUI({ - message: info - }); - setTimeout(finalize, 2000); - }, - failure: function(doc, info) { - console.log(info); - $.blockUI({ - message: info - }); - setTimeout(finalize, 3000); - } - }); - }); - - $('#save_dialog .cancel-button').click(function(){ - $.unblockUI(); + $.wiki.showDialog('#save_dialog'); }); $('.editor').hide(); @@ -81,20 +36,20 @@ $(function() /* * TABS */ - tabs.click(function(event, callback) { - /* hide old */ - var $old = tabs.filter('.active'); - - $old.each(function(){ - $(this).removeClass('active'); - $('#' + $(this).attr('data-ui-related')).hide(); - perspectives[$(this).attr('data-ui-jsclass')].onExit(); - }); + $('#tabs li').live('click', function(event, callback) { + $.wiki.switchToTab(this); + }); + + $('#tabs li > .tabclose').live('click', function(event, callback) { + var $tab = $(this).parent(); + + if($tab.is('.active')) + $.wiki.switchToTab(DEFAULT_PERSPECTIVE); + + var p = $.wiki.perspectiveForTab($tab); + p.destroy(); - /* show new */ - $(this).addClass('active'); - $('#' + $(this).attr('data-ui-related')).show(); - perspectives[$(this).attr('data-ui-jsclass')].onEnter(); + return false; }); @@ -121,18 +76,29 @@ $(function() } ); - $(window).bind('beforeunload', function(event){ - if(wikidoc.has_local_changes) return "Na stronie mogÄ byÄ zmiany."; - }); + window.onbeforeunload = function(e) { + if($.wiki.isDirty()) { + e.returnValue = "Na stronie mogÄ byÄ nie zapisane zmiany."; + return "Na stronie mogÄ byÄ nie zapisane zmiany."; + }; + }; console.log("Fetching document's text"); - wikidoc.fetch({ + $(document).bind('wlapi_document_changed', function(event, doc) { + try { + $('#document-revision').text(doc.revision); + } catch(e) { + console.log("Failed handler", e); + } + }); + + CurrentDocument.fetch({ success: function(){ console.log("Fetch success"); $('#loading-overlay').fadeOut(); - var active_tab = document.location.hash || "#SummaryPerspective"; - var $active = $("#tabs " + active_tab + "-tab"); + var active_tab = document.location.hash || DEFAULT_PERSPECTIVE; + var $active = $("#tabs " + active_tab); $active.trigger("click"); }, @@ -141,28 +107,25 @@ $(function() alert("FAILURE"); } }); - + + $(window).resize(); }; /* end of initialize() */ var initAll = function(a, f) { if (a.length == 0) return f(); - - var klass = a.pop(); - console.log("INIT", klass); - var p = new $.wiki[klass](wikidoc, function() { - perspectives[this.perspective_id] = this; - initAll(a, f); - }); - + + $.wiki.initTab({ + tab: a.pop(), + doc: CurrentDocument, + callback: function(){ + initAll(a, f); + } + }); }; /* * Initialize all perspectives */ - initAll($.makeArray( $('ol#tabs li').map(function(){ - return $(this).attr('data-ui-jsclass'); - })), initialize); - - console.log(location.hash); - + initAll( $.makeArray($('ol#tabs li')), initialize); + console.log(location.hash); }); diff --git a/platforma/static/js/wiki/save_dialog.js b/platforma/static/js/wiki/save_dialog.js index 827b26b2..2159a570 100644 --- a/platforma/static/js/wiki/save_dialog.js +++ b/platforma/static/js/wiki/save_dialog.js @@ -5,36 +5,50 @@ (function($) { function SaveDialog(element) { - $.wiki.cls.GenericDialog.call(this, element); this.ctx = $.wiki.exitContext(); + this.clearForm(); + + /* fill out hidden fields */ + this.$form = $('form', element); + + $("input[name='id']", this.$form).val(CurrentDocument.id); + $("input[name='parent_revision']", this.$form).val(CurrentDocument.revision); + + $.wiki.cls.GenericDialog.call(this, element); }; - SaveDialog.prototype = new $.wiki.cls.GenericDialog(); + SaveDialog.prototype = new $.wiki.cls.GenericDialog(); - SaveDialog.prototype + SaveDialog.prototype.cancelAction = function() { + $.wiki.enterContext(this.ctx); + this.hide(); + }; SaveDialog.prototype.saveAction = function() { var self = this; self.$elem.block({ - message: "Zapisywanie..." + message: "Zapisywanie...", + fadeIn: 0, }); try { CurrentDocument.save({ - comment: $("#komentarz").text(), + form: self.$form, success: function(doc, changed, info){ self.$elem.block({ message: info, - timeout: 1000, + timeout: 2000, fadeOut: 0, onUnblock: function() { self.hide(); + $.wiki.enterContext(self.ctx); } }); }, failure: function(doc, info) { + console.log("Failure", info); self.reportErrors(info); self.$elem.unblock(); } diff --git a/platforma/static/js/wiki/scan_gallery.js b/platforma/static/js/wiki/scan_gallery.js index 1d496f1a..7f646d72 100644 --- a/platforma/static/js/wiki/scan_gallery.js +++ b/platforma/static/js/wiki/scan_gallery.js @@ -1,9 +1,8 @@ (function($){ - function normalizeNumber(number, length){ + function normalizeNumber(pageNumber, pageCount){ // Numer strony musi byÄ pomiÄdzy 1 a najwyższym numerem - var pageCount = length; - pageNumber = parseInt(pageNumber, 10); + var pageNumber = parseInt(pageNumber, 10); if (!pageNumber || pageNumber == NaN || @@ -42,54 +41,61 @@ /* * Perspective */ - function ScanGalleryPerspective(doc, callback){ - var self = this; - - this.perspective_id = ''; - this.doc = doc; - - this.dimensions = {}; - this.zoomFactor = 1; - this.$element = $("#side-gallery"); - this.$numberInput = $('.page-number', this.$element); - - // ... - var origin = {}; - var imageOrigin = {}; - - this.$image = $('.gallery-image img', this.$element).attr('unselectable', 'on'); - - // button handlers - this.$numberInput.change(function(event){ - event.preventDefault(); - self.setPage($(this).val()); - }); - - $('.previous-page', this.$element).click(function(){ - self.setPage(self.$numberInput.val() - 1); - }); - - $('.nexy-page', this.$element).click(function(){ - self.setPage(self.$numberInput.val() + 1); - }); - - $('.zoom-in', this.$element).click(function(){ - self.alterZoom(0.2); - }); - - $('.zoom-out', this.$element).click(function(){ - self.alterZoom(-0.2); - }); - - $(window).resize(function(){ - self.dimensions.galleryWidth = self.$image.parent().width(); - self.dimensions.galleryHeight = self.$image.parent().height(); - }); + function ScanGalleryPerspective(options){ + var old_callback = options.callback || function() { }; + + options.callback = function(){ + var self = this; + + this.dimensions = {}; + this.zoomFactor = 1; + this.$element = $("#side-gallery"); + this.$numberInput = $('.page-number', this.$element); + + // ... + var origin = {}; + var imageOrigin = {}; + + this.$image = $('.gallery-image img', this.$element).attr('unselectable', 'on'); + + // button handlers + this.$numberInput.change(function(event){ + event.preventDefault(); + self.setPage($(this).val()); + }); + + $('.previous-page', this.$element).click(function(){ + self.setPage(parseInt(self.$numberInput.val(),10) - 1); + }); + + $('.next-page', this.$element).click(function(){ + self.setPage(parseInt(self.$numberInput.val(),10) + 1); + }); + + $('.zoom-in', this.$element).click(function(){ + self.alterZoom(0.2); + }); + + $('.zoom-out', this.$element).click(function(){ + self.alterZoom((-0.2)); + }); + + $(window).resize(function(){ + self.dimensions.galleryWidth = self.$image.parent().width(); + self.dimensions.galleryHeight = self.$image.parent().height(); + }); + + $('.gallery-image img', this.$element).load(function(){ + console.log("Image loaded.") + self._resizeImage(); + }).bind('mousedown', function() { + self.imageMoveStart.apply(self, arguments); + }); + + old_callback.call(this); + }; - $('.gallery-image img', this.$element).load(function(){ - console.load("Image loaded.") - self._resizeImage(); - }); + $.wiki.Perspective.call(this, options); }; ScanGalleryPerspective.prototype = new $.wiki.Perspective(); @@ -106,8 +112,8 @@ width: $img.width() * this.zoomFactor, height: $img.height() * this.zoomFactor, originWidth: $img.width(), - originHeight: $img.height(), - galleryWidth: $img.parent().width(), + originHeight: $img.height(), + galleryWidth: $img.parent().width(), galleryHeight: $img.parent().height() }; @@ -128,7 +134,7 @@ }; ScanGalleryPerspective.prototype.setPage = function(newPage){ - newPage = normalizeNumber(newPage, this.$image.length); + newPage = normalizeNumber(newPage, this.doc.galleryImages.length); this.$numberInput.val(newPage); $('.gallery-image img', this.$element).attr('src', this.doc.galleryImages[newPage - 1]); }; @@ -148,120 +154,87 @@ this.dimensions.width = this.dimensions.originWidth * this.zoomFactor; this.dimensions.height = this.dimensions.originHeight * this.zoomFactor; - var position = normalizePosition(this.$image.position().left, this.$image.position().top, this.dimensions.galleryWidth, this.dimensions.galleryHeight, this.dimensions.width, this.dimensions.height); + // var position = normalizePosition(this.$image.position().left, this.$image.position().top, this.dimensions.galleryWidth, this.dimensions.galleryHeight, this.dimensions.width, this.dimensions.height); - this.$image.css({ + this._resizeImage(); + /* this.$image.css({ width: this.dimensions.width, height: this.dimensions.height, left: position.x, top: position.y - }); + });*/ }; + + /* + * Movement + */ + ScanGalleryPerspective.prototype.imageMoved = function(event){ + event.preventDefault(); + + // origin is where the drag started + // imageOrigin is where the drag started on the image + + var newX = event.clientX - this.origin.x + this.imageOrigin.left; + var newY = event.clientY - this.origin.y + this.imageOrigin.top; + + var position = normalizePosition(newX, newY, this.dimensions.galleryWidth, this.dimensions.galleryHeight, this.dimensions.width, this.dimensions.height); + + this.$image.css({ + left: position.x, + top: position.y, + }); + + return false; + }; + + ScanGalleryPerspective.prototype.imageMoveStart = function(event){ + event.preventDefault(); + + var self = this; + + this.origin = { + x: event.clientX, + y: event.clientY + }; + + this.imageOrigin = self.$image.position(); + $(document).bind('mousemove.gallery', function(){ + self.imageMoved.apply(self, arguments); + }).bind('mouseup.gallery', function() { + self.imageMoveStop.apply(self, arguments); + }); + + return false; + }; + + ScanGalleryPerspective.prototype.imageMoveStop = function(event){ + $(document).unbind('mousemove.gallery').unbind('mouseup.gallery'); + }; /* * Loading gallery */ ScanGalleryPerspective.prototype.onEnter = function(success, failure){ - var self = this; - - $.wiki.Perspective.prototype.onEnter.call(this); + var self = this; - this.doc.refreshGallery({ - success: function(doc, data) { - self.$image.show(); - $('.error_message', self.$element).hide(); - success(); - }, - failure: function(doc, message) { - self.$image.hide(); - $('.error_message', self.$element).show().html(message); - failure(); - } - }); + $.wiki.Perspective.prototype.onEnter.call(this); + + this.doc.refreshGallery({ + success: function(doc, data){ + self.$image.show(); + self.setPage( self.$numberInput.val() ); + + $('.error_message', self.$element).hide(); + if(success) success(); + }, + failure: function(doc, message){ + self.$image.hide(); + $('.error_message', self.$element).show().html(message); + if(failure) failure(); + } + }); }; $.wiki.ScanGalleryPerspective = ScanGalleryPerspective; -})(jQuery); - - -/* - - - function onMouseMove(event){ - - - var position = normalizePosition(event.clientX - origin.x + imageOrigin.left, event.clientY - origin.y + imageOrigin.top, imageDimensions.galleryWidth, imageDimensions.galleryHeight, imageDimensions.width, imageDimensions.height); - - - image.css({ - - - position: 'absolute', - - - top: position.y, - - - left: position.x - - - }); - - - return false; - - - } - - - function onMouseUp(event){ - - - $(document).unbind('mousemove.gallery').unbind('mouseup.gallery'); - - - return false; - - - } - - - image.bind('mousedown', function(event){ - - - origin = { - - - x: event.clientX, - - - y: event.clientY - - - }; - - - imageOrigin = image.position(); - - - $(document).bind('mousemove.gallery', onMouseMove).bind('mouseup.gallery', onMouseUp); - - - return false; - - - }); - - - if (url) { - - - updateGallery(url); - - - } - - - }*/ - - + +})(jQuery); \ No newline at end of file diff --git a/platforma/static/js/wiki/source_editor.js b/platforma/static/js/wiki/source_editor.js index 0f671103..9ca3f643 100644 --- a/platforma/static/js/wiki/source_editor.js +++ b/platforma/static/js/wiki/source_editor.js @@ -1,49 +1,51 @@ /* COMMENT */ (function($) { - function CodeMirrorPerspective(doc, callback) + function CodeMirrorPerspective(options) { - this.perspective_id = 'CodeMirrorPerspective'; - this.doc = doc; // document model - - var self = this; - - this.codemirror = CodeMirror.fromTextArea('codemirror_placeholder', { - parserfile: 'parsexml.js', - path: STATIC_URL + "js/lib/codemirror/", - stylesheet: STATIC_URL + "css/xmlcolors_15032010.css", - parserConfig: { - useHTMLKludges: false - }, - iframeClass: 'xml-iframe', - textWrapping: true, - lineNumbers: true, - width: "100%", - tabMode: 'spaces', - indentUnit: 0, - initCallback: function() { - $('#source-editor .toolbar button').click(function(event){ - event.preventDefault(); - var params = eval("(" + $(this).attr('data-ui-action-params') + ")"); - scriptletCenter.scriptlets[$(this).attr('data-ui-action')](self.codemirror, params); - }); - - $('.toolbar select').change(function(event){ - var slug = $(this).val(); - - $('.toolbar-buttons-container').hide().filter('[data-group=' + slug + ']').show(); - $(window).resize(); - }); - - $('.toolbar-buttons-container').hide(); - $('.toolbar select').change(); + var old_callback = options.callback; + options.callback = function(){ + var self = this; + + this.codemirror = CodeMirror.fromTextArea('codemirror_placeholder', { + parserfile: 'parsexml.js', + path: STATIC_URL + "js/lib/codemirror/", + stylesheet: STATIC_URL + "css/xmlcolors_15032010.css", + parserConfig: { + useHTMLKludges: false + }, + iframeClass: 'xml-iframe', + textWrapping: true, + lineNumbers: false, + width: "100%", + tabMode: 'spaces', + indentUnit: 0, + initCallback: function(){ + $('#source-editor .toolbar button').click(function(event){ + event.preventDefault(); + var params = eval("(" + $(this).attr('data-ui-action-params') + ")"); + scriptletCenter.scriptlets[$(this).attr('data-ui-action')](self.codemirror, params); + }); + + $('.toolbar select').change(function(event){ + var slug = $(this).val(); - console.log("Initialized CodeMirror"); - // textarea is no longer needed - $('codemirror_placeholder').remove(); - callback.call(self); - } - }); + $('.toolbar-buttons-container').hide().filter('[data-group=' + slug + ']').show(); + $(window).resize(); + }); + + $('.toolbar-buttons-container').hide(); + $('.toolbar select').change(); + + console.log("Initialized CodeMirror"); + // textarea is no longer needed + $('codemirror_placeholder').remove(); + old_callback.call(self); + } + }); + }; + + $.wiki.Perspective.call(this, options); }; @@ -56,7 +58,7 @@ CodeMirrorPerspective.prototype.onEnter = function(success, failure) { $.wiki.Perspective.prototype.onEnter.call(this); - console.log(this.doc); + console.log('Entering', this.doc); this.codemirror.setCode(this.doc.text); if(success) success(); } @@ -64,7 +66,7 @@ CodeMirrorPerspective.prototype.onExit = function(success, failure) { $.wiki.Perspective.prototype.onExit.call(this); - console.log(this.doc); + console.log('Exiting', this.doc); this.doc.setText(this.codemirror.getCode()); if(success) success(); } diff --git a/platforma/static/js/wiki/summary_view.js b/platforma/static/js/wiki/summary_view.js index bed8155c..35f03f75 100644 --- a/platforma/static/js/wiki/summary_view.js +++ b/platforma/static/js/wiki/summary_view.js @@ -1,10 +1,12 @@ (function($){ - function SummaryPerspective(doc, callback) { - this.perspective_id = 'SummaryPerspective'; - this.doc = doc; + function SummaryPerspective(options) { + var old_callback = options.callback; + options.callback = function(){ + old_callback.call(this); + }; - callback.call(this); + $.wiki.Perspective.call(this, options); }; SummaryPerspective.prototype = new $.wiki.Perspective(); diff --git a/platforma/static/js/wiki/wikiapi.js b/platforma/static/js/wiki/wikiapi.js index ee444ca1..9bf5555a 100644 --- a/platforma/static/js/wiki/wikiapi.js +++ b/platforma/static/js/wiki/wikiapi.js @@ -93,6 +93,10 @@ // this._context_lock = -1; // return old; // }; + + WikiDocument.prototype.triggerDocumentChanged = function() { + $(document).trigger('wlapi_document_changed', this); + }; /* * Fetch text of this document. @@ -114,6 +118,7 @@ self.revision = data.revision; self.gallery = data.gallery; changed = true; + self.triggerDocumentChanged(); } self.has_local_changes = false; @@ -152,18 +157,18 @@ }; WikiDocument.prototype.fetchDiff = function(params) { - /* this doesn't modify anything, so no locks */ + /* this doesn't modify anything, so no locks */ + var self = this; + params = $.extend({ 'from': self.revision, 'to': self.revision }, noops, params); - var self = this; - $.ajax({ method: "GET", url: reverse("ajax_document_diff", self.id), - dataType: 'json', + dataType: 'html', data: {"from": params['from'], "to": params['to']}, success: function(data) { params['success'](self, data); @@ -187,11 +192,11 @@ dataType: 'json', // data: {}, success: function(data) { - this.galleryImages = data.images; - params['success'](self, data); + self.galleryImages = data; + params['success'](self, data); }, error: function() { - this.galleryImages = []; + self.galleryImages = []; params['failure'](self, "<p>Nie udaÅo siÄ wczytaÄ gallerii pod nazwÄ : '" + self.galleryLink + "'.</p>"); @@ -202,11 +207,9 @@ /* * Set document's text */ - WikiDocument.prototype.setText = function(text) { - if (this.text != text) { - this.text = text; - this.has_local_changes = true; - } + WikiDocument.prototype.setText = function(text) { + this.text = text; + this.has_local_changes = true; }; /* @@ -221,26 +224,26 @@ * Save text back to the server */ WikiDocument.prototype.save = function(params){ - params = $.extend({'comment': 'No comment.'}, noops, params); + params = $.extend({}, noops, params); var self = this; - - /* you can't set text while some is fetching it (or saving) */ - + if (!self.has_local_changes) { console.log("Abort: no changes."); return params['success'](self, false, "Nie ma zmian do zapisania."); }; + // Serialize form to dictionary + var data = {}; + $.each(params['form'].serializeArray(), function() { + data[this.name] = this.value; + }); + var metaComment = '<!--'; metaComment += '\n\tgallery:' + self.galleryLink; metaComment += '\n-->\n' - var data = { - name: self.id, - text: metaComment + self.text, - parent_revision: self.revision, - comment: params['comment'], - }; + data.text = metaComment + self.text; + data.comment = data.comment; $.ajax({ url: reverse("ajax_document_text", self.id), @@ -254,15 +257,27 @@ self.revision = data.revision; self.gallery = data.gallery; changed = true; + self.triggerDocumentChanged(); } - params['success'](self, changed, "Zapisano"); + params['success'](self, changed, + ((changed && "UdaÅo siÄ zapisaÄ :)") || "Twoja wersja i serwera jest identyczna") ); }, - error: function() { - params['failure'](self, "Nie udaÅo siÄ zapisaÄ."); + error: function(xhr) { + try { + params['failure'](self, $.parseJSON(xhr.responseText)); + } + catch(e) { + params['failure'](self, {"__message": "<p>Nie udaÅo siÄ zapisaÄ - bÅÄ d serwera.</p>"}); + }; } }); }; /* end of save() */ + WikiDocument.prototype.setTag = function(params) { + + }; + + $.wikiapi.WikiDocument = WikiDocument; })(jQuery); diff --git a/platforma/static/js/wiki/wysiwyg_editor.js b/platforma/static/js/wiki/wysiwyg_editor.js index 4a84e9d6..eba8695f 100644 --- a/platforma/static/js/wiki/wysiwyg_editor.js +++ b/platforma/static/js/wiki/wysiwyg_editor.js @@ -232,17 +232,19 @@ }); } - $('.delete-button', $overlay).click(function(){ - if ($origin.is('.motyw')) { - $('[theme-class=' + $origin.attr('theme-class') + ']').remove(); - } - else { - $origin.remove(); - } - $overlay.remove(); - $(document).unbind('click.blur-overlay'); - return false; - }) + if ($origin.is('.motyw')) { + $('.delete-button', $overlay).click(function() { + if (window.confirm("Czy jesteÅ pewien, że chcesz usunÄ Ä ten motyw ?")) { + $('[theme-class=' + $origin.attr('theme-class') + ']').remove(); + $overlay.remove(); + $(document).unbind('click.blur-overlay'); + return false; + }; + }); + } + else { + $('.delete-button', $overlay).hide(); + } var serializer = new XMLSerializer(); @@ -297,120 +299,124 @@ } }); } - - function VisualPerspective(doc, callback) - { - this.perspective_id = 'VisualPerspective'; - this.doc = doc; + + function VisualPerspective(options){ - var element = $("html-view"); - var button = $('<button class="edit-button">Edytuj</button>'); + var old_callback = options.callback; - $('#html-view').bind('mousemove', function(event){ - var editable = $(event.target).closest('*[x-editable]'); - $('.active[x-editable]', element).not(editable).removeClass('active').children('.edit-button').remove(); - if (!editable.hasClass('active')) { - editable.addClass('active').append(button); - } - if (editable.is('.annotation-inline-box')) { - $('*[x-annotation-box]', editable).css({ - position: 'absolute', - left: event.clientX - editable.offset().left + 5, - top: event.clientY - editable.offset().top + 5 - }).show(); - } - else { - $('*[x-annotation-box]').hide(); - } - }); - - $('.motyw').live('click', function(){ - selectTheme($(this).attr('theme-class')); - }); - - $('#insert-annotation-button').click(function(){ - addAnnotation(); - return false; - }); - - $('#insert-theme-button').click(function(){ - addTheme(); - return false; - }); + options.callback = function() { + var element = $("#html-view"); + var button = $('<button class="edit-button">Edytuj</button>'); + + $('#html-view').bind('mousemove', function(event){ + var editable = $(event.target).closest('*[x-editable]'); + $('.active', element).not(editable).removeClass('active').children('.edit-button').remove(); + + if (!editable.hasClass('active')) { + editable.addClass('active').append(button); + } + if (editable.is('.annotation-inline-box')) { + $('*[x-annotation-box]', editable).css({ + position: 'absolute', + left: event.clientX - editable.offset().left + 5, + top: event.clientY - editable.offset().top + 5 + }).show(); + } + else { + $('*[x-annotation-box]').hide(); + } + }); + + $('.motyw').live('click', function(){ + selectTheme($(this).attr('theme-class')); + }); + + $('#insert-annotation-button').click(function(){ + addAnnotation(); + return false; + }); + + $('#insert-theme-button').click(function(){ + addTheme(); + return false; + }); + + $('.edit-button').live('click', function(event){ + event.preventDefault(); + openForEdit($(this).parent()); + }); + + old_callback.call(this); + }; - $('.edit-button').live('click', function(event){ - event.preventDefault(); - openForEdit($(this).parent()); - }); - - callback.call(this); + $.wiki.Perspective.call(this, options); }; VisualPerspective.prototype = new $.wiki.Perspective(); - - VisualPerspective.prototype.freezeState = function() { + + VisualPerspective.prototype.freezeState = function(){ }; - - VisualPerspective.prototype.onEnter = function(success, failure) - { - $.wiki.Perspective.prototype.onEnter.call(this); - + + VisualPerspective.prototype.onEnter = function(success, failure){ + $.wiki.Perspective.prototype.onEnter.call(this); + $.blockUI({ message: 'Uaktualnianie widoku...' }); - - function _finalize(callback) { - $.unblockUI(); - if (callback) callback(); - } - + + function _finalize(callback){ + $.unblockUI(); + if (callback) + callback(); + } + xml2html({ xml: this.doc.text, success: function(element){ $('#html-view').html(element); _finalize(success); }, - error: function(text) { + error: function(text){ var message = $('<pre></pre>'); message.text(text); $('#html-view').html('<p class="error">WystÄ piÅ bÅÄ d:</p><pre>' + message.html() + - '</pre>'); - _finalize(failure); + '</pre>'); + _finalize(failure); } - }); - }; - - VisualPerspective.prototype.onExit = function(success, failure) - { - var self = this; - + }); + }; + + VisualPerspective.prototype.onExit = function(success, failure){ + var self = this; + $.blockUI({ message: 'Zapisywanie widoku...' - }); - - function _finalize(callback) { - $.unblockUI(); - if (callback) callback(); - } - - if ($('#html-view .error').length > 0) - return _finalize(failure); - + }); + + function _finalize(callback){ + $.unblockUI(); + if (callback) + callback(); + } + + if ($('#html-view .error').length > 0) + return _finalize(failure); + html2text({ element: $('#html-view div').get(0), - success: function(text) { + success: function(text){ self.doc.setText(text); _finalize(success); }, - error: function(text) { - $('#source-editor').html('<p>WystÄ piÅ bÅÄ d:</p><pre>' + text + '</pre>'); - _finalize(failure); + error: function(text){ + $('#source-editor').html('<p>WystÄ piÅ bÅÄ d:</p><pre>' + text + '</pre>'); + _finalize(failure); } - }); - }; - - $.wiki.VisualPerspective = VisualPerspective; + }); + }; + + $.wiki.VisualPerspective = VisualPerspective; })(jQuery); diff --git a/platforma/templates/base.html b/platforma/templates/base.html index cb518a35..ac728d06 100644 --- a/platforma/templates/base.html +++ b/platforma/templates/base.html @@ -11,8 +11,7 @@ <div id="body-wrap"> <div id="content">{% block maincontent %} {% endblock %}</div> </div> - <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" - type="text/javascript"></script> + <!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script> --> {% block extrabody %}{% endblock %} </body> </html> -- 2.20.1