Merge branch 'feature/better-markdown' into 'develop'

Feature - better markdown for description

The description of the poll now has full markdown support:
- Use of ParseDown PHP library to parse markdown
- Use of SimpleMDE JS library to have an more confortable editor
- Possibility to switch from rich editor to simple textarea editor
- Possibility to configure default editor in application
- Small refactoring of adminstuds javascript

See merge request !132
This commit is contained in:
Olivier Perez 2016-08-04 21:54:09 +02:00
commit a86d39c49d
26 changed files with 432 additions and 189 deletions

View File

@ -422,5 +422,6 @@ $smarty->assign('hidden', false);
$smarty->assign('accessGranted', true); $smarty->assign('accessGranted', true);
$smarty->assign('resultPubliclyVisible', true); $smarty->assign('resultPubliclyVisible', true);
$smarty->assign('editedVoteUniqueId', ''); $smarty->assign('editedVoteUniqueId', '');
$smarty->assign('default_to_marldown_editor', $config['markdown_editor_by_default']);
$smarty->display('studs.tpl'); $smarty->display('studs.tpl');

View File

@ -133,32 +133,29 @@ class Utils {
return TABLENAME_PREFIX . $tableName; return TABLENAME_PREFIX . $tableName;
} }
public static function markdown($md, $clear) { public static function markdown($md, $clear=false, $line=true) {
preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/', $md, $md_a_img); // Markdown [![alt](src)](href) $parseDown = new \Parsedown();
preg_match_all('/!\[(.*?)\]\((.*?)\)/', $md, $md_img); // Markdown ![alt](src)
preg_match_all('/\[(.*?)\]\((.*?)\)/', $md, $md_a); // Markdown [text](href)
if (isset($md_a_img[2][0]) && $md_a_img[2][0] != '' && isset($md_a_img[3][0]) && $md_a_img[3][0] != '') { // [![alt](src)](href)
$text = self::htmlEscape($md_a_img[1][0]); $parseDown
$html = '<a href="' . self::htmlEscape($md_a_img[3][0]) . '"><img src="' . self::htmlEscape($md_a_img[2][0]) . '" class="img-responsive" alt="' . $text . '" title="' . $text . '" /></a>'; ->setMarkupEscaped(true)
->setBreaksEnabled(true)
} elseif (isset($md_img[2][0]) && $md_img[2][0] != '') { // ![alt](src) ->setUrlsLinked(false);
$text = self::htmlEscape($md_img[1][0]);
$html = '<img src="' . self::htmlEscape($md_img[2][0]) . '" class="img-responsive" alt="' . $text . '" title="' . $text . '" />';
} elseif (isset($md_a[2][0]) && $md_a[2][0] != '') { // [text](href)
$text = self::htmlEscape($md_a[1][0]);
$html = '<a href="' . $md_a[2][0] . '">' . $text . '</a>';
} else { // text only
$text = self::htmlEscape($md);
$html = $text;
if ($line) {
$html = $parseDown->line($md);
} else {
$md = preg_replace_callback(
'#( ){2,}#',
function ($m) {
return str_repeat('&nbsp;', strlen($m[0]));
},
$md
);
$html = $parseDown->text($md);
} }
$text = strip_tags($html);
return $clear ? $text : $html; return $clear ? $text : $html;
} }

View File

@ -93,4 +93,5 @@ $config = [
'default_poll_duration' => 180, // default values for the new poll duration (number of days). 'default_poll_duration' => 180, // default values for the new poll duration (number of days).
/* create_classic_poll.php */ /* create_classic_poll.php */
'user_can_add_img_or_link' => true, // user can add link or URL when creating his poll. 'user_can_add_img_or_link' => true, // user can add link or URL when creating his poll.
'markdown_editor_by_default' => true // The markdown editor for the description is enabled by default
]; ];

View File

@ -57,8 +57,8 @@ function smarty_function_poll_url($params, Smarty_Internal_Template $template) {
return Utils::getUrlSondage($poll_id, $admin, $vote_unique_id, $action, $action_value); return Utils::getUrlSondage($poll_id, $admin, $vote_unique_id, $action, $action_value);
} }
function smarty_modifier_markdown($md, $clear = false) { function smarty_modifier_markdown($md, $clear = false, $inline=true) {
return Utils::markdown($md, $clear); return Utils::markdown($md, $clear, $inline);
} }
function smarty_modifier_resource($link) { function smarty_modifier_resource($link) {

View File

@ -13,6 +13,7 @@
"smarty/smarty": "3.1.21", "smarty/smarty": "3.1.21",
"o80/i18n": "dev-develop", "o80/i18n": "dev-develop",
"phpmailer/phpmailer": "~5.2", "phpmailer/phpmailer": "~5.2",
"erusev/parsedown": "1.6.0",
"ircmaxell/password-compat": "dev-master" "ircmaxell/password-compat": "dev-master"
}, },

