diff --git a/public/resume-5.html b/public/resume-5.html
index bb0c50a..f694daa 100644
--- a/public/resume-5.html
+++ b/public/resume-5.html
@@ -1034,37 +1034,32 @@
photoReady = Promise.resolve(null);
}
- function flattenColors(el) {
- var s = getComputedStyle(el);
- var props = ['color','background-color','border-color','border-top-color','border-bottom-color','border-left-color','border-right-color','box-shadow','background'];
- var originals = {};
- props.forEach(function(p) {
- var v = s.getPropertyValue(p);
- if (v && v.indexOf('color-mix') !== -1) {
- originals[p] = el.style.getPropertyValue(p);
- el.style.setProperty(p, v);
+ function cloneAndInlineStyles(original) {
+ var clone = original.cloneNode(true);
+ var origEls = original.querySelectorAll('*');
+ var cloneEls = clone.querySelectorAll('*');
+ var allProps = ['color','background-color','background','border-color','border-top-color','border-bottom-color','border-left-color','border-right-color','box-shadow','opacity','font-family','font-size','font-weight','line-height','letter-spacing','text-align','text-decoration','text-transform','padding','padding-top','padding-bottom','padding-left','padding-right','margin','margin-top','margin-bottom','margin-left','margin-right','display','flex-direction','align-items','justify-content','gap','grid-template-columns','grid-column','width','height','min-width','min-height','max-width','max-height','position','top','bottom','left','right','z-index','overflow','border-radius','border-width','border-style','white-space','list-style-type','object-fit'];
+ for (var i = 0; i < origEls.length && i < cloneEls.length; i++) {
+ var cs = getComputedStyle(origEls[i]);
+ for (var j = 0; j < allProps.length; j++) {
+ var v = cs.getPropertyValue(allProps[j]);
+ if (v) cloneEls[i].style.setProperty(allProps[j], v);
}
- });
- var children = el.children;
- for (var i = 0; i < children.length; i++) {
- flattenColors(children[i]);
}
- return originals;
- }
-
- function restoreColors(el, originals) {
- Object.keys(originals).forEach(function(p) {
- if (originals[p]) el.style.setProperty(p, originals[p]);
- else el.style.removeProperty(p);
- });
- var children = el.children;
- for (var i = 0; i < children.length; i++) {
- restoreColors(children[i], originals);
+ var origCs = getComputedStyle(original);
+ for (var j = 0; j < allProps.length; j++) {
+ var v = origCs.getPropertyValue(allProps[j]);
+ if (v) clone.style.setProperty(allProps[j], v);
}
+ var styles = clone.querySelectorAll('style');
+ for (var s = 0; s < styles.length; s++) styles[s].textContent = '';
+ var links = clone.querySelectorAll('link[rel="stylesheet"]');
+ for (var l = 0; l < links.length; l++) links[l].remove();
+ return clone;
}
photoReady.then(function (dataUrl) {
- console.log('[PDF] step 1: photo ready, dataUrl:', dataUrl ? 'yes (' + dataUrl.length + ' chars)' : 'null');
+ console.log('[PDF] step 1: photo ready');
if (dataUrl && photo) photo.setAttribute('src', dataUrl);
console.log('[PDF] step 2: waiting for fonts...');
return document.fonts ? document.fonts.ready : Promise.resolve();
@@ -1074,19 +1069,41 @@
return loadScript(CDN);
})
.then(function () {
- console.log('[PDF] step 4: html2pdf loaded, type:', typeof html2pdf);
- console.log('[PDF] step 4: flattening color-mix() values...');
- var snapshot = flattenColors(doc);
- console.log('[PDF] step 4: starting generation...');
+ console.log('[PDF] step 4: html2pdf loaded, generating...');
return html2pdf().from(doc).set({
margin: 10,
filename: 'Mamadaev_Resume.pdf',
image: { type: 'jpeg', quality: 0.95 },
- html2canvas: { scale: 2, useCORS: true, backgroundColor: '#fff' },
+ html2canvas: {
+ scale: 2,
+ useCORS: true,
+ backgroundColor: '#fff',
+ onclone: function (clonedDoc) {
+ console.log('[PDF] onclone: inlining styles...');
+ var clonedEl = clonedDoc.querySelector('.resume-doc');
+ if (!clonedEl) return;
+ var origEls = doc.querySelectorAll('*');
+ var cloneEls = clonedEl.querySelectorAll('*');
+ var props = ['color','background-color','background','border-color','border-top-color','border-bottom-color','border-left-color','border-right-color','box-shadow','opacity','font-family','font-size','font-weight','line-height','letter-spacing','text-align','text-decoration','text-transform','padding','padding-top','padding-bottom','padding-left','padding-right','margin','margin-top','margin-bottom','margin-left','margin-right','display','flex-direction','align-items','justify-content','gap','grid-template-columns','grid-column','width','height','min-width','min-height','max-width','max-height','position','top','bottom','left','right','z-index','overflow','border-radius','border-width','border-style','white-space','list-style-type','object-fit'];
+ for (var i = 0; i < origEls.length && i < cloneEls.length; i++) {
+ var cs = getComputedStyle(origEls[i]);
+ for (var j = 0; j < props.length; j++) {
+ var v = cs.getPropertyValue(props[j]);
+ if (v) cloneEls[i].style.setProperty(props[j], v);
+ }
+ }
+ var rootCs = getComputedStyle(doc);
+ for (var j = 0; j < props.length; j++) {
+ var v = rootCs.getPropertyValue(props[j]);
+ if (v) clonedEl.style.setProperty(props[j], v);
+ }
+ clonedDoc.querySelectorAll('style').forEach(function(s){ s.textContent = ''; });
+ clonedDoc.querySelectorAll('link[rel="stylesheet"]').forEach(function(l){ l.remove(); });
+ console.log('[PDF] onclone: styles inlined');
+ }
+ },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
- }).save().then(function() {
- restoreColors(doc, snapshot);
- });
+ }).save();
})
.then(function (result) {
console.log('[PDF] step 5: generation COMPLETE, result:', result);
diff --git a/src/pages/resume-5.html b/src/pages/resume-5.html
index f477d6c..189da70 100644
--- a/src/pages/resume-5.html
+++ b/src/pages/resume-5.html
@@ -903,37 +903,32 @@
photoReady = Promise.resolve(null);
}
- function flattenColors(el) {
- var s = getComputedStyle(el);
- var props = ['color','background-color','border-color','border-top-color','border-bottom-color','border-left-color','border-right-color','box-shadow','background'];
- var originals = {};
- props.forEach(function(p) {
- var v = s.getPropertyValue(p);
- if (v && v.indexOf('color-mix') !== -1) {
- originals[p] = el.style.getPropertyValue(p);
- el.style.setProperty(p, v);
+ function cloneAndInlineStyles(original) {
+ var clone = original.cloneNode(true);
+ var origEls = original.querySelectorAll('*');
+ var cloneEls = clone.querySelectorAll('*');
+ var allProps = ['color','background-color','background','border-color','border-top-color','border-bottom-color','border-left-color','border-right-color','box-shadow','opacity','font-family','font-size','font-weight','line-height','letter-spacing','text-align','text-decoration','text-transform','padding','padding-top','padding-bottom','padding-left','padding-right','margin','margin-top','margin-bottom','margin-left','margin-right','display','flex-direction','align-items','justify-content','gap','grid-template-columns','grid-column','width','height','min-width','min-height','max-width','max-height','position','top','bottom','left','right','z-index','overflow','border-radius','border-width','border-style','white-space','list-style-type','object-fit'];
+ for (var i = 0; i < origEls.length && i < cloneEls.length; i++) {
+ var cs = getComputedStyle(origEls[i]);
+ for (var j = 0; j < allProps.length; j++) {
+ var v = cs.getPropertyValue(allProps[j]);
+ if (v) cloneEls[i].style.setProperty(allProps[j], v);
}
- });
- var children = el.children;
- for (var i = 0; i < children.length; i++) {
- flattenColors(children[i]);
}
- return originals;
- }
-
- function restoreColors(el, originals) {
- Object.keys(originals).forEach(function(p) {
- if (originals[p]) el.style.setProperty(p, originals[p]);
- else el.style.removeProperty(p);
- });
- var children = el.children;
- for (var i = 0; i < children.length; i++) {
- restoreColors(children[i], originals);
+ var origCs = getComputedStyle(original);
+ for (var j = 0; j < allProps.length; j++) {
+ var v = origCs.getPropertyValue(allProps[j]);
+ if (v) clone.style.setProperty(allProps[j], v);
}
+ var styles = clone.querySelectorAll('style');
+ for (var s = 0; s < styles.length; s++) styles[s].textContent = '';
+ var links = clone.querySelectorAll('link[rel="stylesheet"]');
+ for (var l = 0; l < links.length; l++) links[l].remove();
+ return clone;
}
photoReady.then(function (dataUrl) {
- console.log('[PDF] step 1: photo ready, dataUrl:', dataUrl ? 'yes (' + dataUrl.length + ' chars)' : 'null');
+ console.log('[PDF] step 1: photo ready');
if (dataUrl && photo) photo.setAttribute('src', dataUrl);
console.log('[PDF] step 2: waiting for fonts...');
return document.fonts ? document.fonts.ready : Promise.resolve();
@@ -943,19 +938,41 @@
return loadScript(CDN);
})
.then(function () {
- console.log('[PDF] step 4: html2pdf loaded, type:', typeof html2pdf);
- console.log('[PDF] step 4: flattening color-mix() values...');
- var snapshot = flattenColors(doc);
- console.log('[PDF] step 4: starting generation...');
+ console.log('[PDF] step 4: html2pdf loaded, generating...');
return html2pdf().from(doc).set({
margin: 10,
filename: 'Mamadaev_Resume.pdf',
image: { type: 'jpeg', quality: 0.95 },
- html2canvas: { scale: 2, useCORS: true, backgroundColor: '#fff' },
+ html2canvas: {
+ scale: 2,
+ useCORS: true,
+ backgroundColor: '#fff',
+ onclone: function (clonedDoc) {
+ console.log('[PDF] onclone: inlining styles...');
+ var clonedEl = clonedDoc.querySelector('.resume-doc');
+ if (!clonedEl) return;
+ var origEls = doc.querySelectorAll('*');
+ var cloneEls = clonedEl.querySelectorAll('*');
+ var props = ['color','background-color','background','border-color','border-top-color','border-bottom-color','border-left-color','border-right-color','box-shadow','opacity','font-family','font-size','font-weight','line-height','letter-spacing','text-align','text-decoration','text-transform','padding','padding-top','padding-bottom','padding-left','padding-right','margin','margin-top','margin-bottom','margin-left','margin-right','display','flex-direction','align-items','justify-content','gap','grid-template-columns','grid-column','width','height','min-width','min-height','max-width','max-height','position','top','bottom','left','right','z-index','overflow','border-radius','border-width','border-style','white-space','list-style-type','object-fit'];
+ for (var i = 0; i < origEls.length && i < cloneEls.length; i++) {
+ var cs = getComputedStyle(origEls[i]);
+ for (var j = 0; j < props.length; j++) {
+ var v = cs.getPropertyValue(props[j]);
+ if (v) cloneEls[i].style.setProperty(props[j], v);
+ }
+ }
+ var rootCs = getComputedStyle(doc);
+ for (var j = 0; j < props.length; j++) {
+ var v = rootCs.getPropertyValue(props[j]);
+ if (v) clonedEl.style.setProperty(props[j], v);
+ }
+ clonedDoc.querySelectorAll('style').forEach(function(s){ s.textContent = ''; });
+ clonedDoc.querySelectorAll('link[rel="stylesheet"]').forEach(function(l){ l.remove(); });
+ console.log('[PDF] onclone: styles inlined');
+ }
+ },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
- }).save().then(function() {
- restoreColors(doc, snapshot);
- });
+ }).save();
})
.then(function (result) {
console.log('[PDF] step 5: generation COMPLETE, result:', result);