Notify nodes removal to Range/Selection after dispatching blur and mutation event

This patch changes notifying nodes removal to Range/Selection after dispatching blur and mutation event. In willRemoveChildren(), like willRemoveChild(); r115686 did same change, although it didn't change willRemoveChildren().

The issue 295010, use-after-free, is caused by setting removed node to Selection in mutation event handler.

BUG=295010
TEST=LayoutTests/fast/dom/Range/range-created-during-remove-children.html, LayoutTests/editing/selection/selection-change-in-mutation-event-by-remove-children.html, LayoutTests/editing/selection/selection-change-in-blur-event-by-remove-children.html
R=tkent@chromium.org

Review URL: https://codereview.chromium.org/25389004

git-svn-id: svn://svn.chromium.org/blink/trunk@159007 bbb929c8-8fbe-4397-9dbb-9b2b20218538
static inline bool checkAcceptChild(ContainerNode* newParent, Node* newChild, Node* oldChild, ExceptionState& es)
{
    if (!newChild) {
        es.throwUninformativeAndGenericDOMException(NotFoundError);
        return false;
    }

    if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isElementNode()) {
        ASSERT(!newParent->isDocumentTypeNode());
        ASSERT(isChildTypeAllowed(newParent, newChild));
        if (containsConsideringHostElements(newChild, newParent)) {
            es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
            return false;
        }
        return true;
    }

    ASSERT(!newChild->isPseudoElement());
    if (newChild->isPseudoElement()) {
        es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
        return false;
    }

    if (containsConsideringHostElements(newChild, newParent)) {
        es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
        return false;
    }

    if (oldChild && newParent->isDocumentNode()) {
        if (!toDocument(newParent)->canReplaceChild(newChild, oldChild)) {
            es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
            return false;
        }
    } else if (!isChildTypeAllowed(newParent, newChild)) {
        es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
        return false;
    }

    return true;
}

static inline bool checkAcceptChild(ContainerNode* newParent, Node* newChild, Node* oldChild, ExceptionState& es)
{
    if (!newChild) {
        es.throwUninformativeAndGenericDOMException(NotFoundError);
        return false;
    }

    if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isElementNode()) {
        ASSERT(!newParent->isDocumentTypeNode());
        ASSERT(isChildTypeAllowed(newParent, newChild));
        if (containsConsideringHostElements(newChild, newParent)) {
            es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
            return false;
        }
        return true;
    }

    ASSERT(!newChild->isPseudoElement());
    if (newChild->isPseudoElement()) {
        es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
        return false;
    }

    if (containsConsideringHostElements(newChild, newParent)) {
        es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
        return false;
    }

    if (oldChild && newParent->isDocumentNode()) {
        if (!toDocument(newParent)->canReplaceChild(newChild, oldChild)) {
            es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
            return false;
        }
    } else if (!isChildTypeAllowed(newParent, newChild)) {
        es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
        return false;
    }

    return true;
}
