From 71c9444694aea1d5f931963bb57f065b2b54efbd Mon Sep 17 00:00:00 2001 From: "NAGOYA, Yoshihiko" Date: Thu, 13 Sep 2012 23:19:53 +0900 Subject: [PATCH] fix for InternationalComposition(e.g., Japanese Input) moved inInternationalComposition from Ace2Inner to top window fix bindTheEventHandlers() because ie9 implement CompositionEvent when inInternationalComposition, NEW_CHANGES msg and ACCEPT_COMMIT msg are pushed msgQueue. when handleUserChanges(), apply msgQueue. --- src/static/js/ace2_inner.js | 20 +++-------- src/static/js/collab_client.js | 64 ++++++++++++++++++++++++++++++++-- src/static/js/pad.js | 16 +++++++++ 3 files changed, 83 insertions(+), 17 deletions(-) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 07580faa..f56b0525 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 a22e181a..b7fe9c3d 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)