@capgo/capacitor-printer 7.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n PrintBase64Options,\n PrintFileOptions,\n PrintHtmlOptions,\n PrintOptions,\n PrintPdfOptions,\n PrinterPlugin,\n} from './definitions';\n\nexport class PrinterWeb extends WebPlugin implements PrinterPlugin {\n async printBase64(options: PrintBase64Options): Promise<void> {\n const { data, mimeType, name } = options;\n\n // Convert base64 to blob\n const byteCharacters = atob(data);\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n const byteArray = new Uint8Array(byteNumbers);\n const blob = new Blob([byteArray], { type: mimeType });\n\n // Create object URL and print\n const url = URL.createObjectURL(blob);\n await this.printFromUrl(url, name);\n URL.revokeObjectURL(url);\n }\n\n async printFile(options: PrintFileOptions): Promise<void> {\n const { path, name } = options;\n\n // On web, we can only print URLs that are accessible\n // This will work for file:// URLs in some browsers or HTTP(S) URLs\n await this.printFromUrl(path, name);\n }\n\n async printHtml(options: PrintHtmlOptions): Promise<void> {\n const { html, name } = options;\n\n // Create a blob URL from the HTML content\n const blob = new Blob([html], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n await this.printFromUrl(url, name);\n URL.revokeObjectURL(url);\n }\n\n async printPdf(options: PrintPdfOptions): Promise<void> {\n const { path, name } = options;\n\n // On web, print the PDF URL\n await this.printFromUrl(path, name);\n }\n\n async printWebView(options?: PrintOptions): Promise<void> {\n // Set document title for print job name\n const originalTitle = document.title;\n if (options?.name) {\n document.title = options.name;\n }\n\n // Trigger browser print dialog\n window.print();\n\n // Restore original title\n document.title = originalTitle;\n }\n\n async getPluginVersion(): Promise<{ version: string }> {\n return { version: '7.0.0' };\n }\n\n private async printFromUrl(url: string, name?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n // Create hidden iframe\n const iframe = document.createElement('iframe');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = 'none';\n\n // Set up load handler\n iframe.onload = () => {\n try {\n // Set document title if name provided\n if (name && iframe.contentDocument) {\n iframe.contentDocument.title = name;\n }\n\n // Small delay to ensure content is loaded\n setTimeout(() => {\n try {\n // Try to access the iframe's window\n const iframeWindow = iframe.contentWindow;\n if (!iframeWindow) {\n throw new Error('Cannot access iframe window');\n }\n\n // Print the iframe content\n iframeWindow.focus();\n iframeWindow.print();\n\n // Clean up after a delay\n setTimeout(() => {\n document.body.removeChild(iframe);\n resolve();\n }, 100);\n } catch (error) {\n document.body.removeChild(iframe);\n reject(error);\n }\n }, 100);\n } catch (error) {\n document.body.removeChild(iframe);\n reject(error);\n }\n };\n\n iframe.onerror = () => {\n document.body.removeChild(iframe);\n reject(new Error('Failed to load content for printing'));\n };\n\n // Add iframe to document and set source\n document.body.appendChild(iframe);\n iframe.src = url;\n });\n }\n}\n"]}
@@ -0,0 +1,120 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const Printer = core.registerPlugin('Printer', {
6
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.PrinterWeb()),
7
+ });
8
+
9
+ class PrinterWeb extends core.WebPlugin {
10
+ async printBase64(options) {
11
+ const { data, mimeType, name } = options;
12
+ // Convert base64 to blob
13
+ const byteCharacters = atob(data);
14
+ const byteNumbers = new Array(byteCharacters.length);
15
+ for (let i = 0; i < byteCharacters.length; i++) {
16
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
17
+ }
18
+ const byteArray = new Uint8Array(byteNumbers);
19
+ const blob = new Blob([byteArray], { type: mimeType });
20
+ // Create object URL and print
21
+ const url = URL.createObjectURL(blob);
22
+ await this.printFromUrl(url, name);
23
+ URL.revokeObjectURL(url);
24
+ }
25
+ async printFile(options) {
26
+ const { path, name } = options;
27
+ // On web, we can only print URLs that are accessible
28
+ // This will work for file:// URLs in some browsers or HTTP(S) URLs
29
+ await this.printFromUrl(path, name);
30
+ }
31
+ async printHtml(options) {
32
+ const { html, name } = options;
33
+ // Create a blob URL from the HTML content
34
+ const blob = new Blob([html], { type: 'text/html' });
35
+ const url = URL.createObjectURL(blob);
36
+ await this.printFromUrl(url, name);
37
+ URL.revokeObjectURL(url);
38
+ }
39
+ async printPdf(options) {
40
+ const { path, name } = options;
41
+ // On web, print the PDF URL
42
+ await this.printFromUrl(path, name);
43
+ }
44
+ async printWebView(options) {
45
+ // Set document title for print job name
46
+ const originalTitle = document.title;
47
+ if (options === null || options === void 0 ? void 0 : options.name) {
48
+ document.title = options.name;
49
+ }
50
+ // Trigger browser print dialog
51
+ window.print();
52
+ // Restore original title
53
+ document.title = originalTitle;
54
+ }
55
+ async getPluginVersion() {
56
+ return { version: '7.0.0' };
57
+ }
58
+ async printFromUrl(url, name) {
59
+ return new Promise((resolve, reject) => {
60
+ // Create hidden iframe
61
+ const iframe = document.createElement('iframe');
62
+ iframe.style.position = 'fixed';
63
+ iframe.style.right = '0';
64
+ iframe.style.bottom = '0';
65
+ iframe.style.width = '0';
66
+ iframe.style.height = '0';
67
+ iframe.style.border = 'none';
68
+ // Set up load handler
69
+ iframe.onload = () => {
70
+ try {
71
+ // Set document title if name provided
72
+ if (name && iframe.contentDocument) {
73
+ iframe.contentDocument.title = name;
74
+ }
75
+ // Small delay to ensure content is loaded
76
+ setTimeout(() => {
77
+ try {
78
+ // Try to access the iframe's window
79
+ const iframeWindow = iframe.contentWindow;
80
+ if (!iframeWindow) {
81
+ throw new Error('Cannot access iframe window');
82
+ }
83
+ // Print the iframe content
84
+ iframeWindow.focus();
85
+ iframeWindow.print();
86
+ // Clean up after a delay
87
+ setTimeout(() => {
88
+ document.body.removeChild(iframe);
89
+ resolve();
90
+ }, 100);
91
+ }
92
+ catch (error) {
93
+ document.body.removeChild(iframe);
94
+ reject(error);
95
+ }
96
+ }, 100);
97
+ }
98
+ catch (error) {
99
+ document.body.removeChild(iframe);
100
+ reject(error);
101
+ }
102
+ };
103
+ iframe.onerror = () => {
104
+ document.body.removeChild(iframe);
105
+ reject(new Error('Failed to load content for printing'));
106
+ };
107
+ // Add iframe to document and set source
108
+ document.body.appendChild(iframe);
109
+ iframe.src = url;
110
+ });
111
+ }
112
+ }
113
+
114
+ var web = /*#__PURE__*/Object.freeze({
115
+ __proto__: null,
116
+ PrinterWeb: PrinterWeb
117
+ });
118
+
119
+ exports.Printer = Printer;
120
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Printer = registerPlugin('Printer', {\n web: () => import('./web').then((m) => new m.PrinterWeb()),\n});\nexport * from './definitions';\nexport { Printer };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class PrinterWeb extends WebPlugin {\n async printBase64(options) {\n const { data, mimeType, name } = options;\n // Convert base64 to blob\n const byteCharacters = atob(data);\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n const byteArray = new Uint8Array(byteNumbers);\n const blob = new Blob([byteArray], { type: mimeType });\n // Create object URL and print\n const url = URL.createObjectURL(blob);\n await this.printFromUrl(url, name);\n URL.revokeObjectURL(url);\n }\n async printFile(options) {\n const { path, name } = options;\n // On web, we can only print URLs that are accessible\n // This will work for file:// URLs in some browsers or HTTP(S) URLs\n await this.printFromUrl(path, name);\n }\n async printHtml(options) {\n const { html, name } = options;\n // Create a blob URL from the HTML content\n const blob = new Blob([html], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n await this.printFromUrl(url, name);\n URL.revokeObjectURL(url);\n }\n async printPdf(options) {\n const { path, name } = options;\n // On web, print the PDF URL\n await this.printFromUrl(path, name);\n }\n async printWebView(options) {\n // Set document title for print job name\n const originalTitle = document.title;\n if (options === null || options === void 0 ? void 0 : options.name) {\n document.title = options.name;\n }\n // Trigger browser print dialog\n window.print();\n // Restore original title\n document.title = originalTitle;\n }\n async getPluginVersion() {\n return { version: '7.0.0' };\n }\n async printFromUrl(url, name) {\n return new Promise((resolve, reject) => {\n // Create hidden iframe\n const iframe = document.createElement('iframe');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = 'none';\n // Set up load handler\n iframe.onload = () => {\n try {\n // Set document title if name provided\n if (name && iframe.contentDocument) {\n iframe.contentDocument.title = name;\n }\n // Small delay to ensure content is loaded\n setTimeout(() => {\n try {\n // Try to access the iframe's window\n const iframeWindow = iframe.contentWindow;\n if (!iframeWindow) {\n throw new Error('Cannot access iframe window');\n }\n // Print the iframe content\n iframeWindow.focus();\n iframeWindow.print();\n // Clean up after a delay\n setTimeout(() => {\n document.body.removeChild(iframe);\n resolve();\n }, 100);\n }\n catch (error) {\n document.body.removeChild(iframe);\n reject(error);\n }\n }, 100);\n }\n catch (error) {\n document.body.removeChild(iframe);\n reject(error);\n }\n };\n iframe.onerror = () => {\n document.body.removeChild(iframe);\n reject(new Error('Failed to load content for printing'));\n };\n // Add iframe to document and set source\n document.body.appendChild(iframe);\n iframe.src = url;\n });\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
package/dist/plugin.js ADDED
@@ -0,0 +1,123 @@
1
+ var capacitorPrinter = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const Printer = core.registerPlugin('Printer', {
5
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.PrinterWeb()),
6
+ });
7
+
8
+ class PrinterWeb extends core.WebPlugin {
9
+ async printBase64(options) {
10
+ const { data, mimeType, name } = options;
11
+ // Convert base64 to blob
12
+ const byteCharacters = atob(data);
13
+ const byteNumbers = new Array(byteCharacters.length);
14
+ for (let i = 0; i < byteCharacters.length; i++) {
15
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
16
+ }
17
+ const byteArray = new Uint8Array(byteNumbers);
18
+ const blob = new Blob([byteArray], { type: mimeType });
19
+ // Create object URL and print
20
+ const url = URL.createObjectURL(blob);
21
+ await this.printFromUrl(url, name);
22
+ URL.revokeObjectURL(url);
23
+ }
24
+ async printFile(options) {
25
+ const { path, name } = options;
26
+ // On web, we can only print URLs that are accessible
27
+ // This will work for file:// URLs in some browsers or HTTP(S) URLs
28
+ await this.printFromUrl(path, name);
29
+ }
30
+ async printHtml(options) {
31
+ const { html, name } = options;
32
+ // Create a blob URL from the HTML content
33
+ const blob = new Blob([html], { type: 'text/html' });
34
+ const url = URL.createObjectURL(blob);
35
+ await this.printFromUrl(url, name);
36
+ URL.revokeObjectURL(url);
37
+ }
38
+ async printPdf(options) {
39
+ const { path, name } = options;
40
+ // On web, print the PDF URL
41
+ await this.printFromUrl(path, name);
42
+ }
43
+ async printWebView(options) {
44
+ // Set document title for print job name
45
+ const originalTitle = document.title;
46
+ if (options === null || options === void 0 ? void 0 : options.name) {
47
+ document.title = options.name;
48
+ }
49
+ // Trigger browser print dialog
50
+ window.print();
51
+ // Restore original title
52
+ document.title = originalTitle;
53
+ }
54
+ async getPluginVersion() {
55
+ return { version: '7.0.0' };
56
+ }
57
+ async printFromUrl(url, name) {
58
+ return new Promise((resolve, reject) => {
59
+ // Create hidden iframe
60
+ const iframe = document.createElement('iframe');
61
+ iframe.style.position = 'fixed';
62
+ iframe.style.right = '0';
63
+ iframe.style.bottom = '0';
64
+ iframe.style.width = '0';
65
+ iframe.style.height = '0';
66
+ iframe.style.border = 'none';
67
+ // Set up load handler
68
+ iframe.onload = () => {
69
+ try {
70
+ // Set document title if name provided
71
+ if (name && iframe.contentDocument) {
72
+ iframe.contentDocument.title = name;
73
+ }
74
+ // Small delay to ensure content is loaded
75
+ setTimeout(() => {
76
+ try {
77
+ // Try to access the iframe's window
78
+ const iframeWindow = iframe.contentWindow;
79
+ if (!iframeWindow) {
80
+ throw new Error('Cannot access iframe window');
81
+ }
82
+ // Print the iframe content
83
+ iframeWindow.focus();
84
+ iframeWindow.print();
85
+ // Clean up after a delay
86
+ setTimeout(() => {
87
+ document.body.removeChild(iframe);
88
+ resolve();
89
+ }, 100);
90
+ }
91
+ catch (error) {
92
+ document.body.removeChild(iframe);
93
+ reject(error);
94
+ }
95
+ }, 100);
96
+ }
97
+ catch (error) {
98
+ document.body.removeChild(iframe);
99
+ reject(error);
100
+ }
101
+ };
102
+ iframe.onerror = () => {
103
+ document.body.removeChild(iframe);
104
+ reject(new Error('Failed to load content for printing'));
105
+ };
106
+ // Add iframe to document and set source
107
+ document.body.appendChild(iframe);
108
+ iframe.src = url;
109
+ });
110
+ }
111
+ }
112
+
113
+ var web = /*#__PURE__*/Object.freeze({
114
+ __proto__: null,
115
+ PrinterWeb: PrinterWeb
116
+ });
117
+
118
+ exports.Printer = Printer;
119
+
120
+ return exports;
121
+
122
+ })({}, capacitorExports);
123
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Printer = registerPlugin('Printer', {\n web: () => import('./web').then((m) => new m.PrinterWeb()),\n});\nexport * from './definitions';\nexport { Printer };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class PrinterWeb extends WebPlugin {\n async printBase64(options) {\n const { data, mimeType, name } = options;\n // Convert base64 to blob\n const byteCharacters = atob(data);\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n const byteArray = new Uint8Array(byteNumbers);\n const blob = new Blob([byteArray], { type: mimeType });\n // Create object URL and print\n const url = URL.createObjectURL(blob);\n await this.printFromUrl(url, name);\n URL.revokeObjectURL(url);\n }\n async printFile(options) {\n const { path, name } = options;\n // On web, we can only print URLs that are accessible\n // This will work for file:// URLs in some browsers or HTTP(S) URLs\n await this.printFromUrl(path, name);\n }\n async printHtml(options) {\n const { html, name } = options;\n // Create a blob URL from the HTML content\n const blob = new Blob([html], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n await this.printFromUrl(url, name);\n URL.revokeObjectURL(url);\n }\n async printPdf(options) {\n const { path, name } = options;\n // On web, print the PDF URL\n await this.printFromUrl(path, name);\n }\n async printWebView(options) {\n // Set document title for print job name\n const originalTitle = document.title;\n if (options === null || options === void 0 ? void 0 : options.name) {\n document.title = options.name;\n }\n // Trigger browser print dialog\n window.print();\n // Restore original title\n document.title = originalTitle;\n }\n async getPluginVersion() {\n return { version: '7.0.0' };\n }\n async printFromUrl(url, name) {\n return new Promise((resolve, reject) => {\n // Create hidden iframe\n const iframe = document.createElement('iframe');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = 'none';\n // Set up load handler\n iframe.onload = () => {\n try {\n // Set document title if name provided\n if (name && iframe.contentDocument) {\n iframe.contentDocument.title = name;\n }\n // Small delay to ensure content is loaded\n setTimeout(() => {\n try {\n // Try to access the iframe's window\n const iframeWindow = iframe.contentWindow;\n if (!iframeWindow) {\n throw new Error('Cannot access iframe window');\n }\n // Print the iframe content\n iframeWindow.focus();\n iframeWindow.print();\n // Clean up after a delay\n setTimeout(() => {\n document.body.removeChild(iframe);\n resolve();\n }, 100);\n }\n catch (error) {\n document.body.removeChild(iframe);\n reject(error);\n }\n }, 100);\n }\n catch (error) {\n document.body.removeChild(iframe);\n reject(error);\n }\n };\n iframe.onerror = () => {\n document.body.removeChild(iframe);\n reject(new Error('Failed to load content for printing'));\n };\n // Add iframe to document and set source\n document.body.appendChild(iframe);\n iframe.src = url;\n });\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
@@ -0,0 +1,207 @@
1
+ import Foundation
2
+ import UIKit
3
+ import WebKit
4
+
5
+ @objc public class Printer: NSObject {
6
+
7
+ enum PrinterError: Error {
8
+ case invalidBase64Data
9
+ case fileNotFound
10
+ case unsupportedMimeType
11
+ case printingNotAvailable
12
+ case invalidData
13
+ }
14
+
15
+ /// Print base64 encoded data
16
+ public func printBase64(
17
+ data: String,
18
+ mimeType: String,
19
+ name: String,
20
+ presentingViewController: UIViewController?
21
+ ) throws {
22
+ // Decode base64 data
23
+ guard let decodedData = Data(base64Encoded: data) else {
24
+ throw PrinterError.invalidBase64Data
25
+ }
26
+
27
+ // Create printable item based on MIME type
28
+ let printInfo = UIPrintInfo(dictionary: nil)
29
+ printInfo.jobName = name
30
+ printInfo.outputType = .general
31
+
32
+ var printFormatter: UIPrintFormatter?
33
+ var printItem: Any?
34
+
35
+ switch mimeType.lowercased() {
36
+ case "application/pdf":
37
+ printInfo.outputType = .general
38
+ printItem = decodedData
39
+
40
+ case "image/jpeg", "image/jpg", "image/png", "image/gif", "image/heic", "image/heif":
41
+ printInfo.outputType = .photo
42
+ if let image = UIImage(data: decodedData) {
43
+ printItem = image
44
+ } else {
45
+ throw PrinterError.invalidData
46
+ }
47
+
48
+ default:
49
+ throw PrinterError.unsupportedMimeType
50
+ }
51
+
52
+ try presentPrintController(
53
+ printInfo: printInfo,
54
+ printFormatter: printFormatter,
55
+ printItem: printItem,
56
+ presentingViewController: presentingViewController
57
+ )
58
+ }
59
+
60
+ /// Print file from path
61
+ public func printFile(
62
+ path: String,
63
+ name: String,
64
+ presentingViewController: UIViewController?
65
+ ) throws {
66
+ // Convert path to URL
67
+ var fileURL: URL
68
+
69
+ if path.hasPrefix("file://") {
70
+ fileURL = URL(fileURLWithPath: String(path.dropFirst(7)))
71
+ } else {
72
+ fileURL = URL(fileURLWithPath: path)
73
+ }
74
+
75
+ // Check if file exists
76
+ guard FileManager.default.fileExists(atPath: fileURL.path) else {
77
+ throw PrinterError.fileNotFound
78
+ }
79
+
80
+ let printInfo = UIPrintInfo(dictionary: nil)
81
+ printInfo.jobName = name
82
+ printInfo.outputType = .general
83
+
84
+ try presentPrintController(
85
+ printInfo: printInfo,
86
+ printFormatter: nil,
87
+ printItem: fileURL,
88
+ presentingViewController: presentingViewController
89
+ )
90
+ }
91
+
92
+ /// Print HTML content
93
+ public func printHtml(
94
+ html: String,
95
+ name: String,
96
+ presentingViewController: UIViewController?
97
+ ) throws {
98
+ let printInfo = UIPrintInfo(dictionary: nil)
99
+ printInfo.jobName = name
100
+ printInfo.outputType = .general
101
+
102
+ // Create a UIMarkupTextPrintFormatter for HTML
103
+ let formatter = UIMarkupTextPrintFormatter(markupText: html)
104
+
105
+ try presentPrintController(
106
+ printInfo: printInfo,
107
+ printFormatter: formatter,
108
+ printItem: nil,
109
+ presentingViewController: presentingViewController
110
+ )
111
+ }
112
+
113
+ /// Print PDF file
114
+ public func printPdf(
115
+ path: String,
116
+ name: String,
117
+ presentingViewController: UIViewController?
118
+ ) throws {
119
+ // Convert path to URL
120
+ var fileURL: URL
121
+
122
+ if path.hasPrefix("file://") {
123
+ fileURL = URL(fileURLWithPath: String(path.dropFirst(7)))
124
+ } else {
125
+ fileURL = URL(fileURLWithPath: path)
126
+ }
127
+
128
+ // Check if file exists
129
+ guard FileManager.default.fileExists(atPath: fileURL.path) else {
130
+ throw PrinterError.fileNotFound
131
+ }
132
+
133
+ let printInfo = UIPrintInfo(dictionary: nil)
134
+ printInfo.jobName = name
135
+ printInfo.outputType = .general
136
+
137
+ try presentPrintController(
138
+ printInfo: printInfo,
139
+ printFormatter: nil,
140
+ printItem: fileURL,
141
+ presentingViewController: presentingViewController
142
+ )
143
+ }
144
+
145
+ /// Print web view content
146
+ public func printWebView(
147
+ webView: WKWebView,
148
+ name: String,
149
+ presentingViewController: UIViewController?
150
+ ) throws {
151
+ let printInfo = UIPrintInfo(dictionary: nil)
152
+ printInfo.jobName = name
153
+ printInfo.outputType = .general
154
+
155
+ let formatter = webView.viewPrintFormatter()
156
+
157
+ try presentPrintController(
158
+ printInfo: printInfo,
159
+ printFormatter: formatter,
160
+ printItem: nil,
161
+ presentingViewController: presentingViewController
162
+ )
163
+ }
164
+
165
+ // MARK: - Private Helper Methods
166
+
167
+ private func presentPrintController(
168
+ printInfo: UIPrintInfo,
169
+ printFormatter: UIPrintFormatter?,
170
+ printItem: Any?,
171
+ presentingViewController: UIViewController?
172
+ ) throws {
173
+ guard UIPrintInteractionController.isPrintingAvailable else {
174
+ throw PrinterError.printingNotAvailable
175
+ }
176
+
177
+ guard let viewController = presentingViewController else {
178
+ throw PrinterError.printingNotAvailable
179
+ }
180
+
181
+ let printController = UIPrintInteractionController.shared
182
+ printController.printInfo = printInfo
183
+
184
+ if let formatter = printFormatter {
185
+ printController.printFormatter = formatter
186
+ } else if let item = printItem {
187
+ printController.printingItem = item
188
+ }
189
+
190
+ // Present print controller
191
+ if UIDevice.current.userInterfaceIdiom == .pad {
192
+ // For iPad, present as popover
193
+ printController.present(
194
+ from: viewController.view.bounds,
195
+ in: viewController.view,
196
+ animated: true,
197
+ completionHandler: nil
198
+ )
199
+ } else {
200
+ // For iPhone, present modally
201
+ printController.present(
202
+ animated: true,
203
+ completionHandler: nil
204
+ )
205
+ }
206
+ }
207
+ }
@@ -0,0 +1,148 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc(PrinterPlugin)
5
+ public class PrinterPlugin: CAPPlugin, CAPBridgedPlugin {
6
+ private let pluginVersion: String = "7.0.0"
7
+ public let identifier = "PrinterPlugin"
8
+ public let jsName = "Printer"
9
+ public let pluginMethods: [CAPPluginMethod] = [
10
+ CAPPluginMethod(name: "printBase64", returnType: CAPPluginReturnPromise),
11
+ CAPPluginMethod(name: "printFile", returnType: CAPPluginReturnPromise),
12
+ CAPPluginMethod(name: "printHtml", returnType: CAPPluginReturnPromise),
13
+ CAPPluginMethod(name: "printPdf", returnType: CAPPluginReturnPromise),
14
+ CAPPluginMethod(name: "printWebView", returnType: CAPPluginReturnPromise),
15
+ CAPPluginMethod(name: "getPluginVersion", returnType: CAPPluginReturnPromise)
16
+ ]
17
+
18
+ private let implementation = Printer()
19
+
20
+ @objc func printBase64(_ call: CAPPluginCall) {
21
+ guard let data = call.getString("data") else {
22
+ call.reject("data is required")
23
+ return
24
+ }
25
+
26
+ guard let mimeType = call.getString("mimeType") else {
27
+ call.reject("mimeType is required")
28
+ return
29
+ }
30
+
31
+ let name = call.getString("name") ?? "Document"
32
+
33
+ DispatchQueue.main.async { [weak self] in
34
+ guard let self = self else { return }
35
+
36
+ do {
37
+ try self.implementation.printBase64(
38
+ data: data,
39
+ mimeType: mimeType,
40
+ name: name,
41
+ presentingViewController: self.bridge?.viewController
42
+ )
43
+ call.resolve()
44
+ } catch {
45
+ call.reject("Failed to print base64 data: \(error.localizedDescription)")
46
+ }
47
+ }
48
+ }
49
+
50
+ @objc func printFile(_ call: CAPPluginCall) {
51
+ guard let path = call.getString("path") else {
52
+ call.reject("path is required")
53
+ return
54
+ }
55
+
56
+ let name = call.getString("name") ?? "Document"
57
+
58
+ DispatchQueue.main.async { [weak self] in
59
+ guard let self = self else { return }
60
+
61
+ do {
62
+ try self.implementation.printFile(
63
+ path: path,
64
+ name: name,
65
+ presentingViewController: self.bridge?.viewController
66
+ )
67
+ call.resolve()
68
+ } catch {
69
+ call.reject("Failed to print file: \(error.localizedDescription)")
70
+ }
71
+ }
72
+ }
73
+
74
+ @objc func printHtml(_ call: CAPPluginCall) {
75
+ guard let html = call.getString("html") else {
76
+ call.reject("html is required")
77
+ return
78
+ }
79
+
80
+ let name = call.getString("name") ?? "Document"
81
+
82
+ DispatchQueue.main.async { [weak self] in
83
+ guard let self = self else { return }
84
+
85
+ do {
86
+ try self.implementation.printHtml(
87
+ html: html,
88
+ name: name,
89
+ presentingViewController: self.bridge?.viewController
90
+ )
91
+ call.resolve()
92
+ } catch {
93
+ call.reject("Failed to print HTML: \(error.localizedDescription)")
94
+ }
95
+ }
96
+ }
97
+
98
+ @objc func printPdf(_ call: CAPPluginCall) {
99
+ guard let path = call.getString("path") else {
100
+ call.reject("path is required")
101
+ return
102
+ }
103
+
104
+ let name = call.getString("name") ?? "Document"
105
+
106
+ DispatchQueue.main.async { [weak self] in
107
+ guard let self = self else { return }
108
+
109
+ do {
110
+ try self.implementation.printPdf(
111
+ path: path,
112
+ name: name,
113
+ presentingViewController: self.bridge?.viewController
114
+ )
115
+ call.resolve()
116
+ } catch {
117
+ call.reject("Failed to print PDF: \(error.localizedDescription)")
118
+ }
119
+ }
120
+ }
121
+
122
+ @objc func printWebView(_ call: CAPPluginCall) {
123
+ let name = call.getString("name") ?? "Document"
124
+
125
+ DispatchQueue.main.async { [weak self] in
126
+ guard let self = self else { return }
127
+ guard let webView = self.bridge?.webView else {
128
+ call.reject("WebView not available")
129
+ return
130
+ }
131
+
132
+ do {
133
+ try self.implementation.printWebView(
134
+ webView: webView,
135
+ name: name,
136
+ presentingViewController: self.bridge?.viewController
137
+ )
138
+ call.resolve()
139
+ } catch {
140
+ call.reject("Failed to print web view: \(error.localizedDescription)")
141
+ }
142
+ }
143
+ }
144
+
145
+ @objc func getPluginVersion(_ call: CAPPluginCall) {
146
+ call.resolve(["version": self.pluginVersion])
147
+ }
148
+ }
@@ -0,0 +1,10 @@
1
+ import XCTest
2
+ @testable import PrinterPlugin
3
+
4
+ class PrinterPluginTests: XCTestCase {
5
+ func testPrinter() {
6
+ // This is a basic test to ensure the plugin compiles
7
+ let implementation = Printer()
8
+ XCTAssertNotNil(implementation)
9
+ }
10
+ }