1
0
Alex Trofimov 6 жил өмнө
parent
commit
0e65507e38

+ 67 - 0
inc/classes/BxDolTemplate.php

@@ -225,6 +225,7 @@ class BxDolTemplate extends BxDolFactory implements iBxDolSingleton
 
     protected $aPage;
     protected $aPageContent;
+    protected $aPageSnapshot = array();
 
     protected $_oTemplateConfig;
     protected $_oTemplateFunctions;
@@ -450,6 +451,66 @@ class BxDolTemplate extends BxDolFactory implements iBxDolSingleton
         return $aResult;
     }
 
+    public function getIncludedUrls($sType)
+    {
+        if (!isset($this->aPage[$sType]))
+            return array();
+        $a = array();
+        foreach ($this->aPage[$sType] as $r)
+            $a[] = $r['url'];
+        return $a;
+    }
+
+    /**
+     * Remember current state of aPage variable with all css, js, etc
+     */
+    public function collectingStart()
+    {
+        $this->aPageSnapshot = $this->aPage;
+    }
+
+    /**
+     * Get difference for non-system css and js files from previously remembered state as ready HTML code, 
+     * additionally filter out css and js from $aExcludeCss and $aExcludeJs arrays
+     */
+    public function collectingEndGetCode($aExcludeCss = array(), $aExcludeJs = array())
+    {
+        $aPageSave = $this->aPage; // save current state to restore later
+
+        // filter funcs
+        $fFilterCss = function ($a) use ($aExcludeCss) {
+            if (in_array($a['url'], $aExcludeCss))
+                return false;
+            foreach ($this->aPageSnapshot['css_compiled'] as $r)
+                if ($r['url'] == $a['url'])
+                    return false;
+            return true;
+        };
+        $fFilterJs = function ($a) use ($aExcludeJs) {
+            if (in_array($a['url'], $aExcludeJs))
+                return false;
+            foreach ($this->aPageSnapshot['js_compiled'] as $r)
+                if ($r['url'] == $a['url'])
+                    return false;
+            return true;
+        };    
+
+        // diff aPageSnapshot and aPage and output only newly added css/js
+        $this->aPage['css_compiled'] = array_filter($this->aPage['css_compiled'], $fFilterCss);
+        $this->aPage['js_compiled'] = array_filter($this->aPage['js_compiled'], $fFilterJs);
+
+        // return js/css
+        $sRet = '';
+        $sRet .= $this->includeFiles('css');
+        $sRet .= $this->includeFiles('js');
+
+        // restore original state
+        $this->aPageSnapshot = array();
+        $this->aPage = $aPageSave; 
+
+        return $sRet;
+    }
+
     public function getClassName()
     {
         return get_class($this);
@@ -1528,6 +1589,12 @@ class BxDolTemplate extends BxDolFactory implements iBxDolSingleton
 			case 'system_js_requred':
                 $sRet = _t('_sys_javascript_requred');
                 break;
+            case 'included_css':
+                $sRet = json_encode($this->getIncludedUrls('css_compiled'));
+                break;
+            case 'included_js':
+                $sRet = json_encode($this->getIncludedUrls('js_compiled'));
+                break;
             default:
                 $sRet = ($sTemplAdd = BxTemplFunctions::getInstance()->TemplPageAddComponent($sKey)) !== false ? $sTemplAdd : $aKeyWrappers['left'] . $sKey . $aKeyWrappers['right'];
         }

+ 16 - 12
inc/js/functions.js

@@ -61,7 +61,7 @@ function processJsonData(oData) {
 		fContinue(oData);
 };
 
