Index: trunk/extensions/VisualEditor/demos/playground/playground.js |
— | — | @@ -23,93 +23,127 @@ |
24 | 24 | $document.unbind( '.surfaceView' );
|
25 | 25 | }
|
26 | 26 | } );
|
| 27 | +
|
| 28 | + document.addEventListener( 'compositionstart', function( e ) {
|
| 29 | + _this.onCompositionStart( e );
|
| 30 | + } );
|
| 31 | + document.addEventListener( 'compositionend', function( e ) {
|
| 32 | + _this.onCompositionEnd( e );
|
| 33 | + } );
|
27 | 34 |
|
28 | 35 | this.$editor.mousedown( function(e) {
|
29 | 36 | return _this.onMouseDown( e );
|
30 | 37 | } );
|
31 | 38 |
|
32 | 39 | // Set initial content for the "editor"
|
33 | | - this.$editor.html("<b>Lorem Ipsum is simply dummy text</b> of the printing and typesetting industry. <b>Lorem Ipsum has been the <i>industry's</i> standard</b> dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it <u>to <b>make <i>a type</i> specimen</b> book.</u>");
|
| 40 | +// this.$editor.html("<b>Lorem Ipsum is simply dummy text</b> of the printing and typesetting industry. <b>Lorem Ipsum has been the <i>industry's</i> standard</b> dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it <u>to <b>make <i>a type</i> specimen</b> book.</u>... New text...");
|
| 41 | + this.$editor.html("New book is good");
|
| 42 | +// this.$editor.html("... <b>w</b>");
|
34 | 43 | this.$editor.addClass('leafNode');
|
35 | 44 |
|
36 | | - this.keydown = false;
|
37 | | - this.keyup = false;
|
38 | | - this.keypress = false;
|
39 | | - this.mousedown = false;
|
| 45 | + this.prevText = app.getDOMText2(this.$editor[0]);
|
| 46 | + this.prevHash = app.getDOMHash(this.$editor[0]);
|
| 47 | + this.prevOffset = null;
|
| 48 | + this.inIME = false;
|
40 | 49 |
|
41 | | - this.loop = false;
|
42 | | - this.logkey = false;
|
| 50 | + setInterval(function() {
|
| 51 | + _this.loopFunc();
|
| 52 | + }, 100);
|
| 53 | +};
|
43 | 54 |
|
44 | | - this.prevText = app.getDOMText(this.$editor[0]).replace(String.fromCharCode(32), " ").replace(String.fromCharCode(160), " ");
|
45 | | -
|
46 | | - this.prevHash = app.getDOMHash(this.$editor[0]);
|
47 | | - console.log("Initial hash", this.prevHash);
|
48 | | -
|
| 55 | +app.prototype.onCompositionStart = function( e ) {
|
| 56 | + console.log('inIME', true);
|
| 57 | + this.inIME = true;
|
49 | 58 | };
|
50 | 59 |
|
| 60 | +app.prototype.onCompositionEnd = function( e ) {
|
| 61 | + console.log('inIME', false);
|
| 62 | + this.inIME = false;
|
| 63 | +};
|
| 64 | +
|
51 | 65 | app.prototype.onKeyDown = function( e ) {
|
52 | | - if ( this.logkey ) {
|
53 | | - console.log("onKeyDown", e.which);
|
54 | | - }
|
55 | | - this.keydown = true;
|
56 | 66 | };
|
57 | 67 |
|
58 | 68 | app.prototype.onKeyUp = function( e ) {
|
59 | | - if ( this.logkey ) {
|
60 | | - console.log("onKeyUp", e.which);
|
61 | | - }
|
62 | | - this.keyup = true;
|
63 | 69 | };
|
64 | 70 |
|
65 | 71 | app.prototype.onKeyPress = function( e ) {
|
66 | | - if ( this.logkey ) {
|
67 | | - console.log("onKeyPress");
|
68 | | - }
|
69 | | - this.keypress = true;
|
70 | 72 | };
|
71 | 73 |
|
72 | 74 | app.prototype.onMouseDown = function( e ) {
|
73 | | - if ( this.logkey ) {
|
74 | | - console.log("onMouseDown");
|
75 | | - }
|
76 | | - this.mousedown = true;
|
77 | | -
|
78 | | - if(this.loop == false) {
|
79 | | - var _this = this;
|
80 | | - setInterval(function() {
|
81 | | - _this.loopFunc();
|
82 | | - }, 100);
|
83 | | - }
|
84 | 75 | };
|
85 | 76 |
|
86 | 77 | app.prototype.loopFunc = function() {
|
87 | | - var text = app.getDOMText(this.$editor[0]).replace(String.fromCharCode(32), " ").replace(String.fromCharCode(160), " ");
|
88 | | - var hash = app.getDOMHash(this.$editor[0]);
|
89 | | -
|
90 | 78 | var selection = rangy.getSelection();
|
91 | 79 |
|
92 | | - if ( !selection.anchorNode ) {
|
| 80 | + if ( !selection.anchorNode || selection.anchorNode.nodeName === 'BODY' ) {
|
93 | 81 | return;
|
94 | 82 | }
|
| 83 | +
|
| 84 | + if ( this.inIME === true ) {
|
| 85 | + return;
|
| 86 | + }
|
95 | 87 |
|
96 | | - var offset = this.getOffset(selection.anchorNode, selection.anchorOffset);
|
| 88 | + var text = app.getDOMText2( this.$editor[0] ),
|
| 89 | + hash = app.getDOMHash( this.$editor[0] ),
|
| 90 | + offset = this.getOffset( selection.anchorNode, selection.anchorOffset );
|
97 | 91 |
|
98 | | - if(text != this.prevText) {
|
99 | | - console.log("new text");
|
| 92 | + if ( text !== this.prevText ) {
|
| 93 | + var textDiffLength = text.length - this.prevText.length,
|
| 94 | + offsetDiff = offset - this.prevOffset,
|
| 95 | + sameFromLeft = 0,
|
| 96 | + sameFromRight = 0,
|
| 97 | + l = Math.max( this.prevText.length, text.length);
|
| 98 | +
|
| 99 | + while ( sameFromLeft < l && this.prevText[sameFromLeft] == text[sameFromLeft] ) {
|
| 100 | + ++sameFromLeft;
|
| 101 | + }
|
| 102 | + //if ( this.prevText.length > sameFromLeft ) {
|
| 103 | + //l = l - sameFromLeft;
|
| 104 | + console.log( this.prevText.charCodeAt(8));
|
| 105 | + console.log( text.charCodeAt(8));
|
| 106 | + while ( sameFromRight < l && this.prevText[this.prevText.length - 1 - sameFromRight] == text[text.length - 1 - sameFromRight] ) {
|
| 107 | + ++sameFromRight;
|
| 108 | + }
|
| 109 | + //}
|
| 110 | +
|
| 111 | +
|
| 112 | +
|
| 113 | +
|
| 114 | + if ( textDiffLength === offsetDiff && this.prevText.substring( 0, this.prevOffset ) === text.substring( 0, this.prevOffset ) ) {
|
| 115 | + console.log("keyboard", text.substring( this.prevOffset, offset ), this.prevOffset);
|
| 116 | + } else {
|
| 117 | + //console.log("spellcheck / autocorrect", text.substring( sameFromLeft, offset ) );
|
| 118 | + console.log('to delete', this.prevText.substring( sameFromLeft, this.prevText.length - sameFromRight), sameFromLeft );
|
| 119 | + console.log('to insert', text.substring( sameFromLeft, text.length - sameFromRight ), sameFromLeft );
|
| 120 | +
|
| 121 | + }
|
| 122 | +
|
| 123 | +
|
| 124 | +
|
| 125 | + console.log('textDiffLength', textDiffLength);
|
| 126 | + console.log('offsetDiff', offsetDiff);
|
| 127 | + console.log('prevOffset', this.prevOffset);
|
| 128 | + console.log('offset', offset);
|
| 129 | + console.log('sameFromLeft', sameFromLeft);
|
| 130 | + console.log('sameFromRight', sameFromRight);
|
| 131 | +
|
100 | 132 | this.prevText = text;
|
101 | 133 | }
|
102 | 134 |
|
103 | | - if(hash != this.prevHash) {
|
104 | | - console.log("new DOM", hash);
|
| 135 | + if ( hash !== this.prevHash ) {
|
105 | 136 | this.prevHash = hash;
|
106 | 137 | }
|
| 138 | +
|
| 139 | + this.prevOffset = offset;
|
107 | 140 |
|
108 | | - this.keypress = false;
|
109 | | - this.keyup = false;
|
110 | | - this.keydown = false;
|
111 | | - this.mousedown = false;
|
112 | 141 | };
|
113 | 142 |
|
| 143 | +app.getDOMText2 = function( elem ) {
|
| 144 | + var regex = new RegExp("[" + String.fromCharCode(32) + String.fromCharCode(160) + "]", "g");
|
| 145 | + return app.getDOMText( elem ).replace( regex, " " );
|
| 146 | +};
|
| 147 | +
|
114 | 148 | app.getDOMText = function( elem ) {
|
115 | 149 | var nodeType = elem.nodeType,
|
116 | 150 | ret = '';
|