diff --git a/build.xml b/build.xml index c39fff14..554e8af8 100644 --- a/build.xml +++ b/build.xml @@ -1,7 +1,7 @@ - + diff --git a/examples/bobsmith/.classpath b/examples/bobsmith/.classpath index 13d3191e..775714fa 100644 --- a/examples/bobsmith/.classpath +++ b/examples/bobsmith/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/charts/.classpath b/examples/charts/.classpath index 52fc886e..ed0d0349 100644 --- a/examples/charts/.classpath +++ b/examples/charts/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/composer/.classpath b/examples/composer/.classpath index 13d3191e..775714fa 100644 --- a/examples/composer/.classpath +++ b/examples/composer/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/dialog/.classpath b/examples/dialog/.classpath index 13d3191e..775714fa 100644 --- a/examples/dialog/.classpath +++ b/examples/dialog/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/dragdrop/.classpath b/examples/dragdrop/.classpath index 13d3191e..775714fa 100644 --- a/examples/dragdrop/.classpath +++ b/examples/dragdrop/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/feature/auth1/.classpath b/examples/feature/auth1/.classpath index c11f1439..518ba452 100644 --- a/examples/feature/auth1/.classpath +++ b/examples/feature/auth1/.classpath @@ -27,8 +27,8 @@ - - + + diff --git a/examples/feature/itemmodel/.classpath b/examples/feature/itemmodel/.classpath index 13d3191e..775714fa 100644 --- a/examples/feature/itemmodel/.classpath +++ b/examples/feature/itemmodel/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/feature/mediaplayer/.classpath b/examples/feature/mediaplayer/.classpath index 13d3191e..775714fa 100644 --- a/examples/feature/mediaplayer/.classpath +++ b/examples/feature/mediaplayer/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/feature/serverpush/.classpath b/examples/feature/serverpush/.classpath index 13d3191e..775714fa 100644 --- a/examples/feature/serverpush/.classpath +++ b/examples/feature/serverpush/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/filetreetable/.classpath b/examples/filetreetable/.classpath index 13d3191e..775714fa 100644 --- a/examples/filetreetable/.classpath +++ b/examples/filetreetable/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/form/.classpath b/examples/form/.classpath index 13d3191e..775714fa 100644 --- a/examples/form/.classpath +++ b/examples/form/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/googlemap/.classpath b/examples/googlemap/.classpath index 13d3191e..775714fa 100644 --- a/examples/googlemap/.classpath +++ b/examples/googlemap/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/hello-mvn/pom.xml b/examples/hello-mvn/pom.xml index 108aedb7..8f360ba1 100644 --- a/examples/hello-mvn/pom.xml +++ b/examples/hello-mvn/pom.xml @@ -29,7 +29,7 @@ eu.webtoolkit jwt - 4.11.1 + 4.11.2 diff --git a/examples/hello/.classpath b/examples/hello/.classpath index 13d3191e..775714fa 100644 --- a/examples/hello/.classpath +++ b/examples/hello/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/hellowidgetset/.classpath b/examples/hellowidgetset/.classpath index 13d3191e..775714fa 100644 --- a/examples/hellowidgetset/.classpath +++ b/examples/hellowidgetset/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/javascript/.classpath b/examples/javascript/.classpath index 13d3191e..775714fa 100644 --- a/examples/javascript/.classpath +++ b/examples/javascript/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/mandelbrot/.classpath b/examples/mandelbrot/.classpath index 13d3191e..775714fa 100644 --- a/examples/mandelbrot/.classpath +++ b/examples/mandelbrot/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/mission/.classpath b/examples/mission/.classpath index 13d3191e..775714fa 100644 --- a/examples/mission/.classpath +++ b/examples/mission/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/painting/.classpath b/examples/painting/.classpath index 832a3bba..5efb0302 100644 --- a/examples/painting/.classpath +++ b/examples/painting/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/planner/.classpath b/examples/planner/.classpath index bc979c29..fd5460f7 100644 --- a/examples/planner/.classpath +++ b/examples/planner/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/simplechat/.classpath b/examples/simplechat/.classpath index 13d3191e..775714fa 100644 --- a/examples/simplechat/.classpath +++ b/examples/simplechat/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/style/.classpath b/examples/style/.classpath index 13d3191e..775714fa 100644 --- a/examples/style/.classpath +++ b/examples/style/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/textedit/.classpath b/examples/textedit/.classpath index 13d3191e..775714fa 100644 --- a/examples/textedit/.classpath +++ b/examples/textedit/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/treeview/.classpath b/examples/treeview/.classpath index 13d3191e..775714fa 100644 --- a/examples/treeview/.classpath +++ b/examples/treeview/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/treeviewdragdrop/.classpath b/examples/treeviewdragdrop/.classpath index 48d47e17..1414da74 100644 --- a/examples/treeviewdragdrop/.classpath +++ b/examples/treeviewdragdrop/.classpath @@ -4,7 +4,7 @@ - + diff --git a/examples/widgetgallery/.classpath b/examples/widgetgallery/.classpath index 95a37304..5a166f83 100644 --- a/examples/widgetgallery/.classpath +++ b/examples/widgetgallery/.classpath @@ -3,7 +3,7 @@ - + diff --git a/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/TreesTables.java b/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/TreesTables.java index 6cd3bb47..f7e83c05 100644 --- a/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/TreesTables.java +++ b/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/TreesTables.java @@ -187,11 +187,14 @@ WWidget StyledTable() { } WWidget Tree() { + WContainerWidget container = new WContainerWidget(); WTree tree = new WTree(); + container.addWidget(tree); tree.setSelectionMode(SelectionMode.Extended); WIconPair folderIcon = new WIconPair("icons/yellow-folder-closed.png", "icons/yellow-folder-open.png", false); WTreeNode node = new WTreeNode("Furniture", folderIcon); + final WTreeNode furnitureNode = node; tree.setTreeRoot(node); tree.getTreeRoot().getLabel().setTextFormat(TextFormat.Plain); tree.getTreeRoot().setLoadPolicy(ContentLoading.NextLevel); @@ -208,7 +211,29 @@ WWidget Tree() { subtree_.addChildNode(new WTreeNode("Dopey")); subtree_.addChildNode(new WTreeNode("Bashful")); subtree_.addChildNode(new WTreeNode("Sleepy")); - return tree; + WPushButton imageButton = new WPushButton("Use Image Icons"); + container.addWidget(imageButton); + imageButton + .clicked() + .addListener( + this, + () -> { + WIconPair icon = + new WIconPair( + "icons/yellow-folder-closed.png", "icons/yellow-folder-open.png", false); + furnitureNode.setLabelIcon(icon); + }); + WPushButton FAButton = new WPushButton("Use Font-Awesome Icons"); + container.addWidget(FAButton); + FAButton.clicked() + .addListener( + this, + () -> { + WIconPair icon = new WIconPair("folder", "folder-open", false); + icon.setIconsType(WIconPair.IconType.IconName); + furnitureNode.setLabelIcon(icon); + }); + return container; } static WTreeTableNode addNode( diff --git a/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/WidgetGalleryServlet.java b/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/WidgetGalleryServlet.java index 0a16bfea..ac868d86 100644 --- a/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/WidgetGalleryServlet.java +++ b/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/WidgetGalleryServlet.java @@ -1,5 +1,6 @@ package eu.webtoolkit.jwt.examples.widgetgallery; +import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -24,6 +25,38 @@ public WidgetGalleryServlet() { setTinyMCEVersion(4); getProperties().put("leafletJSURL", "https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"); getProperties().put("leafletCSSURL", "https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"); + setBotList(new ArrayList( + List.of(".*Slurp.*", + ".*crawl.*", + ".*Crawl.*", + ".*bot.*", + ".*Bot.*", + ".*spider.*", + ".*Spider.*", + ".*ia_archiver.*", + ".*Twiceler.*", + ".*Yandex.*", + ".*Nutch.*", + ".*Ezooms.*", + ".*Scrapy.*", + ".*Buck.*", + ".*Barkrowler.*", + ".*Censys.*", + ".*Blogtrottr.*", + ".*InternetMeasurement.*", + ".*Owler.*", + ".*centuryb.o.t9.*", + ".*Turnitin.*", + ".*MatchorySearch.*", + ".*newspaper.*", + ".*Go-http-client.*", + ".*Mojolicious.*", + ".*python-requests.*", + ".*Python.*", + ".*python-urllib.*", + ".*Apache-HttpClient.*", + ".*com.apple.WebKit.Networking.*", + ".*NetworkingExtension.*"))); } @Override diff --git a/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/src.xml b/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/src.xml index 04b25dc8..7d82efe0 100644 --- a/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/src.xml +++ b/examples/widgetgallery/src/eu/webtoolkit/jwt/examples/widgetgallery/src.xml @@ -5080,11 +5080,14 @@ ]]>
  void Tree() {
+    WContainerWidget container = new WContainerWidget();
     WTree tree = new WTree();
+    container.addWidget(tree);
     tree.setSelectionMode(SelectionMode.Extended);
     WIconPair folderIcon =
         new WIconPair("icons/yellow-folder-closed.png", "icons/yellow-folder-open.png", false);
     WTreeNode node = new WTreeNode("Furniture", folderIcon);
+    final WTreeNode furnitureNode = node;
     tree.setTreeRoot(node);
     tree.getTreeRoot().getLabel().setTextFormat(TextFormat.Plain);
     tree.getTreeRoot().setLoadPolicy(ContentLoading.NextLevel);
@@ -5101,6 +5104,28 @@
     subtree_.addChildNode(new WTreeNode("Dopey"));
     subtree_.addChildNode(new WTreeNode("Bashful"));
     subtree_.addChildNode(new WTreeNode("Sleepy"));
+    WPushButton imageButton = new WPushButton("Use Image Icons");
+    container.addWidget(imageButton);
+    imageButton
+        .clicked()
+        .addListener(
+            this,
+            () -> {
+              WIconPair icon =
+                  new WIconPair(
+                      "icons/yellow-folder-closed.png", "icons/yellow-folder-open.png", false);
+              furnitureNode.setLabelIcon(icon);
+            });
+    WPushButton FAButton = new WPushButton("Use Font-Awesome Icons");
+    container.addWidget(FAButton);
+    FAButton.clicked()
+        .addListener(
+            this,
+            () -> {
+              WIconPair icon = new WIconPair("folder", "folder-open", false);
+              icon.setIconsType(WIconPair.IconType.IconName);
+              furnitureNode.setLabelIcon(icon);
+            });
   }
 
]]>
diff --git a/jwt-4.11.1.pom b/jwt-4.11.2.pom similarity index 98% rename from jwt-4.11.1.pom rename to jwt-4.11.2.pom index 5f76e1b5..868c8cbe 100644 --- a/jwt-4.11.1.pom +++ b/jwt-4.11.2.pom @@ -10,7 +10,7 @@ jwt jar Java Web Toolkit - 4.11.1 + 4.11.2 Java library for developing web applications https://webtoolkit.eu/jwt/ diff --git a/jwt-auth-4.11.1.pom b/jwt-auth-4.11.2.pom similarity index 95% rename from jwt-auth-4.11.1.pom rename to jwt-auth-4.11.2.pom index 3107abd2..0d15b37f 100644 --- a/jwt-auth-4.11.1.pom +++ b/jwt-auth-4.11.2.pom @@ -10,7 +10,7 @@ jwt-auth jar Java Web Toolkit Authentication Library - 4.11.1 + 4.11.2 Authentication library for the Java Web Toolkit https://webtoolkit.eu/jwt/ @@ -31,7 +31,7 @@ eu.webtoolkit jwt - 4.11.1 + 4.11.2 diff --git a/overview.html b/overview.html index ba4df823..5ae30ad0 100755 --- a/overview.html +++ b/overview.html @@ -25,6 +25,110 @@

Release notes

the way you build JWt, the way you configure JWt or the JWt API and behaviour. It also indicates the main changes from version to verison. +

Release 4.11.2 (January 16, 2025)

+ +

+ JWt 4.11.2 is a patch release that addresses the following issues: +

+ +
    +
  • + Issue #12935: + resize handles in layouts now have a fixed height or width instead of them scaling with the spacing of the layout. +
  • +
  • + Issue #12866: + added the setDelayAtBoot() option which can be changed in the Configuration. This option + allows developers to choose whether the loading of the application at boot should be delayed or not. Instead of + immediately calling the loading method, a small delay is introduced to allow additional JavaScript to be executed before + loading. By default this option is set to true, which keeps the delay. This delay can cause the loading of the + application to take a long time in some very specific case. Setting this option to false could however impact any + JavaScript code added at boot time. +
  • +
  • + Issue #13063: + fixed a bug where setting the HTML tag name of a + WWebWidget could lead to a segmentation fault for some tag names. +
  • +
  • + Issue #13366: + ensure that when the application's working directory and the docroot are not the same directory, the image rendering fallback + will attempt to resolve the image relative to both locations. + This is so that clients that do not have JavaScript enabled, are still able to see the same images as JavaScript-enabled clients. +
  • +
  • + Issue #12860: + fixed a bug where a + WDialog would not be centered if + WDialog#exec() was called after the WDialog was loaded. +
  • +
  • + Issue #13082: + fixed styling of elements in layout not being updated in some cases if the change happened while the layout was hidden. +
  • +
  • + Issue #12951: + fixed a bug where a layout in a + WPanel may not work properly during and after some animations. +
  • +
  • + Issue #12934: + fixed a bug in layouts using JavaScript implementation where a widget size could be set higher than it's maximum size, leading to additional space after that widget. +
  • +
  • + Issue #13300: + fixed a missing fallback in JWt's main JavaScript, when handling browser history navigation (using the back and forward buttons). + In case of rewritten browser history, the retrieval would fail, and encounter an undefined state. Throwing a JavaScript error. This error should be guarded against, + and the fallback should always kick in. +
  • +
+ +

+ JWt 4.11.2 also comes with the following improvements: +

+ + +

Release 4.11.1 (November 5, 2024)

JWt 4.11.1 is a patch release that addresses the following issues:

