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 2022/11/25 16:43:29 UTC

[myfaces-tobago] branch main updated: feat: client configuration (#3458)

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

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


The following commit(s) were added to refs/heads/main by this push:
     new 10d0a239e0 feat: client configuration (#3458)
10d0a239e0 is described below

commit 10d0a239e0500bc5e4dee7e508ee8e5177351fc5
Author: Udo Schnurpfeil <lo...@apache.org>
AuthorDate: Fri Nov 25 17:43:24 2022 +0100

    feat: client configuration (#3458)
    
    issue: TOBAGO-2172
    issue: TOBAGO-2173
---
 .../myfaces/tobago/component/Attributes.java       |  3 +
 .../myfaces/tobago/component/RendererTypes.java    |  2 +
 .../org/apache/myfaces/tobago/component/Tags.java  |  2 +
 .../myfaces/tobago/context/TobagoContext.java      | 61 +++++++++++++++++
 .../internal/component/AbstractUIConfig.java       | 79 ++++++++++++++++++++++
 .../renderkit/renderer/ConfigRenderer.java         | 30 ++++++++
 .../internal/renderkit/renderer/PageRenderer.java  |  5 ++
 .../taglib/component/ConfigTagDeclaration.java     | 64 ++++++++++++++++++
 .../tobago/renderkit/html/HtmlAttributes.java      |  3 +
 .../tobago/renderkit/html/HtmlElements.java        |  1 +
 tobago-theme/src/main/scss/_tobago.scss            |  5 ++
 .../src/main/ts/tobago-config.ts                   | 36 ++++++++--
 .../src/main/ts/tobago-focus.ts                    | 11 +--
 .../src/main/ts/tobago-overlay.ts                  | 11 ++-
 .../src/main/ts/tobago-page.ts                     | 25 +++++++
 15 files changed, 322 insertions(+), 16 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
index 70eb42717c..0ad982eff0 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
@@ -115,6 +115,7 @@ public enum Attributes {
   fragment,
   frequency,
   focus,
+  focusOnError,
   focusId,
   formatPattern,
   forValue("for"),
@@ -445,6 +446,8 @@ public enum Attributes {
   update,
   validator,
   viewport,
+  waitOverlayDelayAjax,
+  waitOverlayDelayFull,
   width,
   widthList,
   zIndex;
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
index 0b9f91e1f8..27e90ae5fe 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
@@ -29,6 +29,7 @@ public enum RendererTypes {
   Box,
   Button,
   Buttons,
+  Config,
   Calendar,
   Column,
   ColumnSelector,
@@ -101,6 +102,7 @@ public enum RendererTypes {
   public static final String BOX = "Box";
   public static final String BUTTON = "Button";
   public static final String BUTTONS = "Buttons";
+  public static final String CONFIG = "Config";
   public static final String CALENDAR = "Calendar";
   public static final String COLUMN = "Column";
   public static final String COLUMN_SELECTOR = "ColumnSelector";
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
index 683b8ea686..6620e764e2 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
@@ -34,6 +34,7 @@ public enum Tags {
   button,
   buttons,
   calendar,
+  config,
   column,
   columnNode,
   columnSelector,
@@ -105,6 +106,7 @@ public enum Tags {
   public static final String BUTTON = "button";
   public static final String BUTTONS = "buttons";
   public static final String CALENDAR = "calendar";
+  public static final String CONFIG = "config";
   public static final String COLUMN = "column";
   public static final String COLUMN_NODE = "columnNode";
   public static final String COLUMN_SELECTOR = "columnSelector";
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
index 88bfb07cea..9075e284a2 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
@@ -19,6 +19,7 @@
 
 package org.apache.myfaces.tobago.context;
 
+import org.apache.myfaces.tobago.component.Attributes;
 import org.apache.myfaces.tobago.config.TobagoConfig;
 import org.apache.myfaces.tobago.internal.util.CookieUtils;
 import org.slf4j.Logger;
@@ -182,6 +183,66 @@ public class TobagoContext implements Serializable {
     facesContext.getAttributes().put(ENCTYPE_KEY, enctype);
   }
 
+  /**
+   * @since 5.4.0
+   */
+  public Boolean getFocusOnError() {
+    final Boolean focusOnError = (Boolean) FacesContext.getCurrentInstance().getAttributes().get(Attributes.focusOnError);
+    if (focusOnError != null) {
+      return focusOnError;
+    } else {
+      // todo: get default from TobagoConfig
+      return true;
+    }
+  }
+
+  /**
+   * @since 5.4.0
+   */
+  public void setFocusOnError(final Boolean focusOnError) {
+    FacesContext.getCurrentInstance().getAttributes().put(Attributes.focusOnError, focusOnError);
+  }
+
+  /**
+   * @since 5.4.0
+   */
+  public Integer getWaitOverlayDelayFull() {
+    final Integer waitOverlayDelayFull = (Integer) FacesContext.getCurrentInstance().getAttributes().get(Attributes.waitOverlayDelayFull);
+    if (waitOverlayDelayFull != null) {
+      return waitOverlayDelayFull;
+    } else {
+      // todo: get default from TobagoConfig
+      return 1000;
+    }
+  }
+
+  /**
+   * @since 5.4.0
+   */
+  public void setWaitOverlayDelayFull(final Integer waitOverlayDelayFull) {
+    FacesContext.getCurrentInstance().getAttributes().put(Attributes.waitOverlayDelayFull, waitOverlayDelayFull);
+  }
+
+  /**
+   * @since 5.4.0
+   */
+  public Integer getWaitOverlayDelayAjax() {
+    final Integer waitOverlayDelayAjax = (Integer) FacesContext.getCurrentInstance().getAttributes().get(Attributes.waitOverlayDelayAjax);
+    if (waitOverlayDelayAjax != null) {
+      return waitOverlayDelayAjax;
+    } else {
+      // todo: get default from TobagoConfig
+      return 1000;
+    }
+  }
+
+  /**
+   * @since 5.4.0
+   */
+  public void setWaitOverlayDelayAjax(final Integer waitOverlayDelayAjax) {
+    FacesContext.getCurrentInstance().getAttributes().put(Attributes.waitOverlayDelayAjax, waitOverlayDelayAjax);
+  }
+
   public static TobagoContext getInstance(final FacesContext facesContext) {
     final Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap();
     if (requestMap.containsKey(BEAN_NAME)) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIConfig.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIConfig.java
new file mode 100644
index 0000000000..bbe900f689
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIConfig.java
@@ -0,0 +1,79 @@
+/*
+ * 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.apache.myfaces.tobago.context.TobagoContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.faces.component.UIOutput;
+import javax.faces.event.ComponentSystemEvent;
+import javax.faces.event.ListenerFor;
+import javax.faces.event.PostAddToViewEvent;
+import javax.faces.event.PostRestoreStateEvent;
+import javax.faces.event.PreRenderViewEvent;
+import java.lang.invoke.MethodHandles;
+
+/**
+ * {@link org.apache.myfaces.tobago.internal.taglib.component.ConfigTagDeclaration}
+ *
+ * @since 5.4.0
+ */
+@ListenerFor(systemEventClass = PostAddToViewEvent.class)
+public abstract class AbstractUIConfig extends UIOutput {
+
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  @Override
+  public void processEvent(final ComponentSystemEvent event) {
+
+    super.processEvent(event);
+
+    if (event instanceof PreRenderViewEvent || event instanceof PostRestoreStateEvent) {
+
+      final Boolean focusOnError = getFocusOnError();
+      if (focusOnError != null) {
+        TobagoContext.getInstance(event.getFacesContext()).setFocusOnError(focusOnError);
+      }
+
+      final Integer waitOverlayDelayFull = getWaitOverlayDelayFull();
+      if (waitOverlayDelayFull != null) {
+        TobagoContext.getInstance(event.getFacesContext()).setWaitOverlayDelayFull(waitOverlayDelayFull);
+      }
+
+      final Integer waitOverlayDelayAjax = getWaitOverlayDelayAjax();
+      if (waitOverlayDelayAjax != null) {
+        TobagoContext.getInstance(event.getFacesContext()).setWaitOverlayDelayAjax(waitOverlayDelayAjax);
+      }
+
+    } else if (event instanceof PostAddToViewEvent) {
+      // NOTE: PreRenderViewEvent can not be used
+      getFacesContext().getViewRoot().subscribeToEvent(PreRenderViewEvent.class, this);
+    }
+
+  }
+
+  public abstract Boolean getFocusOnError();
+
+  public abstract Integer getWaitOverlayDelayFull();
+
+  public abstract Integer getWaitOverlayDelayAjax();
+
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ConfigRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ConfigRenderer.java
new file mode 100644
index 0000000000..accd85a5aa
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ConfigRenderer.java
@@ -0,0 +1,30 @@
+/*
+ * 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.renderkit.renderer;
+
+import org.apache.myfaces.tobago.internal.component.AbstractUIConfig;
+import org.apache.myfaces.tobago.renderkit.RendererBase;
+
+/**
+ * Nothing to do, because values are rendered via {@link PageRenderer}.
+ */
+public class ConfigRenderer<T extends AbstractUIConfig> extends RendererBase<T> {
+
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
index 860489317d..5a5a2a6fbc 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
@@ -222,6 +222,11 @@ public class PageRenderer<T extends AbstractUIPage> extends RendererBase<T> {
     writer.writeIdAttribute(clientId);
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, component);
 
+    // write the config
+    writer.writeAttribute(HtmlAttributes.FOCUS_ON_ERROR, Boolean.toString(tobagoContext.getFocusOnError()), false);
+    writer.writeAttribute(HtmlAttributes.WAIT_OVERLAY_DELAY_FULL, tobagoContext.getWaitOverlayDelayFull());
+    writer.writeAttribute(HtmlAttributes.WAIT_OVERLAY_DELAY_AJAX, tobagoContext.getWaitOverlayDelayAjax());
+
     encodeBehavior(writer, facesContext, component);
 
     writer.startElement(HtmlElements.FORM);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ConfigTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ConfigTagDeclaration.java
new file mode 100644
index 0000000000..48ccd68c40
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ConfigTagDeclaration.java
@@ -0,0 +1,64 @@
+/*
+ * 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.taglib.component;
+
+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.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
+
+import javax.faces.component.UIOutput;
+
+/**
+ * Renders a UIComponent for configurations applied in the browser.
+ *
+ * @since 5.4.0
+ */
+@Tag(name = "config")
+@UIComponentTag(
+    uiComponent = "org.apache.myfaces.tobago.component.UIConfig",
+    componentFamily = UIOutput.COMPONENT_FAMILY,
+    rendererType = RendererTypes.CONFIG
+)
+public interface ConfigTagDeclaration extends HasIdBindingAndRendered {
+
+  /**
+   * Should the focus set to first error on page.
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "java.lang.Boolean")
+  void setFocusOnError(String focusOnError);
+
+  /**
+   * The delay before a full request will get an overlay.
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "java.lang.Integer")
+  void setWaitOverlayDelayFull(String waitOverlayDelayFull);
+
+  /**
+   * The delay before a AJAX request will get an overlay.
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "java.lang.Integer")
+  void setWaitOverlayDelayAjax(String waitOverlayDelayAjax);
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlAttributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlAttributes.java
index 84145f99b5..77d97c978e 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlAttributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlAttributes.java
@@ -43,6 +43,7 @@ public enum HtmlAttributes implements MarkupLanguageAttributes {
   DEFER("defer"),
   DISABLED("disabled"),
   ENCTYPE("enctype"),
+  FOCUS_ON_ERROR("focus-on-error"),
   FOR("for"),
   FRAMEBORDER("frameborder"),
   FREQUENCY("frequency"),
@@ -149,6 +150,8 @@ public enum HtmlAttributes implements MarkupLanguageAttributes {
   TYPE("type"),
   VALIGN("valign"),
   VALUE("value"),
+  WAIT_OVERLAY_DELAY_AJAX("wait-overlay-delay-ajax"),
+  WAIT_OVERLAY_DELAY_FULL("wait-overlay-delay-full"),
   WIDTH("width"),
   XMLNS("xmlns");
 
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 6ae0023cc0..5e98ec05ea 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
@@ -142,6 +142,7 @@ public enum HtmlElements {
   TOBAGO_BEHAVIOR("tobago-behavior", Qualifier.INLINE),
   TOBAGO_BUTTONS("tobago-buttons"),
   TOBAGO_BOX("tobago-box"),
+  TOBAGO_CONFIG("tobago-config"),
   TOBAGO_DATE("tobago-date"),
   TOBAGO_DROPDOWN("tobago-dropdown"),
   TOBAGO_FILE("tobago-file"),
diff --git a/tobago-theme/src/main/scss/_tobago.scss b/tobago-theme/src/main/scss/_tobago.scss
index 56cf12da7f..939066b768 100644
--- a/tobago-theme/src/main/scss/_tobago.scss
+++ b/tobago-theme/src/main/scss/_tobago.scss
@@ -1613,3 +1613,8 @@ tobago-tree-listbox {
 /* scroll --------------------------------------------------------- */
 tobago-scroll {
 }
+
+/* config --------------------------------------------------------- */
+tobago-config {
+  display: none;
+}
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-config.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-config.ts
index 6f79193da2..ed767ffaf5 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-config.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-config.ts
@@ -15,21 +15,45 @@
  * limitations under the License.
  */
 
+import {Page} from "./tobago-page";
+
+/**
+ * @deprecated since 5.4.0. Config is stored in Page object
+ */
 export class Config {
 
   private static map: Map<string, any> = new Map<string, any>();
 
+  /**
+   * @deprecated since 5.4.0
+   */
   static set(key: string, value: any): void {
-    this.map.set(key, value);
+    if (key === "Ajax.waitOverlayDelay") {
+       Page.page(document.querySelector("tobago-page")).waitOverlayDelayAjax = parseInt(value);
+    } else if (key === "Tobago.waitOverlayDelay") {
+       Page.page(document.querySelector("tobago-page")).waitOverlayDelayFull = parseInt(value);
+    } else {
+      this.map.set(key, value);
+    }
   }
 
+  /**
+   * @deprecated since 5.4.0
+   */
   static get(key: string): any {
-    const value = this.map.get(key);
-    if (value) {
-      return value;
+
+    if (key === "Ajax.waitOverlayDelay") {
+      return Page.page(document.querySelector("tobago-page")).waitOverlayDelayAjax;
+    } else if (key === "Tobago.waitOverlayDelay") {
+      return Page.page(document.querySelector("tobago-page")).waitOverlayDelayFull;
     } else {
-      console.warn("Config.get(" + key + ") = undefined");
-      return 0;
+      const value = this.map.get(key);
+      if (value) {
+        return value;
+      } else {
+        console.warn("Config.get(" + key + ") = undefined");
+        return 0;
+      }
     }
   }
 }
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-focus.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-focus.ts
index de47e96d8d..6926dc4f8c 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-focus.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-focus.ts
@@ -16,6 +16,7 @@
  */
 
 import {Page} from "./tobago-page";
+import {Config} from "./tobago-config";
 
 export class Focus extends HTMLElement {
 
@@ -53,10 +54,12 @@ export class Focus extends HTMLElement {
    * - first (the first input element (without tabindex=-1) gets the focus, not AJAX)
    */
   connectedCallback(): void {
-    const errorElement = this.errorElement;
-    if (errorElement) {
-      errorElement.focus();
-      return;
+    if (Page.page(this).focusOnError) {
+      const errorElement = this.errorElement;
+      if (errorElement) {
+        errorElement.focus();
+        return;
+      }
     }
 
     if (this.autofocusElements.length > 0) {
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-overlay.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-overlay.ts
index 37a7f9c0a1..6bdb758c4e 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-overlay.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-overlay.ts
@@ -19,16 +19,13 @@
  * Create a overlay barrier and animate it.
  */
 
-import {Config} from "./tobago-config";
+import {Page} from "./tobago-page";
 
 // XXX issue: if a ajax call is scheduled on the same element, the animation arrow will stacking and not desapearing.
 // XXX issue: "error" is not implemented correctly
 // see http://localhost:8080/demo-5-snapshot/content/140-partial/Partial_Ajax.xhtml to use this feature
 // XXX todo: check full page transitions
 
-Config.set("Tobago.waitOverlayDelay", 1000);
-Config.set("Ajax.waitOverlayDelay", 1000);
-
 export class Overlay extends HTMLElement {
 
   constructor() {
@@ -97,13 +94,15 @@ export class Overlay extends HTMLElement {
   }
 
   /**
-   * The delay for the wait overlay. If not set the default delay is read from Tobago.Config.
+   * The delay for the wait overlay. If not set the default delay is read from config.
    */
   get delay(): number {
     if (this.hasAttribute("delay")) {
       return parseInt(this.getAttribute("delay"));
+    } else if (this.type === "ajax") {
+      return Page.page(this).waitOverlayDelayAjax;
     } else {
-      return Config.get(this.type === "ajax" ? "Ajax.waitOverlayDelay" : "Tobago.waitOverlayDelay");
+      return Page.page(this).waitOverlayDelayFull;
     }
   }
 
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-page.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-page.ts
index 27802b8ae6..9b3ef3f7fa 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-page.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-page.ts
@@ -177,6 +177,31 @@ export class Page extends HTMLElement {
     }
     return locale;
   }
+
+  get focusOnError(): boolean {
+    return this.getAttribute("focus-on-error") === "true";
+  }
+
+  set focusOnError(focusOnError: boolean) {
+    this.setAttribute("focus-on-error", String(focusOnError));
+  }
+
+  get waitOverlayDelayFull(): number {
+    return parseInt(this.getAttribute("wait-overlay-delay-full")) || 1000;
+  }
+
+  set waitOverlayDelayFull(waitOverlayDelayFull: number) {
+    this.setAttribute("wait-overlay-delay-full", String(waitOverlayDelayFull));
+  }
+
+  get waitOverlayDelayAjax(): number {
+    return parseInt(this.getAttribute("wait-overlay-delay-ajax")) || 1000;
+  }
+
+  set waitOverlayDelayAjax(waitOverlayDelayAjax: number) {
+    this.setAttribute("wait-overlay-delay-ajax", waitOverlayDelayAjax.toString());
+  }
+
 }
 
 document.addEventListener("tobago.init", (event: Event): void => {