/** * @package Joomla.Component.Builder * * @created 30th April, 2015 * @author Llewellyn van der Merwe * @github Joomla Component Builder * @copyright Copyright (C) 2015 - 2019 Vast Development Method. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ /* JS Document */ var noticeboard = "https://vdm.bz/componentbuilder-noticeboard-md"; var proboard = "https://vdm.bz/componentbuilder-pro-noticeboard-md"; jQuery(document).ready(function () { jQuery.get(noticeboard) .success(function(board) { if (board.length > 5) { jQuery("#noticeboard-md").html(marked(board)); getIS(1,board).done(function(result) { if (result){ jQuery("#vdm-new-notice").show(); getIS(2,board); } }); } else { jQuery("#noticeboard-md").html(all_is_good); } }) .error(function(jqXHR, textStatus, errorThrown) { jQuery("#noticeboard-md").html(all_is_good); }); jQuery.get(proboard) .success(function(board) { if (board.length > 5) { jQuery("#proboard-md").html(marked(board)); } else { jQuery("#proboard-md").html(all_is_good); } }) .error(function(jqXHR, textStatus, errorThrown) { jQuery("#proboard-md").html(all_is_good); }); }); // to check is READ/NEW function getIS(type,notice){ if (type == 1) { var getUrl = JRouter("index.php?option=com_componentbuilder&task=ajax.isNew&format=json&raw=true"); } else if (type == 2) { var getUrl = JRouter("index.php?option=com_componentbuilder&task=ajax.isRead&format=json&raw=true"); } if(token.length > 0 && notice.length){ var request = token+"=1¬ice="+notice; } return jQuery.ajax({ type: "POST", url: getUrl, dataType: 'json', data: request, jsonp: false }); } // start the moment the document is ready jQuery(document).ready(function () { // just get the available categories getCategories(plansPath); }); // add an ajax call tracker var ajaxcall = null; var fromLocal = false; jQuery(document).ready(function(){ jQuery('body').on('click','.getreaction',function(){ // Ajax request var btn = jQuery(this); btn.prop('disabled', true); setTimeout(function(){ btn.prop('disabled', false); }, 3000); var type = btn.data('type'); if ('getCategories' === type) { getCategories(plansPath); } else if ('getPlans' === type) { var name = btn.data('name'); getPlans(plansPath, name); } else if ('all' === type) { var status = btn.data('status'); bulkPlanGithub(status); } else if ('bulk' === type) { checkBulkPlanGithub(); } else if ('get' === type) { var path = btn.data('path'); var status = btn.data('status'); setPlanGithub(path, status); } else { var path = btn.data('path'); getPlanModal(path, type); } }); }); // load every thing once ready jQuery(document).ajaxStop(function () { if (0 === jQuery.active) { //do something special if ('plans' === ajaxcall) { setTimeout( function() { jQuery('#plans-github').html('

'+Joomla.JText._('COM_COMPONENTBUILDER_JCB_COMMUNITY_PLANS')+'

'); jQuery('#plans-display').show(); jQuery('#plans-grid').trigger('display.uk.check'); jQuery('#loading').hide(); }, 1000); } } }); // get the categories function getCategories(path) { var _paths = jQuery.jStorage.get('JCB-Plans-Paths', null); // always hide the plans display jQuery('#plans-display').hide(); // always reset the grid jQuery('#categories-grid').html(''); // set the ajax scope ajaxcall = 'categories'; if (_paths) { buildCategories(_paths); } else { jQuery.get(path) .success(function(paths) { // load only this category paths jQuery.jStorage.set('JCB-Plans-Paths', paths, {TTL: expire}); buildCategories(paths); }) .error(function(jqXHR, textStatus, errorThrown) { jQuery('#plans-github').html(returnError); }); } } // build the ibraries object function buildCategories(paths) { var _temp = jQuery.jStorage.get('JCB-Categories', null); if (_temp) { setCategories(_temp); } else { var temp = {}; jQuery.each(paths.tree, function(key,value) { if (value.path.match(".json$")) { var categoryName = value.path.split(/ -(.+)/)[0]; categoryName = categoryName.trim() temp[categoryName] = categoryName; } }); // load only this category paths jQuery.jStorage.set('JCB-Categories', temp, {TTL: expire}); setCategories(temp); } } // set the categories function setCategories(names) { // now load the category buttons jQuery.each(names, function(value) { setCategory(value); }); setTimeout( function() { jQuery('#plans-github').html('

