Adds preview option to the wiki toolbar (#27758).

Patch by Marius BALTEANU.

git-svn-id: http://svn.redmine.org/redmine/trunk@17521 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang
2018-09-26 07:27:30 +00:00
parent c171797673
commit b9fa262165
38 changed files with 238 additions and 204 deletions

View File

@@ -449,17 +449,6 @@ function hideModal(el) {
modal.dialog("close");
}
function submitPreview(url, form, target) {
$.ajax({
url: url,
type: 'post',
data: $('#'+form).serialize(),
success: function(data){
$('#'+target).html(data);
}
});
}
function collapseScmEntry(id) {
$('.'+id).each(function() {
if ($(this).hasClass('open')) {
@@ -846,6 +835,28 @@ $(document).ready(function(){
toggleDisabledInit();
});
$(document).ready(function(){
$('#content').on('click', 'div.jstTabs a.tab-preview', function(event){
var tab = $(event.target);
var url = tab.data('url');
var form = tab.parents('form');
var jstBlock = tab.parents('.jstBlock');
var element = encodeURIComponent(jstBlock.find('.wiki-edit').val());
var attachments = form.find('.attachments_fields input').serialize();
$.ajax({
url: url,
type: 'post',
data: "text=" + element + '&' + attachments,
success: function(data){
jstBlock.find('.wiki-preview').html(data);
}
});
});
});
function keepAnchorOnSignIn(form){
var hash = decodeURIComponent(self.document.location.hash);
if (hash) {

View File

@@ -237,8 +237,7 @@ function addInlineAttachmentMarkup(file) {
'selectionStart': cursorPosition + newLineBefore,
'selectionEnd': cursorPosition + inlineFilename.length + newLineBefore
});
$textarea.closest('.jstEditor')
.siblings('.jstElements')
$textarea.parents('.jstBlock')
.find('.jstb_img').click();
// move cursor into next line

File diff suppressed because one or more lines are too long

View File

@@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* DotClear is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with DotClear; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -34,15 +34,45 @@ function jsToolBar(textarea) {
this.textarea = textarea;
this.toolbarBlock = document.createElement('div');
this.toolbarBlock.className = 'jstBlock';
this.textarea.parentNode.insertBefore(this.toolbarBlock, this.textarea);
this.editor = document.createElement('div');
this.editor.className = 'jstEditor';
this.textarea.parentNode.insertBefore(this.editor,this.textarea);
this.preview = document.createElement('div');
this.preview.className = 'wiki wiki-preview hidden';
this.preview.setAttribute('id', 'preview_' + textarea.getAttribute('id'));
this.editor.appendChild(this.textarea);
this.editor.appendChild(this.preview);
this.tabsBlock = document.createElement('div');
this.tabsBlock.className = 'jstTabs tabs';
var This = this;
this.writeTab = new jsTab('Write', true);
this.writeTab.onclick = function(event) { This.hidePreview.call(This, event); return false; };
this.previewTab = new jsTab('Preview');
this.previewTab.onclick = function(event) { This.showPreview.call(This, event); return false; };
var elementsTab = document.createElement('li');
elementsTab.classList = 'tab-elements';
var tabs = document.createElement('ul');
tabs.appendChild(this.writeTab);
tabs.appendChild(this.previewTab);
tabs.appendChild(elementsTab);
this.tabsBlock.appendChild(tabs);
this.toolbar = document.createElement("div");
this.toolbar.className = 'jstElements';
this.editor.parentNode.insertBefore(this.toolbar,this.editor);
elementsTab.appendChild(this.toolbar);
this.toolbarBlock.appendChild(this.tabsBlock);
this.toolbarBlock.appendChild(this.editor);
// Dragable resizing
if (this.editor.addEventListener && navigator.appVersion.match(/\bMSIE\b/))
@@ -53,19 +83,40 @@ function jsToolBar(textarea) {
var This = this;
this.handle.addEventListener('mousedown',function(event) { dragStart.call(This,event); },false);
// fix memory leak in Firefox (bug #241518)
window.addEventListener('unload',function() {
window.addEventListener('unload',function() {
var del = This.handle.parentNode.removeChild(This.handle);
delete(This.handle);
},false);
this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling);
}
this.context = null;
this.toolNodes = {}; // lorsque la toolbar est dessinée , cet objet est garni
this.toolNodes = {}; // lorsque la toolbar est dessinée , cet objet est garni
// de raccourcis vers les éléments DOM correspondants aux outils.
}
function jsTab(name, selected) {
selected = selected || false;
if(typeof jsToolBar.strings == 'undefined') {
var tabName = name || null;
} else {
var tabName = jsToolBar.strings[name] || name || null;
}
var tab = document.createElement('li');
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerText = tabName;
link.className = 'tab-' + name.toLowerCase();
if (selected == true) {
link.classList.add('selected');
}
tab.appendChild(link)
return tab;
}
function jsButton(title, fn, scope, className) {
if(typeof jsToolBar.strings == 'undefined') {
this.title = title || null;
@@ -91,6 +142,7 @@ jsButton.prototype.draw = function() {
if (this.icon != undefined) {
button.style.backgroundImage = 'url('+this.icon+')';
}
if (typeof(this.fn) == 'function') {
var This = this;
button.onclick = function() { try { This.fn.apply(This.scope, arguments) } catch (e) {} return false; };
@@ -110,7 +162,7 @@ jsSpace.prototype.draw = function() {
if (this.width) span.style.marginRight = this.width+'px';
return span;
}
}
function jsCombo(title, options, scope, fn, className) {
this.title = title || null;
@@ -136,7 +188,7 @@ jsCombo.prototype.draw = function() {
var This = this;
select.onchange = function() {
try {
try {
This.fn.call(This.scope, this.value);
} catch (e) { alert(e); }
@@ -152,7 +204,7 @@ jsToolBar.prototype = {
mode: 'wiki',
elements: {},
help_link: '',
getMode: function() {
return this.mode;
},
@@ -170,6 +222,10 @@ jsToolBar.prototype = {
this.help_link = link;
},
setPreviewUrl: function(url) {
this.previewTab.firstChild.setAttribute('data-url', url);
},
button: function(toolName) {
var tool = this.elements[toolName];
if (typeof tool.fn[this.mode] != 'function') return null;
@@ -292,7 +348,6 @@ jsToolBar.prototype = {
encloseSelection: function(prefix, suffix, fn) {
this.textarea.focus();
prefix = prefix || '';
suffix = suffix || '';
@@ -343,7 +398,24 @@ jsToolBar.prototype = {
this.textarea.scrollTop = scrollPos;
}
},
showPreview: function(event) {
if (event.target.classList.contains('selected')) { return; }
this.preview.setAttribute('style', 'min-height: ' + this.textarea.clientHeight + 'px;')
this.toolbar.classList.add('hidden');
this.textarea.classList.add('hidden');
this.preview.classList.remove('hidden');
this.tabsBlock.getElementsByClassName('tab-write')[0].classList.remove('selected');
event.target.classList.add('selected');
},
hidePreview: function(event) {
if (event.target.classList.contains('selected')) { return; }
this.toolbar.classList.remove('hidden');
this.textarea.classList.remove('hidden');
this.preview.classList.add('hidden');
this.tabsBlock.getElementsByClassName('tab-preview')[0].classList.remove('selected');
event.target.classList.add('selected');
},
stripBaseURL: function(url) {
if (this.base_url != '') {
var pos = url.indexOf(this.base_url);

View File

@@ -15,3 +15,5 @@ jsToolBar.strings['Unquote'] = 'Remove Quote';
jsToolBar.strings['Preformatted text'] = 'Preformatted text';
jsToolBar.strings['Wiki link'] = 'Link to a Wiki page';
jsToolBar.strings['Image'] = 'Image';
jsToolBar.strings['Write'] = 'Write';
jsToolBar.strings['Preview'] = 'Preview';

View File

@@ -274,7 +274,6 @@ tr.issue.idnt-8 td.subject {padding-left: 136px; background-position: 120px 50%;
tr.issue.idnt-9 td.subject {padding-left: 152px; background-position: 136px 50%;}
table.issue-report {table-layout:fixed;}
table.issue-report th {white-space: normal;}
tr.entry { border: 1px solid #f8f8f8; }
tr.entry td { white-space: nowrap; }
@@ -678,7 +677,6 @@ span.pagination>span {white-space:nowrap;}
min-height: 2em;
clear:left;
}
html>body .tabular p {overflow:hidden;}
.tabular input, .tabular select {max-width:95%}
@@ -730,11 +728,25 @@ label.no-css {
input#time_entry_comments { width: 90%;}
input#months { width: 30px; }
fieldset.preview {margin-top: 1em; min-width: inherit; background: url(../images/draft.png)}
.jstBlock .jstTabs, .jstBlock .wiki-preview { width: 99%; }
.jstBlock .jstTabs { padding-right: 6px; }
.jstBlock .wiki-preview { padding: 2px; }
.jstBlock .wiki-preview p:first-child { padding-top: 0 !important;}
.jstBlock .wiki-preview p:last-child { padding-bottom: 0 !important;}
#content .box .jstBlock .jstTabs li { background-color: #f6f6f6; }
.tabular .wiki-preview, .tabular .jstTabs {width: 95%;}
.tabular.settings .wiki-preview, .tabular.settings .jstTabs { width: 99%; }
.tabular .wiki-preview p {
min-height: initial;
padding: 1em 0 1em 0 !important;
overflow: initial;
}
.tabular.settings p{ padding-left: 300px; }
.tabular.settings label{ margin-left: -300px; width: 295px; }
.tabular.settings textarea { width: 99%; }
.tabular.settings textarea, .tabular.settings .wiki-preview, .tabular.settings .jstTabs { width: 99%; }
.settings.enabled_scm table {width:100%}
.settings.enabled_scm td.scm_name{ font-weight: bold; }

View File

@@ -1,19 +1,45 @@
.jstBlock .hidden {
display: none;
}
.jstEditor {
padding-left: 0px;
}
.jstEditor textarea, .jstEditor iframe {
margin: 0;
}
.jstHandle {
height: 10px;
font-size: 0.1em;
cursor: s-resize;
/*background: transparent url(img/resizer.png) no-repeat 45% 50%;*/
}
#content .jstTabs.tabs {
margin-bottom: 10px;
}
#content .jstTabs.tabs li {
height: 42px;
}
#content .jstTabs.tabs li:before{
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
}
#content .jstTabs.tabs li a {
display: inline-block;
vertical-align: bottom;
line-height: 19px;
}
.jstElements {
padding: 3px 3px 3px 0;
display: inline-block;
vertical-align: bottom;
border-bottom: 1px solid #bbbbbb;
padding-left: 6px;
height: 26px;
}
.wiki-preview {
background-color: #ffffff;
border: 1px solid #bbbbbb;
}
.jstElements button {