//----------------------------------------------------------
// Copyright (C) Microsoft Corporation. All rights reserved.
// Released under the Microsoft Office Extensible File License
// https://raw.github.com/stephen-hardy/docx.js/master/LICENSE.txt
//----------------------------------------------------------
function convertContent(input) { 'use strict'; // Convert HTML to WordprocessingML, and vice versa
var output, inputDoc, i, j, k, id, doc, inNode, inNodeChild, outNode, outNodeChild, styleAttrNode, pCount = 0, tempStr, tempNode, val;
function newXMLnode(name, text) {
var el = doc.createElement('w:' + name);
if (text) { el.appendChild(doc.createTextNode(text)); }
return el;
}
function newHTMLnode(name, html) {
var el = document.createElement(name);
el.innerHTML = html || '';
return el;
}
function color(str) { // Return hex or named color
if (str.charAt(0) === '#') { return str.substr(1); }
if (str.indexOf('rgb') < 0) { return str; }
var values = /rgb\((\d+), (\d+), (\d+)\)/.exec(str), red = +values[1], green = +values[2], blue = +values[3];
return (blue | (green << 8) | (red << 16)).toString(16);
}
function toXML(str) { return new DOMParser().parseFromString(str.replace(/<[a-zA-Z]*?:/g, '<').replace(/<\/[a-zA-Z]*?:/g, ''), 'text/xml').firstChild; }
if (input.files) { // input is file object
inputDoc = toXML(input.files['word/document.xml'].data).getElementsByTagName('body')[0]; output = newHTMLnode('DIV');
for (i = 0; inNode = inputDoc.childNodes[i]; i++) {
j = inNode.childNodes.length;
outNode = output.appendChild(newHTMLnode('P'));
tempStr = '';
for (j = 0; inNodeChild = inNode.childNodes[j]; j++) {
if (inNodeChild.nodeName === 'pPr') {
if (styleAttrNode = inNodeChild.getElementsByTagName('jc')[0]) { outNode.style.textAlign = styleAttrNode.getAttribute('w:val'); }
}
if (inNodeChild.nodeName === 'r') {
val = inNodeChild.textContent;
if (inNodeChild.getElementsByTagName('b').length) { val = '' + val + ''; }
if (inNodeChild.getElementsByTagName('i').length) { val = '' + val + ''; }
if (inNodeChild.getElementsByTagName('u').length) { val = '' + val + ''; }
if (inNodeChild.getElementsByTagName('strike').length) { val = '' + val + ''; }
if (styleAttrNode = inNodeChild.getElementsByTagName('vertAlign')[0]) {
if (styleAttrNode.getAttribute('w:val') === 'subscript') { val = '' + val + ''; }
if (styleAttrNode.getAttribute('w:val') === 'superscript') { val = '' + val + ''; }
}
if (styleAttrNode = inNodeChild.getElementsByTagName('sz')[0]) { val = '' + val + ''; }
if (styleAttrNode = inNodeChild.getElementsByTagName('highlight')[0]) { val = '' + val + ''; }
if (styleAttrNode = inNodeChild.getElementsByTagName('color')[0]) { val = '' + val + ''; }
if (styleAttrNode = inNodeChild.getElementsByTagName('blip')[0]) {
id = styleAttrNode.getAttribute('r:embed');
tempNode = toXML(input.files['word/_rels/document.xml.rels'].data);
k = tempNode.childNodes.length;
while (k--) {
if (tempNode.childNodes[k].getAttribute('Id') === id) {
val = '';
break;
}
}
}
tempStr += val;
}
outNode.innerHTML = tempStr;
}
}
output = output.childNodes;
}
else if (input.nodeName) { // input is HTML DOM
doc = new DOMParser().parseFromString('', 'text/xml')
doc.getElementsByTagName('root')[0].appendChild(newXMLnode('body'));
output = doc.getElementsByTagName('w:body')[0];
for (i = 0; inNode = input.childNodes[i]; i++) {
outNode = output.appendChild(newXMLnode('p'));
pCount++;
if (inNode.style.textAlign) { outNode.appendChild(newXMLnode('pPr')).appendChild(newXMLnode('jc')).setAttribute('val', inNode.style.textAlign); }
if (inNode.nodeName === '#text') { outNode.appendChild(newXMLnode('r')).appendChild(newXMLnode('t', inNode.nodeValue)); }
else {
for (j = 0; inNodeChild = inNode.childNodes[j]; j++) {
outNodeChild = outNode.appendChild(newXMLnode('r'));
if (inNodeChild.nodeName !== '#text') {
styleAttrNode = outNodeChild.appendChild(newXMLnode('rPr'));
tempStr = inNodeChild.outerHTML;
if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('b')); }
if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('i')); }
if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('u')).setAttribute('val', 'single'); }
if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('strike')); }
if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('vertAlign')).setAttribute('val', 'subscript'); }
if (tempStr.indexOf('') > -1) { styleAttrNode.appendChild(newXMLnode('vertAlign')).setAttribute('val', 'superscript'); }
if (tempNode = inNodeChild.nodeName === 'SPAN' ? inNodeChild : inNodeChild.getElementsByTagName('SPAN')[0]) {
if (tempNode.style.fontSize) { styleAttrNode.appendChild(newXMLnode('sz')).setAttribute('val', parseInt(tempNode.style.fontSize, 10) * 2); }
else if (tempNode.style.backgroundColor) { styleAttrNode.appendChild(newXMLnode('highlight')).setAttribute('val', color(tempNode.style.backgroundColor)); }
else if (tempNode.style.color) { styleAttrNode.appendChild(newXMLnode('color')).setAttribute('val', color(tempNode.style.color)); }
}
}
outNodeChild.appendChild(newXMLnode('t', inNodeChild.textContent));
}
}
}
output = {
string: new XMLSerializer().serializeToString(output).replace(//g, '').replace(/val=/g, 'w:val='),
charSpaceCount: input.textContent.length, charCount: input.textContent.replace(/\s/g, '').length, pCount: pCount
};
}
return output;
}
function docx(file) { 'use strict'; // v1.0.1
var result, zip = new JSZip(), zipTime, processTime, docProps, word, content;
if (typeof file === 'string') { // Load
zipTime = Date.now();
zip = zip.load(file, { base64: true });
result = { zipTime: Date.now() - zipTime };
processTime = Date.now();
//{ Get file info from "docProps/core.xml"
s = zip.files['docProps/core.xml'].data;
s = s.substr(s.indexOf('') + 12);
result.creator = s.substring(0, s.indexOf(''));
s = s.substr(s.indexOf('') + 19);
result.lastModifiedBy = s.substring(0, s.indexOf(''));
s = s.substr(s.indexOf('') + 43);
result.created = new Date(s.substring(0, s.indexOf('')));
s = s.substr(s.indexOf('') + 44);
result.modified = new Date(s.substring(0, s.indexOf('')));
//}
result.DOM = convertContent(zip);
result.processTime = Date.now() - processTime;
}
else { // Save
content = convertContent(file.DOM);
processTime = Date.now();
sharedStrings = [[], 0];
//{ Fully static
zip.file('[Content_Types].xml', '');
zip.folder('_rels').file('.rels', '');
docProps = zip.folder('docProps');
word = zip.folder('word');
word.folder('_rels').file('document.xml.rels', '');
word.folder('theme').file('theme1.xml', '');
word.file('fontTable.xml', '');
word.file('settings.xml', '');
word.file('styles.xml', '');
word.file('stylesWithEffects.xml', '');
word.file('webSettings.xml', '');
//}
//{ Not content dependent
docProps.file('core.xml', ''
+ (file.creator || 'DOCX.js') + '' + (file.lastModifiedBy || 'XLSX.js') + '1'
+ (file.created || new Date()).toISOString() + '' + (file.modified || new Date()).toISOString() + '');
//}
//{ Content dependent
//{ docProps/app.xml
docProps.file('app.xml', 'Normal.dotm111'
+ content.charCount + 'DOCX.js01'
+ content.pCount + 'falseMicrosoft Corporationfalse'
+ content.charSpaceCount + 'falsefalse1.0');
//}
word.file('document.xml', ''
+ content.string + '');
//}
processTime = Date.now() - processTime;
zipTime = Date.now();
result = {
base64: zip.generate({ compression: 'DEFLATE' }), zipTime: Date.now() - zipTime, processTime: processTime,
href: function() { return 'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,' + this.base64; }
}
}
return result;
}