X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=js%2FCommon.js;h=ce8546c5708edf2e4cf03397d9332f54a00665ee;hb=0a1c80afc6e291e9b44581dfc0e40e1b1df09adc;hp=985e7d616ccb76c2b00e8e7ece334ce64aa42167;hpb=c7b6016eb318e6feb668af52cca2e582a8ed571c;p=civicrm-core.git diff --git a/js/Common.js b/js/Common.js index 985e7d616c..ce8546c570 100644 --- a/js/Common.js +++ b/js/Common.js @@ -238,9 +238,13 @@ if (!CRM.vars) CRM.vars = {}; }; var scriptsLoaded = {}; - CRM.loadScript = function(url) { + CRM.loadScript = function(url, appendCacheCode) { if (!scriptsLoaded[url]) { - var script = document.createElement('script'); + var script = document.createElement('script'), + src = url; + if (appendCacheCode !== false) { + src += (_.includes(url, '?') ? '&r=' : '?r=') + CRM.config.resourceCacheCode; + } scriptsLoaded[url] = $.Deferred(); script.onload = function () { // Give the script time to execute @@ -256,7 +260,7 @@ if (!CRM.vars) CRM.vars = {}; CRM.CMSjQuery = window.jQuery; window.jQuery = CRM.$; } - script.src = url; + script.src = src; document.getElementsByTagName("head")[0].appendChild(script); } return scriptsLoaded[url]; @@ -466,7 +470,7 @@ if (!CRM.vars) CRM.vars = {}; var entity = $(this).data('api-entity') || ''; $(this) .off('.crmEntity') - .removeClass('crm-form-entityref crm-' + entity.toLowerCase() + '-ref') + .removeClass('crm-form-entityref crm-' + _.kebabCase(entity) + '-ref') .crmSelect2('destroy'); }); } @@ -475,13 +479,17 @@ if (!CRM.vars) CRM.vars = {}; return $(this).each(function() { var $el = $(this).off('.crmEntity'), - entity = options.entity || $el.data('api-entity') || 'contact', + entity = options.entity || $el.data('api-entity') || 'Contact', selectParams = {}; + // Legacy: fix entity name if passed in as snake case + if (entity.charAt(0).toUpperCase() !== entity.charAt(0)) { + entity = _.capitalize(_.camelCase(entity)); + } $el.data('api-entity', entity); $el.data('select-params', $.extend({}, $el.data('select-params') || {}, options.select)); $el.data('api-params', $.extend(true, {}, $el.data('api-params') || {}, options.api)); $el.data('create-links', options.create || $el.data('create-links')); - $el.addClass('crm-form-entityref crm-' + entity.toLowerCase() + '-ref'); + $el.addClass('crm-form-entityref crm-' + _.kebabCase(entity) + '-ref'); var settings = { // Use select2 ajax helper instead of CRM.api3 because it provides more value ajax: { @@ -527,7 +535,7 @@ if (!CRM.vars) CRM.vars = {}; } }; // Create new items inline - works for tags - if ($el.data('create-links') && entity.toLowerCase() === 'tag') { + if ($el.data('create-links') && entity === 'Tag') { selectParams.createSearchChoice = function(term, data) { if (!_.findKey(data, {label: term})) { return {id: "0", term: term, label: term + ' (' + ts('new tag') + ')'}; @@ -578,11 +586,13 @@ if (!CRM.vars) CRM.vars = {}; formUrl = $(this).attr('href') + '&returnExtra=display_name,sort_name' + (extra ? (',' + extra) : ''); $el.select2('close'); CRM.loadForm(formUrl, { - dialog: {width: 500, height: 220} + dialog: {width: '50%', height: 220} }).on('crmFormSuccess', function(e, data) { if (data.status === 'success' && data.id) { - data.label = data.extra.sort_name; - CRM.status(ts('%1 Created', {1: data.extra.display_name})); + if (!data.crmMessages) { + CRM.status(ts('%1 Created', {1: data.label || data.extra.display_name})); + } + data.label = data.label || data.extra.sort_name; if ($el.select2('container').hasClass('select2-container-multi')) { var selection = $el.select2('data'); selection.push(data); @@ -683,33 +693,18 @@ if (!CRM.vars) CRM.vars = {}; var createLinks = $el.data('create-links'), params = getEntityRefApiParams($el).params, + entity = $el.data('api-entity'), markup = ''; return markup; @@ -717,19 +712,20 @@ if (!CRM.vars) CRM.vars = {}; function getEntityRefFilters($el) { var - entity = $el.data('api-entity').toLowerCase(), - filters = $.extend([], CRM.config.entityRef.filters[entity] || []), + entity = $el.data('api-entity'), + filters = CRM.config.entityRef.filters[entity] || [], params = $.extend({params: {}}, $el.data('api-params') || {}).params, result = []; - $.each(filters, function() { - var filter = $.extend({type: 'select', 'attributes': {}, entity: entity}, this); - if (typeof params[filter.key] === 'undefined') { + _.each(filters, function(filter) { + _.defaults(filter, {type: 'select', 'attributes': {}, entity: entity}); + if (!params[filter.key]) { + // Filter out options if params don't match its condition + if (filter.condition && !_.isMatch(params, _.pick(filter.condition, _.keys(params)))) { + return; + } result.push(filter); } else if (filter.key == 'contact_type' && typeof params.contact_sub_type === 'undefined') { - filter.options = _.remove(filter.options, function(option) { - return option.key.indexOf(params.contact_type + '__') === 0; - }); result.push(filter); } }); @@ -772,11 +768,7 @@ if (!CRM.vars) CRM.vars = {}; attrs += ' ' + attr + '="' + val + '"'; }); if (filterSpec.type === 'select') { - markup = ''; - if (filterSpec.options) { - markup += CRM.utils.renderOptions(filterSpec.options, filter.value); - } - markup += ''; + markup = ''; } else { markup = ''; } @@ -797,7 +789,7 @@ if (!CRM.vars) CRM.vars = {}; $('.crm-entityref-filter-value', '#select2-drop').remove(); $valField = $(entityRefFilterValueMarkup(filter, filterSpec)); $keyField.after($valField); - if (filterSpec.type === 'select' && !filterSpec.options) { + if (filterSpec.type === 'select') { loadEntityRefFilterOptions(filter, filterSpec, $valField, $el); } } else { @@ -806,24 +798,38 @@ if (!CRM.vars) CRM.vars = {}; } /** - * Fetch options for a filter via ajax api + * Fetch options for a filter from cache or ajax api */ function loadEntityRefFilterOptions(filter, filterSpec, $valField, $el) { - $valField.prop('disabled', true); // Fieldname may be prefixed with joins - strip those out - var fieldName = _.last(filter.key.split('.')); + var fieldName = _.last(filter.key.split('.')), + params = $.extend({params: {}}, $el.data('api-params') || {}).params; + if (filterSpec.options) { + setEntityRefFilterOptions($valField, fieldName, params, filterSpec); + return; + } + $('.crm-entityref-filters select', '#select2-drop').prop('disabled', true); CRM.api3(filterSpec.entity, 'getoptions', {field: fieldName, context: 'search', sequential: 1}) .done(function(result) { - var entity = $el.data('api-entity').toLowerCase(), - globalFilterSpec = _.find(CRM.config.entityRef.filters[entity], {key: filter.key}) || {}; + var entity = $el.data('api-entity').toLowerCase(); // Store options globally so we don't have to look them up again - globalFilterSpec.options = result.values; - $valField.prop('disabled', false); - CRM.utils.setOptions($valField, result.values); + filterSpec.options = result.values; + $('.crm-entityref-filters select', '#select2-drop').prop('disabled', false); + setEntityRefFilterOptions($valField, fieldName, params, filterSpec); $valField.val(filter.value || ''); }); } + function setEntityRefFilterOptions($valField, fieldName, params, filterSpec) { + var values = _.cloneDeep(filterSpec.options); + if (fieldName === 'contact_type' && params.contact_type) { + values = _.remove(values, function(option) { + return option.key.indexOf(params.contact_type + '__') === 0; + }); + } + CRM.utils.setOptions($valField, values); + } + //CRM-15598 - Override url validator method to allow relative url's (e.g. /index.htm) $.validator.addMethod("url", function(value, element) { if (/^\//.test(value)) { @@ -1498,7 +1504,7 @@ if (!CRM.vars) CRM.vars = {}; // Determine if a user has a given permission. // @see CRM_Core_Resources::addPermissions CRM.checkPerm = function(perm) { - return CRM.permissions[perm]; + return CRM.permissions && CRM.permissions[perm]; }; // Round while preserving sigfigs @@ -1545,4 +1551,11 @@ if (!CRM.vars) CRM.vars = {}; return (yiq >= 128) ? 'black' : 'white'; }; + // CVE-2015-9251 - Prevent auto-execution of scripts when no explicit dataType was provided + $.ajaxPrefilter(function(s) { + if (s.crossDomain) { + s.contents.script = false; + } + }); + })(jQuery, _);