You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2019/08/07 11:44:21 UTC

[myfaces-tobago] 01/02: TOBAGO-1633: TS refactoring

This is an automated email from the ASF dual-hosted git repository.

lofwyr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git

commit 6f8aa6377d57b1f401de6cb7b3830e3a7c2d604f
Author: Udo Schnurpfeil <lo...@apache.org>
AuthorDate: Wed Aug 7 13:17:23 2019 +0200

    TOBAGO-1633: TS refactoring
    
    First PoC of "Custom Elements"
---
 .../internal/renderkit/renderer/StarsRenderer.java |   4 +-
 .../tobago/renderkit/html/HtmlElements.java        |   4 +-
 .../renderkit/html/HtmlElementsUnitTest.java       |  10 +-
 tobago-theme/tobago-theme-standard/pom.xml         |   5 +
 .../src/main/npm/ts/tobago-stars.ts                | 240 ++++++++++-----------
 .../src/main/resources/META-INF/tobago-config.xml  |   2 +
 6 files changed, 140 insertions(+), 125 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
index 1bfa00f..700a46b 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
@@ -58,7 +58,7 @@ public class StarsRenderer extends MessageLayoutRendererBase {
         ? (String) stars.getSubmittedValue() : String.valueOf(value);
     final String hiddenInputValue = required && "0".equals(sliderValue) ? null : sliderValue;
 
-    writer.startElement(HtmlElements.DIV);
+    writer.startElement(HtmlElements.TOBAGO_STARS);
     writer.writeIdAttribute(fieldId);
     writer.writeClassAttribute(
         TobagoClass.STARS,
@@ -121,7 +121,7 @@ public class StarsRenderer extends MessageLayoutRendererBase {
   @Override
   protected void encodeEndField(FacesContext facesContext, UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
-    writer.endElement(HtmlElements.DIV);
+    writer.endElement(HtmlElements.TOBAGO_STARS);
   }
 
   @Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
index b811917..0b239a9 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
@@ -131,7 +131,9 @@ public enum HtmlElements {
   UL("ul"),
   VAR("var"),
   VIDEO("video"),
-  WBR("wbr", Qualifier.VOID);
+  WBR("wbr", Qualifier.VOID),
+
+  TOBAGO_STARS("tobago-stars");
 
   private final String value;
   private final boolean voidElement;
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/HtmlElementsUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/HtmlElementsUnitTest.java
index 590dc31..e89a13f 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/HtmlElementsUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/HtmlElementsUnitTest.java
@@ -34,8 +34,14 @@ public class HtmlElementsUnitTest {
 
       final HtmlElements element = (HtmlElements) field.get(null);
       final String value = element.getValue();
-      Assertions.assertEquals(value, element.name().toLowerCase(), "Check to lower: '" + element + "'");
-      Assertions.assertEquals(value.toUpperCase(), element.name(), "Check to upper: '" + element + "'");
+      Assertions.assertEquals(
+          value,
+          element.name().toLowerCase().replaceAll("_", "-"),
+          "Check to lower: '" + element + "'");
+      Assertions.assertEquals(
+          value.toUpperCase().replaceAll("-", "_"),
+          element.name(),
+          "Check to upper: '" + element + "'");
     }
   }
 
diff --git a/tobago-theme/tobago-theme-standard/pom.xml b/tobago-theme/tobago-theme-standard/pom.xml
index 1a7b324..32b1e71 100644
--- a/tobago-theme/tobago-theme-standard/pom.xml
+++ b/tobago-theme/tobago-theme-standard/pom.xml
@@ -85,6 +85,11 @@
       <version>2.22.2</version>
     </dependency>
     <dependency>
+      <groupId>org.webjars.npm</groupId>
+      <artifactId>webcomponents__custom-elements</artifactId>
+      <version>1.2.1</version>
+    </dependency>
+    <dependency>
       <groupId>org.apache.myfaces.tobago</groupId>
         <artifactId>tobago-pack-typeahead</artifactId>
       <version>${project.version}</version>
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-stars.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-stars.ts
index 22c6bdd..29d0e09 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-stars.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-stars.ts
@@ -15,148 +15,148 @@
  * limitations under the License.
  */
 
-import {Listener, Phase} from "./tobago-listener";
-import {DomUtils, Tobago4Utils} from "./tobago-utils";
-
-class Stars {
-
-  static init(element: HTMLElement) {
-    for (const star of DomUtils.selfOrQuerySelectorAll(element, ".tobago-stars")) {
-      const hiddenInput = star.querySelector("input[type=hidden]") as HTMLInputElement;
-      const container = star.querySelector(".tobago-stars-container") as HTMLElement;
-      const tooltip = container.querySelector(".tobago-stars-tooltip") as HTMLElement;
-      const selected = container.querySelector(".tobago-stars-selected") as HTMLElement;
-      const unselected = container.querySelector(".tobago-stars-unselected") as HTMLElement;
-      const preselected = container.querySelector(".tobago-stars-preselected") as HTMLElement;
-      const slider = container.querySelector(".tobago-stars-slider") as HTMLInputElement;
-
-      const readonly = slider.readOnly;
-      const disabled = slider.disabled;
-      const required = slider.required;
-
-      const max = parseInt(slider.max);
-      const placeholder = parseInt(slider.placeholder);
-
-      if (parseInt(slider.min) === 0) {
-        slider.style["left"] = "-" + (100 / max) + "%";
-        slider.style["width"] = 100 + (100 / max) + "%";
-      }
+class Stars extends HTMLElement {
 
-      const currentValue = parseInt(hiddenInput.value);
-      if (currentValue > 0) {
-        const percentValue = 100 * currentValue / max;
-        selected.style["width"] = percentValue + "%";
-        unselected.style["left"] = percentValue + "%";
-        unselected.style["width"] = 100 - percentValue + "%";
-      } else if (placeholder) {
-        selected.classList.add("tobago-placeholder");
-        const placeholderValue = 100 * placeholder / max;
-        selected.style["width"] = placeholderValue + "%";
-        unselected.style["left"] = placeholderValue + "%";
-        unselected.style["width"] = 100 - placeholderValue + "%";
-      }
+  constructor() {
+    super();
+  }
 
-      if (!readonly && !disabled) {
-        /* preselectMode is a Workaround for IE11: fires change event instead of input event */
-        let preselectMode = false;
-        slider.addEventListener('mousedown', function (event) {
-          preselectMode = true;
-        });
-        slider.addEventListener('mouseup', function (event) {
-          preselectMode = false;
-          selectStars();
-        });
+  connectedCallback() {
+    const hiddenInput = this.querySelector("input[type=hidden]") as HTMLInputElement;
+    const container = this.querySelector(".tobago-stars-container") as HTMLElement;
+    const tooltip = container.querySelector(".tobago-stars-tooltip") as HTMLElement;
+    const selected = container.querySelector(".tobago-stars-selected") as HTMLElement;
+    const unselected = container.querySelector(".tobago-stars-unselected") as HTMLElement;
+    const preselected = container.querySelector(".tobago-stars-preselected") as HTMLElement;
+    const slider = container.querySelector(".tobago-stars-slider") as HTMLInputElement;
+
+    const readonly = slider.readOnly;
+    const disabled = slider.disabled;
+    const required = slider.required;
+
+    const max = parseInt(slider.max);
+    const placeholder = parseInt(slider.placeholder);
+
+    if (parseInt(slider.min) === 0) {
+      slider.style["left"] = "-" + (100 / max) + "%";
+      slider.style["width"] = 100 + (100 / max) + "%";
+    }
 
-        slider.addEventListener('input', function (event) {
-          preselectStars();
-        });
-        slider.addEventListener('touchend', function (event) {
-          /* Workaround for mobile devices. TODO: fire AJAX request for 'touchend' */
-          // slider.trigger("change");
-          slider.dispatchEvent(new Event("change"));
-        });
-        slider.addEventListener('change', function (event) {
-          if (preselectMode) {
-            preselectStars();
-          } else {
-            selectStars();
-          }
-        });
-
-        slider.addEventListener('touchstart', touchstart);
-        slider.addEventListener('touchmove', touchstart);
-      }
+    const currentValue = parseInt(hiddenInput.value);
+    if (currentValue > 0) {
+      const percentValue = 100 * currentValue / max;
+      selected.style["width"] = percentValue + "%";
+      unselected.style["left"] = percentValue + "%";
+      unselected.style["width"] = 100 - percentValue + "%";
+    } else if (placeholder) {
+      selected.classList.add("tobago-placeholder");
+      const placeholderValue = 100 * placeholder / max;
+      selected.style["width"] = placeholderValue + "%";
+      unselected.style["left"] = placeholderValue + "%";
+      unselected.style["width"] = 100 - placeholderValue + "%";
+    }
 
-      // XXX current issue: on ios-Safari select 5 stars and than click on 1 star doesn't work on labeled component.
-      function touchstart(event: TouchEvent) {
-        /* Workaround for Safari browser on iPhone */
-        const target = event.currentTarget as HTMLInputElement;
-        const sliderValue = (parseInt(target.max) / target.offsetWidth) * (event.touches[0].pageX - slider.offsetLeft);
-        if (sliderValue > parseInt(target.max)) {
-          slider.value = target.max;
-        } else if (sliderValue < parseInt(target.min)) {
-          slider.value = target.min;
+    if (!readonly && !disabled) {
+      /* preselectMode is a Workaround for IE11: fires change event instead of input event */
+      let preselectMode = false;
+      slider.addEventListener('mousedown', function (event) {
+        preselectMode = true;
+      });
+      slider.addEventListener('mouseup', function (event) {
+        preselectMode = false;
+        selectStars();
+      });
+
+      slider.addEventListener('input', function (event) {
+        preselectStars();
+      });
+      slider.addEventListener('touchend', function (event) {
+        /* Workaround for mobile devices. TODO: fire AJAX request for 'touchend' */
+        // slider.trigger("change");
+        slider.dispatchEvent(new Event("change"));
+      });
+      slider.addEventListener('change', function (event) {
+        if (preselectMode) {
+          preselectStars();
         } else {
-          slider.value = String(sliderValue);
+          selectStars();
         }
-        preselectStars();
+      });
+
+      slider.addEventListener('touchstart', touchstart);
+      slider.addEventListener('touchmove', touchstart);
+    }
+
+    // XXX current issue: on ios-Safari select 5 stars and than click on 1 star doesn't work on labeled component.
+    function touchstart(event: TouchEvent) {
+      /* Workaround for Safari browser on iPhone */
+      const target = event.currentTarget as HTMLInputElement;
+      const sliderValue = (parseInt(target.max) / target.offsetWidth) * (event.touches[0].pageX - slider.offsetLeft);
+      if (sliderValue > parseInt(target.max)) {
+        slider.value = target.max;
+      } else if (sliderValue < parseInt(target.min)) {
+        slider.value = target.min;
+      } else {
+        slider.value = String(sliderValue);
       }
+      preselectStars();
+    }
+
+    function preselectStars() {
+      tooltip.classList.add("show");
 
-      function preselectStars() {
-        tooltip.classList.add("show");
+      if (parseInt(slider.value) > 0) {
+        tooltip.classList.remove("trash");
+        tooltip.textContent = (5 * (parseInt(slider.value)) / max).toFixed(2);
 
-        if (parseInt(slider.value) > 0) {
-          tooltip.classList.remove("trash");
-          tooltip.textContent = (5 * (parseInt(slider.value)) / max).toFixed(2);
+        preselected.classList.add("show");
+        preselected.style["width"] = (100 * parseInt(slider.value) / max) + "%";
+      } else {
+        tooltip.textContent = "";
+        tooltip.classList.add("trash");
 
+        if (placeholder) {
           preselected.classList.add("show");
-          preselected.style["width"] = (100 * parseInt(slider.value) / max) + "%";
+          preselected.style["width"] = (100 * placeholder / max) + "%";
         } else {
-          tooltip.textContent = "";
-          tooltip.classList.add("trash");
-
-          if (placeholder) {
-            preselected.classList.add("show");
-            preselected.style["width"] = (100 * placeholder / max) + "%";
-          } else {
-            preselected.classList.remove("show");
-          }
+          preselected.classList.remove("show");
         }
       }
+    }
 
-      function selectStars() {
-        tooltip.classList.remove("show");
-        preselected.classList.remove("show");
+    function selectStars() {
+      tooltip.classList.remove("show");
+      preselected.classList.remove("show");
 
-        if (parseInt(slider.value) > 0) {
-          selected.classList.remove("tobago-placeholder");
+      if (parseInt(slider.value) > 0) {
+        selected.classList.remove("tobago-placeholder");
 
-          const percentValue = 100 * parseInt(slider.value) / max;
-          selected.style["width"] = percentValue + "%";
-          unselected.style["left"] = percentValue + "%";
-          unselected.style["width"] = 100 - percentValue + "%";
+        const percentValue = 100 * parseInt(slider.value) / max;
+        selected.style["width"] = percentValue + "%";
+        unselected.style["left"] = percentValue + "%";
+        unselected.style["width"] = 100 - percentValue + "%";
 
-          hiddenInput.value = slider.value;
+        hiddenInput.value = slider.value;
+      } else {
+        if (placeholder) {
+          selected.classList.add("tobago-placeholder");
+          const placeholderValue = 100 * placeholder / max;
+          selected.style["width"] = placeholderValue + "%";
+          unselected.style["left"] = placeholderValue + "%";
+          unselected.style["width"] = 100 - placeholderValue + "%";
         } else {
-          if (placeholder) {
-            selected.classList.add("tobago-placeholder");
-            const placeholderValue = 100 * placeholder / max;
-            selected.style["width"] = placeholderValue + "%";
-            unselected.style["left"] = placeholderValue + "%";
-            unselected.style["width"] = 100 - placeholderValue + "%";
-          } else {
-            selected.classList.remove("tobago-placeholder");
-            selected.style["width"] = "";
-            unselected.style["left"] = "";
-            unselected.style["width"] = "";
-          }
-
-          hiddenInput.value = required ? "" : slider.value;
+          selected.classList.remove("tobago-placeholder");
+          selected.style["width"] = "";
+          unselected.style["left"] = "";
+          unselected.style["width"] = "";
         }
+
+        hiddenInput.value = required ? "" : slider.value;
       }
     }
   }
 }
 
-Listener.register(Stars.init, Phase.DOCUMENT_READY);
-Listener.register(Stars.init, Phase.AFTER_UPDATE);
+document.addEventListener("DOMContentLoaded", function (event) {
+  window.customElements.define('tobago-stars', Stars);
+});
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
index 353e177..5f3f5c1 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
@@ -38,6 +38,7 @@
       <versioned>true</versioned>
       <resources production="true">
         <includes>
+          <script name="/webjars/webcomponents__custom-elements/1.2.1/custom-elements.min.js"/>
           <script name="/webjars/jquery/3.4.1/jquery.min.js"/>
           <script name="/webjars/tether/1.4.0/js/tether.min.js"/>
           <script name="/webjars/popper.js/1.14.3/umd/popper.min.js"/>
@@ -55,6 +56,7 @@
       </resources>
       <resources production="false">
         <includes>
+          <script name="/webjars/webcomponents__custom-elements/1.2.1/externs/custom-elements.js"/>
           <script name="/webjars/jquery/3.4.1/jquery.js"/>
           <script name="/webjars/tether/1.4.0/js/tether.js"/>
           <script name="/webjars/popper.js/1.14.3/umd/popper.js"/>