diff --git a/src/eu/webtoolkit/jwt/Configuration.java b/src/eu/webtoolkit/jwt/Configuration.java index fd5a43b3..f7b511b6 100644 --- a/src/eu/webtoolkit/jwt/Configuration.java +++ b/src/eu/webtoolkit/jwt/Configuration.java @@ -27,6 +27,8 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import eu.webtoolkit.jwt.servlet.WebResponse; + /** * JWt application configuration class. *

@@ -169,6 +171,7 @@ private boolean prefixMatches(byte[] network, byte[] address, int prefixLength) private String favicon = "/favicon.ico"; private boolean progressiveBootstrap = false; + private boolean delayLoadAtBoot = true; private int sessionTimeout = 600; private int idleTimeout = -1; @@ -179,6 +182,9 @@ private boolean prefixMatches(byte[] network, byte[] address, int prefixLength) private String uaCompatible = ""; private List metaHeaders = new ArrayList(); private List headMatter = new ArrayList(); + private boolean useXFrameSameOrigin = true; + private List httpHeaders = new ArrayList(); + private boolean useScriptNonce = false; private int internalDeploymentSize = 0; private long maxRequestSize = 1024*1024; // 1 Megabyte private long maxFormDataSize = 1024*1024; // 1 Megabyte @@ -205,6 +211,10 @@ public Configuration() { botList.add(".ia_archiver.*"); botList.add(".*Googlebot.*"); botList.add(".*Twiceler.*"); + + httpHeaders.add(new HttpHeader("X-Content-Type-Options", "nosniff")); + httpHeaders.add(new HttpHeader("Strict-Transport-Security", "max-age=15724800; includeSubDomains")); + httpHeaders.add(new HttpHeader("Referrer-Policy", "strict-origin-when-cross-origin")); } /** @@ -258,6 +268,8 @@ public Configuration(File configurationFile) { } } else if (node.getNodeName().equalsIgnoreCase("progressive-bootstrap")) { setProgressiveBootstrap(parseBoolean(errorMessage, node)); + } else if (node.getNodeName().equalsIgnoreCase("delay-load-at-boot")) { + setDelayLoadAtBoot(parseBoolean(errorMessage, node)); } else if (node.getNodeName().equalsIgnoreCase("ua-compatible")) { setUaCompatible(node.getTextContent().trim()); } else if (node.getNodeName().equalsIgnoreCase("send-xhtml-mime-type")) { @@ -295,6 +307,12 @@ else if (mode.equals("white-list")) this.allowedOrigins_ = new HashSet(); this.allowedOrigins_.add(origin); } + } else if (node.getNodeName().equalsIgnoreCase("x-frame-same-origin")) { + setUseXFrameSameOrigin(parseBoolean(errorMessage, node)); + } else if (node.getNodeName().equalsIgnoreCase("http-headers")) { + parseHttpHeaders(errorMessage, node); + } else if (node.getNodeName().equalsIgnoreCase("use-script-nonce")) { + setUseScriptNonce(parseBoolean(errorMessage, node)); } } } @@ -312,6 +330,30 @@ private void parseUserAgents(String errorMessage, Node node, List list) } } + private void parseHttpHeaders(String errorMessage, Node node) { + NodeList httpHeaders = node.getChildNodes(); + Node n; + for (int i = 0; i < httpHeaders.getLength(); i++) { + n = httpHeaders.item(i); + if (n.getNodeName().equalsIgnoreCase("header")) { + Node headerName = n.getAttributes().getNamedItem("name"); + if (headerName == null) { + throw new RuntimeException(errorMessage + "header element must contain a name"); + } + String name = headerName.getTextContent().trim(); + String content = new String(); + + Node headerContent = n.getAttributes().getNamedItem("content"); + if (headerContent != null) { + content = headerContent.getTextContent().trim(); + } + + HttpHeader header = new HttpHeader(name, content); + this.httpHeaders.add(header); + } + } + } + private boolean parseBoolean(String errorMessage, Node n) { try { return Boolean.parseBoolean(n.getTextContent().trim()); @@ -721,6 +763,29 @@ public boolean progressiveBootstrap(String internalPath) { return this.progressiveBootstrap ; } + /** + * Configures whether loading the application is delayed at boot. + * + * By default, the loading of the application is delayed. This can in + * some very specific circumstances lead to the browser waiting several + * seconds before loading the application. + * + * If this is a bug that you are facing, consider setting this to false. + * This could however impact your code if you inject JS during boot. + */ + public void setDelayLoadAtBoot(boolean enable) { + this.delayLoadAtBoot = enable; + } + + /** + * Returns whether loading of the application is delayed at boot + * + * @see #setDelayLoadAtBoot(boolean). + */ + public boolean isDelayLoadAtBoot() { + return this.delayLoadAtBoot; + } + public int getKeepAlive() { return getSessionTimeout() / 2; } @@ -1056,6 +1121,14 @@ public List getHeadMatter() { return headMatter; } + /** + * Returns the headers configured to be sent with every HTTP + * response. + */ + public List getHttpHeaders() { + return this.httpHeaders; + } + /** * Sets (static) meta headers. This is an alternative to using * {@link WApplication#addMetaHeader(String, CharSequence)}, but having the @@ -1073,6 +1146,52 @@ public void setHeadMatter(List headMatter) { this.headMatter = headMatter; } + /** + * Sets the headers to send with every HTTP response. + */ + public void setHttpHeaders(List httpHeaders) { + this.httpHeaders = httpHeaders; + } + + /** + * Configures whether nonces are used. + * + * Setting this to true forces every script HTML tag to have the + * same nonce as the one given in the header of the reply in order + * to be executed. This nonce is randomly generated for each reply, + * helping to protect against XSS attacks. + * + * @see servlet.WebResponse#getNonce() + */ + public void setUseScriptNonce(boolean enable) { + this.useScriptNonce = enable; + } + + /** + * Returns whether nonces are used. + */ + public boolean isUseScriptNonce() { + return this.useScriptNonce; + } + + /** + * Configures whether the header X-Frame-Option "SAMEORIGIN" is + * sent when serving the main page or the bootstrap. + */ + public void setUseXFrameSameOrigin(boolean enable) { + this.useXFrameSameOrigin = enable; + } + + /** + * Returns whether the header X-Frame-Option "SAMEORIGIN" is sent + * when serving the main page or the bootstrap. + * + * @see #setUseXFrameSameOrigin(boolean) + */ + public boolean isUseXFrameSameOrigin() { + return this.useXFrameSameOrigin; + } + public boolean isAllowedOrigin(String origin) { if (this.allowedOrigins_.size() == 1 && "*".equals(this.allowedOrigins_.iterator().next())) diff --git a/src/eu/webtoolkit/jwt/DomElement.java b/src/eu/webtoolkit/jwt/DomElement.java index 0fc7ea75..d97400a8 100644 --- a/src/eu/webtoolkit/jwt/DomElement.java +++ b/src/eu/webtoolkit/jwt/DomElement.java @@ -331,7 +331,7 @@ public void setEvent( js.append("o=this;"); if (anchorClick) { js.append( - "if(e.ctrlKey||e.metaKey||e.shiftKey||(Wt4_11_1.button(e) > 1))return true;else{"); + "if(e.ctrlKey||e.metaKey||e.shiftKey||(Wt4.11.2.button(e) > 1))return true;else{"); } js.append(jsCode); if (isExposed) { @@ -438,7 +438,7 @@ public void setTimeout(int delay, int interval) { public void callMethod(final String method) { ++this.numManipulations_; if (this.var_.length() == 0) { - this.javaScript_.append("Wt4_11_1").append(".$('").append(this.id_).append("')."); + this.javaScript_.append("Wt4.11.2").append(".$('").append(this.id_).append("')."); } else { this.javaScript_.append(this.var_).append('.'); } @@ -493,7 +493,7 @@ public final void removeAllChildren() { } /** Removes the element. */ public void removeFromParent() { - this.callJavaScript("Wt4_11_1.remove('" + this.getId() + "');", true); + this.callJavaScript("Wt4.11.2.remove('" + this.getId() + "');", true); } /** Replaces the element by another element. */ public void replaceWith(DomElement newElement) { @@ -582,7 +582,7 @@ public String asJavaScript(final EscapeOStream out, DomElement.Priority priority if (this.removeAllChildren_ >= 0) { this.declare(out); if (this.removeAllChildren_ == 0) { - out.append("Wt4_11_1").append(".setHtml(").append(this.var_).append(", '');\n"); + out.append("Wt4.11.2").append(".setHtml(").append(this.var_).append(", '');\n"); } else { out.append("(Array.from(") .append(this.var_) @@ -615,18 +615,18 @@ public String asJavaScript(final EscapeOStream out, DomElement.Priority priority if (this.properties_.get(Property.StyleDisplay) != null) { String style = this.properties_.get(Property.StyleDisplay); if (style.equals("none")) { - out.append("Wt4_11_1.hide('").append(this.id_).append("');\n"); + out.append("Wt4.11.2.hide('").append(this.id_).append("');\n"); return this.var_; } else { if (style.equals("inline")) { - out.append("Wt4_11_1.inline('" + this.id_ + "');\n"); + out.append("Wt4.11.2.inline('" + this.id_ + "');\n"); return this.var_; } else { if (style.equals("block")) { - out.append("Wt4_11_1.block('" + this.id_ + "');\n"); + out.append("Wt4.11.2.block('" + this.id_ + "');\n"); return this.var_; } else { - out.append("Wt4_11_1.show('") + out.append("Wt4.11.2.show('") .append(this.id_) .append("', '") .append(style) @@ -643,7 +643,7 @@ public String asJavaScript(final EscapeOStream out, DomElement.Priority priority } } if (this.unwrapped_) { - out.append("Wt4_11_1.unwrap('").append(this.id_).append("');\n"); + out.append("Wt4.11.2.unwrap('").append(this.id_).append("');\n"); } this.processEvents(app); this.processProperties(app); @@ -660,7 +660,7 @@ public String asJavaScript(final EscapeOStream out, DomElement.Priority priority .append(");\n"); this.replaced_.createElement(out, app, insertJs.toString()); if (this.unstubbed_) { - out.append("Wt4_11_1.unstub(") + out.append("Wt4.11.2.unstub(") .append(this.var_) .append(',') .append(varr) @@ -686,14 +686,14 @@ public String asJavaScript(final EscapeOStream out, DomElement.Priority priority } if (!this.childrenToSave_.isEmpty()) { this.declare(out); - out.append("Wt4_11_1").append(".saveReparented(").append(this.var_).append(");"); + out.append("Wt4.11.2").append(".saveReparented(").append(this.var_).append(");"); } for (int i = 0; i < this.childrenToSave_.size(); ++i) { out.append("var c") .append(this.var_) .append((int) i) .append('=') - .append("Wt4_11_1.$('") + .append("Wt4.11.2.$('") .append(this.childrenToSave_.get(i)) .append("')"); if (app.getEnvironment().agentIsIE()) { @@ -715,7 +715,7 @@ public String asJavaScript(final EscapeOStream out, DomElement.Priority priority } this.renderInnerHtmlJS(out, app); for (int i = 0; i < this.childrenToSave_.size(); ++i) { - out.append("Wt4_11_1.replaceWith('") + out.append("Wt4.11.2.replaceWith('") .append(this.childrenToSave_.get(i)) .append("',c") .append(this.var_) @@ -902,6 +902,7 @@ public void asHTML( Map.Entry i = i_it.next(); if (i.getValue().jsCode.length() != 0) { if (this.globalUnfocused_ + || app.getEnvironment().getServer().getConfiguration().isUseScriptNonce() || i.getKey() == WInteractWidget.WHEEL_SIGNAL && app.getEnvironment().agentIsIE() && (int) app.getEnvironment().getAgent().getValue() @@ -1106,7 +1107,7 @@ public void declare(final EscapeOStream out) { if (this.var_.length() == 0) { out.append("var ") .append(this.getCreateVar()) - .append("=Wt4_11_1.$('") + .append("=Wt4.11.2.$('") .append(this.id_) .append("');\n"); } @@ -1351,7 +1352,7 @@ private void processEvents(WApplication app) { DomElement.EventHandler keypress = this.eventHandlers_.get(S_keypress); if (keypress != null && keypress.jsCode.length() != 0) { MapUtils.access(self.eventHandlers_, S_keypress, DomElement.EventHandler.class).jsCode = - "if (Wt4_11_1.isKeyPress(event)){" + "if (Wt4.11.2.isKeyPress(event)){" + MapUtils.access(self.eventHandlers_, S_keypress, DomElement.EventHandler.class) .jsCode + '}'; @@ -1367,7 +1368,7 @@ private void processProperties(WApplication app) { if (minw != null || maxw != null) { if (w == null) { StringBuilder expr = new StringBuilder(); - expr.append("Wt4_11_1.IEwidth(this,"); + expr.append("Wt4.11.2.IEwidth(this,"); if (minw != null) { expr.append('\'').append(minw).append('\''); self.properties_.remove(Property.StyleMinWidth); @@ -1406,7 +1407,7 @@ private void setJavaScriptProperties(final EscapeOStream out, WApplication app) if (this.willRenderInnerHtmlJS(app)) { break; } - out.append("Wt4_11_1.setHtml(").append(this.var_).append(','); + out.append("Wt4.11.2.setHtml(").append(this.var_).append(','); if (!pushed) { escaped.pushEscape(EscapeOStream.RuleSet.JsStringLiteralSQuote); pushed = true; @@ -1620,9 +1621,30 @@ private void createElement(final EscapeOStream out, WApplication app, final Stri this.renderInnerHtmlJS(out, app); this.renderDeferredJavaScript(out); } else { - out.append("document.createElement('") - .append(elementNames_[(int) this.type_.getValue()]) - .append("');"); + out.append("document.createElement('"); + if (this.type_ == DomElementType.OTHER) { + boolean foundTag = false; + for (int i = 0; safeElementNames_[i].length() != 0; ++i) { + if (safeElementNames_[i].equals(this.elementTagName_)) { + foundTag = true; + break; + } + } + if (foundTag) { + out.append(this.elementTagName_); + } else { + logger.warn( + new StringWriter() + .append( + "DomElement::createElement(): Cannot create custom ('OTHER') element with tag '" + + this.elementTagName_ + + "'") + .toString()); + } + } else { + out.append(elementNames_[(int) this.type_.getValue()]); + } + out.append("');"); out.append(domInsertJS); this.asJavaScript(out, DomElement.Priority.Create); this.asJavaScript(out, DomElement.Priority.Update); @@ -1645,7 +1667,7 @@ private String addToParent( StringBuilder insertJS = new StringBuilder(); if (pos != -1) { insertJS - .append("Wt4_11_1.insertAt(") + .append("Wt4.11.2.insertAt(") .append(parentVar) .append(",") .append(this.var_) @@ -1679,7 +1701,7 @@ private void renderInnerHtmlJS(final EscapeOStream out, WApplication app) { || !this.childrenHtml_.isEmpty() || innerHTML.length() != 0) { this.declare(out); - out.append("Wt4_11_1.setHtml(").append(this.var_).append(",'"); + out.append("Wt4.11.2.setHtml(").append(this.var_).append(",'"); out.pushEscape(EscapeOStream.RuleSet.JsStringLiteralSQuote); List timeouts = new ArrayList(); EscapeOStream js = new EscapeOStream(); @@ -1838,6 +1860,78 @@ public ChildInsertion(int p, DomElement c) { "hr", "datalist" }; + private static String[] safeElementNames_ = { + "address", + "article", + "aside", + "footer", + "header", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "hgroup", + "main", + "nav", + "section", + "search", + "blockquote", + "div", + "p", + "pre", + "hr", + "figcaption", + "figure", + "dd", + "dl", + "dt", + "li", + "ul", + "ol", + "menu", + "a", + "abbr", + "b", + "bdi", + "bdo", + "br", + "cite", + "code", + "data", + "dfn", + "em", + "i", + "kdb", + "mark", + "q", + "rp", + "rt", + "ruby", + "s", + "samp", + "small", + "span", + "strong", + "sub", + "sup", + "time", + "u", + "var", + "wbr", + "caption", + "col", + "colgroup", + "table", + "tbody", + "td", + "tfoot", + "th", + "thead", + "tr", + "" + }; private static boolean[] defaultInline_ = { true, false, true, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, false, false, true, false, false, true, true, false, false, false, diff --git a/src/eu/webtoolkit/jwt/FilePickerType.java b/src/eu/webtoolkit/jwt/FilePickerType.java index f3c1e4d4..0a071488 100644 --- a/src/eu/webtoolkit/jwt/FilePickerType.java +++ b/src/eu/webtoolkit/jwt/FilePickerType.java @@ -25,6 +25,8 @@ * another where only directories can be selected. */ public enum FilePickerType { + /** No file picker. */ + None, /** Only files can be selected. */ FileSelection, /** Only directories can be selected. */ diff --git a/src/eu/webtoolkit/jwt/FlexItemImpl.java b/src/eu/webtoolkit/jwt/FlexItemImpl.java index 840ce9db..8245656e 100644 --- a/src/eu/webtoolkit/jwt/FlexItemImpl.java +++ b/src/eu/webtoolkit/jwt/FlexItemImpl.java @@ -48,6 +48,22 @@ public int getMinimumWidth() { } } + public int getMaximumHeight() { + if (this.item_.getWidget().isHidden()) { + return 0; + } else { + return (int) this.item_.getWidget().getMaximumHeight().toPixels(); + } + } + + public int getMaximumWidth() { + if (this.item_.getWidget().isHidden()) { + return 0; + } else { + return (int) this.item_.getWidget().getMaximumWidth().toPixels(); + } + } + public DomElement createDomElement( DomElement parent, boolean fitWidth, boolean fitHeight, WApplication app) { WWidget w = this.item_.getWidget(); diff --git a/src/eu/webtoolkit/jwt/FlexLayoutImpl.java b/src/eu/webtoolkit/jwt/FlexLayoutImpl.java index 4cc97654..8ea9e562 100644 --- a/src/eu/webtoolkit/jwt/FlexLayoutImpl.java +++ b/src/eu/webtoolkit/jwt/FlexLayoutImpl.java @@ -58,6 +58,32 @@ public int getMinimumHeight() { return total + (rowCount - 1) * this.grid_.verticalSpacing_; } + public int getMaximumWidth() { + final int colCount = this.grid_.columns_.size(); + int total = 0; + for (int i = 0; i < colCount; ++i) { + int colMax = this.maximumWidthForColumn(i); + if (colMax == 0) { + return 0; + } + total += colMax; + } + return total + (colCount - 1) * this.grid_.horizontalSpacing_; + } + + public int getMaximumHeight() { + final int rowCount = this.grid_.rows_.size(); + int total = 0; + for (int i = 0; i < rowCount; ++i) { + int rowMax = this.maximumHeightForRow(i); + if (rowMax == 0) { + return 0; + } + total += rowMax; + } + return total + (rowCount - 1) * this.grid_.verticalSpacing_; + } + public void itemAdded(WLayoutItem item) { this.addedItems_.add(item); this.update(); @@ -86,7 +112,7 @@ public void updateDom(final DomElement parent) { } this.addedItems_.clear(); for (int i = 0; i < this.removedItems_.size(); ++i) { - div.callJavaScript("Wt4_11_1.remove('" + this.removedItems_.get(i) + "');", true); + div.callJavaScript("Wt4.11.2.remove('" + this.removedItems_.get(i) + "');", true); } this.removedItems_.clear(); div.callMethod("layout.adjust()"); @@ -155,7 +181,7 @@ public DomElement createDomElement( result.addChild(el); } StringBuilder js = new StringBuilder(); - js.append("layout=new Wt4_11_1.FlexLayout(") + js.append("layout=new Wt4.11.2.FlexLayout(") .append(app.getJavaScriptClass()) .append(",'") .append(this.elId_) @@ -201,6 +227,54 @@ private int minimumWidthForColumn(int col) { return minWidth; } + private int maximumHeightForRow(int row) { + int maxHeight = Integer.MAX_VALUE; + boolean isConstrained = false; + final int colCount = this.grid_.columns_.size(); + for (int j = 0; j < colCount; ++j) { + WLayoutItem item = this.grid_.items_.get(row).get(j).item_; + if (item != null) { + int itemMaxHeight = getImpl(item).getMaximumHeight(); + if (itemMaxHeight > 0) { + if (isConstrained) { + maxHeight = Math.min(maxHeight, itemMaxHeight); + } else { + maxHeight = itemMaxHeight; + isConstrained = true; + } + } + } + } + if (!isConstrained) { + maxHeight = 0; + } + return maxHeight; + } + + private int maximumWidthForColumn(int col) { + int maxWidth = Integer.MAX_VALUE; + boolean isConstrained = false; + final int rowCount = this.grid_.rows_.size(); + for (int i = 0; i < rowCount; ++i) { + WLayoutItem item = this.grid_.items_.get(i).get(col).item_; + if (item != null) { + int itemMaxWidth = getImpl(item).getMaximumWidth(); + if (itemMaxWidth > 0) { + if (isConstrained) { + maxWidth = Math.min(maxWidth, itemMaxWidth); + } else { + maxWidth = itemMaxWidth; + isConstrained = true; + } + } + } + } + if (!isConstrained) { + maxWidth = 0; + } + return maxWidth; + } + private DomElement createElement( Orientation orientation, int index, int totalStretch, WApplication app) { final Grid.Item it = this.item(orientation, index); diff --git a/src/eu/webtoolkit/jwt/HttpHeader.java b/src/eu/webtoolkit/jwt/HttpHeader.java new file mode 100644 index 00000000..cac360bb --- /dev/null +++ b/src/eu/webtoolkit/jwt/HttpHeader.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 Emweb bv, Herent, Belgium. + * + * See the LICENSE file for terms of use. + */ +package eu.webtoolkit.jwt; + +import eu.webtoolkit.jwt.auth.*; +import eu.webtoolkit.jwt.auth.mfa.*; +import eu.webtoolkit.jwt.chart.*; +import eu.webtoolkit.jwt.servlet.*; +import eu.webtoolkit.jwt.utils.*; +import java.io.*; +import java.lang.ref.*; +import java.time.*; +import java.util.*; +import java.util.regex.*; +import javax.servlet.*; +import javax.servlet.http.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class HttpHeader { + private static Logger logger = LoggerFactory.getLogger(HttpHeader.class); + + public HttpHeader(String name, String contents) { + this.name_ = name; + this.contents_ = contents; + } + + public String getContents() { + return this.contents_; + } + + public String getName() { + return this.name_; + } + + private String name_; + private String contents_; +} diff --git a/src/eu/webtoolkit/jwt/PaintedSlider.java b/src/eu/webtoolkit/jwt/PaintedSlider.java index 96cb0258..c1a3b955 100644 --- a/src/eu/webtoolkit/jwt/PaintedSlider.java +++ b/src/eu/webtoolkit/jwt/PaintedSlider.java @@ -144,7 +144,7 @@ public void updateState() { char[] buf = new char[30]; StringBuilder mouseDownJS = new StringBuilder(); mouseDownJS - .append("obj.setAttribute('down', Wt4_11_1") + .append("obj.setAttribute('down', Wt4.11.2") .append(".widgetCoordinates(obj, event).") .append(u) .append(");"); @@ -200,7 +200,7 @@ public void updateState() { StringBuilder mouseMovedJS = new StringBuilder(); mouseMovedJS .append("var down = obj.getAttribute('down');") - .append("var WT = Wt4_11_1;") + .append("var WT = Wt4.11.2;") .append("if (down != null && down != '') {") .append(computeD.toString()); mouseMovedJS @@ -244,7 +244,7 @@ public void updateState() { StringBuilder mouseUpJS = new StringBuilder(); mouseUpJS .append("var down = obj.getAttribute('down');") - .append("var WT = Wt4_11_1;") + .append("var WT = Wt4.11.2;") .append("if (down != null && down != '') {") .append(computeD.toString()) .append("d += ") diff --git a/src/eu/webtoolkit/jwt/ResizeSensor.java b/src/eu/webtoolkit/jwt/ResizeSensor.java index 937a70ac..6870c49d 100644 --- a/src/eu/webtoolkit/jwt/ResizeSensor.java +++ b/src/eu/webtoolkit/jwt/ResizeSensor.java @@ -29,7 +29,7 @@ public static void applyIfNeeded(WWidget w) { loadJavaScript(app); w.setJavaScriptMember(" ResizeSensor", ""); w.setJavaScriptMember( - " ResizeSensor", "new Wt4_11_1.ResizeSensor(Wt4_11_1," + w.getJsRef() + ")"); + " ResizeSensor", "new Wt4.11.2.ResizeSensor(Wt4.11.2," + w.getJsRef() + ")"); } } diff --git a/src/eu/webtoolkit/jwt/ServletApi.java b/src/eu/webtoolkit/jwt/ServletApi.java index 62218aaa..86500930 100644 --- a/src/eu/webtoolkit/jwt/ServletApi.java +++ b/src/eu/webtoolkit/jwt/ServletApi.java @@ -214,6 +214,23 @@ protected void handleRequest(final WtServlet servlet, final WebRequest request, } public void doHandleRequest(final WtServlet servlet, final WebRequest request, final WebResponse response) { + if (servlet.getConfiguration().isUseScriptNonce()) { + try { + // Use reflection to bypass accessibility constraint because WebResponse + // is in another package and addNonce should not be public. + java.lang.reflect.Method addNonce = response.getClass().getDeclaredMethod("addNonce"); + addNonce.setAccessible(true); + addNonce.invoke(response); + } catch (NoSuchMethodException e) { + // should never happen + getLogger().error("NoSuchMethodException occurred when adding nonce header: {}", e.getMessage(), e); + } catch (IllegalAccessException e) { + // should never happen + getLogger().error("IllegalAccessException occurred when adding nonce header: {}", e.getMessage(), e); + } catch (Exception e) { + getLogger().error("Exception occurred when adding nonce header: {}", e.getMessage(), e); + } + } if (request.isAsyncSupported()) { request.startAsync(); final long asyncContextTimeout = servlet.getConfiguration().getAsyncContextTimeout(); diff --git a/src/eu/webtoolkit/jwt/StdGridLayoutImpl2.java b/src/eu/webtoolkit/jwt/StdGridLayoutImpl2.java index 5518cb3c..a26e3e07 100644 --- a/src/eu/webtoolkit/jwt/StdGridLayoutImpl2.java +++ b/src/eu/webtoolkit/jwt/StdGridLayoutImpl2.java @@ -70,6 +70,32 @@ public int getMinimumHeight() { return total + (rowCount - 1) * this.grid_.verticalSpacing_; } + public int getMaximumWidth() { + final int colCount = this.grid_.columns_.size(); + int total = 0; + for (int i = 0; i < colCount; ++i) { + int colMax = this.maximumWidthForColumn(i); + if (colMax == 0) { + return 0; + } + total += colMax; + } + return total + (colCount - 1) * this.grid_.horizontalSpacing_; + } + + public int getMaximumHeight() { + final int rowCount = this.grid_.rows_.size(); + int total = 0; + for (int i = 0; i < rowCount; ++i) { + int rowMax = this.maximumHeightForRow(i); + if (rowMax == 0) { + return 0; + } + total += rowMax; + } + return total + (rowCount - 1) * this.grid_.verticalSpacing_; + } + public void itemAdded(WLayoutItem item) { this.addedItems_.add(item); this.update(); @@ -93,7 +119,7 @@ public void updateDom(final DomElement parent) { } this.addedItems_.clear(); for (int i = 0; i < this.removedItems_.size(); ++i) { - parent.callJavaScript("Wt4_11_1.remove('" + this.removedItems_.get(i) + "');", true); + parent.callJavaScript("Wt4.11.2.remove('" + this.removedItems_.get(i) + "');", true); } this.removedItems_.clear(); parent.addChild(div); @@ -189,7 +215,7 @@ public DomElement createDomElement( } StringBuilder js = new StringBuilder(); js.append(app.getJavaScriptClass()) - .append(".layouts2.add(new Wt4_11_1.StdLayout2(") + .append(".layouts2.add(new Wt4.11.2.StdLayout2(") .append(app.getJavaScriptClass()) .append(",'") .append(this.getId()) @@ -609,6 +635,54 @@ private int minimumWidthForColumn(int col) { return minWidth; } + private int maximumHeightForRow(int row) { + int maxHeight = Integer.MAX_VALUE; + boolean isConstrained = false; + final int colCount = this.grid_.columns_.size(); + for (int j = 0; j < colCount; ++j) { + WLayoutItem item = this.grid_.items_.get(row).get(j).item_; + if (item != null) { + int itemMaxHeight = getImpl(item).getMaximumHeight(); + if (itemMaxHeight > 0) { + if (isConstrained) { + maxHeight = Math.min(maxHeight, itemMaxHeight); + } else { + maxHeight = itemMaxHeight; + isConstrained = true; + } + } + } + } + if (!isConstrained) { + maxHeight = 0; + } + return maxHeight; + } + + private int maximumWidthForColumn(int col) { + int maxWidth = Integer.MAX_VALUE; + boolean isConstrained = false; + final int rowCount = this.grid_.rows_.size(); + for (int i = 0; i < rowCount; ++i) { + WLayoutItem item = this.grid_.items_.get(i).get(col).item_; + if (item != null) { + int itemMaxWidth = getImpl(item).getMaximumWidth(); + if (itemMaxWidth > 0) { + if (isConstrained) { + maxWidth = Math.min(maxWidth, itemMaxWidth); + } else { + maxWidth = itemMaxWidth; + isConstrained = true; + } + } + } + } + if (!isConstrained) { + maxWidth = 0; + } + return maxWidth; + } + private static int pixelSize(final WLength size) { if (size.getUnit() == LengthUnit.Percentage) { return 0; @@ -643,9 +717,9 @@ private void streamConfig( js.append("0,"); } if (rows) { - js.append(this.minimumHeightForRow(i)); + js.append(this.minimumHeightForRow(i)).append(",").append(this.maximumHeightForRow(i)); } else { - js.append(this.minimumWidthForColumn(i)); + js.append(this.minimumWidthForColumn(i)).append(",").append(this.maximumWidthForColumn(i)); } js.append("]"); } @@ -741,7 +815,7 @@ static WJavaScriptPreamble wtjs1() { JavaScriptScope.WtClassScope, JavaScriptObjectType.JavaScriptConstructor, "StdLayout2", - "(function(e,t,i,s,n,o,l,f,r,c,a){const d=e.WT;this.descendants=[];const u=0,g=1,h=1,p=0,m=1e6,z=\"-\"+m+\"px\",x=this;let y,S,w,L,W,b,R=a,E=!0,M=!0,H=!1;const N=document.body.classList.contains(\"Wt-rtl\"),C=[{initialized:!1,config:R.cols,margins:r,maxSize:l,measures:[],sizes:[],stretched:[],fixedSize:[],Left:N?\"Right\":\"Left\",left:N?\"right\":\"left\",Right:N?\"Left\":\"Right\",Size:\"Width\",size:\"width\",alignBits:0,getItem:function(e,t){return R.items[t*C[p].config.length+e]},setItem:function(e,t,i){R.items[t*C[p].config.length+e]=i},handleClass:\"Wt-vrh2\",resizeDir:\"h\",resizerClass:\"Wt-hsh2\",fitSize:s,resizeHandles:[]},{initialized:!1,config:R.rows,margins:c,maxSize:f,measures:[],sizes:[],stretched:[],fixedSize:[],Left:\"Top\",left:\"top\",Right:\"Bottom\",Size:\"Height\",size:\"height\",alignBits:4,getItem:function(e,t){return R.items[e*C[p].config.length+t]},setItem:function(e,t,i){R.items[e*C[p].config.length+t]=i},handleClass:\"Wt-hrh2\",resizeDir:\"v\",resizerClass:\"Wt-vsh2\",fitSize:n,resizeHandles:[]}];document.getElementById(t).wtLayout=this;function v(e){for(const t of R.items)if(t&&t.id===e)return t;return null}function D(e,t,i,s){const n=C[t];let o,l,f=t?e.scrollHeight:e.scrollWidth;if(t===p){const i=d.pxself(e,n.left);if(f+i>s.clientWidth||f+i===s.clientWidth&&d.isGecko&&\"hidden\"===s.parentNode.parentNode.style.visibility){o=e.style[n.left];G(e,n.left,z);f=t?e.scrollHeight:e.scrollWidth}}let r=t?e.clientHeight:e.clientWidth;if(d.isGecko&&!e.style[n.size]&&t===p&&(\"visible\"===(c=d.css(e,\"overflow\"))||\"none\"===c)){l=e.style[n.size];G(e,n.size,\"\")}var c;let a=t?e.offsetHeight:e.offsetWidth;o&&G(e,n.left,o);l&&G(e,n.size,l);r>=m&&(r-=m);f>=m&&(f-=m);a>=m&&(a-=m);if(0===f){f=d.pxself(e,n.size);0===f||d.isOpera||d.isGecko||(f-=d.px(e,\"border\"+n.Left+\"Width\")+d.px(e,\"border\"+n.Right+\"Width\"))}if(f>a)if(0===d.pxself(e,n.size))f=r;else{let t=!1;e.querySelectorAll(\".Wt-popup\").forEach((function(e){\"none\"!==e.style.display&&(t=!0)}));t&&(f=r)}const u=d.px(e,\"border\"+n.Left+\"Width\")+d.px(e,\"border\"+n.Right+\"Width\"),g=a-(r+u)!=0;if(i)return[f,g];(d.isGecko||d.isWebKit)&&t===p&&e.getBoundingClientRect().width!==Math.ceil(e.getBoundingClientRect().width)&&(f+=1);d.boxSizing(e)||d.isOpera||(f+=u);f+=d.px(e,\"margin\"+n.Left)+d.px(e,\"margin\"+n.Right);d.boxSizing(e)||(f+=d.px(e,\"padding\"+n.Left)+d.px(e,\"padding\"+n.Right));f+=a-(r+u);f0&&(f=Math.min(h,f));return[Math.round(f),g]}function I(e,t){const i=C[t];if(\"none\"===e.style.display)return 0;if(e[\"layoutMin\"+i.Size])return e[\"layoutMin\"+i.Size];{let t=d.px(e,\"min\"+i.Size);d.boxSizing(e)||(t+=d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right));return t}}function A(e,t){const i=C[t];let s=d.px(e,\"margin\"+i.Left)+d.px(e,\"margin\"+i.Right);d.boxSizing(e)||(s+=d.px(e,\"border\"+i.Left+\"Width\")+d.px(e,\"border\"+i.Right+\"Width\")+d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right));return s}function T(e,t){const i=C[t];return d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right)}function j(e,t){if(d.boxSizing(e)){const i=C[t];return d.px(e,\"border\"+i.Left+\"Width\")+d.px(e,\"border\"+i.Right+\"Width\")+d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right)}return 0}function B(e,t){const i=C[t];return Math.round(d.px(e,\"border\"+i.Left+\"Width\")+d.px(e,\"border\"+i.Right+\"Width\")+d.px(e,\"margin\"+i.Left)+d.px(e,\"margin\"+i.Right)+d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right))}function P(t,i,s){t.dirty=Math.max(t.dirty,i);E=!0;s&&e.layouts2.scheduleAdjust()}function G(e,t,i){if(e.style[t]!==i){e.style[t]=i;return!0}return!1}function k(e){return\"none\"===e.style.display&&!e.ed||e.classList.contains(\"Wt-hidden\")}this.updateSizeInParent=function(e){if(S&&w.id){const e=d.$(w.id);if(e){if(w!==e){S=e.parentNode.wtLayout;S?w=e:O()}}else O()}if(S&&L){const i=C[e];let s=i.measures[2];i.maxSize>0&&(s=Math.min(i.maxSize,s));if(b){const i=d.getElement(t);if(!i)return;let n=i,o=n.parentNode;for(;;){o.wtGetPS&&(s=o.wtGetPS(o,n,e,s));s+=B(o,e);if(o===w)break;1===e&&o===i.parentNode&&!o.lh&&o.offsetHeight>s&&(s=o.offsetHeight);n=o;o=n.parentNode}}else s+=W[e];S.setChildSize(w,e,s)}};function _(i,s,n){const o=s.di,l=C[i],f=C[1^i],r=d.getElement(t);let c,a,g;for(g=o-1;g>=0;--g)if(l.sizes[g]>=0){c=-(l.sizes[g]-l.measures[h][g]);break}a=l.sizes[o]-l.measures[h][o];N&&([c,a]=[-a,-c]);new d.SizeHandle(d,l.resizeDir,d.pxself(s,l.size),d.pxself(s,f.size),c,a,l.resizerClass,(function(t){!function(t,i,s){const n=C[t];N&&(s=-s);if(n.config[i][u]>0&&0===n.config[i+1][u]){++i;s=-s}n.fixedSize[i]=n.sizes[i]+s;e.layouts2.scheduleAdjust()}(i,g,t)}),s,r,n,0,0)}function q(e,t){const i=e.config.length;if(0!==e.config[t][g])for(let s=t+1;s-1)return!0;for(let i=t-1;i>=0;--i)if(e.measures[h][i]>-1)return 0!==e.config[i][g];return!1}this.setConfig=function(t){const i=R;R=t;C[0].config=R.cols;C[1].config=R.rows;C[0].stretched=[];C[1].stretched=[];for(const e of i.items)if(e){const t=v(e.id);if(t){t.ps=e.ps;t.sc=e.sc;t.ms=e.ms;t.size=e.size;t.psize=e.psize;t.fs=e.fs;t.margin=e.margin;t.set=e.set}else if(e.set){e.set[p]&&G(e.w,C[p].size,\"\");e.set[1]&&G(e.w,C[1].size,\"\")}}M=!0;E=!0;e.layouts2.scheduleAdjust()};this.getId=function(){return t};this.setElDirty=function(t){const i=v(t.id);if(i){i.dirty=2;E=!0;e.layouts2.scheduleAdjust()}};this.setItemsDirty=function(t){const i=C[p].config.length;for(const[s,n]of t){const t=R.items[s*i+n];if(t){t.dirty=2;if(t.layout){t.layout=!1;t.wasLayout=!0;e.layouts2.setChildLayoutsDirty(x,t.w)}}}E=!0};this.setDirty=function(){M=!0};this.setAllDirty=function(){for(const e of R.items)e&&(e.dirty=2);E=!0};this.setChildSize=function(e,t,i){const s=C[p].config.length,n=C[t],o=v(e.id);if(o){const l=function(e){let t=0;for(const i of R.items){if(i&&i.id===e)return t;t+=1}return null}(e.id),f=t===p?l%s:l/s;if(o.align>>n.alignBits&15||!n.stretched[f]){o.ps||(o.ps=[]);o.ps[t]=i}o.layout=!0;P(o,1)}};function O(){const e=d.getElement(t);y=null===i;S=null;w=null;L=!0;H=!0;W=[];b=!1;if(y){let t=e,i=t.parentNode;W=[0,0];for(;i!==document&&!t.classList.contains(\"wt-reparented\");){W[p]+=B(i,p);W[1]+=B(i,1);i.wtGetPS&&(b=!0);const e=i.parentNode.wtLayout;if(e){w=i;S=e;break}t=i;i=t.parentNode;1===i.childNodes.length||i.wtGetPS||(L=!1)}const s=e.parentNode;for(let e=0;e<2;++e)C[e].sizeSet=0!==d.pxself(s,C[e].size)}else{S=document.getElementById(i).wtLayout;w=e;W[p]=B(w,p);W[1]=B(w,1)}}this.measure=function(e){const i=d.getElement(t);if(i&&!d.isHidden(i)){H||O();if(E||M){!function(e,t,i){const s=C[e],n=C[1^e],l=s.measures,f=s.config.length,r=n.config.length,c=l.slice();if(5===c.length){c[0]=c[0].slice();c[h]=c[h].slice()}if(E){if(i&&void 0===s.minSize){s.minSize=d.px(i,\"min\"+s.Size);s.minSize>0&&(s.minSize-=j(i,e))}const m=[],z=[],y=!0;let S=!1;for(let H=0;H1){const O=d.$(_.id);if(!O){s.setItem(H,B,null);continue}if(O!==_.w){_.w=O;const $=_;[O,...O.querySelectorAll(\"img\")].filter((e=>\"IMG\"===e.tagName)).forEach((function(e){e.addEventListener(\"load\",(function(){P($,1,!0)}))}))}}if(!o&&\"absolute\"!==_.w.style.position){_.w.style.position=\"absolute\";_.w.style.visibility=\"hidden\"}_.ps||(_.ps=[]);_.sc||(_.sc=[]);_.ms||(_.ms=[]);_.size||(_.size=[]);_.psize||(_.psize=[]);_.fs||(_.fs=[]);_.margin||(_.margin=[]);const q=!_.set;_.set||(_.set=[!1,!1]);if(k(_.w)){_.ps[e]=_.ms[e]=0;continue}if(_.w){if(_.dirty){let J;if(_.dirty>1){J=I(_.w,e);_.ms[e]=J}else J=_.ms[e];_.dirty>1&&(_.margin[e]=A(_.w,e));if(!_.set[e])if(e!==p&&q){const Q=Math.round(d.px(_.w,s.size));Q>Math.max(j(_.w,e),J)?_.fs[e]=Q+_.margin[e]:_.fs[e]=0}else{const U=d.pxself(_.w,s.size);_.fs[e]=U?U+_.margin[e]:0}const K=_.align>>s.alignBits&15;let F=_.fs[e];if(K||y||s.config[H][u]<=0)if(_.layout){0===F&&(F=_.ps[e]);_.ps[e]=F}else{if(_.wasLayout){_.wasLayout=!1;_.set=[!1,!1];_.ps=[];_.w.wtResize&&_.w.wtResize(_.w,-1,-1,!0);G(_.w,C[1].size,\"\")}const V=D(_.w,e,!1,t),X=V[0];let Y=_.set[e];Y&&_.psize[e]>8&&(Y=X>=_.psize[e]-4&&X<=_.psize[e]+4);const Z=void 0!==_.ps[e]&&s.config[H][u]>0&&_.set[e];F=Y||Z?Math.max(F,_.ps[e]):Math.max(F,X);_.ps[e]=F;_.sc[e]=V[1]}else _.layout&&0===F&&(F=_.ps[e]);if(_.span&&1!==_.span[e])S=!0;else{F>N&&(N=F);J>v&&(v=J)}}else if(_.span&&1!==_.span[e])S=!0;else{_.ps[e]>N&&(N=_.ps[e]);_.ms[e]>v&&(v=_.ms[e])}k(_.w)||_.span&&1!==_.span[e]||(T=!1)}}}T?v=N=-1:v>N&&(N=v);m[H]=N;z[H]=v}if(S){function a(t,i){for(let n=f-1;n>=0;--n)for(let o=0;o1){let o,f=t(l),r=0,c=0;for(o=0;o0&&(c+=s.config[n+o][u]);0!==o&&(f-=s.margins[0])}}if(f>=0)if(r>0){c>0&&(r=c);for(o=0;o0?s.config[n+o][u]:1;if(e>0){const t=Math.round(f*(e/r));f-=t;r-=e;i[n+o]+=t}}}else i[n]=f}}}a((function(t){return t.ps[e]}),m);a((function(t){return t.ms[e]}),z)}let w=0,L=0;for(let ee=0;eem[ee]&&(m[ee]=z[ee]);if(z[ee]>-1){w+=m[ee];L+=z[ee]}}let W=0,b=!0,R=!1;for(let te=0;te-1){if(b){W+=s.margins[1];b=!1}else{W+=s.margins[0];R&&(W+=4)}R=0!==s.config[te][g]}b||(W+=s.margins[2]);w+=W;L+=W;s.measures=[m,z,w,L,W]}(M||c[2]!==s.measures[2])&&x.updateSizeInParent(e);if(i&&0===s.minSize&&c[3]!==s.measures[3]&&\"Wt-domRoot\"!==i.parentNode.className){const ie=s.measures[3]+\"px\";G(i,\"min\"+s.Size,ie)}i&&e===p&&i&&d.hasTag(i,\"TD\")&&G(i,s.size,s.measures[2]+\"px\")}(e,i,y?i.parentNode:null)}1===e&&(E=M=!1)}};this.setMaxSize=function(e,t){C[p].maxSize=e;C[1].maxSize=t};this.apply=function(e){const i=d.getElement(t);if(!i)return!1;if(d.isHidden(i))return!0;!function(e,i){const s=C[e],n=C[1^e],l=s.measures;let f=0,r=!1,c=!1;const a=y?i.parentNode:null;if(0===s.maxSize)if(a){const t=d.css(a,\"position\");\"absolute\"===t&&(f=d.pxself(a,s.size));if(0===f){if(!s.initialized){if(e===p&&(\"absolute\"===t||\"fixed\"===t)){a.style.display=\"none\";f=a.clientWidth;a.style.display=\"\"}f=e?a.clientHeight:a.clientWidth;r=!0;let i,n;if(d.hasTag(a,\"TD\")||d.hasTag(a,\"TH\")||a.parentNode.classList.contains(\"Wt-domRoot\")){i=0;n=1}else{i=s.minSize?s.minSize:l[3];n=0}f-(i+T(a,e))<=1&&(s.maxSize=999999)}if(0===f&&0===s.maxSize){f=e?a.clientHeight:a.clientWidth;r=!0}}}else{f=d.pxself(i,s.size);c=!0}else if(s.sizeSet){f=d.pxself(a,s.size);c=!0}let m=0;a&&a.wtGetPS&&1===e&&(m=a.wtGetPS(a,i,e,0));let z=l[2];z=l[3]-m){const e=-1,t=-2,i=0,n=1;let o=f-l[4];const r=[],c=[0,0],a=[0,0];let d=0;for(let p=0;p-1){let t=-1;q(s,p)||delete s.fixedSize[p];if(void 0!==s.fixedSize[p]&&(p+1===L||l[h][p+1]>-1))t=s.fixedSize[p];else if(q(s,p)&&0!==s.config[p][g]&&s.config[p][g][0]>=0){t=s.config[p][g][0];s.config[p][g][1]&&(t=(f-l[4])*t/100)}if(t>=0){r[p]=e;x[p]=t;o-=x[p]}else{let e;if(s.config[p][u]>0){e=n;r[p]=s.config[p][u];d+=r[p]}else{e=i;r[p]=0}c[e]+=l[h][p];a[e]+=l[0][p];x[p]=l[0][p]}}else{r[p]=t;x[p]=-1}s.fixedSize.length>L&&(s.fixedSize.length=L);if(0===d){for(let e=0;ea[i]+c[n]){o-=a[i];if(o>a[n]){if(s.fitSize){o-=a[n];const e=o/d;let t=0;for(let i=0;i0){const n=t;t+=r[i]*e;x[i]+=Math.round(t)-Math.round(n);s.stretched[i]=!0}}}else{const e=n;o0?(o-c[e])/(a[e]-c[e]):0;let i=0;for(let e=0;e0){const s=i;i+=(l[0][e]-l[h][e])*t;x[e]=l[h][e]+Math.round(i)-Math.round(s)}}}else{for(let e=0;e0&&(x[e]=l[h][e]);o-=c[n];const e=i;o0?(o-c[e])/(a[e]-c[e]):0;let s=0;for(let e=0;e-1){if(M){const o=t+\"-rs\"+e+\"-\"+l;let f=d.getElement(o);if(!f){s.resizeHandles[l]=o;f=document.createElement(\"div\");f.setAttribute(\"id\",o);f.di=l;f.style.position=\"absolute\";f.style[n.left]=n.margins[1]+\"px\";f.style[s.size]=s.margins[0]+\"px\";n.cSize&&(f.style[n.size]=n.cSize-n.margins[2]-n.margins[1]+\"px\");f.className=s.handleClass;i.insertBefore(f,i.firstChild);f.onmousedown=f.ontouchstart=function(t){const i=t||window.event;_(e,this,i)}}R+=2;G(f,s.left,R+\"px\");R+=2}else if(s.resizeHandles[l]){const e=d.getElement(s.resizeHandles[l]);e.parentNode.removeChild(e);delete s.resizeHandles[l]}M=0!==s.config[l][g];E?E=!1:R+=s.margins[0]}else if(s.resizeHandles[l]){const e=d.getElement(s.resizeHandles[l]);e.parentNode.removeChild(e);delete s.resizeHandles[l]}for(let t=0;t=x.length);++t){n&&(f+=4);n=0!==s.config[l+t][g];x[l+t-1]>-1&&x[l+t]>-1&&(f+=s.margins[0]);f+=x[l+t]}}G(t,\"visibility\",\"\");let r=i.align>>s.alignBits&15,c=i.ps[e];f=c&&i.set[e]){G(t,s.size,c+\"px\")&&P(i,1);i.set[e]=!1}i.size[e]=c;i.psize[e]=c}else{const o=i.margin[e],l=Math.max(0,f-o),r=0===e&&i.sc[e];if(k(t)||!r&&f===c&&!i.layout)if(i.fs[e])e===p&&G(t,s.size,i.fs[e]-o+\"px\");else{G(t,s.size,\"\")&&P(i,1);i.set&&(i.set[e]=!1)}else if(G(t,s.size,l+\"px\")){P(i,1);i.set[e]=!0}n=R;i.size[e]=l;i.psize[e]=f}if(o)if(H){G(t,s.left,\"4px\");\"absolute\"!==d.css(t,\"position\")&&(t.style.position=\"relative\")}else G(t,s.left,\"0px\");else G(t,s.left,n+\"px\");if(1===e){t.wtResize&&t.wtResize(t,i.set[p]?Math.round(i.size[p]):-1,i.set[1]?Math.round(i.size[1]):-1,!0);i.dirty=0}}}x[l]>-1&&(R+=x[l])}if(s.resizeHandles.length>L){for(const e of s.resizeHandles)if(e){const t=d.getElement(e);t.parentNode.removeChild(t)}s.resizeHandles.length=L}i.querySelectorAll(`:scope > .${n.handleClass}`).forEach((function(e){e.style[s.size]=f-s.margins[2]-s.margins[1]+\"px\"}))}(e,i);return!0};this.contains=function(e){const i=d.getElement(t),s=d.getElement(e.getId());return!(!i||!s)&&d.contains(i,s)};this.WT=d})"); + "(function(e,t,i,s,n,o,f,l,r,c,a){const d=e.WT;this.descendants=[];const u=0,g=1,h=3,p=1,m=0,z=1e6,x=\"-\"+z+\"px\",y=this;let S,w,L,W,b,M,R=a,E=!0,H=!0,N=!1;const C=document.body.classList.contains(\"Wt-rtl\"),v=[{initialized:!1,config:R.cols,margins:r,maxSize:f,measures:[],sizes:[],stretched:[],fixedSize:[],Left:C?\"Right\":\"Left\",left:C?\"right\":\"left\",Right:C?\"Left\":\"Right\",Size:\"Width\",size:\"width\",alignBits:0,getItem:function(e,t){return R.items[t*v[m].config.length+e]},setItem:function(e,t,i){R.items[t*v[m].config.length+e]=i},handleClass:\"Wt-vrh2\",resizeDir:\"h\",resizerClass:\"Wt-hsh2\",fitSize:s,resizeHandles:[]},{initialized:!1,config:R.rows,margins:c,maxSize:l,measures:[],sizes:[],stretched:[],fixedSize:[],Left:\"Top\",left:\"top\",Right:\"Bottom\",Size:\"Height\",size:\"height\",alignBits:4,getItem:function(e,t){return R.items[e*v[m].config.length+t]},setItem:function(e,t,i){R.items[e*v[m].config.length+t]=i},handleClass:\"Wt-hrh2\",resizeDir:\"v\",resizerClass:\"Wt-vsh2\",fitSize:n,resizeHandles:[]}];document.getElementById(t).wtLayout=this;function D(e){for(const t of R.items)if(t&&t.id===e)return t;return null}function I(e,t,i,s){const n=v[t];let o,f,l=t?e.scrollHeight:e.scrollWidth;if(t===m){const i=d.pxself(e,n.left);if(l+i>s.clientWidth||l+i===s.clientWidth&&d.isGecko&&\"hidden\"===s.parentNode.parentNode.style.visibility){o=e.style[n.left];k(e,n.left,x);l=t?e.scrollHeight:e.scrollWidth}}let r=t?e.clientHeight:e.clientWidth;if(d.isGecko&&!e.style[n.size]&&t===m&&(\"visible\"===(c=d.css(e,\"overflow\"))||\"none\"===c)){f=e.style[n.size];k(e,n.size,\"\")}var c;let a=t?e.offsetHeight:e.offsetWidth;o&&k(e,n.left,o);f&&k(e,n.size,f);r>=z&&(r-=z);l>=z&&(l-=z);a>=z&&(a-=z);if(0===l){l=d.pxself(e,n.size);0===l||d.isOpera||d.isGecko||(l-=d.px(e,\"border\"+n.Left+\"Width\")+d.px(e,\"border\"+n.Right+\"Width\"))}if(l>a)if(0===d.pxself(e,n.size))l=r;else{let t=!1;e.querySelectorAll(\".Wt-popup\").forEach((function(e){\"none\"!==e.style.display&&(t=!0)}));t&&(l=r)}const u=d.px(e,\"border\"+n.Left+\"Width\")+d.px(e,\"border\"+n.Right+\"Width\"),g=a-(r+u)!=0;if(i)return[l,g];(d.isGecko||d.isWebKit)&&t===m&&e.getBoundingClientRect().width!==Math.ceil(e.getBoundingClientRect().width)&&(l+=1);d.boxSizing(e)||d.isOpera||(l+=u);l+=d.px(e,\"margin\"+n.Left)+d.px(e,\"margin\"+n.Right);d.boxSizing(e)||(l+=d.px(e,\"padding\"+n.Left)+d.px(e,\"padding\"+n.Right));l+=a-(r+u);l0&&(l=Math.min(h,l));return[Math.round(l),g]}function A(e,t){const i=v[t];if(\"none\"===e.style.display)return 0;if(e[\"layoutMin\"+i.Size])return e[\"layoutMin\"+i.Size];{let t=d.px(e,\"min\"+i.Size);d.boxSizing(e)||(t+=d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right));return t}}function T(e,t){const i=v[t];let s=d.px(e,\"margin\"+i.Left)+d.px(e,\"margin\"+i.Right);d.boxSizing(e)||(s+=d.px(e,\"border\"+i.Left+\"Width\")+d.px(e,\"border\"+i.Right+\"Width\")+d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right));return s}function j(e,t){const i=v[t];return d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right)}function B(e,t){if(d.boxSizing(e)){const i=v[t];return d.px(e,\"border\"+i.Left+\"Width\")+d.px(e,\"border\"+i.Right+\"Width\")+d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right)}return 0}function P(e,t){const i=v[t];return Math.round(d.px(e,\"border\"+i.Left+\"Width\")+d.px(e,\"border\"+i.Right+\"Width\")+d.px(e,\"margin\"+i.Left)+d.px(e,\"margin\"+i.Right)+d.px(e,\"padding\"+i.Left)+d.px(e,\"padding\"+i.Right))}function G(t,i,s){t.dirty=Math.max(t.dirty,i);E=!0;s&&e.layouts2.scheduleAdjust()}function k(e,t,i){if(e.style[t]!==i){e.style[t]=i;return!0}return!1}function _(e){return\"none\"===e.style.display&&!e.ed||e.classList.contains(\"Wt-hidden\")}this.updateSizeInParent=function(e){if(w&&L.id){const e=d.$(L.id);if(e){if(L!==e){w=e.parentNode.wtLayout;w?L=e:J()}}else J()}if(w&&W){const i=v[e];let s=i.measures[2];i.maxSize>0&&(s=Math.min(i.maxSize,s));if(M){const i=d.getElement(t);if(!i)return;let n=i,o=n.parentNode;for(;;){o.wtGetPS&&(s=o.wtGetPS(o,n,e,s));s+=P(o,e);if(o===L)break;1===e&&o===i.parentNode&&!o.lh&&o.offsetHeight>s&&(s=o.offsetHeight);n=o;o=n.parentNode}}else s+=b[e];w.setChildSize(L,e,s)}};function q(e,t){const i=v[e];let s,n=!0,o=0,f=0;for(s=0;s0){o+=i.sizes[s]-i.measures[p][s];n=!1}else f+=i.sizes[s]-i.measures[p][s];n&&(o=f);const l=i.config[t][h];l>0&&(o=Math.min(o,l-i.sizes[t]));return o}function O(i,s,n){const o=s.di,f=v[i],l=v[1^i],r=d.getElement(t);let c,a,g;for(g=o-1;g>=0;--g)if(f.sizes[g]>=0){c=f.config[g][u]>0&&0===f.config[g+1][u]?-q(i,g+1):-(f.sizes[g]-f.measures[p][g]);break}a=f.config[g][u]>0&&0===f.config[g+1][u]?f.sizes[o]-f.measures[p][o]:q(i,g);C&&([c,a]=[-a,-c]);new d.SizeHandle(d,f.resizeDir,d.pxself(s,f.size),d.pxself(s,l.size),c,a,f.resizerClass,(function(t){!function(t,i,s){const n=v[t];C&&(s=-s);if(n.config[i][u]>0&&0===n.config[i+1][u]){++i;s=-s}n.fixedSize[i]=n.sizes[i]+s;e.layouts2.scheduleAdjust()}(i,g,t)}),s,r,n,0,0)}function $(e,t){const i=e.config.length;if(0!==e.config[t][g])for(let s=t+1;s-1)return!0;for(let i=t-1;i>=0;--i)if(e.measures[p][i]>-1)return 0!==e.config[i][g];return!1}this.setConfig=function(t){const i=R;R=t;v[0].config=R.cols;v[1].config=R.rows;v[0].stretched=[];v[1].stretched=[];for(const e of i.items)if(e){const t=D(e.id);if(t){t.ps=e.ps;t.sc=e.sc;t.ms=e.ms;t.size=e.size;t.psize=e.psize;t.fs=e.fs;t.margin=e.margin;t.set=e.set}else if(e.set){e.set[m]&&k(e.w,v[m].size,\"\");e.set[1]&&k(e.w,v[1].size,\"\")}}H=!0;E=!0;e.layouts2.scheduleAdjust()};this.getId=function(){return t};this.setElDirty=function(t){const i=D(t.id);if(i){i.dirty=2;E=!0;e.layouts2.scheduleAdjust()}};this.setItemsDirty=function(t){const i=v[m].config.length;for(const[s,n]of t){const t=R.items[s*i+n];if(t){t.dirty=2;if(t.layout){t.layout=!1;t.wasLayout=!0;e.layouts2.setChildLayoutsDirty(y,t.w)}}}E=!0};this.setDirty=function(){H=!0};this.setAllDirty=function(){for(const e of R.items)e&&(e.dirty=2);E=!0};this.setChildSize=function(e,t,i){const s=v[m].config.length,n=v[t],o=D(e.id);if(o){const f=function(e){let t=0;for(const i of R.items){if(i&&i.id===e)return t;t+=1}return null}(e.id),l=t===m?f%s:f/s;if(o.align>>n.alignBits&15||!n.stretched[l]){o.ps||(o.ps=[]);o.ps[t]=i}o.layout=!0;G(o,1)}};function J(){const e=d.getElement(t);S=null===i;w=null;L=null;W=!0;N=!0;b=[];M=!1;if(S){let t=e,i=t.parentNode;b=[0,0];for(;i!==document&&!t.classList.contains(\"wt-reparented\");){b[m]+=P(i,m);b[1]+=P(i,1);i.wtGetPS&&(M=!0);const e=i.parentNode.wtLayout;if(e){L=i;w=e;break}t=i;i=t.parentNode;1===i.childNodes.length||i.wtGetPS||(W=!1)}const s=e.parentNode;for(let e=0;e<2;++e)v[e].sizeSet=0!==d.pxself(s,v[e].size)}else{w=document.getElementById(i).wtLayout;L=e;b[m]=P(L,m);b[1]=P(L,1)}}this.measure=function(e){const i=d.getElement(t);if(i&&!d.isHidden(i)){N||J();if(E||H){!function(e,t,i){const s=v[e],n=v[1^e],f=s.measures,l=s.config.length,r=n.config.length,c=f.slice();if(5===c.length){c[0]=c[0].slice();c[p]=c[p].slice()}if(E){if(i&&void 0===s.minSize){s.minSize=d.px(i,\"min\"+s.Size);s.minSize>0&&(s.minSize-=B(i,e))}const h=[],z=[],x=!0;let S=!1;for(let R=0;R1){const O=d.$(P.id);if(!O){s.setItem(R,j,null);continue}if(O!==P.w){P.w=O;const $=P;[O,...O.querySelectorAll(\"img\")].filter((e=>\"IMG\"===e.tagName)).forEach((function(e){e.addEventListener(\"load\",(function(){G($,1,!0)}))}))}}if(!o&&\"absolute\"!==P.w.style.position){P.w.style.position=\"absolute\";P.w.style.visibility=\"hidden\"}P.ps||(P.ps=[]);P.sc||(P.sc=[]);P.ms||(P.ms=[]);P.size||(P.size=[]);P.psize||(P.psize=[]);P.fs||(P.fs=[]);P.margin||(P.margin=[]);const q=!P.set;P.set||(P.set=[!1,!1]);if(_(P.w)){P.ps[e]=P.ms[e]=0;continue}if(P.w){if(P.dirty){let J;if(P.dirty>1){J=A(P.w,e);P.ms[e]=J}else J=P.ms[e];P.dirty>1&&(P.margin[e]=T(P.w,e));if(!P.set[e])if(e!==m&&q){const Q=Math.round(d.px(P.w,s.size));Q>Math.max(B(P.w,e),J)?P.fs[e]=Q+P.margin[e]:P.fs[e]=0}else{const U=d.pxself(P.w,s.size);P.fs[e]=U?U+P.margin[e]:0}const K=P.align>>s.alignBits&15;let F=P.fs[e];if(K||x||s.config[R][u]<=0)if(P.layout){0===F&&(F=P.ps[e]);P.ps[e]=F}else{if(P.wasLayout){P.wasLayout=!1;P.set=[!1,!1];P.ps=[];P.w.wtResize&&P.w.wtResize(P.w,-1,-1,!0);k(P.w,v[1].size,\"\")}const V=I(P.w,e,!1,t),X=V[0];let Y=P.set[e];Y&&P.psize[e]>8&&(Y=X>=P.psize[e]-4&&X<=P.psize[e]+4);const Z=void 0!==P.ps[e]&&s.config[R][u]>0&&P.set[e];F=Y||Z?Math.max(F,P.ps[e]):Math.max(F,X);P.ps[e]=F;P.sc[e]=V[1]}else P.layout&&0===F&&(F=P.ps[e]);if(P.span&&1!==P.span[e])S=!0;else{F>N&&(N=F);J>C&&(C=J)}}else if(P.span&&1!==P.span[e])S=!0;else{P.ps[e]>N&&(N=P.ps[e]);P.ms[e]>C&&(C=P.ms[e])}_(P.w)||P.span&&1!==P.span[e]||(D=!1)}}}D?C=N=-1:C>N&&(N=C);h[R]=N;z[R]=C}if(S){function a(t,i){for(let n=l-1;n>=0;--n)for(let o=0;o1){let o,l=t(f),r=0,c=0;for(o=0;o0&&(c+=s.config[n+o][u]);0!==o&&(l-=s.margins[0])}}if(l>=0)if(r>0){c>0&&(r=c);for(o=0;o0?s.config[n+o][u]:1;if(e>0){const t=Math.round(l*(e/r));l-=t;r-=e;i[n+o]+=t}}}else i[n]=l}}}a((function(t){return t.ps[e]}),h);a((function(t){return t.ms[e]}),z)}let w=0,L=0;for(let ee=0;eeh[ee]&&(h[ee]=z[ee]);if(z[ee]>-1){w+=h[ee];L+=z[ee]}}let W=0,b=!0,M=!1;for(let te=0;te-1){if(b){W+=s.margins[1];b=!1}else{W+=s.margins[0];M&&(W+=10)}M=0!==s.config[te][g]}b||(W+=s.margins[2]);w+=W;L+=W;s.measures=[h,z,w,L,W]}(H||c[2]!==s.measures[2])&&y.updateSizeInParent(e);if(i&&0===s.minSize&&c[3]!==s.measures[3]&&\"Wt-domRoot\"!==i.parentNode.className){const ie=s.measures[3]+\"px\";k(i,\"min\"+s.Size,ie)}i&&e===m&&i&&d.hasTag(i,\"TD\")&&k(i,s.size,s.measures[2]+\"px\")}(e,i,S?i.parentNode:null)}1===e&&(E=H=!1)}};this.setMaxSize=function(e,t){v[m].maxSize=e;v[1].maxSize=t};this.apply=function(e){const i=d.getElement(t);if(!i)return!1;if(d.isHidden(i))return!0;!function(e,i){const s=v[e],n=v[1^e],f=s.measures;let l=0,r=!1,c=!1;const a=S?i.parentNode:null;if(0===s.maxSize)if(a){const t=d.css(a,\"position\");\"absolute\"===t&&(l=d.pxself(a,s.size));if(0===l){if(!s.initialized){if(e===m&&(\"absolute\"===t||\"fixed\"===t)){a.style.display=\"none\";l=a.clientWidth;a.style.display=\"\"}l=e?a.clientHeight:a.clientWidth;r=!0;let i,n;if(d.hasTag(a,\"TD\")||d.hasTag(a,\"TH\")||a.parentNode.classList.contains(\"Wt-domRoot\")){i=0;n=1}else{i=s.minSize?s.minSize:f[3];n=0}l-(i+j(a,e))<=1&&(s.maxSize=999999)}if(0===l&&0===s.maxSize){l=e?a.clientHeight:a.clientWidth;r=!0}}}else{l=d.pxself(i,s.size);c=!0}else if(s.sizeSet){l=d.pxself(a,s.size);c=!0}let z=0;a&&a.wtGetPS&&1===e&&(z=a.wtGetPS(a,i,e,0));let x=f[2];x=f[3]-z){const e=-1,t=-2,i=0,n=1;let o=l-f[4];const r=[],c=[0,0],a=[0,0];let d=0;for(let h=0;h-1){let t=-1;$(s,h)||delete s.fixedSize[h];if(void 0!==s.fixedSize[h]&&(h+1===W||f[p][h+1]>-1))t=s.fixedSize[h];else if($(s,h)&&0!==s.config[h][g]&&s.config[h][g][0]>=0){t=s.config[h][g][0];s.config[h][g][1]&&(t=(l-f[4])*t/100)}if(t>=0){r[h]=e;y[h]=t;o-=y[h]}else{let e;if(s.config[h][u]>0){e=n;r[h]=s.config[h][u];d+=r[h]}else{e=i;r[h]=0}c[e]+=f[p][h];a[e]+=f[0][h];y[h]=f[0][h]}}else{r[h]=t;y[h]=-1}s.fixedSize.length>W&&(s.fixedSize.length=W);if(0===d){for(let e=0;ea[i]+c[n]){o-=a[i];if(o>a[n]){if(s.fitSize){o-=a[n];let e=!0;for(;e&&o>0;){const t=o/d;let i=0;for(let e=0;e0){const n=i;i+=r[e]*t;const f=Math.round(i)-Math.round(n);y[e]+=f;o-=f;const l=s.config[e][h];if(l>0){const t=y[e];y[e]=Math.min(y[e],l);if(y[e]===l){o+=t-l;d-=r[e];r[e]=-1}}s.stretched[e]=!0}if(0===d)for(let e=0;e0}}}else{const e=n;o0?(o-c[e])/(a[e]-c[e]):0;let i=0;for(let e=0;e0){const s=i;i+=(f[0][e]-f[p][e])*t;y[e]=f[p][e]+Math.round(i)-Math.round(s)}}}else{for(let e=0;e0&&(y[e]=f[p][e]);o-=c[n];const e=i;o0?(o-c[e])/(a[e]-c[e]):0;let s=0;for(let e=0;e-1){if(H){const o=t+\"-rs\"+e+\"-\"+f;let l=d.getElement(o);if(!l){s.resizeHandles[f]=o;l=document.createElement(\"div\");l.setAttribute(\"id\",o);l.di=f;l.style.position=\"absolute\";l.style[n.left]=n.margins[1]+\"px\";l.style[s.size]=\"5px\";n.cSize&&(l.style[n.size]=n.cSize-n.margins[2]-n.margins[1]+\"px\");l.className=s.handleClass;i.insertBefore(l,i.firstChild);l.onmousedown=l.ontouchstart=function(t){const i=t||window.event;O(e,this,i)}}R+=s.margins[0]/2;k(l,s.left,R+\"px\");R+=5}else if(s.resizeHandles[f]){const e=d.getElement(s.resizeHandles[f]);e.parentNode.removeChild(e);delete s.resizeHandles[f]}E?E=!1:R+=H?s.margins[0]/2:s.margins[0];H=0!==s.config[f][g]}else if(s.resizeHandles[f]){const e=d.getElement(s.resizeHandles[f]);e.parentNode.removeChild(e);delete s.resizeHandles[f]}for(let t=0;t=y.length);++t){n&&(l+=10);n=0!==s.config[f+t][g];y[f+t-1]>-1&&y[f+t]>-1&&(l+=s.margins[0]);l+=y[f+t]}}k(t,\"visibility\",\"\");let r=i.align>>s.alignBits&15,c=i.ps[e];l=c&&i.set[e]){k(t,s.size,c+\"px\")&&G(i,1);i.set[e]=!1}i.size[e]=c;i.psize[e]=c}else{const o=i.margin[e],f=Math.max(0,l-o),r=0===e&&i.sc[e];if(_(t)||!r&&l===c&&!i.layout)if(i.fs[e])e===m&&k(t,s.size,i.fs[e]-o+\"px\");else{k(t,s.size,\"\")&&G(i,1);i.set&&(i.set[e]=!1)}else if(k(t,s.size,f+\"px\")){G(i,1);i.set[e]=!0}n=R;i.size[e]=f;i.psize[e]=l}if(o)if(N){k(t,s.left,\"10px\");\"absolute\"!==d.css(t,\"position\")&&(t.style.position=\"relative\")}else k(t,s.left,\"0px\");else k(t,s.left,n+\"px\");if(1===e){t.wtResize&&t.wtResize(t,i.set[m]?Math.round(i.size[m]):-1,i.set[1]?Math.round(i.size[1]):-1,!0);i.dirty=0}}}y[f]>-1&&(R+=y[f])}if(s.resizeHandles.length>W){for(const e of s.resizeHandles)if(e){const t=d.getElement(e);t.parentNode.removeChild(t)}s.resizeHandles.length=W}i.querySelectorAll(`:scope > .${n.handleClass}`).forEach((function(e){e.style[s.size]=l-s.margins[2]-s.margins[1]+\"px\"}))}(e,i);return!0};this.contains=function(e){const i=d.getElement(t),s=d.getElement(e.getId());return!(!i||!s)&&d.contains(i,s)};this.WT=d})"); } static WJavaScriptPreamble appjs1() { @@ -749,7 +823,7 @@ static WJavaScriptPreamble appjs1() { JavaScriptScope.ApplicationScope, JavaScriptObjectType.JavaScriptObject, "layouts2", - "new function(){const e=[];let t=!1;const i=this;let s=!1;this.find=function(e){const t=document.getElementById(e);return t?t.wtLayout:null};this.setDirty=function(e){const t=this.find(e);if(t){t.setDirty();i.scheduleAdjust()}};this.setElementDirty=function(e){let t=e;e=e.parentNode;for(;e&&e!==document.body;){const i=e.wtLayout;i&&i.setElDirty(t);t=e;e=e.parentNode}};this.setChildLayoutsDirty=function(e,t){for(const i of e.descendants){if(t){const s=e.WT.getElement(i.getId());if(s&&!e.WT.contains(t,s))continue}i.setDirty()}};this.add=function(t){!function e(t,i){for(let s=0,n=t.length;s=6)){n=!0;setTimeout((function(){i.adjust()}),0)}}};this.adjust=function(o,l){if(o){const e=this.find(o);e&&e.setItemsDirty(l);i.scheduleAdjust()}else{n=!1;if(!t){t=!0;f(e,0);r(e,0);f(e,1);r(e,1);t=!1;s=!1}}function f(e,t){for(const i of e){f(i.descendants,t);1===t&&s?i.setDirty():0===t&&i.setAllDirty();i.measure(t)}}function r(e,t){for(let i=0,s=e.length;i=6)){n=!0;setTimeout((function(){i.adjust()}),0)}}};this.adjust=function(o,f){if(o){const e=this.find(o);e&&e.setItemsDirty(f);i.scheduleAdjust()}else{n=!1;if(!t){t=!0;l(e,0);r(e,0);l(e,1);r(e,1);t=!1;s=!1}}function l(e,t){for(const i of e){l(i.descendants,t);1===t&&s?i.setDirty():0===t&&i.setAllDirty();i.measure(t)}}function r(e,t){for(let i=0,s=e.length;i result, WApplication app) { if (this.sourcesChanged_) { for (int i = 0; i < this.sourcesRendered_; ++i) { media.callJavaScript( - "Wt4_11_1.remove('" + this.mediaId_ + "s" + String.valueOf(i) + "');", true); + "Wt4.11.2.remove('" + this.mediaId_ + "s" + String.valueOf(i) + "');", true); } this.sourcesRendered_ = 0; for (int i = 0; i < this.sources_.size(); ++i) { @@ -378,7 +378,7 @@ void updateMediaDom(final DomElement element, boolean all) { if (all && this.alternative_ != null) { element.setAttribute( "onerror", - "if(event.target.error && event.target.error.code==event.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED){while (this.hasChildNodes())if (Wt4_11_1.hasTag(this.firstChild,'SOURCE')){this.removeChild(this.firstChild);}else{this.parentNode.insertBefore(this.firstChild, this);}this.style.display= 'none';}"); + "if(event.target.error && event.target.error.code==event.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED){while (this.hasChildNodes())if (Wt4.11.2.hasTag(this.firstChild,'SOURCE')){this.removeChild(this.firstChild);}else{this.parentNode.insertBefore(this.firstChild, this);}this.style.display= 'none';}"); } if (all || this.flagsChanged_) { if (!all || this.flags_.contains(PlayerOption.Controls)) { @@ -504,7 +504,7 @@ private void renderSource( if (isLast && this.alternative_ != null) { element.setAttribute( "onerror", - "var media = this.parentNode;if(media){while (media && media.children.length)if (Wt4_11_1.hasTag(media.firstChild,'SOURCE')){media.removeChild(media.firstChild);}else{media.parentNode.insertBefore(media.firstChild, media);}media.style.display= 'none';}"); + "var media = this.parentNode;if(media){while (media && media.children.length)if (Wt4.11.2.hasTag(media.firstChild,'SOURCE')){media.removeChild(media.firstChild);}else{media.parentNode.insertBefore(media.firstChild, media);}media.style.display= 'none';}"); } else { element.setAttribute("onerror", ""); } @@ -537,7 +537,7 @@ private void loadJavaScript() { app.loadJavaScript("js/WAbstractMedia.js", wtjs1()); this.setJavaScriptMember( " WAbstractMedia", - "new Wt4_11_1.WAbstractMedia(" + app.getJavaScriptClass() + "," + this.getJsRef() + ");"); + "new Wt4.11.2.WAbstractMedia(" + app.getJavaScriptClass() + "," + this.getJsRef() + ");"); } } diff --git a/src/eu/webtoolkit/jwt/WAbstractSpinBox.java b/src/eu/webtoolkit/jwt/WAbstractSpinBox.java index 317e9021..9392bf0c 100644 --- a/src/eu/webtoolkit/jwt/WAbstractSpinBox.java +++ b/src/eu/webtoolkit/jwt/WAbstractSpinBox.java @@ -275,7 +275,7 @@ private void defineJavaScript() { WApplication app = WApplication.getInstance(); app.loadJavaScript("js/WSpinBox.js", wtjs1()); StringBuilder ss = new StringBuilder(); - ss.append("new Wt4_11_1.WSpinBox(") + ss.append("new Wt4.11.2.WSpinBox(") .append(app.getJavaScriptClass()) .append(",") .append(this.getJsRef()) diff --git a/src/eu/webtoolkit/jwt/WAnchor.java b/src/eu/webtoolkit/jwt/WAnchor.java index a6924da8..d16a39f6 100644 --- a/src/eu/webtoolkit/jwt/WAnchor.java +++ b/src/eu/webtoolkit/jwt/WAnchor.java @@ -409,7 +409,7 @@ static void renderUrlResolution(WWidget widget, final DomElement element, boolea if (all) { element.setProperty(Property.Class, StringUtils.addWord(widget.getStyleClass(), "Wt-rr")); } else { - element.callJavaScript("Wt4_11_1.$('" + widget.getId() + "').classList.add('Wt-rr');"); + element.callJavaScript("Wt4.11.2.$('" + widget.getId() + "').classList.add('Wt-rr');"); } } diff --git a/src/eu/webtoolkit/jwt/WApplication.java b/src/eu/webtoolkit/jwt/WApplication.java index 6a6c967a..900924e8 100644 --- a/src/eu/webtoolkit/jwt/WApplication.java +++ b/src/eu/webtoolkit/jwt/WApplication.java @@ -85,7 +85,7 @@ *

  • support for server-initiated updates with {@link WApplication#enableUpdates(boolean * enabled) enableUpdates()} *
  • localization information and message resources bundles, with {@link - * WApplication#setLocale(Locale locale) setLocale()} and {@link + * WApplication#setLocale(Locale locale, boolean doRefresh) setLocale()} and {@link * WApplication#setLocalizedStrings(WLocalizedStrings translator) setLocalizedStrings()} * */ @@ -896,8 +896,9 @@ public void setLocalizedStrings(final WLocalizedStrings translator) { * *

    By passing an empty locale, the default locale is chosen. * - *

    When the locale is changed, {@link WApplication#refresh() refresh()} is called, which will - * resolve the strings of the current user-interface in the new locale. + *

    By default, when the locale is changed, {@link WApplication#refresh() refresh()} is called, + * which will resolve the strings of the current user-interface in the new locale. This can be + * changed by having the doRefresh parameter set to false. * *

    At construction, the locale is copied from the environment ({@link * WEnvironment#getLocale()}), and this is the locale that was configured by the user in his @@ -908,18 +909,22 @@ public void setLocalizedStrings(final WLocalizedStrings translator) { * @see WApplication#getLocalizedStrings() * @see WString#tr(String key) */ - public void setLocale(final Locale locale) { + public void setLocale(final Locale locale, boolean doRefresh) { this.locale_ = locale; this.localeChanged_ = true; - this.refresh(); + if (doRefresh) { + this.refresh(); + } } /** - * Returns the current locale. - * - *

    + * Changes the locale. * - * @see WApplication#setLocale(Locale locale) + *

    Calls {@link #setLocale(Locale locale, boolean doRefresh) setLocale(locale, true)} */ + public final void setLocale(final Locale locale) { + setLocale(locale, true); + } + /** Returns the current locale. */ public Locale getLocale() { return this.locale_; } @@ -2261,9 +2266,9 @@ public void setLoadingIndicator(WLoadingIndicator indicator) { if (this.loadingIndicator_ != null) { this.domRoot_.addWidget(indicator); this.showLoadJS.setJavaScript( - "function(o,e) {Wt4_11_1.inline('" + this.loadingIndicator_.getId() + "');}"); + "function(o,e) {Wt4.11.2.inline('" + this.loadingIndicator_.getId() + "');}"); this.hideLoadJS.setJavaScript( - "function(o,e) {Wt4_11_1.hide('" + this.loadingIndicator_.getId() + "');}"); + "function(o,e) {Wt4.11.2.hide('" + this.loadingIndicator_.getId() + "');}"); this.loadingIndicator_.hide(); } } @@ -2669,7 +2674,7 @@ protected void enableAjax() { this.domRoot2_.enableAjax(); } this.doJavaScript( - "Wt4_11_1.ajaxInternalPaths(" + "Wt4.11.2.ajaxInternalPaths(" + WWebWidget.jsStringLiteral(this.resolveRelativeUrl(this.getBookmarkUrl("/"))) + ");"); } @@ -3047,7 +3052,7 @@ private void streamJavaScriptPreamble(final StringBuilder out, boolean all) { String scope = preamble.scope == JavaScriptScope.ApplicationScope ? this.getJavaScriptClass() - : "Wt4_11_1"; + : "Wt4.11.2"; if (preamble.type == JavaScriptObjectType.JavaScriptFunction) { out.append(scope) .append('.') diff --git a/src/eu/webtoolkit/jwt/WBootstrap2Theme.java b/src/eu/webtoolkit/jwt/WBootstrap2Theme.java index cd04f47c..ee70ad6a 100644 --- a/src/eu/webtoolkit/jwt/WBootstrap2Theme.java +++ b/src/eu/webtoolkit/jwt/WBootstrap2Theme.java @@ -436,7 +436,7 @@ public void applyValidationStyle( app.loadJavaScript("js/BootstrapValidate.js", wtjs2()); if (app.getEnvironment().hasAjax()) { StringBuilder js = new StringBuilder(); - js.append("Wt4_11_1.setValidationState(") + js.append("Wt4.11.2.setValidationState(") .append(widget.getJsRef()) .append(",") .append(validation.getState() == ValidationState.Valid) diff --git a/src/eu/webtoolkit/jwt/WBootstrap3Theme.java b/src/eu/webtoolkit/jwt/WBootstrap3Theme.java index dfbce730..2c08f2bd 100644 --- a/src/eu/webtoolkit/jwt/WBootstrap3Theme.java +++ b/src/eu/webtoolkit/jwt/WBootstrap3Theme.java @@ -479,7 +479,7 @@ public void applyValidationStyle( app.loadJavaScript("js/BootstrapValidate.js", wtjs2()); if (app.getEnvironment().hasAjax()) { StringBuilder js = new StringBuilder(); - js.append("Wt4_11_1.setValidationState(") + js.append("Wt4.11.2.setValidationState(") .append(widget.getJsRef()) .append(",") .append(validation.getState() == ValidationState.Valid) diff --git a/src/eu/webtoolkit/jwt/WBootstrap5Theme.java b/src/eu/webtoolkit/jwt/WBootstrap5Theme.java index b087d9d0..76f092bd 100644 --- a/src/eu/webtoolkit/jwt/WBootstrap5Theme.java +++ b/src/eu/webtoolkit/jwt/WBootstrap5Theme.java @@ -141,10 +141,10 @@ public void apply(WWidget widget, WWidget child, int widgetRole) { { WApplication app = WApplication.getInstance(); WIconPair iconPair = ObjectUtils.cast(child, WIconPair.class); - iconPair.getIcon1().setInline(false); - iconPair.getIcon1().setImageLink(new WLink(app.getOnePixelGifUrl())); - iconPair.getIcon2().setInline(false); - iconPair.getIcon2().setImageLink(new WLink(app.getOnePixelGifUrl())); + iconPair.getUriIcon1().setInline(false); + iconPair.getUriIcon1().setImageLink(new WLink(app.getOnePixelGifUrl())); + iconPair.getUriIcon2().setInline(false); + iconPair.getUriIcon2().setImageLink(new WLink(app.getOnePixelGifUrl())); iconPair.addStyleClass("Wt-collapse-button"); break; } @@ -470,7 +470,7 @@ public void applyValidationStyle( app.loadJavaScript("js/BootstrapValidate.js", wtjs2()); if (app.getEnvironment().hasAjax()) { StringBuilder js = new StringBuilder(); - js.append("Wt4_11_1.setValidationState(") + js.append("Wt4.11.2.setValidationState(") .append(widget.getJsRef()) .append(",") .append(validation.getState() == ValidationState.Valid) diff --git a/src/eu/webtoolkit/jwt/WCanvasPaintDevice.java b/src/eu/webtoolkit/jwt/WCanvasPaintDevice.java index 8a057c8e..98e2b31c 100644 --- a/src/eu/webtoolkit/jwt/WCanvasPaintDevice.java +++ b/src/eu/webtoolkit/jwt/WCanvasPaintDevice.java @@ -192,7 +192,7 @@ public void drawImage( } int imageIndex = this.createImage(imgUri); this.js_ - .append("Wt4_11_1.gfxUtils.drawImage(ctx,images[") + .append("Wt4.11.2.gfxUtils.drawImage(ctx,images[") .append(String.valueOf(imageIndex)) .append("],") .append(WWebWidget.jsStringLiteral(imgUri)) @@ -214,7 +214,7 @@ public void drawPath(final WPainterPath path) { if (path.isJavaScriptBound()) { this.renderStateChanges(true); this.js_ - .append("Wt4_11_1.gfxUtils.drawPath(ctx,") + .append("Wt4.11.2.gfxUtils.drawPath(ctx,") .append(path.getJsRef()) .append(",") .append(this.currentNoBrush_ ? "false" : "true") @@ -232,7 +232,7 @@ public void drawStencilAlongPath( final WPainterPath stencil, final WPainterPath path, boolean softClipping) { this.renderStateChanges(true); this.js_ - .append("Wt4_11_1") + .append("Wt4.11.2") .append(".gfxUtils.drawStencilAlongPath(ctx,") .append(stencil.getJsRef()) .append(",") @@ -250,7 +250,7 @@ public void drawRect(final WRectF rectangle) { if (rectangle.isJavaScriptBound()) { this.renderStateChanges(true); this.js_ - .append("Wt4_11_1") + .append("Wt4.11.2") .append(".gfxUtils.drawRect(ctx,") .append(rectangle.getJsRef()) .append(",") @@ -283,7 +283,7 @@ public void drawText( case Html5Text: { this.js_ - .append("Wt4_11_1.gfxUtils.drawText(ctx,") + .append("Wt4.11.2.gfxUtils.drawText(ctx,") .append(rect.getJsRef()) .append(',') .append(String.valueOf(EnumUtils.valueOf(flags))) @@ -352,7 +352,7 @@ public void drawText( .append(");"); if (this.currentPen_.isJavaScriptBound()) { this.js_ - .append("ctx.fillStyle=Wt4_11_1.gfxUtils.css_text(") + .append("ctx.fillStyle=Wt4.11.2.gfxUtils.css_text(") .append(this.currentPen_.getJsRef()) .append(".color);"); } else { @@ -426,7 +426,7 @@ public void drawTextOnPath( double lineHeight, boolean softClipping) { this.renderStateChanges(true); - this.js_.append("Wt4_11_1.gfxUtils.drawTextOnPath(ctx,["); + this.js_.append("Wt4.11.2.gfxUtils.drawTextOnPath(ctx,["); for (int i = 0; i < text.size(); ++i) { if (i != 0) { this.js_.append(','); @@ -481,7 +481,7 @@ public void render( final String canvasId, DomElement text, final String updateAreasJs) { - String canvasVar = "Wt4_11_1.getElement('" + canvasId + "')"; + String canvasVar = "Wt4.11.2.getElement('" + canvasId + "')"; String paintedWidgetObjRef = paintedWidgetJsRef + ".wtObj"; StringBuilder tmp = new StringBuilder(); tmp.append(";(function(){"); @@ -659,7 +659,7 @@ private void renderStateChanges(boolean resetPathTranslation) { final WPainterPath p = this.getPainter().getClipPath(); if (!p.isEmpty()) { this.js_ - .append("Wt4_11_1") + .append("Wt4.11.2") .append(".gfxUtils.setClipPath(ctx,") .append(p.getJsRef()) .append(",") @@ -668,7 +668,7 @@ private void renderStateChanges(boolean resetPathTranslation) { .append(this.getPainter().hasClipping() ? "true" : "false") .append(");"); } else { - this.js_.append("Wt4_11_1").append(".gfxUtils.removeClipPath(ctx);"); + this.js_.append("Wt4.11.2").append(".gfxUtils.removeClipPath(ctx);"); } this.currentClipTransform_.assign(t); this.currentClipPath_.assign(p); @@ -745,7 +745,7 @@ && fequal(f.getM22(), this.currentTransform_.getM22())) { } else { if (this.getPainter().getPen().isJavaScriptBound()) { this.js_ - .append("ctx.strokeStyle=Wt4_11_1.gfxUtils.css_text(") + .append("ctx.strokeStyle=Wt4.11.2.gfxUtils.css_text(") .append(this.getPainter().getPen().getJsRef()) .append(".color);"); } else { @@ -836,7 +836,7 @@ && fequal(f.getM22(), this.currentTransform_.getM22())) { } else { if (this.currentBrush_.isJavaScriptBound()) { this.js_ - .append("ctx.fillStyle=Wt4_11_1.gfxUtils.css_text(") + .append("ctx.fillStyle=Wt4.11.2.gfxUtils.css_text(") .append(this.currentBrush_.getJsRef()) .append(".color);"); } else { diff --git a/src/eu/webtoolkit/jwt/WClientGLWidget.java b/src/eu/webtoolkit/jwt/WClientGLWidget.java index 980df3f7..438ea8d3 100644 --- a/src/eu/webtoolkit/jwt/WClientGLWidget.java +++ b/src/eu/webtoolkit/jwt/WClientGLWidget.java @@ -2401,7 +2401,7 @@ public void initJavaScriptMatrix4(final WGLWidget.JavaScriptMatrix4x4 mat) { public void setJavaScriptMatrix4( final WGLWidget.JavaScriptMatrix4x4 jsm, final javax.vecmath.Matrix4f m) { - this.js_.append("Wt4_11_1.glMatrix.mat4.set("); + this.js_.append("Wt4.11.2.glMatrix.mat4.set("); javax.vecmath.Matrix4f t = WebGLUtils.transpose(m); WebGLUtils.renderfv(this.js_, t, JsArrayType.Float32Array); this.js_.append(", ").append(jsm.getJsRef()).append(");"); @@ -2548,7 +2548,7 @@ public void restoreContext(final String jsRef) { public void render(final String jsRef, EnumSet flags) { if (flags.contains(RenderFlag.Full)) { StringWriter tmp = new StringWriter(); - tmp.append("{\nvar o = new Wt4_11_1.WGLWidget(") + tmp.append("{\nvar o = new Wt4.11.2.WGLWidget(") .append(WApplication.getInstance().getJavaScriptClass()) .append(",") .append(jsRef) diff --git a/src/eu/webtoolkit/jwt/WCssStyleSheet.java b/src/eu/webtoolkit/jwt/WCssStyleSheet.java index 7979e9b2..3b3f2be7 100644 --- a/src/eu/webtoolkit/jwt/WCssStyleSheet.java +++ b/src/eu/webtoolkit/jwt/WCssStyleSheet.java @@ -179,14 +179,14 @@ public void cssText(final StringBuilder out, boolean all) { public void javaScriptUpdate(WApplication app, final StringBuilder js, boolean all) { if (!all) { for (int i = 0; i < this.rulesRemoved_.size(); ++i) { - js.append("Wt4_11_1.removeCssRule("); + js.append("Wt4.11.2.removeCssRule("); DomElement.jsStringLiteral(js, this.rulesRemoved_.get(i), '\''); js.append(");"); } this.rulesRemoved_.clear(); for (Iterator i_it = this.rulesModified_.iterator(); i_it.hasNext(); ) { WCssRule i = i_it.next(); - js.append("{ var d= Wt4_11_1.getCssRule("); + js.append("{ var d= Wt4.11.2.getCssRule("); DomElement.jsStringLiteral(js, i.getSelector(), '\''); js.append(");if(d){"); DomElement d = DomElement.updateGiven("d", DomElementType.SPAN); @@ -205,7 +205,7 @@ public void javaScriptUpdate(WApplication app, final StringBuilder js, boolean a final List toProcess = this.rules_; for (int i = 0; i < toProcess.size(); ++i) { WCssRule rule = toProcess.get(i); - js.append("Wt4_11_1.addCss('").append(rule.getSelector()).append("',"); + js.append("Wt4.11.2.addCss('").append(rule.getSelector()).append("',"); DomElement.jsStringLiteral(js, rule.getDeclarations(), '\''); js.append(");\n"); } @@ -213,7 +213,7 @@ public void javaScriptUpdate(WApplication app, final StringBuilder js, boolean a final List toProcess = this.rulesAdded_; for (int i = 0; i < toProcess.size(); ++i) { final WCssRule rule = toProcess.get(i); - js.append("Wt4_11_1.addCss('").append(rule.getSelector()).append("',"); + js.append("Wt4.11.2.addCss('").append(rule.getSelector()).append("',"); DomElement.jsStringLiteral(js, rule.getDeclarations(), '\''); js.append(");\n"); } @@ -226,7 +226,7 @@ public void javaScriptUpdate(WApplication app, final StringBuilder js, boolean a StringBuilder css = new StringBuilder(); this.cssText(css, all); if (!(css.length() == 0)) { - js.append("Wt4_11_1.addCssText("); + js.append("Wt4.11.2.addCssText("); DomElement.jsStringLiteral(js, css.toString(), '\''); js.append(");\n"); } diff --git a/src/eu/webtoolkit/jwt/WCssTheme.java b/src/eu/webtoolkit/jwt/WCssTheme.java index dffb06c5..26ba8eb2 100644 --- a/src/eu/webtoolkit/jwt/WCssTheme.java +++ b/src/eu/webtoolkit/jwt/WCssTheme.java @@ -569,7 +569,7 @@ public void applyValidationStyle( app.loadJavaScript("js/CssThemeValidate.js", wtjs2()); if (app.getEnvironment().hasAjax()) { StringBuilder js = new StringBuilder(); - js.append("Wt4_11_1.setValidationState(") + js.append("Wt4.11.2.setValidationState(") .append(widget.getJsRef()) .append(",") .append(validation.getState() == ValidationState.Valid) diff --git a/src/eu/webtoolkit/jwt/WDateEdit.java b/src/eu/webtoolkit/jwt/WDateEdit.java index a993ca15..730a680a 100644 --- a/src/eu/webtoolkit/jwt/WDateEdit.java +++ b/src/eu/webtoolkit/jwt/WDateEdit.java @@ -346,7 +346,7 @@ private void defineJavaScript() { WApplication app = WApplication.getInstance(); app.loadJavaScript("js/WDateEdit.js", wtjs1()); String jsObj = - "new Wt4_11_1.WDateEdit(" + "new Wt4.11.2.WDateEdit(" + app.getJavaScriptClass() + "," + this.getJsRef() diff --git a/src/eu/webtoolkit/jwt/WDateValidator.java b/src/eu/webtoolkit/jwt/WDateValidator.java index d09005cc..ab643fd2 100644 --- a/src/eu/webtoolkit/jwt/WDateValidator.java +++ b/src/eu/webtoolkit/jwt/WDateValidator.java @@ -304,7 +304,7 @@ public WString getInvalidTooLateText() { public String getJavaScriptValidate() { loadJavaScript(WApplication.getInstance()); StringBuilder js = new StringBuilder(); - js.append("new Wt4_11_1.WDateValidator(").append(this.isMandatory()).append(",["); + js.append("new Wt4.11.2.WDateValidator(").append(this.isMandatory()).append(",["); for (int i = 0; i < this.formats_.size(); ++i) { WDate.RegExpInfo r = WDate.formatToRegExp(this.formats_.get(i)); if (i != 0) { diff --git a/src/eu/webtoolkit/jwt/WDialog.java b/src/eu/webtoolkit/jwt/WDialog.java index 414bfb50..675a74f6 100644 --- a/src/eu/webtoolkit/jwt/WDialog.java +++ b/src/eu/webtoolkit/jwt/WDialog.java @@ -398,7 +398,7 @@ public void setResizable(boolean resizable) { Resizable.loadJavaScript(WApplication.getInstance()); this.setJavaScriptMember( " Resizable", - "(new Wt4_11_1.Resizable(Wt4_11_1," + "(new Wt4.11.2.Resizable(Wt4.11.2," + this.getJsRef() + ")).onresize(function(w, h, done) {var obj = " + this.getJsRef() @@ -548,6 +548,10 @@ public void setHidden(boolean hidden, final WAnimation animation) { } DialogCover c = this.getCover(); if (!hidden) { + if (!WWebWidget.canOptimizeUpdates() || this.isRendered()) { + this.doJavaScript( + "var o = " + this.getJsRef() + ";if (o && o.wtObj) o.wtObj.centerDialog();"); + } if (c != null) { c.pushDialog(this, animation); } @@ -699,7 +703,7 @@ protected void render(EnumSet flags) { } } this.doJavaScript( - "new Wt4_11_1.WDialog(" + "new Wt4.11.2.WDialog(" + app.getJavaScriptClass() + "," + this.getJsRef() diff --git a/src/eu/webtoolkit/jwt/WDoubleValidator.java b/src/eu/webtoolkit/jwt/WDoubleValidator.java index 204dff65..1d9fc828 100644 --- a/src/eu/webtoolkit/jwt/WDoubleValidator.java +++ b/src/eu/webtoolkit/jwt/WDoubleValidator.java @@ -250,7 +250,7 @@ public boolean isIgnoreTrailingSpaces() { public String getJavaScriptValidate() { loadJavaScript(WApplication.getInstance()); StringBuilder js = new StringBuilder(); - js.append("new Wt4_11_1.WDoubleValidator(") + js.append("new Wt4.11.2.WDoubleValidator(") .append(this.isMandatory()) .append(',') .append(this.ignoreTrailingSpaces_) diff --git a/src/eu/webtoolkit/jwt/WEmailEdit.java b/src/eu/webtoolkit/jwt/WEmailEdit.java index 3c232d47..d921fd45 100644 --- a/src/eu/webtoolkit/jwt/WEmailEdit.java +++ b/src/eu/webtoolkit/jwt/WEmailEdit.java @@ -267,7 +267,7 @@ protected void render(EnumSet flags) { super.render(flags); WApplication app = WApplication.getInstance(); app.loadJavaScript("js/WEmailEdit.js", wtjs1()); - super.setJavaScriptMember("wtEncodeValue", "Wt4_11_1.encodeEmailValue"); + super.setJavaScriptMember("wtEncodeValue", "Wt4.11.2.encodeEmailValue"); } void updateDom(final DomElement element, boolean all) { diff --git a/src/eu/webtoolkit/jwt/WEmailValidator.java b/src/eu/webtoolkit/jwt/WEmailValidator.java index 2ea46d9f..630c21c1 100644 --- a/src/eu/webtoolkit/jwt/WEmailValidator.java +++ b/src/eu/webtoolkit/jwt/WEmailValidator.java @@ -213,7 +213,7 @@ public WString getPattern() { public String getJavaScriptValidate() { loadJavaScript(WApplication.getInstance()); StringBuilder js = new StringBuilder(); - js.append("new Wt4_11_1.WEmailValidator(") + js.append("new Wt4.11.2.WEmailValidator(") .append(this.isMandatory()) .append(',') .append(this.isMultiple()) diff --git a/src/eu/webtoolkit/jwt/WEnvironment.java b/src/eu/webtoolkit/jwt/WEnvironment.java index 4bc69476..27f779a0 100644 --- a/src/eu/webtoolkit/jwt/WEnvironment.java +++ b/src/eu/webtoolkit/jwt/WEnvironment.java @@ -52,7 +52,7 @@ public class WEnvironment { /** Wt's JavaScript scope. */ public static String getJavaScriptWtScope() { - return "Wt4_11_1"; + return "Wt4.11.2"; } /** * Parameters passed to the application. @@ -253,7 +253,7 @@ public double getDpiScale() { * *

    * - * @see WApplication#setLocale(Locale locale) + * @see WApplication#setLocale(Locale locale, boolean doRefresh) */ public Locale getLocale() { return this.locale_; @@ -447,7 +447,7 @@ public String getDeploymentPath() { *

    Example: "1.99.2" */ public static String getLibraryVersion() { - return "4.11.1"; + return "4.11.2"; } // public void libraryVersion(final bad java simple ref int series, final bad java simple ref int // major, final bad java simple ref int minor) ; diff --git a/src/eu/webtoolkit/jwt/WFileDropWidget.java b/src/eu/webtoolkit/jwt/WFileDropWidget.java index 52a7ae89..e0315d95 100644 --- a/src/eu/webtoolkit/jwt/WFileDropWidget.java +++ b/src/eu/webtoolkit/jwt/WFileDropWidget.java @@ -570,6 +570,14 @@ public void setAcceptDirectories(boolean enable, boolean recursive) { this.acceptDirectories_ = enable; this.acceptDirectoriesRecursive_ = recursive; this.updateFlags_.set(BIT_ACCEPTDROPS_CHANGED); + if (!this.acceptDirectories_ && this.onClickFilePicker_ == FilePickerType.DirectorySelection) { + logger.warn( + new StringWriter() + .append( + "setAcceptDirectories: Reverting the onClickFilePicker to FileSelection since this widget no longer accepts directories.") + .toString()); + this.setOnClickFilePicker(FilePickerType.FileSelection); + } this.repaint(); } /** @@ -600,11 +608,26 @@ public boolean isAcceptDirectoriesRecursive() { * Set the type of file picker that is opened when a user clicks the widget. * *

    The default is {@link FilePickerType#FileSelection}. + * + *

    When {@link FilePickerType#None} is passed, no file picker will be shown. Files or + * directories can still be dropped in, if {@link WFileDropWidget#setAcceptDrops(boolean enable) + * setAcceptDrops()} is set to true (which by default it is). Also note that in this + * case, the methods {@link WFileDropWidget#openFilePicker() openFilePicker()} and {@link + * WFileDropWidget#openDirectoryPicker() openDirectoryPicker()} can still be used to open a picker + * by redirecting clicks from other buttons. */ public void setOnClickFilePicker(FilePickerType type) { if (this.onClickFilePicker_ == type) { return; } + if (type == FilePickerType.DirectorySelection && !this.acceptDirectories_) { + logger.error( + new StringWriter() + .append( + "setOnClickFilePicker: Cannot configure directory filepicker because this widget does not accept directories.") + .toString()); + return; + } this.onClickFilePicker_ = type; this.updateFlags_.set(BIT_ONCLICKFILEPICKER_CHANGED); this.repaint(); @@ -726,7 +749,7 @@ String renderRemoveJs(boolean recursive) { if (this.isRendered()) { String result = this.getJsRef() + ".destructor();"; if (!recursive) { - result += "Wt4_11_1.remove('" + this.getId() + "');"; + result += "Wt4.11.2.remove('" + this.getId() + "');"; } return result; } else { @@ -785,10 +808,21 @@ void updateDom(final DomElement element, boolean all) { this.getJsRef() + ".setChunkSize(" + String.valueOf(this.chunkSize_) + ");"); } if (this.updateFlags_.get(BIT_ONCLICKFILEPICKER_CHANGED) || all) { - String type = - this.onClickFilePicker_ == FilePickerType.FileSelection - ? "file-selection" - : "directory-selection"; + String type = "file-selection"; + if (this.onClickFilePicker_ == FilePickerType.None) { + type = "none"; + } else { + if (this.onClickFilePicker_ == FilePickerType.DirectorySelection) { + type = "directory-selection"; + } else { + if (this.onClickFilePicker_ != FilePickerType.FileSelection) { + logger.warn( + new StringWriter() + .append("Unknown FilePickerType, falling back to FileSelection.") + .toString()); + } + } + } this.doJavaScript(this.getJsRef() + ".setOnClickFilePicker(\"" + type + "\");"); } this.updateFlags_.clear(); @@ -848,7 +882,7 @@ private void setup() { String maxFileSize = String.valueOf(WApplication.getInstance().getMaximumRequestSize()); this.setJavaScriptMember( " WFileDropWidget", - "new Wt4_11_1.WFileDropWidget(" + "new Wt4.11.2.WFileDropWidget(" + app.getJavaScriptClass() + "," + this.getJsRef() @@ -1162,7 +1196,7 @@ static WJavaScriptPreamble wtjs1() { JavaScriptScope.WtClassScope, JavaScriptObjectType.JavaScriptConstructor, "WFileDropWidget", - "(function(e,t,n){t.wtLObj=this;const i=this,o=e.WT;let s=\"Wt-dropzone-hover\";const r=\"Wt-dropzone-indication\",l=\"Wt-dropzone-dragstyle\",d=[];let a=!1,c=!0,u=!1,f=!1,p=!1,h=!1,m=null,y=0,g=0;const v=document.createElement(\"input\");v.type=\"file\";v.setAttribute(\"multiple\",\"multiple\");v.style.display=\"none\";t.hiddenInput=v;t.appendChild(v);const w=document.createElement(\"input\");w.type=\"file\";w.setAttribute(\"multiple\",\"multiple\");w.style.display=\"none\";window.document.body.appendChild(w);t.serverFileInput=w;const k=document.createElement(\"input\");k.type=\"file\";k.setAttribute(\"multiple\",\"multiple\");k.setAttribute(\"webkitdirectory\",\"webkitdirectory\");k.style.display=\"none\";window.document.body.appendChild(k);t.serverDirInput=k;const b=document.createElement(\"div\");b.classList.add(\"Wt-dropcover\");document.body.appendChild(b);this.validFileCheck=function(e,t,n){const i=new FileReader;i.onload=function(){t(!0,n,e)};i.onerror=function(){t(!1,n,e)};i.readAsText(e.file.slice(0,32))};t.setAcceptDrops=function(e){c=e};t.setAcceptDirectories=function(e,t){u=e;f=t};t.setDropIndication=function(e){p=e};t.setDropForward=function(e){h=e};t.ondragenter=function(e){if(c){if(function(e){const t=e.dataTransfer?.items??null,n=null!==t&&Array.prototype.some.call(t,(e=>\"file\"===e.kind)),i=e.dataTransfer?.types??null,o=null!==i&&i.includes(\"Files\");return n||o}(e)){0===g&&i.setPageHoverStyle();g=2;i.setWidgetHoverStyle(!0)}e.stopPropagation()}};t.ondragleave=function(e){const t=e.clientX,n=e.clientY;let o=document.elementFromPoint(t,n);0===t&&0===n&&(o=null);if(o!==b)i.resetDragDrop();else{i.setWidgetHoverStyle(!1);g=1}};t.ondragover=function(e){e.preventDefault()};const F=function(e){if((p||h)&&\"none\"!==o.css(t,\"display\")&&c){g=1;i.setPageHoverStyle()}};document.body.addEventListener(\"dragenter\",F);b.ondragover=function(e){e.preventDefault();e.stopPropagation()};b.ondragleave=function(e){c&&1===g&&i.resetDragDrop()};b.ondrop=function(e){e.preventDefault();h?t.ondrop(e):i.resetDragDrop()};t.ondrop=function(e){e.preventDefault();if(c){i.resetDragDrop();0!==e.dataTransfer.files.length&&i.addDataTransferItems(Array.from(e.dataTransfer.items))}};this.addDataTransferItems=async function(n){const i=[],o=n.map((e=>e.webkitGetAsEntry()));for(const e of o){const t=D(e);if(e.isFile){const n=await C(e);t.type=n.type;t.size=n.size;const i=L(n);t.id=i.id}else if(e.isDirectory){if(!u){console.warn(\"directory drop not enabled, ignoring entry\",e);continue}t.contents=[];await S(e,t,f)}i.push(t)}if(0!==i.length){console.log(\"All newKeys: \",i);e.emit(t,\"dropsignal\",JSON.stringify(i))}};this.addFiles=function(n){const i=[];for(const e of n){const t=L(e),n={};n.id=t.id;n.filename=t.file.name;n.path=t.file.name;n.type=t.file.type;n.size=t.file.size;i.push(n)}e.emit(t,\"dropsignal\",JSON.stringify(i))};async function S(e,t,n){const i=await function(e){return new Promise((t=>{e.createReader().readEntries((function(e){t(e)}))}))}(e);for(let e=0;e{e.file((function(e){t(e)}))}))}function L(e){const t=new Object;t.id=Math.floor(Math.random()*Math.pow(2,31));t.file=e;d.push(t);return t}t.addEventListener(\"click\",(function(){if(c){v.value=\"\";v.click()}}));t.markForSending=function(e){for(const t of e){const e=t.id;for(const t of d)if(t.id===e){t.ready=!0;break}}a||d.length>0&&d[0].ready&&i.requestSend()};this.requestSend=function(){if(d[0].skip)i.uploadFinished(null);else{a=!0;e.emit(t,\"requestsend\",d[0].id)}};t.send=function(o,s){const r=d[0];if(r.file.size>n){e.emit(t,\"filetoolarge\",r.file.size);i.uploadFinished(null)}else if(\"boolean\"==typeof t.wtUseCustomSend){if(\"function\"!=typeof t.wtCustomSend)console.log(\"Warning: wtUseCustomSend is set, but wtCustomSend is not properly defined as a function. Falling back to the default upload mechanism\");else if(t.wtUseCustomSend){i.validFileCheck(r,t.wtCustomSend,o);return}}else{const e=null!==m&&s?i.workerSend:i.actualSend;i.validFileCheck(r,e,o)}};this.actualSend=function(e,t,n){if(!e){i.uploadFinished(null);return}const o=new XMLHttpRequest;o.addEventListener(\"load\",i.uploadFinished);o.addEventListener(\"error\",i.uploadFinished);o.addEventListener(\"abort\",i.uploadFinished);o.addEventListener(\"timeout\",i.uploadFinished);o.open(\"POST\",t);d[0].request=o;const s=new FormData;s.append(\"file-id\",d[0].id);s.append(\"data\",d[0].file);o.send(s)};this.workerSend=function(e,t,n){if(e){m.upload=d[0];m.postMessage({cmd:\"send\",url:t,upload:d[0],chunksize:y})}else i.uploadFinished(null)};this.uploadFinished=function(n){(null!=n&&\"load\"===n.type&&200===n.currentTarget.status||!0===n)&&e.emit(t,\"uploadfinished\",d[0].id);d.splice(0,1);if(d[0]&&d[0].ready)i.requestSend();else{a=!1;e.emit(t,\"donesending\")}};t.cancelUpload=function(e){if(d[0]&&d[0].id===e){d[0].skip=!0;d[0].request?d[0].request.abort():m&&m.upload===d[0]&&m.postMessage({cmd:\"cancel\",upload:d[0]})}else for(let t=1;t2)return;let o=null,s=\"\";for(let t=0;te.path===s));if(r)o=r;else{const t={};t.path=s;t.filename=n;t.contents=[];null===o?e.push(t):o.contents.push(t);o=t}e=o.contents}const r={},l=L(t);r.id=l.id;r.path=\"/\"+n;r.filename=t.name;r.type=t.type;r.size=t.size;o.contents.push(r)}this.setPageHoverStyle=function(){if(p||h){b.classList.add(l);t.classList.add(l);p&&t.classList.add(r)}};this.setWidgetHoverStyle=function(e){t.classList.toggle(s,e)};this.resetDragDrop=function(){t.classList.remove(r);t.classList.remove(l);b.classList.remove(l);i.setWidgetHoverStyle(!1);g=0};t.configureHoverClass=function(e){s=e};t.setFilters=function(e){v.setAttribute(\"accept\",e);w.setAttribute(\"accept\",e)};t.setUploadWorker=function(n){if(n&&window.Worker){m=new Worker(n);m.onmessage=function(n){if(n.data.workerfeatures){if(\"valid\"!==n.data.workerfeatures){t.setUploadWorker(null);e.emit(t,\"filternotsupported\")}}else i.uploadFinished(n.data)};m.postMessage({cmd:\"check\"})}else m=null};t.setChunkSize=function(e){y=e};t.destructor=function(){document.body.removeEventListener(\"dragenter\",F);document.body.removeChild(b)};t.setOnClickFilePicker=function(e){if(\"directory-selection\"===e)t.hiddenInput.setAttribute(\"webkitdirectory\",\"webkitdirectory\");else{\"file-selection\"!==e&&console.error(\"unknown filepicker type; using 'file-selection'\",e);t.hiddenInput.removeAttribute(\"webkitdirectory\")}}})"); + "(function(e,t,n){t.wtLObj=this;const i=this,o=e.WT;let s=\"Wt-dropzone-hover\";const l=\"Wt-dropzone-indication\",r=\"Wt-dropzone-dragstyle\",d=[];let a=!1,c=!0,u=!1,f=!1,p=!1,h=!1,m=\"file-selection\",y=null,g=0,w=0;const v=document.createElement(\"input\");v.type=\"file\";v.setAttribute(\"multiple\",\"multiple\");v.style.display=\"none\";t.hiddenInput=v;t.appendChild(v);const k=document.createElement(\"input\");k.type=\"file\";k.setAttribute(\"multiple\",\"multiple\");k.style.display=\"none\";window.document.body.appendChild(k);t.serverFileInput=k;const b=document.createElement(\"input\");b.type=\"file\";b.setAttribute(\"multiple\",\"multiple\");b.setAttribute(\"webkitdirectory\",\"webkitdirectory\");b.style.display=\"none\";window.document.body.appendChild(b);t.serverDirInput=b;const F=document.createElement(\"div\");F.classList.add(\"Wt-dropcover\");document.body.appendChild(F);this.validFileCheck=function(e,t,n){const i=new FileReader;i.onload=function(){t(!0,n,e)};i.onerror=function(){t(!1,n,e)};i.readAsText(e.file.slice(0,32))};t.setAcceptDrops=function(e){c=e};t.setAcceptDirectories=function(e,t){u=e;f=t};t.setDropIndication=function(e){p=e};t.setDropForward=function(e){h=e};t.ondragenter=function(e){if(c){if(function(e){const t=e.dataTransfer?.items??null,n=null!==t&&Array.prototype.some.call(t,(e=>\"file\"===e.kind)),i=e.dataTransfer?.types??null,o=null!==i&&i.includes(\"Files\");return n||o}(e)){0===w&&i.setPageHoverStyle();w=2;i.setWidgetHoverStyle(!0)}e.stopPropagation()}};t.ondragleave=function(e){const t=e.clientX,n=e.clientY;let o=document.elementFromPoint(t,n);0===t&&0===n&&(o=null);if(o!==F)i.resetDragDrop();else{i.setWidgetHoverStyle(!1);w=1}};t.ondragover=function(e){e.preventDefault()};const S=function(e){if((p||h)&&\"none\"!==o.css(t,\"display\")&&c){w=1;i.setPageHoverStyle()}};document.body.addEventListener(\"dragenter\",S);F.ondragover=function(e){e.preventDefault();e.stopPropagation()};F.ondragleave=function(e){c&&1===w&&i.resetDragDrop()};F.ondrop=function(e){e.preventDefault();h?t.ondrop(e):i.resetDragDrop()};t.ondrop=function(e){e.preventDefault();if(c){i.resetDragDrop();0!==e.dataTransfer.files.length&&i.addDataTransferItems(Array.from(e.dataTransfer.items))}};this.addDataTransferItems=async function(n){const i=[],o=n.map((e=>e.webkitGetAsEntry()));for(const e of o){const t=C(e);if(e.isFile){const n=await L(e);t.type=n.type;t.size=n.size;const i=W(n);t.id=i.id}else if(e.isDirectory){if(!u){console.warn(\"directory drop not enabled, ignoring entry\",e);continue}t.contents=[];await D(e,t,f)}i.push(t)}if(0!==i.length){console.log(\"All newKeys: \",i);e.emit(t,\"dropsignal\",JSON.stringify(i))}};this.addFiles=function(n){const i=[];for(const e of n){const t=W(e),n={};n.id=t.id;n.filename=t.file.name;n.path=t.file.name;n.type=t.file.type;n.size=t.file.size;i.push(n)}e.emit(t,\"dropsignal\",JSON.stringify(i))};async function D(e,t,n){const i=await function(e){return new Promise((t=>{e.createReader().readEntries((function(e){t(e)}))}))}(e);for(let e=0;e{e.file((function(e){t(e)}))}))}function W(e){const t=new Object;t.id=Math.floor(Math.random()*Math.pow(2,31));t.file=e;d.push(t);return t}t.addEventListener(\"click\",(function(){if(c&&\"none\"!==m){v.value=\"\";v.click()}}));t.markForSending=function(e){for(const t of e){const e=t.id;for(const t of d)if(t.id===e){t.ready=!0;break}}a||d.length>0&&d[0].ready&&i.requestSend()};this.requestSend=function(){if(d[0].skip)i.uploadFinished(null);else{a=!0;e.emit(t,\"requestsend\",d[0].id)}};t.send=function(o,s){const l=d[0];if(l.file.size>n){e.emit(t,\"filetoolarge\",l.file.size);i.uploadFinished(null)}else if(\"boolean\"==typeof t.wtUseCustomSend){if(\"function\"!=typeof t.wtCustomSend)console.log(\"Warning: wtUseCustomSend is set, but wtCustomSend is not properly defined as a function. Falling back to the default upload mechanism\");else if(t.wtUseCustomSend){i.validFileCheck(l,t.wtCustomSend,o);return}}else{const e=null!==y&&s?i.workerSend:i.actualSend;i.validFileCheck(l,e,o)}};this.actualSend=function(e,t,n){if(!e){i.uploadFinished(null);return}const o=new XMLHttpRequest;o.addEventListener(\"load\",i.uploadFinished);o.addEventListener(\"error\",i.uploadFinished);o.addEventListener(\"abort\",i.uploadFinished);o.addEventListener(\"timeout\",i.uploadFinished);o.open(\"POST\",t);d[0].request=o;const s=new FormData;s.append(\"file-id\",d[0].id);s.append(\"data\",d[0].file);o.send(s)};this.workerSend=function(e,t,n){if(e){y.upload=d[0];y.postMessage({cmd:\"send\",url:t,upload:d[0],chunksize:g})}else i.uploadFinished(null)};this.uploadFinished=function(n){(null!=n&&\"load\"===n.type&&200===n.currentTarget.status||!0===n)&&e.emit(t,\"uploadfinished\",d[0].id);d.splice(0,1);if(d[0]&&d[0].ready)i.requestSend();else{a=!1;e.emit(t,\"donesending\")}};t.cancelUpload=function(e){if(d[0]&&d[0].id===e){d[0].skip=!0;d[0].request?d[0].request.abort():y&&y.upload===d[0]&&y.postMessage({cmd:\"cancel\",upload:d[0]})}else for(let t=1;t2)return;let o=null,s=\"\";for(let t=0;te.path===s));if(l)o=l;else{const t={};t.path=s;t.filename=n;t.contents=[];null===o?e.push(t):o.contents.push(t);o=t}e=o.contents}const l={},r=W(t);l.id=r.id;l.path=\"/\"+n;l.filename=t.name;l.type=t.type;l.size=t.size;o.contents.push(l)}this.setPageHoverStyle=function(){if(p||h){F.classList.add(r);t.classList.add(r);p&&t.classList.add(l)}};this.setWidgetHoverStyle=function(e){t.classList.toggle(s,e)};this.resetDragDrop=function(){t.classList.remove(l);t.classList.remove(r);F.classList.remove(r);i.setWidgetHoverStyle(!1);w=0};t.configureHoverClass=function(e){s=e};t.setFilters=function(e){v.setAttribute(\"accept\",e);k.setAttribute(\"accept\",e)};t.setUploadWorker=function(n){if(n&&window.Worker){y=new Worker(n);y.onmessage=function(n){if(n.data.workerfeatures){if(\"valid\"!==n.data.workerfeatures){t.setUploadWorker(null);e.emit(t,\"filternotsupported\")}}else i.uploadFinished(n.data)};y.postMessage({cmd:\"check\"})}else y=null};t.setChunkSize=function(e){g=e};t.destructor=function(){document.body.removeEventListener(\"dragenter\",S);document.body.removeChild(F)};t.setOnClickFilePicker=function(e){if(\"directory-selection\"===e)t.hiddenInput.setAttribute(\"webkitdirectory\",\"webkitdirectory\");else{t.hiddenInput.removeAttribute(\"webkitdirectory\");if(\"file-selection\"!==e&&\"none\"!==e){console.warn(\"unknown filepicker type; using 'file-selection'\",e);e=\"file-selection\"}}m=e}})"); } static List flattenUploadsVector(WFileDropWidget.Directory dir) { diff --git a/src/eu/webtoolkit/jwt/WFileUpload.java b/src/eu/webtoolkit/jwt/WFileUpload.java index 6bf61c19..8e337486 100644 --- a/src/eu/webtoolkit/jwt/WFileUpload.java +++ b/src/eu/webtoolkit/jwt/WFileUpload.java @@ -473,7 +473,7 @@ private void onData(long current, long total) { private void onDataExceeded(long dataExceeded) { this.doJavaScript( - "Wt4_11_1.$('if" + this.getId() + "').src='" + this.fileUploadTarget_.getUrl() + "';"); + "Wt4.11.2.$('if" + this.getId() + "').src='" + this.fileUploadTarget_.getUrl() + "';"); if (this.flags_.get(BIT_UPLOADING)) { this.flags_.clear(BIT_UPLOADING); this.handleFileTooLarge(dataExceeded); @@ -534,7 +534,7 @@ void updateDom(final DomElement element, boolean all) { element.setAttribute("action", this.fileUploadTarget_.generateUrl()); String maxFileSize = String.valueOf(WApplication.getInstance().getMaximumRequestSize()); String command = - "{var submit = true;var x = Wt4_11_1.$('in" + "{var submit = true;var x = Wt4.11.2.$('in" + this.getId() + "');if (x.files != null) {for (var i = 0; i < x.files.length; i++) {var f = x.files[i];if (f.size > " + maxFileSize @@ -681,9 +681,9 @@ protected void propagateSetEnabled(boolean enabled) { String renderRemoveJs(boolean recursive) { boolean isIE = WApplication.getInstance().getEnvironment().agentIsIE(); if (this.isRendered() && isIE) { - String result = "Wt4_11_1.$('if" + this.getId() + "').innerHTML = \"\";"; + String result = "Wt4.11.2.$('if" + this.getId() + "').innerHTML = \"\";"; if (!recursive) { - result += "Wt4_11_1.remove('" + this.getId() + "');"; + result += "Wt4.11.2.remove('" + this.getId() + "');"; } return result; } else { diff --git a/src/eu/webtoolkit/jwt/WFileUploadResource.java b/src/eu/webtoolkit/jwt/WFileUploadResource.java index 177e98f5..4d646d0b 100644 --- a/src/eu/webtoolkit/jwt/WFileUploadResource.java +++ b/src/eu/webtoolkit/jwt/WFileUploadResource.java @@ -40,7 +40,14 @@ protected void handleRequest(final WebRequest request, final WebResponse respons } response.setContentType("text/html; charset=utf-8"); Writer o = response.out(); - o.append("\n"); } @@ -508,7 +512,7 @@ private void serveMainscript(final WebResponse response) throws IOException { "SHOW_ERROR", conf.getErrorReporting() == Configuration.ErrorReporting.ErrorMessage); script.setCondition("UGLY_INTERNAL_PATHS", this.session_.isUseUglyInternalPaths()); script.setCondition("DYNAMIC_JS", false); - script.setVar("WT_CLASS", "Wt4_11_1"); + script.setVar("WT_CLASS", "Wt4.11.2"); script.setVar("APP_CLASS", app.getJavaScriptClass()); script.setCondition("STRICTLY_SERIALIZED_EVENTS", conf.serializedEvents()); script.setCondition("WEB_SOCKETS", conf.webSockets()); @@ -569,18 +573,18 @@ private void serveMainscript(final WebResponse response) throws IOException { boolean enabledAjax = app.enableAjax_; if (app.enableAjax_) { this.collectedJS1_ - .append("var form = Wt4_11_1.getElement('Wt-form'); if (form) {") + .append("var form = Wt4.11.2.getElement('Wt-form'); if (form) {") .append(this.beforeLoadJS_.toString()); this.beforeLoadJS_.setLength(0); this.collectedJS1_ .append("var domRoot=") .append(app.domRoot_.getJsRef()) .append(';') - .append("Wt4_11_1.progressed(domRoot);"); + .append("Wt4.11.2.progressed(domRoot);"); int librariesLoaded = this.loadScriptLibraries(this.collectedJS1_, app); app.streamBeforeLoadJavaScript(this.collectedJS1_, false); this.collectedJS2_ - .append("Wt4_11_1.resolveRelativeAnchors();") + .append("Wt4.11.2.resolveRelativeAnchors();") .append("domRoot.style.visibility = 'visible';") .append(app.getJavaScriptClass()) .append("._p_.doAutoJavaScript();"); @@ -633,7 +637,7 @@ private void serveMainscript(final WebResponse response) throws IOException { .append("}, 400);") .append("else "); } - out.append("Wt4_11_1.ready(function() { ") + out.append("Wt4.11.2.ready(function() { ") .append(app.getJavaScriptClass()) .append("._p_.load(true);});\n"); } @@ -644,7 +648,7 @@ private void serveMainscript(final WebResponse response) throws IOException { private void serveBootstrap(final WebResponse response) throws IOException { final Configuration conf = this.session_.getController().getConfiguration(); FileServe boot = new FileServe(WtServlet.Boot_html); - this.setPageVars(boot); + this.setPageVars(boot, response.getNonce()); StringBuilder noJsRedirectUrl = new StringBuilder(); DomElement.htmlAttributeValue( noJsRedirectUrl, @@ -665,7 +669,9 @@ private void serveBootstrap(final WebResponse response) throws IOException { + String.valueOf(this.pageId_)); boot.setVar("BOOT_STYLE_URL", bootStyleUrl.toString()); this.addNoCacheHeaders(response); - response.addHeader("X-Frame-Options", "SAMEORIGIN"); + if (conf.isUseXFrameSameOrigin()) { + response.addHeader("X-Frame-Options", "SAMEORIGIN"); + } String contentType = "text/html; charset=UTF-8"; this.setHeaders(response, contentType); StringBuilder out = new StringBuilder(); @@ -723,6 +729,9 @@ private void serveMainpage(final WebResponse response) throws IOException { String url = app.scriptLibraries_.get(i).uri; styleSheets.append("\n"); this.beforeLoadJS_.append(app.scriptLibraries_.get(i).beforeLoadJS); } @@ -730,7 +739,7 @@ private void serveMainpage(final WebResponse response) throws IOException { app.newBeforeLoadJavaScript_ = app.beforeLoadJavaScript_.length(); boolean hybridPage = this.session_.isProgressiveBoot() || this.session_.getEnv().hasAjax(); FileServe page = new FileServe(hybridPage ? WtServlet.Hybrid_html : WtServlet.Plain_html); - this.setPageVars(page); + this.setPageVars(page, response.getNonce()); page.setVar("SESSION_ID", this.session_.getSessionId()); String url = app.getEnvironment().agentIsSpiderBot() || !this.session_.isUseUrlRewriting() @@ -751,7 +760,9 @@ private void serveMainpage(final WebResponse response) throws IOException { app.titleChanged_ = false; String contentType = "text/html; charset=UTF-8"; this.addNoCacheHeaders(response); - response.addHeader("X-Frame-Options", "SAMEORIGIN"); + if (conf.isUseXFrameSameOrigin()) { + response.addHeader("X-Frame-Options", "SAMEORIGIN"); + } this.setHeaders(response, contentType); this.currentFormObjectsList_ = this.createFormObjectsList(app); if (hybridPage) { @@ -919,7 +930,7 @@ private void serveMainAjax(final StringBuilder out) { if (widgetset) { String historyE = app.getEnvironment().getParameter("Wt-history"); if (historyE != null) { - out.append("Wt4_11_1") + out.append("Wt4.11.2") .append(".history.initialize('") .append(historyE.charAt(0)) .append("-field', '") @@ -937,7 +948,7 @@ private void serveMainAjax(final StringBuilder out) { out.append("};\n"); } this.renderSetServerPush(out); - out.append("Wt4_11_1.ready(function() { ") + out.append("Wt4.11.2.ready(function() { ") .append(app.getJavaScriptClass()) .append("._p_.load(") .append(!widgetset) @@ -1169,7 +1180,7 @@ private void collectJavaScriptUpdate(final StringBuilder out) { private void loadStyleSheet( final StringBuilder out, WApplication app, final WLinkedCssStyleSheet sheet) { - out.append("Wt4_11_1") + out.append("Wt4.11.2") .append(".addStyleSheet('") .append(sheet.getLink().resolveUrl(app)) .append("', '") @@ -1188,7 +1199,7 @@ private void loadStyleSheets(final StringBuilder out, WApplication app) { private void removeStyleSheets(final StringBuilder out, WApplication app) { for (int i = (int) app.styleSheetsToRemove_.size() - 1; i > -1; --i) { - out.append("Wt4_11_1") + out.append("Wt4.11.2") .append(".removeStyleSheet('") .append(app.styleSheetsToRemove_.get(i).getLink().resolveUrl(app)) .append("');\n "); @@ -1379,8 +1390,9 @@ private void collectJS(StringBuilder js) { app.renderedInternalPath_ = app.newInternalPath_; } - private void setPageVars(final FileServe page) { + private void setPageVars(final FileServe page, final String nonce) { WApplication app = this.session_.getApp(); + final Configuration conf = this.session_.getController().getConfiguration(); page.setVar("DOCTYPE", this.session_.getDocType()); String htmlAttr = ""; if (app != null && app.htmlClass_.length() != 0) { @@ -1420,6 +1432,15 @@ private void setPageVars(final FileServe page) { page.setCondition( "FORM", !this.session_.getEnv().agentIsSpiderBot() && !this.session_.getEnv().hasAjax()); page.setCondition("BOOT_STYLE", true); + page.setCondition("USE_NONCE", conf.isUseScriptNonce()); + page.setVar("NONCE", nonce); + if (conf.isUseScriptNonce() && nonce.length() == 0) { + logger.warn( + new StringWriter() + .append( + "An empty nonce has been defined. This may result in the CSP header not being correctly defined and used.") + .toString()); + } } private void streamBootContent(final WebResponse response, final FileServe boot, boolean hybrid) @@ -1452,6 +1473,7 @@ private void streamBootContent(final WebResponse response, final FileServe boot, "AJAX_CANONICAL_URL", this.safeJsStringLiteral(this.session_.ajaxCanonicalUrl(response))); bootJs.setVar("APP_CLASS", "Wt"); bootJs.setVar("PATH_INFO", this.safeJsStringLiteral(this.session_.pagePathInfo_)); + bootJs.setVar("DELAY_LOAD_AT_BOOT", conf.isDelayLoadAtBoot()); bootJs.setCondition("COOKIE_CHECKS", conf.isCookieChecks()); bootJs.setCondition("HYBRID", hybrid); bootJs.setCondition("PROGRESS", hybrid && !this.session_.getEnv().hasAjax()); diff --git a/src/eu/webtoolkit/jwt/WebSession.java b/src/eu/webtoolkit/jwt/WebSession.java index 0ffd54f4..2263485f 100644 --- a/src/eu/webtoolkit/jwt/WebSession.java +++ b/src/eu/webtoolkit/jwt/WebSession.java @@ -1705,7 +1705,7 @@ public void setLoaded() { this.setState(WebSession.State.Loaded, this.controller_.getConfiguration().getSessionTimeout()); if (wasSuspended) { if (this.env_.hasAjax() && this.controller_.getConfiguration().reloadIsNewSession()) { - this.app_.doJavaScript("Wt4_11_1.history.removeSessionId()"); + this.app_.doJavaScript("Wt4.11.2.history.removeSessionId()"); this.sessionIdInUrl_ = false; } this.app_.unsuspended().trigger(); @@ -2101,7 +2101,7 @@ private void notifySignal(final WEvent e) throws IOException { String hashE = request.getParameter(se + "_"); if (hashE != null) { this.changeInternalPath(hashE, handler.getResponse()); - this.app_.doJavaScript("Wt4_11_1.scrollHistory();"); + this.app_.doJavaScript("Wt4.11.2.scrollHistory();"); } else { this.changeInternalPath("", handler.getResponse()); } diff --git a/src/eu/webtoolkit/jwt/WtServlet.java b/src/eu/webtoolkit/jwt/WtServlet.java index 1ceba4e8..47d4ba1a 100644 --- a/src/eu/webtoolkit/jwt/WtServlet.java +++ b/src/eu/webtoolkit/jwt/WtServlet.java @@ -192,6 +192,7 @@ public void init(ServletConfig config) throws ServletException { void handleRequest(final HttpServletRequest request, final HttpServletResponse response) { String pathInfo = WebRequest.computePathInfo(request, configuration); String resourcePath = configuration.getProperty(WApplication.RESOURCES_URL); + addDefaultHeader(response); if (pathInfo != null) { String scriptName = WebRequest.computeScriptName(request, configuration); @@ -595,4 +596,11 @@ int getIdForWebSocket() { String getContextPath() { return getServletContext().getContextPath(); } + + private void addDefaultHeader(HttpServletResponse response) { + List httpHeaders = configuration.getHttpHeaders(); + for (HttpHeader header : httpHeaders) { + response.addHeader(header.getName(), header.getContents()); + } + } } diff --git a/src/eu/webtoolkit/jwt/auth/AuthThrottle.java b/src/eu/webtoolkit/jwt/auth/AuthThrottle.java index 492f8b7e..7579f1c6 100644 --- a/src/eu/webtoolkit/jwt/auth/AuthThrottle.java +++ b/src/eu/webtoolkit/jwt/auth/AuthThrottle.java @@ -153,7 +153,7 @@ public void initializeThrottlingMessage(WInteractWidget button) { app.loadJavaScript("js/AuthThrottle.js", wtjs1()); button.setJavaScriptMember( " AuthThrottle", - "new Wt4_11_1.AuthThrottle(Wt4_11_1," + "new Wt4.11.2.AuthThrottle(Wt4.11.2," + button.getJsRef() + "," + WString.toWString(WString.tr("Wt.Auth.throttle-retry")).getJsStringLiteral() diff --git a/src/eu/webtoolkit/jwt/auth/OAuthProcess.java b/src/eu/webtoolkit/jwt/auth/OAuthProcess.java index 03d951cf..f8bc3c75 100644 --- a/src/eu/webtoolkit/jwt/auth/OAuthProcess.java +++ b/src/eu/webtoolkit/jwt/auth/OAuthProcess.java @@ -138,7 +138,7 @@ public void connectStartAuthenticate(final AbstractEventSignal s) { && this.service_.isPopupEnabled()) { StringBuilder js = new StringBuilder(); js.append("function(object, event) {") - .append("Wt4_11_1.PopupWindow(Wt4_11_1") + .append("Wt4.11.2.PopupWindow(Wt4.11.2") .append(",") .append(WWebWidget.jsStringLiteral(this.getAuthorizeUrl())) .append(", ") diff --git a/src/eu/webtoolkit/jwt/auth/OAuthRedirectEndpoint.java b/src/eu/webtoolkit/jwt/auth/OAuthRedirectEndpoint.java index 81818cb6..a25ea0e6 100644 --- a/src/eu/webtoolkit/jwt/auth/OAuthRedirectEndpoint.java +++ b/src/eu/webtoolkit/jwt/auth/OAuthRedirectEndpoint.java @@ -92,7 +92,11 @@ public void sendResponse(final WebResponse response) throws IOException { } else { String appJs = app.getJavaScriptClass(); o.append( - "\n\n - + _$_STYLESHEETS_$_ -