Vandaag ben ik begonnen met een nieuw project. Het idee is om een eigen custom implementatie te ontwikkelen voor contenteditable, in eerste instantie gericht en geoptimaliseerd voor FireFox. Latere versies wil ik compatible maken voor andere browsers.
De werking van contenteditable is voor vele browsers verschillend. Alleen al het gedrag van de enter-toets levert in verschillende browsers verschillende resultaten. Ook ben ik zelf zeeeeeeer ongelukkig met het wisselende standaardgedrag van verschillende webbrowsers. Als voorbeeld erger ik me kapot aan het feit dat in FireFox drag handles op een tabel cel gezet worden. Ook ben ik niet tevreden met de positionering van de caret, en het feit dat de kleur van de caret niet de inverse kleur heeft van de achtergrond. Het is en blijft altijd een stom zwart streepje, wat lastig vindbaar is op donkere achtergronden.
Mijn caret wordt gerepresenteerd door een span element zonder content met een border-left van 2px solid *inverse_achtergrond_kleur* en een margin-left van -2px zodat hij de normale flow niet beinvloed. Een interval zorgt ervoor dat de caret knippert en zorgt ervoor dat de border kleur wisselt van transparant naar de inverse van de achtergrond.
Het algoritme voor het verplaatsen van de caret naar links en rechts is eenvoudig. Het span element dat de caret representeert wordt één karakter naar links of rechts verplaatst. De uitdaging zit hem echter in het verticaal verplaatsen van de caret. Nu vraag ik me af of iemand van jullie bekend is met algoritmes voor het verplaatsen van de caret. Hoe bepaal je bijvoorbeeld of de caret naar de volgende regel gaat?
Op dit moment het ik een algoritme gemaakt wat de start X positie registreert. De caret wordt vervolgens karakter voor karakter naar rechts verplaatst. Op het moment dat de X positie van de caret kleiner is dan de start positie, zit je op een nieuwe regel. Dan wordt doorgelopen tot de X positie hoger wordt dan de start X positie van de vorige regel. Dan wordt het verschil gemeter tussen X nieuwe regel en X oude regel. Als die groter is dan het verschil tussen "X nieuwe regel vorige teken" en X oude regel, wordt de caret weer een teken naar links verplaatst (zo staat hij altijd het dichtst bij de oorspronkelijke X oude regel). Deze X oude regel wordt onthouden zolang omhoog of omlaag gedrukt wordt. Als een andere toets ingedrukt wordt, wordt de X oude regel gereset. Dit algoritme levert alleen problemen op in bepaalde uitzonderlijke gevallen (plaatje links gefloat, plaatje rechts gefloat, waardoor de nieuwe regel niet gedetecteerd wordt omdat de X niet kleiner wordt, maar pas bij de volgende regel, waardoor hij feitelijk 2 regels omlaag gaat). Ook is het algoritme niet echt snel, hoewel hier met een soort van divide and conqueror wel iets aan te doen valt.
Een zoektocht op Google levert alleen algoritmes voor caret gedrag in mono-space lettertypes, niet in Rich Text Editors.
De werking van contenteditable is voor vele browsers verschillend. Alleen al het gedrag van de enter-toets levert in verschillende browsers verschillende resultaten. Ook ben ik zelf zeeeeeeer ongelukkig met het wisselende standaardgedrag van verschillende webbrowsers. Als voorbeeld erger ik me kapot aan het feit dat in FireFox drag handles op een tabel cel gezet worden. Ook ben ik niet tevreden met de positionering van de caret, en het feit dat de kleur van de caret niet de inverse kleur heeft van de achtergrond. Het is en blijft altijd een stom zwart streepje, wat lastig vindbaar is op donkere achtergronden.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <body> <div class="page"> <div class="content" contenteditable="true"> <p style="background-color: green; margin: 0; padding: 0; line-height: auto;"><img src="http://algo.inria.fr/broutin/pictures/random_geom_graph.jpg" style="width: 250px; float: left; " />Lorem ipsum <span style="background: #f00;">dol<span id="caret"></span>or sit amet</span>, consectetur adipiscing elit. Praesent bibendum pharetra lorem vitae tincidunt. Mauris vel massa neque. Nulla facilisi. Nulla dapibus dictum magna eu tristique. Curabitur tincidunt tellus non orci commodo pulvinar. Nam velit leo, <img src="http://algo.inria.fr/broutin/pictures/random_geom_graph.jpg" style="width: 250px; float: right;" />sagittis commodo vestibulum a, ullamcorper eget nisi. Ut sed lectus vitae sapien elementum mattis. Vestibulum in elit felis, sit amet malesuada lectus. Sed sed tellus sed risus pharetra condimentum <span class="pellen" id="p1">id</span> quis nulla. <span class="pellen" id="p2">Pellentesque</span> ullamcorper quam vel <img src="http://algo.inria.fr/broutin/pictures/random_geom_graph.jpg" style="width: 441px; float: left;" />erat laoreet imperdiet faucibus lorem consectetur. Donec lacinia tortor ac justo sagittis pellentesque. Sed quis nibh quis metus vulputate lobortis.</p> </div> </div> <div class="page"> <div class="content"> Hallo dit is een test </div> </div> </body> |
Mijn caret wordt gerepresenteerd door een span element zonder content met een border-left van 2px solid *inverse_achtergrond_kleur* en een margin-left van -2px zodat hij de normale flow niet beinvloed. Een interval zorgt ervoor dat de caret knippert en zorgt ervoor dat de border kleur wisselt van transparant naar de inverse van de achtergrond.
Het algoritme voor het verplaatsen van de caret naar links en rechts is eenvoudig. Het span element dat de caret representeert wordt één karakter naar links of rechts verplaatst. De uitdaging zit hem echter in het verticaal verplaatsen van de caret. Nu vraag ik me af of iemand van jullie bekend is met algoritmes voor het verplaatsen van de caret. Hoe bepaal je bijvoorbeeld of de caret naar de volgende regel gaat?
Op dit moment het ik een algoritme gemaakt wat de start X positie registreert. De caret wordt vervolgens karakter voor karakter naar rechts verplaatst. Op het moment dat de X positie van de caret kleiner is dan de start positie, zit je op een nieuwe regel. Dan wordt doorgelopen tot de X positie hoger wordt dan de start X positie van de vorige regel. Dan wordt het verschil gemeter tussen X nieuwe regel en X oude regel. Als die groter is dan het verschil tussen "X nieuwe regel vorige teken" en X oude regel, wordt de caret weer een teken naar links verplaatst (zo staat hij altijd het dichtst bij de oorspronkelijke X oude regel). Deze X oude regel wordt onthouden zolang omhoog of omlaag gedrukt wordt. Als een andere toets ingedrukt wordt, wordt de X oude regel gereset. Dit algoritme levert alleen problemen op in bepaalde uitzonderlijke gevallen (plaatje links gefloat, plaatje rechts gefloat, waardoor de nieuwe regel niet gedetecteerd wordt omdat de X niet kleiner wordt, maar pas bij de volgende regel, waardoor hij feitelijk 2 regels omlaag gaat). Ook is het algoritme niet echt snel, hoewel hier met een soort van divide and conqueror wel iets aan te doen valt.
Een zoektocht op Google levert alleen algoritmes voor caret gedrag in mono-space lettertypes, niet in Rich Text Editors.