From: Łukasz Rekucki Date: Thu, 3 Sep 2009 12:11:23 +0000 (+0200) Subject: Nowe toolbary. X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/300def05b91611b2382df4837c0041d231c8b432 Nowe toolbary. --- diff --git a/apps/explorer/context_processors.py b/apps/explorer/context_processors.py old mode 100644 new mode 100755 diff --git a/apps/explorer/views.py b/apps/explorer/views.py index 19582e25..ed581911 100644 --- a/apps/explorer/views.py +++ b/apps/explorer/views.py @@ -12,7 +12,7 @@ from django.utils import simplejson as json from django.views.generic.simple import direct_to_template from explorer import forms, models - +from toolbar import models as toolbar_models # # Some useful decorators @@ -164,7 +164,9 @@ def file_dc(request, path, repo): @login_required def display_editor(request, path): return direct_to_template(request, 'explorer/editor.html', extra_context={ - 'hash': path, 'panel_list': ['lewy', 'prawy'], + 'hash': path, + 'panel_list': ['lewy', 'prawy'], + 'scriptlets': toolbar_models.Scriptlet.objects.all() }) # =============== diff --git a/apps/toolbar/admin.py b/apps/toolbar/admin.py index 8658d344..052538ea 100644 --- a/apps/toolbar/admin.py +++ b/apps/toolbar/admin.py @@ -18,3 +18,5 @@ admin.site.register(models.ButtonGroup) # list_editable = ('position',) admin.site.register(models.Button) +admin.site.register(models.Scriptlet) + diff --git a/apps/toolbar/models.py b/apps/toolbar/models.py index f91f7390..614cfcb0 100644 --- a/apps/toolbar/models.py +++ b/apps/toolbar/models.py @@ -14,22 +14,36 @@ class ButtonGroup(models.Model): def __unicode__(self): return self.name - class Button(models.Model): label = models.CharField(max_length=32) slug = models.SlugField() #unused - - action = models.CharField(max_length=256) - + + # behaviour + params = models.TextField() # TODO: should be a JSON field + scriptlet = models.ForeignKey('Scriptlet') + + # ui related stuff key = models.CharField(blank=True, max_length=1) - position = models.IntegerField(default=0) + tooltip = models.CharField(blank=True, max_length=120) + + # Why the button is restricted to have the same position in each group ? + # position = models.IntegerField(default=0) group = models.ManyToManyField(ButtonGroup) class Meta: - ordering = ('position', 'label',) + ordering = ('label',) verbose_name, verbose_name_plural = _('button'), _('buttons') def __unicode__(self): return self.label +class Scriptlet(models.Model): + name = models.CharField(max_length=64, primary_key=True) + code = models.TextField() + + # TODO: add this later and remap code property to this + # code_min = models.TextField() + + def __unicode__(self): + return _(u'javascript')+u':'+self.name diff --git a/apps/toolbar/templates/toolbar/toolbar.html b/apps/toolbar/templates/toolbar/toolbar.html index 3238a8c2..a35c7bca 100644 --- a/apps/toolbar/templates/toolbar/toolbar.html +++ b/apps/toolbar/templates/toolbar/toolbar.html @@ -1,6 +1,6 @@ {% load toolbar_tags %}
- +

