You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2013/04/23 06:19:32 UTC
git commit: [flex-falcon] - CSS Support. Hide AS-side styles behind a
mediaquery with custom media -flex-flash
Updated Branches:
refs/heads/develop fd44cbf19 -> c5bd521f1
CSS Support. Hide AS-side styles behind a mediaquery with custom media -flex-flash
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/c5bd521f
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/c5bd521f
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/c5bd521f
Branch: refs/heads/develop
Commit: c5bd521f15071d6df26d56a37fe069280bbb4959
Parents: fd44cbf
Author: Alex Harui <ah...@apache.org>
Authored: Mon Apr 22 21:04:22 2013 -0700
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Apr 22 21:15:56 2013 -0700
----------------------------------------------------------------------
.../org/apache/flex/compiler/clients/MXMLJSC.java | 5 +-
.../codegen/mxml/flexjs/MXMLFlexJSPublisher.java | 19 +-
.../driver/js/flexjs/JSCSSCompilationSession.java | 29 ++
.../driver/mxml/flexjs/MXMLFlexJSBackend.java | 10 +
.../compiler/internal/projects/FlexJSProject.java | 1 +
.../compiler/internal/targets/FlexJSTarget.java | 264 +++++++++++++++
6 files changed, 324 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c5bd521f/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java b/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java
index d4d6bc3..41caa43 100644
--- a/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java
+++ b/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java
@@ -57,7 +57,6 @@ import org.apache.flex.compiler.internal.driver.js.goog.GoogBackend;
import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSBackend;
import org.apache.flex.compiler.internal.projects.CompilerProject;
import org.apache.flex.compiler.internal.projects.FlexJSProject;
-import org.apache.flex.compiler.internal.projects.FlexProject;
import org.apache.flex.compiler.internal.projects.ISourceFileHandler;
import org.apache.flex.compiler.internal.targets.JSTarget;
import org.apache.flex.compiler.internal.units.ResourceModuleCompilationUnit;
@@ -180,7 +179,7 @@ public class MXMLJSC
}
private Workspace workspace;
- private FlexProject project;
+ private FlexJSProject project;
private ProblemQuery problems;
private ISourceFileHandler asFileHandler;
private Configuration config;
@@ -327,7 +326,7 @@ public class MXMLJSC
switch (jsOutputType)
{
case FLEXJS: {
- jsPublisher = new MXMLFlexJSPublisher(config);
+ jsPublisher = new MXMLFlexJSPublisher(config, project);
break;
}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c5bd521f/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java
index 137dd61..9f461fb 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java
@@ -17,6 +17,7 @@ import org.apache.flex.compiler.config.Configuration;
import org.apache.flex.compiler.internal.codegen.js.JSSharedData;
import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogPublisher;
import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
import org.apache.flex.compiler.utils.JSClosureCompilerUtil;
import com.google.javascript.jscomp.ErrorManager;
@@ -33,14 +34,17 @@ public class MXMLFlexJSPublisher extends JSGoogPublisher implements
public static final String FLEXJS_INTERMEDIATE_DIR_NAME = "js-debug";
public static final String FLEXJS_RELEASE_DIR_NAME = "js-release";
- public MXMLFlexJSPublisher(Configuration config)
+ public MXMLFlexJSPublisher(Configuration config, FlexJSProject project)
{
super(config);
this.isMarmotinniRun = ((JSGoogConfiguration) configuration)
.getMarmotinni() != null;
+ this.project = project;
}
+ private FlexJSProject project;
+
private boolean isMarmotinniRun;
@Override
@@ -168,6 +172,8 @@ public class MXMLFlexJSPublisher extends JSGoogPublisher implements
writeHTML("intermediate", projectName, intermediateDirPath);
writeHTML("release", projectName, releaseDirPath);
+ writeCSS(projectName, intermediateDirPath);
+ writeCSS(projectName, releaseDirPath);
ArrayList<String> optionList = new ArrayList<String>();
@@ -257,6 +263,7 @@ public class MXMLFlexJSPublisher extends JSGoogPublisher implements
htmlFile.append("<head>\n");
htmlFile.append("\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n");
htmlFile.append("\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n");
+ htmlFile.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"" + projectName + ".css\">\n");
if (type == "intermediate")
{
@@ -317,4 +324,14 @@ public class MXMLFlexJSPublisher extends JSGoogPublisher implements
writeFile(dirPath + File.separator + "index.html", htmlFile.toString(),
false);
}
+
+ private void writeCSS(String projectName, String dirPath)
+ throws IOException
+ {
+ StringBuilder cssFile = new StringBuilder();
+ cssFile.append(project.cssDocument);
+
+ writeFile(dirPath + File.separator + projectName + ".css", cssFile.toString(),
+ false);
+ }
}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c5bd521f/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/flexjs/JSCSSCompilationSession.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/flexjs/JSCSSCompilationSession.java b/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/flexjs/JSCSSCompilationSession.java
new file mode 100644
index 0000000..af2612b
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/flexjs/JSCSSCompilationSession.java
@@ -0,0 +1,29 @@
+package org.apache.flex.compiler.internal.driver.js.flexjs;
+
+import org.apache.flex.compiler.css.ICSSDocument;
+import org.apache.flex.compiler.css.ICSSRule;
+import org.apache.flex.compiler.internal.css.codegen.CSSCompilationSession;
+
+import com.google.common.collect.ImmutableList;
+
+public class JSCSSCompilationSession extends CSSCompilationSession
+{
+
+ public String emitCSS()
+ {
+ final ICSSDocument css = synthesisNormalizedCSS();
+ StringBuilder sb = new StringBuilder();
+ walkCSS(css, sb);
+ return sb.toString();
+ }
+
+ private void walkCSS(ICSSDocument css, StringBuilder sb)
+ {
+ ImmutableList<ICSSRule> rules = css.getRules();
+ for (ICSSRule rule : rules)
+ {
+ sb.append(rule.toString());
+ sb.append("\n\n");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c5bd521f/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java b/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java
index cdb9845..40453e5 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java
@@ -37,10 +37,14 @@ import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSBlockWalk
import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSEmitter;
import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
import org.apache.flex.compiler.internal.driver.mxml.MXMLBackend;
+import org.apache.flex.compiler.internal.targets.FlexJSTarget;
+import org.apache.flex.compiler.internal.targets.JSTarget;
import org.apache.flex.compiler.internal.visitor.as.ASNodeSwitch;
import org.apache.flex.compiler.internal.visitor.mxml.MXMLNodeSwitch;
import org.apache.flex.compiler.problems.ICompilerProblem;
import org.apache.flex.compiler.projects.IASProject;
+import org.apache.flex.compiler.targets.ITargetProgressMonitor;
+import org.apache.flex.compiler.targets.ITargetSettings;
import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
import org.apache.flex.compiler.units.ICompilationUnit;
import org.apache.flex.compiler.visitor.IBlockVisitor;
@@ -108,4 +112,10 @@ public class MXMLFlexJSBackend extends MXMLBackend
return new MXMLWriter(project, problems, compilationUnit, enableDebug);
}
+ @Override
+ public JSTarget createTarget(IASProject project, ITargetSettings settings,
+ ITargetProgressMonitor monitor)
+ {
+ return new FlexJSTarget(project, settings, monitor);
+ }
}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c5bd521f/compiler.jx/src/org/apache/flex/compiler/internal/projects/FlexJSProject.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/projects/FlexJSProject.java b/compiler.jx/src/org/apache/flex/compiler/internal/projects/FlexJSProject.java
index 078fa34..146da37 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/projects/FlexJSProject.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/projects/FlexJSProject.java
@@ -52,6 +52,7 @@ public class FlexJSProject extends FlexProject
private HashMap<ICompilationUnit, HashMap<String, DependencyType>> requires = new HashMap<ICompilationUnit, HashMap<String, DependencyType>>();
public ICompilationUnit mainCU;
+ public String cssDocument;
@Override
public void addDependency(ICompilationUnit from, ICompilationUnit to,
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c5bd521f/compiler.jx/src/org/apache/flex/compiler/internal/targets/FlexJSTarget.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/targets/FlexJSTarget.java b/compiler.jx/src/org/apache/flex/compiler/internal/targets/FlexJSTarget.java
index a4fc149..3485f7b 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/targets/FlexJSTarget.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/targets/FlexJSTarget.java
@@ -19,10 +19,30 @@
package org.apache.flex.compiler.internal.targets;
+import java.io.File;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.flex.compiler.css.ICSSDocument;
+import org.apache.flex.compiler.css.ICSSManager;
+import org.apache.flex.compiler.definitions.IDefinition;
+import org.apache.flex.compiler.internal.css.semantics.ActivatedStyleSheets;
+import org.apache.flex.compiler.internal.driver.js.flexjs.JSCSSCompilationSession;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.units.SWCCompilationUnit;
+import org.apache.flex.compiler.problems.FileNotFoundProblem;
+import org.apache.flex.compiler.problems.ICompilerProblem;
import org.apache.flex.compiler.projects.IASProject;
import org.apache.flex.compiler.targets.IJSTarget;
import org.apache.flex.compiler.targets.ITargetProgressMonitor;
import org.apache.flex.compiler.targets.ITargetSettings;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.units.ICompilationUnit.UnitType;
+
+import com.google.common.collect.ImmutableList;
public class FlexJSTarget extends JSTarget implements IJSTarget
{
@@ -35,6 +55,250 @@ public class FlexJSTarget extends JSTarget implements IJSTarget
ITargetProgressMonitor progressMonitor)
{
super(project, targetSettings, progressMonitor);
+ flexProject = (FlexJSProject)project;
}
+
+ private final FlexJSProject flexProject;
+
+ ///////////
+ //
+ // Copied from FlexAppSWFTarget.java then modified
+ //
+ ///////////
+ /**
+ * Discovers dependent compilation units from a set of root compilation
+ * units.
+ * <p>
+ * For each public visible definition in all the compilation units, if
+ * there's an applicable CSS rule, check if the CSS rule pulls in any
+ * dependencies. (i.e. embedded assets, skin classes) Add the dependencies
+ * to the list of compilation units, and check if they have any applicable
+ * CSS rules which could pull in more dependencies. Loop until we reach a
+ * stable set of compilation units.
+ * <p>
+ * CSS rules in these CSS documents can introduce class dependencies. If any
+ * candidate rule matches a class known to be linked into the target, the
+ * candidate rule's dependencies are selected for linking. Those selected
+ * dependencies will be included in the next iteration of the dependency
+ * discovery loop.
+ * <p>
+ * Once a CSS document is "activated", it stays in this collection and its
+ * rules are tested against all classes introduced in the
+ * "dependency discovery loop".
+ * <p>
+ * For example: Suppose in project P, there are "A.as" and "styles.css", and
+ * class "A" is selected for linking.<br>
+ * In "styles.css", there're two rules:
+ *
+ * <pre>
+ * A { xSkin : ClassReference("B"); }
+ * K { xSkin : ClassReference("L"); }
+ * </pre>
+ *
+ * In the 1st iteration, rule "A" is matched, which introduces dependency on
+ * "B". <br>
+ * "B" is defined in a SWC library "myskins.swc", and there's a
+ * "defaults.css" in "myskins.swc".
+ *
+ * <pre>
+ * B { ySkin : ClassReference("C"); }
+ * A { ySkin : ClassReference("D"); }
+ * K { ySkin : ClassReference("M"); }
+ * </pre>
+ *
+ * In the 2nd iteration, rule "A" and rule "B" in "defaults.css" are
+ * matched, which introduces dependencies on "C" and "D". However, "K" has
+ * not been selected so far, so "L" and "M" are not selected.
+ * <p>
+ * Now imagine, "C" is defined in "anotherSkin.swc", and there's a
+ * "defaults.css" in "anotherSkin.swc" as well.
+ *
+ * <pre>
+ * C { zSkin : ClassReference("K"); }
+ * </pre>
+ *
+ * In the 3rd iteration, rule "C" is matched because "C" was selected in the
+ * previous iteration, which makes "K" the selected dependency.
+ * <p>
+ * At the beginning of the 4th iteration, the classes selected for linking
+ * are "A", "B", "C", "D" and "K". In this iteration, these classes will be
+ * tested against all the "activated style sheets" - "styles.css" and two
+ * "defaults.css" in "myskins.swc" and "anotherSkin.swc". "K" rules in
+ * "styles.css" and "myskins.swc" are now matched, which introduces new
+ * dependencies on "L" and "M".
+ * <p>
+ * In the 5th iteration, the classes to link are "A", "B", "C", "D", "K",
+ * "L" and "M". They are tested against all the activate CSS. No more
+ * dependencies are introduced by CSS rules, making it the last iteration of
+ * the loop.
+ *
+ * @param compilationUnits Collection of compilation units known to be
+ * linked in.
+ * @param problems Collection of {@link ICompilerProblem}'s that the each
+ * found {@link ICompilationUnit} is added to.
+ * @return All compilation units which were compiled
+ * @throws InterruptedException
+ */
+ @Override
+ protected Set<ICompilationUnit> findAllCompilationUnitsToLink(final Collection<ICompilationUnit> compilationUnits,
+ final Collection<ICompilerProblem> problems)
+ throws InterruptedException
+ {
+ JSCSSCompilationSession cssCompilationSession = new JSCSSCompilationSession();
+ cssCompilationSession.setKeepAllTypeSelectors(targetSettings.keepAllTypeSelectors());
+
+ // Performance heuristic: let's start compilation on all of the compilation
+ // units we know about up front. This is particularly useful on SWC projects where
+ // we are using "include-sources" to force a bunch of possibly unrelated classes to be
+ // compiled.
+ // Note that by putting the code here, we will start aggressive early compilation for
+ // all projects. Limited data so far shows this this is a good thing. But down the
+ // road it's possible that we might find tests cases that force us to reconsider / refine
+ // this "shotgun" approach.
+ for (ICompilationUnit cu : compilationUnits)
+ cu.startBuildAsync(getTargetType());
+
+
+ assert compilationUnits != null : "compilation units can't be null";
+ assert problems != null : "problems can't be null";
+
+ // Collection of all the compilation units that will be linked in the target.
+ final Set<ICompilationUnit> allCompilationUnitsInTarget =
+ new HashSet<ICompilationUnit>(compilationUnits);
+
+ // Collection of all the referenced CSS. Once a CSS is activated, it's always
+ // included in the dependency checking, even none of its rules are matched.
+ final ActivatedStyleSheets activatedStyleSheets = new ActivatedStyleSheets();
+
+ final ICSSManager cssManager = flexProject.getCSSManager();
+
+ collectThemes(cssManager, activatedStyleSheets, problems);
+ collectDefaultCSS(cssManager, activatedStyleSheets, problems);
+
+ // The dependency discovery loop.
+ // It terminates when no more dependencies are introduced by CSS.
+ boolean done = false;
+ while (!done)
+ {
+ //LoggingProfiler.onStartIteration();
+
+ // Get all non-CSS dependencies.
+ final Set<ICompilationUnit> dependencies =
+ getDependentCompilationUnits(allCompilationUnitsInTarget, problems);
+ //LoggingProfiler.onCompilationUnitDependenciesChanged(allCompilationUnitsInTarget, dependencies);
+ allCompilationUnitsInTarget.addAll(dependencies);
+
+ // Get all activated defaults.css from SWCs.
+ final Map<ICSSDocument, File> activatedDefaultCSSList =
+ getAllDefaultCSS(cssManager, allCompilationUnitsInTarget);
+ for (final Map.Entry<ICSSDocument, File> entry : activatedDefaultCSSList.entrySet())
+ {
+ activatedStyleSheets.addLibraryCSS(entry.getKey(), entry.getValue().getAbsolutePath());
+ }
+ //LoggingProfiler.onDefaultsCSSCollectionChanged(activatedStyleSheets);
+
+ // Get all dependencies introduced by defaults.css from SWCs.
+ final ImmutableList<IDefinition> definitions =
+ Target.getAllExternallyVisibleDefinitions(allCompilationUnitsInTarget);
+ final Collection<ICompilationUnit> cssDependencies = new HashSet<ICompilationUnit>();
+ for (final ICSSDocument cssDocument : activatedStyleSheets.all())
+ {
+ // Side-effects of this method:
+ // 1. Resolve all type selectors in the CSS model to IClassDefinition definitions.
+ // 2. Activate CSS rules whose subject is in the definition set.
+ final Collection<ICompilationUnit> dependentCUListFromCSS =
+ cssManager.getDependentCompilationUnitsFromCSS(
+ cssCompilationSession,
+ cssDocument,
+ definitions,
+ problems);
+ cssDependencies.addAll(dependentCUListFromCSS);
+ //LoggingProfiler.onCSSDependenciesChanged(dependentCUListFromCSS);
+ }
+ // If there's more dependencies introduced by CSS, the loop continues.
+ done = !allCompilationUnitsInTarget.addAll(cssDependencies);
+ }
+
+ cssCompilationSession.cssDocuments.addAll(activatedStyleSheets.sort());
+
+ try
+ {
+ flexProject.cssDocument = cssCompilationSession.emitCSS();
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return super.findAllCompilationUnitsToLink(compilationUnits, problems);
+ }
+
+ /**
+ * Collect CSS from themes.
+ */
+ private void collectThemes(
+ final ICSSManager cssManager,
+ final ActivatedStyleSheets activatedStyleSheets,
+ final Collection<ICompilerProblem> problems)
+ {
+ final Collection<ICSSDocument> cssFromThemes = cssManager.getCSSFromThemes(problems);
+ for (final ICSSDocument themeCSS : cssFromThemes)
+ {
+ // Theme files are sorted by declaration order instead of filenames, so we needn't
+ // their filenames here.
+ activatedStyleSheets.addThemeCSS(themeCSS);
+ }
+ }
+
+ /**
+ * Collect CSS from 'defaults-css-files' configuration option.
+ */
+ private void collectDefaultCSS(
+ final ICSSManager cssManager,
+ final ActivatedStyleSheets activatedStyleSheets,
+ final Collection<ICompilerProblem> problems)
+ {
+ for (final String defaultsCSSPath : getTargetSettings().getDefaultsCSSFiles())
+ {
+ final ICSSDocument defaultsCSSModel = cssManager.getCSS(defaultsCSSPath);
+ if (defaultsCSSModel == null)
+ problems.add(new FileNotFoundProblem(defaultsCSSPath));
+ else
+ activatedStyleSheets.addDefaultCSS(defaultsCSSModel);
+ }
+ }
+
+ /**
+ * Find all the {@link SWCCompilationUnit}'s, and return the default CSS
+ * model in the SWCs.
+ *
+ * @param cssManager Project-level CSS manager.
+ * @param compilationUnits All the compilation units. Non-SWC compilation
+ * units are ignored.
+ * @return Model of the default CSS in the SWCs. The map keys are CSS
+ * models; the values are the enclosing SWC file.
+ */
+ private static Map<ICSSDocument, File> getAllDefaultCSS(
+ final ICSSManager cssManager,
+ final Collection<ICompilationUnit> compilationUnits)
+ {
+ assert cssManager != null : "Expected CSS manager.";
+ assert compilationUnits != null : "Expected collection of compilation units.";
+
+ final Map<ICSSDocument, File> result = new HashMap<ICSSDocument, File>();
+ for (final ICompilationUnit compilationUnit : compilationUnits)
+ {
+ if (compilationUnit.getCompilationUnitType() == UnitType.SWC_UNIT)
+ {
+ final File swcFile = new File(compilationUnit.getAbsoluteFilename());
+ final ICSSDocument defaultCSS = cssManager.getDefaultCSS(swcFile);
+ if (defaultCSS != null)
+ result.put(defaultCSS, swcFile);
+ }
+ }
+ return result;
+ }
+
}