public static function compile($source, $path, $todir, $importdirs) { // call Less to compile $parser = new lessc(); $parser->setImportDir(array_keys($importdirs)); $parser->setPreserveComments(true); $output = $parser->compile($source); // update url $arr = preg_split(CANVASLess::$rsplitbegin . CANVASLess::$kfilepath . CANVASLess::$rsplitend, $output, -1, PREG_SPLIT_DELIM_CAPTURE); $output = ''; $file = $relpath = ''; $isfile = false; foreach ($arr as $s) { if ($isfile) { $isfile = false; $file = $s; $relpath = CANVASLess::relativePath($todir, dirname($file)); $output .= "\n#" . CANVASLess::$kfilepath . "{content: \"{$file}\";}\n"; } else { $output .= ($file ? CANVASPath::updateUrl($s, $relpath) : $s) . "\n\n"; $isfile = true; } } return $output; }
/** * @param $tpl template object * @return bool optimize success or not */ public static function optimizecss($tpl) { $outputpath = JPATH_ROOT . '/' . $tpl->getParam('canvas-assets', 'canvas-assets') . '/css'; $outputurl = JURI::root(true) . '/' . $tpl->getParam('canvas-assets', 'canvas-assets') . '/css'; if (!JFile::exists($outputpath)) { JFolder::create($outputpath); @chmod($outputpath, 0755); } if (!is_writeable($outputpath)) { return false; } //prepare config self::prepare($tpl); $doc = JFactory::getDocument(); //======================= Group css ================= // $mediagroup = array(); $cssgroups = array(); $stylesheets = array(); $ielimit = 4095; $selcounts = 0; $regex = '/\\{.+?\\}|,/s'; //selector counter $csspath = ''; // group css into media $mediagroup['all'] = array(); $mediagroup['screen'] = array(); foreach ($doc->_styleSheets as $url => $stylesheet) { $media = $stylesheet['media'] ? $stylesheet['media'] : 'all'; if (empty($mediagroup[$media])) { $mediagroup[$media] = array(); } $mediagroup[$media][$url] = $stylesheet; } foreach ($mediagroup as $media => $group) { $stylesheets = array(); // empty - begin a new group foreach ($group as $url => $stylesheet) { $url = self::fixUrl($url); if ($stylesheet['mime'] == 'text/css' && ($csspath = self::cssPath($url))) { $stylesheet['path'] = $csspath; $stylesheet['data'] = file_get_contents($csspath); $selcount = preg_match_all($regex, $stylesheet['data'], $matched); if (!$selcount) { $selcount = 1; //just for sure } //if we found an @import rule or reach IE limit css selector count, break into the new group if (preg_match('#@import\\s+.+#', $stylesheet['data']) || $selcounts + $selcount >= $ielimit) { if (count($stylesheets)) { $cssgroup = array(); $groupname = array(); foreach ($stylesheets as $gurl => $gsheet) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroup['media'] = $media; $cssgroups[] = $cssgroup; } $stylesheets = array($url => $stylesheet); // empty - begin a new group $selcounts = $selcount; } else { $stylesheets[$url] = $stylesheet; $selcounts += $selcount; } } else { // first get all the stylsheets up to this point, and get them into // the items array if (count($stylesheets)) { $cssgroup = array(); $groupname = array(); foreach ($stylesheets as $gurl => $gsheet) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroup['media'] = $media; $cssgroups[] = $cssgroup; } //mark ignore current stylesheet $cssgroup = array($url => $stylesheet, 'ignore' => true); $cssgroups[] = $cssgroup; $stylesheets = array(); // empty - begin a new group } } if (count($stylesheets)) { $cssgroup = array(); $groupname = array(); foreach ($stylesheets as $gurl => $gsheet) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroup['media'] = $media; $cssgroups[] = $cssgroup; } } //======================= Group css ================= // $output = array(); foreach ($cssgroups as $cssgroup) { if (isset($cssgroup['ignore'])) { unset($cssgroup['ignore']); unset($cssgroup['groupname']); unset($cssgroup['media']); foreach ($cssgroup as $furl => $fsheet) { $output[$furl] = $fsheet; } } else { $media = $cssgroup['media']; $groupname = 'css-' . substr(md5($cssgroup['groupname']), 0, 5) . '.css'; $groupfile = $outputpath . '/' . $groupname; $grouptime = JFile::exists($groupfile) ? @filemtime($groupfile) : -1; $rebuild = $grouptime < 0; //filemtime == -1 => rebuild unset($cssgroup['groupname']); unset($cssgroup['media']); foreach ($cssgroup as $furl => $fsheet) { if (!$rebuild && @filemtime($fsheet['path']) > $grouptime) { $rebuild = true; } } if ($rebuild) { $cssdata = array(); foreach ($cssgroup as $furl => $fsheet) { $cssdata[] = "\n\n/*==============================="; $cssdata[] = $furl; $cssdata[] = "================================================================================*/"; $cssmin = self::minifyCss($fsheet['data']); $cssmin = CANVASPath::updateUrl($cssmin, CANVASPath::relativePath($outputurl, dirname($furl))); $cssdata[] = $cssmin; } $cssdata = implode("\n", $cssdata); if (!JFile::write($groupfile, $cssdata)) { // cannot write file, ignore minify return false; } $grouptime = @filemtime($groupfile); @chmod($groupfile, 0644); } $output[$outputurl . '/' . $groupname . '?t=' . $grouptime % 1000] = array('mime' => 'text/css', 'media' => $media == 'all' ? NULL : $media, 'attribs' => array()); } } //apply the change make change $doc->_styleSheets = $output; }