Bug 1514940 - part 1: Forcibly disable new keyCode/charCode value of keypress events if the document is Confluence r=smaug,Ehsan,kmag

Old Confluence does not aware of conflated model keypress event (see UI Events
spec, https://w3c.github.io/uievents/#determine-keypress-keyCode).
Additionally, Confluence can be hosted with any domains.  Therefore, we cannot
use blacklist to disable the conflated model keypress event only on it.

This patch checks whether current or parent document is Confluence with JS
module, called KeyPressEventModelCheckerChild.  For kicking this module,
nsHTMLDocument dispatches an custom event, CheckKeyPressEventModel, when it
becomes editable only first time.  Finally, if it's a Confluence instance, the
module let PresShell know that we need to use split model keypress event in it.

Differential Revision: https://phabricator.services.mozilla.com/D17907
This commit is contained in:
Masayuki Nakano
2019-02-05 11:35:43 +00:00
parent 8ef944ab85
commit 5133af6274
12 changed files with 274 additions and 2 deletions

View File

@@ -176,7 +176,8 @@ nsHTMLDocument::nsHTMLDocument()
mContentEditableCount(0),
mEditingState(EditingState::eOff),
mDisableCookieAccess(false),
mPendingMaybeEditingStateChanged(false) {
mPendingMaybeEditingStateChanged(false),
mHasBeenEditable(false) {
mType = eHTML;
mDefaultElementType = kNameSpaceID_XHTML;
mCompatMode = eCompatibility_NavQuirks;
@@ -2434,9 +2435,45 @@ nsresult nsHTMLDocument::EditingStateChanged() {
}
htmlEditor->SyncRealTimeSpell();
MaybeDispatchCheckKeyPressEventModelEvent();
return NS_OK;
}
void nsHTMLDocument::MaybeDispatchCheckKeyPressEventModelEvent() {
// Currently, we need to check only when we're becoming editable for
// contenteditable.
if (mEditingState != eContentEditable) {
return;
}
if (mHasBeenEditable) {
return;
}
mHasBeenEditable = true;
// Dispatch "CheckKeyPressEventModel" event. That is handled only by
// KeyPressEventModelCheckerChild. Then, it calls SetKeyPressEventModel()
// with proper keypress event for the active web app.
WidgetEvent checkEvent(true, eUnidentifiedEvent);
checkEvent.mSpecifiedEventType = nsGkAtoms::onCheckKeyPressEventModel;
checkEvent.mFlags.mCancelable = false;
checkEvent.mFlags.mBubbles = false;
checkEvent.mFlags.mOnlySystemGroupDispatch = true;
// Post the event rather than dispatching it synchronously because we need
// a call of SetKeyPressEventModel() before first key input. Therefore, we
// can avoid paying unnecessary runtime cost for most web apps.
(new AsyncEventDispatcher(this, checkEvent))->PostDOMEvent();
}
void nsHTMLDocument::SetKeyPressEventModel(uint16_t aKeyPressEventModel) {
nsIPresShell* presShell = GetShell();
if (!presShell) {
return;
}
presShell->SetKeyPressEventModel(aKeyPressEventModel);
}
void nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode,
nsIPrincipal& aSubjectPrincipal,
ErrorResult& rv) {