lib/transforms/addCacheManifest.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 path = require('path'),
    _ = require('underscore'),
    urlTools = require('../util/urlTools'),
    assets = require('../assets'),
    relations = require('../relations'),
    query = require('../query');

module.exports = function (queryObj) {
    return function addCacheManifest(assetGraph) {
        assetGraph.findAssets(_.extend({type: 'Html'}, queryObj)).forEach(function (htmlAsset) {
            if (htmlAsset.isInline) {
                throw new Error("addCacheManifestSinglePage: Cannot generate a CacheManifest for an inline Html asset");
            }
            // Look for an existing manifests for htmlAsset:
            var manifest,
                existingManifestRelations = assetGraph.findRelations({
                    from: htmlAsset,
                    type: 'HtmlCacheManifest'
                });
            if (existingManifestRelations.length === 1) {
                manifest = existingManifestRelations[0].to;
            } else if (existingManifestRelations.length > 1) {
                throw new Error("addCacheManifestSinglePage: Assertion failure: " + htmlAsset + " has more than one cache manifest relation");
            } else {
                manifest = new assets.CacheManifest({
                    url: htmlAsset.url.replace(/[?#].*$/, '').replace(/\.html$/, '') + assets.CacheManifest.prototype.defaultExtension,
                    isDirty: true,
                    parseTree: {
                        CACHE: [
                            {comment: ' ' + htmlAsset.url.replace(/.*\//, '') + ' @ ' + htmlAsset.md5Hex.substr(0, 10)}
                        ],
                        NETWORK: [
                            {tokens: ['*']}
                        ]
                    }
                });
                assetGraph.addAsset(manifest);
                new relations.HtmlCacheManifest({to: manifest}).attach(htmlAsset, 'first');
            }

            // Find all assets that can be reached from the Html file and add relations to them from the manifest:

            assetGraph.eachAssetPostOrder(htmlAsset,
                                          query.or({type: 'HtmlConditionalComment', condition: '!IE'},
                                                   {type: query.not(['HtmlAnchor', 'HtmlCacheManifest', 'HtmlConditionalComment'])}),
                                          function (asset, incomingRelation) {
                // But only if the asset isn't inline and isn't already in the manifest:
                if (!asset.isInline && asset !== htmlAsset && asset !== manifest && !assetGraph.findRelations({from: manifest, to: asset}).length) {
                    var existingManifestEntriesInCacheSection = assetGraph.findRelations({from: manifest, sectionName: 'CACHE'}),
                        position,
                        adjacentRelation;

                    if (existingManifestEntriesInCacheSection.length === 0) {
                        position = 'first';
                    } else {
                        position = 'after';
                        adjacentRelation = existingManifestEntriesInCacheSection[existingManifestEntriesInCacheSection.length - 1];
                    }
                    new relations.CacheManifestEntry({
                        sectionName: 'CACHE',
                        to: asset
                    }).attach(manifest, position, adjacentRelation);
                }
            });
        });
    };
};