Commit 0a8d7d90 authored by Taico Aerts's avatar Taico Aerts
Browse files

Merge branch 'development' into 'master'

ProjectForum Release v2.7.1 - 21-06-2022

See merge request !744
parents 9e5c3c54 0414dfa0
......@@ -17,8 +17,8 @@ gem 'puma', group: %i[development test]
# Stylesheets: SCSS
gem 'sass-rails'
# Javascript: Uglifier for compression + coffeescript support
gem 'uglifier', '>= 4.0.0'
# Javascript: terser for compression + coffeescript support
gem 'terser'
gem 'coffee-rails'
# JavaScript compiler for Rails 6, disabled for now
# gem 'webpacker'
......@@ -143,10 +143,6 @@ gem 'ransack', github: 'activerecord-hackery/ransack'
# For rendering inline SVG elements
gem 'inline_svg'
# WYSIWYG editor (gives HTML) and convert HTML to Markdown
gem 'ckeditor'
gem 'reverse_markdown'
# =================================================================================================
# Data Exports
# =================================================================================================
......@@ -169,7 +165,7 @@ gem 'graphmatch', '1.0.2', path: 'vendor/gems/graphmatch'
# A ruby wrapper of the GNU GLPK library intended for large-scale LP/MIP/other problems
# Used for the couple/experiment matching
gem 'rglpk', git: 'https://gitlab.ewi.tudelft.nl/eip/bepsys/rglpk'
gem 'rglpk', git: 'https://gitlab.ewi.tudelft.nl/eip/projectforum/rglpk'
# =================================================================================================
# Error reporting
......
......@@ -26,7 +26,7 @@ GIT
activerecord (>= 4.2)
GIT
remote: https://gitlab.ewi.tudelft.nl/eip/bepsys/rglpk
remote: https://gitlab.ewi.tudelft.nl/eip/projectforum/rglpk
revision: fb3118d018873992b2e0ef107cabc46f13717c34
specs:
rglpk (1.0.0)
......@@ -169,8 +169,6 @@ GEM
caxlsx (>= 3.0)
childprocess (3.0.0)
choice (0.2.0)
ckeditor (5.1.1)
orm_adapter (~> 0.5.0)
climate_control (0.2.0)
cocoon (1.2.15)
coderay (1.1.3)
......@@ -193,7 +191,7 @@ GEM
devise_saml_authenticatable (1.9.0)
devise (> 2.0.0)
ruby-saml (~> 1.7)
diffy (3.4.0)
diffy (3.4.1)
docile (1.4.0)
elasticsearch (7.17.1)
elasticsearch-api (= 7.17.1)
......@@ -223,8 +221,8 @@ GEM
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.3)
multipart-post (>= 1.2, < 3)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
......@@ -301,7 +299,7 @@ GEM
rake
mini_magick (4.11.0)
mini_mime (1.1.2)
minitest (5.15.0)
minitest (5.16.0)
minitest-reporters (1.5.0)
ansi
builder
......@@ -309,9 +307,9 @@ GEM
ruby-progressbar
mocha (1.14.0)
multi_json (1.15.0)
multipart-post (2.1.1)
multipart-post (2.2.3)
mysql2 (0.5.4)
net-ldap (0.17.0)
net-ldap (0.17.1)
net-scp (3.0.0)
net-ssh (>= 2.6.5, < 7.0.0)
net-ssh (6.1.0)
......@@ -356,12 +354,12 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-erd (1.7.0)
rails-erd (1.7.1)
activerecord (>= 4.2)
activesupport (>= 4.2)
choice (~> 0.2.0)
ruby-graphviz (~> 1.2)
rails-html-sanitizer (1.4.2)
rails-html-sanitizer (1.4.3)
loofah (~> 2.3)
rails-jquery-autocomplete (1.0.5)
rails (>= 3.2)
......@@ -383,14 +381,13 @@ GEM
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
reverse_markdown (2.1.1)
nokogiri
rexml (3.2.5)
rgl (0.5.7)
rgl (0.5.8)
lazy_priority_queue (~> 0.1.0)
rexml (~> 3.2, >= 3.2.4)
stream (~> 0.5.3)
rolify (6.0.0)
rubocop (1.30.0)
rubocop (1.30.1)
parallel (~> 1.10)
parser (>= 3.1.0.0)
rainbow (>= 2.2.2, < 4.0)
......@@ -401,7 +398,7 @@ GEM
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.18.0)
parser (>= 3.1.1.0)
rubocop-rails (2.14.2)
rubocop-rails (2.15.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.7.0, < 2.0)
......@@ -459,14 +456,16 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sqlite3 (1.4.2)
sqlite3 (1.4.4)
sshkit (1.21.2)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
stream (0.5.3)
stream (0.5.4)
generator
terrapin (0.6.0)
climate_control (>= 0.0.3, < 1.0)
terser (1.1.10)
execjs (>= 0.3.0, < 3)
thor (1.2.1)
tilt (2.0.10)
turbolinks (5.2.1)
......@@ -474,8 +473,6 @@ GEM
turbolinks-source (5.2.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (2.1.0)
warden (1.2.9)
rack (>= 2.0.9)
......@@ -492,7 +489,7 @@ GEM
zebra-datepicker-rails (1.9.7)
railties (>= 3.0)
sass-rails
zeitwerk (2.5.4)
zeitwerk (2.6.0)
zip-zip (0.3)
rubyzip (>= 1.0.0)
......@@ -517,7 +514,6 @@ DEPENDENCIES
capybara (~> 3.18)
caxlsx
caxlsx_rails
ckeditor
cocoon
coffee-rails
connection_pool
......@@ -555,7 +551,6 @@ DEPENDENCIES
rake
ransack!
redcarpet
reverse_markdown
rglpk!
rolify
rubocop (~> 1.0)
......@@ -572,9 +567,9 @@ DEPENDENCIES
spring
spring-watcher-listen (~> 2.0.0)
sqlite3
terser
turbolinks (>= 5.2.0)
tzinfo-data
uglifier (>= 4.0.0)
web-console (>= 3.3.0)
zebra-datepicker-rails
zip-zip
......
......@@ -19,10 +19,12 @@
//= require cocoon
//= require selectize
//= require normal/selectize_inputs
//= require toastui/toastui-editor-all
//= require toastui/toastui-editor-plugin-code-syntax-highlight-all
//= require normal/toastui_editor_init
//= require lightbox
//= require normal/lightboxes
//= require normal/checkbox
//= require normal/markdown
//= require normal/cocoon_limiter
//= require normal/popover
//= require normal/hideable_panels
......
......@@ -19,11 +19,13 @@
//= require zebra-datepicker/core
//= require normal/datepicker_inputs
//= require normal/checkbox
//= require normal/markdown
//= require normal/slick_carousels
//= require lightbox
//= require selectize
//= require normal/selectize_inputs
//= require toastui/toastui-editor-all
//= require toastui/toastui-editor-plugin-code-syntax-highlight-all
//= require normal/toastui_editor_init
//= require cocoon
//= require normal/cocoon_limiter
//= require normal/hideable_panels
......
CKEDITOR.editorConfig = function( config )
{
// Define changes to default configuration here. For example:
// config.language = 'fr';
// config.uiColor = '#AADC6E';
/* Filebrowser routes */
// The location of an external file browser, that should be launched when "Browse Server" button is pressed.
config.filebrowserBrowseUrl = "/ckeditor/attachment_files";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";
// The location of a script that handles file uploads in the Flash dialog.
config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
config.filebrowserImageBrowseUrl = "/ckeditor/pictures";
// The location of a script that handles file uploads in the Image dialog.
config.filebrowserImageUploadUrl = "/ckeditor/pictures?";
// The location of a script that handles file uploads.
config.filebrowserUploadUrl = "/ckeditor/attachment_files";
config.allowedContent = true;
// Toolbar groups configuration.
config.toolbar = [
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source'] },
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
// { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] },
// { name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] },
{ name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] },
{ name: 'insert', items: [ 'Flash', 'Table', 'HorizontalRule', 'SpecialChar' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
'/',
{ name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize' ] },
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }
];
config.toolbar_mini = [
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
{ name: 'styles', items: [ 'Font', 'FontSize' ] },
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] },
{ name: 'insert', items: [ 'Table', 'HorizontalRule', 'SpecialChar' ] }
];
};
$(document).on('turbolinks:load', function(){
var typingTimer;
var typingInterval = 500;
var $input = $('#markdown-input');
var $preview = $('#markdown-preview');
var $panel = $preview.parent().parent();
var $spinner = $panel.find('.spinner-container');
var loadingAnimation = {
start: function() {
if ($panel.hasClass('panel-default')) {
$panel.removeClass('panel-default');
$panel.addClass('panel-info');
$spinner.height($spinner.parent().height() + 2 * parseInt($spinner.parent().css('padding-bottom')));
$spinner.show();
}
},
stop: function() {
$panel.addClass('panel-default');
$panel.removeClass('panel-info');
$spinner.hide();
}
}
$input.on('keyup', function() {
clearTimeout(typingTimer);
typingTimer = setInterval(refreshPreview, typingInterval);
loadingAnimation.start();
});
$input.on('keydown', function() {
clearTimeout(typingTimer);
});
function refreshPreview() {
clearTimeout(typingTimer);
$.ajax({
url: $input.attr('data-url'),
data: {
markdown: $input.val()
},
type: 'post',
dataType: "script",
success: loadingAnimation.stop
});
}
});
$(document).on('turbolinks:load', function () {
toastui.projectforum_markdown_editors = {};
init_tui_editor($('.toastui-editor-init'));
});
$(document).on('turbolinks:load', function () {
init_tui_viewer($('.toastui-viewer-init'));
});
function init_tui_editor(editor_element_array) {
for (editor_element of editor_element_array) {
// insert editor
let output_field = $(editor_element);
editor_element.style = 'visibility:hidden;position:absolute;';
let tui_editor = $('<div></div>').insertAfter(output_field);
let height = output_field.data('height') || '500px';
const editor = createEditor();
// configure toolbar options
editor.removeToolbarItem('image');
// store editor instance
toastui.projectforum_markdown_editors[output_field.attr('id')] = editor;
// configure custom handling for required fields
let isRequired = output_field.attr('required');
if (isRequired) {
output_field.attr('required', false);
}
// insert markdown text into form before submission
configureSubmission();
// tear down editor when page is unloaded
configureTeardown();
/**
* Create a ToastUI editor.
*
* @returns the newly-created editor
*/
function createEditor() {
return new toastui.Editor({
el: tui_editor[0],
height: height,
initialValue: editor_element.value,
initialEditType: 'wysiwyg',
previewStyle: 'vertical',
usageStatistics: false,
plugins: [toastui.Editor.plugin.codeSyntaxHighlight],
hooks: {
// disable base64 images
addImageBlobHook: () => false
}
});
}
/**
* Set up the markdown text to be validated (if necessary) and
* inserted into the output field before form submission.
*/
function configureSubmission() {
output_field.closest('form').submit(function () {
let text = editor.getMarkdown();
// validate if required
if (isRequired && text.length === 0) {
alert('Please fill out all required fields');
return false;
}
output_field.text(text);
return true;
});
}
/**
* Set up editor destruction.
*/
function configureTeardown() {
let destroyed = false;
$(document).on('turbolinks:before-cache', function () {
// do not tear down if editor has already been destroyed
if (destroyed) return;
destroyed = true;
// store current text in output field so that changes are persisted when navigating back/forward
output_field.text(editor.getMarkdown());
// destroy editor
editor.destroy();
// remove editor div from DOM
tui_editor.remove();
});
}
}
}
function init_tui_viewer(viewer_element_array) {
for (viewer_element of viewer_element_array) {
// insert editor
let text_element = $(viewer_element);
viewer_element.style = 'display:none;';
let tui_editor = $('<div></div>').insertAfter(text_element);
const editor = createViewer();
// tear down editor when page is unloaded
configureTeardown();
/**
* Create a ToastUI viewer.
*
* @returns the newly-created viewer
*/
function createViewer() {
return new toastui.Editor.factory({
el: tui_editor[0],
viewer: true,
initialValue: text_element.text(),
usageStatistics: false,
plugins: [toastui.Editor.plugin.codeSyntaxHighlight]
});
}
/**
* Set up viewer destruction.
*/
function configureTeardown() {
let destroyed = false;
$(document).on('turbolinks:before-cache', function () {
// do not tear down if editor has already been destroyed
if (destroyed) return;
destroyed = true;
// destroy editor
editor.destroy();
// remove editor div from DOM
tui_editor.remove();
});
}
}
}
This diff is collapsed.
......@@ -24,9 +24,12 @@ body { padding-top: 0px; }
@import 'selectize';
@import 'selectize.bootstrap3';
@import 'toastui/toastui-editor';
@import 'toastui/prism';
@import 'toastui/toastui-editor-plugin-code-syntax-highlight';
@import 'normal/toastui_editor_tweaks';
@import 'normal/helpers';
@import 'normal/markdown';
@import 'admin/admin';
@import 'admin/steps';
@import 'admin/table';
......
......@@ -32,6 +32,10 @@
@import 'selectize';
@import 'selectize.bootstrap3';
@import 'toastui/toastui-editor';
@import 'toastui/prism';
@import 'toastui/toastui-editor-plugin-code-syntax-highlight';
@import 'normal/toastui_editor_tweaks';
@import 'normal/general';
@import 'normal/helpers';
......@@ -39,7 +43,6 @@
@import 'normal/index';
@import 'normal/group';
@import 'normal/login';
@import 'normal/markdown';
@import 'normal/spinner';
@import 'slick';
@import 'slick-theme';
......
#markdown-preview-panel .panel-body {
position: relative;
}
/**
* Tables
*/
.toastui-editor-contents th.toastui-editor-cell-selected {
background-color: #d8dfec;
}
.toastui-editor-contents table th {
color: #222;
background-color: #fff;
}
.toastui-editor-contents th p {
color: #222;
}
.toastui-editor-contents h1, .toastui-editor-contents h2 {
border-bottom: none;
padding-bottom: 0;
}
/**
* Blue headings
*/
.toastui-editor-contents h1,
.toastui-editor-contents h2,
.toastui-editor-contents h3,
.toastui-editor-contents h4,
.toastui-editor-contents h5,
.toastui-editor-contents h6 {
color: $brand-primary;
}
/**
* Blue separators
*/
.toastui-editor-contents hr {
border-top: 1px solid $brand-primary;
}
/**
* Black text inside blockquotes
*/
.toastui-editor-contents blockquote p,
.toastui-editor-contents blockquote ul,
.toastui-editor-contents blockquote ol {
color: #222;
}
/**
* Black list item dots/numbers
*/
.toastui-editor-contents ul > li::before {
background-color: #222;
}
.toastui-editor-contents ol > li::before {
color: #222;
}
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}