diff options
| author | Michael Williamson <mike@zwobble.org> | 2024-11-30 11:32:45 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2024-11-30 11:32:45 +0000 |
| commit | 0a86099a0d60c8bfe404cf66b5e5f1fb1549bb1d (patch) | |
| tree | e0e090e2a7bb1384e277b55e10294dc518dacfdf | |
| parent | 3751195339954f49f525446de0795d2acad2c234 (diff) | |
Parse default value of complex field checkbox
| -rw-r--r-- | lib/docx/body-reader.js | 31 | ||||
| -rw-r--r-- | lib/xml/index.js | 1 | ||||
| -rw-r--r-- | lib/xml/nodes.js | 2 | ||||
| -rw-r--r-- | test/docx/body-reader.tests.js | 78 |
4 files changed, 85 insertions, 27 deletions
diff --git a/lib/docx/body-reader.js b/lib/docx/body-reader.js index a4a6c0c..2726b76 100644 --- a/lib/docx/body-reader.js +++ b/lib/docx/body-reader.js @@ -7,6 +7,7 @@ var _ = require("underscore"); var documents = require("../documents"); var Result = require("../results").Result; var warning = require("../results").warning; +var xml = require("../xml"); var uris = require("./uris"); function createBodyReader(options) { @@ -157,21 +158,26 @@ function BodyReader(options) { return elementResultWithMessages({styleId: styleId, name: name}, messages); } - var unknownComplexField = {type: "unknown"}; - function readFldChar(element) { var type = element.attributes["w:fldCharType"]; if (type === "begin") { - complexFieldStack.push(unknownComplexField); + complexFieldStack.push({type: "begin", fldChar: element}); currentInstrText = []; } else if (type === "end") { var complexFieldEnd = complexFieldStack.pop(); if (complexFieldEnd.type === "checkbox") { - return elementResult(documents.checkbox({checked: false})); + return elementResult(documents.checkbox({ + checked: complexFieldEnd.checked + })); } } else if (type === "separate") { - var complexField = parseInstrText(currentInstrText.join('')); - complexFieldStack.pop(); + var complexFieldSeparate = complexFieldStack.pop(); + var complexField = parseInstrText( + currentInstrText.join(''), + complexFieldSeparate.type === "begin" + ? complexFieldSeparate.fldChar + : xml.emptyElement + ); complexFieldStack.push(complexField); } return emptyResult(); @@ -184,7 +190,7 @@ function BodyReader(options) { return topHyperlink ? topHyperlink.options : null; } - function parseInstrText(instrText) { + function parseInstrText(instrText, fldChar) { var externalLinkResult = /\s*HYPERLINK "(.*)"/.exec(instrText); if (externalLinkResult) { return {type: "hyperlink", options: {href: externalLinkResult[1]}}; @@ -197,10 +203,17 @@ function BodyReader(options) { var checkboxResult = /\s*FORMCHECKBOX\s*/.exec(instrText); if (checkboxResult) { - return {type: "checkbox"}; + var checkboxElement = fldChar + .firstOrEmpty("w:ffData") + .firstOrEmpty("w:checkBox"); + var defaultValue = readBooleanElement( + checkboxElement.first("w:default") + ); + var checked = defaultValue; + return {type: "checkbox", checked: checked}; } - return unknownComplexField; + return {type: "unknown"}; } function readInstrText(element) { diff --git a/lib/xml/index.js b/lib/xml/index.js index a2f572e..2532bd7 100644 --- a/lib/xml/index.js +++ b/lib/xml/index.js @@ -2,6 +2,7 @@ var nodes = require("./nodes"); exports.Element = nodes.Element; exports.element = nodes.element; +exports.emptyElement = nodes.emptyElement; exports.text = nodes.text; exports.readString = require("./reader").readString; exports.writeString = require("./writer").writeString; diff --git a/lib/xml/nodes.js b/lib/xml/nodes.js index 76f5fd7..2c77d4d 100644 --- a/lib/xml/nodes.js +++ b/lib/xml/nodes.js @@ -13,7 +13,7 @@ exports.text = function(value) { }; -var emptyElement = { +var emptyElement = exports.emptyElement = { first: function() { return null; }, diff --git a/test/docx/body-reader.tests.js b/test/docx/body-reader.tests.js index a431866..49c81b9 100644 --- a/test/docx/body-reader.tests.js +++ b/test/docx/body-reader.tests.js @@ -532,23 +532,28 @@ test("complex fields", (function() { })()); test("checkboxes", { - "complex field checkbox without default or checked elements is unchecked": function() { - var paragraphXml = xml.element("w:p", {}, [ - xml.element("w:r", {}, [ - xml.element("w:fldChar", {"w:fldCharType": "begin"}, [ - xml.element("w:ffData", {}, [ - xml.element("w:checkBox") - ]) - ]) - ]), - xml.element("w:instrText", {}, [ - xml.text(' FORMCHECKBOX ') - ]), - xml.element("w:r", {}, [ - xml.element("w:fldChar", {"w:fldCharType": "separate"}) - ]), - xml.element("w:r", {}, [ - xml.element("w:fldChar", {"w:fldCharType": "end"}) + "complex field checkbox without w:default nor w:checked is unchecked": function() { + var paragraphXml = complexFieldCheckboxParagraph([ + xml.element("w:checkBox") + ]); + + var paragraph = readXmlElementValue(paragraphXml); + + assertThat(paragraph.children, contains( + isEmptyRun, + isEmptyRun, + isRun({ + children: contains( + isCheckbox({checked: equalTo(false)}) + ) + }) + )); + }, + + "complex field checkbox with w:default=0 and without w:checked is unchecked": function() { + var paragraphXml = complexFieldCheckboxParagraph([ + xml.element("w:checkBox", {}, [ + xml.element("w:default", {"w:val": "0"}) ]) ]); @@ -563,9 +568,48 @@ test("checkboxes", { ) }) )); + }, + + "complex field checkbox with w:default=1 and without w:checked is checked": function() { + var paragraphXml = complexFieldCheckboxParagraph([ + xml.element("w:checkBox", {}, [ + xml.element("w:default", {"w:val": "1"}) + ]) + ]); + + var paragraph = readXmlElementValue(paragraphXml); + + assertThat(paragraph.children, contains( + isEmptyRun, + isEmptyRun, + isRun({ + children: contains( + isCheckbox({checked: equalTo(true)}) + ) + }) + )); } }); +function complexFieldCheckboxParagraph(ffDataChildren) { + return xml.element("w:p", {}, [ + xml.element("w:r", {}, [ + xml.element("w:fldChar", {"w:fldCharType": "begin"}, [ + xml.element("w:ffData", {}, ffDataChildren) + ]) + ]), + xml.element("w:instrText", {}, [ + xml.text(' FORMCHECKBOX ') + ]), + xml.element("w:r", {}, [ + xml.element("w:fldChar", {"w:fldCharType": "separate"}) + ]), + xml.element("w:r", {}, [ + xml.element("w:fldChar", {"w:fldCharType": "end"}) + ]) + ]); +} + test("run has no style if it has no properties", function() { var runXml = runWithProperties([]); var run = readXmlElementValue(runXml); |