-function getHtmlData( elem, url, callback, method , confirmation)
+function getHtmlData( elem, url, callback, method, confirmation, values, loading)
 {
     var fPerform = function() {
 		// in most cases it is element ID, in other cases - object of jQuery
@@ -74,21 +74,25 @@ function getHtmlData( elem, url, callback, method , confirmation)
 
 		$block.css('position', 'relative'); // set temporarily for displaying "loading icon"
 
-		bx_loading_content($block, true);
-		var $loadingDiv = $block.find('.bx-loading-ajax');
+        if (typeof loading == undefined || loading) {
+    		bx_loading_content($block, true);
+	    	var $loadingDiv = $block.find('.bx-loading-ajax');
 
-		var iLeftOff = parseInt(($block.innerWidth() / 2.0) - ($loadingDiv.outerWidth()  / 2.0));
-		var iTopOff  = parseInt(($block.innerHeight() / 2.0) - ($loadingDiv.outerHeight()));
-		if (iTopOff<0) iTopOff = 0;
+    		var iLeftOff = parseInt(($block.innerWidth() / 2.0) - ($loadingDiv.outerWidth()  / 2.0));
+	    	var iTopOff  = parseInt(($block.innerHeight() / 2.0) - ($loadingDiv.outerHeight()));
+		    if (iTopOff<0) iTopOff = 0;
 
-		$loadingDiv.css({
-		    position: 'absolute',
-		    left: iLeftOff,
-		    top:  iTopOff
-		});
+    		$loadingDiv.css({
+	    	    position: 'absolute',
+		        left: iLeftOff,
+    		    top:  iTopOff
+	    	});
+        }
 
 		if (undefined != method && (method == 'post' || method == 'POST')) {
-		    $.post(url, function(data) {
+            if (typeof values == 'undefined')
+                values = {};
+		    $.post(url, values, function(data) {
 		        $block.html(data);
 		        $block.css('position', blockPos).bxProcessHtml();
 

+ 2 - 0
template/_header_js.html

@@ -54,4 +54,6 @@
 
     fMediaCallback(null);
 
+    var aIncludedCss = __included_css__;
+    var aIncludedJs = __included_js__;
 </script>

+ 6 - 0
template/block_async_1.html

@@ -0,0 +1,6 @@
+<script>
+  $(document).ready(function () {
+    var iBlockID = '__id__';
+    getHtmlData($('#bx-page-block-' + iBlockID), bx_append_url_params(sUrlRoot, 'dynamic=tab&pageBlock=' + iBlockID), undefined, 'post', false, {includedCss: JSON.stringify(aIncludedCss), includedJs: JSON.stringify(aIncludedJs)});
+  });
+</script>

+ 29 - 0
template/block_async_2.html

@@ -0,0 +1,29 @@
+<div>
+<div class="bx-def-box bx-def-padding-topbottom bx-def-round-corners bx-def-color-bg-box bx-def-margin-bottom">
+    <div class="bx-clearfix">
+        <div class="bx-cont-ph bx-def-thumb-size bx-def-thumb bx-def-box-sizing bx-def-margin" style="float:left;">&nbsp;</div>
+        <span class="bx-cont-ph-inline bx-def-margin-top" style="width:10rem;">&nbsp;</span><br />
+        <span class="bx-cont-ph-inline bx-def-margin-thd-top bx-def-font-small" style="width:7rem;">&nbsp;</span>
+    </div>
+    <div class="bx-cont-ph" style="height:20rem;"></div>
+    <span class="bx-cont-ph-inline bx-def-margin bx-def-font-h3" style="width:18rem;">&nbsp;</span>
+</div>
+<div class="bx-def-box bx-def-padding-topbottom bx-def-round-corners bx-def-color-bg-box bx-def-margin-bottom">
+    <div class="bx-clearfix">
+        <div class="bx-cont-ph bx-def-thumb-size bx-def-thumb bx-def-box-sizing bx-def-margin" style="float:left;">&nbsp;</div>
+        <span class="bx-cont-ph-inline bx-def-margin-top" style="width:10rem;">&nbsp;</span><br />
+        <span class="bx-cont-ph-inline bx-def-margin-thd-top bx-def-font-small" style="width:7rem;">&nbsp;</span>
+    </div>
+    <div class="bx-def-padding">
+        <div class="bx-cont-ph bx-def-margin-thd-bottom">&nbsp;</div>
+        <div class="bx-cont-ph bx-def-margin-thd-bottom">&nbsp;</div>
+        <div class="bx-cont-ph bx-def-margin-thd-bottom">&nbsp;</div>
+        <div class="bx-cont-ph bx-def-margin-thd-bottom">&nbsp;</div>
+    </div>
+</div>
+<script>
+    $(document).ready(function () {
+        var iBlockID = '__id__';
+        getHtmlData($('#bx-page-block-' + iBlockID), bx_append_url_params(sUrlRoot, 'dynamic=tab&pageBlock=' + iBlockID), undefined, 'post', false, {includedCss: JSON.stringify(aIncludedCss), includedJs: JSON.stringify(aIncludedJs)}, false);
+    });
+</script>

+ 45 - 0
template/css/general.css

@@ -500,3 +500,48 @@ video.bx-player-embed {
     text-align:left;
     line-height:150%;
 }
+
+/* --------------- Content loader placeholder */
+
+@-webkit-keyframes bxPlaceHolderShimmer {
+  0% {
+    background-position: -468px 0;
+  }
+  100% {
+    background-position: 468px 0;
+  }
+}
+
+@keyframes bxPlaceHolderShimmer {
+  0% {
+    background-position: -468px 0;
+  }
+  100% {
+    background-position: 468px 0;
+  }
+}
+
+.bx-cont-ph-inline, 
+.bx-cont-ph {
+  -webkit-animation-duration: 1s;
+  animation-duration: 1s;
+  -webkit-animation-fill-mode: forwards;
+  animation-fill-mode: forwards;
+  -webkit-animation-iteration-count: infinite;
+  animation-iteration-count: infinite;
+  -webkit-animation-name: bxPlaceHolderShimmer;
+  animation-name: bxPlaceHolderShimmer;
+  -webkit-animation-timing-function: linear;
+  animation-timing-function: linear;
+  background: #f6f7f8;
+  background: -webkit-gradient(linear, left top, right top, color-stop(8%, #eeeeee), color-stop(18%, #dddddd), color-stop(33%, #eeeeee));
+  background: -webkit-linear-gradient(left, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
+  background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
+  -webkit-background-size: 800px 104px;
+  background-size: 800px 104px;
+  position: relative;
+}
+
+.bx-cont-ph-inline {
+    display:inline-block;
+}

+ 37 - 5
template/scripts/BxBasePage.php

@@ -41,6 +41,8 @@ class BxBasePage extends BxDolPage
      */ 
     public function getCodeDynamic ()
     {
+        // TODO: remake to use use collect* template methods
+
         $oTemplate = BxDolTemplate::getInstance();
 
         // get js&css before the page code is generated
@@ -92,7 +94,16 @@ class BxBasePage extends BxDolPage
             ));
 
             header( 'Content-type:text/html;charset=utf-8' );
-            echo $this->_getBlockOnlyCode($iBlockId);
+
+            BxDolTemplate::getInstance()->collectingStart();
+
+            $s = $this->_getBlockOnlyCode($iBlockId);
+
+            $sCss = bx_get('includedCss');
+            $sJs = bx_get('includedJs');
+            echo BxDolTemplate::getInstance()->collectingEndGetCode($sCss ? json_decode($sCss) : array(), $sJs ? json_decode($sJs) : array());
+
+            echo $s;
             exit;
         }
 
@@ -244,6 +255,17 @@ class BxBasePage extends BxDolPage
         return $this->_replaceMarkers(_t($aBlock['title']), array('block_id' => $aBlock['id']));
     }
 
+    /**
+     * Get code to load block asyncroniously
+     * @param $aBlock block code
+     * @param $iAsync if greater than 0 the it defines loading indicator for the block
+     * @return HTML code string
+     */
+    public function getBlockAsyncCode($aBlock, $iAsync)
+    {
+        return $this->_oTemplate->parseHtmlByName('block_async_' . $iAsync . '.html', $aBlock);
+    }
+
     /**
      * Get page array with all cells and blocks
      */
@@ -310,7 +332,7 @@ class BxBasePage extends BxDolPage
             foreach ($aCell as $aBlock) {
                 $this->processPageBlock($aBlock, false);
 
-                $sContentWithBox = $this->_getBlockCode($aBlock);
+                $sContentWithBox = $this->_getBlockCode($aBlock, $aBlock['async']);
 
             	$sHiddenOn = '';
                 if(!empty($aBlock['hidden_on']))
@@ -353,14 +375,14 @@ class BxBasePage extends BxDolPage
     {
         if (!($aBlock = $this->_oQuery->getPageBlock((int)$iBlockId)))
             return '';
-        return $this->_getBlockCode($aBlock);
+        return $this->_getBlockCode($aBlock, 0);
     }
 
     /**
      * Get block code.
      * @return string
      */
-    protected function _getBlockCode($aBlock)
+    protected function _getBlockCode($aBlock, $iAsync = 0)
     {
         $sContentWithBox = '';
         $oFunctions = $this->_oTemplate->getTemplateFunctions();
@@ -368,7 +390,17 @@ class BxBasePage extends BxDolPage
         if (isset($GLOBALS['bx_profiler'])) $GLOBALS['bx_profiler']->beginPageBlock(_t($aBlock['title']), $aBlock['id']);
 
         $sFunc = '_getBlock' . ucfirst($aBlock['type']);
-        if ($this->_isVisibleBlock($aBlock) && method_exists($this, $sFunc)) {
+        $bBlockVisible = $this->_isVisibleBlock($aBlock);
+        if ($iAsync && $bBlockVisible) {    
+            $sContent = $this->getBlockAsyncCode($aBlock, $iAsync);
+            $aParams = array(
+                $this->getBlockTitle($aBlock),
+                $sContent,
+                $aBlock['designbox_id']
+            );
+            $sContentWithBox = call_user_func_array(array($oFunctions, 'designBoxContent'), $aParams);
+        } 
+        elseif ($bBlockVisible && method_exists($this, $sFunc)) {
             $mixedContent = $this->$sFunc($aBlock);
 
             $sTitle = $this->getBlockTitle($aBlock);