From 149c7c3ff55b5ff41109358f393ec14f020842ca Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Tue, 25 Jan 2011 21:37:56 +0100 Subject: [PATCH] finish cjk support --- lib/ace/css/editor.css | 20 ++++++++++++ lib/ace/edit_session.js | 64 ++++++++++++++++++++++++++----------- lib/ace/layer/text.js | 18 ++++------- lib/ace/virtual_renderer.js | 48 +++++++++++++++------------- 4 files changed, 97 insertions(+), 53 deletions(-) diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index cd537ddd..0390dc5a 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -12,6 +12,20 @@ overflow-y: hidden; } +.ace_content { + position: absolute; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} + +.ace_composition { + position: absolute; + background: #555; + color: #DDD; + z-index: 4; +} + .ace_gutter { position: absolute; overflow-x: hidden; @@ -51,8 +65,14 @@ color: black; } +.ace_cjk { + display: inline-block; + text-align: center; +} + .ace_cursor-layer { cursor: text; + pointer-events: none; } .ace_cursor { diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 3d768a58..5ae0998c 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -241,8 +241,7 @@ var EditSession = function(text, mode) { }; this.tokenRe = /^[\w\d]+/g; - this.nonTokenRe = /^[^\w\d|\x00-\xff]+/g; - + this.nonTokenRe = /^(?:[^\w\d|[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF])+/g this.getWordRange = function(row, column) { var line = this.getLine(row); @@ -635,18 +634,27 @@ var EditSession = function(text, mode) { var remaining = docColumn; var line = this.getLine(row); - for(var i=0; i 0){ + for (var i=0; i 0) { remaining -= 1; - if(c == '\t'){ + // tab + if (c == 9) { screenColumn += tabSize; - } else if(/[^\x00-\xff]/.exec(c)){ - screenColumn += 2; + } + // CJK characters + else if ( + c >= 0x3040 && c <= 0x309F || // Hiragana + c >= 0x30A0 && c <= 0x30FF || // Katakana + c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs + c >= 0xF900 && c <= 0xFAFF || + c >= 0x3400 && c <= 0x4DBF + ) { + screenColumn += 2; } else { screenColumn += 1; } - }else{ + } else { break; } } @@ -661,22 +669,42 @@ var EditSession = function(text, mode) { var remaining = screenColumn; var line = this.getLine(row); - for(var i=0; i 0){ + for(var i=0; i 0) { docColumn += 1; - if(c == '\t'){ - remaining -= tabSize; - } else if(/[^\x00-\xff]/.exec(c)){ - remaining -= 2; + // tab + if (c == 9) { + if (remaining >= tabSize) { + remaining -= tabSize; + } else { + remaining = 0; + docColumn -= 1; + } + } + // CJK characters + else if ( + c >= 0x3040 && c <= 0x309F || // Hiragana + c >= 0x30A0 && c <= 0x30FF || // Katakana + c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs + c >= 0xF900 && c <= 0xFAFF || + c >= 0x3400 && c <= 0x4DBF + ) { + if (remaining >= 2) { + remaining -= 2; + } else { + remaining = 0; + docColumn -= 1; + } } else { remaining -= 1; } - }else{ + } else { break; } } - + return docColumn; }; diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index 815f669a..568f1db9 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -266,6 +266,8 @@ var Text = function(parentEl) { var spaceReplace = " "; } + var characterWidth = this.config.characterWidth; + for ( var i = 0; i < tokens.length; i++) { var token = tokens[i]; @@ -273,19 +275,11 @@ var Text = function(parentEl) { .replace(/&/g, "&") .replace(/" + c + "" + }); - var buffer = ''; - for (var j=0;j" + w + ""; - }else{ - buffer = buffer + w; - } - } - output = buffer; - if (!this.$textToken[token.type]) { var classes = "ace_" + token.type.replace(/\./g, " ace_"); stringBuilder.push("", output, ""); diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 0ae38f7d..fba0aca1 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -67,8 +67,7 @@ var VirtualRenderer = function(container, theme) { this.container.appendChild(this.scroller); this.content = document.createElement("div"); - this.content.style.cssText = "position:absolute;box-sizing:border-box;" + - "-moz-box-sizing:border-box;-webkit-box-sizing:border-box"; + this.content.className = "ace_content"; this.scroller.appendChild(this.content); this.$gutterLayer = new GutterLayer(this.$gutter); @@ -591,35 +590,38 @@ var VirtualRenderer = function(container, theme) { }; this.showComposition = function(position) { - var cur = this.$cursorLayer.element.firstChild; - var scroll = this.scroller; - var top = (parseInt(cur.style.top) || 0) + (parseInt(scroll.style.top) || 0); - var left = (parseInt(cur.style.left) || 0) + (parseInt(scroll.style.left) || 0); - - var edit = document.getElementById("editor").lastChild; - edit.style.color = '#66ff33'; - edit.style.top = (top - 1) + "px"; - edit.style.left = (left + 3) + "px"; - edit.style.background = "transparent"; - edit.style.border = "none"; - edit.style.resize = "none"; - edit.style.outline = "none"; - edit.style.width = "10000px"; - edit.style.height = "10000px"; - edit.style.fontSize = "12px"; - + console.log("show composition") + if (!this.$composition) { + this.$composition = document.createElement("div"); + this.$composition.className = "ace_composition"; + this.content.appendChild(this.$composition); + } + + this.$composition.innerHTML = " "; + + var pos = this.$cursorLayer.getPixelPosition(); + var style = this.$composition.style; + style.top = pos.top + "px"; + style.left = (pos.left + this.$padding) + "px"; + style.height = this.lineHeight + "px"; + //style.width = this.characterWidth + "px"; + this.hideCursor(); }; this.setCompositionText = function(text) { + this.$composition.innerText = this.$composition.textContent = text; }; this.hideComposition = function() { this.showCursor(); - var edit = document.getElementById("editor").lastChild; - edit.className = ''; - edit.style.top = "-10000px"; - edit.style.left = "-10000px"; + + if (!this.$composition) + return; + + var style = this.$composition.style; + style.top = "-10000px"; + style.left = "-10000px"; }; this.setTheme = function(theme) {