lib/transforms/convertStylesheetsToInlineStyles.js

lib/ AssetGraph.js errors.js index.js query.js
assets/ Asset.js Atom.js CacheManifest.js CoffeeScript.js Css.js Flash.js Gif.js Htc.js Html.js I18n.js Ico.js Image.js JavaScript.js Jpeg.js Json.js KnockoutJsTemplate.js Less.js Png.js Rss.js StaticUrlMap.js Stylus.js Text.js Xml.js index.js
relations/ CacheManifestEntry.js CssAlphaImageLoader.js CssBehavior.js CssFontFaceSrc.js CssImage.js CssImport.js CssUrlTokenRelation.js HtmlAlternateLink.js HtmlAnchor.js HtmlAppleTouchStartupImage.js HtmlApplet.js HtmlAudio.js HtmlCacheManifest.js HtmlConditionalComment.js HtmlDataBindAttribute.js HtmlEdgeSideInclude.js HtmlEmbed.js HtmlFrame.js HtmlIFrame.js HtmlIFrameSrcDoc.js HtmlImage.js HtmlInlineScriptTemplate.js HtmlKnockoutContainerless.js HtmlObject.js HtmlRelation.js HtmlRequireJsMain.js HtmlScript.js HtmlShortcutIcon.js HtmlStyle.js HtmlStyleAttribute.js HtmlVideo.js HtmlVideoPoster.js JavaScriptAmdDefine.js JavaScriptAmdRequire.js JavaScriptCommonJsRequire.js JavaScriptExtJsRequire.js JavaScriptGetStaticUrl.js JavaScriptGetText.js JavaScriptInclude.js JavaScriptShimRequire.js JavaScriptTrHtml.js Relation.js StaticUrlMapEntry.js index.js
resolvers/ data.js extJs4Dir.js file.js fixedDirectory.js http.js index.js javascript.js
transforms/ addCacheManifest.js bundleRelations.js bundleRequireJs.js compileCoffeeScriptToJavaScript.js compileLessToCss.js compileStylusToCss.js compressJavaScript.js convertCssImportsToHtmlStyles.js convertHtmlStylesToInlineCssImports.js convertStylesheetsToInlineStyles.js drawGraph.js executeJavaScriptInOrder.js externalizeRelations.js flattenStaticIncludes.js inlineCssImagesWithLegacyFallback.js inlineRelations.js loadAssets.js mergeIdenticalAssets.js minifyAssets.js moveAssets.js moveAssetsInOrder.js populate.js prettyPrintAssets.js pullGlobalsIntoVariables.js registerRequireJsConfig.js removeAssets.js removeRelations.js setAssetContentType.js setAssetEncoding.js setAssetExtension.js setHtmlImageDimensions.js startOverIfAssetSourceFilesChange.js writeAssetsToDisc.js writeAssetsToStdout.js writeStatsToStderr.js
util/ deepCopy.js extendWithGettersAndSetters.js fsTools.js getImageInfoFromBuffers.js memoizeAsyncAccessor.js uniqueId.js urlTools.js
var _ = require('underscore'),
    cssom = require('cssom-papandreou');

module.exports = function (queryObj, media) {
    var includeByMedium = {};
    if (!media) {
        includeByMedium.all = true;
    } else {
        media.split(",").forEach(function (medium) {
            includeByMedium[medium.replace(/^\s+|\s+$/g, '')] = true;
        });
    }
    function includeMedia(media) {
        return includeByMedium.all || media.some(function (medium) {
            medium = medium.replace(/^\s+|\s+$/g, '');
            return medium === 'all' || includeByMedium[medium];
        });
    }

    return function convertStylesheetsToInlineStyles(assetGraph) {
        assetGraph.findAssets(_.extend({isHtml: true}, queryObj)).forEach(function (htmlAsset) {
            var document = htmlAsset.parseTree;
            assetGraph.eachAssetPostOrder(htmlAsset, function (relation) {
                if (relation.type === 'HtmlStyle' || relation.type === 'CssImport') {
                    var relationMedia = ['all'];
                    if (relation.type === 'HtmlStyle') {
                        relationMedia = (relation.node.getAttribute('media') || 'all').split(',');
                    } else if (relation.type === 'CssImport' && relation.cssRule.media.length > 0) {
                        relationMedia = _.toArray(relation.cssRule.media);
                    }
                    if (includeMedia(relationMedia)) {
                        return true;
                    } else {
                        if (assetGraph.findRelations({to: relation.to}).length === 1) {
                            assetGraph.removeAsset(relation.to, true);
                        }
                    }
                }
                return false;
            }, function (cssAsset, incomingRelation) {
                if (cssAsset.type === 'Css') {
                    cssAsset.constructor.eachRuleInParseTree(cssAsset.parseTree, function (cssRule) {
                        if (cssRule.type === cssom.CSSRule.STYLE_RULE) {
                            document.querySelectorAll(cssRule.selectorText).forEach(function (node) {
                                if (node.nodeName === 'style' || node === document.head || node.parentNode === document.head) {
                                    return;
                                }
                                var inlineCssAsset,
                                    htmlStyleAttributeRelation = assetGraph.findRelations({
                                        from: htmlAsset,
                                        type: 'HtmlStyleAttribute',
                                        node: function (_node) {
                                            return _node === node;
                                        }
                                    })[0];
                                if (htmlStyleAttributeRelation) {
                                    inlineCssAsset = htmlStyleAttributeRelation.to;
                                } else {
                                    inlineCssAsset = new assetGraph.constructor.assets.Css({text: ""});
                                    htmlStyleAttributeRelation = new assetGraph.constructor.relations.HtmlStyleAttribute({
                                        node: node,
                                        from: htmlAsset,
                                        to: inlineCssAsset
                                    });
                                    assetGraph.addAsset(inlineCssAsset);
                                    assetGraph.addRelation(htmlStyleAttributeRelation);
                                }
                                var styleRuleIndex = inlineCssAsset.parseTree.cssRules.length;
                                inlineCssAsset.parseTree.insertRule('bogusselector {' + cssRule.style.cssText + '}', styleRuleIndex);
                                var styleRule = inlineCssAsset.parseTree.cssRules[styleRuleIndex];
                                assetGraph.findRelations({
                                    from: cssAsset,
                                    cssRule: function (_cssRule) {
                                        return _cssRule === cssRule;
                                    }
                                }).forEach(function (cssRelation) {
                                    assetGraph.addRelation(new cssRelation.constructor({
                                        cssRule: styleRule,
                                        from: inlineCssAsset,
                                        to: cssRelation.to
                                    }));
                                });
                                inlineCssAsset.markDirty();
                            });
                        } else if (cssRule.type === cssom.CSSRule.MEDIA_RULE) {
                            if (!includeMedia(_.toArray(cssRule.media))) {
                                return false;
                            }
                        }
                    });
                    if (assetGraph.findRelations({to: cssAsset}).length === 1) {
                        assetGraph.removeAsset(cssAsset, true);
                    } else {
                        incomingRelation.detach();
                    }
                }
            });
        });
    };
};