Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss
Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Bestimmte Unicodezeichen in HTML finden und "behandeln"

3 views
Skip to first unread message

Andreas Borutta

unread,
May 27, 2023, 7:04:58 AM5/27/23
to
Moin.

Ihr merkt schon an meinem laienhaft formuierten Subject, dass ich
nicht programmieren kann ; )

Vielleicht reißt ihr mir dennoch nicht gleich den Kopf ab.

Die Situation:
Ich erledige das HTML-Markup für ein freies Fahrradmagazin.

Für eine gute Typografie verwenden wir unter anderem

U+00A0 NO-BREAK SPACE
U+202F NARROW NO-BREAK SPACE
U+2009 THIN SPACE

Die Zeichen sind naturgemäß "unsichtbar".

HTML

foo foo
bar bar
zot zot

Im Lektoratsprozess, also vor der Veröffentlichung, wäre es hilfreich,
wenn man diese Zeichen sichtbar machen könnte. So könnten wir leichter
prüfen, ob die Zeichen korrekt gesetzt sind, oder ob welche fehlen.

Könnte man mit clientseitigem JS Folgendes erreichen?

HTML

foo<span class="invisible">&nbsp;</span>foo
bar<span class="invisible">&#x202F;</span>bar
zot<span class="invisible">&#x2009;</span>zot

CSS

.invisible { background: rgb(190,190,190); }

Danke.

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 27, 2023, 3:56:13 PM5/27/23
to
Stefan Ram:

> Die folgende Variante vermeidet nun doppelte Ersetzungen
> [...]

Ganz herzlichen Dank : )

https://borumat.de/-/fahrradzukunft/zeichen-mit-js-behandeln-von-stefan

Ich habe noch ein paar Kleinigkeiten angepasst:

* Stilregel ausgelagert

* auf HTML5 gewechselt

* im RegEx das zu ersetzende Entity eingeklammert damit es nicht in
der Anweisung zum Ersetzen wiederholt werden muss und

* <span> durch das "Custom Element" "<fz-nbsp>" ersetzt

Das ist eine große Erleichterung für das Lektorat.

Das Skript funktionierte nicht mit mehr als einem <p>. Daher habe ich
erstmal die <br> eingefügt.

Falls Du noch Muße hast, füge doch bitte noch eine Option zum Ersetzen
der anderen Leerzeichen ein.

Denkbare Namen für die anderen beiden Leerzeichen könnten sein:
<fz-nnbsp>
<fz-nsp>

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 27, 2023, 6:37:02 PM5/27/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:

>>Das Skript funktionierte nicht mit mehr als einem <p>. Daher habe ich
>>erstmal die <br> eingefügt.
>>Falls Du noch Muße hast, füge doch bitte noch eine Option zum Ersetzen
>>der anderen Leerzeichen ein.
>
> Dieses Skript hier ersetzt auch in mehreren Absätzen. Allerdings
> kann es sein, daß die hier eingesetzte Technik bei anderem
> oder komplizierterem Aufbau des Dokuments doch versagt.

Gäbe es denn andere Techniken, die vorhersagbar zuverlässig bei
umfangreichem und komplexem HTML sind?

Wichtig wäre auch, dass es nicht mit anderen JS kollidiert.

Wir setzen z.B. MathJax für hochwertigen Formelsatz ein.
https://de.wikipedia.org/wiki/MathJax

Das produziert gewaltige Mengen Markup.
https://borumat.de/-/fahrradzukunft/mathjax-latex

Ideal wäre es, wenn die Technik des Skriptes (wir könnten es
"invisibles.js" nennen) z.B. erlaubt Elemente (und ihre Kinder)
auszuschließen.

> Jetzt werden auch "202F" und "2009" modifiziert. Dabei sucht das
> Skript entweder nach numerischen Entitätsreferenzen genau der
> angegebenen Form oder nach den entsprechenden Unicode-Zeichen.
> Es würde also Varianten von Entitätsreferenzen nicht finden.
>
> <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"
> lang="de" xml:lang="de">
> <head><meta charset="UTF-8" /><title>Programm 2023-05-27T19:59</title>
> </head><body><p>Durch&nbsp;die Verwendung&nbsp;nicht-trennbarer
> Leerzeichen heben wir uns deutlich von anderen Radfahrer-Magazinen
> ab.</p><p>Durch&nbsp;die Verwendung&nbsp;nicht-trennbarer
> Leerzeichen heben wir uns deutlich von anderen Radfahrer-Magazinen
> ab.</p><p>Nach <i>Kursivschrif</i>&#x202F; wird noch etwas Leerraum
> hinzugef&uuml;gt</p><p>Subtile Ver&auml;nderungen erleichtern das Lesen
> des Wortes "Schiff&#x2009;fahrt".</p><script
> type="text/javascript">
>
> function srp( parent, code )
> {
> parent.innerHTML = parent.innerHTML.replace
> ( new RegExp( "\\#x" + code + ";" ),
> "<span style='background: rgb(190,190,190);'>" + "&#x" + code +
> ";" + "</span>" );
>
> n = new Number( "0x" + code )
> c = String.fromCharCode( n )
> parent.innerHTML = parent.innerHTML.replace
> ( c,
> "<span style='background: rgb(190,190,190);'>" + c + "</span>" ); }
>
> function processNode( node )
> { if( node.nodeType == Node.TEXT_NODE )
> { parent = node.parentElement;
> ok = parent.nodeName in{ "P":0, "H1":0 /* ... */ }
> if( ok )
> {
> parent.innerHTML = parent.innerHTML.replace
> ( /&nbsp;/g,
> "<span style='background: rgb(190,190,190);'>" +
> String.fromCharCode( 160 )+ "</span>" );
>
> srp( parent, "202F" );
> srp( parent, "2009" ); }}}
>
> function walk( domObject, extractorCallback )
> { if( !domObject )return;
> processNode( domObject );
> if( domObject.nodeType != Node.ELEMENT_NODE )return;
> const childs = domObject.childNodes;
> for( let i = 0; i < childs.length; ++i )walk( childs[ i ]); }
>
> walk( document.body )
>
> </script></body></html>

Ich verstehe den Code mangels Kenntnissen nicht, sehe aber, dass
"<span ...>" dreimal vorkommt.
Das erschwert etwas die Wartbarkeit.
Ich schrieb ja im letzten Posting, dass ich "Custom Elements"
verwende, statt "<span>", weil das die moderne, prägnantere und besser
lesbare Technik ist.

Und auch für die Wartbarkeit und Lesbarkeit des Skriptes bezüglich der
verschiedenen Leerzeichen, wäre es ideal, wenn jedes Leerzeichen ein
anderes "Custom Element" bekommen kann. Denn sonst wären sie ja nicht
mehr unterscheidbar.

IMHO sowas in der Art:

// Nicht anwenden in diesen Elementen:
// mjx-container

[Skriptcode]

// Unicode: U+00A0
// Name: NO-BREAK SPACE
// Entity: &nbsp;
// HTML Custom Element: <fz-nbsp>

[Skriptcode]

// Unicode: U+202F
// Name: NARROW NO-BREAK SPACE
// Entity: &#x202F;
// Custom Element: <fz-nbsp>

[Skriptcode]

// Unicode: U+2009
// Name: THIN SPACE
// Entity: &#x2009;
// Custom Element: <fz-nsp>

[Skriptcode]

Was denkst Du bitte zu diesen Ideen?

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 28, 2023, 6:55:05 AM5/28/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Was denkst Du bitte zu diesen Ideen?
>
> Mir sind seit gestern zwei Mängel meines Skripts durch den Kopf
> gegangen:
>
> 1. Durch die Verwendung von "innerHTML" könnten die Zeichen auch
> dann ersetzt werden, wenn sie beispielsweise als Attributwerte
> vorkommen würden. Um das zu verhindern, ist es besser auf
> "innerHTML" zu verzichten, was den Code aber etwas aufwendiger
> machen wird.
>
> 2. Der Code wartet nicht explizit, bis das Dokument vollständig
> geladen wurde, wodurch er vielleicht schlechter funktioniert,
> wenn man ihn weiter nach oben bewegt. Vielleicht ist das eine
> Erklärung dafür, daß einige Absätze bei Dir nicht behandelt
> wurden.
>
> Diese Mängel möchte ich noch beheben, danach werde ich Deine
> Wunschliste dann auch noch einmal durchgehen. Bis das Ergebnis
> dieses Prozesses vorliegt, könnte aber etwas Zeit vergehen.
> Ich rechne mit Ergebnissen frühestens heute abend, es könnte
> aber auch länger dauern oder sich als gar nicht möglich erweisen.

Das hat keinerlei Eile lieber Stefan.

Ich möchte Dich mit dieser Bitte auch auf keinen Fall belästigen.
Das weißt Du hoffentlich.
Bitte nur dranbleiben, wenn Du es selber auch etwas interessant
findest.

