diff --git a/lib/Builder.php b/lib/Builder.php index eefd02d..2c1426f 100644 --- a/lib/Builder.php +++ b/lib/Builder.php @@ -113,8 +113,45 @@ public function outputByPackage($glue = "\n\n"){ } protected function _output($modules, $glue = "\n\n"){ + $modules = array_values($modules); $code = array(); - foreach ($modules as $module){ + $urls = array(); + $deps = array(); + $mods = array(); + + foreach ($modules as $module) { + $urls[$module['id']] = $module['url']; + $mods[$module['url']] = $module; + $deps[$module['url']] = array(); + } + + foreach ($mods as $module) { + foreach ($module['dependencies'] as $dependency) { + if (isset($urls[$dependency])) { + $deps[$module['url']][] = $urls[$dependency]; + } + } + } + + function calc_deps(&$results, $deps, $url = null) { + $is_root = empty($url); + $list = $is_root ? $deps : $deps[$url]; + + foreach ($list as $key => $val) { + $target = $is_root ? $key : $val; + calc_deps($results, $deps, $target); + + if (!in_array($target, $results)) { + $results[] = $target; + } + } + }; + + $orders = array(); + calc_deps($orders, $deps); + + foreach ($orders as $url){ + $module = $mods[$url]; if (empty($module['content']) && !empty($module['url'])){ $module['content'] = file_get_contents($module['url']); } diff --git a/lib/Packager.php b/lib/Packager.php index 5588442..fb9abc5 100644 --- a/lib/Packager.php +++ b/lib/Packager.php @@ -17,7 +17,7 @@ public function __construct(){ } /** - * Sets the base path where ->req() and ->addAlias methos are relative to + * Sets the base path where ->req() and ->addAlias methods are relative to * If the baseurl is not set, it will default to the directory of this * Packager.php file * @@ -25,7 +25,7 @@ public function __construct(){ * @return Packager */ public function setBaseUrl($url){ - $this->_baseurl = $url; + $this->_baseurl = str_replace(DIRECTORY_SEPARATOR, '/', $url); return $this; } @@ -90,24 +90,30 @@ protected function _req($id){ if (strpos($id, '!') !== false) return; $filename = $id; + $package = ''; $extension = Path::extname($filename); $amd = !in_array($extension, array('.js', '.css'/* more? */)); - if ($amd) $filename .= '.js'; - $package = ''; - foreach ($this->_alias as $alias => $url){ - if ($id == $alias){ - $filename = $url; - } else { - $len = strlen($alias); - if (substr($filename, 0, $len) == $alias){ - $filename = Path::resolve($url, substr($filename, $len + 1)); - $package = $alias; + if (!preg_match('/^(\/|\.\/|\.\.\/)/', $filename)) { + $syms = explode('/', $filename); + for ($i = count($syms); $i > 0; $i--) { + $path = join('/', array_slice($syms, 0, $i)); + if (isset($this->_alias[$path])) { + $package = $path; + if ($path = $this->_alias[$path]) { + if ($path == 'empty:') return; // exclude this module + array_splice($syms, 0, $i, $path); // replace matched + } else { + array_splice($syms, 0, $i); // delete matched + } break; } } + $filename = implode('/', $syms); } + if ($amd) $filename .= '.js'; + $filename = Path::resolve($this->_baseurl, $filename); if (isset($this->_files[$filename])) return;