From 5771dac3c9827062037bc1f9fbb5a76ad82b8a6c Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 8 May 2015 19:26:36 +0200 Subject: [PATCH] Add support for favicon and apple-touch-icon Fixes #28 --- CHANGES.md | 4 ++ README.md | 21 +++++++ default_index.html | 6 ++ index.js | 39 +++++++++++++ package.json | 2 + spec/HtmlWebpackPluginSpec.js | 85 +++++++++++++++++++++++++++++ spec/fixtures/apple-touch-icon.png | Bin 0 -> 3959 bytes spec/fixtures/appleTouchIcon.js | 1 + spec/fixtures/favicon.ico | Bin 0 -> 766 bytes spec/fixtures/favicon.js | 1 + 10 files changed, 159 insertions(+) create mode 100755 spec/fixtures/apple-touch-icon.png create mode 100644 spec/fixtures/appleTouchIcon.js create mode 100755 spec/fixtures/favicon.ico create mode 100644 spec/fixtures/favicon.js diff --git a/CHANGES.md b/CHANGES.md index 19eed1e..d16fd67 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,10 @@ Change History ============== +HEAD +---- +* Add `favicon.ico` and `apple-touch-icon.png` to the HTML + v1.2.0 ------ * Set charset using HTML5 meta attribute diff --git a/README.md b/README.md index c7765f3..e45f80c 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,27 @@ If you have any css assets in webpack's output (for example, css extracted with the [ExtractTextPlugin](https://github.com/webpack/extract-text-webpack-plugin)) then these will be included with `` tags in the HTML head. +Icons - Favicon & Apple Touch Icon +---------------------------------- + +The plugin will automatically pick up if there is a file named `favicon.ico` +or `apple-touch-icon.png` included in the build, and automatically add them +to the HTML. + +```html + + + + + Webpack App + + + + + + + +``` Configuration ------------- diff --git a/default_index.html b/default_index.html index 2dd1749..9bad69a 100644 --- a/default_index.html +++ b/default_index.html @@ -3,6 +3,12 @@ {%=o.htmlWebpackPlugin.options.title || 'Webpack App'%} + {% if (o.htmlWebpackPlugin.files.favicon) { %} + + {% } %} + {% if (o.htmlWebpackPlugin.files.appleTouchIcon) { %} + + {% } %} {% for (var css in o.htmlWebpackPlugin.files.css) { %} {% } %} diff --git a/index.js b/index.js index e9245da..1d87618 100644 --- a/index.js +++ b/index.js @@ -70,6 +70,32 @@ HtmlWebpackPlugin.prototype.emitHtml = function(compilation, htmlTemplateContent }; }; +HtmlWebpackPlugin.prototype.getAssetPathFromModuleName = function(publicPath, modules) { + var filenameRegexp = [/^favicon\.ico($|\?)/, /^apple-touch-icon\.png($|\?)/]; + + return _.chain(modules) + .filter(function (module) { + // If the module failed to load, skip it to properly propagate the error + if (module.failed) { + return false; + } + + var basename = path.basename(module.name); + return _.some(filenameRegexp, function(regexp) { + return regexp.test(basename); + }); + }) + .map(function (module) { + // If the assets is not base64-encoded + if (module.assets.length) { + return [path.parse(module.name).name, publicPath + module.assets[0]]; + } + + return [path.parse(module.name).name, module.source.substring(18, module.source.length - 1)]; + }) + .zipObject() + .value(); +}; HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function(compilation, webpackStatsJson, includedChunks, excludedChunks) { var self = this; @@ -148,6 +174,11 @@ HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function(compilation, webp // requires the same css. assets.css = _.uniq(assets.css); + assets.extraFiles = self.getAssetPathFromModuleName(publicPath, webpackStatsJson.modules); + + assets.favicon = assets.extraFiles.favicon; + assets.appleTouchIcon = assets.extraFiles['apple-touch-icon']; + return assets; }; @@ -173,6 +204,14 @@ HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function(html, templateParams styles = styles.map(function(stylePath) { return ''; }); + // If there is an apple touch icon present, add it above any link-tags + if (assets.appleTouchIcon) { + styles.unshift(''); + } + // If there is a favicon present, add it above any link-tags + if (assets.favicon) { + styles.unshift(''); + } // Append scripts to body element html = html.replace(/(<\/body>)/i, function (match) { return scripts.join('') + match; diff --git a/package.json b/package.json index 09be008..bb62da2 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,12 @@ "devDependencies": { "css-loader": "^0.12.0", "extract-text-webpack-plugin": "^0.7.1", + "file-loader": "^0.8.1", "jasmine-node": "^1.14.5", "jshint": "^2.7.0", "rimraf": "^2.3.3", "style-loader": "^0.12.2", + "url-loader": "^0.5.5", "webpack": "^1.8.11" }, "dependencies": { diff --git a/spec/HtmlWebpackPluginSpec.js b/spec/HtmlWebpackPluginSpec.js index d6c1a5c..a7f2af7 100644 --- a/spec/HtmlWebpackPluginSpec.js +++ b/spec/HtmlWebpackPluginSpec.js @@ -486,4 +486,89 @@ describe('HtmlWebpackPlugin', function() { /