Die Aufgabe "Unsichtbare Zeichen sichtbar zu machen" halte ich
jedenfalls für so universell nützlich für beliebige Websites, dass es
natürlich großartig wäre, wenn ein zuverlässiges allgemeinverfügbares
Skript herauskäme.




Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 28, 2023, 2:45:05 PM5/28/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Stefan Ram:
>>>Dieses Skript hier ersetzt auch in mehreren Absätzen. Allerdings
>>>kann es sein, daß die hier eingesetzte Technik bei anderem
>>>oder komplizierterem Aufbau des Dokuments doch versagt.
>>Gäbe es denn andere Techniken, die vorhersagbar zuverlässig bei
>>umfangreichem und komplexem HTML sind?
>
> Inzwischen ist das Skript durch die Vermeidung von "innerHTML"
> und eine rekursive Funktion "walk" etwas robuster geworden.
> Ich habe jetzt einige p-Elemente in ein div-Element eingesetzt,
> um zu sehen, ob sie auch dann noch richtig verarbeitet werden.
> Die früheren unnötigen doppelten Ersetzungen sind verschwunden.

Das Skript funktioniert auf Anhieb und ich finde es sehr gut lesbar
und problemlos erweiterbar um weitere Zeichen.

Nochmal herzlichen Dank, Stefan! :)

https://borumat.de/-/fahrradzukunft/invisibles

Ich habe, wie schon zuvor, die <span> durch "Custom Elements" ersetzt
und das CSS ausgelagert.

>>Wichtig wäre auch, dass es nicht mit anderen JS kollidiert.
>
> Mit diesem Thema habe ich leider keine Erfahrung. Es ist für
> mich nicht vorhersehbar, welche Probleme es bei der Integration
> meines Skripts mit anderem JavaScript-Skripten geben könnte.
> Dies hängt auch davon ab, wie die Integration genau stattfindet.

Das werde ich in den nächsten Tagen testen und hier berichten.

>>Ideal wäre es, wenn die Technik des Skriptes (wir könnten es
>>"invisibles.js" nennen) z.B. erlaubt Elemente (und ihre Kinder)
>>auszuschließen.

Funktioniert.

> Ja, es sollte auch als externes JavaScript in einer extra-Datei
> laufen können, ich habe dies aber nicht getestet.

Ich habe das JS ausgelagert. Funktioniert.
Siehe Link oben.

> Auf der Ebene des Objektmodells gibt es wohl keine
> Entitätsreferenzen. Daher suche ich nun nicht mehr nach
> "&nbsp;" oder "&#x00A0", sondern nur noch nach /Zeichen/
> mit dem entsprechenden Code.

Sehr gut. Das sehe ich als Vorteil.

Ich werde weitere Praxistests in den nächsten Tagen durchführen und
dann hier berichten.

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 28, 2023, 3:09:14 PM5/28/23
to
Andreas Borutta:

>>>Wichtig wäre auch, dass es nicht mit anderen JS kollidiert.
>>
>> Mit diesem Thema habe ich leider keine Erfahrung. Es ist für
>> mich nicht vorhersehbar, welche Probleme es bei der Integration
>> meines Skripts mit anderem JavaScript-Skripten geben könnte.
>> Dies hängt auch davon ab, wie die Integration genau stattfindet.
>
> Das werde ich in den nächsten Tagen testen und hier berichten.

Mit Mathjax kollidiert es nicht.
Ich habe den LaTeX-Code im Element <article> platziert, dort die
Verwendung von invibles.js also ausgeschlossen.

Siehe:
https://borumat.de/-/fahrradzukunft/invisibles

Kleinigkeit bitte noch, Stefan:

Wie muss der Code bitte lauten, wenn ich neben <article> weitere
Elemente ausschließen möchte?

Wenn ich es richtig sehe, muss "ARTICLE" zwingend in Großbuchstaben
geschrieben werden, richtig.

Oder wäre auch Skriptcode möglich, der die in HTML übliche
Schreibweise in Kleinbuchstaben erlaubt?

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 28, 2023, 4:56:43 PM5/28/23
to
Stefan Ram:

>>Wie muss der Code bitte lauten, wenn ich neben <article> weitere
>>Elemente ausschließen möchte?
>
> Hierzu kannst Du die Zeile
>
> if( domObject.nodeName == "ARTICLE" )return;
>
> beispielsweise durch die beiden Zeilen
>
> if( domObject.nodeName == "ARTICLE" )return;
> if( domObject.nodeName == "DIV" )return;
>
> ersetzen, um zum Beispiel auch div-Elemente auszuschließen.
>
>>Wenn ich es richtig sehe, muss "ARTICLE" zwingend in Großbuchstaben
>>geschrieben werden, richtig.
>
> Man könnte die Zeile durch die folgende Zeile ersetzen.
> Dann muß man zwingend /Kleinschreibung/ verwenden.
>
> if( domObject.nodeName.toLowerCase() == "article" )return;

Funktioniert.
Ist eingepflegt.
Plus ein paar Kommentarzeilen dazu.

https://borumat.de/-/fahrradzukunft/invisibles

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 28, 2023, 5:14:26 PM5/28/23
to
Andreas Borutta:

> Ich habe [...] das CSS ausgelagert.

Was denkst Du, Stefan, dazu, die bisher in Deinem originalen Skript
verwendete Technik "Inline-CSS-Styles" durch <styles>...</styles> zu
ersetzen, welches vom JS im HTML-Element Head eingefügt wird?


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 29, 2023, 4:15:29 AM5/29/23
to
Stefan Ram:

> if( domObject.nodeName.toLowerCase() in{ "article":0, "div":0 })return;

Ich habe noch eine Idee.

Im Ideal steht in gut anpassbaren Skripten jeder Wert/jedes Wertepaar,
welches der Nutzer typischerweise ändert oder ergänzt, in einer Zeile.

Ein Array und ein mehrdimensionaler Array am Kopf des Skriptes wäre
elegant, das Folgende ist nur eine laienhafte Skizze.


const exclude_elements = [

// Liste auszuschließender HTML-Elemente.
// Wichtig! Nur Kleinbuchstaben verwenden. Am Ende der Zeile immer ein
Komma.
"foo",
"bar",
// Ende der Liste

];


const pairs_unicode_custom_elements = [

// Liste von Paaren aus Unicode-Zeichen und umhüllendem
// HTML-Custom-Element <https://www.w3.org/TR/custom-elements/>
// Wichtig! Keine Entities eingeben. Am Ende der Zeile immer ein
Komma.
[0x00A0, "x-nbsp"],
[0x202F, "x-nnbsp"],
[0x2009, "x-tsp"],
// Ende der Liste

];

Wie findest Du diese Idee?

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 29, 2023, 4:28:03 AM5/29/23
to
Stefan Ram:

>>>Ich habe [...] das CSS ausgelagert.
>>Was denkst Du, Stefan, dazu, die bisher in Deinem originalen Skript
>>verwendete Technik "Inline-CSS-Styles" durch <styles>...</styles> zu
>>ersetzen, welches vom JS im HTML-Element Head eingefügt wird?
>
> Die "style="-Attribute hatte ich nur zur Vereinfachung verwendet.
>
> Als ich mich das letzte Mal damit beschäftigte hatte (vor 7 Jahren?)
> war die Empfehlung für professionelle Seiten, daß die HTML-Ressource
> möglichst nur HTML enthält. Die Stilfestlegungen sollten in
> externen CSS-Ressourcen stehen und das JavaScript in externen
> JS-Ressourcen. Wenn man einem Element ein Erscheinungsbild geben
> will, sollte man ihm dazu eine entsprechende Klasse geben und das
> Erscheinungsbild der Klasse dann in einer CSS-Ressource festlegen.
> Im Idealfall sollten auch alle Elementattribute, die irgendwie
> mit JavaScript zu tun haben, überhaupt erst durch JavaScript zur
> Seite hinzugefügt werden, und die Seite sollte bereits ohne CSS und
> JavaScript in einer sinnvollen Basisversion im Browser erscheinen.

Volle Zustimmung.

Hier reden wir jedoch über ein Skript, welches nur im Lektoratsprozess
eingesetzt wird, also temporär.

Nur deshalb erschien es mir hier sinnvoll, statt eines externen CSS
die Regeln im Element <style> zu platzieren.

Einziges Motiv: es muss nur eine Datei zum Anpassen bearbeitet werden
(JS) statt zwei (JS und externes CSS).

Aber wenn ich jetzt länger drüber nachdenke ist es vielleicht doch
sinnvoll mit dem externen CSS zu arbeiten.

Ist sauberer.

Lassen wir es also, wie es ist : ) Danke für Deine Sicht.

> PS:
>
> symbol = String.fromCharCode( codePoint );
>
> sollte ein "const " ganz am Anfang haben:
>
> const symbol = String.fromCharCode( codePoint );

