Hallo,
Al een poosje ben ik bezig met een What You See Is What You Get editor te maken met javascript die in alle browsers zou moeten werken (mits ze de HTML DOM ondersteunen). Je kan tekst typen, verwijderen met backspace en delete en je kunt enters geven. Er zitten nog aardig wat bugs in, je hebt bijvoorbeeld geen caret (knipperende cursor), als je op backspace of delete drukt bij het begin of einde van een HTML tag dan wist die de halve tag en de loops die gebruikt worden om te achterhalen waar de gebruiker heeft geklikt moeten stukken sneller kunnen (door middel van regexp).
Omdat ik zelf niet echt meer er mee bezig ben maar sommige mensen er misschien wat aan hebben, plaats ik hier wel de code en een voorbeeldje. Als je verbeteringen ofzo hebt, kwak het maar neer en met een beetje mazzel kunnen binnenkort mensen met Opera óók gewoon WYSIWYG gebruiken...
Voorbeeld: http://www.vanderhoorn.info/richtext.html
Al een poosje ben ik bezig met een What You See Is What You Get editor te maken met javascript die in alle browsers zou moeten werken (mits ze de HTML DOM ondersteunen). Je kan tekst typen, verwijderen met backspace en delete en je kunt enters geven. Er zitten nog aardig wat bugs in, je hebt bijvoorbeeld geen caret (knipperende cursor), als je op backspace of delete drukt bij het begin of einde van een HTML tag dan wist die de halve tag en de loops die gebruikt worden om te achterhalen waar de gebruiker heeft geklikt moeten stukken sneller kunnen (door middel van regexp).
Omdat ik zelf niet echt meer er mee bezig ben maar sommige mensen er misschien wat aan hebben, plaats ik hier wel de code en een voorbeeldje. Als je verbeteringen ofzo hebt, kwak het maar neer en met een beetje mazzel kunnen binnenkort mensen met Opera óók gewoon WYSIWYG gebruiken...
Voorbeeld: http://www.vanderhoorn.info/richtext.html
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
| <html>
<head>
<style>
.vElement_input
{
border-left: 2px solid #828177;
border-top: 2px solid #828177;
border-right: 1px solid #E2E2E0;
border-bottom: 1px solid #E2E2E0;
font: 8pt Tahoma;
cursor: text;
padding: 2px 5px 2px 5px;
}
</style>
<script type="text/javascript">
function getOpenTags(input)
{
var tempArray = new Array();
var i = 0;
var tempTags = "";
while (i < input.length)
{
if (input.substr(i, 1) == "<")
{
while (input.substr(i, 1) != ">")
{
tempTags += input.substr(i, 1);
i++;
}
tempTags += input.substr(i, 1);
}
i++;
}
return tempTags;
}
function textclick(element, e)
{
// Remember where the user clicked
var clickLeft = e.clientX - element.offsetLeft;
var clickTop = e.clientY - element.offsetTop;
// Create a temporary element which has the same size as the original div, to
// be able to depend the row on which is clicked
var tempDiv = document.createElement("DIV");
tempDiv.className = "vElement_input";
tempDiv.style.width = element.style.width;
document.body.appendChild(tempDiv);
var tempUntilLastRow = 0;
var tempHeight = 0;
var tempValue = element.innerHTML + "<p> </p>";
var tempCounter = 0;
// Determine the row on which is clicked with this loop. Please note that this loop
// can be speed'n up by replacing tempCounter++; with tempCounter += 20; or something
// like that, after which you create a second loop which will count backwards to get
// the exact character number
while (tempHeight < clickTop)
{
tempDiv.innerHTML = tempValue.substr(0, tempCounter);
// Check if a new row has been created
if (tempHeight != tempDiv.offsetHeight)
{
// If there is a new row, remember after how many character it happened so
// we can determine with which character the row started
tempUntilLastRow = tempCounter;
}
tempHeight = tempDiv.offsetHeight;
tempCounter++;
}
// Remove the temporary DIV
tempDiv.parentNode.removeChild(tempDiv);
// New rows always start with a complete word, search the beginning of the word
// and use it to put the remaining characters of the original text in tempValue
tempCounter = tempCounter - 2;
while (tempValue.substr(tempCounter, 1).match(/\w/) && (tempCounter > 0))
{
tempCounter--;
}
tempCounter++;
var tempTags = getOpenTags(tempValue.substr(0, tempCounter));
tempValue = tempValue.substr(tempCounter);
// Create a new DIV again, but this time, use the x-value of the mouseclick
// as the width of it
var tempDiv = document.createElement("DIV");
tempDiv.className = "vElement_input";
tempDiv.style.width = clickLeft + "px";
tempDiv.innerHTML = "";
document.body.appendChild(tempDiv);
// Count the number of characters which will fit into the DIV until a new row
// will be created
tempChar = 1;
var tempHeight = 0;
var tempWidth = tempDiv.offsetWidth;
while ((tempDiv.offsetHeight <= tempHeight || tempHeight == 0) && tempWidth == tempDiv.offsetWidth)
{
tempDiv.innerHTML = tempTags + tempValue.substr(0, tempChar);
if (tempHeight == 0)
{
tempHeight = tempDiv.offsetHeight;
}
tempChar++;
}
tempChar--;
// Remove the DIV
tempDiv.parentNode.removeChild(tempDiv);
// Return the position on which the user clicked
return (tempCounter + tempChar);
}
function keypress(e)
{
// Use the onkeypress event to determine if SHIFT is hold or not
var element = window["selectedelement"];
if (!element)
{
return;
}
var character = String.fromCharCode(e.keyCode || e.which);
element.innerHTML = element.innerHTML.substr(0, element.caret) + character + element.innerHTML.substr(element.caret);
element.caret++;
}
function keydown(e)
{
// Use onkeydown to detect all other (non visible) characters which are pressed
var element = window["selectedelement"];
if (!element)
{
return;
}
var character = (e.keyCode || e.which);
if (character == 8)
{
// Backspace key
element.innerHTML = element.innerHTML.substr(0, element.caret - 1) + element.innerHTML.substr(element.caret);
element.caret--;
}
else if (character == 46)
{
// Delete key
element.innerHTML = element.innerHTML.substr(0, element.caret) + element.innerHTML.substr(element.caret + 1);
}
else if (character == 10 || character == 13)
{
// Enter key
element.innerHTML = element.innerHTML.substr(0, element.caret) + "<br>" + element.innerHTML.substr(element.caret);
element.caret = element.caret + 3;
}
}
</script>
</head>
<body>
<script type="text/javascript">
// Add a DIV to the screen to test
var myDiv = document.createElement("DIV");
myDiv.className = "vElement_input";
myDiv.style.width = "300px";
myDiv.style.height = "200px";
myDiv.innerHTML = "This is some text <h1>to test if the <u>function<\/u> is working<\/h1> like it should. In <b>most cases it does</b>, but when you enter text which has another size then the other text, it will stop functioning. <font color=\"red\">It also works with colored text.<\/font> It does? Yes, it does ;)";
document.body.appendChild(myDiv);
// Also create an editbox which will hold the focus, to prevent
// that Opera or other browsers might see keyboard input as hotkeys
// Make sure this editbox will be hidden for the user
var tempInput = document.createElement("INPUT");
tempInput.style.position = "absolute";
tempInput.style.width = "0px";
tempInput.style.height = "0px";
tempInput.style.top = "-100px";
document.body.appendChild(tempInput);
myDiv.onmouseup = function (e)
{
// Check where the user clicked
if (!e)
{
var e = window.event;
}
this.caret = textclick(this, e);
window["selectedelement"] = this;
tempInput.focus();
}
document.onkeypress = function (e)
{
if (!e)
{
var e = window.event;
}
keypress(e);
}
document.onkeydown = function (e)
{
if (!e)
{
var e = window.event;
}
keydown(e);
}
</script>
</body>
</html> |