X-Git-Url: https://git.mdrn.pl/redakcja.git/blobdiff_plain/e459e4567cc578abd5d7e02e70a01ec9464f474d..ae9eecda5561b99cd51b1f3709e3cdc803ba47eb:/platforma/static/js/views/html.js diff --git a/platforma/static/js/views/html.js b/platforma/static/js/views/html.js index cc42be24..2dba1c12 100755 --- a/platforma/static/js/views/html.js +++ b/platforma/static/js/views/html.js @@ -8,7 +8,9 @@ var HTMLView = View.extend({ init: function(element, model, parent, template) { var submodel = model.contentModels['html']; this._super(element, submodel, template); - this.parent = parent; + this.parent = parent; + + this.themeEditor = new ThemeEditDialog( $('#theme-edit-dialog') ); this.model .addObserver(this, 'data', this.modelDataChanged.bind(this)) @@ -100,16 +102,21 @@ var HTMLView = View.extend({ if(this.$addThemeButton) this.$addThemeButton.unbind(); + if(this.$addAnnotation) + this.$addAnnotation.unbind(); + this._super(); this.$printLink = $('.htmlview-toolbar .html-print-link', this.element); this.$docbase = $('.htmlview', this.element); - this.$addThemeButton = $('.htmlview-toolbar .html-add-motive', this.element); + this.$addThemeButton = $('.htmlview-toolbar .html-add-theme', this.element); + this.$addAnnotation = $('.htmlview-toolbar .html-add-annotation', this.element); // this.$debugButton = $('.htmlview-toolbar .html-serialize', this.element); this.updatePrintLink(); this.$docbase.bind('click', this.itemClicked.bind(this)); this.$addThemeButton.click( this.addTheme.bind(this) ); + this.$addAnnotation.click( this.addAnnotation.bind(this) ); // this.$debugButton.click( this.serialized.bind(this) ); }, @@ -118,30 +125,6 @@ var HTMLView = View.extend({ console.log( this.model.serializer.serializeToString(this.model.get('data')) ); }, */ - renderPart: function($e, html) { - // exceptions aren't good, but I don't have a better idea right now - if($e.attr('x-annotation-box')) { - // replace the whole annotation - var $p = $e.parent(); - $p.html(html); - var $box = $('*[x-annotation-box]', $p); - $box.append( this.$menuTemplate.clone() ); - - if(this.currentFocused && $p[0] == this.currentFocused[0]) - { - this.currentFocused = $p; - $box.css({ - 'display': 'block' - }); - } - - return; - } - - $e.html(html); - $e.append( this.$menuTemplate.clone() ); - }, - reload: function() { this.model.load(true); }, @@ -185,26 +168,42 @@ var HTMLView = View.extend({ * - this greatly simplifies the whole click check */ - if( $e.hasClass('motyw') ) - { - console.log($e); + if( $e.hasClass('motyw')) + { this.selectTheme($e.attr('theme-class')); return false; } + + if( $e.hasClass('theme-text-list') ) + { + this.selectTheme($e.parent().attr('theme-class')); + return false; + } /* other buttons */ try { + var editable = this.editableFor($e); + + if(!editable) + return false; + if($e.hasClass('delete-button')) - this.deleteElement( this.editableFor($e) ); + this.deleteElement(editable); if($e.hasClass('edit-button')) - this.openForEdit( this.editableFor($e) ); + { + if( editable.hasClass('motyw') ) + this.editTheme(editable); + else + this.openForEdit(editable); + } if($e.hasClass('accept-button')) - this.closeWithSave( this.editableFor($e) ); + this.closeWithSave(editable); if($e.hasClass('reject-button')) - this.closeWithoutSave( this.editableFor($e) ); + this.closeWithoutSave(editable); + } catch(e) { messageCenter.addMessage('error', "wlsave", 'Błąd:' + e.toString()); } @@ -282,7 +281,7 @@ var HTMLView = View.extend({ } if(!$e.attr('x-editable')) - throw Exception("Click outside of editable") + return null; console.log("Trigger", $button, " yields editable: ", $e); return $e; @@ -385,6 +384,10 @@ var HTMLView = View.extend({ } }, + // + // Special stuff for themes + // + // Theme related stuff verifyThemeInsertPoint: function(node) { @@ -414,13 +417,26 @@ var HTMLView = View.extend({ return true; }, - addTheme: function() + + editTheme: function($element) + { + var themeTextSpan = $('.theme-text-list', $element); + this.themeEditor.setFromString( themeTextSpan.text() ); + + function _editThemeFinish(dialog) { + themeTextSpan.text( dialog.userData.themes.join(', ') ); + }; + + this.themeEditor.show(_editThemeFinish); + }, + + + addTheme: function() { var selection = window.getSelection(); var n = selection.rangeCount; console.log("Range count:", n); - if(n == 0) { window.alert("Nie zaznaczono żadnego obszaru"); return false; @@ -432,26 +448,25 @@ var HTMLView = View.extend({ return false; } - // from this point, we will assume that the ranges are disjoint - for(var i=0; i < n; i++) - { - var range = selection.getRangeAt(i); - console.log(i, range.startContainer, range.endContainer); - - // verify if the start/end points make even sense - - // they must be inside a x-node (otherwise they will be discarded) - // and the x-node must be a main text - if(! this.verifyThemeInsertPoint(range.startContainer) ) { - window.alert("Motyw nie może się zaczynać w tym miejscu."); - return false; - } + // remember the selected range + var range = selection.getRangeAt(0); + console.log(range.startContainer, range.endContainer); - if(! this.verifyThemeInsertPoint(range.endContainer) ) { - window.alert("Motyw nie może się kończyć w tym miejscu."); - return false; - } + // verify if the start/end points make even sense - + // they must be inside a x-node (otherwise they will be discarded) + // and the x-node must be a main text + if(! this.verifyThemeInsertPoint(range.startContainer) ) { + window.alert("Motyw nie może się zaczynać w tym miejscu."); + return false; + } - + if(! this.verifyThemeInsertPoint(range.endContainer) ) { + window.alert("Motyw nie może się kończyć w tym miejscu."); + return false; + } + + function _addThemeFinish(dialog) + { var date = (new Date()).getTime(); var random = Math.floor(4000000000*Math.random()); var id = (''+date) + '-' + (''+random); @@ -463,11 +478,13 @@ var HTMLView = View.extend({ epoint.setStart(range.endContainer, range.endOffset); var mtag, btag, etag, errors; + var themesStr = dialog.userData.themes.join(', '); - // insert theme-ref + // insert theme-ref mtag = $(''); spoint.insertNode(mtag[0]); - errors = this.model.updateWithWLML(mtag, 'Nowy Motyw'); + errors = this.model.updateWithWLML(mtag, ''+themesStr+''); + if(errors) { messageCenter.addMessage('error', null, 'Błąd przy dodawaniu motywu :' + errors); return false; @@ -483,7 +500,6 @@ var HTMLView = View.extend({ return false; } - etag = $(''); epoint.insertNode(etag[0]); result = this.model.updateWithWLML(etag, ''); @@ -493,11 +509,16 @@ var HTMLView = View.extend({ messageCenter.addMessage('error', null, 'Błąd przy dodawaniu motywu :' + errors); return false; } - } - selection.removeAllRanges(); - }, + selection.removeAllRanges(); + return true; + }; + // show the modal + this.themeEditor.setFromString(''); + this.themeEditor.show(_addThemeFinish.bind(this)); + }, + selectTheme: function(themeId) { var selection = window.getSelection(); @@ -515,8 +536,125 @@ var HTMLView = View.extend({ range.setEndBefore(e); selection.addRange(range); } + }, + + addAnnotation: function() + { + var selection = window.getSelection(); + var n = selection.rangeCount; + + console.log("Range count:", n); + if(n == 0) { + window.alert("Nie zaznaczono żadnego obszaru"); + return false; + } + + // for now allow only 1 range + if(n > 1) { + window.alert("Zaznacz jeden obszar"); + return false; + } + + // remember the selected range + var range = selection.getRangeAt(0); + + if(! this.verifyThemeInsertPoint(range.endContainer) ) { + window.alert("Nie można wstawić w to miejsce przypisu."); + return false; + } + + var text = range.toString(); + var tag = $(''); + range.collapse(false); + range.insertNode(tag[0]); + var errors = this.model.updateWithWLML(tag, ''+text+" "); + + if(errors) { + tag.remove(); + messageCenter.addMessage('error', null, 'Błąd przy dodawaniu przypisu:' + errors); + return false; + } + + return true; } }); +var ThemeEditDialog = AbstractDialog.extend({ + + validate: function() + { + var active = $('input.theme-list-item:checked', this.$window); + + if(active.length < 1) { + this.errors.push("You must select at least one theme."); + return false; + } + + console.log("Active:", active); + this.userData.themes = $.makeArray(active.map(function() { return this.value; }) ); + console.log('After validate:', this.userData); + return this._super(); + }, + + setFromString: function(string) + { + var $unmatchedList = $('tbody.unknown-themes', this.$window); + + $("tr:not(.header)", $unmatchedList).remove(); + $unmatchedList.hide(); + + $('input.theme-list-item', this.$window).removeAttr('checked'); + + var unmatched = []; + + $.each(string.split(','), function() { + var name = $.trim(this); + if(!name) return; + + console.log('Selecting:', name); + var checkbox = $("input.theme-list-item[value='"+name+"']", this.$window); + + if(checkbox.length > 0) + checkbox.attr('checked', 'checked'); + else + unmatched.push(name); + }); + + if(unmatched.length > 0) + { + $.each(unmatched, function() { + $(''). + appendTo($unmatchedList); + }); + + $unmatchedList.show(); + } + }, + + displayErrors: function() { + var errorP = $('.error-messages-inline-box', this.$window); + if(errorP.length > 0) { + var html = ''; + $.each(this.errors, function() { + html += '' + this + ''; + }); + errorP.html(html); + errorP.show(); + console.log('Validation errors:', html); + } + else + this._super(); + }, + + reset: function() + { + this._super(); + $('.error-messages-inline-box', this.$window).html('').hide(); + } + + }); + // Register view panels['html'] = HTMLView; \ No newline at end of file