diff --git a/Gemfile b/Gemfile index 0118219d..05e824ac 100644 --- a/Gemfile +++ b/Gemfile @@ -8,11 +8,6 @@ source 'https://rubygems.org' ruby ENV.fetch('OSEM_RUBY_VERSION', '3.1.4') -# rails-assets requires >= 1.8.4 -if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.8.4') - abort "Bundler version >= 1.8.4 is required" -end - # as web framework if next? gem 'rails', '~> 7.1' @@ -94,32 +89,6 @@ gem 'jquery-ui-rails', '~> 6.0.1' # for languages validation gem 'iso-639' -# frontend javascripts -source 'https://rails-assets.org' do - # for placeholder images - gem 'rails-assets-holderjs' - # for formating dates - gem 'rails-assets-date.format' - # for or parsing, validating, manipulating, and formatting dates - gem 'rails-assets-momentjs' - # for smooth scrolling - gem 'rails-assets-jquery-smooth-scroll' - # as color picker - gem 'rails-assets-spectrum' - # for color manipulation - gem 'rails-assets-tinycolor' - # for drawing triangle backgrounds - gem 'rails-assets-trianglify' - # for scroll way points - gem 'rails-assets-waypoints' - # for markdown editors - gem 'rails-assets-bootstrap-markdown' - # for select with icon - gem 'rails-assets-bootstrap-select' - gem 'rails-assets-markdown' - gem 'rails-assets-to-markdown', '~> 3' -end - # as date picker gem 'bootstrap3-datetimepicker-rails', '~> 4.17.47' diff --git a/Gemfile.lock b/Gemfile.lock index 76ca425a..64dc765e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,27 +1,3 @@ -GEM - remote: https://rails-assets.org/ - specs: - rails-assets-bootstrap (3.4.1) - rails-assets-jquery (>= 1.9.1, < 4) - rails-assets-bootstrap-markdown (2.10.0) - rails-assets-bootstrap (~> 3) - rails-assets-bootstrap-select (1.13.10) - rails-assets-bootstrap (>= 3.0.0) - rails-assets-jquery (>= 1.9.1, < 4) - rails-assets-date.format (1.2.3) - rails-assets-holderjs (2.9.6) - rails-assets-jquery (3.4.1) - rails-assets-jquery-smooth-scroll (2.2.0) - rails-assets-jquery (>= 1.7.0) - rails-assets-markdown (0.5.0) - rails-assets-momentjs (2.29.4) - rails-assets-spectrum (1.8.0) - rails-assets-jquery (>= 1.7.2) - rails-assets-tinycolor (1.6.0) - rails-assets-to-markdown (3.1.1) - rails-assets-trianglify (1.2.0) - rails-assets-waypoints (4.0.1) - GEM remote: https://rubygems.org/ specs: @@ -697,18 +673,6 @@ DEPENDENCIES prawn-rails puma rails (~> 7.0) - rails-assets-bootstrap-markdown! - rails-assets-bootstrap-select! - rails-assets-date.format! - rails-assets-holderjs! - rails-assets-jquery-smooth-scroll! - rails-assets-markdown! - rails-assets-momentjs! - rails-assets-spectrum! - rails-assets-tinycolor! - rails-assets-to-markdown (~> 3)! - rails-assets-trianglify! - rails-assets-waypoints! rails-controller-testing rails-i18n recaptcha diff --git a/vendor/assets/images/holderjs/test/image.jpg b/vendor/assets/images/holderjs/test/image.jpg new file mode 100644 index 00000000..4d7fa14c Binary files /dev/null and b/vendor/assets/images/holderjs/test/image.jpg differ diff --git a/vendor/assets/javascripts/bootstrap-markdown.js b/vendor/assets/javascripts/bootstrap-markdown.js new file mode 100644 index 00000000..eb380aee --- /dev/null +++ b/vendor/assets/javascripts/bootstrap-markdown.js @@ -0,0 +1 @@ +//= require bootstrap-markdown/bootstrap-markdown.js diff --git a/vendor/assets/javascripts/bootstrap-markdown/bootstrap-markdown.js b/vendor/assets/javascripts/bootstrap-markdown/bootstrap-markdown.js new file mode 100644 index 00000000..21e8c60e --- /dev/null +++ b/vendor/assets/javascripts/bootstrap-markdown/bootstrap-markdown.js @@ -0,0 +1,1390 @@ +/* =================================================== + * bootstrap-markdown.js v2.10.0 + * http://github.com/toopay/bootstrap-markdown + * =================================================== + * Copyright 2013-2016 Taufan Aditya + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +(function(factory){ + if (typeof define === "function" && define.amd) { + //RequireJS + define(["jquery"], factory); + } else if (typeof exports === 'object') { + //Backbone.js + factory(require('jquery')); + } else { + //Jquery plugin + factory(jQuery); + } +}(function($){ + "use strict"; // jshint ;_; + + /* MARKDOWN CLASS DEFINITION + * ========================== */ + + var Markdown = function (element, options) { + // @TODO : remove this BC on next major release + // @see : https://github.com/toopay/bootstrap-markdown/issues/109 + var opts = ['autofocus', 'savable', 'hideable', 'width', + 'height', 'resize', 'iconlibrary', 'language', + 'footer', 'fullscreen', 'hiddenButtons', 'disabledButtons']; + $.each(opts,function(_, opt){ + if (typeof $(element).data(opt) !== 'undefined') { + options = typeof options == 'object' ? options : {} + options[opt] = $(element).data(opt) + } + }); + // End BC + + // Class Properties + this.$ns = 'bootstrap-markdown'; + this.$element = $(element); + this.$editable = {el:null, type:null,attrKeys:[], attrValues:[], content:null}; + this.$options = $.extend(true, {}, $.fn.markdown.defaults, options, this.$element.data('options')); + this.$oldContent = null; + this.$isPreview = false; + this.$isFullscreen = false; + this.$editor = null; + this.$textarea = null; + this.$handler = []; + this.$callback = []; + this.$nextTab = []; + + this.showEditor(); + }; + + Markdown.prototype = { + + constructor: Markdown + + , __alterButtons: function(name,alter) { + var handler = this.$handler, isAll = (name == 'all'),that = this; + + $.each(handler,function(k,v) { + var halt = true; + if (isAll) { + halt = false; + } else { + halt = v.indexOf(name) < 0; + } + + if (halt === false) { + alter(that.$editor.find('button[data-handler="'+v+'"]')); + } + }); + } + + , __buildButtons: function(buttonsArray, container) { + var i, + ns = this.$ns, + handler = this.$handler, + callback = this.$callback; + + for (i=0;i', { + 'class': 'btn-group' + }); + + for (z=0;z'); + buttonContainer.text(' ' + this.__localize(btnText)).addClass('btn-default btn-sm').addClass(btnClass); + if(btnClass.match(/btn\-(primary|success|info|warning|danger|link)/)){ + buttonContainer.removeClass('btn-default'); + } + buttonContainer.attr({ + 'type': 'button', + 'title': this.__localize(button.title) + hotkeyCaption, + 'tabindex': tabIndex, + 'data-provider': ns, + 'data-handler': buttonHandler, + 'data-hotkey': hotkey + }); + if (button.toggle === true){ + buttonContainer.attr('data-toggle', 'button'); + } + buttonIconContainer = $(''); + buttonIconContainer.addClass(buttonIcon); + buttonIconContainer.prependTo(buttonContainer); + + // Attach the button object + btnGroupContainer.append(buttonContainer); + + // Register handler and callback + handler.push(buttonHandler); + callback.push(button.callback); + } + + // Attach the button group into container dom + container.append(btnGroupContainer); + } + } + + return container; + } + , __setListener: function() { + // Set size and resizable Properties + var hasRows = typeof this.$textarea.attr('rows') !== 'undefined', + maxRows = this.$textarea.val().split("\n").length > 5 ? this.$textarea.val().split("\n").length : '5', + rowsVal = hasRows ? this.$textarea.attr('rows') : maxRows; + + this.$textarea.attr('rows',rowsVal); + if (this.$options.resize) { + this.$textarea.css('resize',this.$options.resize); + } + + this.$textarea.on({ + 'focus' : $.proxy(this.focus, this), + 'keyup' : $.proxy(this.keyup, this), + 'change' : $.proxy(this.change, this), + 'select' : $.proxy(this.select, this) + }); + + if (this.eventSupported('keydown')) { + this.$textarea.on('keydown', $.proxy(this.keydown, this)); + } + + if (this.eventSupported('keypress')) { + this.$textarea.on('keypress', $.proxy(this.keypress, this)) + } + + // Re-attach markdown data + this.$textarea.data('markdown',this); + } + + , __handle: function(e) { + var target = $(e.currentTarget), + handler = this.$handler, + callback = this.$callback, + handlerName = target.attr('data-handler'), + callbackIndex = handler.indexOf(handlerName), + callbackHandler = callback[callbackIndex]; + + // Trigger the focusin + $(e.currentTarget).focus(); + + callbackHandler(this); + + // Trigger onChange for each button handle + this.change(this); + + // Unless it was the save handler, + // focusin the textarea + if (handlerName.indexOf('cmdSave') < 0) { + this.$textarea.focus(); + } + + e.preventDefault(); + } + + , __localize: function(string) { + var messages = $.fn.markdown.messages, + language = this.$options.language; + if ( + typeof messages !== 'undefined' && + typeof messages[language] !== 'undefined' && + typeof messages[language][string] !== 'undefined' + ) { + return messages[language][string]; + } + return string; + } + + , __getIcon: function(src) { + return typeof src == 'object' ? src[this.$options.iconlibrary] : src; + } + + , setFullscreen: function(mode) { + var $editor = this.$editor, + $textarea = this.$textarea; + + if (mode === true) { + $editor.addClass('md-fullscreen-mode'); + $('body').addClass('md-nooverflow'); + this.$options.onFullscreen(this); + } else { + $editor.removeClass('md-fullscreen-mode'); + $('body').removeClass('md-nooverflow'); + + if (this.$isPreview == true) this.hidePreview().showPreview() + } + + this.$isFullscreen = mode; + $textarea.focus(); + } + + , showEditor: function() { + var instance = this, + textarea, + ns = this.$ns, + container = this.$element, + originalHeigth = container.css('height'), + originalWidth = container.css('width'), + editable = this.$editable, + handler = this.$handler, + callback = this.$callback, + options = this.$options, + editor = $( '
', { + 'class': 'md-editor', + click: function() { + instance.focus(); + } + }); + + // Prepare the editor + if (this.$editor === null) { + // Create the panel + var editorHeader = $('
', { + 'class': 'md-header btn-toolbar' + }); + + // Merge the main & additional button groups together + var allBtnGroups = []; + if (options.buttons.length > 0) allBtnGroups = allBtnGroups.concat(options.buttons[0]); + if (options.additionalButtons.length > 0) { + // iterate the additional button groups + $.each(options.additionalButtons[0], function(idx, buttonGroup){ + + // see if the group name of the addional group matches an existing group + var matchingGroups = $.grep(allBtnGroups, function(allButtonGroup, allIdx){ + return allButtonGroup.name === buttonGroup.name; + }); + + // if it matches add the addional buttons to that group, if not just add it to the all buttons group + if(matchingGroups.length > 0) { + matchingGroups[0].data = matchingGroups[0].data.concat(buttonGroup.data); + } else { + allBtnGroups.push(options.additionalButtons[0][idx]); + } + + }); + } + + // Reduce and/or reorder the button groups + if (options.reorderButtonGroups.length > 0) { + allBtnGroups = allBtnGroups + .filter(function(btnGroup) { + return options.reorderButtonGroups.indexOf(btnGroup.name) > -1; + }) + .sort(function(a, b) { + if (options.reorderButtonGroups.indexOf(a.name) < options.reorderButtonGroups.indexOf(b.name)) return -1; + if (options.reorderButtonGroups.indexOf(a.name) > options.reorderButtonGroups.indexOf(b.name)) return 1; + return 0; + }); + } + + // Build the buttons + if (allBtnGroups.length > 0) { + editorHeader = this.__buildButtons([allBtnGroups], editorHeader); + } + + if (options.fullscreen.enable) { + editorHeader.append('
').on('click', '.md-control-fullscreen', function(e) { + e.preventDefault(); + instance.setFullscreen(true); + }); + } + + editor.append(editorHeader); + + // Wrap the textarea + if (container.is('textarea')) { + container.before(editor); + textarea = container; + textarea.addClass('md-input'); + editor.append(textarea); + } else { + var rawContent = (typeof toMarkdown == 'function') ? toMarkdown(container.html()) : container.html(), + currentContent = $.trim(rawContent); + + // This is some arbitrary content that could be edited + textarea = $('