Skip to content

Commit

Permalink
Merge branch 'release/1.0.4' into v1
Browse files Browse the repository at this point in the history
  • Loading branch information
khalwat committed Sep 28, 2018
2 parents bf0b37f + 267f63e commit 32b1a40
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 35 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Twigpack Changelog

## 1.0.4 - 2018-09-28
### Added
* Added `this.onload=null;` to async CSS link tag
* Added `craft.twigpack.includeCssRelPreloadPolyfill()`

### Changed
* Better error reporting if modules don't exist in the manifest

## 1.0.3 - 2018-09-24
### Changed
* Allow the `manifestPath` to be a file system path or a URI

## 1.0.2 - 2018-09-23
### Added
* Added `getModuleUri()` function
Expand Down
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,25 @@ You can also include a second optional parameter, to determine whether the CSS s
This will output:

```html
<link rel="preload" href="/css/style.sfkjsf734ashf.css" as="style" onload="this.rel='stylesheet'" />
<link rel="preload" href="/css/style.sfkjsf734ashf.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript><link rel="stylesheet" href="/css/style.sfkjsf734ashf.css"></noscript>
```

There is a `link rel=preload` polyfill that you can include on the page via:

`{{ craft.twigpack.includeCssRelPreloadPolyfill() }}`

This will output:
```html
<script>
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
!function(t){"use strict";t.loadCSS||(t.loadCSS=function(){});var e=loadCSS.relpreload={};if(e.support=function(){var e;try{e=t.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),e.bindMediaToggle=function(t){var e=t.media||"all";function a(){t.media=e}t.addEventListener?t.addEventListener("load",a):t.attachEvent&&t.attachEvent("onload",a),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(a,3e3)},e.poly=function(){if(!e.support())for(var a=t.document.getElementsByTagName("link"),n=0;n<a.length;n++){var o=a[n];"preload"!==o.rel||"style"!==o.getAttribute("as")||o.getAttribute("data-loadcss")||(o.setAttribute("data-loadcss",!0),e.bindMediaToggle(o))}},!e.support()){e.poly();var a=t.setInterval(e.poly,500);t.addEventListener?t.addEventListener("load",function(){e.poly(),t.clearInterval(a)}):t.attachEvent&&t.attachEvent("onload",function(){e.poly(),t.clearInterval(a)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:t.loadCSS=loadCSS}("undefined"!=typeof global?global:this);
</script>
```