Ist eingepflegt.


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 29, 2023, 6:37:36 AM5/29/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Ein Array und ein mehrdimensionaler Array am Kopf des Skriptes wäre
>>elegant, das Folgende ist nur eine laienhafte Skizze.
>
> Ja, es gäbe vielleicht etwas, das die Zusammenarbeit mit anderen
> Skripten noch verbessern könnte. Ein Problem kann auftreten, wenn
> ein anderes Skript einen globalen Namen (einem Namen, der nicht mit
> "const" oder "let" in einer Funktion definiert wurde) ebenfalls
> verwendet. Um dies zu vermeiden, kann man heute /Module/ verwenden,
> welche die Zahl externer Namen reduzieren können. Alternativ könnten
> alle im Skript verwendeten globalen Namen so modfiziert werden,
> daß ihr Vorkommen in weiteren Skripten unwahrscheinlich wird.
> Insbesondere kurze Namen wie "A" und allgemein übliche Namen wie
> "main" sollten daher eigentlich vermieden werden.

Vielen Dank : )
Das Skript mit den Arrays im Kopf ist jetzt viel leichter anpassbar.
Gefällt mir sehr gut.

<https://borumat.de/-/fahrradzukunft/invisibles>

> function processNode( node )
> { if( node.nodeType == Node.TEXT_NODE )
> { const parent = node.parentElement;
> const ok = parent.nodeName in{ "P":0, "H1":0 /* ... */ }
> /* Hinweis: Nicht vergessen, obiges "ok" je nach
> Bedarf um die Typen aller Elemente zu erweitern,
> in denen Ersetzungen stattfinden sollen! */

Hier verstehe ich etwas konzeptionell noch nicht.

Mir ist jetzt erst aufgefallen, dass ich HTL-Elemente explizit
hinzufügen muss, die behandelt werden sollen.
Sozusagen Opt-In.

Wir haben bereits eine Funktion, die es erlaubt, Elemente
auszuschließen (wo eine Anwendung des Skriptes kritisch sein könnte -
wie z.B. ein von einem anderen JS wie MathJax hinzugefügtes Element,
oder wo eine Anwendung unerwünscht ist, wie z.B. in <pre> oder
<code>).

Wäre es vor diesem Hintergrund nicht sinnvoll und praktisch, wenn
automatisch alle HTML5-Elemente vom Skript behandelt werden?
Denn das ist ja der typische Usecase.

Auch alle HTML-Custom-Elemente, die mit einem spezifischen Präfix mit
Minus dahinter im Elementnamen eingeleitet werden, sollten automatisch
vom Skript behandelt werden.
Auf ein solches Präfix müsste sich natürlich der Webauthor im Kopf des
Skriptes festlegen.


Beispiel:
Präfix Custom-Elements "x-"
Namensbeispiel Custom-Element "x-foo"


So eine scheinbar recht kleine Aufgabe "Unsichtbare Zeichen sichtbar
machen" hat es doch ganz schön in sich.


Die neuen Skriptteile zum Erzeugen eines Links zum externen Stylesheet
bzw. zum Einbetten von <style> im <head> muss ich mir noch genauer
anschauen. Die Funktionsweise und die Möglichkeit das zu deaktivieren,
habe ich noch nicht durchdrungen.

Mittlerweile neige ich eh dazu, Stilregeln gar nicht in das JS zu
integrieren. Da habe ich meine Sicht geändert.


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 29, 2023, 1:50:37 PM5/29/23
to
Stefan Ram:

>>Hier verstehe ich etwas konzeptionell noch nicht.
>>Mir ist jetzt erst aufgefallen, dass ich HTL-Elemente explizit
>>hinzufügen muss, die behandelt werden sollen.
>>Sozusagen Opt-In.
>>Wäre es vor diesem Hintergrund nicht sinnvoll und praktisch, wenn
>>automatisch alle HTML5-Elemente vom Skript behandelt werden?
>>Denn das ist ja der typische Usecase.

> [...]
> Du kannst durch "const ok = true;" an Stelle von 'const ok =
> parent.nodeName in{ "P":0, "H1":0 /* ... */ }' (die Zeile
> sollte eigentlich ohnehin auch mit einem Semikolon ";" enden)
> erreichen, daß wirklich /alle/ Elemente, die nicht unter einem
> Element mit ausgeschlossenem Typ liegen, modifiziert werden.
> Aber das könnte, wie gesagt, zu Problemen führen (siehe unten).

Ich habe das eingepflegt. Tests mit komplexeren Dokumenten (mit
verschachtelten Elementen) stehen eh noch aus.

Ich werde berichten.

Grundsätzlich ist natürlich eine hohe Zuverlässigkeit des Skriptes
wichtig.

Und bei einem White-Listing wäre es nur eine Frage der Zeit, wann man
mal auf einer Website ein HTML-Element neu hinzunimmt und vergisst, es
im Skript zu ergänzen. Das Argument erwähnst Du selber ja weiter unten
ebenfalls.

>>Auch alle HTML-Custom-Elemente, die mit einem spezifischen Präfix mit
>>Minus dahinter im Elementnamen eingeleitet werden, sollten automatisch
>>vom Skript behandelt werden.
>
> Du könntest ganz am Anfang des Skriptes folgende Deklaration einfügen:
>
> const prefix = "x-";
>
> . Dadurch ist nun ein Präfix für Elemente festgelegt, die auf jeden
> Fall bearbeitet werden sollen.
>
> Der Anfang der Funktion "processNode" über der Zeile "if( ok )" könnte
> dann so aussehen:
>
> function processNode( node )
> { if( node.nodeType == Node.TEXT_NODE )
> { const parent = node.parentElement;
> const ok1 = parent.nodeName.toLowerCase().startsWith( prefix );
> const ok2 = parent.nodeName.toLowerCase() in
> { "p":0, "h1":0 /* ... */ };
> let ok3 = true;
> for( pairs_unicode_custom_element of pairs_unicode_custom_elements )
> { if
> ( parent.nodeName.toLowerCase() ==
> pairs_unicode_custom_element[ 1 ])
> ok3 = false; }
> const ok =( ok1 || ok2 )&& ok3;
>
> /* Hinweis: Nicht vergessen, obiges "ok2" je nach
> Bedarf um die Typen weiterer Elemente zu erweitern,
> in denen Ersetzungen stattfinden sollen! */

Das habe ich jetzt so eingepflegt.

Aber ich habe Sorge bei den diversen Änderungen doch Fehler
einzubauen.

Bist Du bitte nochmal so nett und führst folgende Änderungen am Skript
durch:

1
Entfernung der Skriptteile für Whitelisting

2
Ergänzung der Blacklist mit "head"

3
Entfernung der Skriptteile, wo man CSS-Regeln angeben kann
<style> ...

4
Entfernung der Skriptteile, wo man ein externes Stylesheet angeben
kann

5
Ergänzung der Deklaration der Konstante für das Prefix im Kopf des
Skriptes.
Namensvorschlag: prefix_custom_element

6
Beim mehrdimensionalen Array steht zur Zeit ein Name im Plural:
pairs_unicode_custom_elements (hatte ich ja so vorgeschlagen)
Entspricht das guter Praxis für Benennungen?
Oder wäre Singular besser?
pair_unicode_custom_element
oder darf man ein "&" verwenden im Namen für mehrdimensionale Arrays?
unicode&custom_element


Durch diese Änderungen fokussieren wir uns auf den Kern der Aufgabe:

a Umhüllung von spezifischen Unicodezeichen mit HTML-Custom-Elements
b Option zum Blacklisting ausgewählter Elemente, zur Sicherheit

CSS kann problemlos manuell als externes Stylesheet eingebunden
werden.
So bleibt die Aufgabe "Gestaltung der umhüllten Unicodezeichen"
getrennt vom Skript.

Ich kann mich erst am späteren Abend wieder melden. Aber eine Antwort
hat auch keine Eile lieber Stefan.

Andreas
--
http://fahrradzukunft.de

Peter J. Holzer

unread,
May 29, 2023, 4:16:07 PM5/29/23
to
On 2023-05-29 19:50, Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>>Beim mehrdimensionalen Array steht zur Zeit ein Name im Plural:
>>pairs_unicode_custom_elements (hatte ich ja so vorgeschlagen)
>
> Das ist eine interessante Frage! Ich hatte früher zum Singular
> geneigt, da "element[ 5 ]" auf deutsch ja "Element fünf" wäre und
> nicht "ElementE fünf". Andererseits sind "element" aber /mehrere/
> Argumente. Die Lösung wäre vielleicht eine Programmiersprache,
> die Singular und Plural versteht,

Perl. $ ist Singular, @ ist Plural.
Daher schreibt man @foo, wenn man das ganze Array meint, $foo[2], wenn
man ein Element meint, und @foo[0, 3], wenn man mehrere Elemente meint.

Leider ist die Syntax mit keiner natürlichen Sprache kompatibel ;-).

hp

Andreas Borutta

unread,
May 29, 2023, 5:08:50 PM5/29/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Bist Du bitte nochmal so nett und führst folgende Änderungen am Skript
>>durch:
>
> Ja, das werde ich dann morgen in Angriff nehmen.

Ich freue mich wirklich sehr, dass Du das Skript geschrieben hast und
es jetzt hier diskutierst und veränderst. Danke.

>>Grundsätzlich ist natürlich eine hohe Zuverlässigkeit des Skriptes
>>wichtig.
>
> Mein Skript ist für Diskussionszwecke im Rahmen der Newsgroup
> gedacht. Ich habe zwar nichts gegen die Verwendung auf
> Web-Seiten einzuwenden, aber gebe keine Garantien über die
> Zuverlässigkeit meines Skriptes ab. Das Risiko trägt also
> derjenige, welcher entscheidet, das Skript einzusetzen - außer
> in den Fällen, in denen meinen Haftung nicht ausgeschlossen
> werden /kann/, wie zum Beispiel bei Vorsatz.

Das ist völlig klar lieber Stefan.

> (Um eine hohe Zuverlässigkeit eines Skriptes zu erreichen,
> ist es im professionellen Bereich wichtig, mit /mehreren guten
> Designern, Programmierern und Testern/ zu arbeiten, da dann
> Spezifikationen, Code-Reviews und Tests eingesetzt werden sollten,
> die von /anderen Personen/ kommen sollten als dem Programmierer.)

Mein Ziel ist jedenfalls, dass aus dieser Idee in diesem Thread ein
zuverlässiges universell verwendbares Skript wird. Ich hoffe, es
springen noch einige kundige Leute auf, damit das zur Reife gebracht
werden kann. Der Stand ist ja schon sehr weit fortgeschritten. Dank
Dir.

>>Beim mehrdimensionalen Array steht zur Zeit ein Name im Plural:
>>pairs_unicode_custom_elements (hatte ich ja so vorgeschlagen)

Unabhängig von der Frage Plural oder Singular:
Das Wort "pairs" erscheint mir überflüssig zu sein.
Die 2 Namen selbst sollten aus sich heraus zeigen, dass es sich um
einen zweidimensionalen Array handelt.

Also:
unicode_and_custom_element

Falls es einen standardisierten und prägnanteren "Kombinator" als
"and" für die Trennung der Bezeichner in mehrdimensionalen Arrays
gibt: schön.

Ich habe das Testcase erweitert:
https://borumat.de/-/fahrradzukunft/invisibles

Dort gibt es jetzt auch ein Elternelement in der Blacklist, mit einem
Kindelement in der Whitelist.

Das Kindelement wird vom Skript behandelt.

Es wäre gut, wenn Kindelemente von geblacklisteten Elementen nicht
behandelt würden. Das scheint mir die Intention von Blacklisting im
Kontext HTML zu sein.
Oder wie siehst Du das?

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 30, 2023, 2:12:45 PM5/30/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Die 2 Namen selbst sollten aus sich heraus zeigen, dass es sich um
>>einen zweidimensionalen Array handelt.
>
> Du sprichst die Frage an, welche Informationen ein Name enthalten
> sollte.

Genau, da bin ich einfach neugierig, was unter Programmierern als gute
Praxis gilt. Namen haben ja eine gewisse Bedeutung für die Lesbarkeit
von Code.

> Der Name sollte gerade die wichtigste Information enthalten,
> aber nicht unnötig lang sein. Was nun genau die wichtigste
> Information darstellt, wird subjektiv unterschiedlich beantwortet.
>
> Durch "_matrix" kann Zweidimensionalität angedeutet werden.

Welchen Namen fändest Du denn subjektiv für unseren zweidimensionalen
Array sinnvoll?

Der eine Wert enthält das Unicodezeichen.
Der andere Wert enthält das HTML Custom Element

Da wir mit dem Unicodezeichen eine eindeutige ID zu verfügung hätten,
ist vielleicht sogar ein assoziativer Array sinnvoll, oder was denkst
Du?

>>Es wäre gut, wenn Kindelemente von geblacklisteten Elementen nicht
>>behandelt würden.
>
> Ja, das sollte für direkte und indirekte Unterelemente nun gelten.
>
> Eine Antwort auf Dein voriges Posting mit der neuen Version des
> Skripts folgt noch separat.

Prima, schaue ich gleich an.


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 30, 2023, 2:25:24 PM5/30/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Bist Du bitte nochmal so nett und führst folgende Änderungen am Skript
>>durch:

> [...]

Erneut mein ganz herzlicher Dank, Stefan : )

Ich habe alles eingepflegt und das Testdokument ebenfalls angepasst.

https://borumat.de/-/fahrradzukunft/invisibles

Alles funktioniert.

Ich freue mich auch, dass Du noch einige Änderungen durchgeführt hast,
die wohl der Robustheit dienlich sind.

>>Ergänzung der Blacklist mit "head"
>
> 2 Bei "head" wollen wir jedoch wohl, daß auch /indirekte/
> Textinhalte nicht verändert werden. Deswegen sollte "head"
> zu der Reihung "exclude_elements" hinzugefügt werden, die solche
> Elementtypen enthält.

Was meinst Du bitte mit /indirekt/ in diesem Zusammenhang?


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 30, 2023, 2:55:31 PM5/30/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Genau, da bin ich einfach neugierig, was unter Programmierern als gute
>>Praxis gilt. Namen haben ja eine gewisse Bedeutung für die Lesbarkeit
>>von Code.
>
> Der Name sollte so kurz wie möglich und so lang wie nötig sein.
>
> Der Name sollte die Information liefern, die nicht bereits aus
> dem Zusammenhang offensichtlich ist.

Diese Empfehlung für den hier diskutierten zweidimensionalen Array
anzuwenden fällt mir schwer.
Das Unicodezeichen hat ein Muster, welches ein Nutzer, der mit Unicode
hantiert sicher gut erkennen kann.
Bei den Custom-Elements ist wohl nicht offensichtlich.

Aber lassen wir dieses Nebenthema auf sich beruhen. Es war ja nur ein
kurzer Ausflug.

>|Name paralysis happens when you get stuck on a naming issue
>| [...]

Eine völlig berechtigte Kritik/Warnung.

Aus meinem eigenen Empfinden liegt die Wahrheit dazwischen.

Es geht darum eine angemessene Zeit in Suche nach gute Namen zu
stecken, damit Code gut zu lesen ist, auch von denjenigen, die ihn
nicht geschrieben haben.
Findet man nicht fix einen, geht man halt pragmatisch vor.

In unserem Beispiel könnte das sein:

// Wertepaar aus Unicodezeichen und umhüllendem Custom-Element

const u_ce_matrix =

und weiter unten dann:

( const u_ce
of u_ce_matrix )




Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 30, 2023, 2:59:38 PM5/30/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Stefan Ram:
>>>2 Bei "head" wollen wir jedoch wohl, daß auch /indirekte/
>>>Textinhalte nicht verändert werden. Deswegen sollte "head"
>>>zu der Reihung "exclude_elements" hinzugefügt werden, die solche
>>>Elementtypen enthält.
>>Was meinst Du bitte mit /indirekt/ in diesem Zusammenhang?
>
> Ich meine: In "<p>abc<span>def</span></p>" ist "def" /direkt/ in
> einem span-Element enthalten und /indirekt/ in einem p-Element.

Dann verstehe ich Dich und teile Deine Bewertung.

Auch solche /indirekten/ Textinhalte sollten nicht behandelt werden.

So hatte ich auch es auch gemeint, dass es im Kontext mit Eltern und
Kindelementen dem ganzen Konzept der Vererbung entspricht.

Schön. Das Skript ist jetzt schon sehr rund.
Freut mich sehr!

Wenn Du Dich mal auf ein Bier einladen lassen möchtest, lasse es mich
wissen : ) Wir wohnen ja in derselben Stadt.

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 31, 2023, 5:36:51 AM5/31/23
to
> Das wäre dann als Abbildung ("Wörterbuch"/"dictionary"):
>
> const type_of_codepoint =
> { 0x00A0: "x-nbsp",
> 0x202F: "x-nnbsp",
> 0x2009: "x-tsp" };
>
> console.log( type_of_codepoint( 0x202F ))
>
> , Ausgabe in das Konsolenlog: x-nnbsp.
>
> Statt "type_of_codepoint" reicht manchmal auch schon "type_of".

