static inline ExceptionCode checkAcceptChild(ContainerNode* newParent, Node* newChild, Node* oldChild) { // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null if (!newChild) return NOT_FOUND_ERR; // Use common case fast path if possible. if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isElementNode()) { ASSERT(!newParent->isReadOnlyNode()); ASSERT(!newParent->isDocumentTypeNode()); ASSERT(isChildTypeAllowed(newParent, newChild)); if (containsConsideringHostElements(newChild, newParent)) return HIERARCHY_REQUEST_ERR; return 0; } // This should never happen, but also protect release builds from tree corruption. ASSERT(!newChild->isPseudoElement()); if (newChild->isPseudoElement()) return HIERARCHY_REQUEST_ERR; if (newParent->isReadOnlyNode()) return NO_MODIFICATION_ALLOWED_ERR; if (containsConsideringHostElements(newChild, newParent)) return HIERARCHY_REQUEST_ERR; if (oldChild && newParent->isDocumentNode()) { if (!toDocument(newParent)->canReplaceChild(newChild, oldChild)) return HIERARCHY_REQUEST_ERR; } else if (!isChildTypeAllowed(newParent, newChild)) return HIERARCHY_REQUEST_ERR; return 0; }
static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode* newParent, Node* newChild, ExceptionCode& ec) { ASSERT(!newParent->isReadOnlyNode()); ASSERT(!newParent->isDocumentTypeNode()); ASSERT(isChildTypeAllowed(newParent, newChild)); if (newChild->contains(newParent)) { ec = HIERARCHY_REQUEST_ERR; return false; } return true; }
void DivNode::insertChild(NodePtr pChild, unsigned i) { if (!pChild) { throw Exception(AVG_ERR_NO_NODE, getID()+"::insertChild called without a node."); } if (pChild->getState() == NS_CONNECTED || pChild->getState() == NS_CANRENDER) { throw(Exception(AVG_ERR_ALREADY_CONNECTED, "Can't connect node with id "+pChild->getID()+ ": already connected.")); } if (getState() == NS_CONNECTED || getState() == NS_CANRENDER) { getCanvas()->registerNode(pChild); } DivNodePtr ptr = dynamic_pointer_cast<DivNode>(shared_from_this()); pChild->checkSetParentError(ptr); if (!isChildTypeAllowed(pChild->getTypeStr())) { throw(Exception(AVG_ERR_ALREADY_CONNECTED, "Can't insert a node of type "+pChild->getTypeStr()+ " into a node of type "+getTypeStr()+".")); } if (i > m_Children.size()) { throw(Exception(AVG_ERR_OUT_OF_RANGE, pChild->getID()+"::insertChild: index out of bounds.")); } std::vector<NodePtr>::iterator pos = m_Children.begin()+i; m_Children.insert(pos, pChild); try { pChild->setParent(ptr, getState(), getCanvas()); } catch (Exception&) { m_Children.erase(m_Children.begin()+i); throw; } if (getState() == NS_CANRENDER) { pChild->connectDisplay(); } }