Skip to content
This repository was archived by the owner on Feb 6, 2025. It is now read-only.

Commit 6353333

Browse files
committed
Fix for eclipse bug 512109
Signed-off-by: Moshe Wajnberg <[email protected]>
1 parent adfa35b commit 6353333

File tree

9 files changed

+182
-31
lines changed

9 files changed

+182
-31
lines changed

bundles/org.eclipse.orion.client.core/web/orion/bidiUtils.js

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ define ([
1212
],
1313
function(util) { /* BDL */
1414

15-
var bidiEnabledStorage = "/orion/preferences/bidi/bidiEnabled"; //$NON-NLS-0$
16-
var bidiLayoutStorage = "/orion/preferences/bidi/bidiLayout"; //$NON-NLS-0$
17-
var LRE = "\u202A"; //$NON-NLS-0$
18-
var PDF = "\u202C"; //$NON-NLS-0$
19-
var RLE = "\u202B"; //$NON-NLS-0$
20-
2115
function setBrowserLangDirection() {
2216

2317
var lang;
@@ -29,7 +23,7 @@ function(util) { /* BDL */
2923
}
3024
var isBidi = lang && "ar iw he".indexOf(lang.substring(0, 2)) !== - 1;
3125

32-
if (isBidi && isBidiEnabled()) {
26+
if (isBidi) {
3327
var htmlElement = document.getElementsByTagName("html")[0];
3428
if (htmlElement){ //should be always true
3529
htmlElement.setAttribute ("dir", "rtl");
@@ -39,6 +33,12 @@ function(util) { /* BDL */
3933

4034
setBrowserLangDirection();
4135

36+
var bidiEnabledStorage = "/orion/preferences/bidi/bidiEnabled"; //$NON-NLS-0$
37+
var bidiLayoutStorage = "/orion/preferences/bidi/bidiLayout"; //$NON-NLS-0$
38+
var LRE = "\u202A"; //$NON-NLS-0$
39+
var PDF = "\u202C"; //$NON-NLS-0$
40+
var RLE = "\u202B"; //$NON-NLS-0$
41+
4242
var bidiLayout = getBidiLayout();
4343

4444
/**
@@ -146,7 +146,16 @@ function(util) { /* BDL */
146146
}
147147
}
148148

149-
function enforceTextDir(range) {
149+
function createNewStyle ( oldStyle, textDir ) {
150+
var newStyle = oldStyle;
151+
if (typeof newStyle.attributes === "undefined") {
152+
newStyle.attributes = {};
153+
}
154+
newStyle.attributes.dir = textDir;
155+
return newStyle;
156+
}
157+
158+
function enforceTextDir( range, textDir ) {
150159
var comments = [{name:"comment block"},
151160
{name:"comment line double-slash"},
152161
{name:"comment block documentation"},
@@ -163,13 +172,17 @@ function(util) { /* BDL */
163172
var newStyle = style;
164173
if (typeof newStyle.attributes === "undefined") {
165174
newStyle.attributes = {};
166-
}
167-
newStyle.attributes.dir = getTextDirection(text);
168-
range.style = newStyle;
175+
}
176+
range.style = createNewStyle( style, getTextDirection(text) );
169177
return range;
170178
}
171179
}
172180
}
181+
else if (style && textDir && textDir.length > 0) {
182+
range.style = createNewStyle( style, textDir );
183+
return range;
184+
}
185+
173186
return range;
174187
}
175188

bundles/org.eclipse.orion.client.core/web/orion/util.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ define(function() {
3030
var isTouch = typeof document !== "undefined" && "ontouchstart" in document.createElement("input"); //$NON-NLS-1$ //$NON-NLS-0$
3131

3232
var platformDelimiter = isWindows ? "\r\n" : "\n"; //$NON-NLS-1$ //$NON-NLS-0$
33+
var LtrMarker = "\u202A\u202A\u202A\u202A\u202A"; //$NON-NLS-0$
34+
var RtlMarker = "\u202B\u202B\u202B\u202B\u202B"; //$NON-NLS-0$
3335

3436
function formatMessage(msg) {
3537
var args = arguments;
@@ -85,6 +87,9 @@ define(function() {
8587
/** Capabilities */
8688
isTouch: isTouch,
8789

88-
platformDelimiter: platformDelimiter
90+
platformDelimiter: platformDelimiter,
91+
LtrMarker: LtrMarker,
92+
RtlMarker: RtlMarker
93+
8994
};
9095
});

bundles/org.eclipse.orion.client.editor/web/orion/editor/keyModes.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ define("orion/editor/keyModes", [ //$NON-NLS-0$
231231
bindings.push({actionID: "escape", keyBinding: new KeyBinding(27), predefined: true}); //$NON-NLS-0$
232232
bindings.push({actionID: "selectAll", keyBinding: new KeyBinding('a', true), predefined: true}); //$NON-NLS-1$ //$NON-NLS-0$
233233
bindings.push({actionID: "toggleTabMode", keyBinding: new KeyBinding('m', true), predefined: true}); //$NON-NLS-1$ //$NON-NLS-0$
234+
bindings.push({actionID: "dirLTR", keyBinding: new KeyBinding(36, null, true, true), predefined: true}); //$NON-NLS-0$
235+
bindings.push({actionID: "dirRTL", keyBinding: new KeyBinding(35, null, true, true), predefined: true}); //$NON-NLS-0$
234236
if (util.isMac) {
235237
bindings.push({actionID: "deleteNext", keyBinding: new KeyBinding(46, null, true), predefined: true}); //$NON-NLS-0$
236238
bindings.push({actionID: "deleteWordPrevious", keyBinding: new KeyBinding(8, null, null, true), predefined: true}); //$NON-NLS-0$

bundles/org.eclipse.orion.client.editor/web/orion/editor/nls/root/messages.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ define({//Default message bundle
8686
"toggleWrapMode": "Toggle Wrap Mode", //$NON-NLS-1$ //$NON-NLS-0$
8787
"toggleTabMode": "Toggle Tab Mode", //$NON-NLS-1$ //$NON-NLS-0$
8888
"toggleOverwriteMode": "Toggle Overwrite Mode", //$NON-NLS-1$ //$NON-NLS-0$
89+
"dirLTR": "Set Left to Right Text Direction", //$NON-NLS-1$ //$NON-NLS-0$
90+
"dirRTL": "Set Right to Left Text Direction", //$NON-NLS-1$ //$NON-NLS-0$
8991

9092
"committerOnTime": "${0} on ${1}", //$NON-NLS-1$ //$NON-NLS-0$
9193

bundles/org.eclipse.orion.client.editor/web/orion/editor/projectionTextModel.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,18 @@ define("orion/editor/projectionTextModel", ['orion/editor/textModel', 'orion/edi
339339
getLineDelimiter: function() {
340340
return this._model.getLineDelimiter();
341341
},
342+
/**
343+
* @see orion.editor.TextModel#getLineTextDir
344+
*/
345+
getLineTextDir: function(lineIndex) {
346+
return this._model.getLineTextDir(lineIndex);
347+
},
348+
/**
349+
* @see orion.editor.TextModel#getTextForSave
350+
*/
351+
getTextForSave: function() {
352+
return this._model.getTextForSave();
353+
},
342354
/**
343355
* @see orion.editor.TextModel#getLineEnd
344356
*/

bundles/org.eclipse.orion.client.editor/web/orion/editor/textModel.js

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
3838
this._lastLineIndex = -1;
3939
this._text = [""];
4040
this._lineOffsets = [0];
41+
this._textDirs = [""];
4142
this.setText(text);
4243
this.setLineDelimiter(lineDelimiter);
4344
}
@@ -370,6 +371,23 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
370371
}
371372
return this._lineOffsets[lineIndex];
372373
},
374+
/**
375+
* Returns the text direction of the given line.
376+
* <p>
377+
* The valid indices are 0 to line count exclusive. Returns <code>""</code>
378+
* if the index is out of range.
379+
* </p>
380+
*
381+
* @param {Number} lineIndex the zero based index of the line.
382+
* @return {String} the text direction of the line<code>""</code> if out of range.
383+
*
384+
*/
385+
getLineTextDir: function(lineIndex) {
386+
if (!(0 <= lineIndex && lineIndex < this.getLineCount())) {
387+
return "";
388+
}
389+
return this._textDirs[lineIndex];
390+
},
373391
/**
374392
* Returns the text for the given range.
375393
* <p>
@@ -416,6 +434,23 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
416434
var afterText = this._text[lastChunk].substring(0, end - lastOffset);
417435
return beforeText + this._text.slice(firstChunk+1, lastChunk).join("") + afterText;
418436
},
437+
/**
438+
* Returns the whole text for save. We keep the text direction of each line by adding the ltr/rtl marker.
439+
*
440+
*/
441+
getTextForSave: function() {
442+
var text = "";
443+
for (var i = 0; i<this.getLineCount(); i++) {
444+
if (this._textDirs[i] === "ltr") {
445+
text += util.LtrMarker + this.getLine(i, true);
446+
} else if (this._textDirs[i] === "rtl") {
447+
text += util.RtlMarker + this.getLine(i, true);
448+
} else {
449+
text += this.getLine(i, true);
450+
}
451+
}
452+
return text;
453+
},
419454
/**
420455
* Notifies all listeners that the text is about to change.
421456
* <p>
@@ -508,6 +543,8 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
508543
if (start === undefined) { start = 0; }
509544
if (end === undefined) { end = this.getCharCount(); }
510545
if (start === end && text === "") { return; }
546+
var ltrMarker = util.LtrMarker;
547+
var rtlMarker = util.RtlMarker;
511548
var startLine = this.getLineAtOffset(start);
512549
var endLine = this.getLineAtOffset(end);
513550
var eventStart = start;
@@ -517,12 +554,21 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
517554
var addedLineCount = 0;
518555
var lineCount = this.getLineCount();
519556

520-
var cr = 0, lf = 0, index = 0;
557+
var cr = 0, lf = 0, index = 0, shift = 0;
521558
var newLineOffsets = [];
522-
while (true) {
559+
var newTextDirs = [];
560+
var origText = text;
561+
562+
563+
while (true) {
523564
if (cr !== -1 && cr <= index) { cr = text.indexOf("\r", index); } //$NON-NLS-0$
524565
if (lf !== -1 && lf <= index) { lf = text.indexOf("\n", index); } //$NON-NLS-0$
525566
if (lf === -1 && cr === -1) { break; }
567+
if (text.substr(index, ltrMarker.length) == ltrMarker) {
568+
shift += ltrMarker.length;
569+
} else if (text.substr(index, rtlMarker.length) == rtlMarker) {
570+
shift += rtlMarker.length;
571+
}
526572
if (cr !== -1 && lf !== -1) {
527573
if (cr + 1 === lf) {
528574
index = lf + 1;
@@ -534,8 +580,20 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
534580
} else {
535581
index = lf + 1;
536582
}
537-
newLineOffsets.push(start + index);
583+
newLineOffsets.push(start + index - shift);
538584
addedLineCount++;
585+
if (text.substr(index, ltrMarker.length) == ltrMarker) {
586+
newTextDirs.push("ltr"); //$NON-NLS-0$
587+
} else if (text.substr(index, rtlMarker.length) == rtlMarker) {
588+
newTextDirs.push("rtl"); //$NON-NLS-0$
589+
} else {
590+
newTextDirs.push(""); //$NON-NLS-0$
591+
}
592+
}
593+
if (text !== ltrMarker && text !== rtlMarker) {
594+
var re1 = new RegExp(ltrMarker, "g"), re2 = new RegExp(rtlMarker, "g");
595+
text = text.replace(re1, "").replace(re2, "");
596+
addedCharCount = text.length;
539597
}
540598

541599
var modelChangingEvent = {
@@ -582,16 +640,26 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
582640
if (newLineOffsets.length < limit) {
583641
args = [startLine + 1, removedLineCount].concat(newLineOffsets);
584642
Array.prototype.splice.apply(this._lineOffsets, args);
643+
args = [startLine + 1, removedLineCount].concat(newTextDirs);
644+
Array.prototype.splice.apply(this._textDirs, args);
585645
} else {
586646
index = startLine + 1;
587647
this._lineOffsets.splice(index, removedLineCount);
588648
for (var k = 0; k < newLineOffsets.length; k += limit) {
589649
args = [index, 0].concat(newLineOffsets.slice(k, Math.min(newLineOffsets.length, k + limit)));
590650
Array.prototype.splice.apply(this._lineOffsets, args);
651+
args = [index, 0].concat(newTextDirs.slice(k, Math.min(newTextDirs.length, k + limit)));
652+
Array.prototype.splice.apply(this._textDirs, args);
591653
index += limit;
592654
}
593655
}
594656

657+
if (origText.indexOf(ltrMarker) == 0) {
658+
this._textDirs[startLine] = "ltr"; //$NON-NLS-0$
659+
} else if (origText.indexOf(rtlMarker) == 0) {
660+
this._textDirs[startLine] = "rtl"; //$NON-NLS-0$
661+
}
662+
595663
var offset = 0, chunk = 0, length;
596664
while (chunk<this._text.length) {
597665
length = this._text[chunk].length;

0 commit comments

Comments
 (0)