55
composer.lock generated
View File

@ -4,9 +4,48 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "aaacda4cfcffe29ffae43780f903e3b6", "hash": "f1508630f28ba4e97878db2b9531bf46",
"content-hash": "c85ba8e14cce189aef869998ce0e2430", "content-hash": "cd2e2aaf0d7e5d3ea95b4d4d8e808a1b",
"packages": [ "packages": [
{
"name": "erusev/parsedown",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
],
"time": "2015-10-04 16:44:32"
},
{ {
"name": "ircmaxell/password-compat", "name": "ircmaxell/password-compat",
"version": "dev-master", "version": "dev-master",
@ -864,16 +903,16 @@
}, },
{ {
"name": "sebastian/environment", "name": "sebastian/environment",
"version": "1.3.5", "version": "1.3.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/environment.git", "url": "https://github.com/sebastianbergmann/environment.git",
"reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf" "reference": "2292b116f43c272ff4328083096114f84ea46a56"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/2292b116f43c272ff4328083096114f84ea46a56",
"reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", "reference": "2292b116f43c272ff4328083096114f84ea46a56",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -910,7 +949,7 @@
"environment", "environment",
"hhvm" "hhvm"
], ],
"time": "2016-02-26 18:40:46" "time": "2016-05-04 07:59:13"
}, },
{ {
"name": "sebastian/exporter", "name": "sebastian/exporter",
@ -1119,7 +1158,7 @@
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v3.0.5", "version": "v3.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/yaml.git", "url": "https://github.com/symfony/yaml.git",

View File

@ -265,12 +265,13 @@ $smarty->assign('title', $title);
$smarty->assign('useRemoteUser', $useRemoteUser); $smarty->assign('useRemoteUser', $useRemoteUser);
$smarty->assign('errors', $errors); $smarty->assign('errors', $errors);
$smarty->assign('use_smtp', $config['use_smtp']); $smarty->assign('use_smtp', $config['use_smtp']);
$smarty->assign('default_to_marldown_editor', $config['markdown_editor_by_default']);
$smarty->assign('goToStep2', GO_TO_STEP_2); $smarty->assign('goToStep2', GO_TO_STEP_2);
$smarty->assign('poll_type', $poll_type); $smarty->assign('poll_type', $poll_type);
$smarty->assign('poll_title', Utils::fromPostOrDefault('title', $_SESSION['form']->title)); $smarty->assign('poll_title', Utils::fromPostOrDefault('title', $_SESSION['form']->title));
$smarty->assign('poll_id', Utils::fromPostOrDefault('id', $_SESSION['form']->id)); $smarty->assign('poll_id', Utils::fromPostOrDefault('id', $_SESSION['form']->id));
$smarty->assign('poll_description', Utils::fromPostOrDefault('description', $_SESSION['form']->description)); $smarty->assign('poll_description', !empty($_POST['description']) ? $_POST['description'] : $_SESSION['form']->description);
$smarty->assign('poll_name', Utils::fromPostOrDefault('name', $_SESSION['form']->admin_name)); $smarty->assign('poll_name', Utils::fromPostOrDefault('name', $_SESSION['form']->admin_name));
$smarty->assign('poll_mail', Utils::fromPostOrDefault('mail', $_SESSION['form']->admin_mail)); $smarty->assign('poll_mail', Utils::fromPostOrDefault('mail', $_SESSION['form']->admin_mail));
$smarty->assign('poll_editable', Utils::fromPostOrDefault('editable', $_SESSION['form']->editable)); $smarty->assign('poll_editable', Utils::fromPostOrDefault('editable', $_SESSION['form']->editable));

7
css/simplemde.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -136,10 +136,22 @@ header .lead {
.poll-description { .poll-description {
font-family: inherit; font-family: inherit;
white-space: pre-wrap;
word-break: initial; word-break: initial;
} }
/** Description in markdown **/
.form-group .CodeMirror, .form-group .CodeMirror-scroll {
min-height: 200px;
}
#description-form .CodeMirror {
background-color: #f5f5f5;
}
.editor-toolbar {
background-color: #eee;
}
h4.control-label { h4.control-label {
display: inline-block; display: inline-block;
max-width: 100%; max-width: 100%;

143
js/app/adminstuds.js Normal file
View File

@ -0,0 +1,143 @@
$(document).ready(function() {
wrapper = new MDEWrapper($('.js-desc textarea')[0], $('#rich-editor-button'), $('#simple-editor-button'));
var firstOpening = true;
$('#title-form .btn-edit').on('click', function() {
$('#title-form h3').hide();
$('.js-title').removeClass('hidden');
$('.js-title input').focus();
return false;
});
$('#title-form .btn-cancel').on('click', function() {
$('#title-form h3').show();
$('#title-form .js-title').addClass('hidden');
$('#title-form .btn-edit').focus();
return false;
});
$('#name-form .btn-edit').on('click', function() {
$('#name-form p').hide();
$('.js-name').removeClass('hidden');
$('.js-name input').focus();
return false;
});
$('#name-form .btn-cancel').on('click', function() {
$('#name-form p').show();
$('#name-form .js-name').addClass('hidden');
$('#name-form .btn-edit').focus();
return false;
});
$('#email-form .btn-edit').on('click', function() {
$('#email-form p').hide();
$('#email-form .js-email').removeClass('hidden');
$('.js-email input').focus();
return false;
});
$('#email-form .btn-cancel').on('click', function() {
$('#email-form p').show();
$('#email-form .js-email').addClass('hidden');
$('#email-form .btn-edit').focus();
return false;
});
$('#description-form .btn-edit').on('click', function() {
$('#description-form .well').hide();
$('#description-form .control-label .btn-edit').hide();
$('#description-form .js-desc').removeClass('hidden');
$('.js-desc textarea').focus();
if (firstOpening) {
firstOpening = false;
if ($('#rich-editor-button').hasClass('active')) {
wrapper.enable();
}
}
return false;
});
$('#description-form .btn-cancel').on('click', function() {
$('#description-form .well').show();
$('#description-form .control-label .btn-edit').show();
$('#description-form .js-desc').addClass('hidden');
$('.js-desc .btn-edit').focus();
return false;
});
$('#poll-rules-form .btn-edit').on('click', function() {
$('#poll-rules-form p').hide();
$('#poll-rules-form .js-poll-rules').removeClass('hidden');
$('.js-poll-rules select').focus();
return false;
});
$('#poll-rules-form .btn-cancel').on('click', function() {
$('#poll-rules-form p').show();
$('#poll-rules-form .js-poll-rules').addClass('hidden');
$('.js-poll-rules .btn-edit').focus();
return false;
});
$('#poll-hidden-form .btn-edit').on('click', function() {
$('#poll-hidden-form p').hide();
$('#poll-hidden-form .js-poll-hidden').removeClass('hidden');
$('.js-poll-hidden input[type=checkbox]').focus();
return false;
});
$('#poll-hidden-form .btn-cancel').on('click', function() {
$('#poll-hidden-form p').show();
$('#poll-hidden-form .js-poll-hidden').addClass('hidden');
$('.js-poll-hidden .btn-edit').focus();
return false;
});
$('#expiration-form .btn-edit').on('click', function() {
$('#expiration-form p').hide();
$('.js-expiration').removeClass('hidden');
$('.js-expiration input').focus();
return false;
});
$('#expiration-form .btn-cancel').on('click', function() {
$('#expiration-form p').show();
$('#expiration-form .js-expiration').addClass('hidden');
$('#expiration-form .btn-edit').focus();
return false;
});
$('#password-form .btn-edit').on('click', function() {
$('#password-form p').hide();
$('#password-form .js-password').removeClass('hidden');
$('#password').focus();
return false;
});
$('#password-form .btn-cancel').on('click', function() {
$('#password-form p').show();
$('#password-form .js-password').addClass('hidden');
$('.js-password .btn-edit').focus();
return false;
});
// Hiding other field when the admin wants to remove the password protection
var removePassword = $('#removePassword');
removePassword.on('click', function() {
var removeButton = removePassword.siblings('button');
if (removePassword.is(":checked")) {
$('#password_information').addClass('hidden');
removeButton.removeClass('hidden');
} else {
$('#password_information').removeClass('hidden');
removeButton.addClass('hidden');
}
removeButton.focus();
});
});

View File

@ -98,14 +98,19 @@
$('#md-a-imgModalLabel').text($(this).attr('title')); $('#md-a-imgModalLabel').text($(this).attr('title'));
}); });
md_a_imgModal.find('.btn-primary').on('click', function () { md_a_imgModal.find('.btn-primary').on('click', function () {
if (md_img.val() != '' && md_val.val() != '') { var text = md_text.val();
$('#' + $(this).val()).val('[![' + md_text.val() + '](' + md_img.val() + ')](' + md_val.val() + ')'); var img = md_img.val();
} else if (md_img.val() != '') { var link = md_val.val();
$('#' + $(this).val()).val('![' + md_text.val() + '](' + md_img.val() + ')'); var element = $('#' + $(this).val());
} else if (md_val.val() != '') {
$('#' + $(this).val()).val('[' + md_text.val() + '](' + md_val.val() + ')'); if (img != '' && link != '') {
element.val('[![' + text + '](' + img + ')](' + link + ')');
} else if (img != '') {
element.val('![' + text + '](' + img + ')');
} else if (link != '') {
element.val('[' + (text?text:link) + '](' + link + ')');
} else { } else {
$('#' + $(this).val()).val(md_text.val()); element.val(text);
} }
md_a_imgModal.modal('hide'); md_a_imgModal.modal('hide');
md_img.val(''); md_img.val('');

View File

@ -90,4 +90,9 @@ $(document).ready(function () {
document.getElementById("cookie-warning").setAttribute("style", ""); document.getElementById("cookie-warning").setAttribute("style", "");
} }
var wrapper = new MDEWrapper($('#poll_comments')[0], $('#rich-editor-button'), $('#simple-editor-button'));
if ($('#rich-editor-button').hasClass('active')) {
wrapper.enable();
}
}); });