Auch eine elegante Schreibweise/ein elegantes Konzept.

> Daß es Wertepaare sind, muß nicht unbedingt im Kommentar stehen,
> weil es der Quellcode bereits enthüllt. Was in einem guten
> Kommentar stehen sollte, das behandelt Robert C. Martin in Kapitel 4
> "Kommentare" seines empfehlenswerten Werks "Clean Code" von 2008.

Mit dem Thema muss ich mich beschäftigen, wenn ich - nicht von mir
verfasste Skripte - kommentiere. Danke für die Anregung.

Falls andere Mitleser zu der Frage Texte empfehlen können, die im Netz
verfügbar sind: gern.

Unabhängig davon:
Was mich aus persönlicher Neugier interessiert:

Wie bewertet ihr Programmierer Sprachen, wo Zeilenumbrüche und
Einrückungen Teil der Syntax sind, wo sie also interpretiert werden?

Solche Sprachen erlauben ja Code mit deutlich weniger Steuerzeichen.




Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 31, 2023, 7:22:48 AM5/31/23
to
> Da fällt mir erst einmal Python ein und dann vielleicht noch YAML.
>
> Ich habe eigentümliche Vorstellungen von Formatierung und bin
> nicht glücklich, wenn ich diese nicht umsetzen kann. Daher
> erwartete ich, daß ich mit Python nicht glücklich sein würde.
>
> Die Einrückung von Python hat sich für mich aber nicht als
> Problem erwiesen. Dazu trägt bei, daß sie zu 90 Prozent ohnehin
> so ist, wie dies für mich akzeptabel ist, und die anderen
> 10 Prozent von mir angepaßt werden können.
>
> Also würde ich sagen: Ob der Zwang zu Einrückung akzeptabel
> ist, hängt davon ab, wie er im Detail realisiert wird, und
> bei Python ist er für mich akzeptabel.
>
> In meinen Programmierkursen hat es mich schon gestört,
> wenn Kursteilnehmer C-Programme nicht gut eingerückt haben,
> aber es war schwer durchzusetzen, wenn die Teilnehmer sagen
> können: "Aber es funktioniert doch so!". Dieses Problem gibt
> es in Python-Kursen nicht.

