我最终做的是进一步调查,发现我可以将它添加到所有排列脚本中,而不是在主机页面中添加清单引用。清单本身可以是一个通用(实际上是空的)文件:
鼓励作者也将主页包含在清单中,但实际上引用清单的页面会自动缓存,即使没有明确提及。(来源)
因此,我写了一个简单Linker
的:
- 创建脱机清单文件
- 将
manifest
属性添加到<html>
所有排列脚本 ( *.cache.html
) 的标记中。
被Linker
称为ManifestLinker
并且相当简单:
package com.example.linker;
// Imports
@LinkerOrder(Order.POST)
public class ManifestLinker extends AbstractLinker {
private static final String MANIFEST_FILE = "manifest.nocache.appcache";
private static final String HTML_FIND = "<html>";
private static final String HTML_REPLACE = "<html manifest=\"" + MANIFEST_FILE + "\">";
/* (non-Javadoc)
* @see com.google.gwt.core.ext.Linker#getDescription()
*/
@Override
public String getDescription() {
return "`Manifest Linker`: Adds AppCache support for static `.cache.html` resources.";
}
@Override
public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet artifacts) throws UnableToCompleteException {
ArtifactSet output = new ArtifactSet(artifacts);
output.add(buildManifest(logger));
for (EmittedArtifact artifact : artifacts.find(EmittedArtifact.class)) {
if (artifact.getVisibility() == Visibility.Public && artifact.getPartialPath().endsWith(".cache.html")) {
logger.log(TreeLogger.TRACE, "Processing file: " + artifact.getPartialPath());
String cacheHtml = Util.readStreamAsString(artifact.getContents(logger));
if (cacheHtml.startsWith(HTML_FIND)) {
cacheHtml = HTML_REPLACE + cacheHtml.substring(HTML_FIND.length()); // Replace `<html>` tag.
output.replace(copyArtifact(logger, artifact, cacheHtml));
}
}
}
logger.log(TreeLogger.INFO, "Manifest created and linked successfully.");
return output;
}
private EmittedArtifact copyArtifact(TreeLogger logger, EmittedArtifact original, String contents) throws UnableToCompleteException {
EmittedArtifact copy = emitString(logger, contents, original.getPartialPath());
copy.setVisibility(original.getVisibility());
return copy;
}
private EmittedArtifact buildManifest(TreeLogger logger) throws UnableToCompleteException {
StringBuilder builder = new StringBuilder();
builder.append("CACHE MANIFEST\n")
.append("# Generated by ")
.append(getClass().getSimpleName())
.append(": ")
.append(System.currentTimeMillis())
.append(".\n\n")
.append("NETWORK:\n")
.append("*\n");
SyntheticArtifact manifest = emitString(logger, builder.toString(), MANIFEST_FILE);
return manifest;
}
}
在我的<module>.gwt.xml
文件中,我定义并添加了链接器:
<?xml version="1.0" encoding="UTF-8"?>
<module>
...
<define-linker name="manifest" class="com.example.linker.ManifestLinker" />
<add-linker name="manifest" />
...
另外,我确保通过我的设置正确的内容类型web.xml
:
...
<mime-mapping>
<extension>appcache</extension>
<mime-type>text/cache-manifest</mime-type>
</mime-mapping>
...
发出manifest.nocache.appcache
的也很简单:
CACHE MANIFEST
# Generated by ManifestLinker: 1366702621298.
NETWORK:
*