From: Lukasz Rekucki Date: Fri, 30 Oct 2009 23:25:06 +0000 (+0100) Subject: Merge branch 'master' into lqc-trunk X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/eba3cb48e4c226b4229e2e38fa390672c3bcc829?hp=aeb0dad220c5e4da9ddd5e8df9f6b0dc554f513f Merge branch 'master' into lqc-trunk --- diff --git a/platforma/static/css/html.css b/platforma/static/css/html.css index 9db90bed..88560687 100755 --- a/platforma/static/css/html.css +++ b/platforma/static/css/html.css @@ -5,7 +5,8 @@ font-size: 16px; font-family: "Georgia", "Times New Roman", serif; line-height: 1.5em; - padding: 3em; + padding: 3em; + padding-left: 55px; } .htmlview * { @@ -25,12 +26,18 @@ text-decoration: none; } +.htmlview a:hover { + text-decoration: none; +} + .htmlview h1 { font-size: 3em; margin: 1.5em 0; text-align: center; line-height: 1.5em; font-weight: bold; + + text-transform: capitalize; } .htmlview h2 { @@ -57,25 +64,6 @@ margin: 0; } -/* ======================== */ -/* = Footnotes and themes = */ -/* ======================== */ -.htmlview .theme-begin { - border-left: 0.1em solid #DDDDDD; - color: #777; - padding: 0 0.5em; - width: 7.5em; - font-style: normal; - font-weight: normal; - font-size: 16px; - float: right; - margin-right: -9.5em; - clear: both; - left: 40em; - line-height: 1.5em; - text-align: left; -} - .htmlview #footnotes div { margin: 1.5em 0 0 0; } @@ -226,22 +214,57 @@ margin: 1em; } -/* Przypisy */ -.htmlview .annotation { - vertical-align: super; - text-decoration: none; - font-size: 0.66em; + .parse-warning .message { + color: purple; + font-weight: bold; } -.htmlview a:hover { + +/* Motywy */ +/* ======================== */ +/* = Footnotes and themes = */ +/* ======================== */ + +.htmlview .theme-begin, .htmlview .theme-end { + background: green; +} + +.htmlview .theme-ref { + position: absolute; + right: -8em; + + min-width: 5em; + max-width: 8em; + + font-weight: normal; + font-size: 10pt; + font-variant: normal; text-decoration: none; + + padding: 0.2em 0.2em 0.2em 0.5em; + + border: 1px solid gray; + border-left: 2px dotted gray; + border-right: none; + + z-index: 1; + -moz-user-select: -moz-none; + -webkit-user-select: none; + user-select: none; } -/* .htmlview .annotation:before { - content: "[\2217]"; -} */ +/* + * Przypisy + */ -.htmlview span.annotation:before { +/* Znaczniki w tekście */ +.htmlview .annotation { + vertical-align: super; + text-decoration: none; + font-size: 0.66em; +} + +.htmlview .annotation:before { content: "[" counter(main) "]"; counter-increment: main; } @@ -250,90 +273,164 @@ background-color: #dfdfdf; } -.parse-warning .message { - color: purple; - font-weight: bold; +*.htmlview *.annotation-inline-box { + position: static; } +/* + * Przypisy w tekście + */ + .htmlview .annotation-inline-box > span[x-annotation-box] + { + display: none; + position: absolute; + + max-width: 36em; + + font-size: 8pt; + line-height: 12pt; + font-weight: normal; + font-style: normal; + + background: white; + border-color: gray; + border-width: 2px; + border-style: outset; + padding: 3px 5px; + + text-decoration: none; + z-index: 10; + } + + +/* + * Przypisy na końcu utworu (aktualnie nieuzywane) + */ +.htmlview .annotations-block { + counter-reset: secondary; +} + +.htmlview .annotations-block .annotation-body { + position: relative; + padding-left: 2.5em; + padding-top: 0.2em; +} + +.htmlview .annotations-block .annotation-backref { + position: absolute; + top: 0.4em; + left: -0.4em; + width: 2.5em; + text-align: right; + +} + +.htmlview .annotations-block .annotation-backref:before { + content: "[" counter(secondary) "]"; + counter-increment: secondary; +} /* * EDITABLE ELEMENTS */ -.htmlview *[x-editable] { - border: 2px solid white; - padding: 5px; +.htmlview *[x-editable] { + padding-left: 3px; } /* focused editable element */ -.htmlview *[x-editable]:hover -{ - background-color: #dfdfdf; - border: 2px solid black; - z-index: 100; -} +/* .htmlview *[x-editable]:hover +{ + +} */ .htmlview *[x-editable][x-open] { visibility: hidden; } -.htmlview *[x-editable] .context-menu { +.htmlview *[x-editable] > .context-menu { position: absolute; - top: -28px; - left: -2px; - height: 24px; + top: 0px; + left: -50px; + width: 50px; text-align: center; - - font-size: 14px; - line-height: 24px; + font-size: 11px; + line-height: 15px; + font-weight: normal; font-style: normal; background-color: #dfdfdf; + margin: 0px; padding: 0px; + visibility: inherit; + display: block; - border-top: 2px solid black; - border-left: 2px solid black; - border-right: 2px solid black; + border-top: 1px solid black; + border-left: 1px solid black; + border-bottom: 1px solid black; - display: none; - visibility: visible; overflow: hidden; - -moz-border-radius-topright: 5px; - -moz-border-radius-topleft: 5px; + -moz-border-radius-topleft: 2px; + -moz-border-radius-bottomleft: 2px; - -webkit-border-top-right-radius: 5px; - -webkit-border-top-left-radius: 5px; + -webkit-border-top-left-radius: 2px; + -webkit-border-bottom-left-radius: 2px; z-index: 3000; } -.htmlview *[x-editable] *.context-menu * { - padding: 5px; +.htmlview *[x-editable] > .context-menu * { + margin: 0px; + display: block; + + -moz-user-select: -moz-none; + -webkit-user-select: none; + + padding: 2px; + cursor: pointer; + border-bottom: 1px solid black; +} + +.htmlview *[x-editable] > .context-menu *:last-child { + cursor: pointer; + border-bottom: none; } -.htmlview *[x-editable] *.context-menu *:hover { - background-color: yellow; - z-index: 3100; +.htmlview *[x-editable] > .context-menu *:hover { + background-color: orange; } /* * VISIBILITY RULES */ -.htmlview *[x-editable]:hover *.default-menu { - display: block; +.htmlview *[x-editable] > .default-menu { + visibility: inherit; + opacity: 0.4; } -.htmlview *[x-editable][x-open] *.default-menu { - display: none; +.htmlview *[x-editable] > .default-menu:hover { + opacity: 1; } -.htmlview *[x-editable][x-open] *.edit-menu { - display: block; +.htmlview *[x-annotation-box][x-editable] > .default-menu { + opacity: 1; +} + +.htmlview *[x-editable][x-open] > .default-menu { + visibility: hidden; +} + +.htmlview *[x-editable] > .edit-menu { + visibility: hidden; +} + +.htmlview *[x-editable][x-open] > .edit-menu { + visibility: visible; } .html-editarea { diff --git a/platforma/static/css/master.css b/platforma/static/css/master.css index 8af8ad48..8200037c 100755 --- a/platforma/static/css/master.css +++ b/platforma/static/css/master.css @@ -153,9 +153,9 @@ text#commit-dialog-message { } .view-overlay { - z-index: 1000; - background: #FFF; - opacity: 0.8; + display: none; + z-index: 0; + background: #FFF; text-align: center; vertical-align: middle; @@ -165,10 +165,11 @@ text#commit-dialog-message { top: 0; bottom: 0; - user-select: 'none'; + /* user-select: 'none'; -webkit-user-select: 'none'; -khtml-user-select: 'none'; - -moz-user-select: 'none'; + -moz-user-select: 'none'; */ + overflow: 'hidden'; } diff --git a/platforma/static/js/button_scripts.js b/platforma/static/js/button_scripts.js old mode 100644 new mode 100755 index 40f45f6f..4af9d72d --- a/platforma/static/js/button_scripts.js +++ b/platforma/static/js/button_scripts.js @@ -6,6 +6,7 @@ function ScriptletCenter() { var text = this.XMLEditorSelectedText(context); var start_tag = '<'+params.tag; + var move_cursor = false; for (var attr in params.attrs) { start_tag += ' '+attr+'="' + params.attrs[attr] + '"'; @@ -39,14 +40,23 @@ function ScriptletCenter() output += token; } else { - output = start_tag + end_tag; + if(params.nocontent) { + output = "<"+params.tag +" />"; + } + else { + output = start_tag + end_tag; + move_cursor = true; + } } this.XMLEditorReplaceSelectedText(context, output); - if (text.length == 0) { - this.XMLEditorMoveCursorForward(context, -params.tag.length-3); - } + try { + if (move_cursor) { + this.XMLEditorMoveCursorForward(context, params.tag.length+2); + } + } catch(e) {} + }.bind(this); this.scriptlets['lineregexp'] = function(context, params) { diff --git a/platforma/static/js/models.js b/platforma/static/js/models.js index ba2f3ce3..40525946 100755 --- a/platforma/static/js/models.js +++ b/platforma/static/js/models.js @@ -522,7 +522,7 @@ Editor.DocumentModel = Editor.Model.extend({ revision: this.get('revision'), user: this.get('user') }, - complete: this.updateCompleted.bind(this), + complete: this.updateCompleted.bind(this) }); }, diff --git a/platforma/static/js/views/html.js b/platforma/static/js/views/html.js index 211b33bc..e1c7b15e 100755 --- a/platforma/static/js/views/html.js +++ b/platforma/static/js/views/html.js @@ -12,25 +12,40 @@ var HTMLView = View.extend({ this.model .addObserver(this, 'data', this.modelDataChanged.bind(this)) .addObserver(this, 'state', this.modelStateChanged.bind(this)); - - $('.htmlview', this.element).html(this.model.get('data')); this.$menuTemplate = $(render_template('html-view-frag-menu-template', this)); - this.modelStateChanged('state', this.model.get('state')); + this.modelDataChanged('data', this.model.get('data')); + this.model.load(); this.currentOpen = null; + this.currentFocused = null; + this.themeBoxes = []; }, modelDataChanged: function(property, value) { $('.htmlview', this.element).html(value); this.updatePrintLink(); var self = this; - - $("*[x-editable]").each(function() { + + /* upgrade editable elements */ + $("*[x-editable]", this.$docbase).each(function() { $(this).append( self.$menuTemplate.clone() ); }); + + /* mark themes */ + /* $(".theme-ref", this.$docbase).each(function() { + var id = $(this).attr('x-theme-class'); + + var end = $("span.theme-end[x-theme-class = " + id+"]"); + var begin = $("span.theme-begin[x-theme-class = " + id+"]"); + + var h = $(this).outerHeight(); + + h = Math.max(h, end.offset().top - begin.offset().top); + $(this).css('height', h); + }); */ }, updatePrintLink: function() { @@ -72,15 +87,46 @@ var HTMLView = View.extend({ }, render: function() { - this.element.unbind('click'); + if(this.$docbase) + this.$docbase.unbind('click'); + + if(this.$printLink) + this.$printLink.unbind(); + + if(this.$addThemeButton) + this.$addThemeButton.unbind(); - if(this.$printLink) this.$printLink.unbind(); this._super(); - this.$printLink = $('.html-print-link', this.element); + + this.$printLink = $('.htmlview-toolbar .html-print-link', this.element); + this.$docbase = $('.htmlview', this.element); + this.$addThemeButton = $('.htmlview-toolbar .html-add-motive', this.element); + this.updatePrintLink(); + this.$docbase.bind('click', this.itemClicked.bind(this)); + this.$addThemeButton.click( this.addTheme.bind(this) ); + }, + + 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'}); + } - this.element.bind('click', this.itemClicked.bind(this)); - // this.element.bind('mouseover', this.itemHover.bind(this)); + return; + } + + $e.html(html); + $e.append( this.$menuTemplate.clone() ); }, reload: function() { @@ -99,6 +145,40 @@ var HTMLView = View.extend({ console.log('click:', event, event.ctrlKey, event.target); var $e = $(event.target); + if($e.hasClass('annotation')) + { + if(this.currentOpen) return false; + + var $p = $e.parent(); + if(this.currentFocused) + { + console.log(this.currentFocused, $p); + if($p[0] == this.currentFocused[0]) { + console.log('unfocus of current'); + this.unfocusAnnotation(); + return false; + } + + console.log('switch unfocus'); + this.unfocusAnnotation(); + } + + this.focusAnnotation($p); + return false; + } + + /* + * Clicking outside of focused area doesn't unfocus by default + * - this greatly simplifies the whole click check + */ + + if( $e.hasClass('theme-ref') ) + { + console.log($e); + this.selectTheme($e.attr('x-theme-class')); + } + + /* other buttons */ if($e.hasClass('edit-button')) this.openForEdit( this.editableFor($e) ); @@ -106,7 +186,38 @@ var HTMLView = View.extend({ this.closeWithSave( this.editableFor($e) ); if($e.hasClass('reject-button')) - this.closeWithoutSave( this.editableFor($e) ); + this.closeWithoutSave( this.editableFor($e) ); + }, + + unfocusAnnotation: function() + { + if(!this.currentFocused) + { + console.log('Redundant unfocus'); + return false; + } + + if(this.currentOpen + && this.currentOpen.is("*[x-annotation-box]") + && this.currentOpen.parent()[0] == this.currentFocused[0]) + { + console.log("Can't unfocus open box"); + return false; + } + + var $box = $("*[x-annotation-box]", this.currentFocused); + $box.css({'display': 'none'}); + // this.currentFocused.removeAttr('x-focused'); + // this.currentFocused.hide(); + this.currentFocused = null; + }, + + focusAnnotation: function($e) { + this.currentFocused = $e; + var $box = $("*[x-annotation-box]", $e); + $box.css({'display': 'block'}); + + // $e.attr('x-focused', 'focused'); }, closeWithSave: function($e) { @@ -128,11 +239,6 @@ var HTMLView = View.extend({ this.currentOpen = null; }, - renderPart: function($e, html) { - $e.html(html); - $e.append( this.$menuTemplate.clone() ); - }, - editableFor: function($button) { var $e = $button; @@ -148,40 +254,122 @@ var HTMLView = View.extend({ if(!$e.attr('x-editable')) throw Exception("Click outside of editable") + console.log("Trigger", $button, " yields editable: ", $e); return $e; }, openForEdit: function($origin) { if(this.currentOpen && this.currentOpen != $origin) { - this.closeWithSave(this.currentOpen); - + this.closeWithSave(this.currentOpen); } - - // start edition on this node - var $overlay = $('
'); - + var x = $origin[0].offsetLeft; var y = $origin[0].offsetTop; var w = $origin.outerWidth(); var h = $origin.innerHeight(); + + console.log("Editable:", $origin, " offsetParent:", $origin[0].offsetParent); + console.log("Dimensions: ", x, y, w , h); + + // start edition on this node + var $overlay = $('
'); - $overlay.css({position: 'absolute', height: h, left: x, top: y, width: '95%'}); - - $origin.offsetParent().append($overlay); - $origin.data('edit-overlay', $overlay); - - this.model.getXMLPart($origin, function(path, data) { - $('textarea', $overlay).val(data); - }); + $overlay.css({position: 'absolute', height: h, left: x, top: y, width: '95%'}); + $($origin[0].offsetParent).append($overlay); + $origin.data('edit-overlay', $overlay); + + this.model.getXMLPart($origin, function(path, data) { + $('textarea', $overlay).val(data); + }); + + if($origin.is("*[x-annotation-box]")) + { + var $b = $origin.parent(); + if(this.currentFocused) { + // if some other is focused + if($b[0] != this.currentFocused[0]) { + this.unfocusAnnotation(); + this.focusAnnotation($b); + } + // already focues + } + else { // nothing was focused + this.focusAnnotation($b); + } + } + else { // this item is not focusable + if(this.currentFocused) this.unfocusAnnotation(); + } - this.currentOpen = $origin; - $origin.attr('x-open', 'open'); + this.currentOpen = $origin; + $origin.attr('x-open', 'open'); + + return false; + }, + + addTheme: function() + { + var selection = document.getSelection(); + var n = selection.rangeCount; + if(n == 0) + window.alert("Nie zaznaczono żadnego obszaru"); + + // for now allow only 1 range + if(n > 1) + window.alert("Zaznacz jeden obszar"); + + // 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); + var date = Date.now(); + var random = Math.floor(4000000000*Math.random()); + var id = (''+date) + '-' + (''+random); + + var ipoint = document.createRange(); + + + + // Firefox alters the later node when inserting, so + // insert from end + ipoint.setStart(range.endContainer, range.endOffset); + elem = $('')[0]; + ipoint.insertNode(elem); + + // insert theme-ref + ipoint.setStart(range.startContainer, range.startOffset); + var elem = $('Nowy motyw')[0]; + ipoint.insertNode(elem); + ipoint.setStartBefore(elem); + + // insert theme-begin + elem = $('')[0]; + ipoint.insertNode(elem); + } + + selection.removeAllRanges(); + }, + + selectTheme: function(themeId) + { + var selection = document.getSelection(); - return false; + // remove current selection + selection.removeAllRanges(); + + var range = document.createRange(); + var s = $('#m'+themeId)[0]; + var e = $('#e'+themeId)[0]; + console.log('Selecting range:', themeId, range, s, e); + + if(s && e) { + range.setStartAfter(s); + range.setEndBefore(e); + selection.addRange(range); + } } - }); // Register view diff --git a/platforma/static/js/views/split.js b/platforma/static/js/views/split.js old mode 100644 new mode 100755 index 30eda4ab..a91cab60 --- a/platforma/static/js/views/split.js +++ b/platforma/static/js/views/split.js @@ -59,6 +59,7 @@ var SplitView = View.extend({ left: this.element.position().left }).appendTo(this.element); this.views.css("-webkit-user-select", "none"); // Safari selects A/B text on a move + this.splitbar.addClass(this.activeClass); this.leftViewOffset = this.leftView[0].offsetWidth - event.pageX; @@ -84,6 +85,11 @@ var SplitView = View.extend({ $(document) .unbind('mousemove.splitview') .unbind('mouseup.splitview'); + + //from beginResize: + // this.views.css("-webkit-user-select", "none"); // Safari selects A/B text on a move + // Restore it! + this.views.css("-webkit-user-select", "auto"); }, resized: function(event) { diff --git a/platforma/templates/explorer/editor.html b/platforma/templates/explorer/editor.html index 2458e8e0..7db4f44a 100755 --- a/platforma/templates/explorer/editor.html +++ b/platforma/templates/explorer/editor.html @@ -65,6 +65,7 @@