|
33 | 33 |
|
34 | 34 | (function() { |
35 | 35 |
|
36 | | - var _VERSION = '2.93.0-RC3'; |
| 36 | + var _VERSION = '2.93.0-RC4'; |
37 | 37 | var _version = _VERSION+'-'+(_now('.')); |
38 | 38 |
|
39 | 39 | /* Establish the win object, 'window' in the browser */ |
|
6294 | 6294 | } |
6295 | 6295 | } |
6296 | 6296 |
|
6297 | | - xsr.renderComponentsInHtml = function (scope, pComponentName, renderSelf) { |
6298 | | - |
6299 | | - (scope && (typeof scope === 'object') && scope.length && !scope[0] && (scope = '')); |
| 6297 | + function _parseAndRenderDomForSpaElements (scope, force) { |
| 6298 | + if (_isBool(scope)) { |
| 6299 | + force = scope; |
| 6300 | + scope = ''; |
| 6301 | + } |
6300 | 6302 | scope = scope||'body'; |
6301 | 6303 |
|
6302 | | - renderOptions = (typeof pComponentName == 'object')? pComponentName : ''; |
6303 | | - pComponentName = (typeof pComponentName == 'string')? pComponentName.trim() : ''; |
6304 | | - |
6305 | | - var $spaCompList = $(scope); |
6306 | | - var retVal; |
6307 | | - |
6308 | | - if (!renderSelf) { |
6309 | | - /*Register Events *for* in a, button, form elements */ |
6310 | | - _registerEventsForComponentRender(scope); |
6311 | | - |
6312 | | - // <spa-template src=""> <x-template src=""> |
6313 | | - var templateTags = _spaTagsSelector('spa-template,x-template'); |
6314 | | - $(scope).find(templateTags).each(function(){ |
6315 | | - // _attr(this, 'data-spa-component', _attr(this,'src')); |
6316 | | - _attr(this, 'data-x-component', _attr(this,'src')); |
6317 | | - _attr(this, 'data-skip-data-bind', 'true'); |
6318 | | - _attr(this, 'data-template-script', 'true'); |
6319 | | - this.style.display = 'none'; |
6320 | | - }); |
6321 | | - |
6322 | | - // <spa-html src=""> <x-html src=""> with optional [data] attribute |
6323 | | - var htmlTags = _spaTagsSelector('spa-html,x-html'); |
6324 | | - $(scope).find(htmlTags).each(function(){ |
6325 | | - var htmlSrc = _attr(this,'src'); |
6326 | | - var isSpaComponent = ((htmlSrc[0] === '$') || !(/[^a-z0-9]/ig).test( htmlSrc )); |
6327 | | - if (isSpaComponent && !xsr.components[htmlSrc.replace(/[^a-z0-9]/gi,'_')]) { |
6328 | | - var cOptions = { |
6329 | | - templateScript: true |
6330 | | - }; |
6331 | | - var skipDataBind = (!(this.hasAttribute('data') || this.hasAttribute('data-url'))); |
6332 | | - if (skipDataBind) { |
6333 | | - cOptions['skipDataBind'] = true; |
6334 | | - } else if (!this.hasAttribute('data-url')) { |
6335 | | - cOptions['data'] = this.hasAttribute('data')? _toObj(_attr(this,'data')) : {}; |
6336 | | - } |
6337 | | - xsr.$(htmlSrc, cOptions); |
6338 | | - } |
6339 | | - // _attr(this, 'data-spa-component', htmlSrc); |
6340 | | - _attr(this, 'data-x-component', htmlSrc); |
6341 | | - }); |
| 6304 | + $spaCompList = _getSpa$Elements(scope, !force); |
6342 | 6305 |
|
6343 | | - // <spa-component src=""> <x-component src=""> |
6344 | | - var componentTags = _spaTagsSelector('spa-component,x-component'); |
6345 | | - $(scope).find(componentTags).each(function(){ |
6346 | | - // _attr(this, 'data-spa-component', _attr(this,'src')); |
6347 | | - _attr(this, 'data-x-component', _attr(this,'src')); |
6348 | | - }); |
| 6306 | + return _renderSpaDomElements($spaCompList); |
| 6307 | + } |
| 6308 | + xsr.refresh = _parseAndRenderDomForSpaElements; |
| 6309 | + xsr.refreshAll = xsr.renderAll = function (scope) { |
| 6310 | + return _parseAndRenderDomForSpaElements(scope, true); |
| 6311 | + }; |
6349 | 6312 |
|
6350 | | - // other [src] |
6351 | | - var altCompSelector = ('[src]'+('audio embed iframe img input script source track video x-script [data-x-component] [data-spa-component]' |
6352 | | - .split(' ').map(function(tag){ return ':not('+tag+')'; }).join(''))); |
6353 | | - $(scope).find(altCompSelector).each(function(){ |
6354 | | - _attr(this, 'data-x-component', _attr(this,'src')); |
6355 | | - }); |
| 6313 | + function _renderSpaDomElements ($spaCompList, pComponentName, renderOptions) { |
| 6314 | + var retVal; |
6356 | 6315 |
|
6357 | | - $spaCompList = $spaCompList.find('[data-x-component],[data-spa-component]').filter(':not([render-after])'); |
| 6316 | + if (arguments.length==1) { |
| 6317 | + pComponentName = ''; |
| 6318 | + renderOptions = {}; |
6358 | 6319 | } |
6359 | 6320 |
|
6360 | 6321 | if ($spaCompList.length){ |
|
6458 | 6419 | } |
6459 | 6420 |
|
6460 | 6421 | return retVal; |
| 6422 | + } |
| 6423 | + |
| 6424 | + function _prepareSpaElements (scope) { |
| 6425 | + /*Register Events *for* in a, button, form elements */ |
| 6426 | + _registerEventsForComponentRender(scope); |
| 6427 | + |
| 6428 | + // <spa-template src=""> <x-template src=""> |
| 6429 | + var templateTags = _spaTagsSelector('spa-template,x-template'); |
| 6430 | + $(scope).find(templateTags).each(function(){ |
| 6431 | + // _attr(this, 'data-spa-component', _attr(this,'src')); |
| 6432 | + _attr(this, 'data-x-component', _attr(this,'src')); |
| 6433 | + _attr(this, 'data-skip-data-bind', 'true'); |
| 6434 | + _attr(this, 'data-template-script', 'true'); |
| 6435 | + this.style.display = 'none'; |
| 6436 | + }); |
| 6437 | + |
| 6438 | + // <spa-html src=""> <x-html src=""> with optional [data] attribute |
| 6439 | + var htmlTags = _spaTagsSelector('spa-html,x-html'); |
| 6440 | + $(scope).find(htmlTags).each(function(){ |
| 6441 | + var htmlSrc = _attr(this,'src'); |
| 6442 | + var isSpaComponent = ((htmlSrc[0] === '$') || !(/[^a-z0-9]/ig).test( htmlSrc )); |
| 6443 | + if (isSpaComponent && !xsr.components[htmlSrc.replace(/[^a-z0-9]/gi,'_')]) { |
| 6444 | + var cOptions = { |
| 6445 | + templateScript: true |
| 6446 | + }; |
| 6447 | + var skipDataBind = (!(this.hasAttribute('data') || this.hasAttribute('data-url'))); |
| 6448 | + if (skipDataBind) { |
| 6449 | + cOptions['skipDataBind'] = true; |
| 6450 | + } else if (!this.hasAttribute('data-url')) { |
| 6451 | + cOptions['data'] = this.hasAttribute('data')? _toObj(_attr(this,'data')) : {}; |
| 6452 | + } |
| 6453 | + xsr.$(htmlSrc, cOptions); |
| 6454 | + } |
| 6455 | + // _attr(this, 'data-spa-component', htmlSrc); |
| 6456 | + _attr(this, 'data-x-component', htmlSrc); |
| 6457 | + }); |
| 6458 | + |
| 6459 | + // <spa-component src=""> <x-component src=""> |
| 6460 | + var componentTags = _spaTagsSelector('spa-component,x-component'); |
| 6461 | + $(scope).find(componentTags).find(':not([data-x-component])').each(function(){ |
| 6462 | + // _attr(this, 'data-spa-component', _attr(this,'src')); |
| 6463 | + _attr(this, 'data-x-component', _attr(this,'src')); |
| 6464 | + }); |
| 6465 | + |
| 6466 | + // other [src] |
| 6467 | + var altCompSelector = ('[src]'+('audio embed iframe img input script source track video x-script [data-x-component] [data-spa-component]' |
| 6468 | + .split(' ').map(function(tag){ return ':not('+tag+')'; }).join(''))); |
| 6469 | + $(scope).find(altCompSelector).each(function(){ |
| 6470 | + _attr(this, 'data-x-component', _attr(this,'src')); |
| 6471 | + }); |
| 6472 | + } |
| 6473 | + |
| 6474 | + function _getSpa$Elements (scope, forMissedOnly) { |
| 6475 | + _prepareSpaElements(scope); |
| 6476 | + |
| 6477 | + var $spaCompList = $(scope); |
| 6478 | + var forMissed = forMissedOnly? ':not([data-rendered-component])' : ''; |
| 6479 | + |
| 6480 | + $spaCompList = $spaCompList.find('[data-x-component],[data-spa-component]').filter(':not([render-after])'+forMissed); |
| 6481 | + |
| 6482 | + return $spaCompList; |
| 6483 | + } |
| 6484 | + |
| 6485 | + xsr.renderComponentsInHtml = function (scope, pComponentName, renderSelf) { |
| 6486 | + |
| 6487 | + (scope && (typeof scope === 'object') && scope.length && !scope[0] && (scope = '')); |
| 6488 | + scope = scope||'body'; |
| 6489 | + |
| 6490 | + renderOptions = (typeof pComponentName == 'object')? pComponentName : ''; |
| 6491 | + pComponentName = (typeof pComponentName == 'string')? pComponentName.trim() : ''; |
| 6492 | + |
| 6493 | + var $spaCompList = $(scope); |
| 6494 | + |
| 6495 | + if (!renderSelf) { |
| 6496 | + $spaCompList = _getSpa$Elements(scope); |
| 6497 | + } |
| 6498 | + |
| 6499 | + return _renderSpaDomElements($spaCompList, pComponentName, renderOptions); |
6461 | 6500 | }; |
6462 | 6501 |
|
6463 | 6502 | xsr.renderUtils = { |
|
6822 | 6861 | xsr.render = function (viewContainerId, uOptions) { |
6823 | 6862 | _log.log('xsr.render', viewContainerId, uOptions); |
6824 | 6863 |
|
6825 | | - if (!arguments.length) return; |
| 6864 | + if ((!arguments.length) || |
| 6865 | + (_isBool(viewContainerId)) || |
| 6866 | + (_isBool(uOptions)) || |
| 6867 | + (_isStr(viewContainerId) && !/^#/.test(viewContainerId.trim()) && !_isObj(uOptions))) { |
| 6868 | + return _parseAndRenderDomForSpaElements.apply(xsr, ([]).slice.call(arguments)); |
| 6869 | + } |
6826 | 6870 |
|
6827 | 6871 | //render with single argument with target |
6828 | 6872 | if ((arguments.length===1) && (typeof viewContainerId === "object")) { |
@@ -10457,34 +10501,40 @@ |
10457 | 10501 |
|
10458 | 10502 |
|
10459 | 10503 | var _isInReact; |
| 10504 | + var _isInReactSet; |
10460 | 10505 | var _isInOjEnv; |
| 10506 | + var _isInOjEnvSet; |
| 10507 | + var _isAMDenv; |
10461 | 10508 | var _isInExtEnv; |
10462 | 10509 |
|
10463 | 10510 | function _checkExtEnv () { |
10464 | | - if (!_isInExtEnv) { |
10465 | | - _isInReact = win.__reactRefreshInjected; |
10466 | | - _isInOjEnv = (win['oj'] && _spa_hasPrimaryKeys(oj, 'version&revision&Model&Router')); |
10467 | | - _isInExtEnv = _isInReact || _isInOjEnv; |
| 10511 | + _log.log('Checking external environments ...'); |
10468 | 10512 |
|
10469 | | - if (_isInExtEnv) { |
| 10513 | + _isAMDenv = !!(win['require'] && win['define']); |
| 10514 | + _isInReact = !!win['__reactRefreshInjected']; |
| 10515 | + _isInOjEnv = !!(win['oj'] && _spa_hasPrimaryKeys(oj, 'version&revision&Model&Router')); |
| 10516 | + _isInExtEnv = _isInReact || _isInOjEnv || _isAMDenv; |
| 10517 | + _log.log('🚀 ~ _isInExtEnv:',_isInExtEnv,' _isInReact:',_isInReact,' _isInOjEnv:',_isInOjEnv,' _isAMDenv:',_isAMDenv); |
10470 | 10518 |
|
10471 | | - if (_isInReact) { |
10472 | | - (_isLocEnv && console.info('Found SPA in React env! Setting default SPA-components folder to "public/components" instead of "app/components". NOTE: This message will not appear in production env.')); |
10473 | | - xsr.defaults.components.rootPath = 'components/'; |
10474 | | - } |
| 10519 | + if (_isInExtEnv) { |
10475 | 10520 |
|
10476 | | - if (_isInOjEnv) { |
10477 | | - (_isLocEnv && console.info('Found SPA in OJet env! Setting default SPA-components folder to "src/js/components" instead of "app/components". NOTE: This message will not appear in production env.')); |
10478 | | - xsr.defaults.components.rootPath = 'js/components/'; |
10479 | | - } |
| 10521 | + if (_isInReact && !_isInReactSet) { |
| 10522 | + (_isLocEnv && console.info('Found SPA in React env! Setting default SPA-components folder to "public/components" instead of "app/components". NOTE: This message will not appear in production env.')); |
| 10523 | + xsr.defaults.components.rootPath = 'components/'; |
| 10524 | + _isInReactSet=true; |
| 10525 | + } |
10480 | 10526 |
|
| 10527 | + if (_isInOjEnv && !_isInOjEnvSet) { |
| 10528 | + (_isLocEnv && console.info('Found SPA in OJet env! Setting default SPA-components folder to "src/js/components" instead of "app/components". NOTE: This message will not appear in production env.')); |
| 10529 | + xsr.defaults.components.rootPath = 'js/components/'; |
| 10530 | + _isInOjEnvSet = true; |
10481 | 10531 | } |
10482 | 10532 |
|
10483 | 10533 | observeDOM(); |
10484 | 10534 | } |
10485 | 10535 | } |
10486 | 10536 |
|
10487 | | - function _initSpaDefaults(){ |
| 10537 | + function _initSpaDefaults(cfgObj){ |
10488 | 10538 | var defaultsInTag |
10489 | 10539 | , $body = $('body') |
10490 | 10540 | , elBody = $body[0] |
|
10515 | 10565 | win[xsr.defaults.alias] = xsr; |
10516 | 10566 | } |
10517 | 10567 |
|
| 10568 | + if (cfgObj && _isObj(cfgObj)) { |
| 10569 | + xsr.defaults.set(cfgObj); |
| 10570 | + } |
| 10571 | + |
10518 | 10572 | _initRoutesDefaults(); //run_once |
10519 | 10573 | _initApiUrls(); //need to run on 1st Component renderCallback as well |
10520 | 10574 | } |
|
10591 | 10645 | } |
10592 | 10646 |
|
10593 | 10647 | var domObserver; |
10594 | | - function onDomChange(mutationsList) { |
| 10648 | + var stoRenderMissingEl; |
| 10649 | + function deferLookupOnDomChange () { |
| 10650 | + _log.log('deferring scan for SPA elements to render on DOM change.'); |
| 10651 | + clearTimeout(stoRenderMissingEl); |
| 10652 | + stoRenderMissingEl = setTimeout(function() { |
| 10653 | + if (_isRendering()) { |
| 10654 | + deferLookupOnDomChange(); |
| 10655 | + } else { |
| 10656 | + _log.log('looking for SPA elements to render on DOM Change ...'); |
| 10657 | + _parseAndRenderDomForSpaElements(); |
| 10658 | + } |
| 10659 | + },200); |
| 10660 | + } |
| 10661 | + function onDomChange(mutationsList) { |
10595 | 10662 | if (!_isRendering() && !stoRender) { |
10596 | 10663 | var pContainer, mutation; |
10597 | 10664 | for(var i=0; i<mutationsList.length; i++) { |
|
10602 | 10669 | break; |
10603 | 10670 | } |
10604 | 10671 | } |
| 10672 | + |
10605 | 10673 | if (pContainer) { |
10606 | 10674 | var pContainerId = pContainer.id || (pContainer.tagName+'-'+(_rand(1000, 9999))+'-'+_now()); |
10607 | 10675 | pContainer.id = pContainerId; |
|
10611 | 10679 | }, 1, '#'+pContainerId); |
10612 | 10680 | _log.log('DOM watch: New element(s) added inside Non-SPA component container', pContainer); |
10613 | 10681 | } |
| 10682 | + } else { |
| 10683 | + deferLookupOnDomChange(); |
10614 | 10684 | } |
10615 | 10685 | } |
10616 | 10686 | function observeDOM () { |
|
10649 | 10719 | _cInfoMsg('Failed to self start SPA! In an external environment, start SPA using spa.start() when all modules are loaded.'); |
10650 | 10720 | } |
10651 | 10721 | } |
10652 | | - function _beginSPA(){ |
| 10722 | + function _beginSPA(cfgObj){ |
10653 | 10723 | _log.log('begin SPA'); |
10654 | 10724 |
|
10655 | 10725 | if (!isSPAReady) _initXHR(); |
|
10660 | 10730 | if (xhrLib) { |
10661 | 10731 |
|
10662 | 10732 | //Read xsr.defaults from body |
10663 | | - _initSpaDefaults(); |
| 10733 | + _initSpaDefaults(cfgObj); |
10664 | 10734 |
|
10665 | 10735 | /* ajaxPrefilter */ |
10666 | 10736 | $ajaxPrefilter(_ajaxPrefilter); |
|
0 commit comments