@sswroom/sswr 1.6.20 → 1.6.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Changelog CHANGED
@@ -1,3 +1,18 @@
1
+ 1.6.21
2
+ -Added data.dataURI2Blob
3
+ -Added EasyPrint.toSVG
4
+ -Added data.blob2DataURL
5
+ -Added data.fetchAsBlob
6
+ -Added text.isDataURL
7
+ -Added text.escapeXhtml
8
+ -Added text.svgStringToDataURI
9
+ -Added web.canvasToBlob
10
+ -Added web.elementToSVGString
11
+ -Added web.genPrintWindowHTML
12
+ -Added web.printImageData
13
+ -Added cesium.CesiumMap.getViewer
14
+ -parser support PNG without EXIF
15
+
1
16
  1.6.20
2
17
  -Enhance XLSXExporter
3
18
  -Added leaflet/EasyPrint.js
package/cesium.d.ts CHANGED
@@ -50,4 +50,5 @@ export class CesiumMap extends map.MapControl
50
50
  layerAddGeometry(geometryLayer: any, geom: any): void;
51
51
  layerRemoveGeometry(geometryLayer: any, geom: any): void;
52
52
  layerClearGeometries(geometryLayer: any): void;
53
+ getViewer(): Viewer;
53
54
  }
package/cesium.js CHANGED
@@ -497,4 +497,8 @@ export class CesiumMap extends map.MapControl
497
497
  layerAddGeometry(geometryLayer: any, geom: any): void;
498
498
  layerRemoveGeometry(geometryLayer: any, geom: any): void;
499
499
  layerClearGeometries(geometryLayer: any): void;*/
500
+ getViewer()
501
+ {
502
+ return this.viewer;
503
+ }
500
504
  }
package/data.d.ts CHANGED
@@ -39,6 +39,9 @@ export function shl32(v: number, n: number): number;
39
39
  export function sar32(v: number, n: number): number;
40
40
  export function shr32(v: number, n: number): number;
41
41
  export function objectParseTS(o: object, items: string[]): void;
42
+ export function dataURI2Blob(dataURI: string): Blob;
43
+ export function blob2DataURL(blob: Blob): Promise<string|null>;
44
+ export function fetchAsBlob(url: string, options?: {cacheBust: boolean; imagePlaceholder?: string}): Promise<Blob|null>;
42
45
 
43
46
  export class DateValue
44
47
  {
package/data.js CHANGED
@@ -1,3 +1,4 @@
1
+ import * as data from "./data.js";
1
2
  import * as text from "./text.js";
2
3
 
3
4
  export const Weekday = {
@@ -455,6 +456,98 @@ export function objectParseTS(o, items)
455
456
  }
456
457
  }
457
458
 
459
+ /**
460
+ * @param {string} dataURI
461
+ */
462
+ export function dataURI2Blob(dataURI)
463
+ {
464
+ let i = dataURI.indexOf(",");
465
+ let dsp = [dataURI.substring(0, i), dataURI.substring(i + 1)];
466
+ let types = dsp[0].split(':')[1].split(';');
467
+ let mimeString = types[0];
468
+ let ab;
469
+ if (types[1] == "base64")
470
+ {
471
+ let byteString = atob(dsp[1]);
472
+ ab = new ArrayBuffer(byteString.length);
473
+ let dw = new DataView(ab);
474
+ for(let i = 0; i < byteString.length; i++) {
475
+ dw.setUint8(i, byteString.charCodeAt(i));
476
+ }
477
+ }
478
+ else
479
+ {
480
+ let enc = new TextEncoder();
481
+ ab = enc.encode(dsp[1]);
482
+ }
483
+ return new Blob([ab], {type: mimeString});
484
+ }
485
+
486
+ /**
487
+ * @param {Blob} blob
488
+ */
489
+ export function blob2DataURL(blob)
490
+ {
491
+ return new Promise((resolve, reject) => {
492
+ let encoder = new FileReader();
493
+ encoder.onloadend = function () {
494
+ let content = encoder.result;
495
+ if (typeof content == 'string')
496
+ resolve(content);
497
+ else
498
+ {
499
+ console.error("Error in converting to dataURL", content);
500
+ resolve(null);
501
+ }
502
+ };
503
+ encoder.readAsDataURL(blob);
504
+ });
505
+ }
506
+
507
+ /**
508
+ * @param {string} url
509
+ * @param {{ cacheBust: boolean; imagePlaceholder: string; }} options
510
+ */
511
+ export async function fetchAsBlob(url, options)
512
+ {
513
+ let TIMEOUT = 30000;
514
+ if(options && options.cacheBust) {
515
+ // Cache bypass so we dont have CORS issues with cached images
516
+ // Source: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache
517
+ url += ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime();
518
+ }
519
+ let placeholder;
520
+ if(options && options.imagePlaceholder) {
521
+ if (text.isDataURL(options.imagePlaceholder))
522
+ {
523
+ placeholder = data.dataURI2Blob(options.imagePlaceholder);
524
+ }
525
+ }
526
+ try
527
+ {
528
+ let req = await fetch(url, {signal: AbortSignal.timeout(TIMEOUT)});
529
+ if (!req.ok)
530
+ {
531
+ if(placeholder) {
532
+ return placeholder;
533
+ } else {
534
+ console.error('Cannot fetch resource: ' + url + ', status: ' + req.status);
535
+ return null;
536
+ }
537
+ }
538
+ return await req.blob();
539
+ }
540
+ catch (error)
541
+ {
542
+ if(placeholder) {
543
+ return placeholder;
544
+ } else {
545
+ console.error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url, error);
546
+ return null;
547
+ }
548
+ }
549
+ }
550
+
458
551
  export class DateValue
