diff options
Diffstat (limited to 'jsquery/src/main')
24 files changed, 1522 insertions, 5 deletions
diff --git a/jsquery/src/main/java/com/google/gwt/dev/javac/StandardGeneratorContext.java b/jsquery/src/main/java/com/google/gwt/dev/javac/StandardGeneratorContext.java new file mode 100644 index 00000000..8ea2f1e6 --- /dev/null +++ b/jsquery/src/main/java/com/google/gwt/dev/javac/StandardGeneratorContext.java @@ -0,0 +1,834 @@ +/* + * Copyright 2007 Google Inc. + * + * Licensed 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 com.google.gwt.dev.javac; + +import com.google.gwt.core.ext.Generator; +import com.google.gwt.core.ext.GeneratorContext; +import com.google.gwt.core.ext.GeneratorContextExt; +import com.google.gwt.core.ext.GeneratorExt; +import com.google.gwt.core.ext.GeneratorExtWrapper; +import com.google.gwt.core.ext.PropertyOracle; +import com.google.gwt.core.ext.TreeLogger; +import com.google.gwt.core.ext.UnableToCompleteException; +import com.google.gwt.core.ext.linker.Artifact; +import com.google.gwt.core.ext.linker.ArtifactSet; +import com.google.gwt.core.ext.linker.GeneratedResource; +import com.google.gwt.core.ext.linker.impl.StandardGeneratedResource; +import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.core.ext.typeinfo.TypeOracle; +import com.google.gwt.dev.cfg.ModuleDef; +import com.google.gwt.dev.javac.rebind.CachedRebindResult; +import com.google.gwt.dev.javac.rebind.RebindResult; +import com.google.gwt.dev.javac.rebind.RebindRuleResolver; +import com.google.gwt.dev.javac.rebind.RebindStatus; +import com.google.gwt.dev.resource.ResourceOracle; +import com.google.gwt.dev.util.DiskCache; +import com.google.gwt.dev.util.Util; +import com.google.gwt.dev.util.collect.HashSet; +import com.google.gwt.dev.util.collect.IdentityHashMap; +import com.google.gwt.dev.util.log.speedtracer.CompilerEventType; +import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger; +import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event; +import com.google.gwt.util.tools.Utility; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.SortedSet; + +/** + * Manages generators and generated units during a single compilation. + */ +public class StandardGeneratorContext implements GeneratorContextExt { + + /** + * Extras added to {@link GeneratedUnit}. + */ + private static interface Generated extends GeneratedUnit { + void abort(); + + void commit(TreeLogger logger); + + /** + * Returns the strong hash of the source. + */ + String getStrongHash(); + + String getTypeName(); + } + + /** + * This generated unit acts as a normal generated unit as well as a buffer + * into which generators can write their source. A controller should ensure + * that source isn't requested until the generator has finished writing it. + * This version is backed by {@link StandardGeneratorContext#diskCache}. + */ + private static class GeneratedUnitImpl implements Generated { + + /** + * A token to retrieve this object's bytes from the disk cache. + */ + protected long sourceToken = -1; + + private long creationTime; + + private String strongHash; // cache so that refreshes work correctly + + private StringWriter sw; + + private final String typeName; + + public GeneratedUnitImpl(StringWriter sw, String typeName) { + this.typeName = typeName; + this.sw = sw; + } + + public void abort() { + sw = null; + } + + /** + * Finalizes the source and adds this generated unit to the host. + */ + public void commit(TreeLogger logger) { + String source = sw.toString(); + System.out.println(">>>>> \n" + source); + strongHash = Util.computeStrongName(Util.getBytes(source)); + sourceToken = diskCache.writeString(source); + sw = null; + creationTime = System.currentTimeMillis(); + } + + public long creationTime() { + return creationTime; + } + + public String getSource() { + if (sw != null) { + throw new IllegalStateException("source not committed"); + } + return diskCache.readString(sourceToken); + } + + public long getSourceToken() { + if (sw != null) { + throw new IllegalStateException("source not committed"); + } + return sourceToken; + } + + public String getStrongHash() { + return strongHash; + } + + public String getTypeName() { + return typeName; + } + + public String optionalFileLocation() { + return null; + } + } + + /** + * This generated unit acts as a normal generated unit as well as a buffer + * into which generators can write their source. A controller should ensure + * that source isn't requested until the generator has finished writing it. + * This version is backed by an explicit generated file. + */ + private static class GeneratedUnitWithFile extends GeneratedUnitImpl { + private final File file; + + public GeneratedUnitWithFile(File file, StringWriter pw, String typeName) { + super(pw, typeName); + this.file = file; + } + + @Override + public void commit(TreeLogger logger) { + super.commit(logger); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + diskCache.transferToStream(sourceToken, fos); + } catch (IOException e) { + logger.log(TreeLogger.WARN, "Error writing out generated unit at '" + + file.getAbsolutePath() + "': " + e); + } finally { + Utility.close(fos); + } + } + + @Override + public String optionalFileLocation() { + return file.exists() ? file.getAbsolutePath() : null; + } + } + + /** + * Manages a resource that is in the process of being created by a generator. + */ + private static class PendingResource extends OutputStream { + + private ByteArrayOutputStream baos = new ByteArrayOutputStream(); + private final String partialPath; + + public PendingResource(String partialPath) { + this.partialPath = partialPath; + } + + public void abort() { + baos = null; + } + + public String getPartialPath() { + return partialPath; + } + + public byte[] takeBytes() { + byte[] result = baos.toByteArray(); + baos = null; + return result; + } + + @Override + public void write(byte[] b) throws IOException { + if (baos == null) { + throw new IOException("stream closed"); + } + baos.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (baos == null) { + throw new IOException("stream closed"); + } + baos.write(b, off, len); + } + + @Override + public void write(int b) throws IOException { + if (baos == null) { + throw new IOException("stream closed"); + } + baos.write(b); + } + } + + private static DiskCache diskCache = DiskCache.INSTANCE; + + private static final Map<String, CompilerEventType> eventsByGeneratorType = + new HashMap<String, CompilerEventType>(); + static { + eventsByGeneratorType.put( + "com.google.gwt.resources.rebind.context.InlineClientBundleGenerator", + CompilerEventType.GENERATOR_CLIENT_BUNDLE); + eventsByGeneratorType.put("com.google.gwt.i18n.rebind.LocalizableGenerator", + CompilerEventType.GENERATOR_I18N); + eventsByGeneratorType.put("com.google.gwt.i18n.rebind.LocaleInfoGenerator", + CompilerEventType.GENERATOR_I18N); + eventsByGeneratorType.put("com.google.gwt.i18n.rebind.CurrencyListGenerator", + CompilerEventType.GENERATOR_I18N); + eventsByGeneratorType.put("com.google.gwt.i18n.rebind.CustomDateTimeFormatGenerator", + CompilerEventType.GENERATOR_I18N); + eventsByGeneratorType.put("com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator", + CompilerEventType.GENERATOR_RPC); + eventsByGeneratorType.put("com.google.gwt.rpc.rebind.RpcServiceGenerator", + CompilerEventType.GENERATOR_RPC); // deRPC + eventsByGeneratorType.put("com.google.gwt.uibinder.rebind.UiBinderGenerator", + CompilerEventType.GENERATOR_UIBINDER); + eventsByGeneratorType.put("com.google.gwt.inject.rebind.GinjectorGenerator", + CompilerEventType.GENERATOR_GIN); + } + + private final ArtifactSet allGeneratedArtifacts; + + private final Map<String, GeneratedUnit> committedGeneratedCups = + new HashMap<String, GeneratedUnit>(); + + private CompilationState compilationState; + + private Class<? extends Generator> currentGenerator; + + private final File genDir; + + private final Map<Class<? extends Generator>, Generator> generators = + new IdentityHashMap<Class<? extends Generator>, Generator>(); + + private final ModuleDef module; + + private ArtifactSet newlyGeneratedArtifacts = new ArtifactSet(); + + private final Set<String> newlyGeneratedTypeNames = new HashSet<String>(); + + private final Map<String, PendingResource> pendingResources = + new HashMap<String, PendingResource>(); + + private transient PropertyOracle propOracle; + + private RebindRuleResolver rebindRuleResolver; + + private final Map<PrintWriter, Generated> uncommittedGeneratedCupsByPrintWriter = + new IdentityHashMap<PrintWriter, Generated>(); + + private CachedRebindResult cachedRebindResult = null; + + private boolean generatorResultCachingEnabled = false; + + private List<String> cachedTypeNamesToReuse = null; + + private boolean isProdMode; + + /** + * Normally, the compiler host would be aware of the same types that are + * available in the supplied type oracle although it isn't strictly required. + */ + public StandardGeneratorContext(CompilationState compilationState, ModuleDef module, File genDir, + ArtifactSet allGeneratedArtifacts, boolean isProdMode) { + this.compilationState = compilationState; + this.module = module; + this.genDir = genDir; + this.allGeneratedArtifacts = allGeneratedArtifacts; + this.isProdMode = isProdMode; + } + + /** + * Adds a generated unit to the context if not already present, but will not + * overwrite an existing unit. + */ + public void addGeneratedUnit(GeneratedUnit gu) { + if (!committedGeneratedCups.containsKey(gu.getTypeName())) { + committedGeneratedCups.put(gu.getTypeName(), gu); + } + } + + /** + * Adds generated units to the context, but will not overwrite any existing + * units that might already be present. + */ + public void addGeneratedUnits(Collection<GeneratedUnit> generatedUnits) { + for (GeneratedUnit gu : generatedUnits) { + addGeneratedUnit(gu); + } + } + + /** + * Adds all available cached generated units to the context. Existing units + * for a given type will not be overwritten. + */ + public void addGeneratedUnitsFromCache() { + if (cachedRebindResult != null && cachedRebindResult.getGeneratedUnits() != null) { + addGeneratedUnits(cachedRebindResult.getGeneratedUnits()); + } + } + + /** + * Adds cached generated units to the context that have been marked for reuse. + * Existing units for a given type will not be overwritten. + */ + public void addGeneratedUnitsMarkedForReuseFromCache() { + if (cachedTypeNamesToReuse != null && cachedRebindResult != null) { + for (String typeName : cachedTypeNamesToReuse) { + GeneratedUnit gu = cachedRebindResult.getGeneratedUnit(typeName); + if (gu != null) { + addGeneratedUnit(gu); + } + } + } + } + + /** + * Checks whether a rebind rule is available for a given sourceTypeName. + */ + public boolean checkRebindRuleAvailable(String sourceTypeName) { + if (rebindRuleResolver != null) { + return rebindRuleResolver.checkRebindRuleResolvable(sourceTypeName); + } else { + return false; + } + } + + /** + * Frees memory used up by compilation state. + */ + public void clear() { + compilationState = null; + generators.clear(); + } + + /** + * Commits a pending generated type. + */ + public final void commit(TreeLogger logger, PrintWriter pw) { + Generated gcup = uncommittedGeneratedCupsByPrintWriter.get(pw); + if (gcup != null) { + gcup.commit(logger); + uncommittedGeneratedCupsByPrintWriter.remove(pw); + committedGeneratedCups.put(gcup.getTypeName(), gcup); + } else { + logger.log(TreeLogger.WARN, "Generator attempted to commit an unknown PrintWriter", null); + } + } + + /** + * Adds an Artifact to the context's ArtifactSets. This will replace a + * pre-existing entry in allGeneratedArtifacts, but will not overwrite an + * entry in the newlyGeneratedArtifacts (since it is assumed by convention + * that only new entries will ever be inserted here for a given generator + * run). + */ + public void commitArtifact(TreeLogger logger, Artifact<?> artifact) { + allGeneratedArtifacts.replace(artifact); + newlyGeneratedArtifacts.add(artifact); + } + + /** + * Commits all available cached Artifacts to the context. + */ + public void commitArtifactsFromCache(TreeLogger logger) { + if (cachedRebindResult != null && cachedRebindResult.getArtifacts() != null) { + for (Artifact<?> art : cachedRebindResult.getArtifacts()) { + commitArtifact(logger, art); + } + } + } + + public GeneratedResource commitResource(TreeLogger logger, OutputStream os) + throws UnableToCompleteException { + + PendingResource pendingResource = null; + String partialPath = null; + if (os instanceof PendingResource) { + pendingResource = (PendingResource) os; + partialPath = pendingResource.getPartialPath(); + // Make sure it's ours by looking it up in the map. + if (pendingResource != pendingResources.get(partialPath)) { + pendingResource = null; + } + } + if (pendingResource == null) { + logger.log(TreeLogger.WARN, "Generator attempted to commit an unknown OutputStream", null); + throw new UnableToCompleteException(); + } + + // Add the GeneratedResource to the ArtifactSet + GeneratedResource toReturn = + new StandardGeneratedResource(currentGenerator, partialPath, pendingResource.takeBytes()); + commitArtifact(logger, toReturn); + pendingResources.remove(pendingResource.getPartialPath()); + return toReturn; + } + + /** + * Call this whenever generators are known to not be running to clear out + * uncommitted compilation units and to force committed compilation units to + * be parsed and added to the type oracle. + * + * @return any newly generated artifacts since the last call + */ + public final ArtifactSet finish(TreeLogger logger) { + abortUncommittedResources(logger); + + try { + TreeLogger branch; + if (!committedGeneratedCups.isEmpty()) { + // Assimilate the new types into the type oracle. + // + String msg = "Assimilating generated source"; + branch = logger.branch(TreeLogger.DEBUG, msg, null); + + TreeLogger subBranch = null; + if (branch.isLoggable(TreeLogger.DEBUG)) { + subBranch = branch.branch(TreeLogger.DEBUG, "Generated source files...", null); + } + + for (GeneratedUnit gcup : committedGeneratedCups.values()) { + String qualifiedTypeName = gcup.getTypeName(); + if (subBranch != null) { + subBranch.log(TreeLogger.DEBUG, qualifiedTypeName, null); + } + } + + compilationState.addGeneratedCompilationUnits(logger, committedGeneratedCups.values()); + } + return newlyGeneratedArtifacts; + } finally { + + // Remind the user if there uncommitted cups. + if (!uncommittedGeneratedCupsByPrintWriter.isEmpty()) { + String msg = + "For the following type(s), generated source was never committed (did you forget to call commit()?)"; + logger = logger.branch(TreeLogger.WARN, msg, null); + + for (Generated unit : uncommittedGeneratedCupsByPrintWriter.values()) { + logger.log(TreeLogger.WARN, unit.getTypeName(), null); + } + } + + uncommittedGeneratedCupsByPrintWriter.clear(); + committedGeneratedCups.clear(); + newlyGeneratedTypeNames.clear(); + newlyGeneratedArtifacts = new ArtifactSet(); + cachedRebindResult = null; + cachedTypeNamesToReuse = null; + } + } + + public Set<String> getActiveLinkerNames() { + return module.getActiveLinkerNames(); + } + + /** + * Gets newly committed artifacts. + */ + public ArtifactSet getArtifacts() { + return new ArtifactSet(newlyGeneratedArtifacts); + } + + /** + * Gets the previously cached rebind result for the current generator. + */ + public CachedRebindResult getCachedGeneratorResult() { + return cachedRebindResult; + } + + public GeneratorContext getCanonicalContext() { + return this; + } + + public CompilationState getCompilationState() { + return compilationState; + } + + /** + * Gets all committed Java units. + */ + public Map<String, GeneratedUnit> getGeneratedUnitMap() { + return committedGeneratedCups; + } + + public final PropertyOracle getPropertyOracle() { + return propOracle; + } + + public ResourceOracle getResourcesOracle() { + return module.getResourcesOracle(); + } + + public final TypeOracle getTypeOracle() { + return compilationState.getTypeOracle(); + } + + public boolean isGeneratorResultCachingEnabled() { + return generatorResultCachingEnabled; + } + + public boolean isProdMode() { + return isProdMode; + } + + /** + * Adds a type name to the list of types to be reused from cache, if + * available. + * + * @param typeName The fully qualified name of a type. + * + * @return true, if the type is available in the cache and was successfully + * added to the list for reuse, false otherwise. + */ + public boolean reuseTypeFromCacheIfAvailable(String typeName) { + if (!isGeneratorResultCachingEnabled() || cachedRebindResult == null + || !cachedRebindResult.isTypeCached(typeName)) { + return false; + } + + if (cachedTypeNamesToReuse == null) { + cachedTypeNamesToReuse = new ArrayList<String>(); + } + cachedTypeNamesToReuse.add(typeName); + return true; + } + + /** + * This method is maintained for backwards compatibility. + * {@link #runGeneratorIncrementally} should be used instead. + */ + public String runGenerator(TreeLogger logger, Class<? extends Generator> generatorClass, + String typeName) throws UnableToCompleteException { + + RebindResult result = runGeneratorIncrementally(logger, generatorClass, typeName); + + return result.getReturnedTypeName(); + } + + /** + * Runs a generator incrementally, with support for managing the returned + * {@link RebindResult} object, which can contain status and cached results. + * This is a replacement for the {@link #runGenerator} method. + * <p> + * If the passed in generatorClass is an instance of {@link GeneratorExt}, + * it's {@link GeneratorExt#generateIncrementally} method will be called. + * <p> + * Otherwise, for backwards compatibility, the generatorClass will be wrapped + * in a {@link GeneratorExt} instance, and it's {@link Generator#generate} + * method will be called. + * + * @param logger + * @param generatorClass + * @param typeName + * @return a RebindResult + * @throws UnableToCompleteException + */ + public RebindResult runGeneratorIncrementally(TreeLogger logger, + Class<? extends Generator> generatorClass, String typeName) throws UnableToCompleteException { + String msg = "Invoking generator " + generatorClass.getName(); + logger = logger.branch(TreeLogger.DEBUG, msg, null); + + Generator generator = generators.get(generatorClass); + if (generator == null) { + try { + generator = generatorClass.newInstance(); + generators.put(generatorClass, generator); + } catch (Throwable e) { + logger.log(TreeLogger.ERROR, "Unexpected error trying to instantiate Generator '" + + generatorClass.getName() + "'", e); + throw new UnableToCompleteException(); + } + } + + setCurrentGenerator(generatorClass); + + // Avoid call to System.currentTimeMillis() if not logging DEBUG level + boolean loggable = logger.isLoggable(TreeLogger.DEBUG); + long before = loggable ? System.currentTimeMillis() : 0L; + String generatorClassName = generator.getClass().getName(); + CompilerEventType type = eventsByGeneratorType.get(generatorClassName); + + if (type == null) { + type = CompilerEventType.GENERATOR_OTHER; + } + + Event generatorEvent = + SpeedTracerLogger.start(type, "class", generatorClassName, "type", typeName); + + try { + GeneratorExt generatorExt; + if (generator instanceof GeneratorExt) { + generatorExt = (GeneratorExt) generator; + } else { + generatorExt = GeneratorExtWrapper.newInstance(generator); + } + + RebindResult result; + result = generatorExt.generateIncrementally(logger, this, typeName); + + if (loggable) { + if (result.getResultStatus() == RebindStatus.USE_EXISTING) { + msg = "Generator did not return a new class, type will be used as is"; + } else { + msg = "Generator returned class '" + result.getReturnedTypeName() + "'"; + } + long after = System.currentTimeMillis(); + msg += "; in " + (after - before) + " ms"; + logger.log(TreeLogger.DEBUG, msg, null); + } + return result; + } catch (AssertionError e) { + // Catch and log the assertion as a convenience to the developer + logger.log(TreeLogger.ERROR, "Generator '" + generatorClass.getName() + + "' failed an assertion while rebinding '" + typeName + "'", e); + throw new UnableToCompleteException(); + } catch (RuntimeException e) { + logger.log(TreeLogger.ERROR, "Generator '" + generatorClass.getName() + + "' threw an exception while rebinding '" + typeName + "'", e); + throw new UnableToCompleteException(); + } finally { + generatorEvent.end(); + } + } + + /** + * Set previously cached rebind result for currently active generator. + */ + public void setCachedGeneratorResult(CachedRebindResult cachedRebindResult) { + this.cachedRebindResult = cachedRebindResult; + } + + public void setCurrentGenerator(Class<? extends Generator> currentGenerator) { + this.currentGenerator = currentGenerator; + } + + public void setGeneratorResultCachingEnabled(boolean enabled) { + this.generatorResultCachingEnabled = enabled; + } + + /** + * Sets the current transient property oracle to answer current property + * questions. + */ + public void setPropertyOracle(PropertyOracle propOracle) { + this.propOracle = propOracle; + } + + public void setRebindRuleResolver(RebindRuleResolver resolver) { + this.rebindRuleResolver = resolver; + } + + public final PrintWriter tryCreate(TreeLogger logger, String packageName, String simpleTypeName) { + String typeName; + if (packageName.length() == 0) { + typeName = simpleTypeName; + } else { + typeName = packageName + '.' + simpleTypeName; + } + // Is type already known to the host? + JClassType existingType = getTypeOracle().findType(packageName, simpleTypeName); + if (existingType != null) { + if (logger.isLoggable(TreeLogger.DEBUG)) { + logger.log(TreeLogger.DEBUG, "Type '" + typeName + + "' already exists and will not be re-created ", null); + } + return null; + } + + // Type recently generated? + if (newlyGeneratedTypeNames.contains(typeName)) { + return null; + } + + // The type isn't there, so we can let the caller create it. Remember that + // it is pending so another attempt to create the same type will fail. + Generated gcup; + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw, true) { + /** + * Overridden to force unix-style line endings for consistent behavior + * across platforms. + */ + @Override + public void println() { + super.print('\n'); + super.flush(); + } + }; + if (this.genDir == null) { + gcup = new GeneratedUnitImpl(sw, typeName); + } else { + File dir = new File(genDir, packageName.replace('.', File.separatorChar)); + // No need to check mkdirs result because an IOException will occur anyway + dir.mkdirs(); + File srcFile = new File(dir, simpleTypeName + ".java"); + if (srcFile.exists()) { + srcFile.delete(); + } + gcup = new GeneratedUnitWithFile(srcFile, sw, typeName); + } + uncommittedGeneratedCupsByPrintWriter.put(pw, gcup); + newlyGeneratedTypeNames.add(typeName); + return pw; + } + + public OutputStream tryCreateResource(TreeLogger logger, String partialPath) + throws UnableToCompleteException { + + logger = + logger.branch(TreeLogger.DEBUG, "Preparing pending output resource '" + partialPath + "'", + null); + + // Disallow null or empty names. + if (partialPath == null || partialPath.trim().equals("")) { + logger.log(TreeLogger.ERROR, "The resource name must be a non-empty string", null); + throw new UnableToCompleteException(); + } + + // Disallow absolute paths. + if (new File(partialPath).isAbsolute()) { + logger + .log( + TreeLogger.ERROR, + "Resource paths are intended to be relative to the compiled output directory and cannot be absolute", + null); + throw new UnableToCompleteException(); + } + + // Disallow backslashes (to promote consistency in calling code). + if (partialPath.indexOf('\\') >= 0) { + logger.log(TreeLogger.ERROR, + "Resource paths must contain forward slashes (not backslashes) to denote subdirectories", + null); + throw new UnableToCompleteException(); + } + + // Check for public path collision. + if (module.findPublicFile(partialPath) != null) { + logger.log(TreeLogger.WARN, "Cannot create resource '" + partialPath + + "' because it already exists on the public path", null); + return null; + } + + // See if the file is already committed. + SortedSet<GeneratedResource> resources = allGeneratedArtifacts.find(GeneratedResource.class); + for (GeneratedResource resource : resources) { + if (partialPath.equals(resource.getPartialPath())) { + return null; + } + } + + // See if the file is pending. + if (pendingResources.containsKey(partialPath)) { + // It is already pending. + logger.log(TreeLogger.WARN, "The file '" + partialPath + "' is already a pending resource", + null); + return null; + } + PendingResource pendingResource = new PendingResource(partialPath); + pendingResources.put(partialPath, pendingResource); + return pendingResource; + } + + private void abortUncommittedResources(TreeLogger logger) { + if (pendingResources.isEmpty()) { + // Nothing to do. + return; + } + + // Warn the user about uncommitted resources. + logger = + logger + .branch( + TreeLogger.WARN, + "The following resources will not be created because they were never committed (did you forget to call commit()?)", + null); + + for (Entry<String, PendingResource> entry : pendingResources.entrySet()) { + logger.log(TreeLogger.WARN, entry.getKey()); + entry.getValue().abort(); + } + pendingResources.clear(); + } +} diff --git a/jsquery/src/main/java/com/google/gwt/query/jsquery/JsQuery.gwt.xml b/jsquery/src/main/java/com/google/gwt/query/jsquery/JsQuery.gwt.xml new file mode 100644 index 00000000..92c82aaf --- /dev/null +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/JsQuery.gwt.xml @@ -0,0 +1,8 @@ +<module> + <inherits name='com.google.gwt.query.Query' /> + + <entry-point class="com.google.gwt.query.jsquery.client.JsQuery" /> + <inherits name='org.timepedia.exporter.Exporter' /> + <set-property name="export" value="yes" /> +</module> + diff --git a/jsquery/src/main/java/com/google/gwt/query/jsquery/JsQueryApi.gwt.xml b/jsquery/src/main/java/com/google/gwt/query/jsquery/JsQueryApi.gwt.xml new file mode 100644 index 00000000..e30aed82 --- /dev/null +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/JsQueryApi.gwt.xml @@ -0,0 +1,40 @@ +<!-- + This Module creates a javascript library able to replace jquery.js +--> +<module rename-to='jsquery'> + <inherits name='com.google.gwt.query.jsquery.JsQuery' /> + + <entry-point class="com.google.gwt.query.jsquery.client.JsQueryApi" /> + + <!-- Minimize JS --> + <set-property name="compiler.stackMode" value="strip"/> + + <!-- cross-site --> + <add-linker name="xsiframe"/> + + <!-- + Hack to put code into the jsquery.nocache.js so as $ is available early + and we can handle the $().ready method which is widely used in jquery pages. + Otherwise $ wont be available until the async loading of the gwt permutation + which happens after the page was ready. + --> + <define-property name="onload" values="default, foo"/> + <property-provider name="onload"> + <![CDATA[ + $wnd.JsQuery = { + onLoadArray: [], + onLoad: function() { + for (i in $wnd.JsQuery.onLoadArray) + $wnd.JsQuery.onLoadArray[i](); + }, + ready: function(f) { + $wnd.JsQuery.onLoadArray.push(f); + } + }; + $wnd._$_ = $wnd.$; + $wnd.$ = function() {return $wnd.JsQuery;} + return 'default'; + ]]> + </property-provider> +</module> + diff --git a/jsquery/src/main/java/com/google/gwt/query/jsquery/client/GQueryOverlay.java b/jsquery/src/main/java/com/google/gwt/query/jsquery/client/GQueryOverlay.java new file mode 100644 index 00000000..e407a89e --- /dev/null +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/client/GQueryOverlay.java @@ -0,0 +1,397 @@ +package com.google.gwt.query.jsquery.client; + +import org.timepedia.exporter.client.Export; +import org.timepedia.exporter.client.ExportAfterCreateMethod; +import org.timepedia.exporter.client.ExportClosure; +import org.timepedia.exporter.client.ExportInstanceMethod; +import org.timepedia.exporter.client.ExportJsInitMethod; +import org.timepedia.exporter.client.ExportOverlay; +import org.timepedia.exporter.client.ExportPackage; +import org.timepedia.exporter.client.ExportStaticMethod; +import org.timepedia.exporter.client.ExporterUtil; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Node; +import com.google.gwt.dom.client.NodeList; +import com.google.gwt.query.client.Function; +import com.google.gwt.query.client.GQuery; +import com.google.gwt.query.client.GQuery.Offset; +import com.google.gwt.query.client.Predicate; +import com.google.gwt.query.client.Properties; +import com.google.gwt.query.client.js.JsUtils; +import com.google.gwt.query.client.plugins.Effects; +import com.google.gwt.query.client.plugins.effects.PropertiesAnimation; +import com.google.gwt.user.client.Event; + +/** + * Class used to expose GQuery methods and object to Javascript using + * gwt-exporter annotations. + * + * We prefer to overlay the original GQuery object instead of adding + * the gwt-exporter dependency to the project. + * + * Because of the differences between java and js apis, we need to + * override some methods in order to deal with complex cases. + * + */ +@ExportPackage("JsQuery") +@Export(value="fn", all=false) +public class GQueryOverlay implements ExportOverlay<GQuery> { + + @ExportPackage("JsQuery") + @Export("jFunction") + @ExportClosure() + public interface FunctionOverlay extends ExportOverlay<Function> { + public void f(); + public boolean f(Event e); + public Object f(Element e, int i); + } + + @ExportPackage("JsQuery") + @Export("jPredicate") + @ExportClosure() + public interface PredicateOverlay extends ExportOverlay<Predicate> { + public boolean f(Element e, int i); + } + + private GQueryOverlay(){} + + /** + * In js a GQuery object represents a Nodelist. + * gwt-exporter will use the object returned by get() to wrap + * the GQuery object + */ + @ExportJsInitMethod + public NodeList<Element> get() {return null;} + + /** + * Customized JS code to execute after GQuery has been exported. + */ + @ExportAfterCreateMethod + public static native void afterCreate() /*-{ + $ = $wnd.$; + window = $wnd; + document = $doc; + }-*/; + + @ExportStaticMethod("$wnd.$") + public static GQuery $(Object o) { + return JsQueryUtils.dollar(o); + } + + @ExportStaticMethod("$wnd.$") + public static GQuery $(String s, Element ctx) { + return GQuery.$(s, ctx); + } + + @ExportStaticMethod("$wnd.$.extend") + public static JavaScriptObject extend(Object...objs) { + return JsQueryUtils.extend(objs); + } + + @ExportStaticMethod("$wnd.$.each") + public static JavaScriptObject[] each(JavaScriptObject[] objs, Function f) { + return JsQueryUtils.each(objs, f); + } + + @ExportStaticMethod("$wnd.$.inArray") + public static int inArray(Object o, Object arr) { + return JsQueryUtils.inArray(o, arr); + } + + @ExportStaticMethod("$wnd.$.isArray") + public static boolean isArray(JavaScriptObject o) { + return JsUtils.isArray(o); + } + + @ExportInstanceMethod + public static GQuery ready(GQuery g, Function f) { + f.fe(); + return g; + } + + @ExportInstanceMethod + // TODO: normally plugins adds new easing functions to jquery.easing array + public static GQuery animate(GQuery g, Object stringOrProperties, int duration, String easing, Function... funcs) { + return g.animate(stringOrProperties, duration, + "linear".equalsIgnoreCase(easing) + ? PropertiesAnimation.Easing.LINEAR + : PropertiesAnimation.Easing.SWING, funcs); + } + + @ExportInstanceMethod + public static Object css(GQuery g, Object o) { + if (o instanceof String) { + return g.css((String)o, false); + } else { + return ExporterUtil.wrap(g.css((Properties)o)); + } + } + + @ExportInstanceMethod + public static GQuery css(GQuery g, String k, Object v) { + return g.css(k, String.valueOf(v)); + } + + @ExportInstanceMethod + public static JavaScriptObject offset(GQuery instance) { + Offset o = instance.offset(); + return Properties.create("left: " + o.left + ", top:" + o.top); + } + + @ExportInstanceMethod + public static GQuery unbind(GQuery g, String s, Function o) { + return g.unbind(s); + } + + public String toString() {return null;} + public GQuery add(GQuery previousObject) {return null;} + public GQuery add(String selector) {return null;} + public GQuery addClass(String... classes) {return null;} + public GQuery after(GQuery query) {return null;} + public GQuery after(Node n) {return null;} + public GQuery after(String html) {return null;} + public GQuery andSelf() {return null;} + +// public GQuery animate(Object stringOrProperties, int duration, Easing easing, Function... funcs) {return null;} + public GQuery animate(Object stringOrProperties, Function... funcs) {return null;} + public GQuery animate(Object stringOrProperties, int duration, Function... funcs) {return null;} +// public GQuery attr(Properties properties) {return null;} + public String attr(String name) {return null;} +// public GQuery attr(String key, Function closure) {return null;} + public GQuery attr(String key, Object value) {return null;} + public int size() {return 0;} + + public GQuery append(GQuery query) {return null;} + public GQuery append(Node n) {return null;} + public GQuery append(String html) {return null;} + public GQuery appendTo(GQuery other) {return null;} + public GQuery appendTo(Node n) {return null;} + public GQuery appendTo(String html) {return null;} + public <T extends GQuery> T as(Class<T> plugin) {return null;} + + public GQuery before(GQuery query) {return null;} + public GQuery before(Node n) {return null;} + public GQuery before(String html) {return null;} +// public GQuery bind(int eventbits, Object data, Function... funcs) {return null;} +// public GQuery bind(String eventType, Object data, Function... funcs) {return null;} + @ExportInstanceMethod + public static GQuery bind(GQuery g, String events, Function func) { + return g.bind(events, null, func); + } + public GQuery blur(Function... f) {return null;} + public GQuery change(Function... f) {return null;} + public GQuery children() {return null;} + public GQuery children(String... filters) {return null;} + public GQuery clearQueue() {return null;} + public GQuery clone() {return null;} + public GQuery clearQueue(String queueName) {return null;} + public GQuery click(Function... f) {return null;} + public GQuery closest(String selector) {return null;} +// public JsNamedArray<NodeList<Element>> closest(String[] selectors) {return null;} +// public JsNamedArray<NodeList<Element>> closest(String[] selectors, Node context) {return null;} + public GQuery closest(String selector, Node context) {return null;} + public GQuery contains(String text) {return null;} + public GQuery contents() {return null;} +// public GQuery css(Properties properties) {return null;} +// public String css(String name) {return null;} +// public String css(String name, boolean force) {return null;} + public GQuery css(String prop, String val) {return null;} + public double cur(String prop) {return 0;} + public double cur(String prop, boolean force) {return 0;} + public Object data(String name) {return null;} +// public <T> T data(String name, Class<T> clz) {return null;} + public GQuery data(String name, Object value) {return null;} + public GQuery dblclick(Function... f) {return null;} + + @ExportInstanceMethod + public static GQuery delay(GQuery g, int milliseconds) { + System.out.println("DDDDD"); + return g.delay(milliseconds); + } + + public GQuery delay(int milliseconds, Function... f) {return null;} + public GQuery delay(int milliseconds, String queueName, Function... f) {return null;} + public GQuery delegate(String selector, String eventType, Function... handlers) {return null;} + public GQuery delegate(String selector, String eventType, Object data, Function... handlers) {return null;} + public GQuery delegate(String selector, int eventbits, Function... handlers) {return null;} + public GQuery delegate(String selector, int eventbits, Object data, Function... handlers) {return null;} + public GQuery dequeue() {return null;} + public GQuery dequeue(String queueName) {return null;} + public GQuery detach() {return null;} + public GQuery detach(String filter) {return null;} + public GQuery die() {return null;} + public GQuery die(String eventName) {return null;} +// public GQuery die(int eventbits) {return null;} + public GQuery each(Function... f) {return null;} + public Element[] elements() {return null;} + public GQuery empty() {return null;} +// public GQuery end() {return null;} + public GQuery eq(int pos) {return null;} + public GQuery error(Function... f) {return null;} + public GQuery fadeIn(Function... f) {return null;} + public GQuery fadeIn(int millisecs, Function... f) {return null;} + public GQuery fadeOut(Function... f) {return null;} + public GQuery fadeOut(int millisecs, Function... f) {return null;} + public Effects fadeToggle(int millisecs, Function... f) {return null;} + public GQuery filter(Predicate filterFn) {return null;} +// public GQuery filter(String... filters) {return null;} + public GQuery find(String... filters) {return null;} + public GQuery first() {return null;} + public GQuery focus(Function... f) {return null;} + public Element get(int i) {return null;} + public Node getContext() {return null;} + public GQuery getPreviousObject() {return null;} + public String getSelector() {return null;} + public GQuery gt(int pos) {return null;} + public boolean hasClass(String... classes) {return false;} + public int height() {return 0;} + public GQuery height(int height) {return null;} + public GQuery height(String height) {return null;} + public GQuery hide() {return null;} + public GQuery hover(Function fover, Function fout) {return null;} + public String html() {return null;} + public GQuery html(String html) {return null;} + public String id() {return null;} + public GQuery id(String id) {return null;} + public int index(Element element) {return 0;} + public int innerHeight() {return 0;} + public int innerWidth() {return 0;} + public GQuery insertAfter(Element elem) {return null;} + public GQuery insertAfter(GQuery query) {return null;} + public GQuery insertAfter(String selector) {return null;} + public GQuery insertBefore(Element item) {return null;} + public GQuery insertBefore(GQuery query) {return null;} + public GQuery insertBefore(String selector) {return null;} + public boolean is(String... filters) {return false;} + public boolean isEmpty() {return false;} + public GQuery keydown(Function... f) {return null;} + public GQuery keydown(int key) {return null;} + public GQuery keypress(Function... f) {return null;} + public GQuery keypress(int key) {return null;} + public GQuery keyup(Function... f) {return null;} + public GQuery keyup(int key) {return null;} + public GQuery last() {return null;} + public int left() {return 0;} + public int length() {return 0;} + public GQuery live(String eventName, Function... funcs) {return null;} +// public GQuery live(int eventbits, Function... funcs) {return null;} +// public GQuery live(int eventbits, Object data, Function... funcs) {return null;} + public GQuery live(String eventName, Object data, Function... funcs) {return null;} +// public GQuery load(Function f) {return null;} + public GQuery lt(int pos) {return null;} +// public <W> List<W> map(Function f) {return null;} + public GQuery mousedown(Function... f) {return null;} + public GQuery mousemove(Function... f) {return null;} + public GQuery mouseout(Function... f) {return null;} + public GQuery mouseover(Function... f) {return null;} + public GQuery mouseup(Function... f) {return null;} + public GQuery next() {return null;} + public GQuery next(String... selectors) {return null;} + public GQuery nextAll() {return null;} + public GQuery nextUntil(String selector) {return null;} + public GQuery not(Element elem) {return null;} + public GQuery not(GQuery gq) {return null;} + public GQuery not(String... filters) {return null;} + public GQuery offsetParent() {return null;} + public GQuery one(int eventbits, Object data, Function f) {return null;} + public int outerHeight() {return 0;} + public int outerHeight(boolean includeMargin) {return 0;} + public int outerWidth() {return 0;} + public int outerWidth(boolean includeMargin) {return 0;} + public GQuery parent() {return null;} + public GQuery parent(String... filters) {return null;} + public GQuery parents() {return null;} + public GQuery parents(String... filters) {return null;} + public GQuery parentsUntil(String selector) {return null;} +// public Offset position() {return null;} + public GQuery prepend(GQuery query) {return null;} + public GQuery prepend(Node n) {return null;} + public GQuery prepend(String html) {return null;} + public GQuery prependTo(GQuery other) {return null;} + public GQuery prependTo(Node n) {return null;} + public GQuery prependTo(String html) {return null;} + public GQuery prev() {return null;} + public GQuery prev(String... selectors) {return null;} + public GQuery prevAll() {return null;} + public GQuery prevUntil(String selector) {return null;} + public boolean prop(String key) {return false;} + public GQuery prop(String key, boolean value) {return null;} + public GQuery prop(String key, Function closure) {return null;} + public int queue() {return 0;} + public int queue(String queueName) {return 0;} + public GQuery queue(Function... f) {return null;} + public GQuery queue(String queueName, Function... f) {return null;} + public GQuery remove() {return null;} + public GQuery remove(String filter) {return null;} + public GQuery removeAttr(String key) {return null;} + public GQuery removeClass(String... classes) {return null;} + public GQuery removeData(String name) {return null;} + public GQuery replaceAll(Element elem) {return null;} + public GQuery replaceAll(GQuery target) {return null;} + public GQuery replaceAll(String selector) {return null;} + public GQuery replaceWith(Element elem) {return null;} + public GQuery replaceWith(GQuery target) {return null;} + public GQuery replaceWith(String html) {return null;} + public GQuery resize(Function... f) {return null;} + public void restoreCssAttrs(String... cssProps) {} + public void resize(Function f) {} + public void saveCssAttrs(String... cssProps) {} + public GQuery scroll(Function... f) {return null;} + public GQuery scrollIntoView() {return null;} + public GQuery scrollIntoView(boolean ensure) {return null;} + public int scrollLeft() {return 0;} + public GQuery scrollLeft(int left) {return null;} + public GQuery scrollTo(int left, int top) {return null;} + public int scrollTop() {return 0;} + public GQuery scrollTop(int top) {return null;} + public GQuery select() {return null;} + public GQuery setArray(NodeList<Element> list) {return null;} + public void setPreviousObject(GQuery previousObject) {} + public GQuery setSelector(String selector) {return null;} + public GQuery show() {return null;} + public GQuery siblings() {return null;} + public GQuery siblings(String... selectors) {return null;} + public GQuery slice(int start, int end) {return null;} + public Effects slideDown(Function... f) {return null;} + public Effects slideDown(int millisecs, Function... f) {return null;} + public Effects slideToggle(int millisecs, Function... f) {return null;} + public Effects slideUp(Function... f) {return null;} + public Effects slideUp(int millisecs, Function... f) {return null;} + public GQuery stop() {return null;} + public GQuery stop(boolean clearQueue) {return null;} + public GQuery stop(boolean clearQueue, boolean jumpToEnd) {return null;} + public GQuery submit(Function... funcs) {return null;} + public String text() {return null;} + public GQuery text(String txt) {return null;} + public GQuery toggle() {return null;} + public GQuery toggle(Function... fn) {return null;} + public GQuery toggleClass(String... classes) {return null;} + public GQuery toggleClass(String clz, boolean addOrRemove) {return null;} + public int top() {return 0;} + public String toString(boolean pretty) {return null;} +// public GQuery trigger(int eventbits, int... keys) {return null;} +// public GQuery unbind(int eventbits) {return null;} + public GQuery undelegate() {return null;} + public GQuery undelegate(String selector) {return null;} + public GQuery undelegate(String selector, String eventName) {return null;} + public GQuery undelegate(String selector, int eventBit) {return null;} +// public JsNodeArray unique(NodeList<Element> result) {return null;} + public GQuery unwrap() {return null;} + public String val() {return null;} + public GQuery val(String... values) {return null;} + public String[] vals() {return null;} + public boolean isVisible() {return false;} + public int width() {return 0;} + public GQuery width(int width) {return null;} + public GQuery wrap(Element elem) {return null;} + public GQuery wrap(GQuery query) {return null;} + public GQuery wrap(String html) {return null;} + public GQuery wrapAll(Element elem) {return null;} + public GQuery wrapAll(GQuery query) {return null;} + public GQuery wrapAll(String html) {return null;} + public GQuery wrapInner(Element elem) {return null;} + public GQuery wrapInner(GQuery query) {return null;} + public GQuery wrapInner(String html) {return null;} +} diff --git a/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQuery.java b/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQuery.java new file mode 100644 index 00000000..6afe7f55 --- /dev/null +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQuery.java @@ -0,0 +1,54 @@ +package com.google.gwt.query.jsquery.client; + +import java.util.logging.Logger; + +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; +import com.google.gwt.query.jsquery.client.GQueryOverlay.FunctionOverlay; +import com.google.gwt.query.jsquery.client.GQueryOverlay.PredicateOverlay; + +public class JsQuery implements EntryPoint { + + public void onModuleLoad() { + GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() { + Logger l = Logger.getLogger("JsQuery"); + public void onUncaughtException(Throwable e) { + String r = ""; + for (StackTraceElement s :e.getStackTrace()) { + r += s + "\n"; + } + l.info(r); + } + }); + // We just export the api, but we do not call GQueryOverlay.onLoad() so as + // apps and plugins could load their stuff before calling it + export(); + + // Un comment for testing stuff below + // testJs(); + } + + public static void export() { + GWT.create(FunctionOverlay.class); + GWT.create(PredicateOverlay.class); + GWT.create(GQueryOverlay.class); + } + + public static native void onLoad() /*-{ + $wnd.onJsQueryLoad && $wnd.onJsQueryLoad(); + $wnd.JsQuery && $wnd.JsQuery.onLoad && $wnd.JsQuery.onLoad(); + }-*/; + + /** + * Used to paste jquery code and test it in dev mode + */ + private native static void testJs() /*-{ + var l = @com.google.gwt.query.jsquery.client.JsQueryUtils::log(Ljava/lang/Object;); + window = $wnd; + document = $doc; + $ = $wnd.$; + + // Paste jquery code here + + }-*/; +} diff --git a/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQueryApi.java b/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQueryApi.java new file mode 100644 index 00000000..2e466a93 --- /dev/null +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQueryApi.java @@ -0,0 +1,10 @@ +package com.google.gwt.query.jsquery.client; + +import com.google.gwt.core.client.EntryPoint; + +public class JsQueryApi implements EntryPoint { + + public void onModuleLoad() { + JsQuery.onLoad(); + } +} diff --git a/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQueryUtils.java b/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQueryUtils.java new file mode 100644 index 00000000..d5ca8bbc --- /dev/null +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/client/JsQueryUtils.java @@ -0,0 +1,135 @@ +package com.google.gwt.query.jsquery.client; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Node; +import com.google.gwt.query.client.Function; +import com.google.gwt.query.client.GQuery; +import com.google.gwt.query.client.js.JsCache; +import com.google.gwt.query.client.js.JsNodeArray; +import com.google.gwt.query.client.js.JsUtils; + +/** + * These are a set of utility methods needed in jsquery because + * either they are not in the GQuery core yet, or they are already + * there but we need to modify their behavior. + * Most of them should be moved to the GQuery core api. + * + */ +public abstract class JsQueryUtils { + + private native static String dumpObject(JavaScriptObject o) /*-{ + var s = ""; + for (k in o) + s += " " + k; + return s; + }-*/; + + public static GQuery dollar(Object o) { + if (o instanceof String) { + return GQuery.$((String) o); + } else if (o instanceof JavaScriptObject) { + JavaScriptObject jso = (JavaScriptObject) o; + if (JsUtils.isFunction(jso)) { + new JsUtils.JsFunction(jso).fe(); + } else { + GQuery r = GQuery.$(jso); + if (!JsUtils.isWindow(jso) && !JsUtils.isElement(jso) && JsUtils.isArray(jso)) { + JsCache c = jso.cast(); + JsNodeArray elms = JsNodeArray.create(); + for (int i = 0; i < c.length(); i++) { + Object obj = c.get(i); + if (obj instanceof Node) { + elms.addNode((Node) obj); + } + } + r = GQuery.$(elms); + } + return r; + } + } + return GQuery.$(); + } + + public static GQuery dollar(String s, Element ctx) { + return GQuery.$(s, ctx); + } + + public static void ready(Function f) { + f.f(); + } + + public static int inArray(Object object, Object array) { + if (array instanceof List) { + return ((List<?>)array).indexOf(object); + } else if (object instanceof JavaScriptObject + && JsUtils.isElement((JavaScriptObject) object)) { + return dollar(array).index((Element) object); + } else if (array instanceof JavaScriptObject + && JsUtils.isArray((JavaScriptObject) array)) { + return ((JsCache) array).indexOf(object); + } + return -1; + } + + public static JavaScriptObject extend(Object... objs) { + int i = 0, l = objs.length; + boolean deep = false; + JavaScriptObject ctx = null; + Object target = objs[i]; + if (target instanceof Boolean) { + deep = (Boolean) target; + if (l == 1) + return ctx; + target = objs[i++]; + } + if (l - i == 1) { + i--; + } else { + ctx = (JavaScriptObject) target; + } + + for (++i; i < l; i++) { + if (objs[i] != null) { + ctx = extendImpl(deep, ctx, objs[i]); + } + } + return ctx; + } + + private static native JavaScriptObject getDefaultPrototype() /*-{ + return $wnd.JsQuery && $wnd.JsQuery.fn + ? $wnd.JsQuery.fn.prototype + : null; + }-*/; + + private static native JavaScriptObject extendImpl(boolean deep, + JavaScriptObject ctx, Object s) /*-{ + var d = ctx ? ctx : $wnd.JsQuery.fn.prototype || {}; + for (k in s) { + d[k] = s[k]; + if (!ctx) + $wnd.$[k] = s[k]; + } + return d; + }-*/; + + public static JavaScriptObject[] each(JavaScriptObject[] objs, Function f) { + ArrayList<Object> ret = new ArrayList<Object>(); + for (Object o : objs) { + f.setDataObject(o); + if (f.fe(null, o)) { + ret.add(o); + } + } + return ret.toArray(new JavaScriptObject[0]); + } + + public static void log(Object l) { + System.out.println(l); + } + +} diff --git a/jsquery/src/main/java/gwtquery/jsquery/JsQuery.gwt.xml b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/JsQuery.gwt.xml index 77569711..77569711 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/JsQuery.gwt.xml +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/JsQuery.gwt.xml diff --git a/jsquery/src/main/java/gwtquery/jsquery/JsQueryXs.gwt.xml b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/JsQueryXs.gwt.xml index 22df149e..22df149e 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/JsQueryXs.gwt.xml +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/JsQueryXs.gwt.xml diff --git a/jsquery/src/main/java/gwtquery/jsquery/client/JsQuery.java b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/client/JsQuery.java index f5f2b386..f5f2b386 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/client/JsQuery.java +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/client/JsQuery.java diff --git a/jsquery/src/main/java/gwtquery/jsquery/client/OverlayGQuery.java b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/client/OverlayGQuery.java index 753489d8..753489d8 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/client/OverlayGQuery.java +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/client/OverlayGQuery.java diff --git a/jsquery/src/main/java/gwtquery/jsquery/client/utils/JsQueryUtils.java b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/client/utils/JsQueryUtils.java index de01bab3..de01bab3 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/client/utils/JsQueryUtils.java +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/client/utils/JsQueryUtils.java diff --git a/jsquery/src/main/java/gwtquery/jsquery/public/JsQuery.html b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/public/JsQuery.html index de1c3800..de1c3800 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/public/JsQuery.html +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/jsquery/public/JsQuery.html diff --git a/jsquery/src/main/java/com/google/gwt/query/jsquery/public/JsQuery.html b/jsquery/src/main/java/com/google/gwt/query/jsquery/public/JsQuery.html new file mode 100644 index 00000000..59877b4d --- /dev/null +++ b/jsquery/src/main/java/com/google/gwt/query/jsquery/public/JsQuery.html @@ -0,0 +1,20 @@ +<!doctype html> +<html> +<head> +<title>JsQuery</title> +<script src="jsquery.nocache.js" ></script> +</head> +<body> + <div id='hello' style='display: none'>Hello</div> + <script> + onJsQueryLoad = function(){ + $('#hello').show().attr("width", true); + $('#hello').fadeOut(1000).text("Hello word").fadeIn(); + } + if (window.$) { + $(document).ready(onJsQueryLoad); + onJsQueryLoad = null; + } + </script> +</body> +</html> diff --git a/jsquery/src/main/java/gwtquery/jsplugins/menu/JsQueryMenu.gwt.xml b/jsquery/src/main/java/gwtquery/jsplugins/menu/JsQueryMenu.gwt.xml new file mode 100644 index 00000000..81153c56 --- /dev/null +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/JsQueryMenu.gwt.xml @@ -0,0 +1,7 @@ +<module rename-to='jsmenu'> + <inherits name='com.google.gwt.query.jsquery.JsQuery' /> + <entry-point class="gwtquery.jsplugins.menu.client.JsQueryMenu" /> + + +</module> + diff --git a/jsquery/src/main/java/gwtquery/jsquery/client/plugins/menu/JsMenu.java b/jsquery/src/main/java/gwtquery/jsplugins/menu/client/JsMenu.java index 28ce5699..0977f6ce 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/client/plugins/menu/JsMenu.java +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/client/JsMenu.java @@ -1,4 +1,4 @@ -package gwtquery.jsquery.client.plugins.menu; +package gwtquery.jsplugins.menu.client; /** * @@ -10,7 +10,7 @@ package gwtquery.jsquery.client.plugins.menu; public abstract class JsMenu { public static native void loadPlugin() /*-{ - var l = @gwtquery.jsquery.client.utils.JsQueryUtils::log(Ljava/lang/Object;); + var l = @com.google.gwt.query.jsquery.client.JsQueryUtils::log(Ljava/lang/Object;); var window = $wnd; var document = $doc; var jQuery = $wnd.$; diff --git a/jsquery/src/main/java/gwtquery/jsplugins/menu/client/JsQueryMenu.java b/jsquery/src/main/java/gwtquery/jsplugins/menu/client/JsQueryMenu.java new file mode 100644 index 00000000..438075d2 --- /dev/null +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/client/JsQueryMenu.java @@ -0,0 +1,12 @@ +package gwtquery.jsplugins.menu.client; + +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.query.jsquery.client.JsQuery; + +public class JsQueryMenu implements EntryPoint { + + public void onModuleLoad() { + JsMenu.loadPlugin(); + JsQuery.onLoad(); + } +} diff --git a/jsquery/src/main/java/gwtquery/jsquery/client/plugins/menu/jsmenu.diff b/jsquery/src/main/java/gwtquery/jsplugins/menu/client/jsmenu.diff index a9ac0d20..a9ac0d20 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/client/plugins/menu/jsmenu.diff +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/client/jsmenu.diff diff --git a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/arrow_right.gif b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/arrow_right.gif Binary files differindex 610344d7..610344d7 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/arrow_right.gif +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/arrow_right.gif diff --git a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/arrowdown.png b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/arrowdown.png Binary files differindex 637c8d94..637c8d94 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/arrowdown.png +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/arrowdown.png diff --git a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/demo.html b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/demo.html index da242157..1e55c326 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/demo.html +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/demo.html @@ -4,7 +4,7 @@ <head> <title>jQuery menu plugin demo page</title> <link rel="stylesheet" type="text/css" href="style.css" /> -<script src="../../dev.nocache.js" ></script> +<script src="jsmenu.nocache.js" ></script> <script type="text/javascript"> // JsQuery will run this function after it is asynchronously loaded diff --git a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/myshadow.png b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/myshadow.png Binary files differindex fb6c71b5..fb6c71b5 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/myshadow.png +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/myshadow.png diff --git a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/style.css b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/style.css index 965233bc..965233bc 100644 --- a/jsquery/src/main/java/gwtquery/jsquery/public/plugins/menu/style.css +++ b/jsquery/src/main/java/gwtquery/jsplugins/menu/public/style.css diff --git a/jsquery/src/main/webapp/index.html b/jsquery/src/main/webapp/index.html index 613ed6d6..6e18b6cd 100644 --- a/jsquery/src/main/webapp/index.html +++ b/jsquery/src/main/webapp/index.html @@ -11,8 +11,8 @@ } </script> <ul> - <li><a href="javascript:goTo('dev/JsQuery.html')">JsQuery.html</a></li> - <li><a href="javascript:goTo('dev/plugins/menu/demo.html')">jquery.menu.html</a></li> + <li><a href="javascript:goTo('jsquery/JsQuery.html')">JsQuery.html</a></li> + <li><a href="javascript:goTo('jsmenu/demo.html')">jquery.menu.html</a></li> </ul> </body> </html> |