From b3ddd85b09422ac07f7e20dea4cb5c7b0e505148 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Thu, 8 Mar 2018 09:17:15 +0100 Subject: [PATCH] Fixed: Editing text in tableviews throws DOM exceptions under certain conditions in Chrome (#2563) Previosly, we unflagged ```CPTextFieldInputDidBlur``` and ```CPTextFieldInputResigning``` before the call to removeChild. This resulted in DOM exceptions in Chrome under certain conditions. See https://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node for why we need to unflag ```CPTextFieldInputDidBlur``` and ```CPTextFieldInputResigning``` only after removing the element. This apply to token fields also but with the corresponding flags. Also token fields now have the same behavior as the text field when bluring etc. --- AppKit/CPTextField.j | 12 +++++++++--- AppKit/CPTokenField.j | 16 ++++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 3e07825e5..e0000f2cb 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -873,12 +873,18 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); if (!CPTextFieldInputDidBlur) CPTextFieldBlurHandler(); - CPTextFieldInputDidBlur = NO; - CPTextFieldInputResigning = NO; - if (element.parentNode == _DOMElement) element.parentNode.removeChild(element); + // Previosly, we unflagged CPTextFieldInputDidBlur and CPTextFieldInputResigning before + // the call to removeChild. This resulted in DOM exceptions in Chrome under certain conditions. + // See https://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node + // for why we need to unflag CPTextFieldInputDidBlur and CPTextFieldInputResigning + // only after removing the element. + + CPTextFieldInputDidBlur = NO; + CPTextFieldInputResigning = NO; + CPTextFieldInputIsActive = NO; if (document.attachEvent) diff --git a/AppKit/CPTokenField.j b/AppKit/CPTokenField.j index 858b11495..1d4471a8c 100644 --- a/AppKit/CPTokenField.j +++ b/AppKit/CPTokenField.j @@ -523,17 +523,25 @@ CPTokenFieldDeleteButtonType = 1; var element = [self _inputElement]; CPTokenFieldInputResigning = YES; - element.blur(); + + if (CPTokenFieldInputIsActive) + element.blur(); if (!CPTokenFieldInputDidBlur) CPTokenFieldBlurHandler(); - CPTokenFieldInputDidBlur = NO; - CPTokenFieldInputResigning = NO; - if (element.parentNode == [_tokenScrollView documentView]._DOMElement) element.parentNode.removeChild(element); + // Previosly, we unflagged CPTokenFieldInputDidBlur and CPTokenFieldInputResigning before + // the call to removeChild. This may result in DOM exceptions in Chrome under certain conditions. + // See https://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node + // for why we need to unflag CPTokenFieldInputDidBlur and CPTokenFieldInputResigning + // only after removing the element. + + CPTokenFieldInputDidBlur = NO; + CPTokenFieldInputResigning = NO; + CPTokenFieldInputIsActive = NO; if (document.attachEvent)