You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2017/02/01 10:40:23 UTC

svn commit: r1781217 - in /myfaces/tobago/branches/tobago-2.0.x: tobago-core/src/main/java/org/apache/myfaces/tobago/component/ tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/ tobago-core/src/main/java/org/apache/myfaces/tobago/...

Author: weber
Date: Wed Feb  1 10:40:22 2017
New Revision: 1781217

URL: http://svn.apache.org/viewvc?rev=1781217&view=rev
Log:
TOBAGO-1690 - Drag and Drop File Upload

Added:
    myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFileDrop.java
    myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileDropTagDeclaration.java
      - copied, changed from r1780074, myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileDropRenderer.java
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-file.js
Modified:
    myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
    myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java
    myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago-theme-config.properties
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago.properties.xml
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago_de.properties.xml
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/tobago.css
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/tobago.less
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/pom.xml
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
    myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago.js

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java Wed Feb  1 10:40:22 2017
@@ -35,6 +35,7 @@ public final class RendererTypes {
   public static final String DATE = "Date";
   public static final String DATE_PICKER = "DatePicker";
   public static final String FILE = "File";
+  public static final String FILE_DROP = "FileDrop";
   public static final String FLOW_LAYOUT = "FlowLayout";
   public static final String FORM = "Form";
   public static final String GRID_LAYOUT = "GridLayout";

Added: myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFileDrop.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFileDrop.java?rev=1781217&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFileDrop.java (added)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFileDrop.java Wed Feb  1 10:40:22 2017
@@ -0,0 +1,59 @@
+/*
+ * 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.myfaces.tobago.internal.component;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.myfaces.tobago.component.SupportsRenderedPartially;
+
+import javax.faces.event.ActionListener;
+
+public abstract class AbstractUIFileDrop extends AbstractUIFile implements SupportsRenderedPartially {
+
+  private static final Logger LOG = LoggerFactory.getLogger(AbstractUIFileDrop.class);
+
+  public enum VisibleType {
+    DROP_ZONE,
+    FILE,
+    BUTTON,
+    IMAGE,
+    NONE;
+
+    public static VisibleType asEnum(String value) {
+      if (value != null) {
+        try {
+          return valueOf(value);
+        } catch (Exception e) {
+          LOG.warn("Caught: {}", e.getMessage());
+        }
+      }
+      return DROP_ZONE;
+    }
+  }
+
+  public abstract String getDropZoneId();
+  public abstract String getVisibleType();
+
+  public void addActionListener(ActionListener listener) {
+    this.addFacesListener(listener);
+  }
+
+}

Copied: myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileDropTagDeclaration.java (from r1780074, myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java)
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileDropTagDeclaration.java?p2=myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileDropTagDeclaration.java&p1=myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java&r1=1780074&r2=1781217&rev=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileDropTagDeclaration.java Wed Feb  1 10:40:22 2017
@@ -20,16 +20,17 @@
 package org.apache.myfaces.tobago.internal.taglib.component;
 
 import org.apache.myfaces.tobago.apt.annotation.DynamicExpression;
-import org.apache.myfaces.tobago.apt.annotation.Facet;
 import org.apache.myfaces.tobago.apt.annotation.Tag;
 import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
-import org.apache.myfaces.tobago.component.Facets;
 import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAction;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasActionListener;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasCurrentMarkup;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasImage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasMarkup;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasOnchange;
@@ -42,14 +43,15 @@ import org.apache.myfaces.tobago.interna
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsGridLayoutComponent;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsMultiple;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsRequired;
-import org.apache.myfaces.tobago.internal.taglib.declaration.IsMultiple;
 
 import javax.faces.component.UIInput;
 
 /**
- * Renders a file input field.
+ * Renders a file drop component.
+ * This component always makes a partial (ajax) upload!
  * You need to define an org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataFilter in your web.xml or
  * add the tobago-fileupload.jar to your project.
  * The tobago-fileupload.jar contains a FacesContextFactory that wraps the
@@ -57,23 +59,19 @@ import javax.faces.component.UIInput;
  * <p />
  * For content constraints please use <a href="validateFileItem.html">tc:validateFileItem</a>.
  */
-@Tag(name = "file")
+@Tag(name = "fileDrop")
 @UIComponentTag(
-    uiComponent = "org.apache.myfaces.tobago.component.UIFile",
-    uiComponentBaseClass = "org.apache.myfaces.tobago.internal.component.AbstractUIFile",
+    uiComponent = "org.apache.myfaces.tobago.component.UIFileDrop",
+    uiComponentBaseClass = "org.apache.myfaces.tobago.internal.component.AbstractUIFileDrop",
     uiComponentFacesClass = "javax.faces.component.UIInput",
     componentFamily = UIInput.COMPONENT_FAMILY,
-    rendererType = RendererTypes.FILE,
-    allowedChildComponenents = "NONE",
-    facets = {
-        @Facet(name = Facets.CHANGE,
-            description =
-                "This facet can contain a UICommand that is invoked in a case of a change event from the component")
-    })
-public interface FileTagDeclaration
+    rendererType = RendererTypes.FILE_DROP,
+    allowedChildComponenents = "NONE")
+public interface FileDropTagDeclaration
     extends HasValidator, HasValidatorMessage, HasRequiredMessage, HasConverterMessage, HasOnchange,
     HasValueChangeListener, HasIdBindingAndRendered, IsDisabled, HasMarkup, HasCurrentMarkup, IsFocus, IsMultiple,
