some browser jam stuff

This commit is contained in:
Adam D. Ruppe 2024-09-13 22:02:07 -04:00
parent 21c8eb6cbd
commit 6e4e2966ca
3 changed files with 125 additions and 8 deletions

39
dom.d
View File

@ -3078,7 +3078,7 @@ class Element : DomParent {
/* done */ /* done */
_computedStyle = new CssStyle(null, style); // gives at least something to work with _computedStyle = computedStyleFactory(this);
} }
return _computedStyle; return _computedStyle;
} }
@ -7640,6 +7640,24 @@ Element[] removeDuplicates(Element[] input) {
// done with CSS selector handling // done with CSS selector handling
/++
This delegate is called if you call [Element.computedStyle] to attach an object to the element
that holds stylesheet information. You can rebind it to something else to return a subclass
if you want to hold more per-element extension data than the normal computed style object holds
(e.g. layout info as well).
The default is `return new CssStyle(null, element.style);`
History:
Added September 13, 2024 (dub v11.6)
+/
CssStyle function(Element e) computedStyleFactory = &defaultComputedStyleFactory;
/// ditto
CssStyle defaultComputedStyleFactory(Element e) {
return new CssStyle(null, e.style); // gives at least something to work with
}
// FIXME: use the better parser from html.d // FIXME: use the better parser from html.d
/// This is probably not useful to you unless you're writing a browser or something like that. /// This is probably not useful to you unless you're writing a browser or something like that.
@ -7726,7 +7744,7 @@ class CssStyle {
if(value is null) if(value is null)
return getValue(name); return getValue(name);
else else
return setValue(name, value, 0x02000000 /* inline specificity */); return setValue(name, value, Specificity(0x02000000) /* inline specificity */);
} }
/// takes dash style name /// takes dash style name
@ -8709,11 +8727,13 @@ void fillForm(T)(Form form, T obj, string name) {
History: History:
Added March 25, 2022 (dub v10.8) Added March 25, 2022 (dub v10.8)
The `stripLeadingAndTrailing` argument was added September 13, 2024 (dub v11.6).
+/ +/
string normalizeWhitespace(string text) { string normalizeWhitespace(string text, bool stripLeadingAndTrailing = true) {
string ret; string ret;
ret.reserve(text.length); ret.reserve(text.length);
bool lastWasWhite = true; bool lastWasWhite = stripLeadingAndTrailing;
foreach(char ch; text) { foreach(char ch; text) {
if(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') { if(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
if(lastWasWhite) if(lastWasWhite)
@ -8727,12 +8747,23 @@ string normalizeWhitespace(string text) {
ret ~= ch; ret ~= ch;
} }
if(stripLeadingAndTrailing)
return ret.stripRight; return ret.stripRight;
else {
/+
if(lastWasWhite && (ret.length == 0 || ret[$-1] != ' '))
ret ~= ' ';
+/
return ret;
}
} }
unittest { unittest {
assert(normalizeWhitespace(" foo ") == "foo"); assert(normalizeWhitespace(" foo ") == "foo");
assert(normalizeWhitespace(" f\n \t oo ") == "f oo"); assert(normalizeWhitespace(" f\n \t oo ") == "f oo");
assert(normalizeWhitespace(" foo ", false) == " foo ");
assert(normalizeWhitespace(" foo ", false) == " foo ");
assert(normalizeWhitespace("\nfoo", false) == " foo");
} }
unittest { unittest {

View File

@ -1560,11 +1560,23 @@ class Widget : ReflectableProperties {
+/ +/
final @property inout(Window) parentWindow() inout @nogc nothrow pure { return _parentWindow; } final @property inout(Window) parentWindow() inout @nogc nothrow pure { return _parentWindow; }
private @property void parentWindow(Window parent) { private @property void parentWindow(Window parent) {
auto old = _parentWindow;
_parentWindow = parent; _parentWindow = parent;
newParentWindow(old, _parentWindow);
foreach(child; children) foreach(child; children)
child.parentWindow = parent; // please note that this is recursive child.parentWindow = parent; // please note that this is recursive
} }
/++
Called when the widget has been added to or remove from a parent window.
Note that either oldParent and/or newParent may be null any time this is called.
History:
Added September 13, 2024
+/
protected void newParentWindow(Window oldParent, Window newParent) {}
/++ /++
Returns the list of the widget's children. Returns the list of the widget's children.
@ -12093,6 +12105,7 @@ class TextDisplayHelper : Widget {
with(l.selection()) { with(l.selection()) {
if(!isEmpty()) { if(!isEmpty()) {
getPrimarySelection(parentWindow.win, (in char[] txt) { getPrimarySelection(parentWindow.win, (in char[] txt) {
// import std.stdio; writeln("txt: ", txt, " sel: ", getContentString);
if(txt.length) { if(txt.length) {
preservedPrimaryText = txt.idup; preservedPrimaryText = txt.idup;
// writeln(preservedPrimaryText); // writeln(preservedPrimaryText);
@ -12425,6 +12438,8 @@ class TextDisplayHelper : Widget {
parentWindow.win.getPrimarySelection((txt) { parentWindow.win.getPrimarySelection((txt) {
doStateCheckpoint(); doStateCheckpoint();
// import arsd.core; writeln(txt);writeln(l.selection.getContentString);writeln(preservedPrimaryText);
if(txt == l.selection.getContentString && preservedPrimaryText.length) if(txt == l.selection.getContentString && preservedPrimaryText.length)
l.selection.replaceContent(preservedPrimaryText); l.selection.replaceContent(preservedPrimaryText);
else else
@ -12910,7 +12925,10 @@ abstract class EditableTextWidget : EditableTextWidgetParent {
this.tabStop = false; this.tabStop = false;
smw.tabStop = false; smw.tabStop = false;
tdh = textDisplayHelperFactory(textLayout, smw); tdh = textDisplayHelperFactory(textLayout, smw);
}
override void newParentWindow(Window old, Window n) {
if(n is null) return;
this.parentWindow.addEventListener((scope DpiChangedEvent dce) { this.parentWindow.addEventListener((scope DpiChangedEvent dce) {
if(textLayout) { if(textLayout) {
if(auto style = cast(TextDisplayHelper.MyTextStyle) textLayout.defaultStyle()) { if(auto style = cast(TextDisplayHelper.MyTextStyle) textLayout.defaultStyle()) {
@ -13453,6 +13471,9 @@ abstract class GenericListViewWidget : Widget {
private ScrollMessageWidget smw; private ScrollMessageWidget smw;
private GenericListViewWidgetInner inner; private GenericListViewWidgetInner inner;
/++
+/
abstract GenericListViewItem itemFactory(Widget parent); abstract GenericListViewItem itemFactory(Widget parent);
// in device-dependent pixels // in device-dependent pixels
/++ /++
@ -13508,9 +13529,7 @@ abstract class GenericListViewWidget : Widget {
private GenericListViewItem[] items; private GenericListViewItem[] items;
} }
/++ /// ditto
+/
abstract class GenericListViewItem : Widget { abstract class GenericListViewItem : Widget {
/++ /++
+/ +/
@ -13544,6 +13563,52 @@ abstract class GenericListViewItem : Widget {
} }
} }
///
unittest {
import arsd.minigui;
import std.conv;
void main() {
auto mw = new MainWindow();
static class MyListViewItem : GenericListViewItem {
this(Widget parent) {
super(parent);
label = new TextLabel("unloaded", TextAlignment.Left, this);
button = new Button("Click", this);
button.addEventListener("triggered", (){
messageBox(text("clicked ", currentIndexLoaded()));
});
}
override void showItem(int idx) {
label.label = "Item " ~ to!string(idx);
}
TextLabel label;
Button button;
}
auto widget = new class GenericListViewWidget {
this() {
super(mw);
}
override GenericListViewItem itemFactory(Widget parent) {
return new MyListViewItem(parent);
}
override Size itemSize() {
return Size(0, scaleWithDpi(80));
}
};
widget.setItemCount(5000);
mw.loop();
}
}
private class GenericListViewWidgetInner : Widget { private class GenericListViewWidgetInner : Widget {
this(GenericListViewWidget glvw, ScrollMessageWidget smw) { this(GenericListViewWidget glvw, ScrollMessageWidget smw) {
super(smw); super(smw);

View File

@ -1212,6 +1212,8 @@ class TextLayouter {
Starts from the given selection and moves in the direction to find next. Starts from the given selection and moves in the direction to find next.
Returns true if found. Returns true if found.
NOT IMPLEMENTED use a selection instead
+/ +/
FindResult find(int selectionId, in const(char)[] text, bool direction, bool wraparound) { FindResult find(int selectionId, in const(char)[] text, bool direction, bool wraparound) {
return FindResult.NotFound; return FindResult.NotFound;
@ -1756,6 +1758,25 @@ class TextLayouter {
return idx; return idx;
} }
/++
History:
Added September 13, 2024
+/
const(TextStyle) styleAtPoint(Point p) {
TextStyle s;
getInternalSegments(delegate bool(size_t segmentIndex, scope ref Segment segment) {
if(segment.boundingBox.contains(p)) {
s = stylePalette[segment.styleInformationIndex];
return false;
}
return true;
}, Rectangle(p, Size(1, 1)));
return s;
}
private StyleHandle getInsertionStyleAt(int offset) { private StyleHandle getInsertionStyleAt(int offset) {
assert(offset >= 0 && offset < text.length); assert(offset >= 0 && offset < text.length);
/+ /+