'+Joomla.JText._('COM_COMPONENTBUILDER_AVAILABLE_CATEGORIES')+'

'); jQuery('#categories-display').show(); jQuery('#categories-grid').trigger('display.uk.check'); }, 1000); } // set the plans function setCategory(name) { // get useful ID var keyID = getKeyID(name); // build the category display var html = '
'; html += '
'; html += '

' + name + '

'; html += '
'; // set the data buttons html += setCategoryButtons(name); // close the box panel html += '
'; html += '
'; // now we have the category jQuery('#categories-grid').append(html); } function setCategoryButtons(name) { return ''; } // get the plans function getPlans(path, categoryName) { jQuery('#loading').show(); // get local values if set var _paths = jQuery.jStorage.get('JCB-Plans-Paths', null); // always reset the grid jQuery('#plans-grid').html(''); // always hide categories jQuery('#categories-display').hide(); // set the ajax scope ajaxcall = 'plans'; fromLocal = false; if (_paths) { setPlans(_paths, categoryName); jQuery('#plans-github').html('

'+Joomla.JText._('COM_COMPONENTBUILDER_JCB_COMMUNITY_PLANS')+'

'); } else { jQuery.get(path) .success(function(paths) { // load only this category paths jQuery.jStorage.set('JCB-Plans-Paths', paths, {TTL: expire}); setPlans(paths, categoryName); }) .error(function(jqXHR, textStatus, errorThrown) { jQuery('#plans-github').html(returnError); }); } // only use if loading localy if (fromLocal) { jQuery('#plans-display').show(); jQuery('#plans-grid').trigger('display.uk.check'); jQuery('#loading').hide(); } } // set the plans function setPlans(paths, categoryName) { // set the ajax scope ajaxcall = 'plans'; jQuery.each(paths.tree, function(key,value) { if (value.path.match(".json$") && value.path.match("^"+categoryName)) { var _plan = jQuery.jStorage.get(value.path, null); if (_plan) { setPlan(_plan, value.path); fromLocal = true; } else { jQuery.get(planPath+value.path) .success(function(plan) { // convert the string to json.object plan = jQuery.parseJSON(plan); jQuery.jStorage.set(value.path, plan, {TTL: expire}); setPlan(plan, value.path); }) .error(function(jqXHR, textStatus, errorThrown) { // we could do more }); } } }); } // set the plans function setPlan(plan, key) { // get useful ID var keyID = getKeyID(key); // get the status var status = getPlanStatus(plan, key); // add to bulk updater if ('equal' !== status) { bulkItems[status].push(key); } // build the plan display var html = '
'; html += '
'; html += '
'; html += '

' + plan.category+ ' - (' + plan.type + ') ' + plan.name + '