-    HasLabel, HasTip, IsReadonly, IsRequired, HasTabIndex, IsGridLayoutComponent {
+    HasLabel, HasImage, HasTip, IsReadonly, IsRequired, HasTabIndex, IsGridLayoutComponent,
+    HasAction, HasActionListener {
 
   /**
    * Value binding expression pointing to a
@@ -85,4 +83,73 @@ public interface FileTagDeclaration
       type = { "org.apache.commons.fileupload.FileItem", "org.apache.commons.fileupload.FileItem[]" },
       expression = DynamicExpression.VALUE_EXPRESSION_REQUIRED)
   void setValue(String value);
+
+  /**
+   * <p>
+   * Indicate the partially rendered components in a case of a file drop.
+   * </p>
+   * <p>
+   * The search depends on the number of prefixed colons in the relativeId:
+   * <dl>
+   *   <dd>number of prefixed colons == 0</dd>
+   *   <dt>fully relative</dt>
+   *   <dd>number of prefixed colons == 1</dd>
+   *   <dt>absolute (still normal findComponent syntax)</dt>
+   *   <dd>number of prefixed colons == 2</dd>
+   *   <dt>search in the current naming container (same as 0 colons)</dt>
+   *   <dd>number of prefixed colons == 3</dd>
+   *   <dt>search in the parent naming container of the current naming container</dt>
+   *   <dd>number of prefixed colons > 3</dd>
+   *   <dt>go to the next parent naming container for each additional colon</dt>
+   * </dl>
+   * </p>
+   * <p>
+   * If a literal is specified: to use more than one identifier the identifiers must be space delimited.
+   * </p>
+   * <p>
+   *  As default the dropZoneId is used.
+   * </p>
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "java.lang.String[]")
+  void setRenderedPartially(String componentIds);
+
+  /**
+   * <p>
+   * Indicate the highlighted file drop area.
+   * </p>
+   * <p>
+   *   You should use:
+   *   <ul>
+   *     <li>a clientId (absolute or relative see setRenderedPartially)</li>
+   *     <li>@this to use only the layouted space of this tc:fileDrop</li>
+   *     <li>@parent to use the layouted space of the next parent UIComponent</li>
+   *     <li>@panel to use the layouted space of the next parent tc:panel</li>
+   *   </ul>
+   * </p>
+   *
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "java.lang.String")
+  void setDropZoneId(String dropZoneId);
+
+  /**
+   * <p>
+   * Indicate visible .
+   * </p>
+   * <p>
+   *   Possible values:
+   *   <ul>
+   *     <li>DROP_ZONE</li>
+   *     <li>FILE</li>
+   *     <li>BUTTON</li>
+   *     <li>IMAGE</li>
+   *     <li>NONE</li>
+   *   </ul>
+   * </p>
+   *
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "java.lang.String")
+  void setVisibleType(String visibleType);
 }

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java Wed Feb  1 10:40:22 2017
@@ -34,6 +34,7 @@ public class Upload {
   private FileItem file2;
   private FileItem[] fileMulti;
   private FileItem[] fileAjax;
+  private FileItem[] fileDnd;
 
   private List<UploadItem> list = new ArrayList<UploadItem>();
 
@@ -42,6 +43,7 @@ public class Upload {
    upload(file2);
    upload(fileMulti);
    upload(fileAjax);
+   upload(fileDnd);
       return null;
     }
 
@@ -103,6 +105,14 @@ public class Upload {
     this.fileAjax = fileAjax;
   }
 
+  public FileItem[] getFileDnd() {
+    return fileDnd;
+  }
+
+  public void setFileDnd(FileItem[] fileDnd) {
+    this.fileDnd = fileDnd;
+  }
+
   public List<UploadItem> getList() {
     return list;
   }

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml Wed Feb  1 10:40:22 2017
@@ -25,7 +25,7 @@
   <ui:param name="title" value="File Upload"/>
   <tc:panel id="uploadPanel">
     <f:facet name="layout">
-      <tc:gridLayout rows="auto;auto;*"/>
+      <tc:gridLayout rows="auto;*"/>
     </f:facet>
 
     <tc:panel>
@@ -54,20 +54,37 @@
 
     </tc:panel>
 
-    <tc:sheet var="entry" value="#{upload.list}" columns="*;*;*">
-
-      <tc:column label="Name">
-        <tc:out value="#{entry.name}"/>
-      </tc:column>
-
-      <tc:column label="Type">
-        <tc:out value="#{entry.type}"/>
-      </tc:column>
-
-      <tc:column label="Size">
-        <tc:out value="#{entry.size}"/>
-      </tc:column>
+    <tc:panel id="fileDropArea">
+      <f:facet name="layout">
+        <tc:gridLayout rows="auto;1*"/>
+      </f:facet>
+      <tc:panel >
+        <tc:fileDrop multiple="true"
+                     value="#{upload.fileDnd}"
+                     action="#{upload.upload}"
+                     dropZoneId=":page:fileDropArea"/>
+                     <!--
+                     label="Drop file or click to browse"
+                     tip="multiple files"
+                     visibleType="BUTTON"
+                     renderedPartially="uploadPanel"
+                     -->
+      </tc:panel>
+      <tc:sheet var="entry" value="#{upload.list}" columns="*;*;*">
+
+        <tc:column label="Name">
+          <tc:out value="#{entry.name}"/>
+        </tc:column>
+
+        <tc:column label="Type">
+          <tc:out value="#{entry.type}"/>
+        </tc:column>
+
+        <tc:column label="Size">
+          <tc:out value="#{entry.size}"/>
+        </tc:column>
 
-    </tc:sheet>
+      </tc:sheet>
+    </tc:panel>
   </tc:panel>
 </ui:composition>

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago-theme-config.properties
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago-theme-config.properties?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago-theme-config.properties (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago-theme-config.properties Wed Feb  1 10:40:22 2017
@@ -97,6 +97,9 @@ File.maximumHeight=20
 # borderLeft + paddingLeft + paddingRight + borderRight + iconWidth + space = 2+2+2+2+5+16
 File.prettyWidthSub=29
 
+FileDrop.minimumHeight=20
+FileDrop.preferredHeight=45
+
 #deprecated
 GridLayout.cellSpacing=5
 

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago.properties.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago.properties.xml?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago.properties.xml (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago.properties.xml Wed Feb  1 10:40:22 2017
@@ -37,6 +37,7 @@
 
   <!-- File-->
   <entry key="tobago.file.multiFormat">{} files selected</entry>
+  <entry key="tobago.fileDrop.defaultLabel">Drop files here or click to browse.</entry>
 
   <!-- Sheet -->
   <entry key="sheetFirst">First Page</entry>

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago_de.properties.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago_de.properties.xml?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago_de.properties.xml (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/property/tobago_de.properties.xml Wed Feb  1 10:40:22 2017
@@ -39,6 +39,7 @@
 
   <!-- File-->
   <entry key="tobago.file.multiFormat">{} Dateien ausgewählt</entry>
+  <entry key="tobago.fileDrop.defaultLabel">Dateien hier ablegen oder zum Suchen hier Klicken.</entry>
 
   <!-- Sheet -->
   <entry key="sheetFirst">erste Seite</entry>

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/tobago.css
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/tobago.css?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/tobago.css (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/tobago.css Wed Feb  1 10:40:22 2017
@@ -319,6 +319,29 @@ span.tobago-calendar-header {
   filter: alpha(opacity: 0);
 }
 
+/* fileDrop -------------------------------------------------------------------- */
+
+.tobago-fileDrop {
+  border: 1px dotted #d8e9fb;
+  border-radius: 3px;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -ms-box-sizing: border-box;
+  text-align: center;
+}
+.tobago-fileDrop > .tobago-out {
+  min-height: 100%;
+  display: inline-flex;
+  align-content: center;
+}
+
+.tobago-fileDrop-dropZone {
+  border: 2px dashed #d8e9fb;
+  border-radius: 5px;
+  background: rgba(238, 238, 238, .6);
+}
+
 /* formatted --------------------------------------------------------------- */
 
 .tobago-formatted {

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/tobago.less
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/tobago.less?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/tobago.less (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/tobago.less Wed Feb  1 10:40:22 2017
@@ -303,6 +303,14 @@
 .tobago-file-pretty-markup-fatal {
   border-color: #ff00ff;
 }
+/* fileDrop -------------------------------------------------------------------- */
+
+.tobago-fileDrop {
+  border: 1px dotted darken(@borderColor, 10%);
+}
+.tobago-fileDrop-dropZone {
+  border: 2px dashed darken(@borderColor, 10%);
+}
 
 /* in ---------------------------------------------------------------------- */
 

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/pom.xml?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/pom.xml (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/pom.xml Wed Feb  1 10:40:22 2017
@@ -60,10 +60,12 @@
             <configuration>
               <target>
                 <concat destfile="${project.build.directory}/javascript-min/standard/script/tobago.min.js" force="no">
-                  <filelist dir="${basedir}/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script" files="tobago.js,tobago-calendar.js,tobago-converter.js,tobago-in.js,tobago-menu.js,tobago-overlay.js,tobago-popup.js,tobago-sheet.js,tobago-suggest.js,tobago-tab.js,tobago-tree.js,tobago-utils.js" />
+                  <filelist dir="${basedir}/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script"
+                            files="tobago.js,tobago-calendar.js,tobago-converter.js,tobago-in.js,tobago-menu.js,tobago-overlay.js,tobago-popup.js,tobago-sheet.js,tobago-suggest.js,tobago-tab.js,tobago-tree.js,tobago-utils.js,tobago-file.js" />
                 </concat>
                 <concat destfile="${project.build.directory}/javascript-min/msie_6_0/script/tobago.min.js" force="no">
-                  <filelist dir="${basedir}/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/msie_6_0/script" files="tobago.js" />
+                  <filelist dir="${basedir}/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/msie_6_0/script"
+                            files="tobago.js" />
                 </concat>
                 <replaceregexp match="^.*//.*@DEV_ONLY.*$" replace="" byline="true">
                   <fileset dir="${project.build.directory}/javascript-min">

Added: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileDropRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileDropRenderer.java?rev=1781217&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileDropRenderer.java (added)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileDropRenderer.java Wed Feb  1 10:40:22 2017
@@ -0,0 +1,355 @@
+/*
+ * 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.myfaces.tobago.renderkit.html.standard.standard.tag;
+
+import org.apache.myfaces.tobago.component.Attributes;
+import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.component.SupportsMarkup;
+import org.apache.myfaces.tobago.component.UIButton;
+import org.apache.myfaces.tobago.component.UICommand;
+import org.apache.myfaces.tobago.component.UIFileDrop;
+import org.apache.myfaces.tobago.component.UIOut;
+import org.apache.myfaces.tobago.config.Configurable;
+import org.apache.myfaces.tobago.context.ResourceManagerUtils;
+import org.apache.myfaces.tobago.internal.component.AbstractUIFile;
+import org.apache.myfaces.tobago.internal.component.AbstractUIFileDrop.VisibleType;
+import org.apache.myfaces.tobago.internal.component.AbstractUIPanel;
+import org.apache.myfaces.tobago.layout.Measure;
+import org.apache.myfaces.tobago.renderkit.css.Classes;
+import org.apache.myfaces.tobago.renderkit.css.Style;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
+
+import javax.el.ExpressionFactory;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIOutput;
+import javax.faces.context.FacesContext;
+import javax.faces.event.MethodExpressionActionListener;
+import java.io.IOException;
+
+public class FileDropRenderer extends FileRenderer {
+
+  private static final String FILE_DROP_DATA_ATTRIBUTE_NAME = "tobago-file-drop";
+
+  @Override
+  public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
+    super.prepareRender(facesContext, component);
+    UIFileDrop fileDrop = (UIFileDrop) component;
+    if (fileDrop.getFacet("change") == null) {
+      createActionFacet(facesContext, fileDrop);
+    }
+    VisibleType visibleType = getVisibleType(fileDrop);
+    switch (visibleType) {
+      case DROP_ZONE:
+        if (fileDrop.getFacet("out") == null) {
+          createOut(facesContext, fileDrop);
+        }
+        break;
+      case BUTTON:
+        if (fileDrop.getFacet("button") == null) {
+          createButton(facesContext, fileDrop);
+        }
+        UIButton button = (UIButton) fileDrop.getFacet("button");
+        // TODO: prepareRender(button)
+        break;
+      default:
+    }
+  }
+
+  @Override
+  protected void writeDataAttributes(FacesContext facesContext, TobagoResponseWriter writer, AbstractUIFile file)
+      throws IOException {
+    String dataValue = buildDataValue(facesContext, (UIFileDrop) file);
+    ComponentUtils.putDataAttribute(file, FILE_DROP_DATA_ATTRIBUTE_NAME, dataValue);
+    super.writeDataAttributes(facesContext, writer, file);
+  }
+
+  private String buildDataValue(FacesContext facesContext, UIFileDrop fileDrop) {
+    return "{\"dropZoneId\":\"" + calculateDropZoneId(facesContext, fileDrop) + "\"}";
+  }
+
+  private String calculateDropZoneId(FacesContext facesContext, UIFileDrop fileDrop) {
+    String dropZoneId = fileDrop.getDropZoneId();
+    if ("@this".equals(dropZoneId)) {
+      dropZoneId = ":" + fileDrop.getClientId(facesContext);
+    } else if ("@parent".equals(dropZoneId)) {
+      dropZoneId = ":" + fileDrop.getParent().getClientId(facesContext);
+    } else if ("@panel".equals(dropZoneId)) {
+      dropZoneId = ":" + findPanel(fileDrop).getClientId(facesContext);
+    }
+    return dropZoneId;
+  }
+
+  private AbstractUIPanel findPanel(UIComponent component) {
+    if (component instanceof AbstractUIPanel) {
+      return (AbstractUIPanel) component;
+    } else if (component != null) {
+      return findPanel(component.getParent());
+    } else {
+      throw new IllegalStateException("No parent tc:panel found!");
+    }
+  }
+
+  private void createActionFacet(FacesContext facesContext, UIFileDrop fileDrop) {
+    UICommand command = (UICommand) facesContext.getApplication()
+        .createComponent(facesContext, UICommand.COMPONENT_TYPE, RendererTypes.COMMAND);
+    command.setId(fileDrop.getId() + "-command-facet");
+
+    ValueExpression valueExpression = fileDrop.getValueExpression(Attributes.RENDERED_PARTIALLY);
+    if (valueExpression != null) {
+      command.setValueExpression(Attributes.RENDERED_PARTIALLY, valueExpression);
+    } else {
+      String[] renderedPartially = fileDrop.getRenderedPartially();
+      if (renderedPartially != null && renderedPartially.length != 0) {
+        command.setRenderedPartially(renderedPartially);
+      } else {
+        valueExpression = fileDrop.getValueExpression("dropZoneId");
+        if (valueExpression != null) {
+          command.setValueExpression(Attributes.RENDERED_PARTIALLY, valueExpression);
+        } else {
+          command.setRenderedPartially(new String[]{calculateDropZoneId(facesContext, fileDrop)});
+        }
+      }
+    }
+
+    final ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
+
+    String expressionString = getExpressionString(fileDrop, Attributes.ACTION);
+    if (expressionString != null) {
+      final MethodExpression action = expressionFactory.createMethodExpression(
+          facesContext.getELContext(), expressionString, String.class, ComponentUtils.ACTION_ARGS);
+      command.setActionExpression(action);
+    }
+
+    expressionString = getExpressionString(fileDrop, Attributes.ACTION_LISTENER);
+    if (expressionString != null) {
+      final MethodExpression actionListener = expressionFactory.createMethodExpression(
+          facesContext.getELContext(), expressionString, null, ComponentUtils.ACTION_LISTENER_ARGS);
+      command.addActionListener(new MethodExpressionActionListener(actionListener));
+    }
+
+    fileDrop.getFacets().put("change", command);
+  }
+
+  private void createButton(FacesContext facesContext, UIFileDrop fileDrop) {
+    UIButton command = (UIButton) facesContext.getApplication()
+        .createComponent(facesContext, UIButton.COMPONENT_TYPE, RendererTypes.BUTTON);
+    command.setId(fileDrop.getId() + "-button-facet");
+    command.setOmit(true);
+
+    String label = fileDrop.getLabel();
+    String image = fileDrop.getImage();
+
+    ValueExpression valueExpression = fileDrop.getValueExpression(Attributes.LABEL);
+    if (valueExpression != null) {
+      command.setValueExpression(Attributes.LABEL, valueExpression);
+    } else {
+      if (label != null) {
+        command.setLabel(label);
+      } else if (image == null) {
+        command.setLabel(getDefaultLabel(facesContext));
+      }
+    }
+
+    valueExpression = fileDrop.getValueExpression(Attributes.IMAGE);
+    if (valueExpression != null) {
+      command.setValueExpression(Attributes.IMAGE, valueExpression);
+    } else {
+      command.setImage(image);
+    }
+
+
+    fileDrop.getFacets().put("button", command);
+  }
+
+  private String getDefaultLabel(FacesContext facesContext) {
+    return ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "tobago.fileDrop.defaultLabel");
+  }
+
+  private void createOut(FacesContext facesContext, UIFileDrop fileDrop) {
+    UIOut out = (UIOut) facesContext.getApplication()
+        .createComponent(facesContext, UIOut.COMPONENT_TYPE, RendererTypes.OUT);
+    out.setId(fileDrop.getId() + "-out-facet");
+
+    String label = fileDrop.getLabel();
+
+    ValueExpression valueExpression = fileDrop.getValueExpression(Attributes.LABEL);
+    if (valueExpression != null) {
+      out.setValueExpression(Attributes.VALUE, valueExpression);
+    } else {
+      if (label != null) {
+        out.setValue(label);
+      } else {
+        out.setValue(getDefaultLabel(facesContext));
+      }
+    }
+
+    fileDrop.getFacets().put("out", out);
+  }
+
+  private String getExpressionString(UIFileDrop component, String name) {
+    ValueExpression expression = component.getValueExpression(name);
+    if (expression != null) {
+      return expression.getExpressionString();
+    } else {
+      return null;
+    }
+  }
+
+  @Override
+  protected void writeVisibleInput(FacesContext facesContext, TobagoResponseWriter writer, AbstractUIFile file,
+      String clientId, Style style) throws IOException {
+    UIFileDrop fileDrop = (UIFileDrop) file;
+    VisibleType visibleType = getVisibleType(fileDrop);
+    switch (visibleType) {
+      case DROP_ZONE:
+        writeDropZone(facesContext, writer, fileDrop);
+        break;
+      case FILE:
+        super.writeVisibleInput(facesContext, writer, file, clientId, style);
+        break;
+      case BUTTON:
+        writeButton(facesContext, writer, fileDrop);
+        break;
+      case IMAGE:
+        writeImage(facesContext, writer, fileDrop);
+        break;
+      default:
+        // NONE
+    }
+
+  }
+
+  private void writeDropZone(FacesContext facesContext, TobagoResponseWriter writer, UIFileDrop fileDrop)
+      throws IOException {
+    writeComponent(facesContext, fileDrop.getFacet("out"));
+  }
+
+  private void writeButton(FacesContext facesContext, TobagoResponseWriter writer, UIFileDrop fileDrop)
+      throws IOException {
+    writeComponent(facesContext, fileDrop.getFacet("button"));
+  }
+
+  private void writeImage(FacesContext facesContext, TobagoResponseWriter writer, UIFileDrop fileDrop) {
+    // TODO:
+  }
+
+  private void writeComponent(FacesContext facesContext, UIComponent component) throws IOException {
+    component.encodeBegin(facesContext);
+    component.encodeChildren(facesContext);
+    component.encodeEnd(facesContext);
+  }
+
+  @Override
+  public Measure getMinimumHeight(FacesContext facesContext, Configurable component) {
+    VisibleType visibleType = getVisibleType((UIFileDrop) component);
+    switch (visibleType) {
+      case DROP_ZONE:
+        super.getMinimumHeight(facesContext, component);
+      case FILE:
+        return getResourceManager()
+            .getThemeMeasure(facesContext, RendererTypes.FILE, null, Attributes.MINIMUM_HEIGHT);
+      case BUTTON:
+        return getResourceManager()
+            .getThemeMeasure(facesContext, RendererTypes.BUTTON, null, Attributes.MINIMUM_HEIGHT);
+      default:
+        return Measure.ZERO;
+    }
+  }
+
+  @Override
+  public Measure getPreferredHeight(FacesContext facesContext, Configurable component) {
+    VisibleType visibleType = getVisibleType((UIFileDrop) component);
+    switch (visibleType) {
+      case DROP_ZONE:
+        super.getPreferredHeight(facesContext, component);
+      case FILE:
+        return getResourceManager()
+            .getThemeMeasure(facesContext, RendererTypes.FILE, null, Attributes.PREFERRED_HEIGHT);
+      case BUTTON:
+        return getResourceManager()
+            .getThemeMeasure(facesContext, RendererTypes.BUTTON, null, Attributes.PREFERRED_HEIGHT);
+      default:
+        return Measure.ZERO;
+    }
+  }
+
+  @Override
+  public Measure getMaximumHeight(FacesContext facesContext, Configurable component) {
+    VisibleType visibleType = getVisibleType((UIFileDrop) component);
+    switch (visibleType) {
+      case DROP_ZONE:
+        super.getMaximumHeight(facesContext, component);
+      case FILE:
+        return getResourceManager()
+            .getThemeMeasure(facesContext, RendererTypes.FILE, null, Attributes.MAXIMUM_HEIGHT);
+      case BUTTON:
+        return getResourceManager()
+            .getThemeMeasure(facesContext, RendererTypes.BUTTON, null, Attributes.MAXIMUM_HEIGHT);
+      default:
+      return null;
+    }
+  }
+
+  @Override
+  protected Measure getPrettyWidthSub(FacesContext facesContext, AbstractUIFile file) {
+    return getResourceManager().getThemeMeasure(facesContext, RendererTypes.FILE, null, "prettyWidthSub");
+  }
+
+
+  @Override
+  protected Classes getCssClasses(UIComponent component, String sub) {
+    return super.getCssClasses(getCssComponent(component, sub), sub);
+  }
+
+  private UIComponent getCssComponent(UIComponent component, String sub) {
+    VisibleType visibleType = getVisibleType((UIFileDrop) component);
+    if ("real".equals(sub) || visibleType.equals(VisibleType.FILE)) {
+      return createCssComponent(RendererTypes.FILE, component);
+    } else {
+      switch (visibleType) {
+        case DROP_ZONE:
+          return component;
+          default:
+            return createCssComponent(RendererTypes.PANEL, component);
+      }
+    }
+  }
+
+  private UIComponent createCssComponent(String rendererType, UIComponent component) {
+    UIComponent cssComponent;
+    if (component instanceof SupportsMarkup) {
+      SupportsMarkup supportsMarkup = (SupportsMarkup) component;
+      UIOut uiOut = new UIOut();
+      uiOut.setMarkup(supportsMarkup.getMarkup());
+      cssComponent = uiOut;
+    } else {
+      cssComponent = new UIOutput();
+    }
+    cssComponent.setRendererType(rendererType);
+    return cssComponent;
+  }
+
+  private VisibleType getVisibleType(UIFileDrop fileDrop) {
+    return VisibleType.asEnum(fileDrop.getVisibleType());
+  }
+}

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java Wed Feb  1 10:40:22 2017
@@ -115,30 +115,19 @@ public class FileRenderer extends InputR
 
     writer.startElement(HtmlElements.DIV, file);
     writer.writeIdAttribute(clientId);
-    writer.writeClassAttribute(Classes.create(file));
-    HtmlRendererUtils.writeDataAttributes(facesContext, writer, file);
+    writer.writeClassAttribute(getCssClasses(file, null));
+    writeDataAttributes(facesContext, writer, file);
     writer.writeStyleAttribute(style);
 
     // visible fake input for a pretty look
-    final Style inputStyle = new Style();
-    final Measure prettyWidthSub = getResourceManager().getThemeMeasure(facesContext, file, "prettyWidthSub");
-    inputStyle.setWidth(style.getWidth().subtract(prettyWidthSub));
-    writer.startElement(HtmlElements.INPUT, file);
-    writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "pretty");
-    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT, false);
-    writer.writeClassAttribute(Classes.create(file, "pretty"));
-    writer.writeStyleAttribute(inputStyle);
-    writer.writeAttribute(HtmlAttributes.DISABLED, true);
-    // TODO Focus
-    //HtmlRendererUtils.renderFocus(clientId, file.isFocus(), ComponentUtils.isError(file), facesContext, writer);
-    writer.endElement(HtmlElements.INPUT);
+    writeVisibleInput(facesContext, writer, file, clientId, style);
 
     // invisible file input
     writer.startElement(HtmlElements.INPUT, file);
     writer.writeAttribute(HtmlAttributes.MULTIPLE, file.isMultiple());
     writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "real");
     writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.FILE, false);
-    writer.writeClassAttribute(Classes.create(file, "real"));
+    writer.writeClassAttribute(getCssClasses(file, "real"));
     writer.writeNameAttribute(clientId);
     String multiFormat = ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "tobago.file.multiFormat");
     writer.writeAttribute("data-tobago-file-multi-format", multiFormat, true);
@@ -160,4 +149,33 @@ public class FileRenderer extends InputR
 
     writer.endElement(HtmlElements.DIV);
   }
+
+  protected Classes getCssClasses(UIComponent component, String sub) {
+    return Classes.create(component, sub);
+  }
+
+  protected void writeDataAttributes(FacesContext facesContext, TobagoResponseWriter writer, AbstractUIFile file)
+      throws IOException {
+    HtmlRendererUtils.writeDataAttributes(facesContext, writer, file);
+  }
+
+  protected void writeVisibleInput(FacesContext facesContext, TobagoResponseWriter writer, AbstractUIFile file,
+      String clientId, Style style) throws IOException {
+    final Style inputStyle = new Style();
+    final Measure prettyWidthSub = getPrettyWidthSub(facesContext, file);
+    inputStyle.setWidth(style.getWidth().subtract(prettyWidthSub));
+    writer.startElement(HtmlElements.INPUT, file);
+    writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "pretty");
+    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT, false);
+    writer.writeClassAttribute(getCssClasses(file, "pretty"));
+    writer.writeStyleAttribute(inputStyle);
+    writer.writeAttribute(HtmlAttributes.DISABLED, true);
+    // TODO Focus
+    //HtmlRendererUtils.renderFocus(clientId, file.isFocus(), ComponentUtils.isError(file), facesContext, writer);
+    writer.endElement(HtmlElements.INPUT);
+  }
+
+  protected Measure getPrettyWidthSub(FacesContext facesContext, AbstractUIFile file) {
+    return getResourceManager().getThemeMeasure(facesContext, file, "prettyWidthSub");
+  }
 }

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml Wed Feb  1 10:40:22 2017
@@ -402,6 +402,7 @@
         <script name="script/tobago-calendar.js"/>
         <script name="script/tobago-console.js"/>
         <script name="script/tobago-converter.js"/>
+        <script name="script/tobago-file.js"/>
         <script name="script/tobago-in.js"/>
         <script name="script/tobago-menu.js"/>
         <script name="script/tobago-overlay.js"/>

Added: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-file.js
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-file.js?rev=1781217&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-file.js (added)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-file.js Wed Feb  1 10:40:22 2017
@@ -0,0 +1,222 @@
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Tobago.File = {};
+
+Tobago.File.init = function(elements) {
+  var files = Tobago.Utils.selectWithJQuery(elements, ".tobago-file-real");
+  files.change(function () {
+    var file = jQuery(this);
+    var pretty = file.prev();
+    var text;
+    if (file.prop("multiple")) {
+      var format = file.data("tobago-file-multi-format");
+      text = format.replace("{}", file.prop("files").length);
+    } else {
+      text = file.val();
+      // remove path, if any. Some old browsers set the path, others like webkit uses the prefix "C:\facepath\".
+      var pos = Math.max(text.lastIndexOf('/'), text.lastIndexOf('\\'));
+      if (pos >= 0) {
+        text = text.substr(pos + 1);
+      }
+    }
+    pretty.val(text);
+  });
+  if (files.length > 0) {
+    jQuery("form").attr('enctype', 'multipart/form-data')
+  }
+};
+
+Tobago.registerListener(Tobago.File.init, Tobago.Phase.DOCUMENT_READY);
+Tobago.registerListener(Tobago.File.init, Tobago.Phase.AFTER_UPDATE);
+
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+(function (jQuery) {
+
+  var dragenterCount = 0;
+
+  function initFileDropAreas(elements) {
+    console.info("initFileDropAreas " + (elements ? elements.length : "body")); // @DEV_ONLY
+
+    if (elements === undefined) {
+      console.info("initialize Body"); // @DEV_ONLY
+      var body = jQuery("body");
+      //noinspection SpellCheckingInspection
+      body.on("dragenter", dragenter);
+      //noinspection SpellCheckingInspection
+      body.on("dragleave", dragleave);
+      //noinspection SpellCheckingInspection
+      jQuery(window).on("dragover", dragoverOnDocument);
+      jQuery(window).on("drop", dropOnDocument);
+    }
+
+
+    Tobago.Utils.selectWithJQuery(elements, "[data-tobago-file-drop]").each(initFileDropArea);
+  }
+
+  function initFileDropArea() {
+    var area = jQuery(this);
+    console.info("initFileDropArea " + area.attr("id")); // @DEV_ONLY
+    area.filedroparea();
+  }
+
+
+  function dragenter(event) {
+    // console.info("dragEnter : " + dragenterCount + " : " + event.target.id); // @DEV_ONLY
+    event.stopPropagation();
+    event.stopImmediatePropagation();
+    event.preventDefault();
+    if (dragenterCount == 0) {
+      jQuery("[data-tobago-file-drop]").each(showDropAreas);
+    }
+    dragenterCount++;
+  }
+
+  function showDropAreas() {
+    // console.info("showDropAreas"); // @DEV_ONLY
+    jQuery(this).filedroparea("show");
+  }
+
+  function dragleave(event) {
+    // console.info("dragLeave : " + dragenterCount + " : " + event.target.id); // @DEV_ONLY
+    event.stopPropagation();
+    event.stopImmediatePropagation();
+    event.preventDefault();
+    dragenterCount--;
+    if (dragenterCount == 0) {
+      jQuery("[data-tobago-file-drop]").each(hideDropArea);
+    }
+  }
+
+  function hideDropArea() {
+    // console.info("hideDropArea"); // @DEV_ONLY
+    jQuery(this).filedroparea("hide");
+  }
+
+
+  function dragoverOnDocument(event) {
+    // console.info("dragoverOnDocument : " + event.target.id); // @DEV_ONLY
+    event.stopPropagation();
+    event.stopImmediatePropagation();
+    event.preventDefault();
+  }
+
+  function dropOnDocument(event) {
+    // console.info("dropOnDocument : " + event.target.id); // @DEV_ONLY
+    event.stopPropagation();
+    event.stopImmediatePropagation();
+    event.preventDefault();
+    jQuery("[data-tobago-file-drop]").each(removeDropListener);
+    dragenterCount = 0;
+  }
+
+
+  function removeDropListener() {
+    // console.info("removeDropListener"); // @DEV_ONLY
+    jQuery(this).filedroparea("hide");
+  }
+
+  jQuery.widget("tobago.filedroparea", {
+
+    options: {
+
+    },
+
+    fileDropArea: null,
+
+    findDropElement: function (dropZoneId) {
+      if (dropZoneId.charAt(0) == ":" && dropZoneId.charAt(1) != ":") {
+        return jQuery(Tobago.Utils.escapeClientId(dropZoneId.substring(1)));
+      } else  {
+        // TODO
+        return jQuery(Tobago.Utils.escapeClientId(dropZoneId));
+      }
+    },
+
+    _create: function () {
+
+      console.info("filedroparea.create"); // @DEV_ONLY
+      var data = this.element.data("tobago-file-drop");
+
+      var dropZoneId = data.dropZoneId;
+
+      var dropElement = this.findDropElement(dropZoneId);
+
+      // create the overlay
+      this.fileDropArea = jQuery("<div>").addClass("tobago-fileDrop-dropZone");
+      this.fileDropArea.css({display: 'none'});
+      this.fileDropArea.outerWidth(dropElement.outerWidth());
+      this.fileDropArea.outerHeight(dropElement.outerHeight());
+      this.fileDropArea.offset(dropElement.offset());
+      this.fileDropArea.data("widget-element", this.element);
+
+      jQuery(".tobago-page-menuStore").append(this.fileDropArea);
+
+      this.element.click(function (event) {
+        if (event.target.tagName != "input" && event.target.type != "file") {
+          // don't delegate click if already clicked on file input
+          jQuery(this).find("input[type='file']").click();
+        }
+      })
+    },
+
+    show: function () {
+      // console.info("show");  // @DEV_ONLY
+      this.fileDropArea.css({display: ''});
+      this.fileDropArea.on("drop", this.filesDropped);
+    },
+
+    hide: function () {
+      // console.info("hide"); // @DEV_ONLY
+      this.fileDropArea.off("drop");
+      this.fileDropArea.css({display: 'none'});
+    },
+
+    filesDropped: function (event) {
+      console.info("dropFile"); // @DEV_ONLY
+      event.stopPropagation();
+      event.stopImmediatePropagation();
+      event.preventDefault();
+
+      var dropThis = jQuery(this);
+      var fileDrop = dropThis.data("widget-element");
+      jQuery("[data-tobago-file-drop]").each(removeDropListener);
+      dragenterCount = 0;
+
+      //noinspection JSUnresolvedVariable
+      var files = event.originalEvent.dataTransfer.files;
+      console.info("files.length: " + files.length); // @DEV_ONLY
+      for (var i = 0; i < files.length; i++) {
+        var file = files[i];
+        console.info("file: " + file.name); // @DEV_ONLY
+      }
+
+      if (files.length == 0) {
+        console.warn("no files dropped, aborting upload!");
+      }
+
+      var fileElement = fileDrop.find("input[type='file']");
+      var commands = fileElement.data("tobago-commands");
+      if (!commands || !commands.change || !commands.change.partially) {
+        console.error("No input type file with renderedPartially found, abbort upload!");
+      }
+
+      jQuery(Tobago.form).data("tobago-file-drag-and-drop-files", {name: fileElement.attr("name"), files: files});
+      fileElement.change();
+
+    },
+
+    _destroy: function () {
+      try {
+        this.fileDropArea.remove();
+      } catch (e) { /* ignore */ }
+      this.fileDropArea = null;
+    }
+
+  });
+
+  Tobago.registerListener(initFileDropAreas, Tobago.Phase.AFTER_UPDATE);
+  Tobago.registerListener(initFileDropAreas, Tobago.Phase.DOCUMENT_READY);
+
+}(jQuery));