...as per [How To Use loadCSS (Recommended example)
](https://github.com/filamentgroup/loadCSS#how-to-use-loadcss-recommended-example). You'll want to include this once on the page, after you do `{{ craft.twigpack.includeCssModule("style.css", true) }}`. It's only if you're doing async CSS loading, and need to support older browsers via the polyfill.

### Including JavaScript

To include a versioned JavaScript module in your templates, do:
Expand Down Expand Up @@ -193,7 +208,7 @@ This will output:
</script>
```

...as per the [safari-nomodule.js Gist](https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc). You'll want to include this one on the page, before you do `{{ craft.twigpack.includeJsModule("app.js", true) }}`. It's only necessary if you're using legacy/modern JavaScript bundles.
...as per the [safari-nomodule.js Gist](https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc). You'll want to include this once on the page, before you do `{{ craft.twigpack.includeJsModule("app.js", true) }}`. It's only necessary if you're using legacy/modern JavaScript bundles.

### Getting a Module URI

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "nystudio107/craft-twigpack",
"description": "Twigpack is a bridge between Twig and webpack, with manifest.json & webpack-dev-server HMR support",
"type": "craft-plugin",
"version": "1.0.2",
"version": "1.0.4",
"keywords": [
"craftcms",
"craft-plugin",
Expand Down
78 changes: 53 additions & 25 deletions src/helpers/Manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ public static function getCssModuleTags(array $config, string $moduleName, bool
{
$legacyModule = self::getModule($config, $moduleName, 'legacy');
if ($legacyModule === null) {
return null;
return '';
}
$lines = [];
if ($async) {
$lines[] = "<link rel=\"preload\" href=\"{$legacyModule}\" as=\"style\" onload=\"this.rel='stylesheet'\" />";
$lines[] = "<link rel=\"preload\" href=\"{$legacyModule}\" as=\"style\" onload=\"this.onload=null;this.rel='stylesheet'\" />";
$lines[] = "<noscript><link rel=\"stylesheet\" href=\"{$legacyModule}\"></noscript>";
} else {
$lines[] = "<link rel=\"stylesheet\" href=\"{$legacyModule}\" />";
Expand All @@ -70,6 +70,22 @@ public static function getCssModuleTags(array $config, string $moduleName, bool
return implode("\r\n", $lines);
}

/**
* Returns the uglified loadCSS rel=preload Polyfill as per:
* https://github.com/filamentgroup/loadCSS#how-to-use-loadcss-recommended-example
*
* @return string
*/
public static function getCssRelPreloadPolyfill(): string
{
return <<<EOT
<script>
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
!function(t){"use strict";t.loadCSS||(t.loadCSS=function(){});var e=loadCSS.relpreload={};if(e.support=function(){var e;try{e=t.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),e.bindMediaToggle=function(t){var e=t.media||"all";function a(){t.media=e}t.addEventListener?t.addEventListener("load",a):t.attachEvent&&t.attachEvent("onload",a),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(a,3e3)},e.poly=function(){if(!e.support())for(var a=t.document.getElementsByTagName("link"),n=0;n<a.length;n++){var o=a[n];"preload"!==o.rel||"style"!==o.getAttribute("as")||o.getAttribute("data-loadcss")||(o.setAttribute("data-loadcss",!0),e.bindMediaToggle(o))}},!e.support()){e.poly();var a=t.setInterval(e.poly,500);t.addEventListener?t.addEventListener("load",function(){e.poly(),t.clearInterval(a)}):t.attachEvent&&t.attachEvent("onload",function(){e.poly(),t.clearInterval(a)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:t.loadCSS=loadCSS}("undefined"!=typeof global?global:this);
</script>
EOT;
}

/**
* @param array $config
* @param string $moduleName
Expand All @@ -82,12 +98,12 @@ public static function getJsModuleTags(array $config, string $moduleName, bool $
{
$legacyModule = self::getModule($config, $moduleName, 'legacy');
if ($legacyModule === null) {
return null;
return '';
}
if ($async) {
$modernModule = self::getModule($config, $moduleName, 'modern');
if ($modernModule === null) {
return null;
return '';
}
}
$lines = [];
Expand Down Expand Up @@ -148,6 +164,16 @@ public static function getModule(array $config, string $moduleName, string $type
// Get the manifest file
$manifest = self::getManifestFile($config, $isHot, $type);
if ($manifest !== null) {
// Make sure it exists in the manifest
if ($manifest[$moduleName] === null) {
self::reportError(Craft::t(
'twigpack',
'Module does not exist in the manifest: {moduleName}',
['moduleName' => $moduleName]
));

return null;
}
$module = $manifest[$moduleName];
$prefix = $isHot
? $config['devServer']['publicPath']
Expand Down Expand Up @@ -192,30 +218,17 @@ public static function getManifestFile(array $config, bool &$isHot, string $type
$manifest = self::getJsonFileFromUri($path);
// If the manifest isn't found, and it was hot, fall back on non-hot
if ($manifest === null) {
Craft::error(
Craft::t(
'twigpack',
'Manifest file not found at: {manifestPath}',
['manifestPath' => $manifestPath]
),
__METHOD__
);
// We couldn't find a manifest; throw an error
self::reportError(Craft::t(
'twigpack',
'Manifest file not found at: {manifestPath}',
['manifestPath' => $manifestPath]
), true);
if ($isHot) {
// Try again, but not with home module replacement
$isHot = false;
} else {
$devMode = Craft::$app->getConfig()->getGeneral()->devMode;
if ($devMode) {
// We couldn't find a manifest; throw an error
throw new NotFoundHttpException(
Craft::t(
'twigpack',
'Manifest file not found at: {manifestPath}',
['manifestPath' => $manifestPath]
)
);
}

// Give up and return null
return null;
}
}
Expand Down Expand Up @@ -247,7 +260,7 @@ public static function invalidateCaches()
protected static function getJsonFileFromUri(string $path)
{
// Make sure it's a full URL
if (!UrlHelper::isAbsoluteUrl($path)) {
if (!UrlHelper::isAbsoluteUrl($path) && !is_file($path)) {
try {
$path = UrlHelper::siteUrl($path);
} catch (Exception $e) {
Expand Down Expand Up @@ -335,4 +348,19 @@ protected static function combinePaths(string ...$paths): string

return implode('/', $paths);
}

/**
* @param string $error
* @param bool $soft
*
* @throws NotFoundHttpException
*/
protected static function reportError(string $error, $soft = false)
{
$devMode = Craft::$app->getConfig()->getGeneral()->devMode;
if ($devMode && !$soft) {
throw new NotFoundHttpException($error);
}
Craft::error($error, __METHOD__);
}
}
15 changes: 13 additions & 2 deletions src/services/Manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ public function getCssModuleTags(string $moduleName, bool $async = false, $confi
return ManifestHelper::getCssModuleTags($config, $moduleName, $async);
}

/**
* Returns the uglified loadCSS rel=preload Polyfill as per:
* https://github.com/filamentgroup/loadCSS#how-to-use-loadcss-recommended-example
*
* @return string
*/
public function getCssRelPreloadPolyfill(): string
{
return ManifestHelper::getCssRelPreloadPolyfill();
}

/**
* Return the HTML tags to include the JavaScript module
*
Expand All @@ -67,9 +78,9 @@ public function getJsModuleTags(string $moduleName, bool $async = false, $config
/**
* Return the Safari 10.1 nomodule JavaScript fix
*
* @return null|string
* @return string
*/
public function getSafariNomoduleFix()
public function getSafariNomoduleFix(): string
{
return ManifestHelper::getSafariNomoduleFix();
}
Expand Down
8 changes: 5 additions & 3 deletions src/translations/en/twigpack.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
/**
* Twigpack plugin for Craft CMS 3.x
*
* Twigpack is the conduit between Twig and webpack, with manifest.json & webpack-dev-server HMR support
* Twigpack is the conduit between Twig and webpack, with manifest.json &
* webpack-dev-server HMR support
*
* @link https://nystudio107.com/
* @copyright Copyright (c) 2018 nystudio107
Expand All @@ -15,6 +16,7 @@
*/
return [
'Twigpack Manifest Cache' => 'Twigpack Manifest Cache',
'{name} plugin loaded' => '{name} plugin loaded',
'Manifest file not found at: {manifestPath}' => 'Manifest file not found at: {manifestPath}'
'{name} plugin loaded' => '{name} plugin loaded',
'Manifest file not found at: {manifestPath}' => 'Manifest file not found at: {manifestPath}',
'Module does not exist in the manifest: {moduleName}' => 'Module does not exist in the manifest: {moduleName}',
];
18 changes: 16 additions & 2 deletions src/variables/ManifestVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
/**
* Twigpack plugin for Craft CMS 3.x
*
* Twigpack is the conduit between Twig and webpack, with manifest.json & webpack-dev-server HMR support
* Twigpack is the conduit between Twig and webpack, with manifest.json &
* webpack-dev-server HMR support
*
* @link https://nystudio107.com/
* @copyright Copyright (c) 2018 nystudio107
Expand Down Expand Up @@ -39,6 +40,19 @@ public function includeCssModule(string $moduleName, bool $async = false, $confi
);
}

/**
* Returns the uglified loadCSS rel=preload Polyfill as per:
* https://github.com/filamentgroup/loadCSS#how-to-use-loadcss-recommended-example
*
* @return string
*/
public static function includeCssRelPreloadPolyfill(): string
{
return Template::raw(
Twigpack::$plugin->manifest->getCssRelPreloadPolyfill()
);
}

/**
* @param string $moduleName
* @param bool $async
Expand Down Expand Up @@ -74,7 +88,7 @@ public function getModuleUri(string $moduleName, string $type = 'modern', $confi
/**
* Include the Safari 10.1 nomodule fix JavaScript
*
* @return null|\Twig_Markup
* @return \Twig_Markup
*/
public function includeSafariNomoduleFix(): \Twig_Markup
{
Expand Down

0 comments on commit 32b1a40

Please sign in to comment.