1 /*global View render_template panels */
2 var HTMLView = View.extend({
3 _className: 'HTMLView',
6 template: 'html-view-template',
8 init: function(element, model, parent, template) {
9 this._super(element, model, template);
13 .addObserver(this, 'data', this.modelDataChanged.bind(this))
14 .addObserver(this, 'state', this.modelStateChanged.bind(this));
17 this.$menuTemplate = $(render_template('html-view-frag-menu-template', this));
18 this.modelStateChanged('state', this.model.get('state'));
19 this.modelDataChanged('data', this.model.get('data'));
23 this.currentOpen = null;
24 this.currentFocused = null;
28 modelDataChanged: function(property, value) {
29 $('.htmlview', this.element).html(value);
30 this.updatePrintLink();
33 /* upgrade editable elements */
34 $("*[x-editable]").each(function() {
35 $(this).append( self.$menuTemplate.clone() );
38 var doc_base = $('.htmlview .utwor', this.element);
41 $(".theme-ref").each(function() {
42 var id = $(this).attr('x-theme-class');
44 var end = $("span.theme-end[x-theme-class = " + id+"]");
45 var begin = $("span.theme-begin[x-theme-class = " + id+"]");
47 var h = $(this).outerHeight();
49 h = Math.max(h, end.offset().top - begin.offset().top);
50 $(this).css('height', h);
54 updatePrintLink: function() {
55 var base = this.$printLink.attr('ui:baseref');
56 this.$printLink.attr('href', base + "?user="+this.model.document.get('user')+"&revision=" + this.model.get('revision'));
59 modelStateChanged: function(property, value)
63 if (value == 'synced' || value == 'dirty') {
65 } else if (value == 'unsynced') {
66 if(this.currentOpen) this.closeWithoutSave(this.currentOpen);
67 this.freeze('Niezsynchronizowany...');
68 } else if (value == 'loading') {
69 this.freeze('Ćadowanie...');
70 } else if (value == 'saving') {
71 this.freeze('Zapisywanie...');
72 } else if (value == 'error') {
73 this.freeze(this.model.get('error'));
74 $('.xml-editor-ref', this.overlay).click(
76 console.log("Sending scroll rq.", this);
78 var href = $(this).attr('href').split('-');
79 var line = parseInt(href[1]);
80 var column = parseInt(href[2]);
82 $(document).trigger('xml-scroll-request', {line:line, column:column});
93 this.element.unbind('click');
95 if(this.$printLink) this.$printLink.unbind();
97 this.$printLink = $('.html-print-link', this.element);
98 this.updatePrintLink();
100 this.element.bind('click', this.itemClicked.bind(this));
101 // this.element.bind('mouseover', this.itemHover.bind(this));
105 this.model.load(true);
108 dispose: function() {
109 this.model.removeObserver(this);
113 itemClicked: function(event)
117 console.log('click:', event, event.ctrlKey, event.target);
118 var $e = $(event.target);
120 if($e.hasClass('annotation'))
122 if(this.currentOpen) return false;
124 var $p = $e.parent();
125 if(this.currentFocused)
127 console.log(this.currentFocused, $p);
128 if($p[0] == this.currentFocused[0]) {
129 console.log('unfocus of current');
130 this.unfocusAnnotation();
134 console.log('switch unfocus');
135 this.unfocusAnnotation();
138 this.focusAnnotation($p);
143 * Clicking outside of focused area doesn't unfocus by default
144 * - this greatly simplifies the whole click check
148 if($e.hasClass('edit-button'))
149 this.openForEdit( this.editableFor($e) );
151 if($e.hasClass('accept-button'))
152 this.closeWithSave( this.editableFor($e) );
154 if($e.hasClass('reject-button'))
155 this.closeWithoutSave( this.editableFor($e) );
158 unfocusAnnotation: function()
160 if(!this.currentFocused)
162 console.log('Redundant unfocus');
167 && this.currentOpen.is("*[x-annotation-box]")
168 && this.currentOpen.parent()[0] == this.currentFocused[0])
170 console.log("Can't unfocus open box");
174 var $box = $("*[x-annotation-box]", this.currentFocused);
175 $box.css({'display': 'none'});
176 // this.currentFocused.removeAttr('x-focused');
177 // this.currentFocused.hide();
178 this.currentFocused = null;
181 focusAnnotation: function($e) {
182 this.currentFocused = $e;
183 var $box = $("*[x-annotation-box]", $e);
184 $box.css({'display': 'block'});
186 // $e.attr('x-focused', 'focused');
189 closeWithSave: function($e) {
190 var $edit = $e.data('edit-overlay');
191 var newText = $('textarea', $edit).val();
193 this.model.putXMLPart($e, newText, function($e, html) {
194 this.renderPart($e, html);
196 $e.removeAttr('x-open');
198 this.currentOpen = null;
201 closeWithoutSave: function($e) {
202 var $edit = $e.data('edit-overlay');
204 $e.removeAttr('x-open');
205 this.currentOpen = null;
208 renderPart: function($e, html) {
209 // exceptions aren't good, but I don't have a better idea right now
210 if($e.attr('x-annotation-box')) {
211 // replace the whole annotation
212 var $p = $e.parent();
214 var $box = $('*[x-annotation-box]', $p);
215 $box.append( this.$menuTemplate.clone() );
217 if(this.currentFocused && $p[0] == this.currentFocused[0])
219 this.currentFocused = $p;
220 $box.css({'display': 'block'});
227 $e.append( this.$menuTemplate.clone() );
230 editableFor: function($button)
235 while( ($e[0] != this.element[0]) && !($e.attr('x-editable')) && n < 50)
237 // console.log($e, $e.parent(), this.element);
242 if(!$e.attr('x-editable'))
243 throw Exception("Click outside of editable")
245 console.log("Trigger", $button, " yields editable: ", $e);
249 openForEdit: function($origin)
251 if(this.currentOpen && this.currentOpen != $origin) {
252 this.closeWithSave(this.currentOpen);
255 var x = $origin[0].offsetLeft;
256 var y = $origin[0].offsetTop;
257 var w = $origin.outerWidth();
258 var h = $origin.innerHeight();
260 console.log("Editable:", $origin, " offsetParent:", $origin[0].offsetParent);
261 console.log("Dimensions: ", x, y, w , h);
263 // start edition on this node
264 var $overlay = $('<div class="html-editarea"><textarea></textarea></div>');
266 $overlay.css({position: 'absolute', height: h, left: x, top: y, width: '95%'});
267 $($origin[0].offsetParent).append($overlay);
268 $origin.data('edit-overlay', $overlay);
270 this.model.getXMLPart($origin, function(path, data) {
271 $('textarea', $overlay).val(data);
274 if($origin.is("*[x-annotation-box]"))
276 var $b = $origin.parent();
277 if(this.currentFocused) {
278 // if some other is focused
279 if($b[0] != this.currentFocused[0]) {
280 this.unfocusAnnotation();
281 this.focusAnnotation($b);
285 else { // nothing was focused
286 this.focusAnnotation($b);
289 else { // this item is not focusable
290 if(this.currentFocused) this.unfocusAnnotation();
293 this.currentOpen = $origin;
294 $origin.attr('x-open', 'open');
302 panels['html'] = HTMLView;