Danke für den Einblick und die Bewertung : )

Zum Skript "invisible.js" noch:

Deine Arbeit wurde im xhtmlforum.de sehr gelobt.

Das Kompliment reiche ich also gerne weiter.

In dem Forum hatte ich die Frage nach einem Skript gepostet, einige
Tage bevor ich es hier tat.


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
May 31, 2023, 2:24:18 PM5/31/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Deine Arbeit wurde im xhtmlforum.de sehr gelobt.
>
> Danke! Das freut mich zu hören. Genauso wie
>
>|Das Skript ist jetzt schon sehr rund.
>
> aus <pid89yi9zupg$.d...@borumat.de>.
>
> (Einerseits sehe ich natürlich immer noch Verbesserungsmöglichkeiten,
> andererseits denke ich: "Irgendwann muß Schluß sein.", denn man kann
> alles immer noch verbessern, aber dann wird man nie mit etwas fertig.)

Vom Bedienkomfort sehe ich keine weitere Verbesserungsmöglichkeit.
Das ist jetzt wunderbar übersichtlich.

Wenn Dir noch Techniken einfallen, die die Zuverlässigkeit verbessern,
fühle Dich bitte jederzeit frei : )




Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 2, 2023, 10:38:18 AM6/2/23
to
Stefan Ram:

>|Das Skript ist jetzt schon sehr rund.

Bisher habe ich ja im Kopf des Skriptes Deine Urheberschaft namentlich
erwähnt.

Hast Du mal überlegt es unter eine Creative Commons Lizenz zu stellen?
Dann wüßten Interessierte, ob und unter welchen Bedingungen sie es
verwenden dürfen.

Ich trage gerne ein, was Du Dir wünscht.

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 2, 2023, 11:36:52 AM6/2/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Ich trage gerne ein, was Du Dir wünscht.
>
> Lizenz: Die JavaScript-Programmteile, welche von mir im Mai 2023
> in der Usenet-Newsgroup "de.comp.lang.javascript" veröffentlicht
> wurden, dürfen unentgeltlich kopiert, modifiziert und verwendet
> werden, selbst ohne Nennung meines Namens und für kommerzielle
> Zwecke, wenn dabei anerkannt wird, daß meine Haftung für sie bis
> zum Maximum dessen, was gesetzlich möglich ist, ausgeschlossen ist.

Ist drin.

Andreas Borutta

unread,
Jun 4, 2023, 5:42:37 AM6/4/23
to
Andreas Borutta:

> Das Skript ist jetzt schon sehr rund.

Ich habe, wie versprochen, noch einen weiteren Test mit einem
umfangreichen (natürlich validen) HTML-Dokument durchgeführt:

https://borumat.de/-/fahrradzukunft/invisibles-2

Hier greift das Skript an diversen Stellen noch nicht.

Beispiele mit Zeilennummern mit aus dem Quelltext:

513: 250&#8239;%

515: 25&#8239;km/h

535: 16&#8239;kg

598: 100&#8239;km

...


Ich kann bisher keine Randbedingungen erkennen, die als Ursache in
Frage kommen.

Ich habe auch einen Test durchgeführt, wo ich alle
&#8239;
durch
&#x2009;
ersetzt habe.

Keine Änderung.


Hier noch eine Kopie des Quelltextes des HTML-Dokumentes als
TXT-Dokument:

https://borumat.de/-/fahrradzukunft/invisibles-2.txt

Stefan, oder andere Mitleser, seht ihr eventuell, woran es haken
könnte?



Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 4, 2023, 7:23:38 AM6/4/23
to
Andreas Borutta:

> Ich habe, wie versprochen, noch einen weiteren Test mit einem
> umfangreichen (natürlich validen) HTML-Dokument durchgeführt:
>
> https://borumat.de/-/fahrradzukunft/invisibles-2
>
> Hier greift das Skript an diversen Stellen noch nicht.
> [...]
> Ich kann bisher keine Randbedingungen erkennen, die als Ursache in
> Frage kommen.

Hier noch ein Test, wo das Skript am Ende des Dokumentes steht.

https://borumat.de/-/fahrradzukunft/invisibles-3

Es hat keine Auswirkung.

Getestete Browser:
Firefox macOS
Chrome macOS
Safari macOS

Irgendwas bringt das Skript aus dem Tritt.

Und wie es scheint erst ab der erwähnten Zeile 513. Danach wird kein
Fundort mehr getroffen.

Und vor Zeile 513 werden alle Fundorte getroffen.


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 4, 2023, 11:54:08 AM6/4/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Beispiele mit Zeilennummern mit aus dem Quelltext:
>>513: 250&#8239;%
>
> Inzwischen habe ich nun eine neue Version des Skriptes erstellt,
> bei der dieses Problem hoffentlich nicht mehr auftritt.

Dafür erstmal Danke.

> Dabei habe ich die Schreibweise zur Definition der zu suchenden
> Texte etwas verändert:
>
> const typeForString =
> { /* String - Doppelpunkt - Elementtyp - Komma */
> [ String.fromCharCode( 0x00A0 /* sedezimal */ )]: "x-nbsp",
> [ String.fromCharCode( 0x2009 /* sedezimal */ )]: "x-tsp",
> [ String.fromCharCode( 8239 /* dezimal */ )]: "x-nnbsp"
> /* =&#x202F; */, };

Verstehe ich es richtig, dass jetzt mit Hilfe von regulären Ausdrücken
gesucht wird?

Falls ja:

1 Ist das wirklich robust? Ich kann die kritischen Situationen nicht
übersehen.

2 Müsste man jedes Vorkommen des Strings "8239" irgendwo im
HTML-Quelltext, was nicht Teil von "&#8239;" ist, speziell
"behandeln"? Müsste man also an sowas "denken"?

3 Würden verschiedene Entities desselben Unicodezeichens und das
Unicodezeichen selbst (ich kann es hier im Usenet-Posting leider nicht
darstellen) ebenfalls vom Skript erfasst?
Beispiel:
&#8239;
&#x202F;
[Unicodezeichen U+202F]

Wenn ich den regEx oben richtig interpretiere, vermutlich nicht, oder?
Man müsste jedes denkbare Entity und das Unicodezeichen selbst in
einem ODER-Ausdruck auflisten, richtig?

4 Falls sich die Verwendung von regulären Ausdrücken für das Skript
nicht vermeiden lässt, kann man den Anwendungsbereich auf den Inhalt
von HTML-Elementen beschränken?




Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 4, 2023, 1:15:22 PM6/4/23
to
Stefan Ram:

> Man sollte das ganze einfacher so schreiben:
>
> const typeForString =
> { /* String - Doppelpunkt - Elementtyp - Komma */
> "\xA0": "x-nbsp",
> "\u2009": "x-tsp",
> "\u202F": "x-nnbsp", };
>
> Meine vorige Variante war unnötig kompliziert. Es reicht vermutlich,
> wenn Du dir merkst, daß Du darin hinter dem "\u" vier hexadezimale
> Ziffern für das zu suchende Zeichen einsetzen kannst.
>
> "\u202F" ist ein Zeichenfolgenliteral für einen regulärer Ausdruck,
> der genau das Zeichen U+202F erkennt.

Darauf hätte ich kommen können, Verzeihung bitte.

Jetzt verstehe ich die Schreibweise.

>>3 Würden verschiedene Entities desselben Unicodezeichens und das
>>Unicodezeichen selbst (ich kann es hier im Usenet-Posting leider nicht
>>darstellen) ebenfalls vom Skript erfasst?
>
> Das sollte so sein, wurde aber nicht von mir getestet.
>
>>Wenn ich den regEx oben richtig interpretiere, vermutlich nicht, oder?
>>Man müsste jedes denkbare Entity und das Unicodezeichen selbst in
>>einem ODER-Ausdruck auflisten, richtig?
>
> Nein, das sollte nicht nötig sein. Dies wurde aber nicht von
> mir getestet.

Ich werde beides testen und berichten.