'; html += plan.heading + '
'; // set the data buttons html += setDataButtons(plan, key, status); // set the plan ref button html += setRefButtons(plan, key, status, keyID); // set the contributor buttons html += setContributorButtons(plan, key); // close the box panel html += '
'; html += '
'; // now we have the plan jQuery('#plans-grid').append(html); } // set the plan status function getPlanStatus(plan, key) { // check if JCB already has this plan if(local_plans.hasOwnProperty(key)){ // first get local time stamp var local_created = strtotime(local_plans[key].created); var local_modified = strtotime(local_plans[key].modified); // now get github time stamps var created = strtotime(plan.created); var modified = strtotime(plan.modified); // work out the status if (local_created == created) { if (local_modified == modified) { return 'equal'; } else if (local_modified > modified) { return 'ahead'; } else if (local_modified < modified) { return 'behind'; } } return 'diverged'; } return 'new'; } function setDataButtons(plan, key, status) { var html = '
'; html += ''; html += ''; html += ''; html += '
'; // return data buttons return html; } function setRefButtons(plan, key, status, keyID) { var html = '
' + plan.name + '
'; // set the update button html += '
'; if ('equal' !== status) { if ('new' === status) { var tooltip = Joomla.JText._('COM_COMPONENTBUILDER_GET_THE_PLAN_FROM_GITHUB_AND_INSTALL_IT_LOCALLY'); } else { var tooltip = Joomla.JText._('COM_COMPONENTBUILDER_GET_THE_PLAN_FROM_GITHUB_AND_UPDATE_THE_LOCAL_VERSION'); } html += ''; } else { html += ''; } html += '
'; // return data buttons return html; } function setContributorButtons(plan, key) { // set the contributor name if (plan.contributor_company) { var contributor_name = plan.contributor_company; } else if (plan.contributor_name) { var contributor_name = plan.contributor_name; } else { var contributor_name = Joomla.JText._('COM_COMPONENTBUILDER_JCB_COMMUNITY'); } // set the contributor url if (plan.contributor_website) { var contributor_url = plan.contributor_website; } else if (plan.contributor_email) { var contributor_url = 'mailto:'+plan.contributor_email; } else { var contributor_url = 'https://github.com/vdm-io/Joomla-Component-Builder-Plans'; } var html = ''; // return contributor buttons return html; } // do a bulk update function checkBulkPlanGithub() { // check if there is new items if (bulkItems.new.length === 0) { jQuery('#bulk-button-new').prop('disabled', true); jQuery('#bulk-button-new').attr('title', Joomla.JText._('COM_COMPONENTBUILDER_THERE_ARE_NO_NEW_PLANS_AT_THIS_TIME')); jQuery('#bulk-notice-new').show(); } // check if there is diverged items if (bulkItems.diverged.length === 0) { jQuery('#bulk-button-diverged').prop('disabled', true); jQuery('#bulk-button-diverged').attr('title', Joomla.JText._('COM_COMPONENTBUILDER_THERE_ARE_NO_DIVERGED_PLANS_AT_THIS_TIME')); jQuery('#bulk-notice-diverged').show(); } // check if there is ahead items if (bulkItems.ahead.length === 0) { jQuery('#bulk-button-ahead').prop('disabled', true); jQuery('#bulk-button-ahead').attr('title', Joomla.JText._('COM_COMPONENTBUILDER_THERE_ARE_NO_AHEAD_PLANS_AT_THIS_TIME')); jQuery('#bulk-notice-ahead').show(); } // check if there is behind items if (bulkItems.behind.length === 0) { jQuery('#bulk-button-behind').prop('disabled', true); jQuery('#bulk-button-behind').attr('title', Joomla.JText._('COM_COMPONENTBUILDER_THERE_ARE_NO_OUT_OF_DATE_PLANS_AT_THIS_TIME')); jQuery('#bulk-notice-behind').show(); } // check if all we should close the all button if (bulkItems.behind.length === 0 && bulkItems.new.length === 0 && bulkItems.ahead.length === 0 && bulkItems.diverged.length === 0) { jQuery('#bulk-button-all').prop('disabled', true); jQuery('#bulk-button-all').attr('title', Joomla.JText._('COM_COMPONENTBUILDER_THERE_ARE_NO_PLANS_TO_UPDATE_AT_THIS_TIME')); jQuery('#bulk-notice-all').show(); } } // do a bulk update function bulkPlanGithub(status) { // if all then trigger those with values if ('all' === status) { bulkPlanGithub('behind'); bulkPlanGithub('new'); bulkPlanGithub('ahead'); bulkPlanGithub('diverged'); } else if (bulkItems[status].length > 0) { jQuery.each(bulkItems[status], function(i, key){ setTimeout(function(){ doBulkUpdate_server(key, status).done(function(result) { if (result.message) { // only show errors if ('error' === result.status || 'warning' === result.status) { UIkit.notify(result.message, {status: result.status}); } // update local items if ('success' === result.status) { // get key ID var keyID = getKeyID(key); // update plan if we can updatePlanDisplay(keyID, 'equal'); } } else { UIkit.notify(Joomla.JText._('COM_COMPONENTBUILDER_PLAN_COULD_NOT_BE_UPDATEDSAVED'), {status:'danger'}); } }); }, 200); }); // reset array bulkItems[status].length = 0; // update the buttons (since we only do the bulk update once) checkBulkPlanGithub(); } } function doBulkUpdate_server(path, status) { // set the ajax scope ajaxcall = null; var getUrl = JRouter("index.php?option=com_componentbuilder&task=ajax.setPlanGithub&format=json&raw=true"); if (token.length > 0 && path.length > 0 && status.length > 0) { var request = token+'=1&path='+path+'&status='+status; } return jQuery.ajax({ type: 'POST', url: getUrl, dataType: 'json', data: request, jsonp: false }); } // set the plan from gitHub function setPlanGithub(key, status) { var message = getConfirmUpdate(status); UIkit.modal.confirm(message, function(){ // will be executed on confirm. setPlanGithub_server(key, status).done(function(result) { if (result.message) { UIkit.notify(result.message, {status: result.status}); if ('success' === result.status) { // get key ID var keyID = getKeyID(key); // update plan if we can updatePlanDisplay(keyID, 'equal'); } } else { UIkit.notify(Joomla.JText._('COM_COMPONENTBUILDER_PLAN_COULD_NOT_BE_UPDATEDSAVED'), {status:'danger'}); } }); }); } function setPlanGithub_server(path, status) { // set the ajax scope ajaxcall = null; var getUrl = JRouter("index.php?option=com_componentbuilder&task=ajax.setPlanGithub&format=json&raw=true"); if (token.length > 0 && path.length > 0 && status.length > 0) { var request = token+'=1&path='+path+'&status='+status; } return jQuery.ajax({ type: 'POST', url: getUrl, dataType: 'json', data: request, jsonp: false }); } // update the plan display function updatePlanDisplay(keyID, status) { // update badge jQuery('#'+keyID+'-badge').html(' ' +status); jQuery('#'+keyID+'-badge').attr('href' , '#'+status+'-meaning'); // update button if ('equal' === status) { // update notice jQuery('#'+keyID+'-getbutton').attr('title', Joomla.JText._('COM_COMPONENTBUILDER_NO_NEED_TO_GET_IT_SINCE_IT_IS_ALREADY_IN_SYNC_WITH_YOUR_LOCAL_VERSION')); jQuery('#'+keyID+'-getbutton').prop('disabled', true); jQuery('#'+keyID+'-getbutton').html(' ' + Joomla.JText._('COM_COMPONENTBUILDER_LOCAL_PLAN')); // counter delay just incase setTimeout(function(){ jQuery('#'+keyID+'-getbutton').prop('disabled', true); }, 2000); } // update the data filter jQuery('#'+keyID+'-panel').attr('data-uk-filter', status); // tell the grid to update jQuery('#plans-grid').trigger('display.uk.check'); } // set the modal function getPlanModal(key, type) { // set the ajax scope ajaxcall = 'plans'; var _plan = jQuery.jStorage.get(key, null); if (_plan) { // show modal showPlanModal(_plan, type); } else { jQuery.get('https://raw.githubusercontent.com/vdm-io/Joomla-Component-Builder-Plans/master/'+key) .success(function(plan) { // convert the string to json.object plan = jQuery.parseJSON(plan); jQuery.jStorage.set(key, plan, {TTL: expire}); // show modal showPlanModal(plan, type); }) .error(function(jqXHR, textStatus, errorThrown) { // we could do more }); } } // show the modal function showPlanModal(plan, type) { var html = '
'; html += ''; html += '

