You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by hn...@apache.org on 2023/02/28 14:00:17 UTC
[myfaces-tobago] branch main updated: fix: menu store position
This is an automated email from the ASF dual-hosted git repository.
hnoeth 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 a13445f8ec fix: menu store position
a13445f8ec is described below
commit a13445f8ecb17e66791d5fb14ead377506630ec6
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Tue Feb 28 12:54:28 2023 +0100
fix: menu store position
* add test
* render the menu store at the start of the page
Issue: TOBAGO-2198
---
.../internal/renderkit/renderer/PageRenderer.java | 48 ++++++++++------------
.../tobago/example/demo/ExceptionController.java | 13 ++++++
.../50000-java/40-force-npe/Force_NPE.test.js | 35 ++++++++++++++++
.../50000-java/40-force-npe/Force_NPE.xhtml | 36 ++++++++++++++++
4 files changed, 106 insertions(+), 26 deletions(-)
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 5a5a2a6fbc..fc8d83a06d 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
@@ -19,6 +19,14 @@
package org.apache.myfaces.tobago.internal.renderkit.renderer;
+import jakarta.faces.application.Application;
+import jakarta.faces.application.ProjectStage;
+import jakarta.faces.application.ViewHandler;
+import jakarta.faces.component.UIComponent;
+import jakarta.faces.component.UIOutput;
+import jakarta.faces.component.UIViewRoot;
+import jakarta.faces.context.ExternalContext;
+import jakarta.faces.context.FacesContext;
import org.apache.myfaces.tobago.component.Attributes;
import org.apache.myfaces.tobago.component.RendererTypes;
import org.apache.myfaces.tobago.component.Tags;
@@ -52,15 +60,6 @@ import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import jakarta.faces.application.Application;
-import jakarta.faces.application.ProjectStage;
-import jakarta.faces.application.ViewHandler;
-import jakarta.faces.component.UIComponent;
-import jakarta.faces.component.UIOutput;
-import jakarta.faces.component.UIViewRoot;
-import jakarta.faces.context.ExternalContext;
-import jakarta.faces.context.FacesContext;
-
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
@@ -131,6 +130,7 @@ public class PageRenderer<T extends AbstractUIPage> extends RendererBase<T> {
final UIViewRoot viewRoot = facesContext.getViewRoot();
final String viewId = viewRoot.getViewId();
final String formAction = externalContext.encodeActionURL(viewHandler.getActionURL(facesContext, viewId));
+ final boolean ajax = facesContext.getPartialViewContext().isAjaxRequest();
final String contentType = writer.getContentTypeWithCharSet();
ResponseUtils.ensureContentTypeHeader(facesContext, contentType);
@@ -276,6 +276,19 @@ public class PageRenderer<T extends AbstractUIPage> extends RendererBase<T> {
}
}
+ // placeholder for menus
+ writer.startElement(HtmlElements.DIV);
+ writer.writeClassAttribute(TobagoClass.PAGE__MENU_STORE);
+ writer.endElement(HtmlElements.DIV);
+
+ writer.startElement(HtmlElements.SPAN);
+ writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "faces-state-container");
+ writer.flush();
+ if (!ajax) {
+ viewHandler.writeState(facesContext);
+ }
+ writer.endElement(HtmlElements.SPAN);
+
if (component.getFacet("backButtonDetector") != null) {
final UIComponent hidden = component.getFacet("backButtonDetector");
hidden.encodeAll(facesContext);
@@ -302,23 +315,6 @@ public class PageRenderer<T extends AbstractUIPage> extends RendererBase<T> {
final UIViewRoot viewRoot = facesContext.getViewRoot();
final TobagoResponseWriter writer = getResponseWriter(facesContext);
- final String clientId = component.getClientId(facesContext);
- final Application application = facesContext.getApplication();
- final ViewHandler viewHandler = application.getViewHandler();
- final boolean ajax = facesContext.getPartialViewContext().isAjaxRequest();
-
- // placeholder for menus
- writer.startElement(HtmlElements.DIV);
- writer.writeClassAttribute(TobagoClass.PAGE__MENU_STORE);
- writer.endElement(HtmlElements.DIV);
-
- writer.startElement(HtmlElements.SPAN);
- writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "faces-state-container");
- writer.flush();
- if (!ajax) {
- viewHandler.writeState(facesContext);
- }
- writer.endElement(HtmlElements.SPAN);
writer.endElement(HtmlElements.FORM);
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/ExceptionController.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/ExceptionController.java
index 85037a7c2c..cebe28d6fd 100644
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/ExceptionController.java
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/ExceptionController.java
@@ -31,6 +31,8 @@ import java.io.StringWriter;
@Named
public class ExceptionController implements Serializable {
+ private boolean returnNpe;
+
public String getStackTrace() {
final Throwable exception = (Throwable) FacesContext.getCurrentInstance().getExternalContext()
.getRequestMap().get("jakarta.servlet.error.exception");
@@ -41,4 +43,15 @@ public class ExceptionController implements Serializable {
}
return stringWriter.toString();
}
+
+ public String getStringOrNpe() {
+ if (returnNpe) {
+ throw new NullPointerException("The exception is thrown by purpose.");
+ }
+ return "no NPE";
+ }
+
+ public void returnNpe() {
+ returnNpe = true;
+ }
}
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/50000-java/40-force-npe/Force_NPE.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/50000-java/40-force-npe/Force_NPE.test.js
new file mode 100644
index 0000000000..30dc11e3fd
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/50000-java/40-force-npe/Force_NPE.test.js
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+import {elementByIdFn, querySelectorFn} from "/script/tobago-test.js";
+import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
+
+it("menu store must be available", function (done) {
+ const timestampFn = querySelectorFn("#page\\:mainForm\\:timestamp .form-control-plaintext");
+ const submitFn = elementByIdFn("page:mainForm:submitButton");
+ const forceNpeFn = elementByIdFn("page:mainForm:forceNpeButton");
+ const menuStoreFn = querySelectorFn(".tobago-page-menuStore");
+
+ const timestampValue = timestampFn().textContent;
+
+ let test = new JasmineTestTool(done);
+ test.setup(() => menuStoreFn() !== null, null, "click", submitFn);
+ test.do(() => expect(menuStoreFn()).not.toBeNull());
+ test.event("click", forceNpeFn, () => timestampFn().textContent !== timestampValue);
+ test.do(() => expect(menuStoreFn()).not.toBeNull());
+ test.start();
+});
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/50000-java/40-force-npe/Force_NPE.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/50000-java/40-force-npe/Force_NPE.xhtml
new file mode 100644
index 0000000000..4a3dc17c8e
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/50000-java/40-force-npe/Force_NPE.xhtml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ * 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.
+-->
+
+<ui:composition template="/main.xhtml"
+ xmlns:f="http://xmlns.jcp.org/jsf/core"
+ xmlns:tc="http://myfaces.apache.org/tobago/component"
+ xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
+ <ui:param name="title" value="Ajax Unicode"/>
+
+ <tc:button id="ajaxButton" label="AJAX">
+ <f:ajax render="box"/>
+ </tc:button>
+ <tc:button id="submitButton" label="Submit"/>
+ <tc:button id="forceNpeButton" label="NPE!" action="#{exceptionController.returnNpe()}"/>
+
+ <tc:box id="box" label="Box">
+ <tc:out id="timestamp" label="Timestamp" value="#{ajaxSpecialCharacterController.timestamp}"/>
+ <tc:out label="NPE?" value="#{exceptionController.stringOrNpe}"/>
+ </tc:box>
+</ui:composition>