>>4 Falls sich die Verwendung von regulären Ausdrücken für das Skript
>>nicht vermeiden lässt, kann man den Anwendungsbereich auf den Inhalt
>>von HTML-Elementen beschränken?
>
> Nachdem "innerHTML" entfernt wurde, sollte das Skript jetzt
> immer nur im Textinhalt von Elementen suchen.

Prima.

Postest Du bitte nochmal das vollständige Skript.


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 4, 2023, 6:36:25 PM6/4/23
to
Stefan Ram:

>>Postest Du bitte nochmal das vollständige Skript.
>
> Ok,

https://borumat.de/-/fahrradzukunft/invisibles

Das Testcase habe ich erweitert um verschiedene Entities und auch das
Unicodezeichen selbst.
Klappt.

https://borumat.de/-/fahrradzukunft/invisibles-2

Auch hier finde ich keine Fehler in der Ausgabe : )

Mein IDE zeigt jedoch zwei Fehler zum Skriptcode:
https://borumat.de/-/fahrradzukunft/invisibles.js

Zeile 113: "elementType" is assigned a value but never used.

Zeile 161: "event" is assigned a value but never used.

Kleine Syntaxfrage:

Du verwendest für
const typeForString
"{}"
für
const excludeElements
jedoch
"[]"

Ist das bewußt so gewählt, oder sind das einfach gleichwertige
Alternativen?

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 5, 2023, 9:48:19 AM6/5/23
to
Stefan Ram:

>>Zeile 113: "elementType" is assigned a value but never used.
>
> Ja, in der Funktion "replaceCertainStringsByAnElement" ist die
> Zeile "const elementType = parent.nodeName.toLowerCase();"
> überflüssig

OK, ich habe sie entfernt.

>>Zeile 161: "event" is assigned a value but never used.
>
> Das ist vermutlich die letzte Zeile des Skripts.

Richtig.

> In diesem Fall
> ist das Absicht und kein Fehler. Wahrscheinlich steht bei Deiner
> Meldung auch nicht wirklich das Wort "error". Es ist nur ein
> Hinweis der IDE.

Es steht zwar der Hinweis "error", aber ich lasse es so. War nur
neugierig, hätte ja sein können, dass es sich um etwas Relevantes
handelt.

>>Du verwendest für
>>const typeForString
>>"{}"
>>für
>>const excludeElements
>>jedoch
>>"[]"
>>Ist das bewußt so gewählt, oder sind das einfach gleichwertige
>>Alternativen?
>
> Die beiden Schreibweisen haben unterschiedliche Bedeutungen:
> [...]

Danke für die Klarstellung.

Und danke nochmal für das gut funktionierende Skript : )

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 5, 2023, 12:17:09 PM6/5/23
to
Stefan Ram:

>>Es steht zwar der Hinweis "error", aber ich lasse es so.
>
> Das ist vermutlich ein "error" insofern es gegen die
> vorgegebene Richtlinien von ESLint verstößt, aber es
> verstößt nicht gegen Regeln von JavaScript.
>
> Möglicherweise könnte diese Meldung unterdrückt werden,
> indem die Zeile
>
> /*eslint no-unused-vars: ["error", {"args": "after-used"}]*/
>
> vor die vorletzte Zeile "window.addEventListener" eingefügt
> wird. Leider kann ich dies aber hier nicht testen.

Ich habe es getestet. Ändert nix an der Meldung.

Finde ich aber nicht weiter wichtig. Ich wollte nur wissen, ob Du
daraus einen Nutzen ziehen kannst.

Mein Editor für HTML ist übrigens "Brackets":
https://brackets.io/

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 5, 2023, 5:47:25 PM6/5/23
to
kStefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>Das Testcase habe ich erweitert um verschiedene Entities und auch das
>>Unicodezeichen selbst.
>
> Mein Skript sollte eigentlich ein Modul sein, um
> Namenskonflikte mit anderen Skripten zu vermeiden.

Das wäre, ganz im Sinne der Zuverlässigkeit, sehr nützlich.

> <script type="module" src="beispiel.js"></script>
>
> . Allerdings könnte es sein, daß zum Testen dann ein
> Web-Server verwendet werden muß:

Was meinst Du damit bitte?

Meine beiden Testcases laufen ja auf einem Webserver:

https://borumat.de/-/fahrradzukunft/invisibles
https://borumat.de/-/fahrradzukunft/invisibles-2


Andreas
--
http://fahrradzukunft.de

Peter J. Holzer

unread,
Jun 5, 2023, 6:07:24 PM6/5/23
to
On 2023-06-05 21:47, Andreas Borutta <bor...@gmx.de> wrote:
> kStefan Ram:
>> <script type="module" src="beispiel.js"></script>
>>
>> . Allerdings könnte es sein, daß zum Testen dann ein
>> Web-Server verwendet werden muß:
>
> Was meinst Du damit bitte?
>
> Meine beiden Testcases laufen ja auf einem Webserver:

Das ist schön für dich, aber normalerweise braucht man für HTML/CSS/JS
eben nicht unbedingt einen Webserver. Ein Browser kann das auch von der
lokalen Platte (mittels file:-URL) laden und das funktioniert genauso.
Ist beim Testen und Experimentieren oft ganz praktisch.

Stefen macht eben darauf aufmerksam, dass JS-Module (möglicherweise)
nicht mit file:-URLs funktionieren und ein Webserver notwendig ist.

hp

Andreas Borutta

unread,
Jun 5, 2023, 6:12:24 PM6/5/23
to
Andreas Borutta:

https://borumat.de/-/fahrradzukunft/invisibles


Aus Neugier:

Wenn ich mir in Firefox oder Chrome den "Seitenquelltext" ansehe, wird
dort das Entity

&nbsp;

ausgegeben.
Das entspricht der Erwartung, denn das steht im Quelltext.

Das Entity &#x202F; oder &#8239; jedoch nicht. Statt seiner statt
erscheint das Unicodezeichen.
Das entspricht nicht der Erwartung, denn die Entities stehen im
Quelltext.

Ist das eine Eigenschaft der Browser oder des Skriptes?

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 5, 2023, 6:17:38 PM6/5/23
to
Peter J. Holzer:
Danke für die Erklärung, gut zu wissen.

Ich wollte so realitätsnah wie möglich testen, daher habe ich immer
"auf dem Server" getestet.

@Stefan
type="module"

ist jetzt drin.
https://borumat.de/-/fahrradzukunft/invisibles

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 5, 2023, 6:35:13 PM6/5/23
to
Andreas Borutta:
Ich mach mal die Ingrid ; )

Das Phänomen tritt auch ganz ohne Skript auf.

Das Verhalten der Browser leuchtet mir nicht ein.

Warum wird das eine Entity im Quelltest ausgegeben, und das andere
nicht?


Andreas
--
http://fahrradzukunft.de

Peter J. Holzer

unread,
Jun 5, 2023, 6:35:16 PM6/5/23
to
On 2023-06-05 22:12, Andreas Borutta <bor...@gmx.de> wrote:
> Andreas Borutta:
>
> https://borumat.de/-/fahrradzukunft/invisibles
>
>
> Aus Neugier:
>
> Wenn ich mir in Firefox oder Chrome den "Seitenquelltext" ansehe,

Wie machst Du das? Wenn ich im Firefox Ctrl-U drücke (oder äquivalent
Rechte Maustaste -> View Page Source), dann ...

> wird
> dort das Entity
>
> &nbsp;
>
> ausgegeben.
> Das entspricht der Erwartung, denn das steht im Quelltext.
>
> Das Entity &#x202F; oder &#8239;

... sehe ich in Zeile 25 »bar&#x202F;bar</p>«
und in Zeile 28 »bar&#8239;bar</p>«,

Wenn ich hingegen einen Teil der Seite markiere und "View Selection
Source" auswähle, sieht es eher so aus wie von dir beschrieben. Aber das
ist der Inhalt *nachdem* das Script gelaufen ist: Man sieht da die Tags,
die das Script eingefügt hat, une egal ob da vorher &nbsp; oder &#160;
oder   stand, zeigt der Browser auf jeden Fall &nbsp; an. Zu dem
Zeitpunkt gibt es aber keinen "Source-Code" mehr, weil das, was Du auf
der Seite siehst und markiert hast, ja (teilweise) von einem Script
erzeugt wurde. Was Dir der Browser als "Source Code" zeigt, ist aus dem
DOM-Tree rekonstruiert. Und da wird ein U+00A0 immer gleich (als &nbsp;)
und ein U+202F auch immer gleich (einfach als Leerzeichen) angezeigt,
unabhängig davon, wie das erzeugt wurde (denn diese Information ist
nicht mehr vorhanden).

hp

Peter J. Holzer

unread,
Jun 5, 2023, 6:37:56 PM6/5/23
to
On 2023-06-05 22:35, Andreas Borutta <bor...@gmx.de> wrote:
> Warum wird das eine Entity im Quelltest ausgegeben, und das andere
> nicht?

