diff --git a/dom/m_dom_character_data.m4 b/dom/m_dom_character_data.m4 index dfcd1916..3f51a756 100644 --- a/dom/m_dom_character_data.m4 +++ b/dom/m_dom_character_data.m4 @@ -101,6 +101,10 @@ TOHW_m_dom_contents(` TOHW_m_dom_throw_error(FoX_INVALID_CDATA_SECTION) endif + ! And propagate length upwards ... + if (getNodeType(arg)/=COMMENT_NODE) & + call updateTextContentLength(arg, len(data)) + end subroutine appendData @@ -139,6 +143,10 @@ TOHW_m_dom_contents(` TOHW_m_dom_throw_error(FoX_INVALID_CDATA_SECTION) endif + ! And propagate length upwards ... + if (getNodeType(arg)/=COMMENT_NODE) & + call updateTextContentLength(arg, len(data)) + end subroutine insertData @@ -148,6 +156,7 @@ TOHW_m_dom_contents(` integer, intent(in) :: count character, pointer :: tmp(:) + integer :: n if (.not.associated(arg)) then TOHW_m_dom_throw_error(FoX_NODE_IS_NULL) @@ -160,11 +169,21 @@ TOHW_m_dom_contents(` elseif (offset<0.or.offset>size(arg%nodeValue).or.count<0) then TOHW_m_dom_throw_error(INDEX_SIZE_ERR) endif + + if (offset+count>size(arg%nodeValue)) then + n = size(arg%nodeValue)-offset + else + n = count + endif tmp => arg%nodeValue arg%nodeValue => vs_str_alloc(str_vs(tmp(:offset))//str_vs(tmp(offset+count+1:))) deallocate(tmp) + ! And propagate length upwards ... + if (getNodeType(arg)/=COMMENT_NODE) & + call updateTextContentLength(arg, -n) + end subroutine deleteData @@ -175,6 +194,7 @@ TOHW_m_dom_contents(` character(len=*), intent(in) :: data character, pointer :: tmp(:) + integer :: n if (.not.associated(arg)) then TOHW_m_dom_throw_error(FoX_NODE_IS_NULL) @@ -192,6 +212,12 @@ TOHW_m_dom_contents(` TOHW_m_dom_throw_error(FoX_INVALID_CHARACTER) endif + if (offset+count>size(arg%nodeValue)) then + n = len(data)-(size(arg%nodeValue)-offset) + else + n = len(data)-count + endif + tmp => arg%nodeValue if (offset+count <= size(arg%nodeValue)) then arg%nodeValue => vs_str_alloc(str_vs(tmp(:offset))//data//str_vs(tmp(offset+count+1:))) @@ -208,6 +234,10 @@ TOHW_m_dom_contents(` TOHW_m_dom_throw_error(FoX_INVALID_CDATA_SECTION) endif + ! And propagate length upwards ... + if (getNodeType(arg)/=COMMENT_NODE) & + call updateTextContentLength(arg, n) + end subroutine replaceData ')`'dnl diff --git a/dom/m_dom_common.m4 b/dom/m_dom_common.m4 index 27440de3..5e12a183 100644 --- a/dom/m_dom_common.m4 +++ b/dom/m_dom_common.m4 @@ -17,6 +17,8 @@ TOHW_m_dom_contents(` TOHW_subroutine(setData, (arg, data)) type(Node), pointer :: arg character(len=*) :: data + + integer :: n if (.not.associated(arg)) then TOHW_m_dom_throw_error(FoX_NODE_IS_NULL) @@ -30,11 +32,34 @@ TOHW_m_dom_contents(` if (arg%readonly) then TOHW_m_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR) endif - deallocate(arg%nodeValue) - arg%nodeValue => vs_str_alloc(data) else TOHW_m_dom_throw_error(FoX_INVALID_NODE) endif + + select case (arg%nodeType) + case (CDATA_SECTION_NODE) + if (index(data,"]]>")>0) then + TOHW_m_dom_throw_error(FoX_INVALID_CDATA_SECTION) + endif + case (COMMENT_NODE) + if (index(data,"--")>0) then + TOHW_m_dom_throw_error(FoX_INVALID_COMMENT) + endif + case (PROCESSING_INSTRUCTION_NODE) + if (index(data,"?>")>0) then + TOHW_m_dom_throw_error(FoX_INVALID_PI_DATA) + endif + end select + + deallocate(arg%nodeValue) + arg%nodeValue => vs_str_alloc(data) + + if (arg%nodeType==TEXT_NODE .or. & + arg%nodeType==CDATA_SECTION_NODE) then + n = len(data) - arg%textContentLength + call updateTextContentLength(arg, n) + endif + end subroutine setData TOHW_m_dom_get(DOMString, name, np%nodeName, (DOCUMENT_TYPE_NODE, ATTRIBUTE_NODE)) diff --git a/dom/m_dom_document.m4 b/dom/m_dom_document.m4 index 45712fbe..3a210b98 100644 --- a/dom/m_dom_document.m4 +++ b/dom/m_dom_document.m4 @@ -222,6 +222,7 @@ TOHW_m_dom_get(Node, documentElement, np%docExtras%documentElement, (DOCUMENT_NO endif np => createNode(arg, TEXT_NODE, "#text", data) + np%textContentLength = len(data) if (getGCstate(arg)) then np%inDocument = .false. @@ -250,6 +251,7 @@ TOHW_m_dom_get(Node, documentElement, np%docExtras%documentElement, (DOCUMENT_NO endif np => createNode(arg, COMMENT_NODE, "#comment", data) + np%textContentLength = len(data) if (getGCstate(arg)) then np%inDocument = .false. @@ -278,6 +280,7 @@ TOHW_m_dom_get(Node, documentElement, np%docExtras%documentElement, (DOCUMENT_NO endif np => createNode(arg, CDATA_SECTION_NODE, "#cdata-section", data) + np%textContentLength = len(data) if (getGCstate(arg)) then np%inDocument = .false. @@ -309,6 +312,7 @@ TOHW_m_dom_get(Node, documentElement, np%docExtras%documentElement, (DOCUMENT_NO endif np => createNode(arg, PROCESSING_INSTRUCTION_NODE, target, data) + np%textContentLength = len(data) if (getGCstate(arg)) then np%inDocument = .false. diff --git a/dom/m_dom_dom.f90 b/dom/m_dom_dom.f90 index db525170..619f7654 100644 --- a/dom/m_dom_dom.f90 +++ b/dom/m_dom_dom.f90 @@ -1940,6 +1940,8 @@ function insertBefore(arg, newChild, refChild, ex)result(np) call updateNodeLists(arg%ownerDocument) + call updateTextContentLength(arg, newChild%textContentLength) + end function insertBefore @@ -2447,6 +2449,8 @@ function replaceChild(arg, newChild, oldChild, ex)result(np) call updateNodeLists(arg%ownerDocument) + call updateTextContentLength(arg, newChild%textContentLength-oldChild%textContentLength) + end function replaceChild @@ -2541,6 +2545,8 @@ function removeChild(arg, oldChild, ex)result(np) call updateNodeLists(arg%ownerDocument) + call updateTextContentLength(arg, -oldChild%textContentLength) + end function removeChild @@ -3010,6 +3016,8 @@ function appendChild(arg, newChild, ex)result(np) call updateNodeLists(arg%ownerDocument) + call updateTextContentLength(arg, newChild%textContentLength) + end function appendChild @@ -4114,12 +4122,15 @@ subroutine updateTextContentLength(np, n) type(Node), pointer :: np integer, intent(in) :: n - if (n/=0) then - do while (associated(np)) - np%textContentLength = np%textContentLength + n - np => getParentNode(np) - if (associated(np)) then - if (getNodeType(np)==DOCUMENT_NODE) exit + type(Node), pointer :: this + + if (n/=0) then + this => np + do while (associated(this)) + this%textContentLength = this%textContentLength + n + this => getParentNode(this) + if (associated(this)) then + if (getNodeType(this)==DOCUMENT_NODE) exit endif enddo endif @@ -6036,6 +6047,7 @@ function createTextNode(arg, data, ex)result(np) endif np => createNode(arg, TEXT_NODE, "#text", data) + np%textContentLength = len(data) if (getGCstate(arg)) then np%inDocument = .false. @@ -6097,6 +6109,7 @@ function createComment(arg, data, ex)result(np) endif np => createNode(arg, COMMENT_NODE, "#comment", data) + np%textContentLength = len(data) if (getGCstate(arg)) then np%inDocument = .false. @@ -6158,6 +6171,7 @@ function createCdataSection(arg, data, ex)result(np) endif np => createNode(arg, CDATA_SECTION_NODE, "#cdata-section", data) + np%textContentLength = len(data) if (getGCstate(arg)) then np%inDocument = .false. @@ -6230,6 +6244,7 @@ function createProcessingInstruction(arg, target, data, ex)result(np) endif np => createNode(arg, PROCESSING_INSTRUCTION_NODE, target, data) + np%textContentLength = len(data) if (getGCstate(arg)) then np%inDocument = .false. @@ -9875,6 +9890,10 @@ subroutine appendData(arg, data, ex) endif + ! And propagate length upwards ... + if (getNodeType(arg)/=COMMENT_NODE) & + call updateTextContentLength(arg, len(data)) + end subroutine appendData @@ -9970,6 +9989,10 @@ subroutine insertData(arg, offset, data, ex) endif + ! And propagate length upwards ... + if (getNodeType(arg)/=COMMENT_NODE) & + call updateTextContentLength(arg, len(data)) + end subroutine insertData @@ -9980,6 +10003,7 @@ subroutine deleteData(arg, offset, count, ex) integer, intent(in) :: count character, pointer :: tmp(:) + integer :: n if (.not.associated(arg)) then if (getFoX_checks().or.FoX_NODE_IS_NULL<200) then @@ -10024,11 +10048,21 @@ subroutine deleteData(arg, offset, count, ex) endif endif + + if (offset+count>size(arg%nodeValue)) then + n = size(arg%nodeValue)-offset + else + n = count + endif tmp => arg%nodeValue arg%nodeValue => vs_str_alloc(str_vs(tmp(:offset))//str_vs(tmp(offset+count+1:))) deallocate(tmp) + ! And propagate length upwards ... + if (getNodeType(arg)/=COMMENT_NODE) & + call updateTextContentLength(arg, -n) + end subroutine deleteData @@ -10040,6 +10074,7 @@ subroutine replaceData(arg, offset, count, data, ex) character(len=*), intent(in) :: data character, pointer :: tmp(:) + integer :: n if (.not.associated(arg)) then if (getFoX_checks().or.FoX_NODE_IS_NULL<200) then @@ -10097,6 +10132,12 @@ subroutine replaceData(arg, offset, count, data, ex) endif + if (offset+count>size(arg%nodeValue)) then + n = len(data)-(size(arg%nodeValue)-offset) + else + n = len(data)-count + endif + tmp => arg%nodeValue if (offset+count <= size(arg%nodeValue)) then arg%nodeValue => vs_str_alloc(str_vs(tmp(:offset))//data//str_vs(tmp(offset+count+1:))) @@ -10129,6 +10170,10 @@ subroutine replaceData(arg, offset, count, data, ex) endif + ! And propagate length upwards ... + if (getNodeType(arg)/=COMMENT_NODE) & + call updateTextContentLength(arg, n) + end subroutine replaceData @@ -10492,7 +10537,17 @@ subroutine setIsElementContentWhitespace(np, isElementContentWhitespace, ex) type(Node), pointer :: np logical :: isElementContentWhitespace + integer :: n + np%ignorableWhitespace = isElementContentWhitespace + + if (isElementContentWhitespace) then + n = -np%textContentLength + else + n = size(np%nodeValue) + endif + + call updateTextContentLength(np, n) end subroutine setIsElementContentWhitespace @@ -10561,6 +10616,8 @@ subroutine setData(arg, data, ex) type(DOMException), intent(out), optional :: ex type(Node), pointer :: arg character(len=*) :: data + + integer :: n if (.not.associated(arg)) then if (getFoX_checks().or.FoX_NODE_IS_NULL<200) then @@ -10590,8 +10647,6 @@ subroutine setData(arg, data, ex) endif endif - deallocate(arg%nodeValue) - arg%nodeValue => vs_str_alloc(data) else if (getFoX_checks().or.FoX_INVALID_NODE<200) then call throw_exception(FoX_INVALID_NODE, "setData", ex) @@ -10603,6 +10658,55 @@ subroutine setData(arg, data, ex) endif endif + + select case (arg%nodeType) + case (CDATA_SECTION_NODE) + if (index(data,"]]>")>0) then + if (getFoX_checks().or.FoX_INVALID_CDATA_SECTION<200) then + call throw_exception(FoX_INVALID_CDATA_SECTION, "setData", ex) + if (present(ex)) then + if (inException(ex)) then + return + endif + endif +endif + + endif + case (COMMENT_NODE) + if (index(data,"--")>0) then + if (getFoX_checks().or.FoX_INVALID_COMMENT<200) then + call throw_exception(FoX_INVALID_COMMENT, "setData", ex) + if (present(ex)) then + if (inException(ex)) then + return + endif + endif +endif + + endif + case (PROCESSING_INSTRUCTION_NODE) + if (index(data,"?>")>0) then + if (getFoX_checks().or.FoX_INVALID_PI_DATA<200) then + call throw_exception(FoX_INVALID_PI_DATA, "setData", ex) + if (present(ex)) then + if (inException(ex)) then + return + endif + endif +endif + + endif + end select + + deallocate(arg%nodeValue) + arg%nodeValue => vs_str_alloc(data) + + if (arg%nodeType==TEXT_NODE .or. & + arg%nodeType==CDATA_SECTION_NODE) then + n = len(data) - arg%textContentLength + call updateTextContentLength(arg, n) + endif + end subroutine setData diff --git a/dom/m_dom_node.m4 b/dom/m_dom_node.m4 index 4f261583..c8ce3d5c 100644 --- a/dom/m_dom_node.m4 +++ b/dom/m_dom_node.m4 @@ -344,6 +344,8 @@ TOHW_m_dom_get(Node, nextSibling, np%nextSibling) call updateNodeLists(arg%ownerDocument) + call updateTextContentLength(arg, newChild%textContentLength) + end function insertBefore @@ -480,6 +482,8 @@ TOHW_m_dom_get(Node, nextSibling, np%nextSibling) call updateNodeLists(arg%ownerDocument) + call updateTextContentLength(arg, newChild%textContentLength-oldChild%textContentLength) + end function replaceChild @@ -549,6 +553,8 @@ TOHW_m_dom_get(Node, nextSibling, np%nextSibling) call updateNodeLists(arg%ownerDocument) + call updateTextContentLength(arg, -oldChild%textContentLength) + end function removeChild @@ -667,6 +673,8 @@ TOHW_m_dom_get(Node, nextSibling, np%nextSibling) call updateNodeLists(arg%ownerDocument) + call updateTextContentLength(arg, newChild%textContentLength) + end function appendChild @@ -1348,12 +1356,15 @@ TOHW_m_dom_treewalk(` type(Node), pointer :: np integer, intent(in) :: n - if (n/=0) then - do while (associated(np)) - np%textContentLength = np%textContentLength + n - np => getParentNode(np) - if (associated(np)) then - if (getNodeType(np)==DOCUMENT_NODE) exit + type(Node), pointer :: this + + if (n/=0) then + this => np + do while (associated(this)) + this%textContentLength = this%textContentLength + n + this => getParentNode(this) + if (associated(this)) then + if (getNodeType(this)==DOCUMENT_NODE) exit endif enddo endif diff --git a/dom/m_dom_text.m4 b/dom/m_dom_text.m4 index 340fbd17..61061166 100644 --- a/dom/m_dom_text.m4 +++ b/dom/m_dom_text.m4 @@ -50,7 +50,17 @@ TOHW_m_dom_get(logical, isElementContentWhitespace, np%ignorableWhitespace, (TEX type(Node), pointer :: np logical :: isElementContentWhitespace + integer :: n + np%ignorableWhitespace = isElementContentWhitespace + + if (isElementContentWhitespace) then + n = -np%textContentLength + else + n = size(np%nodeValue) + endif + + call updateTextContentLength(np, n) end subroutine setIsElementContentWhitespace