Update actions, Add IFrame
This commit is contained in:
parent
be55b1db77
commit
96c1c3b01b
@ -1,12 +1,17 @@
|
|||||||
package me.mrletsplay.nojs;
|
package me.mrletsplay.nojs;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import org.slf4j.helpers.NOPLogger;
|
import org.slf4j.helpers.NOPLogger;
|
||||||
|
|
||||||
import me.mrletsplay.nojs._test.DynPage;
|
import me.mrletsplay.nojs._test.DynPage;
|
||||||
import me.mrletsplay.nojs._test.LinksPage;
|
import me.mrletsplay.nojs._test.LinksPage;
|
||||||
|
import me.mrletsplay.nojs.page.Page;
|
||||||
import me.mrletsplay.simplehttpserver.dom.html.HtmlDocument;
|
import me.mrletsplay.simplehttpserver.dom.html.HtmlDocument;
|
||||||
import me.mrletsplay.simplehttpserver.dom.html.HtmlElement;
|
import me.mrletsplay.simplehttpserver.dom.html.HtmlElement;
|
||||||
import me.mrletsplay.simplehttpserver.dom.html.element.HtmlButton;
|
import me.mrletsplay.simplehttpserver.dom.html.element.HtmlButton;
|
||||||
@ -58,8 +63,25 @@ public class NoJS {
|
|||||||
|
|
||||||
// new TestEndpoint().register(httpServer.getDocumentProvider());
|
// new TestEndpoint().register(httpServer.getDocumentProvider());
|
||||||
|
|
||||||
new DynPage().register(httpServer.getDocumentProvider(), "/dyn");
|
BufferedImage img = new BufferedImage(64, 64, BufferedImage.TYPE_3BYTE_BGR);
|
||||||
new LinksPage().register(httpServer.getDocumentProvider(), "/links");
|
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
ImageIO.write(img, "PNG", bOut);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
byte[] bytes = bOut.toByteArray();
|
||||||
|
|
||||||
|
httpServer.getDocumentProvider().register(HttpRequestMethod.GET, "/favicon.ico", () -> {
|
||||||
|
HttpRequestContext ctx = HttpRequestContext.getCurrentContext();
|
||||||
|
ctx.getServerHeader().setContent(MimeType.PNG, bytes);
|
||||||
|
});
|
||||||
|
|
||||||
|
Page.register(
|
||||||
|
httpServer.getDocumentProvider(),
|
||||||
|
new DynPage(),
|
||||||
|
new LinksPage()
|
||||||
|
);
|
||||||
|
|
||||||
httpServer.getDocumentProvider().register(HttpRequestMethod.POST, "/", () -> {
|
httpServer.getDocumentProvider().register(HttpRequestMethod.POST, "/", () -> {
|
||||||
HttpRequestContext ctx = HttpRequestContext.getCurrentContext();
|
HttpRequestContext ctx = HttpRequestContext.getCurrentContext();
|
||||||
|
@ -11,6 +11,7 @@ import me.mrletsplay.nojs.component.impl.Text;
|
|||||||
import me.mrletsplay.nojs.page.Page;
|
import me.mrletsplay.nojs.page.Page;
|
||||||
import me.mrletsplay.nojs.page.layout.GridLayout;
|
import me.mrletsplay.nojs.page.layout.GridLayout;
|
||||||
import me.mrletsplay.nojs.page.layout.InsetLayout;
|
import me.mrletsplay.nojs.page.layout.InsetLayout;
|
||||||
|
import me.mrletsplay.simplehttpserver.http.request.HttpRequestContext;
|
||||||
|
|
||||||
public class DynPage implements Page {
|
public class DynPage implements Page {
|
||||||
|
|
||||||
@ -27,4 +28,15 @@ public class DynPage implements Page {
|
|||||||
.vAlignment(GridLayout.VAlignment.CENTER));
|
.vAlignment(GridLayout.VAlignment.CENTER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath() {
|
||||||
|
return "/dyn";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createContent() {
|
||||||
|
HttpRequestContext.getCurrentContext().getServerHeader().getFields().add("Refresh", "10");
|
||||||
|
Page.super.createContent();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
package me.mrletsplay.nojs._test;
|
package me.mrletsplay.nojs._test;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import me.mrletsplay.nojs.action.Action;
|
import me.mrletsplay.nojs.action.Action;
|
||||||
import me.mrletsplay.nojs.action.ActionData;
|
import me.mrletsplay.nojs.action.ActionData;
|
||||||
import me.mrletsplay.nojs.action.ActionEvent;
|
import me.mrletsplay.nojs.action.ActionEvent;
|
||||||
import me.mrletsplay.nojs.action.ActionHandler;
|
import me.mrletsplay.nojs.action.ActionHandler;
|
||||||
|
import me.mrletsplay.nojs.action.ActionResult;
|
||||||
import me.mrletsplay.nojs.component.Component;
|
import me.mrletsplay.nojs.component.Component;
|
||||||
import me.mrletsplay.nojs.component.impl.Button;
|
import me.mrletsplay.nojs.component.impl.Button;
|
||||||
import me.mrletsplay.nojs.component.impl.Form;
|
import me.mrletsplay.nojs.component.impl.Form;
|
||||||
import me.mrletsplay.nojs.component.impl.Group;
|
import me.mrletsplay.nojs.component.impl.Group;
|
||||||
|
import me.mrletsplay.nojs.component.impl.IFrame;
|
||||||
import me.mrletsplay.nojs.component.impl.Link;
|
import me.mrletsplay.nojs.component.impl.Link;
|
||||||
import me.mrletsplay.nojs.component.impl.Message;
|
import me.mrletsplay.nojs.component.impl.Message;
|
||||||
import me.mrletsplay.nojs.component.impl.Select;
|
import me.mrletsplay.nojs.component.impl.Select;
|
||||||
@ -19,11 +22,12 @@ import me.mrletsplay.nojs.component.impl.TextInput;
|
|||||||
import me.mrletsplay.nojs.page.Page;
|
import me.mrletsplay.nojs.page.Page;
|
||||||
import me.mrletsplay.nojs.page.layout.GridLayout;
|
import me.mrletsplay.nojs.page.layout.GridLayout;
|
||||||
import me.mrletsplay.nojs.page.layout.HClampLayout;
|
import me.mrletsplay.nojs.page.layout.HClampLayout;
|
||||||
|
import me.mrletsplay.simplehttpserver.http.request.HttpRequestContext;
|
||||||
|
import me.mrletsplay.simplehttpserver.http.request.urlencoded.UrlEncoded;
|
||||||
|
|
||||||
public class LinksPage implements Page {
|
public class LinksPage implements Page {
|
||||||
|
|
||||||
private Map<String, String> links = new LinkedHashMap<>();
|
private Map<String, String> links = new LinkedHashMap<>();
|
||||||
private String error;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getContent() {
|
public Component getContent() {
|
||||||
@ -54,11 +58,11 @@ public class LinksPage implements Page {
|
|||||||
linksGroup.add(new Text().text("No links added yet"));
|
linksGroup.add(new Text().text("No links added yet"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(error != null) {
|
UrlEncoded query = HttpRequestContext.getCurrentContext().getRequestedPath().getQuery();
|
||||||
|
if(query.has("error")) {
|
||||||
linksGroup.add(new Message()
|
linksGroup.add(new Message()
|
||||||
.text(error)
|
.text((String) query.getFirst("error"))
|
||||||
.type(Message.Type.ERROR));
|
.type(Message.Type.ERROR));
|
||||||
error = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Group()
|
return new Group()
|
||||||
@ -79,19 +83,27 @@ public class LinksPage implements Page {
|
|||||||
.layout(GridLayout.ofColumns(1).gap("4px"))
|
.layout(GridLayout.ofColumns(1).gap("4px"))
|
||||||
.action(new Action("addLink"))
|
.action(new Action("addLink"))
|
||||||
)
|
)
|
||||||
|
.add(new IFrame(new DynPage()).data(new UrlEncoded(Map.of("error", List.of("Sussy baka iframe")))))
|
||||||
.layout(GridLayout.ofColumns(1).gap("10px"))
|
.layout(GridLayout.ofColumns(1).gap("10px"))
|
||||||
)
|
)
|
||||||
.layout(new HClampLayout("200px", "100%", "800px")
|
.layout(new HClampLayout("200px", "100%", "800px")
|
||||||
.hAlignment(HClampLayout.HAlignment.CENTER));
|
.hAlignment(HClampLayout.HAlignment.CENTER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath() {
|
||||||
|
return "/links";
|
||||||
|
}
|
||||||
|
|
||||||
@ActionHandler("addLink")
|
@ActionHandler("addLink")
|
||||||
public void addLink(ActionEvent event) {
|
public void addLink(ActionEvent event) {
|
||||||
String linkName = event.getData("linkName");
|
String linkName = event.getData("linkName");
|
||||||
String link = event.getData("link");
|
String link = event.getData("link");
|
||||||
if(link == null || link.isBlank() || (!link.startsWith("http://") && !link.startsWith("https://"))
|
if(link == null || link.isBlank() || (!link.startsWith("http://") && !link.startsWith("https://"))
|
||||||
|| linkName == null || linkName.isBlank()) {
|
|| linkName == null || linkName.isBlank()) {
|
||||||
error = "Invalid link";
|
UrlEncoded data = new UrlEncoded();
|
||||||
|
data.set("error", "Invalid link");
|
||||||
|
event.setResult(ActionResult.refresh(data));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,11 @@ import me.mrletsplay.simplehttpserver.http.request.urlencoded.UrlEncoded;
|
|||||||
public class ActionEvent {
|
public class ActionEvent {
|
||||||
|
|
||||||
private UrlEncoded data;
|
private UrlEncoded data;
|
||||||
|
private ActionResult result;
|
||||||
|
|
||||||
public ActionEvent(UrlEncoded data) {
|
public ActionEvent(UrlEncoded data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.result = ActionResult.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAction() {
|
public String getAction() {
|
||||||
@ -18,4 +20,12 @@ public class ActionEvent {
|
|||||||
return data.getFirst(name);
|
return data.getFirst(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setResult(ActionResult result) {
|
||||||
|
this.result = result != null ? result : ActionResult.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
63
src/main/java/me/mrletsplay/nojs/action/ActionResult.java
Normal file
63
src/main/java/me/mrletsplay/nojs/action/ActionResult.java
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package me.mrletsplay.nojs.action;
|
||||||
|
|
||||||
|
import me.mrletsplay.nojs.page.Page;
|
||||||
|
import me.mrletsplay.simplehttpserver.http.request.urlencoded.UrlEncoded;
|
||||||
|
|
||||||
|
public class ActionResult {
|
||||||
|
|
||||||
|
private static final ActionResult REFRESH = new ActionResult(Type.REFRESH, null, null);
|
||||||
|
|
||||||
|
private Type type;
|
||||||
|
private String url;
|
||||||
|
private UrlEncoded data;
|
||||||
|
|
||||||
|
private ActionResult(Type type, String url, UrlEncoded data) {
|
||||||
|
this.type = type;
|
||||||
|
this.url = url;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UrlEncoded getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionResult refresh(UrlEncoded data) {
|
||||||
|
return new ActionResult(Type.REFRESH, null, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionResult refresh() {
|
||||||
|
return REFRESH;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionResult redirectTo(String url, UrlEncoded data) {
|
||||||
|
return new ActionResult(Type.REDIRECT, url, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionResult redirectTo(String url) {
|
||||||
|
return redirectTo(url, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionResult redirectTo(Page page, UrlEncoded data) {
|
||||||
|
return redirectTo(page.getPath(), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionResult redirectTo(Page page) {
|
||||||
|
return redirectTo(page, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum Type {
|
||||||
|
|
||||||
|
REFRESH,
|
||||||
|
REDIRECT,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
41
src/main/java/me/mrletsplay/nojs/component/impl/IFrame.java
Normal file
41
src/main/java/me/mrletsplay/nojs/component/impl/IFrame.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package me.mrletsplay.nojs.component.impl;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import me.mrletsplay.nojs.component.Component;
|
||||||
|
import me.mrletsplay.nojs.page.Page;
|
||||||
|
import me.mrletsplay.simplehttpserver.dom.html.HtmlElement;
|
||||||
|
import me.mrletsplay.simplehttpserver.http.request.urlencoded.UrlEncoded;
|
||||||
|
|
||||||
|
public class IFrame implements Component {
|
||||||
|
|
||||||
|
private Page page;
|
||||||
|
private UrlEncoded data;
|
||||||
|
// private Duration autoRefresh; TODO: auto refresh
|
||||||
|
|
||||||
|
public IFrame(Page page) {
|
||||||
|
Objects.requireNonNull(page, "page");
|
||||||
|
|
||||||
|
this.page = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IFrame data(UrlEncoded data) {
|
||||||
|
this.data = data;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HtmlElement toHtml() {
|
||||||
|
HtmlElement iframe = HtmlElement.of("iframe");
|
||||||
|
iframe.addClass("iframe");
|
||||||
|
|
||||||
|
String path = page.getPath();
|
||||||
|
if(data != null) {
|
||||||
|
path += "?" + data.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe.setAttribute("src", path);
|
||||||
|
return iframe;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,7 +11,7 @@ public class Link implements Component {
|
|||||||
|
|
||||||
public Link() {
|
public Link() {
|
||||||
this.text = "Link";
|
this.text = "Link";
|
||||||
this.href = "#";
|
this.href = "";
|
||||||
this.target = Target.SELF;
|
this.target = Target.SELF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ public class Link implements Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Link href(String href) {
|
public Link href(String href) {
|
||||||
this.href = href != null ? href : "#";
|
this.href = href != null ? href : "";
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ public interface Page extends HttpDocument, ActionHandlers {
|
|||||||
|
|
||||||
public Component getContent();
|
public Component getContent();
|
||||||
|
|
||||||
|
public String getPath();
|
||||||
|
|
||||||
public default HtmlDocument toHtml() {
|
public default HtmlDocument toHtml() {
|
||||||
HtmlDocument doc = new HtmlDocument();
|
HtmlDocument doc = new HtmlDocument();
|
||||||
doc.addStyleSheet("/base.css");
|
doc.addStyleSheet("/base.css");
|
||||||
@ -49,16 +51,32 @@ public interface Page extends HttpDocument, ActionHandlers {
|
|||||||
ActionEvent e = new ActionEvent(data);
|
ActionEvent e = new ActionEvent(data);
|
||||||
onAction(e);
|
onAction(e);
|
||||||
|
|
||||||
ctx.redirect(HttpStatusCodes.SEE_OTHER_303, ctx.getClientHeader().getPath().toString());
|
String path = ctx.getClientHeader().getPath().getDocumentPath();
|
||||||
|
if(e.getResult().getUrl() != null) {
|
||||||
|
path = e.getResult().getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.getResult().getData() != null) {
|
||||||
|
path += "?" + e.getResult().getData().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.redirect(HttpStatusCodes.SEE_OTHER_303, path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.respond(HttpStatusCodes.OK_200, new HtmlResponse(toHtml()));
|
ctx.respond(HttpStatusCodes.OK_200, new HtmlResponse(toHtml()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public default void register(DocumentProvider provider, String path) {
|
public default void register(DocumentProvider provider) {
|
||||||
|
String path = getPath();
|
||||||
provider.register(HttpRequestMethod.GET, path, this);
|
provider.register(HttpRequestMethod.GET, path, this);
|
||||||
provider.register(HttpRequestMethod.POST, path, this);
|
provider.register(HttpRequestMethod.POST, path, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void register(DocumentProvider provider, Page... pages) {
|
||||||
|
for(Page page : pages) {
|
||||||
|
page.register(provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,21 +26,21 @@ public class GridLayout implements Layout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GridLayout columns(Collection<String> columns) {
|
public GridLayout columns(Collection<String> columns) {
|
||||||
this.columns = new ArrayList<>(columns == null ? Collections.emptyList() : columns);
|
this.columns = new ArrayList<>(columns != null ? columns : Collections.emptyList());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridLayout rows(Collection<String> rows) {
|
public GridLayout rows(Collection<String> rows) {
|
||||||
this.rows = new ArrayList<>(rows == null ? Collections.emptyList() : rows);
|
this.rows = new ArrayList<>(rows != null ? rows : Collections.emptyList());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridLayout columns(String... columns) {
|
public GridLayout columns(String... columns) {
|
||||||
return columns(columns == null ? null : Arrays.asList(columns));
|
return columns(columns != null ? Arrays.asList(columns) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridLayout rows(String... rows) {
|
public GridLayout rows(String... rows) {
|
||||||
return rows(rows == null ? null : Arrays.asList(rows));
|
return rows(rows != null ? Arrays.asList(rows) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridLayout gap(String gap) {
|
public GridLayout gap(String gap) {
|
||||||
@ -49,7 +49,7 @@ public class GridLayout implements Layout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GridLayout flow(Flow flow) {
|
public GridLayout flow(Flow flow) {
|
||||||
this.flow = flow;
|
this.flow = flow != null ? flow : Flow.ROW;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,3 +131,7 @@ body {
|
|||||||
.message:has(:checked) {
|
.message:has(:checked) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iframe {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user