459
552
  {
460
553
  constructor()
@@ -1,3 +1,5 @@
1
+ import * as data from "../data.js";
2
+ import * as text from "../text.js";
1
3
  import * as util from "./util.js";
2
4
  import * as inliner from "./inliner.js";
3
5
 
@@ -7,9 +9,9 @@ import * as inliner from "./inliner.js";
7
9
  * @returns {Promise<HTMLImageElement>}
8
10
  */
9
11
  async function inline(element, options) {
10
- if (util.isDataUrl(element.src)) return element;
11
- let data = await util.getAndEncode(element.src, options);
12
- let dataUrl = util.dataAsUrl(data, util.mimeType(element.src));
12
+ if (text.isDataURL(element.src)) return element;
13
+ let blob = await data.fetchAsBlob(element.src, options);
14
+ let dataUrl = await data.blob2DataURL(blob);
13
15
  return await new Promise(function (resolve, reject) {
14
16
  element.onload = () => {resolve(element);};
15
17
  element.onerror = reject;
@@ -1,3 +1,5 @@
1
+ import * as text from "../text.js";
2
+ import * as web from "../web.js";
1
3
  import * as util from "./util.js";
2
4
  import * as images from "./images.js";
3
5
  import * as fontFaces from "./fontFaces.js";
@@ -74,7 +76,7 @@ export async function toPng(node, options) {
74
76
  * */
75
77
  export async function toJpeg(node, options) {
76
78
  options = options || {};
77
- let canvas = await draw(node, options);
79
+ let canvas = await draw(node, options || {});
78
80
  return canvas.toDataURL('image/jpeg', options.quality || 1.0);
79
81
  }
80
82
 
@@ -84,7 +86,7 @@ export async function toJpeg(node, options) {
84
86
  * */
85
87
  export async function toBlob(node, options) {
86
88
  let canvas = await draw(node, options || {});
87
- return await util.canvasToBlob(canvas);
89
+ return await web.canvasToBlob(canvas);
88
90
  }
89
91
 
90
92
  /**
@@ -109,21 +111,27 @@ function copyOptions(options) {
109
111
 
110
112
  /**
111
113
  * @param {HTMLElement} domNode
112
- * @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options
114
+ * @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}} options
113
115
  */
114
116
  async function draw(domNode, options) {
115
117
  let svgUrl = await toSvg(domNode, options);
116
118
  let image = await util.makeImage(svgUrl);
117
- await util.delay(100)();
118
119
  let canvas = newCanvas(domNode, options);
119
120
  let ctx = canvas.getContext('2d');
120
- if (ctx) ctx.drawImage(image, 0, 0);
121
- return canvas;
121
+ return await new Promise((resolve, reject) => {
122
+ setTimeout(() => {
123
+ if (ctx)
124
+ {
125
+ ctx.drawImage(image, 0, 0);
126
+ }
127
+ resolve(canvas);
128
+ }, 1);
129
+ });
122
130
  }
123
131
 
124
132
  /**
125
133
  * @param {HTMLElement} domNode
126
- * @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options
134
+ * @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}} options
127
135
  */
128
136
  function newCanvas(domNode, options) {
129
137
  let canvas = document.createElement('canvas');
@@ -131,9 +139,10 @@ function newCanvas(domNode, options) {
131
139
  canvas.height = options.height || domNode.offsetHeight;
132
140
 
133
141
  if (options.bgcolor) {
134
- var ctx = canvas.getContext('2d');
142
+ let ctx = canvas.getContext('2d');
135
143
  if (ctx != null)
136
144
  {
145
+ ctx.globalAlpha = 1;
137
146
  ctx.fillStyle = options.bgcolor;
138
147
  ctx.fillRect(0, 0, canvas.width, canvas.height);
139
148
  }
@@ -320,9 +329,5 @@ async function inlineImages(node, implOptions) {
320
329
  * @param {string | number} height
321
330
  */
322
331
  function makeSvgDataUri(node, width, height) {
323
- node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
324
- let xhtml = util.escapeXhtml(new XMLSerializer().serializeToString(node));
325
- let foreignObject = '<foreignObject x="0" y="0" width="100%" height="100%">' + xhtml + '</foreignObject>';
326
- let svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '">' + foreignObject + '</svg>';
327
- return 'data:image/svg+xml;charset=utf-8,' + svg;
332
+ return text.svgStringToDataURI(web.elementToSVGString(node, width, height));
328
333
  }
@@ -1,3 +1,5 @@
1
+ import * as data from "../data.js";
2
+ import * as text from "../text.js";
1
3
  import * as util from "./util.js";
2
4
 
3
5
  let URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g;
@@ -19,7 +21,7 @@ function readUrls(string) {
19
21
  result.push(match[1]);
20
22
  }
21
23
  return result.filter(function (url) {
22
- return !util.isDataUrl(url);
24
+ return !text.isDataURL(url);
23
25
  });
24
26
  }
25
27
 
@@ -34,24 +36,24 @@ function urlAsRegex(url) {
34
36
  * @param {string} string
35
37
  * @param {string} url
36
38
  * @param {string | null | undefined} baseUrl
37
- * @param {((url: string)=>string)|undefined} get
39
+ * @param {((url: string)=>Blob)|undefined} get
38
40
  * @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} options
39
41
  */
40
42
  async function inline(string, url, baseUrl, get, options) {
41
43
  url = baseUrl ? util.resolveUrl(url, baseUrl) : url;
42
- let data;
44
+ let blob;
43
45
  if (get)
44
- data = get(url);
46
+ blob = get(url);
45
47
  else
46
- data = await util.getAndEncode(url, options);
47
- let dataUrl = util.dataAsUrl(data, util.mimeType(url));
48
+ blob = await data.fetchAsBlob(url, options);
49
+ let dataUrl = await data.blob2DataURL(blob);
48
50
  return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3');
49
51
  }
50
52
 
51
53
  /**
52
54
  * @param {string} string
53
55
  * @param {string | null | undefined} baseUrl
54
- * @param {((url: string)=>string)|undefined} get
56
+ * @param {((url: string)=>Blob)|undefined} get
55
57
  * @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} options
56
58
  */
57
59
  export async function inlineAll(string, baseUrl, get, options) {
@@ -41,44 +41,6 @@ export function mimeType(url) {
41
41
  return mimes()[extension] || '';
42
42
  }
43
43
 
44
- /**
45
- * @param {string} url
46
- */
47
- export function isDataUrl(url) {
48
- return url.search(/^(data:)/) !== -1;
49
- }
50
-
51
- /**
52
- * @param {HTMLCanvasElement} canvas
53
- */
54
- function toBlob(canvas) {
55
- let binaryString = window.atob(canvas.toDataURL().split(',')[1]);
56
- let length = binaryString.length;
57
- let binaryArray = new Uint8Array(length);
58
-
59
- for (let i = 0; i < length; i++)
60
- binaryArray[i] = binaryString.charCodeAt(i);
61
-
62
- return new Blob([binaryArray], {
63
- type: 'image/png'
64
- });
65
- }
66
-
67
- /**
68
- * @param {HTMLCanvasElement} canvas
69
- * @returns {Promise<Blob|null>}
70
- */
71
- export async function canvasToBlob(canvas) {
72
- if (canvas.toBlob)
73
- {
74
- return await new Promise(function (resolve) {
75
- canvas.toBlob(resolve);
76
- });
77
- }
78
-
79
- return toBlob(canvas);
80
- }
81
-
82
44
  /**
83
45
  * @param {string} url
84
46
  * @param {string} baseUrl
@@ -122,67 +84,6 @@ export function makeImage(uri) {
122
84
  });
123
85
  }
124
86
 
125
- /**
126
- * @param {string} url
127
- * @param {{ cacheBust: boolean; imagePlaceholder?: string} | undefined} options
128
- */
129
- export async function getAndEncode(url, options) {
130
- let TIMEOUT = 30000;
131
- if(options && options.cacheBust) {
132
- // Cache bypass so we dont have CORS issues with cached images
133
- // Source: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache
134
- url += ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime();
135
- }
136
- let placeholder;
137
- if(options && options.imagePlaceholder) {
138
- let split = options.imagePlaceholder.split(/,/);
139
- if(split && split[1]) {
140
- placeholder = split[1];
141
- }
142
- }
143
- try
144
- {
145
- let req = await fetch(url, {signal: AbortSignal.timeout(TIMEOUT)});
146
- /** @type {string} */
147
- if (!req.ok)
148
- {
149
- if(placeholder) {
150
- return placeholder;
151
- } else {
152
- console.error('cannot fetch resource: ' + url + ', status: ' + req.status);
153
- return "";
154
- }
155
- }
156
- let blob = await req.blob();
157
- return await new Promise((resolve, reject) => {
158
- let encoder = new FileReader();
159
- encoder.onloadend = function () {
160
- let content = encoder.result;
161
- if (typeof content == 'string') resolve(content.split(/,/)[1]);
162
- resolve(content);
163
- };
164
- encoder.readAsDataURL(blob);
165
- });
166
- }
167
- catch (error)
168
- {
169
- if(placeholder) {
170
- return placeholder;
171
- } else {
172
- console.error('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url, error);
173
- return "";
174
- }
175
- }
176
- }
177
-
178
- /**
179
- * @param {string} content
180
- * @param {string} type
181
- */
182
- export function dataAsUrl(content, type) {
183
- return 'data:' + type + ';base64,' + content;
184
- }
185
-
186
87
  /**
187
88
  * @param {string} string
188
89
  */
@@ -213,13 +114,6 @@ export function asArray(arrayLike) {
213
114
  return array;
214
115
  }
215
116
 
216
- /**
217
- * @param {string} string
218
- */
219
- export function escapeXhtml(string) {
220
- return string.replace(/#/g, '%23').replace(/\n/g, '%0A');
221
- }
222
-
223
117
  /**
224
118
  * @param {Element} node
225
119
  */
@@ -128,6 +128,7 @@ export class EasyPrint
128
128
  printMap(event, filename) {
129
129
  this.resolve = null;
130
130
  this.reject = null;
131
+ this.format = "PNG";
131
132
  if (filename) {
132
133
  this.options.filename = filename
133
134
  }
@@ -183,6 +184,7 @@ export class EasyPrint
183
184
  toPNG(size) {
184
185
  this.resolve = null;
185
186
  this.reject = null;
187
+ this.format = "PNG";
186
188
  this._sizeModeObjs();
187
189
  this.originalState = {
188
190
  mapWidth: this.mapContainer.style.width,
@@ -227,6 +229,58 @@ export class EasyPrint
227
229
  });
228
230
  }
229
231
 
232
+ /**
233
+ * @param {math.Coord2D} size
234
+ * @returns {Promise<Blob>}
235
+ */
236
+ toSVG(size) {
237
+ this.resolve = null;
238
+ this.reject = null;
239
+ this.format = "SVG";
240
+ this._sizeModeObjs();
241
+ this.originalState = {
242
+ mapWidth: this.mapContainer.style.width,
243
+ widthWasAuto: false,
244
+ widthWasPercentage: false,
245
+ mapHeight: this.mapContainer.style.height,
246
+ zoom: this._map.getZoom(),
247
+ center: this._map.getCenter()
248
+ };
249
+ if (this.originalState.mapWidth === 'auto') {
250
+ this.originalState.mapWidth = this._map.getSize().x + 'px'
251
+ this.originalState.widthWasAuto = true
252
+ } else if (this.originalState.mapWidth.includes('%')) {
253
+ this.originalState.percentageWidth = this.originalState.mapWidth
254
+ this.originalState.widthWasPercentage = true
255
+ this.originalState.mapWidth = this._map.getSize().x + 'px'
256
+ }
257
+ let plugin = this;
258
+ return new Promise((resolve, reject) => {
259
+ plugin.resolve = resolve;
260
+ plugin.reject = reject;
261
+ if (!plugin.options.hidden) {
262
+ plugin._togglePageSizeButtons({type: null});
263
+ }
264
+ if (plugin.options.hideControlContainer) {
265
+ plugin._toggleControls();
266
+ }
267
+ if (plugin.options.hideClasses) {
268
+ plugin._toggleClasses(plugin.options.hideClasses);
269
+ }
270
+ if (plugin.options.hideIds) {
271
+ plugin._toggleIds(plugin.options.hideIds);
272
+ }
273
+ if (size == null) {
274
+ return plugin._printOpertion('CurrentSize');
275
+ }
276
+ plugin.outerContainer = plugin._createOuterContainer(plugin.mapContainer)
277
+ if (plugin.originalState.widthWasAuto) {
278
+ plugin.outerContainer.style.width = plugin.originalState.mapWidth
279
+ }
280
+ plugin._createImagePlaceholder(size)
281
+ });
282
+ }
283
+
230
284
  /**
231
285
  * @param {string} name
232
286
  * @param {any} value
@@ -304,9 +358,9 @@ export class EasyPrint
304
358
  this.mapContainer.style.width = pageSize.width + 'px';
305
359
  this.mapContainer.style.height = (pageSize.height - pageBorderHeight) + 'px';
306
360
  if (pageSize.width < pageSize.height) {
307
- this.orientation = 'portrait';
361
+ this.orientation = web.PaperOrientation.Portrait;
308
362
  } else {
309
- this.orientation = 'landscape';
363
+ this.orientation = web.PaperOrientation.Landscape;
310
364
  }
311
365
  this.paperSize = pageSize.paperSize;
312
366
  this._map.setView(this.originalState.center);
@@ -362,14 +416,26 @@ export class EasyPrint
362
416
  if (this.originalState.widthWasAuto && sizemode === 'CurrentSize' || this.originalState.widthWasPercentage && sizemode === 'CurrentSize') {
363
417
  widthForExport = this.originalState.mapWidth
364
418
  }
365
- let dataUrl = await domtoimage.toPng(plugin.mapContainer, {
419
+ let dataUrl;
420
+ if (this.format == "SVG")
421
+ {
422
+ dataUrl = await domtoimage.toSvg(plugin.mapContainer, {
423
+ width: parseInt(widthForExport),
424
+ height: parseInt(plugin.mapContainer.style.height.replace('px')),
425
+ imagePlaceholder: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH6AMECQMVtyBSbwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAALSURBVAjXY2AAAgAABQAB4iYFmwAAAABJRU5ErkJggg=="
426
+ });
427
+ }
428
+ else
429
+ {
430
+ dataUrl = await domtoimage.toPng(plugin.mapContainer, {
366
431
  width: parseInt(widthForExport),
367
432
  height: parseInt(plugin.mapContainer.style.height.replace('px')),
368
433
  imagePlaceholder: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH6AMECQMVtyBSbwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAALSURBVAjXY2AAAgAABQAB4iYFmwAAAABJRU5ErkJggg=="
369
434
  });
435
+ }
370
436
  try
371
437
  {
372
- let blob = plugin._dataURItoBlob(dataUrl);
438
+ let blob = data.dataURI2Blob(dataUrl);
373
439
  if (plugin.resolve) {
374
440
  plugin.resolve(blob);
375
441
  } else if (plugin.options.exportOnly) {
@@ -431,12 +497,12 @@ export class EasyPrint
431
497
 
432
498
  /**
433
499
  * @param {string} img
434
- * @param {string} orientation
435
- * @param {any} paperSize
500
+ * @param {web.PaperOrientation} orientation
501
+ * @param {string | null} paperSize
436
502
  */
437
503
  _sendToBrowserPrint(img, orientation, paperSize) {
438
504
  this._page.resizeTo(600, 800);
439
- let pageContent = this._createNewWindow(img, orientation, this, paperSize)
505
+ let pageContent = web.genPrintWindowHTML(img, orientation, paperSize, this.options);
440
506
  this._page.document.body.innerHTML = ''
441
507
  this._page.document.write(pageContent);
442
508
  this._page.document.close();
@@ -523,50 +589,6 @@ export class EasyPrint
523
589
  <div class="`+spinnerClass+`">Loading...</div></body></html>`;
524
590
  }
525
591
 
526
- /**
527
- * @param {string} img
528
- * @param {string} orientation
529
- * @param {this} plugin
530
- * @param {string|null} paperSize
531
- */
532
- _createNewWindow(img, orientation, plugin, paperSize) {
533
- let strs = new Array();
534
- strs.push(`<html><head>
535
- <style>@media print {
536
- img { max-width: 98%!important; max-height: 98%!important; }
537
- @page { size: ` + (paperSize?paperSize:'')+' '+ orientation + `;}}
538
- </style>
539
- <script>function step1(){
540
- setTimeout('step2()', 10);}
541
- function step2(){window.print();window.close()}
542
- </script></head><body onload='step1()' style="margin: 0px;">`);
543
- if (plugin.options.pageBorderTopHTML || plugin.options.pageBorderBottomHTML)
544
- {
545
- strs.push("<table border=\"0\" width=\"100%\" height=\"100%\">");
546
- if (plugin.options.pageBorderTopHTML)
547
- {
548
- strs.push("<tr><td>"+plugin.options.pageBorderTopHTML+"</td></tr>");
549
- }
550
- strs.push(`<tr><td>`);
551
- if (plugin.options.overlayHTML)
552
- strs.push(plugin.options.overlayHTML);
553
- strs.push(`<img src="` + img + `" style="display:block; margin:auto;"></td></tr>`);
554
- if (plugin.options.pageBorderBottomHTML)
555
- {
556
- strs.push("<tr><td>"+plugin.options.pageBorderBottomHTML+"</td></tr>");
557
- }
558
- strs.push("</table>");
559
- }
560
- else
561
- {
562
- if (plugin.options.overlayHTML)
563
- strs.push(plugin.options.overlayHTML);
564
- strs.push(`<img src="` + img + `" style="display:block; margin:auto;">`);
565
- }
566
- strs.push(`</body></html>`);
567
- return strs.join("");
568
- }
569
-
570
592
  /**
571
593
  * @param {HTMLDivElement} mapDiv
572
594
  */
@@ -656,20 +678,6 @@ export class EasyPrint
656
678
  document.body.appendChild(css);
657
679
  }
658
680
 
659
- /**
660
- * @param {string} dataURI
661
- */
662
- _dataURItoBlob(dataURI) {
663
- let byteString = atob(dataURI.split(',')[1]);
664
- let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
665
- let ab = new ArrayBuffer(byteString.length);
666
- let dw = new DataView(ab);
667
- for(let i = 0; i < byteString.length; i++) {
668
- dw.setUint8(i, byteString.charCodeAt(i));
669
- }
670
- return new Blob([ab], {type: mimeString});
671
- }
672
-
673
681
  /**
674
682
  * @param {{ type: any; }} e
675
683
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sswroom/sswr",
3
- "version": "1.6.20",
3
+ "version": "1.6.21",
4
4
  "description": "Libraries made by sswroom",
5
5
  "main": "sswr.js",
6
6
  "scripts": {
package/parser.js CHANGED
@@ -980,6 +980,25 @@ async function parseJpg(reader, sourceName)
980
980
  return null;
981
981
  }
982
982
 
983
+ /**
984
+ * @param {data.ByteReader} reader
985
+ * @param {string} sourceName
986
+ */
987
+ async function parsePng(reader, sourceName)
988
+ {
989
+ if (!(reader instanceof data.ByteReader))
990
+ return null;
991
+ if (reader.getLength() < 20)
992
+ return null;
993
+ if (reader.readUInt32(0, false) != 0x89504e47 || reader.readUInt32(4, false) != 0x0d0a1a0a)
994
+ return null;
995
+ let buff = reader.getArrayBuffer();
996
+ let b = new Blob([buff], {type: "image/png"});
997
+ let img = await media.loadImageFromBlob(b);
998
+ let simg = new media.StaticImage(img, sourceName, "image/png");
999
+ return simg;
1000
+ }
1001
+
983
1002
  /**
984
1003
  * @param {data.ByteReader} reader
985
1004
  * @param {string} sourceName
@@ -1300,6 +1319,7 @@ export async function parseFile(file)
1300
1319
  {
1301
1320
  let view = new data.ByteReader(await file.arrayBuffer());
1302
1321
  let obj;
1322
+ if (obj = await parsePng(view, file.name)) return obj;
1303
1323
  if (obj = await parseJpg(view, file.name)) return obj;
1304
1324
  if (obj = await parseWebp(view, file.name)) return obj;
1305
1325
  if (obj = parseX509(view, file.name, t)) return obj;
package/text.d.ts CHANGED
@@ -56,6 +56,9 @@ export function replaceAll(s: string, replaceFrom: string, replaceTo: string): s
56
56
  export function getEncList(): TextBinEnc[];
57
57
  export function b64Enc(s: string, cs?: Base64Charset): string;
58
58
  export function b64Dec(b64Str: string): string;
59
+ export function isDataURL(url: string): boolean;
60
+ export function escapeXhtml(s: string): string;
61
+ export function svgStringToDataURI(svg: string): string;
59
62
 
60
63
  export class TextBinEnc
61
64
  {
package/text.js CHANGED
@@ -617,6 +617,30 @@ export function b64Dec(b64Str)
617
617
  return dec.decode(b64.decodeBin(b64Str));
618
618
  }
619
619
 
620
+ /**
621
+ * @param {string} url
622
+ */
623
+ export function isDataURL(url)
624
+ {
625
+ return url.startsWith("data:");
626
+ }
627
+
628
+ /**
629
+ * @param {string} s
630
+ */
631
+ export function escapeXhtml(s)
632
+ {
633
+ return s.replace(/#/g, '%23').replace(/\n/g, '%0A');
634
+ }
635
+
636
+ /**
637
+ * @param {string} svg
638
+ */
639
+ export function svgStringToDataURI(svg)
640
+ {
641
+ return 'data:image/svg+xml;charset=utf-8,' + svg;
642
+ }
643
+
620
644
  export class TextBinEnc
621
645
  {
622
646
  constructor(name)
package/web.d.ts CHANGED
@@ -12,6 +12,14 @@ declare class ImageInfo
12
12
  height: number;
13
13
  }
14
14
 
15
+ declare class PrintOptions
16
+ {
17
+ pageBorderTopHTML?: string;
18
+ pageBorderBottomHTML?: string;
19
+ overlayHTML?: string;
20
+ pageTitle?: string;
21
+ }
22
+
15
23
  export enum OSType
16
24
  {
17
25
  Unknown,
@@ -88,6 +96,12 @@ export enum BrowserType
88
96
  MiBrowser
89
97
  }
90
98
 
99
+ export enum PaperOrientation
100
+ {
101
+ Landscape,
102
+ Portrait
103
+ }
104
+
91
105
  declare class BrowserInfo
92
106
  {
93
107
  os: OSType;
@@ -118,6 +132,10 @@ export function getDivElement(id: string): HTMLDivElement;
118
132
  export function getSpanElement(id: string): HTMLSpanElement;
119
133
  export function getCanvasElement(id: string): HTMLCanvasElement;
120
134
  export function getImgElement(id: string): HTMLImageElement;
135
+ export function canvasToBlob(canvas: HTMLCanvasElement): Promise<Blob|null>;
136
+ export function elementToSVGString(node: Element, width: string | number, height: string | number): string;
137
+ export function genPrintWindowHTML(imgDataURL: string, orientation: PaperOrientation, paperSize?: string, options: PrintOptions): string;
138
+ export function printImageData(imgDataURL: string, orientation: PaperOrientation, paperSize?: string, options: PrintOptions): void;
121
139
  export function getBrowserInfo(): Promise<BrowserInfo>;
122
140
  export function parseUserAgent(userAgent: string): BrowserInfo;
123
141
 
package/web.js CHANGED
@@ -76,6 +76,11 @@ export const BrowserType = {
76
76
  MiBrowser: "MiBrowser"
77
77
  }
78
78
 
79
+ export const PaperOrientation = {
80
+ Landscape: "landscape",
81
+ Portrait: "portrait"
82
+ }
83
+
79
84
  export function getRequestURLBase()
80
85
  {
81
86
  let url = document.location.href;
@@ -1057,6 +1062,101 @@ export function getImgElement(id)
1057
1062
  throw new Error("Element with id \""+id+"\" is not an img");
1058
1063
  }
1059
1064
 
1065
+ /**
1066
+ * @param {HTMLCanvasElement} canvas
1067
+ * @returns {Promise<Blob|null>}
1068
+ */
1069
+ export async function canvasToBlob(canvas)
1070
+ {
1071
+ if (canvas.toBlob)
1072
+ {
1073
+ return await new Promise(function (resolve) {
1074
+ canvas.toBlob(resolve);
1075
+ });
1076
+ }
1077
+ return data.dataURI2Blob(canvas.toDataURL());
1078
+ }
1079
+
1080
+ /**
1081
+ * @param {Element} node
1082
+ * @param {string | number} width
1083
+ * @param {string | number} height
1084
+ */
1085
+ export function elementToSVGString(node, width, height)
1086
+ {
1087
+ node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
1088
+ let xhtml = text.escapeXhtml(new XMLSerializer().serializeToString(node));
1089
+ let foreignObject = '<foreignObject x="0" y="0" width="100%" height="100%">' + xhtml + '</foreignObject>';
1090
+ return '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '">' + foreignObject + '</svg>';
1091
+ }
1092
+
1093
+ /**
1094
+ * @param {string} imgDataURL
1095
+ * @param {string} orientation
1096
+ * @param {string | null | undefined} paperSize
1097
+ * @param {{ pageBorderTopHTML?: string; pageBorderBottomHTML?: string; overlayHTML?: string; pageTitle?: string; }} options
1098
+ */
1099
+ export function genPrintWindowHTML(imgDataURL, orientation, paperSize, options)
1100
+ {
1101
+ let strs = new Array();
1102
+ strs.push("<html><head>");
1103
+ if (options.pageTitle)
1104
+ {
1105
+ strs.push("<title>"+text.toHTMLText(options.pageTitle)+"</title>");
1106
+ }
1107
+ strs.push(`<style>@media print {
1108
+ img { max-width: 98%!important; max-height: 98%!important; }
1109
+ @page { size: ` + (paperSize?paperSize:'')+' '+ orientation + `;}}
1110
+ </style>
1111
+ <script>function step1(){
1112
+ setTimeout('step2()', 10);}
1113
+ function step2(){window.print();window.close()}
1114
+ </script></head><body onload='step1()' style="margin: 0px;">`);
1115
+ if (options.pageBorderTopHTML || options.pageBorderBottomHTML)
1116
+ {
1117
+ strs.push("<table border=\"0\" width=\"100%\" height=\"100%\">");
1118
+ if (options.pageBorderTopHTML)
1119
+ {
1120
+ strs.push("<tr><td>"+options.pageBorderTopHTML+"</td></tr>");
1121
+ }
1122
+ strs.push(`<tr><td>`);
1123
+ if (options.overlayHTML)
1124
+ strs.push(options.overlayHTML);
1125
+ strs.push(`<img src="` + imgDataURL + `" style="display:block; margin:auto;"></td></tr>`);
1126
+ if (options.pageBorderBottomHTML)
1127
+ {
1128
+ strs.push("<tr><td>"+options.pageBorderBottomHTML+"</td></tr>");
1129
+ }
1130
+ strs.push("</table>");
1131
+ }
1132
+ else
1133
+ {
1134
+ if (options.overlayHTML)
1135
+ strs.push(options.overlayHTML);
1136
+ strs.push(`<img src="` + imgDataURL + `" style="display:block; margin:auto;">`);
1137
+ }
1138
+ strs.push(`</body></html>`);
1139
+ return strs.join("");
1140
+ }
1141
+
1142
+ /**
1143
+ * @param {string} imgDataURL
1144
+ * @param {string} orientation
1145
+ * @param {string | null | undefined} paperSize
1146
+ * @param {{ pageBorderTopHTML?: string; pageBorderBottomHTML?: string; overlayHTML?: string }} options
1147
+ */
1148
+ export function printImageData(imgDataURL, orientation, paperSize, options)
1149
+ {
1150
+ let page = window.open("", "_blank", 'toolbar=no,status=no,menubar=no,scrollbars=no,resizable=no,left=10, top=10, width=600, height=800, visible=none');
1151
+ if (page == null)
1152
+ return false;
1153
+ let pageContent = genPrintWindowHTML(imgDataURL, orientation, paperSize, options);
1154
+ page.document.body.innerHTML = ''
1155
+ page.document.write(pageContent);
1156
+ page.document.close();
1157
+ return true;
1158
+ }
1159
+
1060
1160
  /**
1061
1161
  * @returns {Promise<{os: String,osVer?:string,browser: String,browserVer?: string,devName?:string}>}
1062
1162
  */