From 302b7cb45b50e3181a3e2d05626dc0600fb77905 Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Tue, 19 May 2015 13:05:01 -0400 Subject: [PATCH 01/25] Initial commit --- .gitignore | 27 +++++++++++++++++++++++++++ LICENSE | 22 ++++++++++++++++++++++ README.md | 1 + 3 files changed, 50 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..123ae94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b464b78 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 fog-glory + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..417a631 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# fog-glory From 21016670dd1f04737e1e1e3d7cf62cca67006e91 Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Sun, 24 May 2015 14:38:43 -0400 Subject: [PATCH 02/25] basic plugin interface --- bundle.js | 56 +++++++++++++++++++++++++++++++++++++++++++++++ content.js | 1 + entry.js | 1 + index.html | 8 +++++++ plugin | 1 + webpack.config.js | 17 ++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 bundle.js create mode 100644 content.js create mode 100644 entry.js create mode 100644 index.html create mode 160000 plugin create mode 100644 webpack.config.js diff --git a/bundle.js b/bundle.js new file mode 100644 index 0000000..797ba1a --- /dev/null +++ b/bundle.js @@ -0,0 +1,56 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + document.write(__webpack_require__(1)); + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = "It works from content.js."; + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/content.js b/content.js new file mode 100644 index 0000000..73c0056 --- /dev/null +++ b/content.js @@ -0,0 +1 @@ +module.exports = "It works from content.js."; \ No newline at end of file diff --git a/entry.js b/entry.js new file mode 100644 index 0000000..c62dce6 --- /dev/null +++ b/entry.js @@ -0,0 +1 @@ +document.write(require("./content.js")); \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..da9edba --- /dev/null +++ b/index.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/plugin b/plugin new file mode 160000 index 0000000..f2caf94 --- /dev/null +++ b/plugin @@ -0,0 +1 @@ +Subproject commit f2caf94e9ffb80e3bab80ffcf5f4baba0e3d7340 diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..62ac378 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,17 @@ +var DemoPlugin = require('./plugin/index'); +var path = require('path'); + +module.exports = { + entry: "./entry.js", + output: { + path: __dirname, + filename: "bundle.js" + }, + + plugins: [ + new DemoPlugin(path.join(__dirname), { + chunkModules: true, + }) + ] + +}; \ No newline at end of file From 5585799fda4818953d7c388bdf7097a13a90876c Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Sun, 24 May 2015 14:52:11 -0400 Subject: [PATCH 03/25] deleted plugin folder, placed plugin.js in root --- plugin | 1 - plugin.js | 21 +++++++++++++++++++++ webpack.config.js | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) delete mode 160000 plugin create mode 100644 plugin.js diff --git a/plugin b/plugin deleted file mode 160000 index f2caf94..0000000 --- a/plugin +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f2caf94e9ffb80e3bab80ffcf5f4baba0e3d7340 diff --git a/plugin.js b/plugin.js new file mode 100644 index 0000000..f298439 --- /dev/null +++ b/plugin.js @@ -0,0 +1,21 @@ +var fs = require('fs'); + +var DemoPlugin = function(output, options) { + this.output = output; + this.options = options; + + console.log('hi from constructor'); + +}; + +module.exports = DemoPlugin; + +DemoPlugin.prototype.apply = function(compiler) { + + compiler.plugin('compile', function(params) { + console.log('hi from compiler'); + + + }); +}; + diff --git a/webpack.config.js b/webpack.config.js index 62ac378..11e9137 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,4 +1,4 @@ -var DemoPlugin = require('./plugin/index'); +var DemoPlugin = require('./plugin.js'); var path = require('path'); module.exports = { From 3e1551a89f4be44fbe30d3d8963e8c7980a1949c Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Sun, 24 May 2015 15:38:00 -0400 Subject: [PATCH 04/25] plugin accesses source js --- content.js | 2 +- plugin.js | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/content.js b/content.js index 73c0056..469c626 100644 --- a/content.js +++ b/content.js @@ -1 +1 @@ -module.exports = "It works from content.js."; \ No newline at end of file +module.exports = "It works from content.js."; diff --git a/plugin.js b/plugin.js index f298439..f5a0a83 100644 --- a/plugin.js +++ b/plugin.js @@ -12,10 +12,18 @@ module.exports = DemoPlugin; DemoPlugin.prototype.apply = function(compiler) { - compiler.plugin('compile', function(params) { - console.log('hi from compiler'); + compiler.plugin('compilation', function(compilation) { + compilation.plugin("optimize-chunk-assets", function(chunks, callback) { + var modules = []; - }); -}; + chunks.forEach(function(chunk) { + chunk.modules.forEach(function(module) { + modules.push(module._source); + }); + });//end chunks.forEach + console.log(modules); + })//end compilation.plugin + });//end compiler.plugin +}; \ No newline at end of file From 41a5df3faa32c4d9aa735204d16e5eead1ac4dda Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Sun, 24 May 2015 17:38:27 -0400 Subject: [PATCH 05/25] added style.css and package.json --- entry.js | 1 + package.json | 28 ++++++++++++++++++++++++++++ plugin.js | 5 +---- style.css | 3 +++ webpack.config.js | 5 ++++- 5 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 package.json create mode 100644 style.css diff --git a/entry.js b/entry.js index c62dce6..d58c14b 100644 --- a/entry.js +++ b/entry.js @@ -1 +1,2 @@ +require("!style!css!./style.css"); document.write(require("./content.js")); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..1817ff6 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "fog-glory", + "version": "1.0.0", + "description": "uncss plugin for webpack", + "main": "bundle.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/fog-glory/fog-glory.git" + }, + "keywords": [ + "webpack", + "uncss", + "plugin" + ], + "author": "kenny matt phoebe", + "license": "ISC", + "bugs": { + "url": "https://github.com/fog-glory/fog-glory/issues" + }, + "homepage": "https://github.com/fog-glory/fog-glory", + "dependencies": { + "css-loader": "^0.14.2", + "style-loader": "^0.12.3" + } +} diff --git a/plugin.js b/plugin.js index f5a0a83..4af230d 100644 --- a/plugin.js +++ b/plugin.js @@ -3,9 +3,6 @@ var fs = require('fs'); var DemoPlugin = function(output, options) { this.output = output; this.options = options; - - console.log('hi from constructor'); - }; module.exports = DemoPlugin; @@ -19,7 +16,7 @@ DemoPlugin.prototype.apply = function(compiler) { chunks.forEach(function(chunk) { chunk.modules.forEach(function(module) { - modules.push(module._source); + modules.push(module._source._value); }); });//end chunks.forEach console.log(modules); diff --git a/style.css b/style.css new file mode 100644 index 0000000..0329bde --- /dev/null +++ b/style.css @@ -0,0 +1,3 @@ +body { + background: yellow; +} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 11e9137..b6283b6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,7 +7,10 @@ module.exports = { path: __dirname, filename: "bundle.js" }, - + loaders: [{ + test: /\.css$/, + loader: "style!css" + }], plugins: [ new DemoPlugin(path.join(__dirname), { chunkModules: true, From 4d23d2152b58ad2e12c171d5becc2bfdc6cdf26f Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Sun, 24 May 2015 18:46:37 -0400 Subject: [PATCH 06/25] updated plugin.js w/ roadmap --- bundle.js | 10 +++------- content.js | 4 +++- entry.js | 1 + plugin.js | 23 +++++++++++++---------- style2.css | 3 +++ webpack.config.js | 1 + 6 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 style2.css diff --git a/bundle.js b/bundle.js index 797ba1a..f02dc5b 100644 --- a/bundle.js +++ b/bundle.js @@ -44,13 +44,9 @@ /* 0 */ /***/ function(module, exports, __webpack_require__) { - document.write(__webpack_require__(1)); - -/***/ }, -/* 1 */ -/***/ function(module, exports, __webpack_require__) { - - module.exports = "It works from content.js."; + __webpack_require__(null); + __webpack_require__(null); + document.write(__webpack_require__(null)); /***/ } /******/ ]); \ No newline at end of file diff --git a/content.js b/content.js index 469c626..8195cba 100644 --- a/content.js +++ b/content.js @@ -1 +1,3 @@ -module.exports = "It works from content.js."; +module.exports = "It works from content.js."; + +console.log('some stuff'); diff --git a/entry.js b/entry.js index d58c14b..a9eb919 100644 --- a/entry.js +++ b/entry.js @@ -1,2 +1,3 @@ require("!style!css!./style.css"); +require("!style!css!./style2.css"); document.write(require("./content.js")); \ No newline at end of file diff --git a/plugin.js b/plugin.js index 4af230d..518b4ef 100644 --- a/plugin.js +++ b/plugin.js @@ -11,16 +11,19 @@ DemoPlugin.prototype.apply = function(compiler) { compiler.plugin('compilation', function(compilation) { - compilation.plugin("optimize-chunk-assets", function(chunks, callback) { - var modules = []; + compilation.plugin("optimize-modules", function(modules) { + //iterate over modules + //check if filepath ends in css + //split at ! and fs + //concat file path to css array + //check if module is first css + //if not, splice out module + //check if filepath does not contain node_modules + //concat path to content array + //pass css and content array into kenny's function + //store result in uncss string + //go back to first css module and splice in our code - chunks.forEach(function(chunk) { - chunk.modules.forEach(function(module) { - modules.push(module._source._value); - }); - });//end chunks.forEach - console.log(modules); - })//end compilation.plugin + }); //end compiler.plugin - });//end compiler.plugin }; \ No newline at end of file diff --git a/style2.css b/style2.css new file mode 100644 index 0000000..c489d30 --- /dev/null +++ b/style2.css @@ -0,0 +1,3 @@ +body { + background: red; +} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index b6283b6..7125919 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,7 @@ var DemoPlugin = require('./plugin.js'); var path = require('path'); + module.exports = { entry: "./entry.js", output: { From 0dd3d65dece0165095cf81cc744c62b94d7024ca Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Sun, 24 May 2015 19:22:21 -0400 Subject: [PATCH 07/25] update roadmap in plugin.js to compare each css individually --- plugin.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugin.js b/plugin.js index 518b4ef..15037bd 100644 --- a/plugin.js +++ b/plugin.js @@ -16,13 +16,11 @@ DemoPlugin.prototype.apply = function(compiler) { //check if filepath ends in css //split at ! and fs //concat file path to css array - //check if module is first css - //if not, splice out module //check if filepath does not contain node_modules //concat path to content array //pass css and content array into kenny's function - //store result in uncss string - //go back to first css module and splice in our code + //store results in uncss array + //update css modules accordingly }); //end compiler.plugin From adbe3e5b40090fe2d4f02a8865a8e479260ff62b Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Tue, 26 May 2015 16:29:58 -0400 Subject: [PATCH 08/25] integrated plugin w/ purify css module --- .floo | 3 + .flooignore | 8 ++ bundle.js | 362 ++++++++++++++++++++++++++++++++++++++++++++++++++- content.js | 2 +- package.json | 4 + plugin.js | 51 ++++++-- style.css | 9 ++ style2.css | 16 +++ 8 files changed, 442 insertions(+), 13 deletions(-) create mode 100644 .floo create mode 100644 .flooignore diff --git a/.floo b/.floo new file mode 100644 index 0000000..de25524 --- /dev/null +++ b/.floo @@ -0,0 +1,3 @@ +{ + "url": "https://floobits.com/HackReactor/fog-glory-plugin" +} \ No newline at end of file diff --git a/.flooignore b/.flooignore new file mode 100644 index 0000000..8c380e3 --- /dev/null +++ b/.flooignore @@ -0,0 +1,8 @@ +#* +*.o +*.pyc +*~ +extern/ +node_modules/ +tmp +vendor/ \ No newline at end of file diff --git a/bundle.js b/bundle.js index f02dc5b..ce32d1a 100644 --- a/bundle.js +++ b/bundle.js @@ -44,9 +44,365 @@ /* 0 */ /***/ function(module, exports, __webpack_require__) { - __webpack_require__(null); - __webpack_require__(null); - document.write(__webpack_require__(null)); + __webpack_require__(1); + __webpack_require__(5); + document.write(__webpack_require__(7)); + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + // style-loader: Adds some css to the DOM by adding a tag + + // load the styles + var content = __webpack_require__(2); + if(typeof content === 'string') content = [[module.id, content, '']]; + // add the styles to the DOM + var update = __webpack_require__(4)(content, {}); + if(content.locals) module.exports = content.locals; + // Hot Module Replacement + if(false) { + // When the styles change, update the tags + if(!content.locals) { + module.hot.accept("!!./node_modules/css-loader/index.js!./style.css", function() { + var newContent = require("!!./node_modules/css-loader/index.js!./style.css"); + if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; + update(newContent); + }); + } + // When the module is disposed, remove the tags + module.hot.dispose(function() { update(); }); + } + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + exports = module.exports = __webpack_require__(3)(); + exports.push([module.id, "body {\n background: yellow;\n}\np{\n background: green;\n}\n", ""]); + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + /* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra + */ + // css base code, injected by the css-loader + module.exports = function() { + var list = []; + + // return the list of modules as css string + list.toString = function toString() { + var result = []; + for(var i = 0; i < this.length; i++) { + var item = this[i]; + if(item[2]) { + result.push("@media " + item[2] + "{" + item[1] + "}"); + } else { + result.push(item[1]); + } + } + return result.join(""); + }; + + // import a list of modules into the list + list.i = function(modules, mediaQuery) { + if(typeof modules === "string") + modules = [[null, modules, ""]]; + var alreadyImportedModules = {}; + for(var i = 0; i < this.length; i++) { + var id = this[i][0]; + if(typeof id === "number") + alreadyImportedModules[id] = true; + } + for(i = 0; i < modules.length; i++) { + var item = modules[i]; + // skip already imported module + // this implementation is not 100% perfect for weird media query combinations + // when a module is imported multiple times with different media queries. + // I hope this will never occur (Hey this way we have smaller bundles) + if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { + if(mediaQuery && !item[2]) { + item[2] = mediaQuery; + } else if(mediaQuery) { + item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; + } + list.push(item); + } + } + }; + return list; + }; + + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + /* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra + */ + var stylesInDom = {}, + memoize = function(fn) { + var memo; + return function () { + if (typeof memo === "undefined") memo = fn.apply(this, arguments); + return memo; + }; + }, + isOldIE = memoize(function() { + return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase()); + }), + getHeadElement = memoize(function () { + return document.head || document.getElementsByTagName("head")[0]; + }), + singletonElement = null, + singletonCounter = 0; + + module.exports = function(list, options) { + if(false) { + if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); + } + + options = options || {}; + // Force single-tag solution on IE6-9, which has a hard limit on the # of + // tags it will allow on a page + if (typeof options.singleton === "undefined") options.singleton = isOldIE(); + + var styles = listToStyles(list); + addStylesToDom(styles, options); + + return function update(newList) { + var mayRemove = []; + for(var i = 0; i < styles.length; i++) { + var item = styles[i]; + var domStyle = stylesInDom[item.id]; + domStyle.refs--; + mayRemove.push(domStyle); + } + if(newList) { + var newStyles = listToStyles(newList); + addStylesToDom(newStyles, options); + } + for(var i = 0; i < mayRemove.length; i++) { + var domStyle = mayRemove[i]; + if(domStyle.refs === 0) { + for(var j = 0; j < domStyle.parts.length; j++) + domStyle.parts[j](); + delete stylesInDom[domStyle.id]; + } + } + }; + } + + function addStylesToDom(styles, options) { + for(var i = 0; i < styles.length; i++) { + var item = styles[i]; + var domStyle = stylesInDom[item.id]; + if(domStyle) { + domStyle.refs++; + for(var j = 0; j < domStyle.parts.length; j++) { + domStyle.parts[j](item.parts[j]); + } + for(; j < item.parts.length; j++) { + domStyle.parts.push(addStyle(item.parts[j], options)); + } + } else { + var parts = []; + for(var j = 0; j < item.parts.length; j++) { + parts.push(addStyle(item.parts[j], options)); + } + stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts}; + } + } + } + + function listToStyles(list) { + var styles = []; + var newStyles = {}; + for(var i = 0; i < list.length; i++) { + var item = list[i]; + var id = item[0]; + var css = item[1]; + var media = item[2]; + var sourceMap = item[3]; + var part = {css: css, media: media, sourceMap: sourceMap}; + if(!newStyles[id]) + styles.push(newStyles[id] = {id: id, parts: [part]}); + else + newStyles[id].parts.push(part); + } + return styles; + } + + function createStyleElement() { + var styleElement = document.createElement("style"); + var head = getHeadElement(); + styleElement.type = "text/css"; + head.appendChild(styleElement); + return styleElement; + } + + function createLinkElement() { + var linkElement = document.createElement("link"); + var head = getHeadElement(); + linkElement.rel = "stylesheet"; + head.appendChild(linkElement); + return linkElement; + } + + function addStyle(obj, options) { + var styleElement, update, remove; + + if (options.singleton) { + var styleIndex = singletonCounter++; + styleElement = singletonElement || (singletonElement = createStyleElement()); + update = applyToSingletonTag.bind(null, styleElement, styleIndex, false); + remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true); + } else if(obj.sourceMap && + typeof URL === "function" && + typeof URL.createObjectURL === "function" && + typeof URL.revokeObjectURL === "function" && + typeof Blob === "function" && + typeof btoa === "function") { + styleElement = createLinkElement(); + update = updateLink.bind(null, styleElement); + remove = function() { + styleElement.parentNode.removeChild(styleElement); + if(styleElement.href) + URL.revokeObjectURL(styleElement.href); + }; + } else { + styleElement = createStyleElement(); + update = applyToTag.bind(null, styleElement); + remove = function() { + styleElement.parentNode.removeChild(styleElement); + }; + } + + update(obj); + + return function updateStyle(newObj) { + if(newObj) { + if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) + return; + update(obj = newObj); + } else { + remove(); + } + }; + } + + var replaceText = (function () { + var textStore = []; + + return function (index, replacement) { + textStore[index] = replacement; + return textStore.filter(Boolean).join('\n'); + }; + })(); + + function applyToSingletonTag(styleElement, index, remove, obj) { + var css = remove ? "" : obj.css; + + if (styleElement.styleSheet) { + styleElement.styleSheet.cssText = replaceText(index, css); + } else { + var cssNode = document.createTextNode(css); + var childNodes = styleElement.childNodes; + if (childNodes[index]) styleElement.removeChild(childNodes[index]); + if (childNodes.length) { + styleElement.insertBefore(cssNode, childNodes[index]); + } else { + styleElement.appendChild(cssNode); + } + } + } + + function applyToTag(styleElement, obj) { + var css = obj.css; + var media = obj.media; + var sourceMap = obj.sourceMap; + + if(media) { + styleElement.setAttribute("media", media) + } + + if(styleElement.styleSheet) { + styleElement.styleSheet.cssText = css; + } else { + while(styleElement.firstChild) { + styleElement.removeChild(styleElement.firstChild); + } + styleElement.appendChild(document.createTextNode(css)); + } + } + + function updateLink(linkElement, obj) { + var css = obj.css; + var media = obj.media; + var sourceMap = obj.sourceMap; + + if(sourceMap) { + // http://stackoverflow.com/a/26603875 + css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */"; + } + + var blob = new Blob([css], { type: "text/css" }); + + var oldSrc = linkElement.href; + + linkElement.href = URL.createObjectURL(blob); + + if(oldSrc) + URL.revokeObjectURL(oldSrc); + } + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + // style-loader: Adds some css to the DOM by adding a tag + + // load the styles + var content = __webpack_require__(6); + if(typeof content === 'string') content = [[module.id, content, '']]; + // add the styles to the DOM + var update = __webpack_require__(4)(content, {}); + if(content.locals) module.exports = content.locals; + // Hot Module Replacement + if(false) { + // When the styles change, update the tags + if(!content.locals) { + module.hot.accept("!!./node_modules/css-loader/index.js!./style2.css", function() { + var newContent = require("!!./node_modules/css-loader/index.js!./style2.css"); + if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; + update(newContent); + }); + } + // When the module is disposed, remove the tags + module.hot.dispose(function() { update(); }); + } + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + exports = module.exports = __webpack_require__(3)(); + exports.push([module.id, "body {\n background: red;\n}\n", ""]); + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = "It works from content.js."; + + console.log('body'); + /***/ } /******/ ]); \ No newline at end of file diff --git a/content.js b/content.js index 8195cba..3c463bb 100644 --- a/content.js +++ b/content.js @@ -1,3 +1,3 @@ module.exports = "It works from content.js."; -console.log('some stuff'); +console.log('body'); diff --git a/package.json b/package.json index 1817ff6..e135bed 100644 --- a/package.json +++ b/package.json @@ -24,5 +24,9 @@ "dependencies": { "css-loader": "^0.14.2", "style-loader": "^0.12.3" + }, + "devDependencies": { + "purify-css": "^1.0.0", + "string": "^3.1.1" } } diff --git a/plugin.js b/plugin.js index 15037bd..20e0432 100644 --- a/plugin.js +++ b/plugin.js @@ -1,4 +1,6 @@ var fs = require('fs'); +var purify = require('./node_modules/purify-css/purifycss.js'); +var S = require('string'); var DemoPlugin = function(output, options) { this.output = output; @@ -12,16 +14,47 @@ DemoPlugin.prototype.apply = function(compiler) { compiler.plugin('compilation', function(compilation) { compilation.plugin("optimize-modules", function(modules) { - //iterate over modules - //check if filepath ends in css - //split at ! and fs - //concat file path to css array + var content = []; + var css = []; + + //get all html/js contents + modules.forEach(function(module) { //check if filepath does not contain node_modules + var filepath = module._source._name; + var sourcecode = module._source._value; + + if (!S(filepath).contains('node_modules')) { //concat path to content array - //pass css and content array into kenny's function - //store results in uncss array - //update css modules accordingly + content.push(sourcecode); + } + }) + + content = content.join(""); + + modules.forEach(function(module) { + //iterate over modules + var filepath = module._source._name; + var sourcecode = module._source._value; + + //skip over files loaded by style-loader + if (S(filepath).contains('!') && !S(filepath).contains('style-loader')) { + //parse sourcecode for only css + var css = S(sourcecode).between('module.id, ',', ""]);').s; + + //pass css and content array into kenny's function + var uncss = purify(content, eval(css), {write: false, minify: false}); + + //stringify purified css + uncss = JSON.stringify(uncss); + + //insert back into module + module._source._value = sourcecode.replace(css, uncss) + console.log('-----MODULE------',module._source._value); + } + + }) //end modules.forEach - }); //end compiler.plugin + }); //end compiler.plugin -}; \ No newline at end of file + }); +} \ No newline at end of file diff --git a/style.css b/style.css index 0329bde..ace4a01 100644 --- a/style.css +++ b/style.css @@ -1,3 +1,12 @@ body { background: yellow; +} +p{ + background: green; +} +video { + background: white; +} +span{ + background: blue; } \ No newline at end of file diff --git a/style2.css b/style2.css index c489d30..4138bce 100644 --- a/style2.css +++ b/style2.css @@ -1,3 +1,19 @@ body { background: red; +} + +div{ + color:purple; +} + +h1 { + margin: 5px; +} + +h2 { + padding: 20em; +} + +button { + background-color: black; } \ No newline at end of file From 3224fbfedff463a8ff3df43ced0a1ae5c86a1341 Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Tue, 26 May 2015 16:50:38 -0400 Subject: [PATCH 09/25] restructure for testing, run npm test --- plugin.js => index.js | 0 package.json | 14 +++++--- test/fixtures/content.js | 3 ++ entry.js => test/fixtures/entry.js | 0 index.html => test/fixtures/index.html | 2 +- style.css => test/fixtures/style.css | 0 style2.css => test/fixtures/style2.css | 0 bundle.js => test/output/bundle.js | 8 ++--- test/plugin.js | 48 ++++++++++++++++++++++++++ webpack.config.js | 21 ----------- 10 files changed, 65 insertions(+), 31 deletions(-) rename plugin.js => index.js (100%) create mode 100644 test/fixtures/content.js rename entry.js => test/fixtures/entry.js (100%) rename index.html => test/fixtures/index.html (50%) rename style.css => test/fixtures/style.css (100%) rename style2.css => test/fixtures/style2.css (100%) rename bundle.js => test/output/bundle.js (94%) create mode 100644 test/plugin.js delete mode 100644 webpack.config.js diff --git a/plugin.js b/index.js similarity index 100% rename from plugin.js rename to index.js diff --git a/package.json b/package.json index e135bed..bcd5e83 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "uncss plugin for webpack", "main": "bundle.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "./node_modules/.bin/nodeunit test/plugin.js" }, "repository": { "type": "git", @@ -13,7 +13,8 @@ "keywords": [ "webpack", "uncss", - "plugin" + "plugin", + "purify" ], "author": "kenny matt phoebe", "license": "ISC", @@ -23,10 +24,13 @@ "homepage": "https://github.com/fog-glory/fog-glory", "dependencies": { "css-loader": "^0.14.2", - "style-loader": "^0.12.3" + "style-loader": "^0.12.3", + }, "devDependencies": { "purify-css": "^1.0.0", - "string": "^3.1.1" + "string": "^3.1.1", + "nodeunit": "^0.9", + "webpack": "^1.0" } -} +} \ No newline at end of file diff --git a/test/fixtures/content.js b/test/fixtures/content.js new file mode 100644 index 0000000..3c463bb --- /dev/null +++ b/test/fixtures/content.js @@ -0,0 +1,3 @@ +module.exports = "It works from content.js."; + +console.log('body'); diff --git a/entry.js b/test/fixtures/entry.js similarity index 100% rename from entry.js rename to test/fixtures/entry.js diff --git a/index.html b/test/fixtures/index.html similarity index 50% rename from index.html rename to test/fixtures/index.html index da9edba..49c6b5a 100644 --- a/index.html +++ b/test/fixtures/index.html @@ -3,6 +3,6 @@ - + \ No newline at end of file diff --git a/style.css b/test/fixtures/style.css similarity index 100% rename from style.css rename to test/fixtures/style.css diff --git a/style2.css b/test/fixtures/style2.css similarity index 100% rename from style2.css rename to test/fixtures/style2.css diff --git a/bundle.js b/test/output/bundle.js similarity index 94% rename from bundle.js rename to test/output/bundle.js index ce32d1a..88f8191 100644 --- a/bundle.js +++ b/test/output/bundle.js @@ -64,8 +64,8 @@ if(false) { // When the styles change, update the tags if(!content.locals) { - module.hot.accept("!!./node_modules/css-loader/index.js!./style.css", function() { - var newContent = require("!!./node_modules/css-loader/index.js!./style.css"); + module.hot.accept("!!./../../node_modules/css-loader/index.js!./style.css", function() { + var newContent = require("!!./../../node_modules/css-loader/index.js!./style.css"); if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; update(newContent); }); @@ -378,8 +378,8 @@ if(false) { // When the styles change, update the tags if(!content.locals) { - module.hot.accept("!!./node_modules/css-loader/index.js!./style2.css", function() { - var newContent = require("!!./node_modules/css-loader/index.js!./style2.css"); + module.hot.accept("!!./../../node_modules/css-loader/index.js!./style2.css", function() { + var newContent = require("!!./../../node_modules/css-loader/index.js!./style2.css"); if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; update(newContent); }); diff --git a/test/plugin.js b/test/plugin.js new file mode 100644 index 0000000..5ac503b --- /dev/null +++ b/test/plugin.js @@ -0,0 +1,48 @@ +var fs = require('fs'); +var path = require('path'); +var webpack = require('webpack'); +var DemoPlugin = require('../'); + +var inputFolder = path.join(__dirname, 'fixtures'); +var inputFile = path.join(inputFolder, 'entry.js'); +var outputFolder = path.join(__dirname, 'output'); +var outputFile = path.join(outputFolder, 'bundle.js'); + +var options = { + chunkModules: true, + exclude: [/node_modules[\\\/]/] +}; + +var compiler = webpack({ + entry: inputFile, + + output: { + path: outputFolder, + filename: "bundle.js" + }, + + loaders: [{ + test: /\.css$/, + loader: "style!css" + }], + + plugins: [ + new DemoPlugin(path.join(__dirname), { + chunkModules: true, + }) + ] +}); + +module.exports.test = { + + 'removes unused css': function(test) { + compiler.run(function(err, stats) { + // var expected = JSON.stringify(stats.toJson(options)); + // var actual = fs.readFileSync(outputFile); + // test.equal(actual, expected); + console.log('write test'); + test.done(); + }); + } + +}; \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 7125919..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,21 +0,0 @@ -var DemoPlugin = require('./plugin.js'); -var path = require('path'); - - -module.exports = { - entry: "./entry.js", - output: { - path: __dirname, - filename: "bundle.js" - }, - loaders: [{ - test: /\.css$/, - loader: "style!css" - }], - plugins: [ - new DemoPlugin(path.join(__dirname), { - chunkModules: true, - }) - ] - -}; \ No newline at end of file From 491f976f4888d46262d2c87d8bc25e8802015c73 Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Tue, 26 May 2015 16:52:48 -0400 Subject: [PATCH 10/25] git ignore floobits, cleaned up root --- .gitignore | 4 ++++ content.js | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 content.js diff --git a/.gitignore b/.gitignore index 123ae94..1f02b46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +#floobits +.floobits +.flooignore + # Logs logs *.log diff --git a/content.js b/content.js deleted file mode 100644 index 3c463bb..0000000 --- a/content.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = "It works from content.js."; - -console.log('body'); From b0a282f27add64052fae745dc318a6d4fe190843 Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Tue, 26 May 2015 16:53:33 -0400 Subject: [PATCH 11/25] Delete .floo --- .floo | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .floo diff --git a/.floo b/.floo deleted file mode 100644 index de25524..0000000 --- a/.floo +++ /dev/null @@ -1,3 +0,0 @@ -{ - "url": "https://floobits.com/HackReactor/fog-glory-plugin" -} \ No newline at end of file From 7c192255d26b774160a80677178f9f07b1074995 Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Tue, 26 May 2015 16:53:41 -0400 Subject: [PATCH 12/25] Delete .flooignore --- .flooignore | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .flooignore diff --git a/.flooignore b/.flooignore deleted file mode 100644 index 8c380e3..0000000 --- a/.flooignore +++ /dev/null @@ -1,8 +0,0 @@ -#* -*.o -*.pyc -*~ -extern/ -node_modules/ -tmp -vendor/ \ No newline at end of file From f7af0b91e94b431e6f11383b8b1b1bf3e3d446d2 Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Tue, 26 May 2015 17:01:38 -0400 Subject: [PATCH 13/25] add .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d2f3209 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js \ No newline at end of file From 4860c4b06e46d11d11ce0d82f324f757621b4fbc Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Tue, 26 May 2015 14:37:52 -0700 Subject: [PATCH 14/25] Add webpack loader functionality --- index.js | 65 +++++++++++++++------------------------------------- loader.js | 13 +++++++++++ package.json | 8 +++---- 3 files changed, 36 insertions(+), 50 deletions(-) create mode 100644 loader.js diff --git a/index.js b/index.js index 20e0432..1901c4d 100644 --- a/index.js +++ b/index.js @@ -1,60 +1,33 @@ -var fs = require('fs'); -var purify = require('./node_modules/purify-css/purifycss.js'); -var S = require('string'); - -var DemoPlugin = function(output, options) { - this.output = output; - this.options = options; +var DemoPlugin = function(rootHtml) { + this.rootHtml = rootHtml }; module.exports = DemoPlugin; DemoPlugin.prototype.apply = function(compiler) { + compiler.plugin('this-compilation', function(compilation) { - compiler.plugin('compilation', function(compilation) { + var content = ""; compilation.plugin("optimize-modules", function(modules) { - var content = []; - var css = []; - - //get all html/js contents - modules.forEach(function(module) { - //check if filepath does not contain node_modules - var filepath = module._source._name; - var sourcecode = module._source._value; - if (!S(filepath).contains('node_modules')) { - //concat path to content array - content.push(sourcecode); + modules.forEach(function(m){ + if(m._source && m._source._value && + m._source._name.indexOf('.css') === -1 && + m._source._name.indexOf('node_modules') === -1){ + content += m._source._value; } - }) - - content = content.join(""); - - modules.forEach(function(module) { - //iterate over modules - var filepath = module._source._name; - var sourcecode = module._source._value; - - //skip over files loaded by style-loader - if (S(filepath).contains('!') && !S(filepath).contains('style-loader')) { - //parse sourcecode for only css - var css = S(sourcecode).between('module.id, ',', ""]);').s; + }); - //pass css and content array into kenny's function - var uncss = purify(content, eval(css), {write: false, minify: false}); + compilation.__content = content; - //stringify purified css - uncss = JSON.stringify(uncss); - - //insert back into module - module._source._value = sourcecode.replace(css, uncss) - console.log('-----MODULE------',module._source._value); + modules.forEach(function(m){ + if(m._source && m._source._name.indexOf('.css') > -1){ + compilation.rebuildModule(m, function(err){ + if(err) console.log(err); + }); } - - }) //end modules.forEach - - }); //end compiler.plugin - + }); + }); }); -} \ No newline at end of file +}; diff --git a/loader.js b/loader.js new file mode 100644 index 0000000..0981b36 --- /dev/null +++ b/loader.js @@ -0,0 +1,13 @@ +var purify = require('purify-css'); + +module.exports = function(input){ + if(typeof this._compilation.__content === 'undefined'){ + return input; + } + + console.log(this._compilation.__content.length); + console.log(''); + console.log('YOOOOOOOOOOOOOOOOO'); + console.log(''); + return purify(this._compilation.__content, input); +}; diff --git a/package.json b/package.json index bcd5e83..e4ff991 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { "name": "fog-glory", "version": "1.0.0", - "description": "uncss plugin for webpack", + "description": "purify-css plugin for webpack", "main": "bundle.js", "scripts": { "test": "./node_modules/.bin/nodeunit test/plugin.js" }, "repository": { "type": "git", - "url": "https://github.com/fog-glory/fog-glory.git" + "url": "https://github.com/purifycss/purify-css.git" }, "keywords": [ "webpack", @@ -19,9 +19,9 @@ "author": "kenny matt phoebe", "license": "ISC", "bugs": { - "url": "https://github.com/fog-glory/fog-glory/issues" + "url": "https://github.com/purifycss/purify-css/issues" }, - "homepage": "https://github.com/fog-glory/fog-glory", + "homepage": "https://github.com/purifycss/purify-css", "dependencies": { "css-loader": "^0.14.2", "style-loader": "^0.12.3", From c9745ad9fa728cb2b329076527f0645d5321a376 Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Tue, 26 May 2015 15:14:48 -0700 Subject: [PATCH 15/25] Remove console logs. Fix package.json typo --- .gitignore | 2 ++ loader.js | 4 ---- package.json | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 1f02b46..bf0d423 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ build/Release # Dependency directory # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules + +example \ No newline at end of file diff --git a/loader.js b/loader.js index 0981b36..165837c 100644 --- a/loader.js +++ b/loader.js @@ -5,9 +5,5 @@ module.exports = function(input){ return input; } - console.log(this._compilation.__content.length); - console.log(''); - console.log('YOOOOOOOOOOOOOOOOO'); - console.log(''); return purify(this._compilation.__content, input); }; diff --git a/package.json b/package.json index e4ff991..f168030 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ "homepage": "https://github.com/purifycss/purify-css", "dependencies": { "css-loader": "^0.14.2", - "style-loader": "^0.12.3", - + "purify-css": "^1.0.0", + "style-loader": "^0.12.3" }, "devDependencies": { "purify-css": "^1.0.0", @@ -33,4 +33,4 @@ "nodeunit": "^0.9", "webpack": "^1.0" } -} \ No newline at end of file +} From 3ee555ebc7b5266b8ae7f854a39302798a271271 Mon Sep 17 00:00:00 2001 From: Phoebe Li Date: Tue, 26 May 2015 18:24:12 -0400 Subject: [PATCH 16/25] wrote tests for webpack-plugin --- test/plugin.js | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/test/plugin.js b/test/plugin.js index 5ac503b..e9e6241 100644 --- a/test/plugin.js +++ b/test/plugin.js @@ -2,6 +2,7 @@ var fs = require('fs'); var path = require('path'); var webpack = require('webpack'); var DemoPlugin = require('../'); +var S = require('string'); var inputFolder = path.join(__dirname, 'fixtures'); var inputFile = path.join(inputFolder, 'entry.js'); @@ -33,14 +34,32 @@ var compiler = webpack({ ] }); -module.exports.test = { +module.exports.tests = { - 'removes unused css': function(test) { + 'bundle includes all css classes': function(test) { compiler.run(function(err, stats) { - // var expected = JSON.stringify(stats.toJson(options)); - // var actual = fs.readFileSync(outputFile); - // test.equal(actual, expected); - console.log('write test'); + var expected = ["body", "p"]; + var actual = fs.readFileSync(outputFile, 'utf-8'); + + var allPass = expected.every(function(className) { + return S(actual).contains(className) + }); + + test.ok(allPass, "bundle includes all css classes"); + test.done(); + }) + }, + + 'bundle does not include css classes not in source html/js': function(test) { + compiler.run(function(err, stats) { + var expected = ["video", "span", "div", "h1", "h2", "button"]; + var actual = fs.readFileSync(outputFile, 'utf-8'); + + var allPass = expected.every(function(className) { + return !S(actual).contains(className) + }); + + test.ok(allPass, "bundle does not include css classes not in source html/js"); test.done(); }); } From f666f1920599022caad754dbdc617012c4ab0907 Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Sat, 6 Jun 2015 16:47:44 -0700 Subject: [PATCH 17/25] Add preliminary functionality for plugin --- index.js | 74 +++++++++++++++++++++++++++++++++++++++++++------------ loader.js | 7 +++--- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/index.js b/index.js index 1901c4d..713893a 100644 --- a/index.js +++ b/index.js @@ -4,30 +4,72 @@ var DemoPlugin = function(rootHtml) { module.exports = DemoPlugin; +var isCss = function(module){ + console.log(module._source._name); + return module._source && module._source._value && + module._source._name.indexOf('.css') > -1 && + module._source._name.indexOf('node_modules') === -1; +}; + +var isContent = function(module){ + return module._source && module._source._value && + module._source._name.indexOf('.css') === -1 && + module._source._name.indexOf('node_modules') === -1; +}; + +var getContentHash = function(compilation){ + return compilation.chunks.reduce(function(contentHash, chunk){ + var modules = chunk.modules; + var content = modules.reduce(function(total, m){ + if(isContent(m)){ + total += m._source._value; + } + + return total; + }, ""); + + contentHash[chunk.name] = content; + return contentHash; + }, {}); +}; + +var getCssModules = function(modules){ + return modules.filter(function(module){ + return isCss(module); + }); +}; + DemoPlugin.prototype.apply = function(compiler) { + var chunkContent; + var cssModules; + compiler.plugin('this-compilation', function(compilation) { + compilation._purifycss_callback = function(){ + if(cssModules.length === 0){ + return; + } - var content = ""; + var nextModule = cssModules.pop(); + compilation._purifycss_content = ''; - compilation.plugin("optimize-modules", function(modules) { - - modules.forEach(function(m){ - if(m._source && m._source._value && - m._source._name.indexOf('.css') === -1 && - m._source._name.indexOf('node_modules') === -1){ - content += m._source._value; - } + nextModule.chunks.forEach(function(chunk){ + compilation._purifycss_content += chunkContent[chunk.name] + ' '; }); - compilation.__content = content; - - modules.forEach(function(m){ - if(m._source && m._source._name.indexOf('.css') > -1){ - compilation.rebuildModule(m, function(err){ - if(err) console.log(err); - }); + compilation.rebuildModule(nextModule, function(err){ + if(err){ + console.log(err); } + + compilation._purifycss_callback(); }); + }; + + compilation.plugin("optimize-modules", function(modules) { + chunkContent = getContentHash(compilation); + cssModules = getCssModules(modules); + console.log(cssModules); + compilation._purifycss_callback(); }); }); }; diff --git a/loader.js b/loader.js index 165837c..ba05f6f 100644 --- a/loader.js +++ b/loader.js @@ -1,9 +1,10 @@ var purify = require('purify-css'); module.exports = function(input){ - if(typeof this._compilation.__content === 'undefined'){ + if(typeof this._compilation._purifycss_content === 'undefined'){ return input; } - - return purify(this._compilation.__content, input); + + var content = this._compilation._purifycss_content; + return purify(content, input); }; From 0108922a03ad921f87161944d3be3c8124b0ffae Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Sun, 7 Jun 2015 21:06:06 -0700 Subject: [PATCH 18/25] Change to optimize-tree. Currently working --- index.js | 18 +++++++----------- loader.js | 3 +++ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index 713893a..41dfece 100644 --- a/index.js +++ b/index.js @@ -5,16 +5,13 @@ var DemoPlugin = function(rootHtml) { module.exports = DemoPlugin; var isCss = function(module){ - console.log(module._source._name); return module._source && module._source._value && - module._source._name.indexOf('.css') > -1 && - module._source._name.indexOf('node_modules') === -1; + module._source._name.indexOf('.css') > -1; }; var isContent = function(module){ return module._source && module._source._value && - module._source._name.indexOf('.css') === -1 && - module._source._name.indexOf('node_modules') === -1; + module._source._name.indexOf('.css') === -1; }; var getContentHash = function(compilation){ @@ -44,9 +41,9 @@ DemoPlugin.prototype.apply = function(compiler) { var cssModules; compiler.plugin('this-compilation', function(compilation) { - compilation._purifycss_callback = function(){ + compilation._purifycss_callback = function(callback){ if(cssModules.length === 0){ - return; + return callback(); } var nextModule = cssModules.pop(); @@ -61,15 +58,14 @@ DemoPlugin.prototype.apply = function(compiler) { console.log(err); } - compilation._purifycss_callback(); + compilation._purifycss_callback(callback); }); }; - compilation.plugin("optimize-modules", function(modules) { + compilation.plugin("optimize-tree", function(chunks, modules, callback) { chunkContent = getContentHash(compilation); cssModules = getCssModules(modules); - console.log(cssModules); - compilation._purifycss_callback(); + compilation._purifycss_callback(callback); }); }); }; diff --git a/loader.js b/loader.js index ba05f6f..adad247 100644 --- a/loader.js +++ b/loader.js @@ -2,9 +2,12 @@ var purify = require('purify-css'); module.exports = function(input){ if(typeof this._compilation._purifycss_content === 'undefined'){ + console.log('SEE ME PLEASE'); return input; } var content = this._compilation._purifycss_content; + // this._compilation._purifycss_callback(); + return purify(content, input); }; From 09169a6cefc4c536fde5395601a65cbe2312cc78 Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Mon, 8 Jun 2015 10:43:43 -0700 Subject: [PATCH 19/25] Update package.json names --- package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index f168030..64ecc4e 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { - "name": "fog-glory", + "name": "purifycss-webpack-plugin", "version": "1.0.0", - "description": "purify-css plugin for webpack", - "main": "bundle.js", + "description": "PurifyCSS plugin for webpack", + "main": "index.js", "scripts": { "test": "./node_modules/.bin/nodeunit test/plugin.js" }, "repository": { "type": "git", - "url": "https://github.com/purifycss/purify-css.git" + "url": "https://github.com/purifycss/purifycss-webpack-plugin.git" }, "keywords": [ "webpack", @@ -16,12 +16,12 @@ "plugin", "purify" ], - "author": "kenny matt phoebe", + "author": "Kenny Tran, Matthew Rourke, Phoebe Li", "license": "ISC", "bugs": { - "url": "https://github.com/purifycss/purify-css/issues" + "url": "https://github.com/purifycss/purifycss-webpack-plugin/issues" }, - "homepage": "https://github.com/purifycss/purify-css", + "homepage": "https://github.com/purifycss/purifycss-webpack-plugin", "dependencies": { "css-loader": "^0.14.2", "purify-css": "^1.0.0", From 6944b6ac6c09cb521932bd30a5f8938c313a19e4 Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Mon, 8 Jun 2015 10:56:44 -0700 Subject: [PATCH 20/25] Able to detect classes in root html --- index.js | 24 +++++++++++++++++------- loader.js | 1 - 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 41dfece..1cd0071 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,17 @@ -var DemoPlugin = function(rootHtml) { - this.rootHtml = rootHtml +var fs = require('fs'); + +var PurifyCssPlugin = function(absolutePath) { + var htmlPaths = Array.prototype.slice.call(arguments, 1); + this.htmlContent = concatFiles(absolutePath, htmlPaths); }; -module.exports = DemoPlugin; +module.exports = PurifyCssPlugin; + +var concatFiles = function(absolutePath, filePaths){ + return filePaths.reduce(function(content, filePath){ + return content + fs.readFileSync(absolutePath + filePath, 'utf8'); + }, ''); +}; var isCss = function(module){ return module._source && module._source._value && @@ -23,7 +32,7 @@ var getContentHash = function(compilation){ } return total; - }, ""); + }, ''); contentHash[chunk.name] = content; return contentHash; @@ -36,9 +45,10 @@ var getCssModules = function(modules){ }); }; -DemoPlugin.prototype.apply = function(compiler) { +PurifyCssPlugin.prototype.apply = function(compiler) { var chunkContent; var cssModules; + var htmlContent = this.htmlContent; compiler.plugin('this-compilation', function(compilation) { compilation._purifycss_callback = function(callback){ @@ -47,7 +57,7 @@ DemoPlugin.prototype.apply = function(compiler) { } var nextModule = cssModules.pop(); - compilation._purifycss_content = ''; + compilation._purifycss_content = htmlContent; nextModule.chunks.forEach(function(chunk){ compilation._purifycss_content += chunkContent[chunk.name] + ' '; @@ -62,7 +72,7 @@ DemoPlugin.prototype.apply = function(compiler) { }); }; - compilation.plugin("optimize-tree", function(chunks, modules, callback) { + compilation.plugin('optimize-tree', function(chunks, modules, callback) { chunkContent = getContentHash(compilation); cssModules = getCssModules(modules); compilation._purifycss_callback(callback); diff --git a/loader.js b/loader.js index adad247..797309e 100644 --- a/loader.js +++ b/loader.js @@ -7,7 +7,6 @@ module.exports = function(input){ } var content = this._compilation._purifycss_content; - // this._compilation._purifycss_callback(); return purify(content, input); }; From 84a0c4790faf4e1ec5116bd08f1388d767e22e52 Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Fri, 12 Jun 2015 08:26:10 -0700 Subject: [PATCH 21/25] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 417a631..b316b2c 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# fog-glory +# Currently in development From a992f9972c8461c16a77766ecaddea5d550e4a40 Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Tue, 16 Jun 2015 07:02:09 -0700 Subject: [PATCH 22/25] Change from plugin to loader --- index.js => PurifyCssPlugin.js | 0 loader.js | 1 - package.json | 2 +- 3 files changed, 1 insertion(+), 2 deletions(-) rename index.js => PurifyCssPlugin.js (100%) diff --git a/index.js b/PurifyCssPlugin.js similarity index 100% rename from index.js rename to PurifyCssPlugin.js diff --git a/loader.js b/loader.js index 797309e..2ff4afe 100644 --- a/loader.js +++ b/loader.js @@ -2,7 +2,6 @@ var purify = require('purify-css'); module.exports = function(input){ if(typeof this._compilation._purifycss_content === 'undefined'){ - console.log('SEE ME PLEASE'); return input; } diff --git a/package.json b/package.json index 64ecc4e..5e47b28 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "purifycss-webpack-plugin", + "name": "purifycss-loader", "version": "1.0.0", "description": "PurifyCSS plugin for webpack", "main": "index.js", From b3532d7ebd3c5fcae25ac99dba46aad4a19728b2 Mon Sep 17 00:00:00 2001 From: Kenny Tran Date: Tue, 16 Jun 2015 07:11:56 -0700 Subject: [PATCH 23/25] Update README.md --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b316b2c..f431744 100644 --- a/README.md +++ b/README.md @@ -1 +1,28 @@ -# Currently in development +* [PurifyCSS](https://github.com/purifycss/purifycss) plugin/loader for webpack. + +# Installation +``` +npm install purifycss-loader +``` + +# Usage +``` javascript +var PurifyCssPlugin = require('purifycss-loader/PurifyCssPlugin'); + +var webpackConfig = { + // ... + + module: { + loaders: [{ + test: /\.css$/, loader: "style-loader!css-loader!purifycss-loader" + }] + }, + + plugins: { + new PurifyCssPlugin(__dirname, '/index.html') + } +} +``` + +# API +Pass in the filepath to the root html for us to detect classes there. PurifyCSS will look at all your bundles on its own. From 0a60cf358cacb4a398be4344b1fa289f5223a881 Mon Sep 17 00:00:00 2001 From: Maxime Tyler <127086@supinfo.com> Date: Wed, 15 Jul 2015 15:08:11 +0200 Subject: [PATCH 24/25] fix: point to the right main script fixes https://github.com/purifycss/purifycss-webpack-plugin/issues/38 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5e47b28..32d1b16 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "purifycss-loader", "version": "1.0.0", "description": "PurifyCSS plugin for webpack", - "main": "index.js", + "main": "loader.js", "scripts": { "test": "./node_modules/.bin/nodeunit test/plugin.js" }, From 897e690637a1427139b2e9249007919e64924859 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 15 Jul 2015 18:11:58 +0300 Subject: [PATCH 25/25] Fix example --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f431744..d061dec 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,16 @@ var PurifyCssPlugin = require('purifycss-loader/PurifyCssPlugin'); var webpackConfig = { // ... - + module: { loaders: [{ test: /\.css$/, loader: "style-loader!css-loader!purifycss-loader" }] }, - - plugins: { + + plugins: [ new PurifyCssPlugin(__dirname, '/index.html') - } + ] } ```