' + plan.category + ' - (' + plan.type + ') ' + plan.name + '

'; if ('contributor' === type) { html += '
'; html += '
'+Joomla.JText._('COM_COMPONENTBUILDER_COMPANY_NAME')+'
'; html += '
'+plan.contributor_company+'
'; html += '
'+Joomla.JText._('COM_COMPONENTBUILDER_AUTHOR_NAME')+'
'; html += '
'+plan.contributor_name+'
'; html += '
'+Joomla.JText._('COM_COMPONENTBUILDER_AUTHOR_EMAIL')+'
'; html += '
'+plan.contributor_email+'
'; html += '
'+Joomla.JText._('COM_COMPONENTBUILDER_AUTHOR_WEBSITE')+'
'; html += '
'+plan.contributor_website+'
'; html += '
'; } else { html += '
'; } html += '
C: ' + plan.created + ' | M: ' + plan.modified + ''; html += '
'; // get current page position var scroll = jQuery(window).scrollTop(); // add html to modal var modal = UIkit.modal.blockUI(html, {center:true, bgclose:true}).on({ 'hide.uk.modal': function(){ // scroll fix since the modal pops to the top of the page jQuery(window).scrollTop(scroll); } }); // show modal modal.show(); } // get key ID function getKeyID(key) { // get useful ID var keyID = key.replace('-', ''); keyID = keyID.replace('.json', ''); keyID = keyID.replace(/\s+/ig, '-'); keyID = keyID.replace(/\(/g, ''); keyID = keyID.replace(/\)/g, ''); // return the id build return keyID; } // get key ID function getKeyID(key) { // get useful ID var keyID = key.replace('-', ''); keyID = keyID.replace('.json', ''); keyID = keyID.replace(/\s+/ig, '-'); keyID = keyID.replace(/\(/g, ''); keyID = keyID.replace(/\)/g, ''); // return the id build return keyID; } jQuery.string_replace = function (search, replace, subject, countObj) { // discuss at: https://locutus.io/php/str_replace/ // original by: Kevin van Zonneveld (https://kvz.io) // improved by: Gabriel Paderni // improved by: Philip Peterson // improved by: Simon Willison (https://simonwillison.net) // improved by: Kevin van Zonneveld (https://kvz.io) // improved by: Onno Marsman (https://twitter.com/onnomarsman) // improved by: Brett Zamir (https://brett-zamir.me) // revised by: Jonas Raoni Soares Silva (https://www.jsfromhell.com) // bugfixed by: Anton Ongson // bugfixed by: Kevin van Zonneveld (https://kvz.io) // bugfixed by: Oleg Eremeev // bugfixed by: Glen Arason (https://CanadianDomainRegistry.ca) // bugfixed by: Glen Arason (https://CanadianDomainRegistry.ca) // input by: Onno Marsman (https://twitter.com/onnomarsman) // input by: Brett Zamir (https://brett-zamir.me) // input by: Oleg Eremeev // note 1: The countObj parameter (optional) if used must be passed in as a // note 1: object. The count will then be written by reference into it's `value` property // example 1: str_replace(' ', '.', 'Kevin van Zonneveld') // returns 1: 'Kevin.van.Zonneveld' // example 2: str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars') // returns 2: 'hemmo, mars' // example 3: str_replace(Array('S','F'),'x','ASDFASDF') // returns 3: 'AxDxAxDx' // example 4: var countObj = {} // example 4: str_replace(['A','D'], ['x','y'] , 'ASDFASDF' , countObj) // example 4: var $result = countObj.value // returns 4: 4 var i = 0 var j = 0 var temp = '' var repl = '' var sl = 0 var fl = 0 var f = [].concat(search) var r = [].concat(replace) var s = subject var ra = Object.prototype.toString.call(r) === '[object Array]' var sa = Object.prototype.toString.call(s) === '[object Array]' s = [].concat(s) var $global = (typeof window !== 'undefined' ? window : global) $global.$locutus = $global.$locutus || {} var $locutus = $global.$locutus $locutus.php = $locutus.php || {} if (typeof (search) === 'object' && typeof (replace) === 'string') { temp = replace replace = [] for (i = 0; i < search.length; i += 1) { replace[i] = temp } temp = '' r = [].concat(replace) ra = Object.prototype.toString.call(r) === '[object Array]' } if (typeof countObj !== 'undefined') { countObj.value = 0 } for (i = 0, sl = s.length; i < sl; i++) { if (s[i] === '') { continue } for (j = 0, fl = f.length; j < fl; j++) { temp = s[i] + '' repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0] s[i] = (temp).split(f[j]).join(repl) if (typeof countObj !== 'undefined') { countObj.value += ((temp.split(f[j])).length - 1) } } } return sa ? s : s[0] } /** * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ ;(function($){ "use strict"; $.subformRepeatableVDM = function(container, options){ this.$container = $(container); // check if already exist if(this.$container.data("subformRepeatableVDM")){ return self; } // Add a reverse reference to the DOM object this.$container.data("subformRepeatableVDM", self); // merge options this.options = $.extend({}, $.subformRepeatableVDM.defaults, options); // template for the repeating group this.template = ''; // prepare a row template, and find available field names this.prepareTemplate(); // check rows container this.$containerRows = this.options.rowsContainer ? this.$container.find(this.options.rowsContainer) : this.$container; // To avoid scope issues, var self = this; // bind add button this.$container.on('click', this.options.btAdd, function (e) { e.preventDefault(); var after = $(this).parents(self.options.repeatableElement); if(!after.length){ after = null; } self.addRow(after); }); // bind remove button this.$container.on('click', this.options.btRemove, function (e) { e.preventDefault(); var $row = $(this).parents(self.options.repeatableElement); self.removeRow($row); }); // bind move button if(this.options.btMove){ this.$containerRows.sortable({ items: this.options.repeatableElement, handle: this.options.btMove, tolerance: 'pointer' }); } // tell all that we a ready this.$container.trigger('subform-ready'); }; // prepare a template that we will use repeating $.subformRepeatableVDM.prototype.prepareTemplate = function(){ // create from template if (this.options.rowTemplateSelector) { // Find the template element and get its HTML content, this is our template. var $tmplElement = this.$container.find(this.options.rowTemplateSelector).last(); this.template = $.trim($tmplElement.html()) || ''; // This is IE fix for