public static function run($pluginsInitCode, Kwf_SourceMaps_SourceMap $sourcemap) { $js = "\n require('es6-promise').polyfill(); //required for older nodejs\n var postcss = require('postcss');\n var plugins = [];\n " . $pluginsInitCode . "\n var instance = postcss( plugins );\n var css = '';\n process.stdin.setEncoding('utf-8')\n process.stdin.on('data', function(buf) { css += buf.toString(); });\n process.stdin.on('end', function() {\n instance.process(css).then(function (result) {\n process.stdout.write(result.css);\n }).catch(function(e) {\n console.log(e);\n process.exit(1);\n });\n });\n process.stdin.resume();\n "; $runfile = tempnam("temp/", 'postcss'); file_put_contents($runfile, $js); putenv("NODE_PATH=" . getcwd() . "/node_modules" . PATH_SEPARATOR . getcwd() . "/" . KWF_PATH . PATH_SEPARATOR . getcwd() . "/"); $cmd = getcwd() . "/" . VENDOR_PATH . "/bin/node " . $runfile; $cmd .= " 2>&1"; $process = new Symfony\Component\Process\Process($cmd); $mapData = $sourcemap->getMapContentsData(false); $hasSourcemap = !!$mapData->mappings; if ($hasSourcemap) { $process->setInput($sourcemap->getFileContentsInlineMap(false)); } else { $process->setInput($sourcemap->getFileContents()); } if ($process->run() !== 0) { throw new Kwf_Exception("Process '{$cmd}' failed with " . $process->getExitCode() . "\n" . $process->getOutput()); } putenv("NODE_PATH="); unlink($runfile); $out = $process->getOutput(); if (Kwf_SourceMaps_SourceMap::hasInline($out)) { $ret = Kwf_SourceMaps_SourceMap::createFromInline($out); } else { $ret = Kwf_SourceMaps_SourceMap::createEmptyMap($out); $ret->setMimeType('text/css'); } $ret->setSources($sourcemap->getSources()); return $ret; }
public function testAdd() { $map = new Kwf_SourceMaps_SourceMap(Kwf_SourceMaps_TestData::$testMap, Kwf_SourceMaps_TestData::$testGeneratedCode); $mappings = $map->getMappings(); $map->addSource('three.js'); $sources = $map->getSources(); $this->assertEquals(array('one.js', 'two.js', 'three.js'), $sources); $c = $map->getFileContentsInlineMap(false); $map = Kwf_SourceMaps_SourceMap::createFromInline($c); $this->assertEquals(array('one.js', 'two.js', 'three.js'), $sources); $map->addMapping(1, 1, 1, 1, 'one.js'); $c = $map->getFileContentsInlineMap(false); $this->assertEquals(array('one.js', 'two.js', 'three.js'), $sources); }
public function build() { $babel = getcwd() . "/" . VENDOR_PATH . "/bin/node " . getcwd() . '/node_modules/babel-cli/bin/babel.js'; $cmd = "{$babel} "; $arguments = implode(' ', array_values($this->_getArguments())); $cmd .= "{$arguments} "; $cmd .= escapeshellarg($this->_sourceFile); $cmd .= " 2>&1"; $out = array(); $nodePath = implode(PATH_SEPARATOR, $this->_getNodePath()); putenv("NODE_PATH={$nodePath}"); exec($cmd, $out, $retVal); putenv("NODE_PATH="); if ($retVal) { throw new Kwf_Exception("babel failed: " . implode("\n", $out)); } $contents = implode("\n", $out); return Kwf_SourceMaps_SourceMap::createFromInline($contents); }
public function filter(Kwf_SourceMaps_SourceMap $sourcemap) { putenv("NODE_PATH=" . getcwd() . "/node_modules"); $cmd = getcwd() . "/" . VENDOR_PATH . "/bin/node " . __DIR__ . "/CssChunks.js"; $cmd .= " 2>&1"; $process = new Symfony\Component\Process\Process($cmd); $process->setInput($sourcemap->getFileContentsInlineMap(false)); $process->mustRun(); $out = $process->getOutput(); $out = explode("\n/* ***** NEXT CHUNK ***** */\n", $out); $ret = array(); foreach ($out as $chunk) { if (Kwf_SourceMaps_SourceMap::hasInline($chunk)) { $mapChunk = Kwf_SourceMaps_SourceMap::createFromInline($chunk); } else { $mapChunk = Kwf_SourceMaps_SourceMap::createEmptyMap($chunk); $mapChunk->setMimeType('text/css'); } $ret[] = $mapChunk; } return $ret; }
private function _buildPackageContents($mimeType) { foreach ($this->_providerList->getProviders() as $provider) { $provider->initialize(); } $packageMap = Kwf_SourceMaps_SourceMap::createEmptyMap(''); if ($mimeType == 'text/css' || $mimeType == 'text/css; ie8') { $packageMap->setMimeType('text/css'); } else { $packageMap->setMimeType('text/javascript'); } $trlData = array(); // ***** commonjs $commonJsData = $this->_getCommonJsData($mimeType); if ($commonJsData) { foreach ($commonJsData as &$i) { $data = $i['source']->getMapContentsData(false); if (isset($data->{'_x_org_koala-framework_trlData'})) { $trlData = array_merge($trlData, $data->{'_x_org_koala-framework_trlData'}); } $data->sourcesContent = $data->sources; //browser-pack needs sourcesContent, else it would ignore input source map. This is fake obviously and we'll drop it anyway after browser-pack finished if (isset($i['source']->getMapContentsData(false)->sources[0])) { $i['sourceFile'] = $i['source']->getMapContentsData(false)->sources[0]; } $i['source'] = $i['source']->getFileContentsInlineMap(false); } $contents = 'window.require = ' . Kwf_Assets_CommonJs_BrowserPack::pack(array_values($commonJsData)); $map = Kwf_SourceMaps_SourceMap::createFromInline($contents); $fileContents = $map->getFileContents(); $fileContents .= ";\n"; $map->setFileContents($fileContents); $data = $map->getMapContentsData(false); unset($data->sourcesContent); //drop fake sourcesContent (see comment above) if ($data->sources[0] == 'node_modules/browser-pack/_prelude.js') { $data->sources[0] = '/assets/web/node_modules/browser-pack/_prelude.js'; } $packageMap->concat($map); } // ***** non-commonjs, css $filterMimeType = $mimeType; if ($filterMimeType == 'text/css; ie8') { $filterMimeType = 'text/css'; } foreach ($this->_getFilteredUniqueDependencies($filterMimeType) as $dep) { if ($dep->getIncludeInPackage()) { if (!(($mimeType == 'text/javascript' || $mimeType == 'text/javascript; defer') && $dep->isCommonJsEntry())) { $map = $this->_getFilteredDependencyContents($dep, $mimeType); $data = $map->getMapContentsData(false); if (isset($data->{'_x_org_koala-framework_trlData'})) { $trlData = array_merge($trlData, $data->{'_x_org_koala-framework_trlData'}); } if (strpos($map->getFileContents(), "//@ sourceMappingURL=") !== false && strpos($map->getFileContents(), "//# sourceMappingURL=") !== false) { throw new Kwf_Exception("contents must not contain sourceMappingURL"); } $sourcesCount = 0; $packageData = $packageMap->getMapContentsData(false); if (isset($packageData->sources)) { $sourcesCount = count($packageData->sources); } unset($packageData); // $ret .= "/* *** $dep */\n"; // attention: commenting this in breaks source maps $packageMap->concat($map); if (isset($data->{'_x_org_koala-framework_sourcesContent'})) { $packageMapData = $packageMap->getMapContentsData(false); if (!isset($packageMapData->{'_x_org_koala-framework_sourcesContent'})) { $packageMapData->{'_x_org_koala-framework_sourcesContent'} = array(); } //copy sourcesContent to packageMap with $sourcesCount offset foreach ($data->{'_x_org_koala-framework_sourcesContent'} as $k => $i) { $packageMapData->{'_x_org_koala-framework_sourcesContent'}[$k + $sourcesCount] = $i; } } } } } if ($mimeType == 'text/javascript' || $mimeType == 'text/javascript; defer') { if ($uniquePrefix = Kwf_Config::getValue('application.uniquePrefix')) { $packageMap = Kwf_Assets_Package_Filter_UniquePrefix::filter($packageMap, $uniquePrefix); } } foreach ($this->getProviderList()->getFilters() as $filter) { if ($filter->getExecuteFor() == Kwf_Assets_Filter_Abstract::EXECUTE_FOR_PACKAGE && $filter->getMimeType() == $mimeType) { $packageMap = $filter->filter($packageMap); } } $data = $packageMap->getMapContentsData(false); $data->sourcesContent = array(); foreach ($data->sources as $k => $i) { if (substr($i, 0, 8) != '/assets/') { throw new Kwf_Exception("Source path doesn't start with /assets/: {$i}"); } $i = substr($i, 8); if (isset($data->{'_x_org_koala-framework_sourcesContent'}[$k])) { $data->sourcesContent[$k] = $data->{'_x_org_koala-framework_sourcesContent'}[$k]; } else { $i = new Kwf_Assets_Dependency_File($this->_providerList, $i); $data->sourcesContent[$k] = $i->getContentsSourceString(); } } return array('contents' => $packageMap, 'trlData' => $trlData); }
public function getContentsPacked($language) { $hash = ''; foreach ($this->_componentDependencies as $dep) { $src = $dep->getContentsSource(); if ($src['type'] == 'file') { $hash .= md5_file($src['file']); } else { if ($src['type'] == 'contents') { $hash .= md5($src['contents']); } else { throw new Kwf_Exception_NotYetImplemented(); } } } $hash = md5($hash); $cacheFile = "cache/componentassets/{$this->_componentClass}" . ($this->usesLanguage() ? "-{$language}" : '') . "-" . Kwf_Config::getValue('application.uniquePrefix') . "-{$hash}"; if (file_exists($cacheFile)) { $ret = Kwf_SourceMaps_SourceMap::createFromInline(file_get_contents($cacheFile)); } else { $ret = Kwf_SourceMaps_SourceMap::createEmptyMap(''); foreach ($this->_componentDependencies as $dep) { $c = $dep->getContentsPacked($language); if (Kwf_Config::getValue('application.uniquePrefix')) { $c->stringReplace('kwcBem--', $this->_getKwcClass() . '--'); $c->stringReplace('kwcBem__', $this->_getKwcClass() . '__'); } else { $c->stringReplace('kwcBem--', ''); $c->stringReplace('kwcBem__', ''); } $c->stringReplace('.kwcClass', '.' . $this->_getKwcClass()); $ret->concat($c); } file_put_contents($cacheFile, $ret->getFileContentsInlineMap()); } return $ret; }
public function getPackageContents($mimeType, $language, $includeSourceMapComment = true) { if (!Kwf_Assets_BuildCache::getInstance()->building && !Kwf_Config::getValue('assets.lazyBuild')) { if (Kwf_Exception_Abstract::isDebug()) { //proper error message on development server throw new Kwf_Exception("Building assets is disabled (assets.lazyBuild). Please upload build contents."); } else { throw new Kwf_Exception_NotFound(); } } $packageMap = Kwf_SourceMaps_SourceMap::createEmptyMap(''); if ($mimeType == 'text/javascript') { $ext = 'js'; } else { if ($mimeType == 'text/javascript; defer') { $ext = 'defer.js'; } else { if ($mimeType == 'text/css') { $ext = 'css'; } else { if ($mimeType == 'text/css; media=print') { $ext = 'printcss'; } } } } $packageMap->setFile($this->getPackageUrl($ext, $language)); $maxMTime = 0; $commonJsData = array(); $commonJsDeps = array(); foreach ($this->_getFilteredUniqueDependencies($mimeType) as $i) { if ($i->getIncludeInPackage()) { if (($mimeType == 'text/javascript' || $mimeType == 'text/javascript') && $i->isCommonJsEntry()) { $c = $i->getContentsPacked($language)->getFileContentsInlineMap(false); $commonJsDeps = $this->_getCommonJsDeps($i, $language); $commonJsData[$i->__toString()] = array('id' => $i->__toString(), 'source' => $c, 'sourceFile' => $i->__toString(), 'deps' => $commonJsDeps['deps'], 'entry' => true); foreach ($commonJsDeps['data'] as $k => $j) { if (!isset($commonJsData[$k])) { $commonJsData[$k] = $j; } } } else { $map = $i->getContentsPacked($language); if (strpos($map->getFileContents(), "//@ sourceMappingURL=") !== false && strpos($map->getFileContents(), "//# sourceMappingURL=") !== false) { throw new Kwf_Exception("contents must not contain sourceMappingURL"); } foreach ($map->getMapContentsData(false)->sources as &$s) { $s = '/assets/' . $s; } // $ret .= "/* *** $i */\n"; // attention: commenting this in breaks source maps $packageMap->concat($map); } } $mTime = $i->getMTime(); if ($mTime) { $maxMTime = max($maxMTime, $mTime); } } if ($commonJsData) { if ($mimeType == 'text/javascript; defer') { //in defer.js don't include deps that are already loaded in non-defer foreach ($this->_getFilteredUniqueDependencies('text/javascript') as $i) { $commonJsDeps = $this->_getCommonJsDeps($i, $language); foreach (array_keys($commonJsDeps['data']) as $key) { if (isset($commonJsData[$key])) { unset($commonJsData[$key]); } } $c = $i->getContentsPacked($language)->getFileContentsInlineMap(false); $commonJsData[$i->__toString()] = array('id' => $i->__toString(), 'source' => $c, 'sourceFile' => $i->__toString(), 'deps' => $commonJsDeps['deps'], 'entry' => true); } } $contents = 'window.require = ' . Kwf_Assets_CommonJs_BrowserPack::pack(array_values($commonJsData)); $map = Kwf_SourceMaps_SourceMap::createFromInline($contents); $packageMap->concat($map); } if ($mimeType == 'text/javascript' || $mimeType == 'text/javascript; defer') { if ($uniquePrefix = Kwf_Config::getValue('application.uniquePrefix')) { $packageMap = Kwf_Assets_Package_Filter_UniquePrefix::filter($packageMap, $uniquePrefix); } } if ($includeSourceMapComment) { $contents = $packageMap->getFileContents(); if ($mimeType == 'text/javascript') { $ext = 'js'; } else { if ($mimeType == 'text/javascript; defer') { $ext = 'defer.js'; } else { if ($mimeType == 'text/css') { $ext = 'css'; } else { if ($mimeType == 'text/css; media=print') { $ext = 'printcss'; } else { throw new Kwf_Exception_NotYetImplemented(); } } } } if ($ext == 'js' || $ext == 'defer.js') { $contents .= "\n//# sourceMappingURL=" . $this->getPackageUrl($ext . '.map', $language) . "\n"; } else { if ($ext == 'css' || $ext == 'printcss') { $contents .= "\n/*# sourceMappingURL=" . $this->getPackageUrl($ext . '.map', $language) . " */\n"; } } $packageMap->setFileContents($contents); } return $packageMap; }