summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McLear <john@mclear.co.uk>2012-09-14 04:50:08 -0700
committerJohn McLear <john@mclear.co.uk>2012-09-14 04:50:08 -0700
commitba8177fc6f97c5cf12890ea70fc407cdf744ea7e (patch)
tree9c74891de4be8f85e88384f454684d4e010a8c2a
parentc2f5fc32cc84b40d86fcf55162ba0aebe551a9e2 (diff)
parent22315cd30e29efe9a403b95c94fb941597c065c1 (diff)
downloadetherpad-lite-ba8177fc6f97c5cf12890ea70fc407cdf744ea7e.zip
Merge pull request #999 from lepidum/develop
Fixed international composition issues (e.g., Japanese Input method)
-rw-r--r--src/static/js/ace2_inner.js20
-rw-r--r--src/static/js/collab_client.js64
-rw-r--r--src/static/js/pad.js16
3 files changed, 83 insertions, 17 deletions
diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js
index 6bf6720f..4eaf041d 100644
--- a/src/static/js/ace2_inner.js
+++ b/src/static/js/ace2_inner.js
@@ -1161,7 +1161,7 @@ function Ace2Inner(){
//if (! top.BEFORE) top.BEFORE = [];
//top.BEFORE.push(magicdom.root.dom.innerHTML);
//if (! isEditable) return; // and don't reschedule
- if (inInternationalComposition)
+ if (window.parent.parent.inInternationalComposition)
{
// don't do idle input incorporation during international input composition
idleWorkTimer.atLeast(500);
@@ -1486,7 +1486,6 @@ function Ace2Inner(){
if (currentCallStack.domClean) return false;
- inInternationalComposition = false; // if we need the document normalized, so be it
currentCallStack.isUserChange = true;
isTimeUp = (isTimeUp ||
@@ -3690,7 +3689,7 @@ function Ace2Inner(){
thisKeyDoesntTriggerNormalize = true;
}
- if ((!specialHandled) && (!thisKeyDoesntTriggerNormalize) && (!inInternationalComposition))
+ if ((!specialHandled) && (!thisKeyDoesntTriggerNormalize) && (!window.parent.parent.inInternationalComposition))
{
if (type != "keyup" || !incorpIfQuick())
{
@@ -4550,19 +4549,9 @@ function Ace2Inner(){
}
}
- var inInternationalComposition = false;
-
function handleCompositionEvent(evt)
{
- // international input events, fired in FF3, at least; allow e.g. Japanese input
- if (evt.type == "compositionstart")
- {
- inInternationalComposition = true;
- }
- else if (evt.type == "compositionend")
- {
- inInternationalComposition = false;
- }
+ window.parent.parent.handleCompositionEvent(evt);
}
function bindTheEventHandlers()
@@ -4577,7 +4566,8 @@ function Ace2Inner(){
$(document).on("click", handleIEOuterClick);
}
if (browser.msie) $(root).on("paste", handleIEPaste);
- if ((!browser.msie) && document.documentElement)
+ // CompositionEvent is not implemented below IE version 8
+ if ( !(browser.msie && browser.version < 9) && document.documentElement)
{
$(document.documentElement).on("compositionstart", handleCompositionEvent);
$(document.documentElement).on("compositionend", handleCompositionEvent);
diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js
index 7e984710..d149b256 100644
--- a/src/static/js/collab_client.js
+++ b/src/static/js/collab_client.js
@@ -62,6 +62,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
var caughtErrorCatchers = [];
var caughtErrorTimes = [];
var debugMessages = [];
+ var msgQueue = [];
tellAceAboutHistoricalAuthors(serverVars.historicalAuthorData);
tellAceActiveAuthorInfo(initialUserInfo);
@@ -110,6 +111,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
function handleUserChanges()
{
+ if (window.parent.parent.inInternationalComposition) return;
if ((!getSocket()) || channelState == "CONNECTING")
{
if (channelState == "CONNECTING" && (((+new Date()) - initialStartConnectTime) > 20000))
@@ -128,12 +130,12 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
if (state != "IDLE")
{
- if (state == "COMMITTING" && (t - lastCommitTime) > 20000)
+ if (state == "COMMITTING" && msgQueue.length == 0 && (t - lastCommitTime) > 20000)
{
// a commit is taking too long
setChannelState("DISCONNECTED", "slowcommit");
}
- else if (state == "COMMITTING" && (t - lastCommitTime) > 5000)
+ else if (state == "COMMITTING" && msgQueue.length == 0 && (t - lastCommitTime) > 5000)
{
callbacks.onConnectionTrouble("SLOW");
}
@@ -152,6 +154,36 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
return;
}
+ // apply msgQueue changeset.
+ if (msgQueue.length != 0) {
+ while (msg = msgQueue.shift()) {
+ var newRev = msg.newRev;
+ rev=newRev;
+ if (msg.type == "ACCEPT_COMMIT")
+ {
+ editor.applyPreparedChangesetToBase();
+ setStateIdle();
+ callCatchingErrors("onInternalAction", function()
+ {
+ callbacks.onInternalAction("commitAcceptedByServer");
+ });
+ callCatchingErrors("onConnectionTrouble", function()
+ {
+ callbacks.onConnectionTrouble("OK");
+ });
+ handleUserChanges();
+ }
+ else if (msg.type == "NEW_CHANGES")
+ {
+ var changeset = msg.changeset;
+ var author = (msg.author || '');
+ var apool = msg.apool;
+
+ editor.applyChangesToBase(changeset, author, apool);
+ }
+ }
+ }
+
var sentMessage = false;
var userChangesData = editor.prepareUserChangeset();
if (userChangesData.changeset)
@@ -254,6 +286,22 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
var changeset = msg.changeset;
var author = (msg.author || '');
var apool = msg.apool;
+
+ // When inInternationalComposition, msg pushed msgQueue.
+ if (msgQueue.length > 0 || window.parent.parent.inInternationalComposition) {
+ if (msgQueue.length > 0) oldRev = msgQueue[msgQueue.length - 1].newRev;
+ else oldRev = rev;
+
+ if (newRev != (oldRev + 1))
+ {
+ dmesg("bad message revision on NEW_CHANGES: " + newRev + " not " + (oldRev + 1));
+ setChannelState("DISCONNECTED", "badmessage_newchanges");
+ return;
+ }
+ msgQueue.push(msg);
+ return;
+ }
+
if (newRev != (rev + 1))
{
dmesg("bad message revision on NEW_CHANGES: " + newRev + " not " + (rev + 1));
@@ -266,6 +314,18 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
else if (msg.type == "ACCEPT_COMMIT")
{
var newRev = msg.newRev;
+ if (msgQueue.length > 0)
+ {
+ if (newRev != (msgQueue[msgQueue.length - 1].newRev + 1))
+ {
+ dmesg("bad message revision on ACCEPT_COMMIT: " + newRev + " not " + (msgQueue[msgQueue.length - 1][0] + 1));
+ setChannelState("DISCONNECTED", "badmessage_acceptcommit");
+ return;
+ }
+ msgQueue.push(msg);
+ return;
+ }
+
if (newRev != (rev + 1))
{
dmesg("bad message revision on ACCEPT_COMMIT: " + newRev + " not " + (rev + 1));
diff --git a/src/static/js/pad.js b/src/static/js/pad.js
index 46586508..737f5dc6 100644
--- a/src/static/js/pad.js
+++ b/src/static/js/pad.js
@@ -50,6 +50,22 @@ var randomString = require('./pad_utils').randomString;
var hooks = require('./pluginfw/hooks');
+window.inInternationalComposition = false;
+var inInternationalComposition = window.inInternationalComposition;
+
+window.handleCompositionEvent = function handleCompositionEvent(evt)
+ {
+ // international input events, fired in FF3, at least; allow e.g. Japanese input
+ if (evt.type == "compositionstart")
+ {
+ this.inInternationalComposition = true;
+ }
+ else if (evt.type == "compositionend")
+ {
+ this.inInternationalComposition = false;
+ }
+ }
+
function createCookie(name, value, days, path)
{
if (days)