Skip to content

Commit 8e3ba86

Browse files
committed
v2.92.0
+ minor enhancements to spa.bindTemplateData + dataUrlParams with :paramX. It can be a function, which will be resolved before dataUrl request + minor enhancments/fix in routing system
1 parent c090661 commit 8e3ba86

File tree

6 files changed

+95
-30
lines changed

6 files changed

+95
-30
lines changed

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "Single Page Application (SPA) Simplified Framework/Library",
44
"main": "dist/spa-bundle.js",
55

6-
"version": "2.91.0",
6+
"version": "2.92.0",
77
"license": "MIT",
88
"homepage": "https://github.com/sucom/SPA.js",
99

dist/spa-bundle.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/spa-bundle.slim.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "spa.js",
3-
"version": "2.91.0",
3+
"version": "2.92.0",
44
"description": "Single Page Application (SPA) Simplified Framework/Library",
55
"main": "dist/spa-bundle.js",
66
"repository": {

src/spa.js

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
*/
3333

3434
(function() {
35-
var _VERSION = '2.91.0';
35+
var _VERSION = '2.92.0';
3636

3737
/* Establish the win object, 'window' in the browser */
3838
var win = window||globalThis, _doc = document, isSPAReady, docBody = _doc.body;
@@ -382,6 +382,13 @@
382382
return ((''+this).charAt(0).toLowerCase()) + ((''+this).slice(1));
383383
};
384384

385+
_strProto.test = function (rx, rxOpt) {
386+
if (_isStr(rx)) {
387+
rx = rxOpt? new RegExp(rx, rxOpt) : new RegExp(rx);
388+
}
389+
return rx.test(''+this);
390+
};
391+
385392
function _sanitizeHTML(str) {
386393
var sBoxEl = document.createElement('div');
387394
sBoxEl.textContent = str;
@@ -4482,32 +4489,61 @@
44824489
return onVirtualDOM? ($contextRoot.html().replace((new RegExp(blockedScriptTagName, 'g')), "script").replace(/spa-vdom-textarea/g,'textarea') ) : $contextRoot;
44834490
};
44844491

4485-
xsr.bindTemplateData = function (xTemplate, data) {
4486-
var xContent = xTemplate;
4492+
xsr.bindTemplateData = xsr.bindTemplate = xsr.renderTemplate = function (xTemplate, data) {
4493+
var xContent = xTemplate, tmplType = '', elTarget, renderTarget = arguments[arguments.length-1];
44874494
if ((/^\s*#[a-z]+/i).test(xTemplate)) {
4488-
xContent = $(xTemplate).html();
4495+
elTarget = $(xTemplate)[0];
4496+
xContent = elTarget.innerHTML.replace(/^\s*/,'');
44894497
}
44904498

4491-
if (_isBlank(data)) {
4499+
if ((arguments.length==1) || (arguments.length==2 && _isObj(data))) {
4500+
tmplType = elTarget.getAttribute('type');
4501+
renderTarget = elTarget.getAttribute('target');
4502+
}
4503+
4504+
if (_isStr(data) && arguments.length==3) {
4505+
tmplType = data.trim();
4506+
data = arguments[2];
4507+
}
4508+
if (!(_isObj(data) || renderTarget)) {
44924509
return xContent;
44934510
}
44944511

4495-
if ((/ data-bind\s*=/i).test(xContent)) {
4496-
xContent = xsr.bindData(xTemplate, data);
4512+
if (elTarget && !tmplType) {
4513+
tmplType = elTarget.getAttribute('type');
44974514
}
44984515

4499-
if ((/{{(.+)}}/).test(xContent)) {
4500-
if (compileTemplate) {
4501-
try {
4502-
xContent = compileTemplate(xContent)(data);
4503-
} catch (e) {
4504-
console.warn('Error Template compile/bind.', e);
4505-
}
4516+
(_isUndef(data) && (data={}));
4517+
4518+
if (/knockout|ko/gi.test(tmplType)) {
4519+
var elTarget = $(xTemplate)[0];
4520+
ko.cleanNode(elTarget);
4521+
ko.applyBindings(data, elTarget);
4522+
} else {
4523+
if (tmplType) {
4524+
xContent = win[tmplType].compile(xContent)(data);
45064525
} else {
4507-
console.warn('Template Library (Handlebars/doT) not found!');
4526+
if ((/ data-bind\s*=/i).test(xContent)) {
4527+
xContent = xsr.bindData(xTemplate, data);
4528+
}
4529+
if ((/{{(.+)}}/).test(xContent)) {
4530+
if (compileTemplate) {
4531+
try {
4532+
xContent = compileTemplate(xContent)(data);
4533+
} catch (e) {
4534+
console.warn('Error Template compile/bind.', e);
4535+
}
4536+
} else {
4537+
console.warn('Template Library (Handlebars/doT) not found!');
4538+
}
4539+
}
45084540
}
45094541
}
45104542

4543+
if (_isStr(renderTarget) && (/^\s*#[a-z]+/i).test(renderTarget)) {
4544+
$(renderTarget).html(xContent);
4545+
}
4546+
45114547
return xContent;
45124548
};
45134549

@@ -6494,8 +6530,9 @@
64946530
function _isDynSpa$(cName) {
64956531
return (/^(\$)*(dyn)*SPA\$/i.test(cName));
64966532
}
6533+
64976534
function _renderForComponent() {
6498-
event.preventDefault();
6535+
(event && event.preventDefault());
64996536

65006537
var onEvent = event;
65016538
var xEl = this;
@@ -6692,6 +6729,20 @@
66926729
return (_isFn(defaultPayload)? defaultPayload() : (_isObj(defaultPayload)? _mergeDeep({}, defaultPayload) : defaultPayload) );
66936730
}
66946731

6732+
function _evalObjProps ( srcObj, asNew ) {
6733+
var retObj = asNew? {} : srcObj;
6734+
if (!_isBlank(srcObj)) {
6735+
Object.keys(srcObj).forEach(function (key) {
6736+
if (_isFn(srcObj[key])) {
6737+
retObj[key] = srcObj[key].call(srcObj);
6738+
} else {
6739+
retObj[key] = srcObj[key];
6740+
}
6741+
})
6742+
};
6743+
return retObj;
6744+
}
6745+
66956746
/*
66966747
* xsr.render("#containerID")
66976748
*
@@ -7295,7 +7346,7 @@
72957346

72967347
dataUrlPayLoad = spaRVOptions.dataParams;
72977348
if ((!spaRVOptions.hasOwnProperty('defaultPayload')) && (!_isBlank(defPayLoad))) {
7298-
dataUrlPayLoad = _mergeDeep({}, defPayLoad, ((!_isBlank(dataUrlPayLoad) && _isObj(dataUrlPayLoad))? dataUrlPayLoad : {}));
7349+
dataUrlPayLoad = _evalObjProps(_mergeDeep({}, defPayLoad, ((!_isBlank(dataUrlPayLoad) && _isObj(dataUrlPayLoad))? dataUrlPayLoad : {})));
72997350
}
73007351
if (!_isBlank(dataUrlPayLoad) && _stringifyPayload) {
73017352
dataUrlPayLoad = JSON.stringify(dataUrlPayLoad);
@@ -7304,7 +7355,7 @@
73047355
var axOptions = {
73057356
url: dataModelUrl,
73067357
method: (''+(_renderOption('dataUrlMethod', 'urlMethod') || 'GET')).toUpperCase(),
7307-
headers: ((_isFn(ajaxReqHeaders))? ajaxReqHeaders() : ajaxReqHeaders),
7358+
headers: _evalObjProps(((_isFn(ajaxReqHeaders))? ajaxReqHeaders() : ajaxReqHeaders), true),
73087359
data: dataUrlPayLoad,
73097360
cache: spaRVOptions['dataUrlCache'] || spaRVOptions['dataCache'],
73107361
dataType: spaRVOptions.dataType || _find(window, 'app.api.ajaxOptions.dataType', 'text'),
@@ -7943,6 +7994,7 @@
79437994
$(viewContainerId).attr('data-rendered-component', rCompName).data('renderedComponent', rCompName);
79447995
_$renderCountUpdate(rCompName);
79457996
unlock$render(spaRVOptions['inProgress']);
7997+
$(viewContainerId)[0].removeAttribute('render-for-route');
79467998
_log.info("Render: SUCCESS");
79477999
var rhKeys = _keys(xsr.renderHistory);
79488000
var rhLen = rhKeys.length;
@@ -8370,8 +8422,10 @@
83708422
},
83718423
renameAttr: function(oldName, newName){
83728424
this.each(function(){
8373-
_attr(this, newName, _attr(this,oldName));
8374-
this.removeAttribute(oldName);
8425+
if (this.hasAttribute(oldName)) {
8426+
_attr(this, newName, _attr(this,oldName));
8427+
this.removeAttribute(oldName);
8428+
}
83758429
});
83768430
return this;
83778431
},
@@ -8577,23 +8631,24 @@
85778631
var lookupUrl = ((apiKey || '').trim()[0] === xsr.api.urlKeyIndicator);
85788632

85798633
apiKey = lookupUrl? (apiKey||'').trimLeftStr(xsr.api.urlKeyIndicator) : (apiKey || '');
8580-
urlReplaceKeyValues = urlReplaceKeyValues || {};
8634+
urlReplaceKeyValues = _evalObjProps(urlReplaceKeyValues || {}, true);
85818635

85828636
var apiUrl = _getUrl(apiKey) || apiKey // (xsr.api.urls[apiKey] || apiKey)
85838637
, isStaticUrl = apiUrl.beginsWithStr('!') || xsr.api.mock || app.api.mock
85848638
, forceParamValuesInMockUrls = apiUrl.beginsWithStr('!!') || apiUrl.beginsWithStr('~') || xsr.api.forceParamValuesInMockUrls
8585-
, paramsInUrl = apiUrl.extractStrBetweenIn('{', '}', true)
8639+
, paramsInUrl = apiUrl.extractStrBetweenIn('{', '}', true).concat(((apiUrl).match(/:[a-zA-Z_](\w*)/gi)||[]).__unique())
85868640
, pKey, pValue, skip, vFilters=[], ivFilters=[], filterContext = {url: apiUrl, urlParams: urlReplaceKeyValues}, defaultValue
85878641
, isMockReq = (xsr.api.mock || app.api.mock || apiUrl.beginsWithStr('!'));
85888642

85898643
if (!isMockReq) {
85908644
apiUrl = _removeMockParams(apiUrl);
85918645
}
8646+
85928647
if (!_isBlank(paramsInUrl)) {
85938648
_each(paramsInUrl, function(param){
85948649
ivFilters = [];
85958650
vFilters = [];
8596-
pKey = param.replace(/[{}<>]/g, '').trim();
8651+
pKey = param.replace(/[{}<>:]/g, '').trim();
85978652
if (pKey) {
85988653
if (pKey.indexOf('|')>0) {
85998654
vFilters = pKey.split('|').map(function(x){ return x.replace(/\(.*\)/g, '').trim(); });
@@ -9635,6 +9690,15 @@
96359690
}
96369691
xsr.parseRoutes = _getNewMatchingRoutes;
96379692

9693+
function _routeByEl ( el ) {
9694+
if (el.matches('[for][data-render-target]')) {
9695+
var rTargetEl = $(_attr(el, 'data-render-target'))[0];
9696+
if (!rTargetEl.hasAttribute('render-for-route')) {
9697+
rTargetEl.setAttribute('render-for-route', 'InProgress');
9698+
_renderForComponent.call(el);
9699+
}
9700+
}
9701+
}
96389702
function _onRouteElClick(e){
96399703
var spaRoutePath = xsr.urlHash([], _urlHashBase);
96409704
//console.clear();
@@ -9694,6 +9758,7 @@
96949758
//console.log('Dynamic Route URL', routeName);
96959759
}
96969760

9761+
setTimeout(_routeByEl, 0, targetEl);
96979762
_triggerClickEventOnAttr(targetEl, 'onrouteclick');
96989763

96999764
if ($routeEl.hasClass('AUTO-ROUTING')) { //exit if it's still routing ...

src/spa.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)