|
1 | 1 | import $ from 'jquery';
|
2 |
| -import {hideElem} from '../utils/dom.js'; |
| 2 | +import {GET} from '../modules/fetch.js'; |
| 3 | +import {hideElem, loadElem} from '../utils/dom.js'; |
| 4 | +import {parseDom} from '../utils.js'; |
3 | 5 |
|
4 |
| -function getDefaultSvgBoundsIfUndefined(svgXml, src) { |
| 6 | +function getDefaultSvgBoundsIfUndefined(text, src) { |
5 | 7 | const DefaultSize = 300;
|
6 | 8 | const MaxSize = 99999;
|
7 | 9 |
|
8 |
| - const svg = svgXml.documentElement; |
| 10 | + const svgDoc = parseDom(text, 'image/svg+xml'); |
| 11 | + const svg = svgDoc.documentElement; |
9 | 12 | const width = svg?.width?.baseVal;
|
10 | 13 | const height = svg?.height?.baseVal;
|
11 | 14 | if (width === undefined || height === undefined) {
|
@@ -65,74 +68,54 @@ export function initImageDiff() {
|
65 | 68 | };
|
66 | 69 | }
|
67 | 70 |
|
68 |
| - $('.image-diff:not([data-image-diff-loaded])').each(function() { |
| 71 | + $('.image-diff:not([data-image-diff-loaded])').each(async function() { |
69 | 72 | const $container = $(this);
|
70 | 73 | $container.attr('data-image-diff-loaded', 'true');
|
71 | 74 |
|
72 | 75 | // the container may be hidden by "viewed" checkbox, so use the parent's width for reference
|
73 | 76 | const diffContainerWidth = Math.max($container.closest('.diff-file-box').width() - 300, 100);
|
74 |
| - const pathAfter = $container.data('path-after'); |
75 |
| - const pathBefore = $container.data('path-before'); |
76 | 77 |
|
77 | 78 | const imageInfos = [{
|
78 |
| - loaded: false, |
79 |
| - path: pathAfter, |
80 |
| - $image: $container.find('img.image-after'), |
| 79 | + path: this.getAttribute('data-path-after'), |
| 80 | + mime: this.getAttribute('data-mime-after'), |
| 81 | + $images: $container.find('img.image-after'), // matches 3 <img> |
81 | 82 | $boundsInfo: $container.find('.bounds-info-after')
|
82 | 83 | }, {
|
83 |
| - loaded: false, |
84 |
| - path: pathBefore, |
85 |
| - $image: $container.find('img.image-before'), |
| 84 | + path: this.getAttribute('data-path-before'), |
| 85 | + mime: this.getAttribute('data-mime-before'), |
| 86 | + $images: $container.find('img.image-before'), // matches 3 <img> |
86 | 87 | $boundsInfo: $container.find('.bounds-info-before')
|
87 | 88 | }];
|
88 | 89 |
|
89 |
| - for (const info of imageInfos) { |
90 |
| - if (info.$image.length > 0) { |
91 |
| - $.ajax({ |
92 |
| - url: info.path, |
93 |
| - success: (data, _, jqXHR) => { |
94 |
| - info.$image.on('load', () => { |
95 |
| - info.loaded = true; |
96 |
| - setReadyIfLoaded(); |
97 |
| - }).on('error', () => { |
98 |
| - info.loaded = true; |
99 |
| - setReadyIfLoaded(); |
100 |
| - info.$boundsInfo.text('(image error)'); |
101 |
| - }); |
102 |
| - info.$image.attr('src', info.path); |
103 |
| - |
104 |
| - if (jqXHR.getResponseHeader('Content-Type') === 'image/svg+xml') { |
105 |
| - const bounds = getDefaultSvgBoundsIfUndefined(data, info.path); |
106 |
| - if (bounds) { |
107 |
| - info.$image.attr('width', bounds.width); |
108 |
| - info.$image.attr('height', bounds.height); |
109 |
| - hideElem(info.$boundsInfo); |
110 |
| - } |
111 |
| - } |
112 |
| - } |
113 |
| - }); |
114 |
| - } else { |
115 |
| - info.loaded = true; |
116 |
| - setReadyIfLoaded(); |
117 |
| - } |
118 |
| - } |
119 |
| - |
120 |
| - function setReadyIfLoaded() { |
121 |
| - if (imageInfos[0].loaded && imageInfos[1].loaded) { |
122 |
| - initViews(imageInfos[0].$image, imageInfos[1].$image); |
| 90 | + await Promise.all(imageInfos.map(async (info) => { |
| 91 | + const [success] = await Promise.all(Array.from(info.$images, (img) => { |
| 92 | + return loadElem(img, info.path); |
| 93 | + })); |
| 94 | + // only the first images is associated with $boundsInfo |
| 95 | + if (!success) info.$boundsInfo.text('(image error)'); |
| 96 | + if (info.mime === 'image/svg+xml') { |
| 97 | + const resp = await GET(info.path); |
| 98 | + const text = await resp.text(); |
| 99 | + const bounds = getDefaultSvgBoundsIfUndefined(text, info.path); |
| 100 | + if (bounds) { |
| 101 | + info.$images.attr('width', bounds.width); |
| 102 | + info.$images.attr('height', bounds.height); |
| 103 | + hideElem(info.$boundsInfo); |
| 104 | + } |
123 | 105 | }
|
124 |
| - } |
| 106 | + })); |
125 | 107 |
|
126 |
| - function initViews($imageAfter, $imageBefore) { |
127 |
| - initSideBySide(createContext($imageAfter[0], $imageBefore[0])); |
128 |
| - if ($imageAfter.length > 0 && $imageBefore.length > 0) { |
129 |
| - initSwipe(createContext($imageAfter[1], $imageBefore[1])); |
130 |
| - initOverlay(createContext($imageAfter[2], $imageBefore[2])); |
131 |
| - } |
| 108 | + const $imagesAfter = imageInfos[0].$images; |
| 109 | + const $imagesBefore = imageInfos[1].$images; |
132 | 110 |
|
133 |
| - $container.find('> .image-diff-tabs').removeClass('is-loading'); |
| 111 | + initSideBySide(createContext($imagesAfter[0], $imagesBefore[0])); |
| 112 | + if ($imagesAfter.length > 0 && $imagesBefore.length > 0) { |
| 113 | + initSwipe(createContext($imagesAfter[1], $imagesBefore[1])); |
| 114 | + initOverlay(createContext($imagesAfter[2], $imagesBefore[2])); |
134 | 115 | }
|
135 | 116 |
|
| 117 | + $container.find('> .image-diff-tabs').removeClass('is-loading'); |
| 118 | + |
136 | 119 | function initSideBySide(sizes) {
|
137 | 120 | let factor = 1;
|
138 | 121 | if (sizes.max.width > (diffContainerWidth - 24) / 2) {
|
|
0 commit comments