View File

@ -2,137 +2,6 @@ $(document).ready(function() {
window.lang = $('html').attr('lang'); window.lang = $('html').attr('lang');
/**
* adminstuds.php
**/
$('#title-form .btn-edit').on('click', function() {
$('#title-form h3').hide();
$('.js-title').removeClass('hidden');
$('.js-title input').focus();
return false;
});
$('#title-form .btn-cancel').on('click', function() {
$('#title-form h3').show();
$('#title-form .js-title').addClass('hidden');
$('#title-form .btn-edit').focus();
return false;
});
$('#name-form .btn-edit').on('click', function() {
$('#name-form p').hide();
$('.js-name').removeClass('hidden');
$('.js-name input').focus();
return false;
});
$('#name-form .btn-cancel').on('click', function() {
$('#name-form p').show();
$('#name-form .js-name').addClass('hidden');
$('#name-form .btn-edit').focus();
return false;
});
$('#email-form .btn-edit').on('click', function() {
$('#email-form p').hide();
$('#email-form .js-email').removeClass('hidden');
$('.js-email input').focus();
return false;
});
$('#email-form .btn-cancel').on('click', function() {
$('#email-form p').show();
$('#email-form .js-email').addClass('hidden');
$('#email-form .btn-edit').focus();
return false;
});
$('#description-form .btn-edit').on('click', function() {
$('#description-form .well').hide();
$('#description-form .js-desc').removeClass('hidden');
$('.js-desc textarea').focus();
return false;
});
$('#description-form .btn-cancel').on('click', function() {
$('#description-form .well').show();
$('#description-form .js-desc').addClass('hidden');
$('.js-desc .btn-edit').focus();
return false;
});
$('#poll-rules-form .btn-edit').on('click', function() {
$('#poll-rules-form p').hide();
$('#poll-rules-form .js-poll-rules').removeClass('hidden');
$('.js-poll-rules select').focus();
return false;
});
$('#poll-rules-form .btn-cancel').on('click', function() {
$('#poll-rules-form p').show();
$('#poll-rules-form .js-poll-rules').addClass('hidden');
$('.js-poll-rules .btn-edit').focus();
return false;
});
$('#poll-hidden-form .btn-edit').on('click', function() {
$('#poll-hidden-form p').hide();
$('#poll-hidden-form .js-poll-hidden').removeClass('hidden');
$('.js-poll-hidden input[type=checkbox]').focus();
return false;
});
$('#poll-hidden-form .btn-cancel').on('click', function() {
$('#poll-hidden-form p').show();
$('#poll-hidden-form .js-poll-hidden').addClass('hidden');
$('.js-poll-hidden .btn-edit').focus();
return false;
});
$('#expiration-form .btn-edit').on('click', function() {
$('#expiration-form p').hide();
$('.js-expiration').removeClass('hidden');
$('.js-expiration input').focus();
return false;
});
$('#expiration-form .btn-cancel').on('click', function() {
$('#expiration-form p').show();
$('#expiration-form .js-expiration').addClass('hidden');
$('#expiration-form .btn-edit').focus();
return false;
});
$('#password-form .btn-edit').on('click', function() {
$('#password-form p').hide();
$('#password-form .js-password').removeClass('hidden');
$('#password').focus();
return false;
});
$('#password-form .btn-cancel').on('click', function() {
$('#password-form p').show();
$('#password-form .js-password').addClass('hidden');
$('.js-password .btn-edit').focus();
return false;
});
// Hiding other field when the admin wants to remove the password protection
var removePassword = $('#removePassword');
removePassword.on('click', function() {
var removeButton = removePassword.siblings('button');
if (removePassword.is(":checked")) {
$('#password_information').addClass('hidden');
removeButton.removeClass('hidden');
} else {
$('#password_information').removeClass('hidden');
removeButton.addClass('hidden');
}
removeButton.focus();
});
// Horizontal scroll buttons // Horizontal scroll buttons
if($('.results').width() > $('.container').width()) { if($('.results').width() > $('.container').width()) {
$('.scroll-buttons').removeClass('hidden'); $('.scroll-buttons').removeClass('hidden');

62
js/mde-wrapper.js Normal file
View File

@ -0,0 +1,62 @@
function myPreviewRender (text) {
text = text.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#'+i.charCodeAt(0)+';';
});
text = SimpleMDE.prototype.markdown(text);
text = text.replace(/ /g, '&nbsp;');
return text;
};
function MDEWrapper(textarea, enableButton, disableButton) {
this.element = textarea;
this.enableButton = enableButton;
this.disableButton = disableButton;
this.simplemde = null;
var wrapper = this;
if (this.enableButton) {
this.enableButton.on('click', function() {wrapper.enable()});
}
if (this.disableButton) {
this.disableButton.on('click', function() {wrapper.disable()});
}
}
MDEWrapper.prototype.enable = function() {
var wrapper = this;
if (this.simplemde == null) {
this.simplemde = new SimpleMDE({
element: wrapper.element,
forceSync: true,
status: true,
previewRender: myPreviewRender,
spellChecker: false,
promptURLs: true
});
if (this.enableButton) {
this.enableButton.addClass('active');
}
if (this.disableButton) {
this.disableButton.removeClass('active');
}
}
}
MDEWrapper.prototype.disable = function() {
if (this.simplemde != null) {
this.simplemde.toTextArea();
this.simplemde = null;
if (this.disableButton) {
this.disableButton.addClass('active');
}
if (this.enableButton) {
this.enableButton.removeClass('active');
}
}
}
MDEWrapper.prototype.isEnabled = function() {
return this.simplemde != null;
}

14
js/simplemde.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -38,6 +38,7 @@
"Search": "Suche", "Search": "Suche",
"Creation date:": "Erstellungsdatum:", "Creation date:": "Erstellungsdatum:",
"Caption": "Bildunterschrift", "Caption": "Bildunterschrift",
"Markdown": "Markdown",
"ASTERISK": "*" "ASTERISK": "*"
}, },
"Date": { "Date": {
@ -131,7 +132,9 @@
"Password protected": "DE_Protégé par mot de passe", "Password protected": "DE_Protégé par mot de passe",
"Votes protected by password": "DE_Votes protégés par mot de passe", "Votes protected by password": "DE_Votes protégés par mot de passe",
"No password": "DE_Pas de mot de passe", "No password": "DE_Pas de mot de passe",
"Remove password": "DE_Supprimer le mot de passe" "Remove password": "DE_Supprimer le mot de passe",
"Rich editor": "DE_Editeur avancé",
"Simple editor": "DE_Editeur simple"
}, },
"Poll results": { "Poll results": {
"Votes of the poll": "Stimmabgaben zur Umfrage", "Votes of the poll": "Stimmabgaben zur Umfrage",
@ -242,7 +245,10 @@
"The results are publicly visible": "DE_Les résultats sont visibles sans mot de passe", "The results are publicly visible": "DE_Les résultats sont visibles sans mot de passe",
"Poll password": "DE_Mot de passe", "Poll password": "DE_Mot de passe",
"Confirm password": "DE_Confirmer votre mot de passe", "Confirm password": "DE_Confirmer votre mot de passe",
"Go to step 2": "Weiter zum 2. Schritt" "Go to step 2": "Weiter zum 2. Schritt",
"To make the description more attractive, you can use the Markdown format.": "DE_Afin de rendre le descriptif de ce sondage plus attractif, vous pouvez utiliser le formatage Markdown.",
"You can enable or disable the editor at will.": "DE_Vous pouvez activer ou désactiver l'éditeur à votre guise.",
"More informations here:": "DE_Plus d'informations ici :"
}, },
"Step 2": { "Step 2": {
"Back to step 1": "Zurück zum 1. Schritt", "Back to step 1": "Zurück zum 1. Schritt",

View File

@ -38,6 +38,7 @@
"Search": "Search", "Search": "Search",
"Creation date:": "Creation date:", "Creation date:": "Creation date:",
"Caption": "Caption", "Caption": "Caption",
"Markdown": "Markdown",
"ASTERISK": "*" "ASTERISK": "*"
}, },
"Date" : { "Date" : {
@ -131,7 +132,9 @@
"Password protected": "Password protected", "Password protected": "Password protected",
"Votes protected by password": "Votes protected by password", "Votes protected by password": "Votes protected by password",
"No password": "No password", "No password": "No password",
"Remove password": "Remove password" "Remove password": "Remove password",
"Rich editor": "Rich editor",
"Simple editor": "Simple editor"
}, },
"Poll results": { "Poll results": {
"Votes of the poll": "Votes", "Votes of the poll": "Votes",
@ -242,7 +245,10 @@
"The results are publicly visible": "The results are publicly visible", "The results are publicly visible": "The results are publicly visible",
"Poll password": "Password", "Poll password": "Password",
"Confirm password": "Confirmer votre mot de passe", "Confirm password": "Confirmer votre mot de passe",
"Go to step 2": "Go to step 2" "Go to step 2": "Go to step 2",
"To make the description more attractive, you can use the Markdown format.": "To make the description more attractive, you can use the Markdown format.",
"You can enable or disable the editor at will.": "You can enable or disable the editor at will.",
"More informations here:": "More informations here:"
}, },
"Step 2": { "Step 2": {
"Back to step 1": "Return to step 1", "Back to step 1": "Return to step 1",

View File

@ -38,6 +38,7 @@
"Search": "Búsqueda", "Search": "Búsqueda",
"Creation date:": "Fecha de creación:", "Creation date:": "Fecha de creación:",
"Caption": "Leyenda", "Caption": "Leyenda",
"Markdown": "Markdown",
"ASTERISK": "*" "ASTERISK": "*"
}, },
"Date": { "Date": {
@ -131,7 +132,9 @@
"Password protected": "ES_Protégé par mot de passe", "Password protected": "ES_Protégé par mot de passe",
"Votes protected by password": "ES_Votes protégés par mot de passe", "Votes protected by password": "ES_Votes protégés par mot de passe",
"No password": "ES_Pas de mot de passe", "No password": "ES_Pas de mot de passe",
"Remove password": "ES_Supprimer le mot de passe" "Remove password": "ES_Supprimer le mot de passe",
"Rich editor": "ES_Editeur avancé",
"Simple editor": "ES_Editeur simple"
}, },
"Poll results": { "Poll results": {
"Votes of the poll": "Votos de la encuesta", "Votes of the poll": "Votos de la encuesta",
@ -242,7 +245,10 @@
"The results are publicly visible": "ES_Les résultats sont visibles sans mot de passe", "The results are publicly visible": "ES_Les résultats sont visibles sans mot de passe",
"Poll password": "ES_Mot de passe", "Poll password": "ES_Mot de passe",
"Confirm password": "ES_Confirmer votre mot de passe", "Confirm password": "ES_Confirmer votre mot de passe",
"Go to step 2": "Ir al paso número 2" "Go to step 2": "Ir al paso número 2",
"To make the description more attractive, you can use the Markdown format.": "ES_Afin de rendre le descriptif de ce sondage plus attractif, vous pouvez utiliser le formatage Markdown.",
"You can enable or disable the editor at will.": "ES_Vous pouvez activer ou désactiver l'éditeur à votre guise.",
"More informations here:": "ES_Plus d'informations ici :"
}, },
"Step 2": { "Step 2": {
"Back to step 1": "Volver al paso número 1", "Back to step 1": "Volver al paso número 1",

View File

@ -38,6 +38,7 @@
"Search": "Chercher", "Search": "Chercher",
"Creation date:": "Date de création :", "Creation date:": "Date de création :",
"Caption": "Légende", "Caption": "Légende",
"Markdown": "Markdown",
"ASTERISK": "*" "ASTERISK": "*"
}, },
"Date": { "Date": {
@ -131,7 +132,9 @@
"Password protected": "Protégé par mot de passe", "Password protected": "Protégé par mot de passe",
"Votes protected by password": "Votes protégés par mot de passe", "Votes protected by password": "Votes protégés par mot de passe",
"No password": "Pas de mot de passe", "No password": "Pas de mot de passe",
"Remove password": "Supprimer le mot de passe" "Remove password": "Supprimer le mot de passe",
"Rich editor": "Editeur avancé",
"Simple editor": "Editeur simple"
}, },
"Poll results": { "Poll results": {
"Votes of the poll": "Votes du sondage", "Votes of the poll": "Votes du sondage",
@ -242,7 +245,10 @@
"The results are publicly visible": "Les résultats sont visibles sans mot de passe", "The results are publicly visible": "Les résultats sont visibles sans mot de passe",
"Poll password": "Mot de passe", "Poll password": "Mot de passe",
"Confirm password": "Confirmer votre mot de passe ", "Confirm password": "Confirmer votre mot de passe ",
"Go to step 2": "Aller à l'étape 2" "Go to step 2": "Aller à l'étape 2",
"To make the description more attractive, you can use the Markdown format.": "Afin de rendre le descriptif de ce sondage plus attractif, vous pouvez utiliser le formatage Markdown.",
"You can enable or disable the editor at will.": "Vous pouvez activer ou désactiver l'éditeur à votre guise.",
"More informations here:": "Plus d'informations ici :"
}, },
"Step 2": { "Step 2": {
"Back to step 1": "Revenir à létape 1", "Back to step 1": "Revenir à létape 1",

View File

@ -38,6 +38,7 @@
"Search": "Cercare", "Search": "Cercare",
"Creation date:": "Data di creazione:", "Creation date:": "Data di creazione:",
"Caption": "Titolo", "Caption": "Titolo",
"Markdown": "Markdown",
"ASTERISK": "*" "ASTERISK": "*"
}, },
"Date": { "Date": {
@ -131,7 +132,9 @@
"Password protected": "Protetto da una password", "Password protected": "Protetto da una password",
"Votes protected by password": "Voti protetti da una password", "Votes protected by password": "Voti protetti da una password",
"No password": "Nessuna password", "No password": "Nessuna password",
"Remove password": "Eliminare la password" "Remove password": "Eliminare la password",
"Rich editor": "IT_Editeur avancé",
"Simple editor": "IT_Editeur simple"
}, },
"Poll results": { "Poll results": {
"Votes of the poll": "Voti del sondaggio ", "Votes of the poll": "Voti del sondaggio ",
@ -242,7 +245,10 @@
"The results are publicly visible": "I risultati sono visibili senza password", "The results are publicly visible": "I risultati sono visibili senza password",
"Poll password": "Password", "Poll password": "Password",
"Confirm password": "Conferma della password", "Confirm password": "Conferma della password",
"Go to step 2": "Andare al punto 2" "Go to step 2": "Andare al punto 2",
"To make the description more attractive, you can use the Markdown format.": "IT_Afin de rendre le descriptif de ce sondage plus attractif, vous pouvez utiliser le formatage Markdown.",
"You can enable or disable the editor at will.": "IT_Vous pouvez activer ou désactiver l'éditeur à votre guise.",
"More informations here:": "IT_Plus d'informations ici :"
}, },
"Step 2": { "Step 2": {
"Back to step 1": "Torna al punto 1", "Back to step 1": "Torna al punto 1",

View File

@ -38,6 +38,7 @@
"Search": "Cercar", "Search": "Cercar",
"Creation date:": "Data de creacion :", "Creation date:": "Data de creacion :",
"Caption": "OC_Légende", "Caption": "OC_Légende",
"Markdown": "Markdown",
"ASTERISK": "*" "ASTERISK": "*"
}, },
"Date": { "Date": {
@ -131,7 +132,9 @@
"Password protected": "OC_Protégé par mot de passe", "Password protected": "OC_Protégé par mot de passe",
"Votes protected by password": "OC_Votes protégés par mot de passe", "Votes protected by password": "OC_Votes protégés par mot de passe",
"No password": "OC_Pas de mot de passe", "No password": "OC_Pas de mot de passe",
"Remove password": "OC_Supprimer le mot de passe" "Remove password": "OC_Supprimer le mot de passe",
"Rich editor": "OC_Editeur avancé",
"Simple editor": "OC_Editeur simple"
}, },
"Poll results": { "Poll results": {
"Votes of the poll": "Vòtes del sondatge", "Votes of the poll": "Vòtes del sondatge",
@ -242,7 +245,10 @@
"The results are publicly visible": "OC_Les résultats sont visibles sans mot de passe", "The results are publicly visible": "OC_Les résultats sont visibles sans mot de passe",
"Poll password": "OC_Mot de passe", "Poll password": "OC_Mot de passe",
"Confirm password": "OC_Confirmer votre mot de passe ", "Confirm password": "OC_Confirmer votre mot de passe ",
"Go to step 2": "Anar a l'etapa 2" "Go to step 2": "Anar a l'etapa 2",
"To make the description more attractive, you can use the Markdown format.": "OC_Afin de rendre le descriptif de ce sondage plus attractif, vous pouvez utiliser le formatage Markdown.",
"You can enable or disable the editor at will.": "OC_Vous pouvez activer ou désactiver l'éditeur à votre guise.",
"More informations here:": "OC_Plus d'informations ici :"
}, },
"Step 2": { "Step 2": {
"Back to step 1": "Tornar a l'etapa 1", "Back to step 1": "Tornar a l'etapa 1",

View File

@ -93,4 +93,5 @@ $config = [
'default_poll_duration' => 180, // default values for the new poll duration (number of days). 'default_poll_duration' => 180, // default values for the new poll duration (number of days).
/* create_classic_poll.php */ /* create_classic_poll.php */
'user_can_add_img_or_link' => true, // user can add link or URL when creating his poll. 'user_can_add_img_or_link' => true, // user can add link or URL when creating his poll.
'markdown_editor_by_default' => true // The markdown editor for the description is enabled by default
]; ];

View File

@ -1,8 +1,12 @@
{extends file='page.tpl'} {extends file='page.tpl'}
{block name="header"} {block name="header"}
<script src="{"js/simplemde.min.js"|resource}" type="text/javascript"></script>
<script src="{"js/mde-wrapper.js"|resource}" type="text/javascript"></script>
<script src="{"js/app/create_poll.js"|resource}" type="text/javascript"></script> <script src="{"js/app/create_poll.js"|resource}" type="text/javascript"></script>
<link rel="stylesheet" href="{"css/app/create_poll.css"|resource}"> <link rel="stylesheet" href="{"css/app/create_poll.css"|resource}">
<link rel="stylesheet" href="{"css/simplemde.min.css"|resource}">
{/block} {/block}
{block name=main} {block name=main}
@ -61,9 +65,12 @@
<label for="poll_comments" class="col-sm-4 control-label">{__('Generic', 'Description')}</label> <label for="poll_comments" class="col-sm-4 control-label">{__('Generic', 'Description')}</label>
<div class="col-sm-8"> <div class="col-sm-8">
<textarea id="poll_comments" name="description" {include 'part/description_markdown.tpl'}
class="form-control" {$errors['description']['aria']} <div>
rows="5">{$poll_description|html}</textarea> <textarea id="poll_comments" name="description"
class="form-control" {$errors['description']['aria']}
rows="5">{$poll_description|escape}</textarea>
</div>
</div> </div>
</div> </div>
{if !empty($errors['description']['msg'])} {if !empty($errors['description']['msg'])}

View File

@ -0,0 +1,34 @@
{* Description buttons for markdown *}
<div class="btn-group" role="group" aria-label="...">
<button type="button" id="rich-editor-button" class="btn btn-default btn-xs{if $default_to_marldown_editor} active{/if}">{__('PollInfo', 'Rich editor')}</button>
<button type="button" id="simple-editor-button" class="btn btn-default btn-xs{if !$default_to_marldown_editor} active{/if}">{__('PollInfo', 'Simple editor')}</button>
</div>
<a href="" data-toggle="modal" data-target="#markdown_modal"><i class="glyphicon glyphicon-info-sign"></i></a><!-- TODO Add accessibility -->
<div id="markdown_modal" class="modal fade">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">{__('Generic', 'Markdown')}</h4>
</div>
<div class="modal-body">
<p>
{__('Step 1', 'To make the description more attractive, you can use the Markdown format.')}
</p>
<p>
{__('Step 1', 'You can enable or disable the editor at will.')}
</p>
<p>
{__('Step 1', 'More informations here:')}
<a href="http://{$locale}.wikipedia.org/wiki/Markdown">http://{$locale}.wikipedia.org/wiki/Markdown</a>
</p>
</div>
</div>
</div>
</div>

View File

@ -75,10 +75,11 @@
{if $admin || preg_match('/[^ \r\n]/', $poll->description)} {if $admin || preg_match('/[^ \r\n]/', $poll->description)}
<div class="form-group col-md-8" id="description-form"> <div class="form-group col-md-8" id="description-form">
<label class="control-label">{__('Generic', 'Description')}{if $admin && !$expired} <button class="btn btn-link btn-sm btn-edit" title="{__('PollInfo', 'Edit the description')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span></button>{/if}</label> <label class="control-label">{__('Generic', 'Description')}{if $admin && !$expired} <button class="btn btn-link btn-sm btn-edit" title="{__('PollInfo', 'Edit the description')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span></button>{/if}</label>
<pre class="form-control-static well poll-description">{$poll->description|html}</pre> <div class="form-control-static well poll-description">{$poll->description|markdown:false:false}</div>
{if $admin && !$expired} {if $admin && !$expired}
<div class="hidden js-desc text-right"> <div class="hidden js-desc">
<label class="sr-only" for="newdescription">{__('Generic', 'Description')}</label> <label class="sr-only" for="newdescription">{__('Generic', 'Description')}</label>
{include 'part/description_markdown.tpl'}
<textarea class="form-control" id="newdescription" name="description" rows="2" cols="40">{$poll->description|html}</textarea> <textarea class="form-control" id="newdescription" name="description" rows="2" cols="40">{$poll->description|html}</textarea>
<button type="submit" id="btn-new-desc" name="update_poll_info" value="description" class="btn btn-sm btn-success" title="{__('PollInfo', 'Save the description')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Save')}</span></button> <button type="submit" id="btn-new-desc" name="update_poll_info" value="description" class="btn btn-sm btn-success" title="{__('PollInfo', 'Save the description')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Save')}</span></button>
<button class="btn btn-default btn-sm btn-cancel" title="{__('PollInfo', 'Cancel the description edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{__('Generic', 'Cancel')}</span></button> <button class="btn btn-default btn-sm btn-cancel" title="{__('PollInfo', 'Cancel the description edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{__('Generic', 'Cancel')}</span></button>

View File

@ -7,6 +7,13 @@
<script src="{"js/app/studs.js"|resource}" type="text/javascript"></script> <script src="{"js/app/studs.js"|resource}" type="text/javascript"></script>
<link rel="stylesheet" href="{'css/jquery-ui.min.css'|resource}"> <link rel="stylesheet" href="{'css/jquery-ui.min.css'|resource}">
{if $admin}
<script src="{"js/simplemde.min.js"|resource}" type="text/javascript"></script>
<script src="{"js/mde-wrapper.js"|resource}" type="text/javascript"></script>
<script src="{"js/app/adminstuds.js"|resource}" type="text/javascript"></script>
<link rel="stylesheet" href="{'css/simplemde.min.css'|resource}">
{/if}
{/block} {/block}
{block name=main} {block name=main}