+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/webapp/resources/applib/js/app-support.js b/src/main/webapp/resources/applib/js/app-support.js
index 6e660ea..7e98ec5 100644
--- a/src/main/webapp/resources/applib/js/app-support.js
+++ b/src/main/webapp/resources/applib/js/app-support.js
@@ -208,6 +208,21 @@ class AppSupport {
static sleep(ms) {
return new Promise((r) => setTimeout(r, ms));
}
+
+ /**************************************************************************
+ * PDF파일 미리보기 창 열기
+ **************************************************************************/
+ static openPDF(blob, windowName){
+
+ var popup = window.open(
+ wctx.url("/webjars/applib/html/pdf.html")
+ ,windowName
+ ,'top=10, left=10'
+ );
+ popup.onload = () => {
+ popup.makePdfFromBlob(blob);
+ };
+ }
}
diff --git a/src/main/webapp/resources/applib/js/pdfobject.js b/src/main/webapp/resources/applib/js/pdfobject.js
new file mode 100644
index 0000000..f6738a8
--- /dev/null
+++ b/src/main/webapp/resources/applib/js/pdfobject.js
@@ -0,0 +1,341 @@
+/**
+ * PDFObject v2.2.12
+ * https://github.com/pipwerks/PDFObject
+ * @license
+ * Copyright (c) 2008-2023 Philip Hutchison
+ * MIT-style license: http://pipwerks.mit-license.org/
+ * UMD module pattern from https://github.com/umdjs/umd/blob/master/templates/returnExports.js
+ */
+
+(function (root, factory) {
+ if (typeof define === "function" && define.amd) {
+ // AMD. Register as an anonymous module.
+ define([], factory);
+ } else if (typeof module === "object" && module.exports) {
+ // Node. Does not work with strict CommonJS, but
+ // only CommonJS-like environments that support module.exports,
+ // like Node.
+ module.exports = factory();
+ } else {
+ // Browser globals (root is window)
+ root.PDFObject = factory();
+ }
+}(this, function () {
+
+ "use strict";
+
+ //PDFObject is designed for client-side (browsers), not server-side (node)
+ //Will choke on undefined navigator and window vars when run on server
+ //Return boolean false and exit function when running server-side
+
+ if( typeof window === "undefined" ||
+ window.navigator === undefined ||
+ window.navigator.userAgent === undefined ||
+ window.navigator.mimeTypes === undefined){
+ return false;
+ }
+
+ let pdfobjectversion = "2.2.12";
+ let nav = window.navigator;
+ let ua = window.navigator.userAgent;
+
+ //Time to jump through hoops -- browser vendors do not make it easy to detect PDF support.
+
+ /*
+ IE11 still uses ActiveX for Adobe Reader, but IE 11 doesn't expose window.ActiveXObject the same way
+ previous versions of IE did. window.ActiveXObject will evaluate to false in IE 11, but "ActiveXObject"
+ in window evaluates to true.
+
+ MS Edge does not support ActiveX so this test will evaluate false
+ */
+ let isIE = ("ActiveXObject" in window);
+
+ /*
+ There is a coincidental correlation between implementation of window.promises and native PDF support in desktop browsers
+ We use this to assume if the browser supports promises it supports embedded PDFs
+ Is this fragile? Sort of. But browser vendors removed mimetype detection, so we're left to improvise
+ */
+ let isModernBrowser = (window.Promise !== undefined);
+
+ //Older browsers still expose the mimeType
+ let supportsPdfMimeType = (nav.mimeTypes["application/pdf"] !== undefined);
+
+ //Safari on iPadOS doesn't report as 'mobile' when requesting desktop site, yet still fails to embed PDFs
+ let isSafariIOSDesktopMode = ( nav.platform !== undefined &&
+ nav.platform === "MacIntel" &&
+ nav.maxTouchPoints !== undefined &&
+ nav.maxTouchPoints > 1 );
+
+ //Quick test for mobile devices.
+ let isMobileDevice = (isSafariIOSDesktopMode || /Mobi|Tablet|Android|iPad|iPhone/.test(ua));
+
+ //Safari desktop requires special handling
+ let isSafariDesktop = ( !isMobileDevice &&
+ nav.vendor !== undefined &&
+ /Apple/.test(nav.vendor) &&
+ /Safari/.test(ua) );
+
+ //Firefox started shipping PDF.js in Firefox 19. If this is Firefox 19 or greater, assume PDF.js is available
+ let isFirefoxWithPDFJS = (!isMobileDevice && /irefox/.test(ua) && ua.split("rv:").length > 1) ? (parseInt(ua.split("rv:")[1].split(".")[0], 10) > 18) : false;
+
+
+ /* ----------------------------------------------------
+ Supporting functions
+ ---------------------------------------------------- */
+
+ let createAXO = function (type){
+ var ax;
+ try {
+ ax = new ActiveXObject(type);
+ } catch (e) {
+ ax = null; //ensure ax remains null
+ }
+ return ax;
+ };
+
+ //If either ActiveX support for "AcroPDF.PDF" or "PDF.PdfCtrl" are found, return true
+ //Constructed as a method (not a prop) to avoid unneccesarry overhead -- will only be evaluated if needed
+ let supportsPdfActiveX = function (){ return !!(createAXO("AcroPDF.PDF") || createAXO("PDF.PdfCtrl")); };
+
+ //Determines whether PDF support is available
+ let supportsPDFs = (
+ //As of Sept 2020 no mobile browsers properly support PDF embeds
+ !isMobileDevice && (
+ //We're moving into the age of MIME-less browsers. They mostly all support PDF rendering without plugins.
+ isModernBrowser ||
+ //Modern versions of Firefox come bundled with PDFJS
+ isFirefoxWithPDFJS ||
+ //Browsers that still support the original MIME type check
+ supportsPdfMimeType ||
+ //Pity the poor souls still using IE
+ (isIE && supportsPdfActiveX())
+ )
+ );
+
+ //Create a fragment identifier for using PDF Open parameters when embedding PDF
+ let buildURLFragmentString = function(pdfParams){
+
+ let string = "";
+ let prop;
+
+ if(pdfParams){
+
+ for (prop in pdfParams) {
+ if (pdfParams.hasOwnProperty(prop)) {
+ string += encodeURIComponent(prop) + "=" + encodeURIComponent(pdfParams[prop]) + "&";
+ }
+ }
+
+ //The string will be empty if no PDF Params found
+ if(string){
+
+ string = "#" + string;
+
+ //Remove last ampersand
+ string = string.slice(0, string.length - 1);
+
+ }
+
+ }
+
+ return string;
+
+ };
+
+ let embedError = function (msg, suppressConsole){
+ if(!suppressConsole){
+ console.log("[PDFObject] " + msg);
+ }
+ return false;
+ };
+
+ let emptyNodeContents = function (node){
+ while(node.firstChild){
+ node.removeChild(node.firstChild);
+ }
+ };
+
+ let getTargetElement = function (targetSelector){
+
+ //Default to body for full-browser PDF
+ let targetNode = document.body;
+
+ //If a targetSelector is specified, check to see whether
+ //it's passing a selector, jQuery object, or an HTML element
+
+ if(typeof targetSelector === "string"){
+
+ //Is CSS selector
+ targetNode = document.querySelector(targetSelector);
+
+ } else if (window.jQuery !== undefined && targetSelector instanceof jQuery && targetSelector.length) {
+
+ //Is jQuery element. Extract HTML node
+ targetNode = targetSelector.get(0);
+
+ } else if (targetSelector.nodeType !== undefined && targetSelector.nodeType === 1){
+
+ //Is HTML element
+ targetNode = targetSelector;
+
+ }
+
+ return targetNode;
+
+ };
+
+ let generatePDFObjectMarkup = function (embedType, targetNode, url, pdfOpenFragment, width, height, id, title, omitInlineStyles, customAttribute, PDFJS_URL){
+
+ //Ensure target element is empty first
+ emptyNodeContents(targetNode);
+
+ let source = url;
+
+ if(embedType === "pdfjs"){
+ //If PDFJS_URL already contains a ?, assume querystring is in place, and use an ampersand to append PDFJS's file parameter
+ let connector = (PDFJS_URL.indexOf("?") !== -1) ? "&" : "?";
+ source = PDFJS_URL + connector + "file=" + encodeURIComponent(url) + pdfOpenFragment;
+ } else {
+ source += pdfOpenFragment;
+ }
+
+ let el_type = (embedType === "pdfjs" || embedType === "iframe") ? "iframe" : "embed";
+ let el = document.createElement(el_type);
+
+ el.className = "pdfobject";
+ el.type = "application/pdf";
+ el.title = title;
+ el.src = source;
+
+ if(id){
+ el.id = id;
+ }
+
+ if(el_type === "iframe"){
+ el.allow = "fullscreen";
+ el.frameborder = "0";
+ }
+
+ if(!omitInlineStyles){
+
+ let style = (el_type === "embed") ? "overflow: auto;" : "border: none;";
+
+ if(targetNode !== document.body){
+ //assign width and height to target node
+ style += "width: " + width + "; height: " + height + ";";
+ } else {
+ //this is a full-page embed, use CSS to fill the viewport
+ style += "position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%;";
+ }
+
+ el.style.cssText = style;
+
+ }
+
+ //Allow developer to insert custom attribute on embed/iframe element, but ensure it does not conflict with attributes used by PDFObject
+ let reservedTokens = ["className", "type", "title", "src", "style", "id", "allow", "frameborder"];
+ if(customAttribute && customAttribute.key && reservedTokens.indexOf(customAttribute.key) === -1){
+ el.setAttribute(customAttribute.key, (typeof customAttribute.value !== "undefined") ? customAttribute.value : "");
+ }
+
+ targetNode.classList.add("pdfobject-container");
+ targetNode.appendChild(el);
+
+ return targetNode.getElementsByTagName(el_type)[0];
+
+ };
+
+ let embed = function(url, targetSelector, options){
+
+ //If targetSelector is not defined, convert to boolean
+ let selector = targetSelector || false;
+
+ //Ensure options object is not undefined -- enables easier error checking below
+ let opt = options || {};
+
+ //Get passed options, or set reasonable defaults
+ let id = (typeof opt.id === "string") ? opt.id : "";
+ let page = opt.page || false;
+ let pdfOpenParams = opt.pdfOpenParams || {};
+ let fallbackLink = (typeof opt.fallbackLink === "string" || typeof opt.fallbackLink === "boolean") ? opt.fallbackLink : true;
+ let width = opt.width || "100%";
+ let height = opt.height || "100%";
+ let title = opt.title || "Embedded PDF";
+ let assumptionMode = (typeof opt.assumptionMode === "boolean") ? opt.assumptionMode : true;
+ let forcePDFJS = (typeof opt.forcePDFJS === "boolean") ? opt.forcePDFJS : false;
+ let supportRedirect = (typeof opt.supportRedirect === "boolean") ? opt.supportRedirect : false;
+ let omitInlineStyles = (typeof opt.omitInlineStyles === "boolean") ? opt.omitInlineStyles : false;
+ let suppressConsole = (typeof opt.suppressConsole === "boolean") ? opt.suppressConsole : false;
+ let forceIframe = (typeof opt.forceIframe === "boolean") ? opt.forceIframe : false;
+ let PDFJS_URL = opt.PDFJS_URL || false;
+ let targetNode = getTargetElement(selector);
+ let fallbackHTML = "";
+ let pdfOpenFragment = "";
+ let customAttribute = opt.customAttribute || {};
+ let fallbackHTML_default = "
This browser does not support inline PDFs. Please download the PDF to view it: Download PDF
";
+
+ //Ensure URL is available. If not, exit now.
+ if(typeof url !== "string"){ return embedError("URL is not valid", suppressConsole); }
+
+ //If target element is specified but is not valid, exit without doing anything
+ if(!targetNode){ return embedError("Target element cannot be determined", suppressConsole); }
+
+ //page option overrides pdfOpenParams, if found
+ if(page){ pdfOpenParams.page = page; }
+
+ //Stringify optional Adobe params for opening document (as fragment identifier)
+ pdfOpenFragment = buildURLFragmentString(pdfOpenParams);
+
+
+ // --== Do the dance: Embed attempt #1 ==--
+
+ //If the forcePDFJS option is invoked, skip everything else and embed as directed
+ if(forcePDFJS && PDFJS_URL){
+ return generatePDFObjectMarkup("pdfjs", targetNode, url, pdfOpenFragment, width, height, id, title, omitInlineStyles, customAttribute, PDFJS_URL);
+ }
+
+ // --== Embed attempt #2 ==--
+
+ //Embed PDF if traditional support is provided, or if this developer is willing to roll with assumption
+ //that modern desktop (not mobile) browsers natively support PDFs
+ if(supportsPDFs || (assumptionMode && !isMobileDevice)){
+
+ //Should we use