Wird sie nicht. Vergleich mal die Absätze, in denen Du das gleiche
Zeichen auf verschiedene Art geschrieben hast.

hp

Andreas Borutta

unread,
Jun 5, 2023, 6:40:02 PM6/5/23
to
Peter J. Holzer:

> Wenn ich hingegen einen Teil der Seite markiere und "View Selection
> Source" auswähle, sieht es eher so aus wie von dir beschrieben.

Das meinte ich. Mein Fehler, hätte ich dazuschreiben sollen.

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 6, 2023, 2:33:34 AM6/6/23
to
Peter J. Holzer:
Im Quelltext kommen zwei Entities für zwei verschiedene Leerzeichen
vor:

&nbsp;
&#x202F;

Das erste wird bei "Auswahlquelltext" ausgegeben, das zweite nicht.

Kannst Du da bitte ein Beispiel nennen, was Du meinst?


Andreas
--
http://fahrradzukunft.de

Peter J. Holzer

unread,
Jun 6, 2023, 5:58:29 AM6/6/23
to
On 2023-06-06 06:33, Andreas Borutta <bor...@gmx.de> wrote:
> Peter J. Holzer:
>> On 2023-06-05 22:35, Andreas Borutta <bor...@gmx.de> wrote:
>>> Warum wird das eine Entity im Quelltest ausgegeben, und das andere
>>> nicht?
>>
>> Wird sie nicht. Vergleich mal die Absätze, in denen Du das gleiche
>> Zeichen auf verschiedene Art geschrieben hast.
>
> Im Quelltext kommen zwei Entities für zwei verschiedene Leerzeichen
> vor:
>
> &nbsp;
> &#x202F;

Nein, im Quelltext kommen drei verschiedene Arten, U+00A0 zu schreiben
vor:

<p>U+00A0 NO-BREAK SPACE<br>
&amp;nbsp; <br />
foo&nbsp;foo</p>
<p>U+00A0 NO-BREAK SPACE<br>
&amp;#160; <br />
foo&#160;foo</p>
<p>U+00A0 NO-BREAK SPACE<br>
Unicodezeichen <br />
foo foo</p>

»&nbsp;«, »&#160;« und » «. Alle drei aber werden bei "View Selectio
Source" aber als »&nbsp;« dargestellt.

Es hast auch U+202F auf zwei verschiedene Arten geschrieben:

<p>U+202F NARROW NO-BREAK SPACE<br>
&amp;#x202F; <br />
bar&#x202F;bar</p>
<p>U+202F NARROW NO-BREAK SPACE<br>
&amp;#8239; <br />
bar&#8239;bar</p>

Und beide werden gleich (als Leerzeichen - welche Art von Leerzeichen
ist optisch nicht erkennbar) ausgegeben.

Es wird also offensichtlich weder bei U+00A0 noch bei U+202F der
Quelltext ausgegeben. Sondern es wird im ersten Fall das Zeichen in
»&nbsp;« übersetzt, damit man es optisch erkennen kann, während es im
zweiten Fall einfach so ausgegeben wird (entweder weil die Entwickler
eine optische Kennzeichnung nicht für wichtig erachtet haben, oder weil
sie der Meinung waren, dass das störend wäre)

hp

Andreas Borutta

unread,
Jun 6, 2023, 9:52:25 AM6/6/23
to
Peter J. Holzer:

> On 2023-06-06 06:33, Andreas Borutta <bor...@gmx.de> wrote:
>> Peter J. Holzer:
>>> On 2023-06-05 22:35, Andreas Borutta <bor...@gmx.de> wrote:
>>>> Warum wird das eine Entity im Quelltest ausgegeben, und das andere
>>>> nicht?
>>>
>>> Wird sie nicht. Vergleich mal die Absätze, in denen Du das gleiche
>>> Zeichen auf verschiedene Art geschrieben hast.
>>
>> Im Quelltext kommen zwei Entities für zwei verschiedene Leerzeichen
>> vor:
>>
>> &nbsp;
>> &#x202F;
>
> Nein, im Quelltext kommen drei verschiedene Arten, U+00A0 zu schreiben
> vor:

> [...]

Verzeihung, ich hatte ja im Laufe des Threads zwei Testdokumente
erwähnt:
https://borumat.de/-/fahrradzukunft/invisibles
https://borumat.de/-/fahrradzukunft/invisibles-2

Im zweiten kommen nur 2 verschiedene Entities vor.

> <p>U+00A0 NO-BREAK SPACE<br>
> &amp;nbsp; <br />
> foo&nbsp;foo</p>
> <p>U+00A0 NO-BREAK SPACE<br>
> &amp;#160; <br />
> foo&#160;foo</p>
> <p>U+00A0 NO-BREAK SPACE<br>
> Unicodezeichen <br />
> foo foo</p>
>
> »&nbsp;«, »&#160;« und » «. Alle drei aber werden bei "View Selectio
> Source" aber als »&nbsp;« dargestellt.

Komisch, oder? Warum diese "Normalisierung"?

> Es hast auch U+202F auf zwei verschiedene Arten geschrieben:
>
> <p>U+202F NARROW NO-BREAK SPACE<br>
> &amp;#x202F; <br />
> bar&#x202F;bar</p>
> <p>U+202F NARROW NO-BREAK SPACE<br>
> &amp;#8239; <br />
> bar&#8239;bar</p>
>
> Und beide werden gleich (als Leerzeichen - welche Art von Leerzeichen
> ist optisch nicht erkennbar) ausgegeben.
>
> Es wird also offensichtlich weder bei U+00A0 noch bei U+202F der
> Quelltext ausgegeben.

Richtig.

> Sondern es wird im ersten Fall das Zeichen in
> »&nbsp;« übersetzt, damit man es optisch erkennen kann, während es im
> zweiten Fall einfach so ausgegeben wird (entweder weil die Entwickler
> eine optische Kennzeichnung nicht für wichtig erachtet haben, oder weil
> sie der Meinung waren, dass das störend wäre)

Mir erschließt sich das Motiv für die verschiedene Behandlung nicht.
"störend" scheidet ja aus, denn dann würde die Entwickler von Firefox
ja auch beim No-BREAK SPACE kein Entity ausgeben.

Wir spekulieren und können das auch so stehenlassen. Hier lesen ja
keine Mozilla-Entwickler mit.

Andreas
--
http://fahrradzukunft.de

Peter J. Holzer

unread,
Jun 6, 2023, 10:29:54 AM6/6/23
to
On 2023-06-06 13:52, Andreas Borutta <bor...@gmx.de> wrote:
> Peter J. Holzer:
>> On 2023-06-06 06:33, Andreas Borutta <bor...@gmx.de> wrote:
>>> Peter J. Holzer:
>>>> On 2023-06-05 22:35, Andreas Borutta <bor...@gmx.de> wrote:
>>>>> Warum wird das eine Entity im Quelltest ausgegeben, und das andere
>>>>> nicht?
>>>>
>>>> Wird sie nicht. Vergleich mal die Absätze, in denen Du das gleiche
>>>> Zeichen auf verschiedene Art geschrieben hast.
>>>
>>> Im Quelltext kommen zwei Entities für zwei verschiedene Leerzeichen
>>> vor:
>>>
>>> &nbsp;
>>> &#x202F;
>>
>> Nein, im Quelltext kommen drei verschiedene Arten, U+00A0 zu schreiben
>> vor:
>
>> [...]
>
> Verzeihung, ich hatte ja im Laufe des Threads zwei Testdokumente
> erwähnt:
> https://borumat.de/-/fahrradzukunft/invisibles
> https://borumat.de/-/fahrradzukunft/invisibles-2
>
> Im zweiten kommen nur 2 verschiedene Entities vor.

Sorry, habe mir nur das erste angeschaut.


>> »&nbsp;«, »&#160;« und » «. Alle drei aber werden bei "View Selectio
>> Source" aber als »&nbsp;« dargestellt.
>
> Komisch, oder?

Nein, gar nicht.

> Warum diese "Normalisierung"?

Das HTML wird in eine interne Datenstruktur (DOM = Document Object
Model) übersetzt. damit es der Browser darstellen kann. Danach wird das
HTML nicht mehr gebraucht, und üb im Source-Code »&#auml;«, »&#228;«,
»&#xE4;« oder »ä« stand ist nicht mehr relevant und auch gar nicht mehr
unterscheidbar. Das trifft nicht nur auf Entities zu, sondern z.B. auch
auf HTML-Tags. Sobald der Browser das Ende eines Absatzes gefunden hat,
ist nicht mehr relevant, ob das Ende durch ein explizites »</p>«
signalisiert wurde oder indirekt durch das Start-Tag eines anderen
Elements.

Wenn Du jetzt aber einen Teil des DOM-Baums markierst und den
"Source-Code" sehen willst, dann muss der Browser HTML aus dem DOM
erzeugen. Denn einen eigentlichen Source-Code gibt es nicht
notwendigerweise, der DOM-Baum könnte ja mittels JavaScript erzeugt oder
zumindest verändert worden sein. Dabei kommt dann notwendigerweise eine
normalisierte Darstellung heraus. Ein »ä« wird immer als »ä« dargestellt
werden, ein Absatz wird immer mit »</p>« enden, eine Tabelle wird immer
einen tbody enthalten, etc.

