Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions to.etc.domui/src/main/java/to/etc/domui/dom/Animations.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ public NodeFixer(NodeBase node, DisplayType newDisplay) {
* Since after the slideDown the node in the browser will have its default display this is also the state
* in DomUI's node.
*
* @param node
* @param node target node
*/
static public void slideDown(NodeBase node) {
node.getPage().addAfterRenderListener(new NodeFixer(node, node.getDisplay()));
node.setDisplay(DisplayType.NONE);
node.appendStatement()
.select(node)
.method("slideDown").end()
.method("doSlideDown").end()
.endmethod()
.next();
}
Expand All @@ -75,7 +75,7 @@ static public void slideUp(NodeBase node, String jsCallback) {
node.getPage().addAfterRenderListener(new NodeFixer(node, DisplayType.NONE));
node.appendStatement()
.select(node)
.append(".slideUp(function() { " + jsCallback + " })")
.append(".doSlideUp(function() { " + jsCallback + " })")
.next();
}

Expand Down Expand Up @@ -104,6 +104,7 @@ static public void bounce(NodeBase node) {

/**
* Does pulsate effect.
*
* @param node target node
* @param times if 0 it uses default behavior for pulsate.
*/
Expand Down
56 changes: 50 additions & 6 deletions to.etc.domui/src/main/java/to/etc/domui/dom/HtmlTagRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@
import to.etc.util.StringTool;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static to.etc.util.StringTool.isBlank;

/**
* Basic, mostly standard-compliant handler for rendering HTML tags.
Expand All @@ -90,6 +95,15 @@
* Created on Aug 17, 2007
*/
public class HtmlTagRenderer implements INodeVisitor {

/** Replacing specific style attributes with build-in classes -> optimization when we render styles attributes as jquery js code for CSP support */
private static final Map<String, String> STYLE_ATTRIBUTES_TO_CLASSES = Map.of(
"display:none", "ui-display-none", //
"display:inline", "ui-display-inline", //
"display:block", "ui-display-block", //
"display:flex", "ui-display-flex" //
);

/** Scratch stringbuffer. */
private StringBuilder m_sb;

Expand Down Expand Up @@ -615,7 +629,7 @@ static private String border(final StringBuilder a, final int w, final String s,
}

static private void renderBorderIf(@NonNull Appendable a, @Nullable String border) throws IOException {
if(StringTool.isBlank(border))
if(isBlank(border))
return;
a.append("border:").append(border).append(";");
}
Expand Down Expand Up @@ -678,8 +692,26 @@ public void basicNodeRender(final NodeBase b, final IBrowserOutput o, boolean in
}

String s = getStyleFor(b); // Get/recalculate style

//collect replacing classes for specified style attributes
List<String> classesFromStyleAttributes = new ArrayList<>();
if(!s.isEmpty() || b.isStyleRendered()) {
o.attr("style", s);
StringBuilder styleSb = new StringBuilder();
String[] styles = s.split(";");
for(int i = 0; i < styles.length; i++) {
String stylePart = styles[i];
if(!isBlank(stylePart)) {
String aClass = STYLE_ATTRIBUTES_TO_CLASSES.get(stylePart);
if(null != aClass) {
classesFromStyleAttributes.add(aClass);
} else {
styleSb.append(stylePart).append(";");
}
}
}
if(styleSb.length() > 0) {
o.attr("style", styleSb.toString());
}
if(s.isEmpty()) {
b.clearStyleRendered(); // if we rendered the empty style we can remove it next time
} else {
Expand Down Expand Up @@ -721,8 +753,20 @@ public void basicNodeRender(final NodeBase b, final IBrowserOutput o, boolean in

if(b.isStretchHeight())
o.attr("stretch", "true");
if(b.getCssClass() != null)
o.attr("class", b.getCssClass());

//append collected replacing classes too to existing classes of an element
String cssClass = b.getCssClass();
if(cssClass != null || !classesFromStyleAttributes.isEmpty()) {
if(!classesFromStyleAttributes.isEmpty()) {
String appendedClasses = classesFromStyleAttributes.stream().collect(Collectors.joining(" "));
if(null == cssClass) {
cssClass = appendedClasses;
}else {
cssClass = cssClass + " " + appendedClasses;
}
}
o.attr("class", cssClass);
}

List<String> sal = b.getSpecialAttributeList();
if(sal != null) {
Expand Down Expand Up @@ -1076,11 +1120,11 @@ public void visitInput(final Input n) throws Exception {
o().attr("onblur", sb().append(transformScript).append("WebUI.hideLookupTypingPopup('").append(n.getActualID()).append("')").toString());
} else {
//-- Attach normal onKeyPress handling.
if(!StringTool.isBlank(n.getOnKeyPressJS())) {
if(!isBlank(n.getOnKeyPressJS())) {
o().attr("onkeypress", "return " + n.getOnKeyPressJS());
}

if(!StringTool.isBlank(transformScript)) {
if(!isBlank(transformScript)) {
o().attr("onblur", sb().append(transformScript).toString());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,19 @@ i, em {
text-align: left;
white-space: nowrap;
}

.ui-display-none {
display: none !important;
}

.ui-display-inline {
display: inline !important;
}

.ui-display-block {
display: block !important;
}

.ui-display-flex {
display: flex !important;
}
52 changes: 52 additions & 0 deletions to.etc.domui/src/main/resources/resources/ts/domui.comp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,16 +393,65 @@ namespace WebUI {
WebUI.valuechanged('eh', id);
}

export function fixDisplayClass(elem): void {
let style = $(elem).attr("style");
if(null == style) {
return;
}
if(style.includes("display: none;")) {
style = style
.replace("display: none;", "")
$(elem).attr("style", style);
$(elem).removeClass("ui-display-block");
$(elem).removeClass("ui-display-flex");
$(elem).removeClass("ui-display-inline");
$(elem).addClass("ui-display-none");
}
if(style.includes("display: block;")) {
style = style
.replace("display: block;", "")
$(elem).attr("style", style);
$(elem).removeClass("ui-display-none");
$(elem).removeClass("ui-display-flex");
$(elem).removeClass("ui-display-inline");
$(elem).addClass("ui-display-block");
}
if(style.includes("display: inline;")) {
style = style
.replace("display: inline;", "")
$(elem).attr("style", style);
$(elem).removeClass("ui-display-none");
$(elem).removeClass("ui-display-block");
$(elem).removeClass("ui-display-flex");
$(elem).addClass("ui-display-inline");
}
if(style.includes("display: flex;")) {
style = style
.replace("display: flex;", "")
$(elem).attr("style", style);
$(elem).removeClass("ui-display-none");
$(elem).removeClass("ui-display-block");
$(elem).removeClass("ui-display-inline");
$(elem).addClass("ui-display-flex");
}
}

export function flare(id): void {
$('#' + id).css('display', 'none');
$('#' + id).removeClass("ui-display-none");
$('#' + id).fadeIn('fast', function() {
WebUI.fixDisplayClass($('#' + id));
$('#' + id).delay(500).fadeOut(1000, function() {
$('#' + id).remove();
});
});
}

export function flareStay(id): void {
$('#' + id).css('display', 'none');
$('#' + id).removeClass("ui-display-none");
$('#' + id).fadeIn('fast', function() {
WebUI.fixDisplayClass($('#' + id));
$('body,html').bind('mousemove.' + id, function(e) {
$('body,html').unbind('mousemove.' + id);
$('#' + id).delay(500).fadeOut(1000, function() {
Expand All @@ -413,7 +462,10 @@ namespace WebUI {
}

export function flareStayCustom(id, delay, fadeOut): void {
$('#' + id).css('display', 'none');
$('#' + id).removeClass("ui-display-none");
$('#' + id).fadeIn('fast', function() {
WebUI.fixDisplayClass($('#' + id));
$('body,html').bind('mousemove.' + id, function(e) {
$('body,html').unbind('mousemove.' + id);
$('#' + id).delay(delay).fadeOut(fadeOut, function() {
Expand Down
31 changes: 31 additions & 0 deletions to.etc.domui/src/main/resources/resources/ts/domui.jquery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,37 @@ $.fn.extend({
});
$(this).markerTransformed = true;
});
},

doSlideUp: function(callback) {
let fixDisplayCallback = function(elem) {
WebUI.fixDisplayClass(elem);
}

let myOnSlideUp = fixDisplayCallback;
if(null != callback) {
myOnSlideUp = function(elem) {
callback();
fixDisplayCallback(elem);
}
}
this.slideUp(myOnSlideUp(this));
},

doSlideDown: function(callback) {
let fixDisplayCallback = function(elem) {
WebUI.fixDisplayClass(elem);
}

let myOnSlideDown = fixDisplayCallback;
if(null != callback) {
myOnSlideDown = function(elem) {
callback();
fixDisplayCallback(elem);
}
}
this.slideDown(myOnSlideDown(this));
}

});