{% for group in groups %} @@ -17,8 +17,9 @@ {# buttons for this group #} {% for button in group.button_set.all %} {% endfor %} diff --git a/project/static/js/editor.js b/project/static/js/editor.js index 5366c587..628c78d4 100644 --- a/project/static/js/editor.js +++ b/project/static/js/editor.js @@ -1,34 +1,36 @@ function Panel(panelWrap) { - var self = this; - self.wrap = panelWrap; - self.contentDiv = $('.panel-content', panelWrap); - self.instanceId = Math.ceil(Math.random() * 1000000000); - $.log('new panel - wrap: ', self.wrap); + var self = this; + self.wrap = panelWrap; + self.contentDiv = $('.panel-content', panelWrap); + self.instanceId = Math.ceil(Math.random() * 1000000000); + $.log('new panel - wrap: ', self.wrap); - $(document).bind('panel:unload.' + self.instanceId, - function(event, data) { self.unload(event, data); }); - - $(document).bind('panel:contentChanged', function(event, data) { - $.log(self, ' got changed event from: ', data); - if(self != data) - self.otherPanelChanged(event.target); - else - self.markChanged(); - - return false; - }); + $(document).bind('panel:unload.' + self.instanceId, + function(event, data) { + self.unload(event, data); + }); + + $(document).bind('panel:contentChanged', function(event, data) { + $.log(self, ' got changed event from: ', data); + if(self != data) + self.otherPanelChanged(event.target); + else + self.markChanged(); + + return false; + }); } Panel.prototype.callHook = function() { - args = $.makeArray(arguments) + var args = $.makeArray(arguments) var hookName = args.splice(0,1)[0] var noHookAction = args.splice(0,1)[0] var result = false; - $.log('calling hook: ', hookName, 'with args: ', args); - if(this.hooks && this.hooks[hookName]) - result = this.hooks[hookName].apply(this, args); - else if (noHookAction instanceof Function) + $.log('calling hook: ', hookName, 'with args: ', args); + if(this.hooks && this.hooks[hookName]) + result = this.hooks[hookName].apply(this, args); + else if (noHookAction instanceof Function) result = noHookAction(args); return result; } @@ -36,20 +38,20 @@ Panel.prototype.callHook = function() { Panel.prototype.load = function (url) { $.log('preparing xhr load: ', this.wrap); $(document).trigger('panel:unload', this); - var self = this; - self.current_url = url; + var self = this; + self.current_url = url; $.ajax({ url: url, dataType: 'html', - success: function(data, tstat) { - panel_hooks = null; - $(self.contentDiv).html(data); - self.hooks = panel_hooks; - panel_hooks = null; + success: function(data, tstat) { + panel_hooks = null; + $(self.contentDiv).html(data); + self.hooks = panel_hooks; + panel_hooks = null; self.connectToolbar(); - self.callHook('load'); - }, + self.callHook('load'); + }, error: function(request, textStatus, errorThrown) { $.log('ajax', url, this.target, 'error:', textStatus, errorThrown); $(self.contentDiv).html("

Wystapił błąd podczas wczytywania panelu."); @@ -58,54 +60,57 @@ Panel.prototype.load = function (url) { } Panel.prototype.unload = function(event, data) { - $.log('got unload signal', this, ' target: ', data); + $.log('got unload signal', this, ' target: ', data); - if( data == this ) { - $.log('unloading', this); + if( data == this ) { + $.log('unloading', this); $(this.contentDiv).html(''); - this.callHook('unload'); - this.hooks = null; // flush the hooks - return false; + this.callHook('unload'); + this.hooks = null; // flush the hooks + return false; }; } Panel.prototype.refresh = function(event, data) { var self = this; reload = function() { - $.log('hard reload for panel ', self.current_url); - self.load(self.current_url); + $.log('hard reload for panel ', self.current_url); + self.load(self.current_url); return true; } if( this.callHook('refresh', reload) ) - $('.change-notification', this.wrap).fadeOut(); + $('.change-notification', this.wrap).fadeOut(); } Panel.prototype.otherPanelChanged = function(other) { - $.log('panel ', other, ' changed.'); - if(!this.callHook('dirty')) + $.log('panel ', other, ' changed.'); + if(!this.callHook('dirty')) $('.change-notification', this.wrap).fadeIn(); } Panel.prototype.markChanged = function () { - this.wrap.addClass('changed'); + this.wrap.addClass('changed'); } Panel.prototype.changed = function () { - return this.wrap.hasClass('changed'); + return this.wrap.hasClass('changed'); } Panel.prototype.unmarkChanged = function () { - this.wrap.removeClass('changed'); + this.wrap.removeClass('changed'); } Panel.prototype.saveInfo = function() { - var saveInfo = {}; - this.callHook('saveInfo', null, saveInfo); - return saveInfo; + var saveInfo = {}; + this.callHook('saveInfo', null, saveInfo); + return saveInfo; } -Panel.prototype.connectToolbar = function() { +Panel.prototype.connectToolbar = function() +{ + var self = this; + // check if there is a one var toolbar = $("div.toolbar", this.contentDiv); $.log('Connecting toolbar', toolbar); @@ -140,36 +145,41 @@ Panel.prototype.connectToolbar = function() { // connect action buttons var action_buttons = $('*.toolbar-button-groups-container button'); action_buttons.each(function() { - var button = $(this); - var action = button.attr('ui:action').split(':'); - var action_name = action[0]; - var action_data = action[1]; + var button = $(this); button.click(function() { - $.log('emiting action ', action_name, ' with data: ', action_data); - $(document).trigger('ui:action:' + action_name, action_data); + editor.callScriptlet(button.attr('ui:action'), + self, eval(button.attr('ui:action-params')) ); }); + }); } -function Editor() { - this.rootDiv = $('#panels'); +// +Panel.prototype.fireEvent = function(name) { + $(document).trigger('panel:'+name, this); +} + +function Editor() +{ + this.rootDiv = $('#panels'); this.popupQueue = []; this.autosaveTimer = null; + this.scriplets = {}; } Editor.prototype.setupUI = function() { - // set up the UI visually and attach callbacks - var self = this; + // set up the UI visually and attach callbacks + var self = this; - self.rootDiv.makeHorizPanel({}); // TODO: this probably doesn't belong into jQuery + self.rootDiv.makeHorizPanel({}); // TODO: this probably doesn't belong into jQuery // self.rootDiv.css('top', ($('#header').outerHeight() ) + 'px'); - $('#panels > *.panel-wrap').each(function() { - var panelWrap = $(this); - $.log('wrap: ', panelWrap); - var panel = new Panel(panelWrap); - panelWrap.data('ctrl', panel); // attach controllers to wraps + $('#panels > *.panel-wrap').each(function() { + var panelWrap = $(this); + $.log('wrap: ', panelWrap); + var panel = new Panel(panelWrap); + panelWrap.data('ctrl', panel); // attach controllers to wraps panel.load($('.panel-toolbar select', panelWrap).val()); $('.panel-toolbar select', panelWrap).change(function() { @@ -179,28 +189,45 @@ Editor.prototype.setupUI = function() { }); $('.panel-toolbar button.refresh-button', panelWrap).click( - function() { panel.refresh(); } ); + function() { + panel.refresh(); + } ); }); - $(document).bind('panel:contentChanged', function() { self.onContentChanged.apply(self, arguments) }); + $(document).bind('panel:contentChanged', function() { + self.onContentChanged.apply(self, arguments) + }); - $('#toolbar-button-save').click( function (event, data) { self.saveToBranch(); } ); - $('#toolbar-button-commit').click( function (event, data) { self.sendPullRequest(); } ); - self.rootDiv.bind('stopResize', function() { self.savePanelOptions() }); + $('#toolbar-button-save').click( function (event, data) { + self.saveToBranch(); + } ); + $('#toolbar-button-commit').click( function (event, data) { + self.sendPullRequest(); + } ); + self.rootDiv.bind('stopResize', function() { + self.savePanelOptions() + }); } Editor.prototype.loadConfig = function() { // Load options from cookie var defaultOptions = { panels: [ - {name: 'htmleditor', ratio: 0.5}, - {name: 'gallery', ratio: 0.5} + { + name: 'htmleditor', + ratio: 0.5 + }, + + { + name: 'gallery', + ratio: 0.5 + } ], - lastUpdate: 0, + lastUpdate: 0 } try { - var cookie = $.cookie('options'); + var cookie = $.cookie('options'); this.options = $.secureEvalJSON(cookie); if (!this.options) { this.options = defaultOptions; @@ -222,19 +249,19 @@ Editor.prototype.loadPanelOptions = function() { if ($(this).hasClass('last-panel')) { $(this).css({ left: totalWidth, - right: 0, + right: 0 }); } else { $(this).css({ left: totalWidth, - width: panelWidth, + width: panelWidth }); totalWidth += panelWidth; } $.log('panel:', this, $(this).css('left')); $('.panel-toolbar select', this).val( $('.panel-toolbar option[name=' + self.options.panels[index].name + ']', this).attr('value') - ) + ) }); } @@ -250,28 +277,31 @@ Editor.prototype.savePanelOptions = function() { self.options.panels = panels; self.options.lastUpdate = (new Date()).getTime() / 1000; $.log($.toJSON(self.options)); - $.cookie('options', $.toJSON(self.options), { expires: 7, path: '/'}); + $.cookie('options', $.toJSON(self.options), { + expires: 7, + path: '/' + }); } Editor.prototype.saveToBranch = function(msg) { - var changed_panel = $('.panel-wrap.changed'); - var self = this; - $.log('Saving to local branch - panel:', changed_panel); + var changed_panel = $('.panel-wrap.changed'); + var self = this; + $.log('Saving to local branch - panel:', changed_panel); - if(!msg) msg = "Zapis z edytora platformy."; + if(!msg) msg = "Zapis z edytora platformy."; - if( changed_panel.length == 0) { - $.log('Nothing to save.'); - return true; /* no changes */ - } + if( changed_panel.length == 0) { + $.log('Nothing to save.'); + return true; /* no changes */ + } - if( changed_panel.length > 1) { - alert('Błąd: więcej niż jeden panel został zmodyfikowany. Nie można zapisać.'); - return false; - } + if( changed_panel.length > 1) { + alert('Błąd: więcej niż jeden panel został zmodyfikowany. Nie można zapisać.'); + return false; + } - saveInfo = changed_panel.data('ctrl').saveInfo(); + saveInfo = changed_panel.data('ctrl').saveInfo(); var postData = '' if(saveInfo.postData instanceof Object) @@ -279,16 +309,18 @@ Editor.prototype.saveToBranch = function(msg) else postData = saveInfo.postData; - postData += '&' + $.param({'commit_message': msg}) + postData += '&' + $.param({ + 'commit_message': msg + }) - $.ajax({ - url: saveInfo.url, - dataType: 'json', - success: function(data, textStatus) { - if (data.result != 'ok') - self.showPopup('save-error', data.errors[0]); - else { - self.refreshPanels(changed_panel); + $.ajax({ + url: saveInfo.url, + dataType: 'json', + success: function(data, textStatus) { + if (data.result != 'ok') + self.showPopup('save-error', data.errors[0]); + else { + self.refreshPanels(changed_panel); $('#toolbar-button-save').attr('disabled', 'disabled'); $('#toolbar-button-commit').removeAttr('disabled'); if(self.autosaveTimer) @@ -296,13 +328,13 @@ Editor.prototype.saveToBranch = function(msg) self.showPopup('save-successful'); } - }, - error: function(rq, tstat, err) { + }, + error: function(rq, tstat, err) { self.showPopup('save-error'); - }, - type: 'POST', - data: postData - }); + }, + type: 'POST', + data: postData + }); return true; }; @@ -316,27 +348,29 @@ Editor.prototype.autoSave = function() } Editor.prototype.onContentChanged = function(event, data) { - var self = this; + var self = this; - $('#toolbar-button-save').removeAttr('disabled'); - $('#toolbar-button-commit').attr('disabled', 'disabled'); + $('#toolbar-button-save').removeAttr('disabled'); + $('#toolbar-button-commit').attr('disabled', 'disabled'); - if(this.autosaveTimer) return; - this.autosaveTimer = setTimeout( function() { self.autoSave(); }, 300000 ); + if(this.autosaveTimer) return; + this.autosaveTimer = setTimeout( function() { + self.autoSave(); + }, 300000 ); }; Editor.prototype.refreshPanels = function(goodPanel) { - var self = this; - var panels = $('#' + self.rootDiv.attr('id') +' > *.panel-wrap', self.rootDiv.parent()); - - panels.each(function() { - var panel = $(this).data('ctrl'); - $.log('Refreshing: ', this, panel); - if ( panel.changed() ) - panel.unmarkChanged(); - else - panel.refresh(); - }); + var self = this; + var panels = $('#' + self.rootDiv.attr('id') +' > *.panel-wrap', self.rootDiv.parent()); + + panels.each(function() { + var panel = $(this).data('ctrl'); + $.log('Refreshing: ', this, panel); + if ( panel.changed() ) + panel.unmarkChanged(); + else + panel.refresh(); + }); }; @@ -393,11 +427,25 @@ Editor.prototype.showPopup = function(name, text) setTimeout(self._nextPopup, 5000); } +Editor.prototype.registerScriptlet = function(scriptlet_id, scriptlet_func) +{ + // I briefly assume, that it's verified not to break the world on SS + if (!this[scriptlet_id]) + this[scriptlet_id] = scriptlet_func; +} +Editor.prototype.callScriptlet = function(scriptlet_id, panel, params) { + var func = this[scriptlet_id] + if(!func) + throw 'No scriptlet named "' + scriptlet_id + '" found.'; + + return func(this, panel, params); +} + $(function() { - editor = new Editor(); + editor = new Editor(); - // do the layout - editor.loadConfig(); - editor.setupUI(); + // do the layout + editor.loadConfig(); + editor.setupUI(); }); diff --git a/project/templates/base.html b/project/templates/base.html index bf7ed04e..86b63adb 100644 --- a/project/templates/base.html +++ b/project/templates/base.html @@ -20,5 +20,7 @@

{% block message-box %} {% endblock %}
{% block maincontent %} {% endblock %}
+ + {% block extrabody %} {% endblock %} diff --git a/project/templates/explorer/editor.html b/project/templates/explorer/editor.html index bba8e1d1..4d37618a 100644 --- a/project/templates/explorer/editor.html +++ b/project/templates/explorer/editor.html @@ -10,8 +10,22 @@ + {% endblock extrahead %} +{% block extrabody %} + +{% endblock extrabody %} + {% block breadcrumbs %}Platforma Redakcyjna ❯ plik {{ hash }}{% endblock breadcrumbs %} {% block header-toolbar %} diff --git a/project/templates/explorer/panels/xmleditor.html b/project/templates/explorer/panels/xmleditor.html index e2e6b0b4..c818550e 100644 --- a/project/templates/explorer/panels/xmleditor.html +++ b/project/templates/explorer/panels/xmleditor.html @@ -35,17 +35,7 @@ panel_hooks = { // Editor is loaded // Buttons are connected // register callbacks for actions - $(document).bind("ui:action:INSERT_TAG", function(event, data) { - var tag = data; - var text = texteditor.selection(); - editor.replaceSelection('<' + tag + '>' + text + ''); - if (text.length == 0) { - var pos = texteditor.cursorPosition(); - texteditor.selectLines(pos.line, pos.character + tag.length + 2); - } - - $(document).trigger('panel:contentChanged', self); - }); + /* texteditor.grabKeys(function(event) { if (keys[event.keyCode]) { @@ -78,9 +68,8 @@ panel_hooks = { var frameBody = $('body', $(texteditor.frame).contents()); console.log(frameBody.css('font-size')); frameBody.css('font-size', parseInt(frameBody.css('font-size')) + 2); - }); - - this.texteditor = texteditor; + }); + this.texteditor = texteditor; }, unload: function() {