Bei "View Page Source" hingegen zeigt der Browser einfach den
Source-Code an, der geladen wurde. Der entspricht nicht notwendigerweise
dem aktuellen Inhalt der Seite (könnte ja inzwischen durch JavaScript
geändert worden sein), aber oft will man wissen, was der Server
tatsächlich geliefert hat, daher merkt sich der Browser das (Darüber gab
es seinerzeit eine lange Diskussion bei Mozilla).


>> Sondern es wird im ersten Fall das Zeichen in
>> »&nbsp;« übersetzt, damit man es optisch erkennen kann, während es im
>> zweiten Fall einfach so ausgegeben wird (entweder weil die Entwickler
>> eine optische Kennzeichnung nicht für wichtig erachtet haben, oder weil
>> sie der Meinung waren, dass das störend wäre)
>
> Mir erschließt sich das Motiv für die verschiedene Behandlung nicht.
> "störend" scheidet ja aus, denn dann würde die Entwickler von Firefox
> ja auch beim No-BREAK SPACE kein Entity ausgeben.

Die Unterscheidung zwischen einem normalen und einem geschütztemn
Leerzeichen ist oft relevant. Nicht umsonst gibt es für das geschützte
Leerzeichen eine vordefinierte Entity. Bei anderen Arten von Leerzeichen
ist es weit weniger klar, ob die speziell markiert werden sollen.
Generell reduziert ja jede spezielle Markierung die Lesbarkeit, man
möchte das also eigentlich nur dort haben, wo die zusätzliche
Information die schlechtere Lesbarkeit aufwiegt. Das ist dann halt
Abwägungssache. Kaum jemand wird ein »A« als »&#x41;« dargestellt haben
wollen, nur um es von einem Alpha unterscheiden zu können. Bei diversen
Leerzeichen, Strichen, etc. werden die Meinungen aber auseinandergehen.
Aber irgendwie muss es der Browser darstellen, also müssen die
Entwickler eine Entscheidung treffen.

hp

Andreas Borutta

unread,
Jun 6, 2023, 6:15:48 PM6/6/23
to
Peter J. Holzer:

> Die Unterscheidung zwischen einem normalen und einem geschütztemn
> Leerzeichen ist oft relevant.

Damit bin ich völlig einig.

Und genau deshalb schrieb ich ja:

>> Mir erschließt sich das Motiv für die verschiedene Behandlung nicht.
>> "störend" scheidet ja aus, denn dann würde die Entwickler von Firefox
>> ja auch beim No-BREAK SPACE kein Entity ausgeben.

> Nicht umsonst gibt es für das geschützte
> Leerzeichen eine vordefinierte Entity. Bei anderen Arten von Leerzeichen
> ist es weit weniger klar, ob die speziell markiert werden sollen.

Aus meiner Sicht ist es klar.

Sie sind unsichtbar, sie lassen sich nicht/kaum unterscheiden, wenn
dort kein Entity steht.

Wie auch immer, wir müssen uns dazu nicht einig sein.


Andreas
--
http://fahrradzukunft.de

Peter J. Holzer

unread,
Jun 7, 2023, 2:51:42 AM6/7/23
to
On 2023-06-06 22:15, Andreas Borutta <bor...@gmx.de> wrote:
> Aus meiner Sicht ist es klar.
>
> Sie sind unsichtbar, sie lassen sich nicht/kaum unterscheiden, wenn
> dort kein Entity steht.
>
> Wie auch immer, wir müssen uns dazu nicht einig sein.

Firefox ist ein Open-Source-Projekt. Schreib ein Ticket (normalerweise
würde ich "und einen Patch" anhängen, aber der Firefox-Source-Code ist
eher nur für erfahrene C++-Programmierer lesbar).

hp

Andreas Borutta

unread,
Jun 7, 2023, 3:43:15 AM6/7/23
to
Peter J. Holzer:

>> Aus meiner Sicht ist es klar.
>>
>> Sie sind unsichtbar, sie lassen sich nicht/kaum unterscheiden, wenn
>> dort kein Entity steht.
>>
>> Wie auch immer, wir müssen uns dazu nicht einig sein.
>
> Firefox ist ein Open-Source-Projekt. Schreib ein Ticket (normalerweise
> würde ich "und einen Patch" anhängen, aber der Firefox-Source-Code ist
> eher nur für erfahrene C++-Programmierer lesbar).

Dafür ist mir die Sache nicht wichtig genug. Ich war vor allem daran
interessiert, wie ihr die Entscheidungen der Entwickler von FF
bewertet und ob ihr sie, anders als ich, nachvollziehen könnt.

Andreas
--
http://fahrradzukunft.de

Peter J. Holzer

unread,
Jun 7, 2023, 4:01:36 AM6/7/23
to
On 2023-06-07 07:43, Andreas Borutta <bor...@gmx.de> wrote:
> Peter J. Holzer:
>> Firefox ist ein Open-Source-Projekt. Schreib ein Ticket (normalerweise
>> würde ich "und einen Patch" anhängen, aber der Firefox-Source-Code ist
>> eher nur für erfahrene C++-Programmierer lesbar).
>
> Dafür ist mir die Sache nicht wichtig genug. Ich war vor allem daran
> interessiert, wie ihr die Entscheidungen der Entwickler von FF
> bewertet und ob ihr sie, anders als ich, nachvollziehen könnt.

Du hast gerade ein weiteres Argument geliefert: Wenn ein Feature so
unwichtig ist, dass es kein User wert findet, ein paar Minuten zu
investieren, um es zu beschreiben, warum sollte man es implementieren?

hp

Andreas Borutta

unread,
Jun 7, 2023, 6:39:59 AM6/7/23
to
Andreas Borutta:

> U+00A0 NO-BREAK SPACE
> U+202F NARROW NO-BREAK SPACE
> U+2009 THIN SPACE
>
> Die Zeichen sind naturgemäß "unsichtbar".

Mittlerweile lassen sich diese Zeichen dank des guten Skriptes von
Stefan sichtbar machen.

<https://borumat.de/-/fahrradzukunft/invisibles>

Ich habe mich nun noch an einem weiteren, sehr speziellen,
unsichtbarem Zeichen versucht.

Dem bedingten Trennstrich.

U+00AD SOFT HYPHEN

Das Skript erfasst zuverlässig auch dieses Zeichen, siehe Testcase.

Sinnvoll ist es in dieser Form kaum, denn natürlich möchte man alle
manuell gesetzten bedingten Trennstriche sehe, auch wenn der Browser
sie aufgrund der zur Verfügung stehenden Breite gerade NICHT setzt.

Fällt euch dazu ein Ansatz ein?
Wie kann man einen Browser dazu bewegen bedingte Trennstrich auch dann
anzuzeigen, wenn die "Bedingung" gerade nicht erfüllt ist?
Vermutlich unlösbar, oder?

Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 8, 2023, 3:06:42 AM6/8/23
to
Wenn es ein paar Minuten wären, wenn ich das Problem technisch präzise
für die FF-Entwickler beschreiben könnte, wenn ich vertraut wäre mit
der Kultur der OpenSource-Entwickler und somit ein solches Ticket eine
gewisse Aussicht auf Erfolg hätte, dann wäre ich aktiv geworden (in
anderen Bereichen werde ich regelmäßig aktiv).


Andreas
--
http://fahrradzukunft.de

Andreas Borutta

unread,
Jun 8, 2023, 3:16:51 AM6/8/23
to
Stefan Ram:

> Andreas Borutta <bor...@gmx.de> writes:
>>U+00AD SOFT HYPHEN
>>Wie kann man einen Browser dazu bewegen bedingte Trennstrich auch dann
>>anzuzeigen, wenn die "Bedingung" gerade nicht erfüllt ist?
>
> Wenn Du einen bedingten Trennstrich mit
>
> "\xAD": "x-shy",
>
> zur Abbildung "typeForString" hinzufügst, kannst Du in CSS3 mit
>
> x-shy::after{content: "|"}
>
> vielleicht dafür sorgen, daß dort ein senkrechter Strich erscheint,
> auch wenn dort nicht getrennt wird.

Danke für die Idee. Dieses Einfügen von generated content via CSS
funktioniert, aber der "|" wird erwartungsgemäß auch dann eingefügt,
wenn ein bedingter Trennstrich am Ende einer Zeile steht.
Das will man nicht.

Nötig für eine Lösung der Aufgabe wäre die unterschiedliche Behandlung
der zwei Situationen

"Bedingter Trennstrich wird angezeigt, weil der Worteil davor passend
am Ende einer Zeile steht"

"Bedingter Trennstrich wird nicht angezeigt, weil der Worteil davor
passend nicht am Ende einer Zeile steht"

Ob HTML oder CSS für so eine Unterscheidung einen Hebel bieten, weiß
ich nicht.




Andreas
--
http://fahrradzukunft.de
0 new messages