summaryrefslogtreecommitdiff
path: root/public/assets/js
diff options
context:
space:
mode:
Diffstat (limited to 'public/assets/js')
-rw-r--r--public/assets/js/admin/edit_lesson.js149
-rw-r--r--public/assets/js/admin/edit_page.js382
-rw-r--r--public/assets/js/admin/pages.js240
-rw-r--r--public/assets/js/lesson-features.js55
4 files changed, 752 insertions, 74 deletions
diff --git a/public/assets/js/admin/edit_lesson.js b/public/assets/js/admin/edit_lesson.js
index ee1b537..367c3b7 100644
--- a/public/assets/js/admin/edit_lesson.js
+++ b/public/assets/js/admin/edit_lesson.js
@@ -1,3 +1,9 @@
+/** NOTE:
+ * depricated code for tag-system is commented-out and kept in the source-code
+ * as case-study; the code is operational;
+ */
+
+
// Globals
// -----------------------------------------------------------------------------
@@ -23,9 +29,6 @@ var files = []; // array of { id:.., title:.., type:.., path:.. } records
// var tags = []; // array of integers
-const files_root = '/media/'; // files root firectory
-
-
// an alternative--id when a lesson_id not exists (needed for file-upload)
// ... consist of a 6-digit date string + random number up to 999
const yymmdd = new Date().toISOString().slice(2, 10).replaceAll('-','');
@@ -166,22 +169,27 @@ $(document).ready(function() {
});
- // // init tags (select2)
- // // ...
- // $('#tags').select2({
- // placeholder: 'Ετικέτες (tags/keywords)',
- // width: '100%',
- // tags: true
- // });
-
+ /** DEPRICATED: (tag system)
+ *
+ * // init tags (select2)
+ * // ...
+ * $('#tags').select2({
+ * placeholder: 'Ετικέτες (tags/keywords)',
+ * width: '100%',
+ * tags: true
+ * });
+ */
- // init editor (tiny MCE)
- // tinymce.init({
- // selector: 'form textarea[name=body]',
- // language: 'el',
- // menubar: true
- // });
- // --- -- -- - - -
+ /** DEPRICATED:
+ *
+ * // TINY-MCE EDITOR
+ * init editor (tiny MCE)
+ * tinymce.init({
+ * selector: 'form textarea[name=body]',
+ * language: 'el',
+ * menubar: true
+ * });
+ */
/** preload content
@@ -252,15 +260,18 @@ $(document).ready(function() {
});
categories.sort( compare_label ); // sort categories by breadcrumb
- // construct tags data
- // ---
- /// Object.keys(tags_response[0]).forEach( key => {
- /// tag = tags_response[0][key];
- /// tags.push({
- /// id: tag.id,
- /// label: tag.name
- /// });
- /// });
+ /** DEPRICATED: (tag system)
+ *
+ * // construct tags data
+ * // ---
+ * Object.keys(tags_response[0]).forEach( key => {
+ * tag = tags_response[0][key];
+ * tags.push({
+ * id: tag.id,
+ * label: tag.name
+ * });
+ * });
+ */
// construct provileges data
// ---
@@ -283,17 +294,21 @@ $(document).ready(function() {
// setup category_id options; select post's chosen category-id
set_parent_options( $('#course_id'), categories, lesson.course_id );
- // parse selected tags
- // ---
- /// var selected_tag_ids = [];
- /// if (post.tags_json != null) {
- /// var selected_tags = JSON.parse(post.tags_json);
- /// selected_tags.forEach( itag => { selected_tag_ids.push(itag.id); })
- /// }
+ /*** DEPRICATED: (tag system)
+ *
+ * // parse selected tags
+ * // ---
+ * var selected_tag_ids = [];
+ * if (post.tags_json != null) {
+ * var selected_tags = JSON.parse(post.tags_json);
+ * selected_tags.forEach( itag => { selected_tag_ids.push(itag.id); })
+ * }
+ */
+
// setup tags options; select post's chosen tags
set_parent_options( $('#privilege_id'), privileges, lesson.privilege_id );
- // ALSO: if tags selectd, show tags field
+ // DEPRICATED: ALSO: if tags selectd, show tags field
// if (selected_tag_ids.length != 0) { $('.optional label[for=tags]').addClass('show'); }
}
@@ -374,16 +389,20 @@ $(document).ready(function() {
$('.edit-post form').submit( event => {
event.preventDefault();
- // // rearrange tags to old and new ones
- // // ---
- // var old_tags = [];
- // var new_tags = [];
- // var tags = $('#tags').select2('data');
- // tags.forEach( t => {
- // if (!parseInt(t.id)) {
- // new_tags.push(t.text);
- // } else { old_tags.push(t.id); }
- // })
+ /** DEPRICATED:
+ *
+ ### TAG SYSTEM
+ # // rearrange tags to old and new ones
+ # // ---
+ # var old_tags = [];
+ # var new_tags = [];
+ # var tags = $('#tags').select2('data');
+ # tags.forEach( t => {
+ # if (!parseInt(t.id)) {
+ # new_tags.push(t.text);
+ # } else { old_tags.push(t.id); }
+ # })
+ */
var attachments = [];
// attachments (array) of "`media_id`;`reference`" strings
@@ -471,25 +490,27 @@ $(document).ready(function() {
-
- // show|hide file as referece button
- // --- -- -- - - -
- $('.admin-container').on('click', 'button.js-reference', function (e) {
- var id = $(this).data('id');
-
- // toggle reference attribute of item with `id` = id
- // ---
- var temp = [];
- files.forEach( it => {
- if (it.id == id) {
- it.reference = (it.reference==0) ? 1 : 0;
- }
- temp.push(it)
- });
-
- files = temp; // re-define files
- draw_files_list(); // then re-draw files list
- });
+ /** DEPRICATED:
+ *
+ # // show|hide file as referece button
+ # // --- -- -- - - -
+ # $('.admin-container').on('click', 'button.js-reference', function (e) {
+ # var id = $(this).data('id');
+ #
+ # // toggle reference attribute of item with `id` = id
+ # // ---
+ # var temp = [];
+ # files.forEach( it => {
+ # if (it.id == id) {
+ # it.reference = (it.reference==0) ? 1 : 0;
+ # }
+ # temp.push(it)
+ # });
+ #
+ # files = temp; // re-define files
+ # draw_files_list(); // then re-draw files list
+ # });
+ */
diff --git a/public/assets/js/admin/edit_page.js b/public/assets/js/admin/edit_page.js
new file mode 100644
index 0000000..ec0e84e
--- /dev/null
+++ b/public/assets/js/admin/edit_page.js
@@ -0,0 +1,382 @@
+// Globals
+// -----------------------------------------------------------------------------
+
+// NOTE:
+// Variable `entity_id` is defined before evaluating this script
+// id (int) : the id of edited post (or 0 if new post)
+
+var page;
+
+var id = (entity_id == 0) ? false : entity_id;
+
+var files = []; // array of { id:.., title:.., type:.., path:.. } records
+
+// TODO: support tags
+// var tags = []; // array of integers
+
+
+
+// an alternative--id when a page_id not exists (needed for file-upload)
+// ... consist of a 6-digit date string + random number up to 999
+const yymmdd = new Date().toISOString().slice(2, 10).replaceAll('-','');
+var rnd999 = Math.floor(Math.random() * 1000);
+var altID = (id == 0) ? ( yymmdd +'-'+ rnd999.toString() ) : id;
+
+
+
+
+// Supplamentary functions
+// -----------------------------------------------------------------------------
+
+// function for sorting an array by 'label' attribute
+// --- -- -- - - -
+function compare_label (a,b) {
+ if ( a.label < b.label ) { return -1; }
+ if ( a.label > b.label ) { return 1; }
+ return 0;
+}
+
+// return course record by course-id
+// --- -- -- - - -
+function course_record(id) {
+ var record = 0;
+ categories.forEach(el => { if (el.id == id) record = el; });
+
+ return record;
+}
+
+
+
+
+// Modal HTML Creators
+// -----------------------------------------------------------------------------
+
+const modal_header = (title) => {
+ return [
+ '<div class="modal-header">',
+ '<h4 class="modal-title" id="myModalLabel">',
+ title,
+ '</h4>',
+ '<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">',
+ '<span aria-hidden="true"></span>',
+ '</button>',
+ '</div>'
+ ].join('\n');
+}
+
+
+const upload_file_form = () => {
+ return [
+ '<form method="POST" id="file_upload_form" name="upload_file_form">',
+
+ '<div class="modal-body">',
+
+ '<input type="hidden" name="folder" value="'+ altID +'">',
+
+ '<div class="form-group">',
+ '<label for="title">Τίτλος/Περιγραφή για το Αρχείο</label>',
+ '<input type="text" class="form-control " value="" name="title" id="title" placeholder="Τίτλος για το Αρχείο" required="">',
+ '</div>',
+
+ '<div class="form-group">',
+ '<label class="control-label" for="file">Εισαγωγή Αρχείου</label>',
+ '<input class="form-control" type="file" id="file" name="file" required="">',
+ '</div>',
+
+ '</div>',
+
+ '<div class="modal-footer">',
+ '<div class="row" style="width: 50%;">',
+ '<div class="form-actions">',
+ '<div class="col col-4">',
+ '<buton type="button" class="btn btn-default js-modal-close col-12" data-bs-dismiss="modal">',
+ 'Κλείσιμο',
+ '</button>',
+ '</div>',
+ '<div class="col-8">',
+ '<button class="btn btn-success col-12" type="submit">Καταχώριση</button>',
+ '</div>',
+ '</div>',
+ '</div>',
+ '</div>',
+
+ '</form>'
+ ].join('\n');
+}
+
+
+const preview_article = (title, body) => {
+ return [
+ '<div class="modal-body">',
+ '<div class="post">',
+
+ '<h2>'+ title +'</h2>',
+
+ '<div class="article-body">',
+ marked.parse(body, { sanitize: true }),
+ '</div>',
+
+ '</div>',
+ '</div>',
+ '<div class="modal-footer">',
+ '<div class="row" style="width: 50%;">',
+ '<div class="form-actions">',
+ '<div class="col-md-4 col-md-offset-4 col-6 col-offset-3">',
+ '<buton type="button" class="btn btn-default js-modal-close col-12" data-bs-dismiss="modal">',
+ 'Κλείσιμο',
+ '</button>',
+ '</div>',
+ '</div>',
+ '</div>',
+ '</div>'
+ ].join('\n');
+}
+
+
+$(document).ready(function() {
+
+ // When document is ready
+ // -------------------------------------------------------------------------
+
+ /** preload content
+ * --- -- -- - - -
+ * get page
+ * update content (form-elements)
+ */
+ if (id) { // if an `id` is given, load post .. then init_form
+
+ $.getJSON( "/admin/api/page/" + id )
+ .done( function (data) {
+ page = data; // keep post
+
+ // update fields' values
+ $('input[name=id]').val(page.id); // id
+ $('input[name=title]').val(page.title); // title
+ $('textarea[name=body]').val(page.body); // body
+ $('select[name=status]').val(
+ (page.status == 0) ? '0' : "one"
+ ).trigger('change');
+
+ // $('#post-info').html('Δημιουργία: '+post.creation_date+'<br>Τελευταία Ενημέρωση: '+ post.update_date);
+
+ // parse media files; then draw
+ if (page.medias_json != null) {
+ files = JSON.parse(page.medias_json);
+ }
+ draw_files_list(); // then draw the files list
+
+ });
+
+ }
+
+
+ /** draw_files_list
+ * --- -- -- - - -
+ */
+ function draw_files_list() {
+ var li_list = [];
+ var ref_icon, ref_class;
+
+ files.forEach( item => {
+ var copy = [ // copy button
+ '<button type="button" class="btn btn-xs btn-default js-copy"',
+ ' data-url="' + item.path +'"',
+ ' data-type="' + item.type + '"',
+ '>',
+ '<i class="far fa-clone"></i>',
+ '</button>'
+ ].join('');
+
+ var del = [ // delete button
+ '<button type="button" class="btn btn-xs btn-danger js-delete"',
+ 'data-id="' + item.id + '">',
+ '<i class="fas fa-trash-alt"></i>',
+ '</button>'
+ ].join('');
+ var option = [ // li html
+ '<li>',
+ '<div class="text">' + item.label + '</div>',
+ '<div class="actions">',
+ copy, ' ', del,
+ '</div>',
+ '</li>'
+ ].join('');
+ li_list.push(option); // push to li_list
+ });
+ $('#files_list').html( li_list.join('\n') );
+
+ }
+
+
+
+ // When form's action-buttons are clicked
+ // -------------------------------------------------------------------------
+
+
+ // form submit
+ // --- -- -- - - -
+ $('.edit-page form').submit( event => {
+ event.preventDefault();
+
+ var attachments = [];
+ // attachments (array) of "`media_id`;`reference`" strings
+ files.forEach( f => { attachments.push( f.id ) });
+
+ // prepare data to POST
+ // ---
+ var data = {
+ id: parseInt($('.edit-page form input[name=id]').val()),
+ title: $('.edit-page form input[name=title]').val(),
+ body: $('.edit-page form textarea[name=body]').val(),
+ status: ( ($('select[name=status]').val() == "0") ? 0 : 1 ),
+ media: attachments
+ };
+
+ // select action url (add or update)
+ // ---
+ var request = '/admin/api/page/' + ((data.id == 0) ? 'add' : 'update');
+
+ // send POST (ajax) request
+ $.post(request, data)
+ .done(function( data ) {
+ console.log(data);
+ window.location.href = '/admin/pages'; // seems ok; bach to articles
+ });
+
+ });
+
+
+ // go-back (to pages)
+ // --- -- -- - - -
+ $('#go-back').click( event => {
+ if (confirm('Θέλετε να ακυρώσετε τις όποιες αλλαγές και να φύγτε από τη σελίδα;')) {
+ window.location.href = '/admin/pages';
+ }
+ });
+
+
+ // copy url button
+ // --- -- -- - - -
+ $('.admin-container').on('click', 'button.js-copy', function (e) {
+ var copytext = ''; // default: copy nothing
+
+ if ($(this).data('id') !== undefined) {
+ copytext = window.location.origin +'/page/' + $(this).data('id');
+ }
+
+ if ($(this).data('url') !== undefined) {
+ copytext = window.location.origin + '/serve/file/' + $(this).data('url') + '?type=' + $(this).data('type');
+ }
+
+ navigator.clipboard
+ .writeText(copytext)
+ .then(() => { // notify the copy event
+ $(this).addClass('copied');
+ setTimeout( () => { $(this).removeClass('copied'); }, 700);
+ console.log(copytext, ' copied!');
+ })
+ .catch(() => {
+ console.log("error on coping text");
+ });
+ });
+
+
+
+ // delete (remove) file button
+ // --- -- -- - - -
+ $('.admin-container').on('click', 'button.js-delete', function (e) {
+ console.log('delete!');
+ var media_id = $(this).data('id');
+
+ // remove from files array the one with id == media_id
+ // ---
+ var temp = [];
+ files.forEach( it => { if (it.id != media_id) temp.push(it); });
+
+ files = temp; // re-define files
+ draw_files_list(); // then re-draw files list
+ });
+
+
+
+ /** When modal show-up
+ * -------------------------------------------------------------------------
+ * ... prepare the manage-category form
+ * ... update select2 with possible parents
+ */
+ $('#editorModal').on('show.bs.modal', event => {
+ let button = $(event.relatedTarget); // Button that triggered the modal
+ let action = button.data('action'); // action
+ // var modal = $(this); // modal object
+
+ // update modal literature
+
+ switch (action) {
+ case 'upload_file':
+ $("#editorModal .modal-content").html(
+ modal_header('Εισαγωγή Αρχείου') + upload_file_form()
+ );
+ break;
+
+ case 'preview':
+ let preview = preview_article(
+ $('.edit-page form input[name=title]').val(),
+ $('.edit-page form textarea[name=body]').val()
+ );
+ $("#editorModal .modal-content").html( modal_header('Προεπισκόπηση') + preview);
+ break;
+
+ default:
+ // do nothing
+ }
+
+ });
+
+
+
+ /** submit upload file event
+ * -------------------------------------------------------------------------
+ */
+ $('#editorModal').on('submit', 'form[name=upload_file_form]', function (event) {
+ event.preventDefault();
+
+ // create the FormData object
+ // --- -- -- - - -
+ var fd = new FormData(document.getElementById('file_upload_form'));
+
+ // post the form (via ajax)
+ $.ajax({
+ url: '/admin/api/file_upload',
+ type: 'POST',
+ data: fd,
+ contentType: false,
+ processData: false,
+ dataType: 'json',
+ success: function(response) { // on success
+
+ if (response.success) {
+ files.push({ // ... update files array
+ id: response.id,
+ label: response.title,
+ path: response.path,
+ type: response.type
+ });
+ draw_files_list();
+
+ $('#editorModal').modal('hide');
+
+ } else {
+ console.log('File not uploaded');
+ }
+ }
+ });
+ });
+
+
+ // TODO:
+ // disable links while previewing the article
+ // OR add a target="_blank"
+
+
+});
+
diff --git a/public/assets/js/admin/pages.js b/public/assets/js/admin/pages.js
new file mode 100644
index 0000000..4aa02ca
--- /dev/null
+++ b/public/assets/js/admin/pages.js
@@ -0,0 +1,240 @@
+// Globals
+// -----------------------------------------------------------------------------
+var categories = [];
+var privileges = [ { id: 0, label: 'Δημόσιο' } ];
+var pages = [];
+var table;
+
+
+
+// Supplamentary functions
+// -----------------------------------------------------------------------------
+
+// array.indexOf polyfill
+// --- -- -- - - -
+if (!Array.prototype.indexOf)
+{
+ Array.prototype.indexOf = function(elt /*, from*/)
+ {
+ var len = this.length >>> 0;
+
+ var from = Number(arguments[1]) || 0;
+ from = (from < 0)
+ ? Math.ceil(from)
+ : Math.floor(from);
+ if (from < 0)
+ from += len;
+
+ for (; from < len; from++)
+ {
+ if (from in this &&
+ this[from] === elt)
+ return from;
+ }
+ return -1;
+ };
+}
+
+
+// function for sorting an array by 'label' attribute
+// --- -- -- - - -
+function compare_label (a,b) {
+ if ( a.label < b.label ) { return -1; }
+ if ( a.label > b.label ) { return 1; }
+ return 0;
+}
+
+
+// function for sorting an array by 'breadcrumb' attribute
+// --- -- -- - - -
+function compare_breadcrumb (a,b) {
+ if ( a.breadcrumb < b.breadcrumb ) { return -1; }
+ if ( a.breadcrumb > b.breadcrumb ) { return 1; }
+ return 0;
+}
+
+// return category record by category-id
+// --- -- -- - - -
+function page_record(id) {
+ var record = 0;
+ pages.forEach(el => { if (el.id == id) record = el; });
+
+ return record;
+}
+
+
+// create actions html (edit and delete buttons)
+// --- -- -- - - -
+function create_actions_html(el) {
+
+ var pub, del, edit;
+
+ // preapre [show|hide]-file as reference
+ if (el.status == 1) {
+ pub = '<span class="btn btn-sm"><i class="fas fa-eye"></i></span>';
+
+ } else {
+ pub = '<span class="btn btn-sm"><i class="fas fa-eye-slash"></i></span>';
+ }
+
+ del = "";
+
+ fast_edit = [
+ '<button type="button" class="btn btn-sm btn-light"',
+ 'data-bs-toggle="modal" data-bs-target="#managePages"',
+ 'data-id="'+ el.id +'">',
+ '<i class="fa-solid fa-bolt"></i>',
+ '</button>'
+ ].join('\n');
+
+ edit = [
+ '<a type="button" class="btn btn-sm btn-warning "',
+ 'href="/admin/edit_page/'+ el.id +'">',
+ '<i class="fas fa-pencil-alt"></i>',
+ '</a>'
+ ].join('\n');
+
+ return pub +' '+ fast_edit +' '+ edit +' '+ del;
+}
+
+
+
+$(document).ready(function() {
+
+ // When document is ready
+ // -------------------------------------------------------------------------
+
+
+ /** init_table
+ * --- -- -- - - -
+ * get categories
+ * constuct categories array
+ * render dataTable
+ */
+ function init_table() {
+
+ // get all categories from server (ajax)
+ $.getJSON( "/admin/api/pages")
+ .done(function( json ) {
+ // then ...
+
+ // reset categories
+ pages.length = 0;
+
+ // construct (new) categories data
+ Object.keys(json).forEach( key => {
+ el = json[key];
+ pages.push({
+ id: parseInt(el.id),
+ title: el.title,
+ actions: create_actions_html(el)
+ });
+ });
+
+ // sort by breadcrumb
+ // categories.sort( compare_breadcrumb );
+
+ // destroy previous datatable table instances
+ $('#dt-pages').dataTable().fnClearTable();
+ $('#dt-pages').dataTable().fnDestroy();
+
+ // (re-)create categories datatable
+ table = $('#dt-pages').DataTable({
+ language: { url: '/libs/DataTables/localization/Greek.json' },
+ data: pages,
+ ordering: false,
+ columns: [
+ { data: 'id' },
+ { data: 'title' },
+ { data: 'actions' }
+ ]
+ });
+
+ })
+ .fail(function( jqxhr, textStatus, error ) {
+ console.log( "Request Failed (" + error +")" );
+ });
+
+ }
+ init_table(); // init table on first run
+
+
+
+ /** When modal show-up
+ * -------------------------------------------------------------------------
+ * ... prepare the manage-category form
+ * ... update select2 with possible parents
+ */
+ $('#managePages').on('show.bs.modal', event => {
+ var button = $(event.relatedTarget); // Button that triggered the modal
+ var id = parseInt( button.data('id') ); // category_id from data-id
+ // var modal = $(this); // modal object
+
+ //// update modal literature
+ //// ---
+ //$('#manageCategory .modal-title').html( // modal title
+ // (id) ? 'Ενημέρωση Κατηγορίας' : 'Δημιουργία Κατηγορίας'
+ //);
+ //$('#manageCategory form input[name=id]').val( id ); // category id (hidden)
+ //$('#manageCategory form input[name=label]').val( // category label
+ // (id) ? category_record(id).label : ""
+ //);
+ //prepare_parents_element(id); // prepare <select> for parents
+ })
+
+
+ /** set_parent_options()
+ *
+ * -> create options for parents <select>
+ * -> choose selected parent
+ *
+ * NOTE:
+ * the targer <select> should be a select2 control
+ *
+ * @param parents (array): array of parents
+ * @param selected (int): selected parent
+ */
+ function set_parent_options(selector, list, selected_value = false) {
+
+ list.forEach( li => { // attach options into <select> control
+ selector.append(`<option value="${li.id}">${li.label}</option>`);
+ });
+
+ if (selected_value !== false) { // mark selected option(s)
+ selector.val(selected_value).trigger('change');
+ }
+ else { selector.val(null).trigger('change'); }
+ }
+
+
+
+
+
+ // When form is submited
+ // -------------------------------------------------------------------------
+
+ $('#manageCategory form').submit( event => {
+ event.preventDefault();
+
+ // prepare data to POST
+ var data = {
+ id: parseInt($('#manageCategory form input[name=id]').val()),
+ label: $('#manageCategory form input[name=label]').val(),
+ parent_id: parseInt($('#parent_id').select2('data')[0].id)
+ };
+
+ // select action url (add or update)
+ var request = '/admin/api/categories/' + ((data.id == 0) ? 'add' : 'update');
+
+ // send POST request
+ $.post(request, data)
+ .done(function( data ) {
+
+ $('#manageCategory').modal('hide'); // when done, close modal
+
+ init_table(); // reload table of categories
+ });
+
+ });
+
+});
diff --git a/public/assets/js/lesson-features.js b/public/assets/js/lesson-features.js
index 369c8f7..3634aa3 100644
--- a/public/assets/js/lesson-features.js
+++ b/public/assets/js/lesson-features.js
@@ -1,5 +1,8 @@
const valid_codeblocks = [ // supported sort-code keys
- 'youtube'
+ 'youtube',
+ 'spotify',
+ 'spotify-track',
+ 'world-data'
];
@@ -16,17 +19,21 @@ const symbol_escapes = [
var youtube_template = ( id => {
- return '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/'+ id +'?rel=0&controls=0" title="YouTube video player" frameborder="0" allow="clipboard-write; encrypted-media; picture-in-picture; web-share" allowfullscreen></iframe>'
+ return '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/'+ id +'?rel=0&controls=0" title="YouTube video player" frameborder="0" allow="clipboard-write; encrypted-media; picture-in-picture; web-share" allowfullscreen></iframe>';
});
-/*
-
-
-<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/6EA-MIYY1bg?controls=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
+var spotify_template = ( id => {
+ return '<iframe style="border-radius:12px" src="https://open.spotify.com/embed/episode/'+ id +'?utm_source=generator" width="100%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>';
+});
+var spotify_track = ( id => {
+ return '<iframe style="border-radius:12px" src="https://open.spotify.com/embed/track/'+ id +'?utm_source=generator" width="100%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>';
+});
-*/
+var owid_template = ( id => { // our world in data (explorer)
+ return '<iframe src="https://ourworldindata.org/explorers/'+ id +'?zoomToSelection=true&hideControls=true" loading="lazy" style="width: 100%; height: 480px; border: 0px none;"></iframe>'
+});
/** inject_codeblocks
@@ -51,6 +58,8 @@ function inject_codeblocks(code) {
// console.log(matches);
var output = code; // use a copy of (source) code
+
+ console.log(matches);
matches.forEach( match => {
// parse (every) match
@@ -59,15 +68,41 @@ function inject_codeblocks(code) {
// match[0] : `{{youtube=6EA-MIYY1bg}}`
// match[1] : `youtube=6EA-MIYY1bg`
// match[3] : the (source) code string
- let blockparts = unescaped_str( match[1] ).trim().split('=');
+
+ // let blockparts = unescaped_str( match[1] ).trim().split('=');
+ let blockparts = match[1].trim().split('=');
let target = blockparts[0].toLowerCase();
let id = blockparts[1];
// let label = escaped_str(blockparts[1]);
if (valid_codeblocks.includes(target)) {
- if (target == 'youtube') {
- var codeblock = youtube_template(id);
+ var codeblock = '';
+
+ console.log(target, id);
+
+ switch (target) {
+
+ case 'youtube':
+ codeblock = youtube_template(id);
+ break;
+
+ case 'spotify':
+ codeblock = spotify_template(id);
+ break;
+
+ case 'spotify-track':
+ codeblock = spotify_track(id);
+ break;
+
+ case 'world-data':
+ codeblock = owid_template(id);
+ break;
+
+ default:
+ codeblock = id;
+
}
+
output = output.replaceAll(match[0], codeblock);
}