JSIncludeScript, JSIncludeCSS, and JSIncludeAsset metadata
These are similar to the -js-include-script, -js-include-css, and -js-include-asset compiler options, except that they associate these files with the specific package-level definition. So, if they are compiled into a SWC, the files are copied, and <script>/<link> tags are added, only if that definition is actually used. The compiler options do that if any definition in a SWC is used.
Works similarly to the classic [Embed] metadata with a source attribute to specify a file path that is either absolute or relative to the current .as or .mxml source file.
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCNative.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCNative.java
index 6837c0d..b8998ca 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCNative.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCNative.java
@@ -28,6 +28,7 @@
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
+import java.nio.file.Files;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
@@ -56,6 +57,9 @@
import org.apache.royale.compiler.clients.MXMLJSC.JSTargetType;
import org.apache.royale.compiler.clients.problems.ProblemQuery;
import org.apache.royale.compiler.codegen.js.IJSWriter;
+import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
import org.apache.royale.compiler.driver.IBackend;
import org.apache.royale.compiler.driver.js.IJSApplication;
import org.apache.royale.compiler.exceptions.ConfigurationException;
@@ -65,12 +69,14 @@
import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
import org.apache.royale.compiler.internal.projects.CompilerProject;
import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.scopes.ASProjectScope.DefinitionPromise;
import org.apache.royale.compiler.internal.targets.RoyaleSWCTarget;
import org.apache.royale.compiler.internal.units.SWCCompilationUnit;
import org.apache.royale.compiler.internal.watcher.WatchThread;
import org.apache.royale.compiler.internal.watcher.WatchThread.IWatchWriter;
import org.apache.royale.compiler.internal.targets.JSTarget;
import org.apache.royale.compiler.internal.workspaces.Workspace;
+import org.apache.royale.compiler.problems.FileNotFoundProblem;
import org.apache.royale.compiler.problems.ICompilerProblem;
import org.apache.royale.compiler.problems.InternalCompilerProblem;
import org.apache.royale.compiler.problems.LibraryNotFoundProblem;
@@ -420,6 +426,9 @@
processSourceMap(sourceMapTemp, baos, outputClassFile, symbol);
writeFileToZip(zipOutputStream, sourceMapFilePath, baos, fileList);
}
+
+ writeJSIncludesForCompilationUnitToZip(cu, zipOutputStream, fileList);
+
writer.close();
}
}
@@ -502,6 +511,125 @@
return true;
}
+ private void writeJSIncludesForCompilationUnitToZip(ICompilationUnit cu, ZipOutputStream zipOutputStream, StringBuilder fileList) throws IOException
+ {
+ for (IDefinition def : cu.getDefinitionPromises())
+ {
+ if (def instanceof DefinitionPromise)
+ {
+ def = ((DefinitionPromise) def).getActualDefinition();
+ }
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeScript"))
+ {
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ String includePath = metaAttr.getValue();
+
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ if (includedFile.exists() && !includedFile.isDirectory())
+ {
+ String includedFilePath = "js/scripts-meta/" + includedFile.getName();
+ if (config.isVerbose())
+ {
+ System.out.println("Writing file: " + includedFilePath);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] includedFileBytes = Files.readAllBytes(includedFile.toPath());
+ baos.write(includedFileBytes);
+ writeFileToZip(zipOutputStream, includedFilePath, baos, fileList);
+ }
+ else
+ {
+ problems.add(new FileNotFoundProblem(metaTag, includePath));
+ }
+ break;
+ }
+ }
+ }
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeCSS"))
+ {
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ String includePath = metaAttr.getValue();
+
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ if (includedFile.exists() && !includedFile.isDirectory())
+ {
+ String includedFilePath = "js/css-meta/" + includedFile.getName();
+ if (config.isVerbose())
+ {
+ System.out.println("Writing file: " + includedFilePath);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] includedFileBytes = Files.readAllBytes(includedFile.toPath());
+ baos.write(includedFileBytes);
+ writeFileToZip(zipOutputStream, includedFilePath, baos, fileList);
+ }
+ else
+ {
+ problems.add(new FileNotFoundProblem(metaTag, includePath));
+ }
+ break;
+ }
+ }
+ }
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeAsset"))
+ {
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ String includePath = metaAttr.getValue();
+
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ if (includedFile.exists() && !includedFile.isDirectory())
+ {
+ String includedFilePath = "js/assets-meta/" + includedFile.getName();
+ if (config.isVerbose())
+ {
+ System.out.println("Writing file: " + includedFilePath);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] includedFileBytes = Files.readAllBytes(includedFile.toPath());
+ baos.write(includedFileBytes);
+ writeFileToZip(zipOutputStream, includedFilePath, baos, fileList);
+ }
+ else
+ {
+ problems.add(new FileNotFoundProblem(metaTag, includePath));
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
private void processSourceMap(ByteArrayOutputStream sourceMapTemp, ByteArrayOutputStream baos, File outputClassFile, String symbol)
{
String sourceMapSourceRoot = project.config.getSourceMapSourceRoot();
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java
index b1550cd..989aa8c 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java
@@ -28,6 +28,7 @@
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
+import java.nio.file.Files;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
@@ -48,6 +49,9 @@
import org.apache.royale.compiler.clients.MXMLJSC.JSTargetType;
import org.apache.royale.compiler.clients.problems.ProblemQuery;
import org.apache.royale.compiler.codegen.js.IJSWriter;
+import org.apache.royale.compiler.definitions.IDefinition;
+import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
import org.apache.royale.compiler.driver.IBackend;
import org.apache.royale.compiler.driver.js.IJSApplication;
import org.apache.royale.compiler.exceptions.ConfigurationException;
@@ -57,12 +61,14 @@
import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate;
import org.apache.royale.compiler.internal.projects.CompilerProject;
import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.scopes.ASProjectScope.DefinitionPromise;
import org.apache.royale.compiler.internal.targets.RoyaleSWCTarget;
import org.apache.royale.compiler.internal.units.SWCCompilationUnit;
import org.apache.royale.compiler.internal.watcher.WatchThread;
import org.apache.royale.compiler.internal.watcher.WatchThread.IWatchWriter;
import org.apache.royale.compiler.internal.targets.JSTarget;
import org.apache.royale.compiler.internal.workspaces.Workspace;
+import org.apache.royale.compiler.problems.FileNotFoundProblem;
import org.apache.royale.compiler.problems.ICompilerProblem;
import org.apache.royale.compiler.problems.InternalCompilerProblem;
import org.apache.royale.compiler.problems.LibraryNotFoundProblem;
@@ -442,6 +448,9 @@
processSourceMap(sourceMapTemp, baos, outputClassFile, symbol);
writeFileToZip(zipOutputStream, sourceMapFilePath, baos, fileList);
}
+
+ writeJSIncludesForCompilationUnitToZip(cu, zipOutputStream, fileList);
+
writer.close();
}
}
@@ -569,6 +578,125 @@
return true;
}
+ private void writeJSIncludesForCompilationUnitToZip(ICompilationUnit cu, ZipOutputStream zipOutputStream, StringBuilder fileList) throws IOException
+ {
+ for (IDefinition def : cu.getDefinitionPromises())
+ {
+ if (def instanceof DefinitionPromise)
+ {
+ def = ((DefinitionPromise) def).getActualDefinition();
+ }
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeScript"))
+ {
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ String includePath = metaAttr.getValue();
+
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ if (includedFile.exists() && !includedFile.isDirectory())
+ {
+ String includedFilePath = "js/scripts-meta/" + includedFile.getName();
+ if (config.isVerbose())
+ {
+ System.out.println("Writing file: " + includedFilePath);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] includedFileBytes = Files.readAllBytes(includedFile.toPath());
+ baos.write(includedFileBytes);
+ writeFileToZip(zipOutputStream, includedFilePath, baos, fileList);
+ }
+ else
+ {
+ problems.add(new FileNotFoundProblem(metaTag, includePath));
+ }
+ break;
+ }
+ }
+ }
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeCSS"))
+ {
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ String includePath = metaAttr.getValue();
+
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ if (includedFile.exists() && !includedFile.isDirectory())
+ {
+ String includedFilePath = "js/css-meta/" + includedFile.getName();
+ if (config.isVerbose())
+ {
+ System.out.println("Writing file: " + includedFilePath);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] includedFileBytes = Files.readAllBytes(includedFile.toPath());
+ baos.write(includedFileBytes);
+ writeFileToZip(zipOutputStream, includedFilePath, baos, fileList);
+ }
+ else
+ {
+ problems.add(new FileNotFoundProblem(metaTag, includePath));
+ }
+ break;
+ }
+ }
+ }
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeAsset"))
+ {
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ String includePath = metaAttr.getValue();
+
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ if (includedFile.exists() && !includedFile.isDirectory())
+ {
+ String includedFilePath = "js/assets-meta/" + includedFile.getName();
+ if (config.isVerbose())
+ {
+ System.out.println("Writing file: " + includedFilePath);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] includedFileBytes = Files.readAllBytes(includedFile.toPath());
+ baos.write(includedFileBytes);
+ writeFileToZip(zipOutputStream, includedFilePath, baos, fileList);
+ }
+ else
+ {
+ problems.add(new FileNotFoundProblem(metaTag, includePath));
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
private void processSourceMap(ByteArrayOutputStream sourceMapTemp, ByteArrayOutputStream baos, File outputClassFile, String symbol)
{
String sourceMapSourceRoot = project.config.getSourceMapSourceRoot();
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyalePublisher.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyalePublisher.java
index 5e03d9c..76a388b 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyalePublisher.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyalePublisher.java
@@ -30,11 +30,13 @@
import org.apache.commons.io.filefilter.RegexFileFilter;
import org.apache.royale.compiler.clients.problems.ProblemQuery;
import org.apache.royale.compiler.codegen.js.royale.IJSRoyalePublisher;
+import org.apache.royale.compiler.common.ISourceLocation;
import org.apache.royale.compiler.config.Configuration;
import org.apache.royale.compiler.css.ICSSPropertyValue;
import org.apache.royale.compiler.definitions.IClassDefinition;
import org.apache.royale.compiler.definitions.IDefinition;
import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
import org.apache.royale.compiler.filespecs.IFileSpecification;
import org.apache.royale.compiler.internal.codegen.js.JSPublisher;
import org.apache.royale.compiler.internal.codegen.js.goog.JarSourceFile;
@@ -48,8 +50,11 @@
import org.apache.royale.compiler.internal.scopes.ASProjectScope.DefinitionPromise;
import org.apache.royale.compiler.internal.targets.ITargetAttributes;
import org.apache.royale.compiler.internal.units.SWCCompilationUnit;
+import org.apache.royale.compiler.problems.FileInLibraryNotFoundProblem;
import org.apache.royale.compiler.problems.FileNotFoundProblem;
import org.apache.royale.compiler.problems.HTMLTemplateFileNotFoundProblem;
+import org.apache.royale.compiler.problems.JSIncludeMetaTagNoSourceAttributeProblem;
+import org.apache.royale.compiler.problems.JSIncludeMetaTagUnknownAttributeProblem;
import org.apache.royale.compiler.units.ICompilationUnit;
import org.apache.royale.compiler.utils.JSClosureCompilerWrapper;
import org.apache.royale.swc.ISWC;
@@ -980,6 +985,11 @@
private void copyIncludeFileFromSwcToOutput(String type, ISWC swc, String swcFileKey, String fileOutputPath, ProblemQuery problems)
{
ISWCFileEntry swcFileEntry = swc.getFile(swcFileKey);
+ if (swcFileEntry == null)
+ {
+ problems.add(new FileInLibraryNotFoundProblem(swcFileKey, swc.getSWCFile().getAbsolutePath()));
+ return;
+ }
try
{
InputStream is = swcFileEntry.createInputStream();
@@ -1007,32 +1017,88 @@
}
}
- private void copyIncludeFileToOutput(String type, String originFilePath, String targetOutputPath, ProblemQuery problems)
+ private void handleJSIncludeAssetFromSWC(String type, String swcFileEntryKey, ISWC swc, StringBuilder depsHTML, ProblemQuery problems)
{
- File scriptFile = new File(originFilePath);
- if (scriptFile.exists() && !scriptFile.isDirectory())
+ String assetOutputPath = Paths.get("assets").resolve(Paths.get(swcFileEntryKey).getFileName()).toString();
+ copyIncludeFileFromSwcToOutput(type, swc, swcFileEntryKey, assetOutputPath, problems);
+ }
+
+ private void handleJSIncludeAsset(String type, File includedAssetFile, StringBuilder depsHTML, ISourceLocation sourceLocation, ProblemQuery problems)
+ {
+ String assetOutputPath = Paths.get("assets").resolve(includedAssetFile.getName()).toString();
+ copyIncludeFileToOutput(type, includedAssetFile, assetOutputPath, null, problems);
+ }
+
+ private void handleJSIncludeScriptFromSWC(String type, String swcFileEntryKey, ISWC swc, StringBuilder depsHTML, ProblemQuery problems)
+ {
+ String scriptOutputPath = Paths.get("scripts").resolve(Paths.get(swcFileEntryKey).getFileName()).toString();
+ depsHTML.append("\t<script type=\"text/javascript\" src=\"");
+ depsHTML.append(scriptOutputPath);
+ depsHTML.append("\"></script>\n");
+
+ copyIncludeFileFromSwcToOutput(type, swc, swcFileEntryKey, scriptOutputPath, problems);
+ }
+
+ private void handleJSIncludeScript(String type, File includedScriptFile, StringBuilder depsHTML, ISourceLocation sourceLocation, ProblemQuery problems)
+ {
+ String scriptOutputPath = Paths.get("scripts").resolve(includedScriptFile.getName()).toString();
+ depsHTML.append("\t<script type=\"text/javascript\" src=\"");
+ depsHTML.append(scriptOutputPath);
+ depsHTML.append("\"></script>\n");
+
+ copyIncludeFileToOutput(type, includedScriptFile, scriptOutputPath, null, problems);
+ }
+
+ private void handleJSIncludeCSSFromSWC(String type, String swcFileEntryKey, ISWC swc, StringBuilder depsHTML, ProblemQuery problems)
+ {
+ String cssOutputPath = Paths.get("css").resolve(Paths.get(swcFileEntryKey).getFileName()).toString();
+
+ depsHTML.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"");
+ depsHTML.append(cssOutputPath);
+ depsHTML.append("\">\n");
+
+ copyIncludeFileFromSwcToOutput(type, swc, swcFileEntryKey, cssOutputPath, problems);
+ }
+
+ private void handleJSIncludeCSS(String type, File includedCSSFile, StringBuilder depsHTML, ISourceLocation sourceLocation, ProblemQuery problems)
+ {
+ String cssOutputPath = Paths.get("css").resolve(includedCSSFile.getName()).toString();
+ depsHTML.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"");
+ depsHTML.append(cssOutputPath);
+ depsHTML.append("\">\n");
+
+ copyIncludeFileToOutput(type, includedCSSFile, cssOutputPath, sourceLocation, problems);
+ }
+
+ private void copyIncludeFileToOutput(String type, File originFile, String targetOutputPath, ISourceLocation sourceLocation, ProblemQuery problems)
+ {
+ if (originFile.exists() && !originFile.isDirectory())
{
try
{
if ("intermediate".equals(type))
{
final File intermediateDir = outputFolder;
- FileUtils.copyFile(scriptFile, new File(intermediateDir, targetOutputPath));
+ FileUtils.copyFile(originFile, new File(intermediateDir, targetOutputPath));
}
else
{
final File releaseDir = new File(outputParentFolder, ROYALE_RELEASE_DIR_NAME);
- FileUtils.copyFile(scriptFile, new File(releaseDir, targetOutputPath));
+ FileUtils.copyFile(originFile, new File(releaseDir, targetOutputPath));
}
}
catch (IOException e)
{
- throw new RuntimeException("Unable to copy script file: " + scriptFile.getAbsolutePath());
+ throw new RuntimeException("Unable to copy script file: " + originFile.getAbsolutePath());
}
}
+ else if (sourceLocation != null)
+ {
+ problems.add(new FileNotFoundProblem(sourceLocation, originFile.getPath()));
+ }
else
{
- problems.add(new FileNotFoundProblem(originFilePath));
+ problems.add(new FileNotFoundProblem(originFile.getPath()));
}
}
@@ -1049,7 +1115,161 @@
List<ICompilationUnit> reachableUnits = project.getReachableCompilationUnitsInSWFOrder(Arrays.asList(project.mainCU));
for (ICompilationUnit unit : reachableUnits)
{
- if (!(unit instanceof SWCCompilationUnit))
+ boolean isSWCUnit = unit instanceof SWCCompilationUnit;
+ for (IDefinition def : unit.getDefinitionPromises())
+ {
+ if (def instanceof DefinitionPromise)
+ {
+ def = ((DefinitionPromise) def).getActualDefinition();
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeScript"))
+ {
+ boolean foundSource = false;
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ foundSource = true;
+
+ String includePath = metaAttr.getValue();
+ if (isSWCUnit)
+ {
+ SWCCompilationUnit swcUnit = (SWCCompilationUnit) unit;
+ ISWC swc = swcUnit.getSWC();
+ String fileName = new File(includePath).getName();
+ String swcFileEntryPath = "js\\scripts-meta\\" + fileName;
+ ISWCFileEntry swcFileEntry = swc.getFile(swcFileEntryPath);
+ if (swcFileEntry == null)
+ {
+ swcFileEntryPath = "js/scripts-meta/" + fileName;
+ swcFileEntry = swc.getFile(swcFileEntryPath);
+ }
+ handleJSIncludeScriptFromSWC(type, swcFileEntryPath, swc, depsHTML, problems);
+ }
+ else
+ {
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ handleJSIncludeScript(type, includedFile, depsHTML, null, problems);
+ }
+ break;
+ }
+ else
+ {
+ problems.add(new JSIncludeMetaTagUnknownAttributeProblem(metaTag, key));
+ }
+ }
+ if (!foundSource)
+ {
+ problems.add(new JSIncludeMetaTagNoSourceAttributeProblem(metaTag));
+ }
+ }
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeCSS"))
+ {
+ boolean foundSource = false;
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ foundSource = true;
+
+ String includePath = metaAttr.getValue();
+
+ if (isSWCUnit)
+ {
+ SWCCompilationUnit swcUnit = (SWCCompilationUnit) unit;
+ ISWC swc = swcUnit.getSWC();
+ String fileName = new File(includePath).getName();
+ String swcFileEntryPath = "js\\css-meta\\" + fileName;
+ ISWCFileEntry swcFileEntry = swc.getFile(swcFileEntryPath);
+ if (swcFileEntry == null)
+ {
+ swcFileEntryPath = "js/css-meta/" + fileName;
+ swcFileEntry = swc.getFile(swcFileEntryPath);
+ }
+ handleJSIncludeCSSFromSWC(type, swcFileEntryPath, swc, depsHTML, problems);
+ }
+ else
+ {
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ handleJSIncludeCSS(type, includedFile, depsHTML, metaTag, problems);
+ }
+ }
+ else
+ {
+ problems.add(new JSIncludeMetaTagUnknownAttributeProblem(metaTag, key));
+ }
+ }
+ if (!foundSource)
+ {
+ problems.add(new JSIncludeMetaTagNoSourceAttributeProblem(metaTag));
+ }
+ }
+ for (IMetaTag metaTag : def.getMetaTagsByName("JSIncludeAsset"))
+ {
+ boolean foundSource = false;
+ for (IMetaTagAttribute metaAttr : metaTag.getAllAttributes())
+ {
+ String key = metaAttr.getKey();
+ if ("source".equals(key) || key == null)
+ {
+ foundSource = true;
+
+ String includePath = metaAttr.getValue();
+
+ if (isSWCUnit)
+ {
+ SWCCompilationUnit swcUnit = (SWCCompilationUnit) unit;
+ ISWC swc = swcUnit.getSWC();
+ String fileName = new File(includePath).getName();
+ String swcFileEntryPath = "js\\assets-meta\\" + fileName;
+ ISWCFileEntry swcFileEntry = swc.getFile(swcFileEntryPath);
+ if (swcFileEntry == null)
+ {
+ swcFileEntryPath = "js/assets-meta/" + fileName;
+ swcFileEntry = swc.getFile(swcFileEntryPath);
+ }
+ handleJSIncludeAssetFromSWC(type, swcFileEntryPath, swc, depsHTML, problems);
+ }
+ else
+ {
+ File includedFile = new File(includePath);
+ if (!includedFile.isAbsolute())
+ {
+ File basePath = new File(def.getContainingFilePath()).getParentFile();
+ includedFile = new File(basePath, includePath);
+ }
+
+ handleJSIncludeAsset(type, includedFile, depsHTML, metaTag, problems);
+ }
+ break;
+ }
+ else
+ {
+ problems.add(new JSIncludeMetaTagUnknownAttributeProblem(metaTag, key));
+ }
+ }
+ if (!foundSource)
+ {
+ problems.add(new JSIncludeMetaTagNoSourceAttributeProblem(metaTag));
+ }
+ }
+ }
+ }
+
+ if (!isSWCUnit)
{
continue;
}
@@ -1076,17 +1296,15 @@
{
for (String key : swc.getFiles().keySet())
{
- if (key.startsWith("js/assets") || key.startsWith("js\\assets"))
+ if (key.startsWith("js/assets/") || key.startsWith("js\\assets\\"))
{
- String assetPath = Paths.get("js").relativize(Paths.get(key)).toString();
- copyIncludeFileFromSwcToOutput(type, swc, key, assetPath, problems);
+ handleJSIncludeAssetFromSWC(type, key, swc, depsHTML, problems);
}
}
}
for (String asset : googConfiguration.getJSIncludeAsset())
{
- String assetOutputPath = Paths.get("assets").resolve(Paths.get(asset).getFileName()).toString();
- copyIncludeFileToOutput(type, asset, assetOutputPath, problems);
+ handleJSIncludeAsset(type, new File(asset), depsHTML, null, problems);
}
// included CSS appears before included JS scripts
@@ -1095,27 +1313,16 @@
{
for (String key : swc.getFiles().keySet())
{
- if (key.startsWith("js/css") || key.startsWith("js\\css"))
+ if (key.startsWith("js/css/") || key.startsWith("js\\css\\"))
{
- String cssPath = Paths.get("js").relativize(Paths.get(key)).toString();
-
- depsHTML.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"");
- depsHTML.append(cssPath);
- depsHTML.append("\">\n");
-
- copyIncludeFileFromSwcToOutput(type, swc, key, cssPath, problems);
+ handleJSIncludeCSSFromSWC(type, key, swc, depsHTML, problems);
}
}
}
for (String css : googConfiguration.getJSIncludeCss())
{
- String cssOutputPath = Paths.get("css").resolve(Paths.get(css).getFileName()).toString();
- depsHTML.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"");
- depsHTML.append(cssOutputPath);
- depsHTML.append("\">\n");
-
- copyIncludeFileToOutput(type, css, cssOutputPath, problems);
+ handleJSIncludeCSS(type, new File(css), depsHTML, null, problems);
}
// included JS scripts appear after included CSS
@@ -1125,26 +1332,16 @@
{
for (String key : swc.getFiles().keySet())
{
- if (key.startsWith("js/scripts") || key.startsWith("js\\scripts"))
+ if (key.startsWith("js/scripts/") || key.startsWith("js\\scripts\\"))
{
- String scriptPath = Paths.get("js").relativize(Paths.get(key)).toString();
- depsHTML.append("\t<script type=\"text/javascript\" src=\"");
- depsHTML.append(scriptPath);
- depsHTML.append("\"></script>\n");
-
- copyIncludeFileFromSwcToOutput(type, swc, key, scriptPath, problems);
+ handleJSIncludeScriptFromSWC(type, key, swc, depsHTML, problems);
}
}
}
for (String script : googConfiguration.getJSIncludeScript())
{
- String scriptOutputPath = Paths.get("scripts").resolve(Paths.get(script).getFileName()).toString();
- depsHTML.append("\t<script type=\"text/javascript\" src=\"");
- depsHTML.append(scriptOutputPath);
- depsHTML.append("\"></script>\n");
-
- copyIncludeFileToOutput(type, script, scriptOutputPath, problems);
+ handleJSIncludeScript(type, new File(script), depsHTML, null, problems);
}
if ("intermediate".equals(type))
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/problems/JSIncludeMetaTagNoSourceAttributeProblem.java b/compiler-jx/src/main/java/org/apache/royale/compiler/problems/JSIncludeMetaTagNoSourceAttributeProblem.java
new file mode 100644
index 0000000..0bad7b5
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/problems/JSIncludeMetaTagNoSourceAttributeProblem.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.royale.compiler.problems;
+
+import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+
+public final class JSIncludeMetaTagNoSourceAttributeProblem extends CompilerProblem
+{
+ public static final String DESCRIPTION =
+ "${metaTagName} requires a '${SOURCE}' file attribute";
+
+ public static final int errorCode = 1346;
+
+ public JSIncludeMetaTagNoSourceAttributeProblem(IMetaTag site)
+ {
+ super(site);
+ metaTagName = site.getTagName();
+ }
+
+ // Prevent these from being localized.
+ public final String SOURCE = "source";
+
+ public String metaTagName;
+}
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/problems/JSIncludeMetaTagUnknownAttributeProblem.java b/compiler-jx/src/main/java/org/apache/royale/compiler/problems/JSIncludeMetaTagUnknownAttributeProblem.java
new file mode 100644
index 0000000..1a04781
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/problems/JSIncludeMetaTagUnknownAttributeProblem.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.royale.compiler.problems;
+
+import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+
+public final class JSIncludeMetaTagUnknownAttributeProblem extends CompilerProblem
+{
+ public static final String DESCRIPTION =
+ "Unknown attribute on ${metaTagName} meta tag: ${attr}";
+
+ public static final int errorCode = 1358;
+ public JSIncludeMetaTagUnknownAttributeProblem(IMetaTag site, String attr)
+ {
+ super(site);
+ metaTagName = site.getTagName();
+ this.attr = attr;
+ }
+
+ public final String attr;
+
+ public String metaTagName;
+}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSManager.java b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSManager.java
index 1e61179..6e3fae7 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSManager.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSManager.java
@@ -284,9 +284,12 @@
if ("css".equalsIgnoreCase(suffix)
&& !fileName.contains("default")
// ignore .css files bundled with -js-include-css
- // because they are simply added as <link> tags in HTML
+ // or with [JSIncludeCSS] because they are
+ // separately added as <link> tags in HTML
&& !fileName.startsWith("js/css/")
- && !fileName.startsWith("js\\css\\"))
+ && !fileName.startsWith("js\\css\\")
+ && !fileName.startsWith("js/css-meta/")
+ && !fileName.startsWith("js\\css-meta\\"))
{
final CacheStoreKeyBase key = CSSDocumentCache.createKey(swc, fileName);
final ICSSDocument extracss = cssCache.get(key);