Modified: myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago.js
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago.js?rev=1781217&r1=1781216&r2=1781217&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago.js (original)
+++ myfaces/tobago/branches/tobago-2.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago.js Wed Feb  1 10:40:22 2017
@@ -1931,8 +1931,19 @@ Tobago.Transport.JqueryTransport = {
       Tobago.partialRequestIds.value = requestOptions.ajaxComponentIds;
       var form = jQuery(Tobago.form);
       console.debug("enctype: " + form.attr("enctype")); // @DEV_ONLY
-      if ((form.attr("enctype")|| "").toLocaleLowerCase() == "multipart/form-data") {
-        requestObject.data = new FormData(Tobago.form);
+      if ((form.attr("enctype") || "").toLocaleLowerCase() == "multipart/form-data") {
+        var formData = new FormData(Tobago.form);
+        var fileData = form.data("tobago-file-drag-and-drop-files");
+        if (fileData && fileData.files.length > 0) {
+          var clientName = fileData.name;
+          for (var i = 0; i < fileData.files.length; i++) {
+            var file = fileData.files[i];
+            console.info("adding " + clientName + " file " + file.name); // @DEV_ONLY
+            formData.append(clientName, file);
+          }
+          form.removeData("tobago-file-drag-and-drop-files");
+        }
+        requestObject.data = formData;
         requestObject.processData = false;
         requestObject.contentType = false;
       } else {
@@ -2755,37 +2766,6 @@ Tobago.registerListener(Tobago.SelectMan
 
 // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-Tobago.File = {};
-
-Tobago.File.init = function(elements) {
-  var files = Tobago.Utils.selectWithJQuery(elements, ".tobago-file-real");
-  files.change(function () {
-    var file = jQuery(this);
-    var pretty = file.prev();
-    var text;
-    if (file.prop("multiple")) {
-      var format = file.data("tobago-file-multi-format");
-      text = format.replace("{}", file.prop("files").length);
-    } else {
-      text = file.val();
-      // remove path, if any. Some old browsers set the path, others like webkit uses the prefix "C:\facepath\".
-      var pos = Math.max(text.lastIndexOf('/'), text.lastIndexOf('\\'));
-      if (pos >= 0) {
-        text = text.substr(pos + 1);
-      }
-    }
-    pretty.val(text);
-  });
-  if (files.length > 0) {
-    jQuery("form").attr('enctype', 'multipart/form-data')
-  }
-};
-
-Tobago.registerListener(Tobago.File.init, Tobago.Phase.DOCUMENT_READY);
-Tobago.registerListener(Tobago.File.init, Tobago.Phase.AFTER_UPDATE);
-
-// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
 Tobago.Codi = {};
 
 /**