Skip to content

Commit

Permalink
Read complex field checkboxes, always unchecked
Browse files Browse the repository at this point in the history
  • Loading branch information
mwilliamson committed Nov 30, 2024
1 parent f79db6f commit 3751195
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 9 deletions.
9 changes: 9 additions & 0 deletions lib/documents.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var types = exports.types = {
run: "run",
text: "text",
tab: "tab",
checkbox: "checkbox",
hyperlink: "hyperlink",
noteReference: "noteReference",
image: "image",
Expand Down Expand Up @@ -87,6 +88,13 @@ function Tab() {
};
}

function Checkbox(options) {
return {
type: types.checkbox,
checked: options.checked
};
}

function Hyperlink(children, options) {
return {
type: types.hyperlink,
Expand Down Expand Up @@ -227,6 +235,7 @@ exports.paragraph = exports.Paragraph = Paragraph;
exports.run = exports.Run = Run;
exports.text = exports.Text = Text;
exports.tab = exports.Tab = Tab;
exports.checkbox = exports.Checkbox = Checkbox;
exports.Hyperlink = Hyperlink;
exports.noteReference = exports.NoteReference = NoteReference;
exports.Notes = Notes;
Expand Down
25 changes: 16 additions & 9 deletions lib/docx/body-reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,12 @@ function BodyReader(options) {
complexFieldStack.push(unknownComplexField);
currentInstrText = [];
} else if (type === "end") {
complexFieldStack.pop();
var complexFieldEnd = complexFieldStack.pop();
if (complexFieldEnd.type === "checkbox") {
return elementResult(documents.checkbox({checked: false}));
}
} else if (type === "separate") {
var hyperlinkOptions = parseHyperlinkFieldCode(currentInstrText.join(''));
var complexField = hyperlinkOptions === null ? unknownComplexField : {type: "hyperlink", options: hyperlinkOptions};
var complexField = parseInstrText(currentInstrText.join(''));
complexFieldStack.pop();
complexFieldStack.push(complexField);
}
Expand All @@ -182,18 +184,23 @@ function BodyReader(options) {
return topHyperlink ? topHyperlink.options : null;
}

function parseHyperlinkFieldCode(code) {
var externalLinkResult = /\s*HYPERLINK "(.*)"/.exec(code);
function parseInstrText(instrText) {
var externalLinkResult = /\s*HYPERLINK "(.*)"/.exec(instrText);
if (externalLinkResult) {
return {href: externalLinkResult[1]};
return {type: "hyperlink", options: {href: externalLinkResult[1]}};
}

var internalLinkResult = /\s*HYPERLINK\s+\\l\s+"(.*)"/.exec(code);
var internalLinkResult = /\s*HYPERLINK\s+\\l\s+"(.*)"/.exec(instrText);
if (internalLinkResult) {
return {anchor: internalLinkResult[1]};
return {type: "hyperlink", options: {anchor: internalLinkResult[1]}};
}

var checkboxResult = /\s*FORMCHECKBOX\s*/.exec(instrText);
if (checkboxResult) {
return {type: "checkbox"};
}

return null;
return unknownComplexField;
}

function readInstrText(element) {
Expand Down
37 changes: 37 additions & 0 deletions test/docx/body-reader.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ var assertThat = hamjest.assertThat;
var promiseThat = hamjest.promiseThat;
var allOf = hamjest.allOf;
var contains = hamjest.contains;
var equalTo = hamjest.equalTo;
var hasProperties = hamjest.hasProperties;
var willBe = hamjest.willBe;
var FeatureMatcher = hamjest.FeatureMatcher;

var documentMatchers = require("./document-matchers");
var isEmptyRun = documentMatchers.isEmptyRun;
var isCheckbox = documentMatchers.isCheckbox;
var isHyperlink = documentMatchers.isHyperlink;
var isRun = documentMatchers.isRun;
var isText = documentMatchers.isText;
Expand Down Expand Up @@ -529,6 +531,41 @@ 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"})
])
]);

var paragraph = readXmlElementValue(paragraphXml);

assertThat(paragraph.children, contains(
isEmptyRun,
isEmptyRun,
isRun({
children: contains(
isCheckbox({checked: equalTo(false)})
)
})
));
}
});

test("run has no style if it has no properties", function() {
var runXml = runWithProperties([]);
var run = readXmlElementValue(runXml);
Expand Down
5 changes: 5 additions & 0 deletions test/docx/document-matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var documents = require("../../lib/documents");
exports.isEmptyRun = isRun({children: []});
exports.isRun = isRun;
exports.isText = isText;
exports.isCheckbox = isCheckbox;
exports.isHyperlink = isHyperlink;
exports.isTable = isTable;
exports.isRow = isRow;
Expand All @@ -20,6 +21,10 @@ function isText(text) {
return isDocumentElement(documents.types.text, {value: text});
}

function isCheckbox(properties) {
return isDocumentElement(documents.types.checkbox, properties);
}

function isHyperlink(properties) {
return isDocumentElement(documents.types.hyperlink, properties);
}
Expand Down

0 comments on commit 3751195

Please sign in to comment.